/*
 * \file libusb1-glue.c
 * Low-level USB interface glue towards libusb.
 *
 * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
 * Copyright (C) 2005-2012 Linus Walleij <triad@df.lth.se>
 * Copyright (C) 2006-2012 Marcus Meissner
 * Copyright (C) 2007 Ted Bullock
 * Copyright (C) 2008 Chris Bagwell <chris@cnpbagwell.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Created by Richard Low on 24/12/2005. (as mtp-utils.c)
 * Modified by Linus Walleij 2006-03-06
 *  (Notice that Anglo-Saxons use little-endian dates and Swedes
 *   use big-endian dates.)
 *
 */
#include "config.h"
#include "libmtp.h"
#include "libusb-glue.h"
#include "device-flags.h"
#include "util.h"
#include "ptp.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "ptp-pack.c"

/*
 * Default USB timeout length.  This can be overridden as needed
 * but should start with a reasonable value so most common
 * requests can be completed.  The original value of 4000 was
 * not long enough for large file transfer.  Also, players can
 * spend a bit of time collecting data.  Higher values also
 * make connecting/disconnecting more reliable.
 */
#define USB_TIMEOUT_DEFAULT     20000
#define USB_TIMEOUT_LONG        60000
static inline int get_timeout(PTP_USB* ptp_usb)
{
  if (FLAG_LONG_TIMEOUT(ptp_usb)) {
    return USB_TIMEOUT_LONG;
  }
  return USB_TIMEOUT_DEFAULT;
}

/* USB Feature selector HALT */
#ifndef USB_FEATURE_HALT
#define USB_FEATURE_HALT	0x00
#endif

/* Internal data types */
struct mtpdevice_list_struct {
  libusb_device *device;
  PTPParams *params;
  PTP_USB *ptp_usb;
  uint32_t bus_location;
  struct mtpdevice_list_struct *next;
};
typedef struct mtpdevice_list_struct mtpdevice_list_t;

static const LIBMTP_device_entry_t mtp_device_table[] = {
/* We include an .h file which is shared between us and libgphoto2 */
#include "music-players.h"
};
static const int mtp_device_table_size =
  sizeof(mtp_device_table) / sizeof(LIBMTP_device_entry_t);

// Local functions
static LIBMTP_error_number_t init_usb();
static void close_usb(PTP_USB* ptp_usb);
static int find_interface_and_endpoints(libusb_device *dev,
					uint8_t *conf,
					uint8_t *interface,
					uint8_t *altsetting,
					int* inep,
					int* inep_maxpacket,
					int* outep,
					int* outep_maxpacket,
					int* intep);
static void clear_stall(PTP_USB* ptp_usb);
static int init_ptp_usb(PTPParams* params,
		PTP_USB* ptp_usb, libusb_device* dev);
static short ptp_write_func(unsigned long,
		PTPDataHandler*, void *data, unsigned long*);
static short ptp_read_func (unsigned long,
		PTPDataHandler*, void *data, unsigned long*, int);
static int usb_get_endpoint_status(PTP_USB* ptp_usb,
		int ep, uint16_t* status);

/**
 * Get a list of the supported USB devices.
 *
 * The developers depend on users of this library to constantly
 * add in to the list of supported devices. What we need is the
 * device name, USB Vendor ID (VID) and USB Product ID (PID).
 * put this into a bug ticket at the project homepage, please.
 * The VID/PID is used to let e.g. udev lift the device to
 * console userspace access when it's plugged in.
 *
 * @param devices a pointer to a pointer that will hold a device
 *        list after the call to this function, if it was
 *        successful.
 * @param numdevs a pointer to an integer that will hold the number
 *        of devices in the device list if the call was successful.
 * @return 0 if the list was successfull retrieved, any other
 *        value means failure.
 */
int LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices,
				      int * const numdevs)
{
  *devices = (LIBMTP_device_entry_t *) &mtp_device_table;
  *numdevs = mtp_device_table_size;
  return 0;
}


static LIBMTP_error_number_t init_usb()
{
  static int libusb1_initialized = 0;

  /*
   * Some additional libusb debugging please.
   * We use the same level debug between MTP and USB.
   */
  if (libusb1_initialized)
     return LIBMTP_ERROR_NONE;

  if (libusb_init(NULL) < 0) {
    LIBMTP_ERROR("Libusb1 init failed\n");
    return LIBMTP_ERROR_USB_LAYER;
  }

  libusb1_initialized = 1;

  if ((LIBMTP_debug & LIBMTP_DEBUG_USB) != 0)
    libusb_set_debug(NULL,9);
  return LIBMTP_ERROR_NONE;
}

/**
 * Small recursive function to append a new usb_device to the linked
 * list of USB MTP devices
 * @param devlist dynamic linked list of pointers to usb devices with
 *        MTP properties, to be extended with new device.
 * @param newdevice the new device to add.
 * @param bus_location bus for this device.
 * @return an extended array or NULL on failure.
 */
static mtpdevice_list_t *append_to_mtpdevice_list(mtpdevice_list_t *devlist,
						  libusb_device *newdevice,
						  uint32_t bus_location)
{
  mtpdevice_list_t *new_list_entry;

  new_list_entry = (mtpdevice_list_t *) malloc(sizeof(mtpdevice_list_t));
  if (new_list_entry == NULL) {
    return NULL;
  }
  // Fill in USB device, if we *HAVE* to make a copy of the device do it here.
  new_list_entry->device = newdevice;
  new_list_entry->bus_location = bus_location;
  new_list_entry->next = NULL;

  if (devlist == NULL) {
    return new_list_entry;
  } else {
    mtpdevice_list_t *tmp = devlist;
    while (tmp->next != NULL) {
      tmp = tmp->next;
    }
    tmp->next = new_list_entry;
  }
  return devlist;
}

/**
 * Small recursive function to free dynamic memory allocated to the linked list
 * of USB MTP devices
 * @param devlist dynamic linked list of pointers to usb devices with MTP
 * properties.
 * @return nothing
 */
static void free_mtpdevice_list(mtpdevice_list_t *devlist)
{
  mtpdevice_list_t *tmplist = devlist;

  if (devlist == NULL)
    return;
  while (tmplist != NULL) {
    mtpdevice_list_t *tmp = tmplist;
    tmplist = tmplist->next;
    // Do not free() the fields (ptp_usb, params)! These are used elsewhere.
    free(tmp);
  }
  return;
}

/**
 * This checks if a device has an MTP descriptor. The descriptor was
 * elaborated about in gPhoto bug 1482084, and some official documentation
 * with no strings attached was published by Microsoft at
 * http://www.microsoft.com/whdc/system/bus/USB/USBFAQ_intermed.mspx#E3HAC
 *
 * @param dev a device struct from libusb.
 * @param dumpfile set to non-NULL to make the descriptors dump out
 *        to this file in human-readable hex so we can scruitinze them.
 * @return 1 if the device is MTP compliant, 0 if not.
 */
static int probe_device_descriptor(libusb_device *dev, FILE *dumpfile)
{
  libusb_device_handle *devh;
  unsigned char buf[1024], cmd;
  int i;
  int ret;
  /* This is to indicate if we find some vendor interface */
  int found_vendor_spec_interface = 0;
  struct libusb_device_descriptor desc;

  ret = libusb_get_device_descriptor (dev, &desc);
  if (ret != LIBUSB_SUCCESS) return 0;
  /*
   * Don't examine devices that are not likely to
   * contain any MTP interface, update this the day
   * you find some weird combination...
   */
  if (!(desc.bDeviceClass == LIBUSB_CLASS_PER_INTERFACE ||
	desc.bDeviceClass == LIBUSB_CLASS_COMM ||
	desc.bDeviceClass == LIBUSB_CLASS_PTP ||
	desc.bDeviceClass == 0xEF ||	/* Intf. Association Desc.*/
	desc.bDeviceClass == LIBUSB_CLASS_VENDOR_SPEC)) {
    return 0;
  }

  /*
   * Attempt to open Device on this port
   *
   * TODO: is there a way to check the number of endpoints etc WITHOUT
   * opening the device? Some color calibration devices are REALLY
   * sensitive to this, and I found a Canon custom scanner that doesn't
   * like it at all either :-(
   */
  ret = libusb_open(dev, &devh);
  if (ret != LIBUSB_SUCCESS) {
    /* Could not open this device */
    return 0;
  }

  /*
   * Loop over the device configurations and interfaces. Nokia MTP-capable
   * handsets (possibly others) typically have the string "MTP" in their
   * MTP interface descriptions, that's how they can be detected, before
   * we try the more esoteric "OS descriptors" (below).
   */
  for (i = 0; i < desc.bNumConfigurations; i++) {
     uint8_t j;
     struct libusb_config_descriptor *config;

     ret = libusb_get_config_descriptor (dev, i, &config);
     if (ret != LIBUSB_SUCCESS) {
       LIBMTP_INFO("configdescriptor %d get failed with ret %d in probe_device_descriptor yet dev->descriptor.bNumConfigurations > 0\n", i, ret);
       continue;
     }

     for (j = 0; j < config->bNumInterfaces; j++) {
        int k;
        for (k = 0; k < config->interface[j].num_altsetting; k++) {
	  /* Current interface descriptor */
	  const struct libusb_interface_descriptor *intf =
	    &config->interface[j].altsetting[k];

	  /*
	   * MTP interfaces have three endpoints, two bulk and one
	   * interrupt. Don't probe anything else.
	   */
	  if (intf->bNumEndpoints != 3)
	    continue;

	  /*
	   * We only want to probe for the OS descriptor if the
	   * device is LIBUSB_CLASS_VENDOR_SPEC or one of the interfaces
	   * in it is, so flag if we find an interface like this.
	   */
	  if (intf->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC) {
	    found_vendor_spec_interface = 1;
	  }

	  /*
	   * TODO: Check for Still Image Capture class with PIMA 15740
	   * protocol, also known as PTP
	   */
#if 0
	  if (intf->bInterfaceClass == LIBUSB_CLASS_PTP
	      && intf->bInterfaceSubClass == 0x01
	      && intf->bInterfaceProtocol == 0x01) {
	    if (dumpfile != NULL) {
              fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
	      fprintf(dumpfile, "   Found PTP device, check vendor "
		      "extension...\n");
	    }
	    /*
	     * This is where we may insert code to open a PTP
	     * session and query the vendor extension ID to see
	     * if it is 0xffffffff, i.e. MTP according to the spec.
	     */
	    if (was_mtp_extension) {
	      libusb_close(devh);
	      return 1;
	    }
	  }
#endif

	  /*
	   * Next we search for the MTP substring in the interface name.
	   * For example : "RIM MS/MTP" should work.
	   */
          buf[0] = '\0';
          ret = libusb_get_string_descriptor_ascii(devh,
				      config->interface[j].altsetting[k].iInterface,
				      buf,
				      1024);
	  if (ret < 3)
	    continue;
          if (strstr((char *) buf, "MTP") != NULL) {
	    if (dumpfile != NULL) {
              fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
	      fprintf(dumpfile, "   Interface description contains the string \"MTP\"\n");
	      fprintf(dumpfile, "   Device recognized as MTP, no further probing.\n");
	    }
            libusb_free_config_descriptor(config);
            libusb_close(devh);
            return 1;
          }
          if (libusb_kernel_driver_active(devh, config->interface[j].altsetting[k].iInterface))
	  {
	    /*
	     * Specifically avoid probing anything else than USB mass storage devices
	     * and non-associated drivers in Linux.
	     */
	    if (config->interface[j].altsetting[k].bInterfaceClass !=
		LIBUSB_CLASS_MASS_STORAGE) {
	      LIBMTP_INFO("avoid probing device using attached kernel interface\n");
              libusb_free_config_descriptor(config);
	      libusb_close(devh);
	      return 0;
	    }
	  }
        }
     }
     libusb_free_config_descriptor(config);
  }

  /*
   * Only probe for OS descriptor if the device is vendor specific
   * or one of the interfaces found is.
   */
  if (desc.bDeviceClass == LIBUSB_CLASS_VENDOR_SPEC ||
      found_vendor_spec_interface) {

    /* Read the special descriptor */
    ret = libusb_get_descriptor(devh, 0x03, 0xee, buf, sizeof(buf));

    /*
     * If something failed we're probably stalled to we need
     * to clear the stall off the endpoint and say this is not
     * MTP.
     */
    if (ret < 0) {
      /* EP0 is the default control endpoint */
      libusb_clear_halt (devh, 0);
      libusb_close(devh);
      return 0;
    }

    // Dump it, if requested
    if (dumpfile != NULL && ret > 0) {
      fprintf(dumpfile, "Microsoft device descriptor 0xee:\n");
      data_dump_ascii(dumpfile, buf, ret, 16);
    }

    /* Check if descriptor length is at least 10 bytes */
    if (ret < 10) {
      libusb_close(devh);
      return 0;
    }

    /* Check if this device has a Microsoft Descriptor */
    if (!((buf[2] == 'M') && (buf[4] == 'S') &&
	  (buf[6] == 'F') && (buf[8] == 'T'))) {
      libusb_close(devh);
      return 0;
    }

    /* Check if device responds to control message 1 or if there is an error */
    cmd = buf[16];
    ret = libusb_control_transfer (devh,
			   LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR,
			   cmd,
			   0,
			   4,
			   buf,
			   sizeof(buf),
			   USB_TIMEOUT_DEFAULT);

    // Dump it, if requested
    if (dumpfile != NULL && ret > 0) {
      fprintf(dumpfile, "Microsoft device response to control message 1, CMD 0x%02x:\n", cmd);
      data_dump_ascii(dumpfile, buf, ret, 16);
    }

    /* If this is true, the device either isn't MTP or there was an error */
    if (ret <= 0x15) {
      /* TODO: If there was an error, flag it and let the user know somehow */
      /* if(ret == -1) {} */
      libusb_close(devh);
      return 0;
    }

    /* Check if device is MTP or if it is something like a USB Mass Storage
       device with Janus DRM support */
    if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
      libusb_close(devh);
      return 0;
    }

    /* After this point we are probably dealing with an MTP device */

    /*
     * Check if device responds to control message 2, which is
     * the extended device parameters. Most devices will just
     * respond with a copy of the same message as for the first
     * message, some respond with zero-length (which is OK)
     * and some with pure garbage. We're not parsing the result
     * so this is not very important.
     */
    ret = libusb_control_transfer (devh,
			   LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR,
			   cmd,
			   0,
			   5,
			   buf,
			   sizeof(buf),
			   USB_TIMEOUT_DEFAULT);

    // Dump it, if requested
    if (dumpfile != NULL && ret > 0) {
      fprintf(dumpfile, "Microsoft device response to control message 2, CMD 0x%02x:\n", cmd);
      data_dump_ascii(dumpfile, buf, ret, 16);
    }

    /* If this is true, the device errored against control message 2 */
    if (ret == -1) {
      /* TODO: Implement callback function to let managing program know there
	 was a problem, along with description of the problem */
      LIBMTP_ERROR("Potential MTP Device with VendorID:%04x and "
		   "ProductID:%04x encountered an error responding to "
		   "control message 2.\n"
		   "Problems may arrise but continuing\n",
		   desc.idVendor, desc.idProduct);
    } else if (dumpfile != NULL && ret == 0) {
      fprintf(dumpfile, "Zero-length response to control message 2 (OK)\n");
    } else if (dumpfile != NULL) {
      fprintf(dumpfile, "Device responds to control message 2 with some data.\n");
    }
    /* Close the USB device handle */
    libusb_close(devh);
    return 1;
  }

  /* Close the USB device handle */
  libusb_close(devh);
  return 0;
}

/**
 * This function scans through the connected usb devices on a machine and
 * if they match known Vendor and Product identifiers appends them to the
 * dynamic array mtp_device_list. Be sure to call
 * <code>free_mtpdevice_list(mtp_device_list)</code> when you are done
 * with it, assuming it is not NULL.
 * @param mtp_device_list dynamic array of pointers to usb devices with MTP
 *        properties (if this list is not empty, new entries will be appended
 *        to the list).
 * @return LIBMTP_ERROR_NONE implies that devices have been found, scan the list
 *        appropriately. LIBMTP_ERROR_NO_DEVICE_ATTACHED implies that no
 *        devices have been found.
 */
static LIBMTP_error_number_t get_mtp_usb_device_list(mtpdevice_list_t ** mtp_device_list)
{
  ssize_t nrofdevs;
  libusb_device **devs = NULL;
  int ret, i;
  LIBMTP_error_number_t init_usb_ret;

  init_usb_ret = init_usb();
  if (init_usb_ret != LIBMTP_ERROR_NONE)
    return init_usb_ret;

  nrofdevs = libusb_get_device_list (NULL, &devs);
  for (i = 0; i < nrofdevs ; i++) {
      libusb_device *dev = devs[i];
      struct libusb_device_descriptor desc;

      ret = libusb_get_device_descriptor(dev, &desc);
      if (ret != LIBUSB_SUCCESS) continue;

      if (desc.bDeviceClass != LIBUSB_CLASS_HUB) {
	int i;
        int found = 0;

	// First check if we know about the device already.
	// Devices well known to us will not have their descriptors
	// probed, it caused problems with some devices.
        for(i = 0; i < mtp_device_table_size; i++) {
          if(desc.idVendor == mtp_device_table[i].vendor_id &&
            desc.idProduct == mtp_device_table[i].product_id) {
            /* Append this usb device to the MTP device list */
            *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
							dev,
							libusb_get_bus_number(dev));
            found = 1;
            break;
          }
        }
	// If we didn't know it, try probing the "OS Descriptor".
        if (!found) {
          if (probe_device_descriptor(dev, NULL)) {
            /* Append this usb device to the MTP USB Device List */
            *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
							dev,
							libusb_get_bus_number(dev));
          }
          /*
	   * By thomas_-_s: Also append devices that are no MTP but PTP devices
	   * if this is commented out.
	   */
	  /*
	  else {
	    // Check whether the device is no USB hub but a PTP.
	    if ( dev->config != NULL &&dev->config->interface->altsetting->bInterfaceClass == LIBUSB_CLASS_PTP && dev->descriptor.bDeviceClass != LIBUSB_CLASS_HUB ) {
	      *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list, dev, bus->location);
	    }
          }
	  */
        }
      }
    }
    libusb_free_device_list (devs, 0);

  /* If nothing was found we end up here. */
  if(*mtp_device_list == NULL) {
    return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
  }
  return LIBMTP_ERROR_NONE;
}

/**
 * Checks if a specific device with a certain bus and device
 * number has an MTP type device descriptor.
 *
 * @param busno the bus number of the device to check
 * @param deviceno the device number of the device to check
 * @return 1 if the device is MTP else 0
 */
int LIBMTP_Check_Specific_Device(int busno, int devno)
{
  ssize_t nrofdevs;
  libusb_device **devs = NULL;
  int i;
  LIBMTP_error_number_t init_usb_ret;

  init_usb_ret = init_usb();
  if (init_usb_ret != LIBMTP_ERROR_NONE)
    return 0;

  nrofdevs = libusb_get_device_list (NULL, &devs);
  for (i = 0; i < nrofdevs ; i++ ) {

    if (libusb_get_bus_number(devs[i]) != busno)
      continue;
    if (libusb_get_device_address(devs[i]) != devno)
      continue;

      if (probe_device_descriptor(devs[i], NULL))
	return 1;
  }
  return 0;
}

/**
 * Detect the raw MTP device descriptors and return a list of
 * of the devices found.
 *
 * @param devices a pointer to a variable that will hold
 *        the list of raw devices found. This may be NULL
 *        on return if the number of detected devices is zero.
 *        The user shall simply <code>free()</code> this
 *        variable when finished with the raw devices,
 *        in order to release memory.
 * @param numdevs a pointer to an integer that will hold
 *        the number of devices in the list. This may
 *        be 0.
 * @return 0 if successful, any other value means failure.
 */
LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t ** devices,
			      int * numdevs)
{
  mtpdevice_list_t *devlist = NULL;
  mtpdevice_list_t *dev;
  LIBMTP_error_number_t ret;
  LIBMTP_raw_device_t *retdevs;
  int devs = 0;
  int i, j;

  ret = get_mtp_usb_device_list(&devlist);
  if (ret == LIBMTP_ERROR_NO_DEVICE_ATTACHED) {
    *devices = NULL;
    *numdevs = 0;
    return ret;
  } else if (ret != LIBMTP_ERROR_NONE) {
    LIBMTP_ERROR("LIBMTP PANIC: get_mtp_usb_device_list() "
	    "error code: %d on line %d\n", ret, __LINE__);
    return ret;
  }

  // Get list size
  dev = devlist;
  while (dev != NULL) {
    devs++;
    dev = dev->next;
  }
  if (devs == 0) {
    *devices = NULL;
    *numdevs = 0;
    return LIBMTP_ERROR_NONE;
  }
  // Conjure a device list
  retdevs = (LIBMTP_raw_device_t *) malloc(sizeof(LIBMTP_raw_device_t) * devs);
  if (retdevs == NULL) {
    // Out of memory
    *devices = NULL;
    *numdevs = 0;
    return LIBMTP_ERROR_MEMORY_ALLOCATION;
  }
  dev = devlist;
  i = 0;
  while (dev != NULL) {
    int device_known = 0;
    struct libusb_device_descriptor desc;

    libusb_get_device_descriptor (dev->device, &desc);
    // Assign default device info
    retdevs[i].device_entry.vendor = NULL;
    retdevs[i].device_entry.vendor_id = desc.idVendor;
    retdevs[i].device_entry.product = NULL;
    retdevs[i].device_entry.product_id = desc.idProduct;
    retdevs[i].device_entry.device_flags = 0x00000000U;
    // See if we can locate some additional vendor info and device flags
    for(j = 0; j < mtp_device_table_size; j++) {
      if(desc.idVendor == mtp_device_table[j].vendor_id &&
	 desc.idProduct == mtp_device_table[j].product_id) {
	device_known = 1;
	retdevs[i].device_entry.vendor = mtp_device_table[j].vendor;
	retdevs[i].device_entry.product = mtp_device_table[j].product;
	retdevs[i].device_entry.device_flags = mtp_device_table[j].device_flags;

	// This device is known to the developers
	LIBMTP_ERROR("Device %d (VID=%04x and PID=%04x) is a %s %s.\n",
		i,
		desc.idVendor,
		desc.idProduct,
		mtp_device_table[j].vendor,
		mtp_device_table[j].product);
	break;
      }
    }
    if (!device_known) {
      device_unknown(i, desc.idVendor, desc.idProduct);
    }
    // Save the location on the bus
    retdevs[i].bus_location = libusb_get_bus_number (dev->device);
    retdevs[i].devnum = libusb_get_device_address (dev->device);
    i++;
    dev = dev->next;
  }
  *devices = retdevs;
  *numdevs = i;
  free_mtpdevice_list(devlist);
  return LIBMTP_ERROR_NONE;
}

/**
 * This routine just dumps out low-level
 * USB information about the current device.
 * @param ptp_usb the USB device to get information from.
 */
void dump_usbinfo(PTP_USB *ptp_usb)
{
  libusb_device *dev;
  struct libusb_device_descriptor desc;

  if (libusb_kernel_driver_active(ptp_usb->handle, ptp_usb->interface))
    LIBMTP_INFO("   Interface has a kernel driver attached.\n");

  dev = libusb_get_device (ptp_usb->handle);
  libusb_get_device_descriptor (dev, &desc);

  LIBMTP_INFO("   bcdUSB: %d\n", desc.bcdUSB);
  LIBMTP_INFO("   bDeviceClass: %d\n", desc.bDeviceClass);
  LIBMTP_INFO("   bDeviceSubClass: %d\n", desc.bDeviceSubClass);
  LIBMTP_INFO("   bDeviceProtocol: %d\n", desc.bDeviceProtocol);
  LIBMTP_INFO("   idVendor: %04x\n", desc.idVendor);
  LIBMTP_INFO("   idProduct: %04x\n", desc.idProduct);
  LIBMTP_INFO("   IN endpoint maxpacket: %d bytes\n", ptp_usb->inep_maxpacket);
  LIBMTP_INFO("   OUT endpoint maxpacket: %d bytes\n", ptp_usb->outep_maxpacket);
  LIBMTP_INFO("   Raw device info:\n");
  LIBMTP_INFO("      Bus location: %d\n", ptp_usb->rawdevice.bus_location);
  LIBMTP_INFO("      Device number: %d\n", ptp_usb->rawdevice.devnum);
  LIBMTP_INFO("      Device entry info:\n");
  LIBMTP_INFO("         Vendor: %s\n", ptp_usb->rawdevice.device_entry.vendor);
  LIBMTP_INFO("         Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.vendor_id);
  LIBMTP_INFO("         Product: %s\n", ptp_usb->rawdevice.device_entry.product);
  LIBMTP_INFO("         Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.product_id);
  LIBMTP_INFO("         Device flags: 0x%08x\n", ptp_usb->rawdevice.device_entry.device_flags);
  (void) probe_device_descriptor(dev, stdout);
}

/**
 * Retrieve the apropriate playlist extension for this
 * device. Rather hacky at the moment. This is probably
 * desired by the managing software, but when creating
 * lists on the device itself you notice certain preferences.
 * @param ptp_usb the USB device to get suggestion for.
 * @return the suggested playlist extension.
 */
const char *get_playlist_extension(PTP_USB *ptp_usb)
{
  libusb_device *dev;
  struct libusb_device_descriptor desc;
  static char creative_pl_extension[] = ".zpl";
  static char default_pl_extension[] = ".pla";

  dev = libusb_get_device(ptp_usb->handle);
  libusb_get_device_descriptor (dev, &desc);
  if (desc.idVendor == 0x041e)
    return creative_pl_extension;
  return default_pl_extension;
}

static void
libusb_glue_debug (PTPParams *params, const char *format, ...)
{
        va_list args;

        va_start (args, format);
        if (params->debug_func!=NULL)
                params->debug_func (params->data, format, args);
        else
	{
                vfprintf (stderr, format, args);
		fprintf (stderr,"\n");
		fflush (stderr);
	}
        va_end (args);
}

static void
libusb_glue_error (PTPParams *params, const char *format, ...)
{
        va_list args;

        va_start (args, format);
        if (params->error_func!=NULL)
                params->error_func (params->data, format, args);
        else
	{
                vfprintf (stderr, format, args);
		fprintf (stderr,"\n");
		fflush (stderr);
	}
        va_end (args);
}


/*
 * ptp_read_func() and ptp_write_func() are
 * based on same functions usb.c in libgphoto2.
 * Much reading packet logs and having fun with trials and errors
 * reveals that WMP / Windows is probably using an algorithm like this
 * for large transfers:
 *
 * 1. Send the command (0x0c bytes) if headers are split, else, send
 *    command plus sizeof(endpoint) - 0x0c bytes.
 * 2. Send first packet, max size to be sizeof(endpoint) but only when using
 *    split headers. Else goto 3.
 * 3. REPEAT send 0x10000 byte chunks UNTIL remaining bytes < 0x10000
 *    We call 0x10000 CONTEXT_BLOCK_SIZE.
 * 4. Send remaining bytes MOD sizeof(endpoint)
 * 5. Send remaining bytes. If this happens to be exactly sizeof(endpoint)
 *    then also send a zero-length package.
 *
 * Further there is some special quirks to handle zero reads from the
 * device, since some devices can't do them at all due to shortcomings
 * of the USB slave controller in the device.
 */
#define CONTEXT_BLOCK_SIZE_1	0x3e00
#define CONTEXT_BLOCK_SIZE_2  0x200
#define CONTEXT_BLOCK_SIZE    CONTEXT_BLOCK_SIZE_1+CONTEXT_BLOCK_SIZE_2
static short
ptp_read_func (
	unsigned long size, PTPDataHandler *handler,void *data,
	unsigned long *readbytes,
	int readzero
) {
  PTP_USB *ptp_usb = (PTP_USB *)data;
  unsigned long toread = 0;
  int ret = 0;
  int xread;
  unsigned long curread = 0;
  unsigned long written;
  unsigned char *bytes;
  int expect_terminator_byte = 0;
  unsigned long usb_inep_maxpacket_size;
  unsigned long context_block_size_1;
  unsigned long context_block_size_2;
  uint16_t ptp_dev_vendor_id = ptp_usb->rawdevice.device_entry.vendor_id;

  //"iRiver" device special handling
  if (ptp_dev_vendor_id == 0x4102 || ptp_dev_vendor_id == 0x1006) {
	  usb_inep_maxpacket_size = ptp_usb->inep_maxpacket;
	  if (usb_inep_maxpacket_size == 0x400) {
		  context_block_size_1 = CONTEXT_BLOCK_SIZE_1 - 0x200;
		  context_block_size_2 = CONTEXT_BLOCK_SIZE_2 + 0x200;
	  }
	  else {
		  context_block_size_1 = CONTEXT_BLOCK_SIZE_1;
		  context_block_size_2 = CONTEXT_BLOCK_SIZE_2;
	  }
  }
  // This is the largest block we'll need to read in.
  bytes = malloc(CONTEXT_BLOCK_SIZE);
  while (curread < size) {

    LIBMTP_USB_DEBUG("Remaining size to read: 0x%04lx bytes\n", size - curread);

    // check equal to condition here
    if (size - curread < CONTEXT_BLOCK_SIZE)
    {
      // this is the last packet
      toread = size - curread;
      // this is equivalent to zero read for these devices
      if (readzero && FLAG_NO_ZERO_READS(ptp_usb) && toread % 64 == 0) {
        toread += 1;
        expect_terminator_byte = 1;
      }
    }
    else if (ptp_dev_vendor_id == 0x4102 || ptp_dev_vendor_id == 0x1006) {
	    //"iRiver" device special handling
	    if (curread == 0)
		    // we are first packet, but not last packet
		    toread = context_block_size_1;
	    else if (toread == context_block_size_1)
		    toread = context_block_size_2;
	    else if (toread == context_block_size_2)
		    toread = context_block_size_1;
	    else
		    LIBMTP_INFO("unexpected toread size 0x%04x, 0x%04x remaining bytes\n",
				(unsigned int) toread, (unsigned int) (size-curread));
    }
    else
	    toread = CONTEXT_BLOCK_SIZE;

    LIBMTP_USB_DEBUG("Reading in 0x%04lx bytes\n", toread);

    ret = USB_BULK_READ(ptp_usb->handle,
			   ptp_usb->inep,
			   bytes,
			   toread,
                           &xread,
			   ptp_usb->timeout);

    LIBMTP_USB_DEBUG("Result of read: 0x%04x (%d bytes)\n", ret, xread);

    if (ret != LIBUSB_SUCCESS)
      return PTP_ERROR_IO;

    LIBMTP_USB_DEBUG("<==USB IN\n");
    if (xread == 0)
      LIBMTP_USB_DEBUG("Zero Read\n");
    else
      LIBMTP_USB_DATA(bytes, xread, 16);

    // want to discard extra byte
    if (expect_terminator_byte && xread == toread)
    {
      LIBMTP_USB_DEBUG("<==USB IN\nDiscarding extra byte\n");

      xread--;
    }

    int putfunc_ret = handler->putfunc(NULL, handler->priv, xread, bytes, &written);
    if (putfunc_ret != PTP_RC_OK)
      return putfunc_ret;

    ptp_usb->current_transfer_complete += xread;
    curread += xread;

    // Increase counters, call callback
    if (ptp_usb->callback_active) {
      if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
	// send last update and disable callback.
	ptp_usb->current_transfer_complete = ptp_usb->current_transfer_total;
	ptp_usb->callback_active = 0;
      }
      if (ptp_usb->current_transfer_callback != NULL) {
	int ret;
	ret = ptp_usb->current_transfer_callback(ptp_usb->current_transfer_complete,
						 ptp_usb->current_transfer_total,
						 ptp_usb->current_transfer_callback_data);
	if (ret != 0) {
	  return PTP_ERROR_CANCEL;
	}
      }
    }

    if (xread < toread) /* short reads are common */
      break;
  }
  if (readbytes) *readbytes = curread;
  free (bytes);

  // there might be a zero packet waiting for us...
  if (readzero &&
      !FLAG_NO_ZERO_READS(ptp_usb) &&
      curread % ptp_usb->outep_maxpacket == 0) {
    unsigned char temp;
    int zeroresult = 0, xread;

    LIBMTP_USB_DEBUG("<==USB IN\n");
    LIBMTP_USB_DEBUG("Zero Read\n");

    zeroresult = USB_BULK_READ(ptp_usb->handle,
			       ptp_usb->inep,
			       &temp,
			       0,
                               &xread,
			       ptp_usb->timeout);
    if (zeroresult != LIBUSB_SUCCESS)
      LIBMTP_INFO("LIBMTP panic: unable to read in zero packet, response 0x%04x", zeroresult);
  }

  return PTP_RC_OK;
}

static short
ptp_write_func (
        unsigned long   size,
        PTPDataHandler  *handler,
        void            *data,
        unsigned long   *written
) {
  PTP_USB *ptp_usb = (PTP_USB *)data;
  unsigned long towrite = 0;
  int ret = 0;
  unsigned long curwrite = 0;
  unsigned char *bytes;

  // This is the largest block we'll need to read in.
  bytes = malloc(CONTEXT_BLOCK_SIZE);
  if (!bytes) {
    return PTP_ERROR_IO;
  }
  while (curwrite < size) {
    unsigned long usbwritten = 0;
    int xwritten = 0;

    towrite = size-curwrite;
    if (towrite > CONTEXT_BLOCK_SIZE) {
      towrite = CONTEXT_BLOCK_SIZE;
    } else {
      // This magic makes packets the same size that WMP send them.
      if (towrite > ptp_usb->outep_maxpacket && towrite % ptp_usb->outep_maxpacket != 0) {
        towrite -= towrite % ptp_usb->outep_maxpacket;
      }
    }
    int getfunc_ret = handler->getfunc(NULL, handler->priv,towrite,bytes,&towrite);
    if (getfunc_ret != PTP_RC_OK) {
      free(bytes);
      return getfunc_ret;
    }
    while (usbwritten < towrite) {
	    ret = USB_BULK_WRITE(ptp_usb->handle,
				    ptp_usb->outep,
				    bytes+usbwritten,
				    towrite-usbwritten,
                                    &xwritten,
				    ptp_usb->timeout);

	    LIBMTP_USB_DEBUG("USB OUT==>\n");

	    if (ret != LIBUSB_SUCCESS) {
              free(bytes);
	      return PTP_ERROR_IO;
	    }
	    LIBMTP_USB_DATA(bytes+usbwritten, xwritten, 16);
	    // check for result == 0 perhaps too.
	    // Increase counters
	    ptp_usb->current_transfer_complete += xwritten;
	    curwrite += xwritten;
	    usbwritten += xwritten;
    }
    // call callback
    if (ptp_usb->callback_active) {
      if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
	// send last update and disable callback.
	ptp_usb->current_transfer_complete = ptp_usb->current_transfer_total;
	ptp_usb->callback_active = 0;
      }
      if (ptp_usb->current_transfer_callback != NULL) {
	int ret;
	ret = ptp_usb->current_transfer_callback(ptp_usb->current_transfer_complete,
						 ptp_usb->current_transfer_total,
						 ptp_usb->current_transfer_callback_data);
	if (ret != 0) {
          free(bytes);
	  return PTP_ERROR_CANCEL;
	}
      }
    }
    if (xwritten < towrite) /* short writes happen */
      break;
  }
  free (bytes);
  if (written) {
    *written = curwrite;
  }

  // If this is the last transfer send a zero write if required
  if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
    if ((towrite % ptp_usb->outep_maxpacket) == 0) {
      int xwritten;

      LIBMTP_USB_DEBUG("USB OUT==>\n");
      LIBMTP_USB_DEBUG("Zero Write\n");

      ret =USB_BULK_WRITE(ptp_usb->handle,
			    ptp_usb->outep,
			    (unsigned char *) "x",
			    0,
                            &xwritten,
			    ptp_usb->timeout);
    }
  }

  if (ret != LIBUSB_SUCCESS)
    return PTP_ERROR_IO;
  return PTP_RC_OK;
}

/* memory data get/put handler */
typedef struct {
	unsigned char	*data;
	unsigned long	size, curoff;
} PTPMemHandlerPrivate;

static uint16_t
memory_getfunc(PTPParams* params, void* private,
	       unsigned long wantlen, unsigned char *data,
	       unsigned long *gotlen
) {
	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
	unsigned long tocopy = wantlen;

	if (priv->curoff + tocopy > priv->size)
		tocopy = priv->size - priv->curoff;
	memcpy (data, priv->data + priv->curoff, tocopy);
	priv->curoff += tocopy;
	*gotlen = tocopy;
	return PTP_RC_OK;
}

static uint16_t
memory_putfunc(PTPParams* params, void* private,
	       unsigned long sendlen, unsigned char *data,
	       unsigned long *putlen
) {
	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;

	if (priv->curoff + sendlen > priv->size) {
		priv->data = realloc (priv->data, priv->curoff+sendlen);
		priv->size = priv->curoff + sendlen;
	}
	memcpy (priv->data + priv->curoff, data, sendlen);
	priv->curoff += sendlen;
	*putlen = sendlen;
	return PTP_RC_OK;
}

/* init private struct for receiving data. */
static uint16_t
ptp_init_recv_memory_handler(PTPDataHandler *handler) {
	PTPMemHandlerPrivate* priv;
	priv = malloc (sizeof(PTPMemHandlerPrivate));
	handler->priv = priv;
	handler->getfunc = memory_getfunc;
	handler->putfunc = memory_putfunc;
	priv->data = NULL;
	priv->size = 0;
	priv->curoff = 0;
	return PTP_RC_OK;
}

/* init private struct and put data in for sending data.
 * data is still owned by caller.
 */
static uint16_t
ptp_init_send_memory_handler(PTPDataHandler *handler,
	unsigned char *data, unsigned long len
) {
	PTPMemHandlerPrivate* priv;
	priv = malloc (sizeof(PTPMemHandlerPrivate));
	if (!priv)
		return PTP_RC_GeneralError;
	handler->priv = priv;
	handler->getfunc = memory_getfunc;
	handler->putfunc = memory_putfunc;
	priv->data = data;
	priv->size = len;
	priv->curoff = 0;
	return PTP_RC_OK;
}

/* free private struct + data */
static uint16_t
ptp_exit_send_memory_handler (PTPDataHandler *handler) {
	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
	/* data is owned by caller */
	free (priv);
	return PTP_RC_OK;
}

/* hand over our internal data to caller */
static uint16_t
ptp_exit_recv_memory_handler (PTPDataHandler *handler,
	unsigned char **data, unsigned long *size
) {
	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
	*data = priv->data;
	*size = priv->size;
	free (priv);
	return PTP_RC_OK;
}

/* send / receive functions */

uint16_t
ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
{
	uint16_t ret;
	PTPUSBBulkContainer usbreq;
	PTPDataHandler	memhandler;
	unsigned long written = 0;
	unsigned long towrite;

	char txt[256];

	(void) ptp_render_opcode (params, req->Code, sizeof(txt), txt);
	LIBMTP_USB_DEBUG("REQUEST: 0x%04x, %s\n", req->Code, txt);

	/* build appropriate USB container */
	usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
		(sizeof(uint32_t)*(5-req->Nparam)));
	usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
	usbreq.code=htod16(req->Code);
	usbreq.trans_id=htod32(req->Transaction_ID);
	usbreq.payload.params.param1=htod32(req->Param1);
	usbreq.payload.params.param2=htod32(req->Param2);
	usbreq.payload.params.param3=htod32(req->Param3);
	usbreq.payload.params.param4=htod32(req->Param4);
	usbreq.payload.params.param5=htod32(req->Param5);
	/* send it to responder */
	towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam));
	ptp_init_send_memory_handler (&memhandler, (unsigned char*)&usbreq, towrite);
	ret=ptp_write_func(
		towrite,
		&memhandler,
		params->data,
		&written
	);
	ptp_exit_send_memory_handler (&memhandler);
	if (ret != PTP_RC_OK && ret != PTP_ERROR_CANCEL) {
		ret = PTP_ERROR_IO;
	}
	if (written != towrite && ret != PTP_ERROR_CANCEL && ret != PTP_ERROR_IO) {
		libusb_glue_error (params,
			"PTP: request code 0x%04x sending req wrote only %ld bytes instead of %d",
			req->Code, written, towrite
		);
		ret = PTP_ERROR_IO;
	}
	return ret;
}

uint16_t
ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
		  uint64_t size, PTPDataHandler *handler
) {
	uint16_t ret;
	int wlen, datawlen;
	unsigned long written;
	PTPUSBBulkContainer usbdata;
	uint64_t bytes_left_to_transfer;
	PTPDataHandler memhandler;


	LIBMTP_USB_DEBUG("SEND DATA PHASE\n");

	/* build appropriate USB container */
	usbdata.length	= htod32(PTP_USB_BULK_HDR_LEN+size);
	usbdata.type	= htod16(PTP_USB_CONTAINER_DATA);
	usbdata.code	= htod16(ptp->Code);
	usbdata.trans_id= htod32(ptp->Transaction_ID);

	((PTP_USB*)params->data)->current_transfer_complete = 0;
	((PTP_USB*)params->data)->current_transfer_total = size+PTP_USB_BULK_HDR_LEN;

	if (params->split_header_data) {
		datawlen = 0;
		wlen = PTP_USB_BULK_HDR_LEN;
	} else {
		unsigned long gotlen;
		/* For all camera devices. */
		datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN_WRITE)?size:PTP_USB_BULK_PAYLOAD_LEN_WRITE;
		wlen = PTP_USB_BULK_HDR_LEN + datawlen;

		ret = handler->getfunc(params, handler->priv, datawlen, usbdata.payload.data, &gotlen);
		if (ret != PTP_RC_OK)
			return ret;
		if (gotlen != datawlen)
			return PTP_RC_GeneralError;
	}
	ptp_init_send_memory_handler (&memhandler, (unsigned char *)&usbdata, wlen);
	/* send first part of data */
	ret = ptp_write_func(wlen, &memhandler, params->data, &written);
	ptp_exit_send_memory_handler (&memhandler);
	if (ret != PTP_RC_OK) {
		return ret;
	}
	if (size <= datawlen) return ret;
	/* if everything OK send the rest */
	bytes_left_to_transfer = size-datawlen;
	ret = PTP_RC_OK;
	while(bytes_left_to_transfer > 0) {
		ret = ptp_write_func (bytes_left_to_transfer, handler, params->data, &written);
		if (ret != PTP_RC_OK)
			break;
		if (written == 0) {
			ret = PTP_ERROR_IO;
			break;
		}
		bytes_left_to_transfer -= written;
	}
	if (ret != PTP_RC_OK && ret != PTP_ERROR_CANCEL)
		ret = PTP_ERROR_IO;
	return ret;
}

static uint16_t ptp_usb_getpacket(PTPParams *params,
		PTPUSBBulkContainer *packet, unsigned long *rlen)
{
	PTPDataHandler	memhandler;
	uint16_t	ret;
	unsigned char	*x = NULL;
	unsigned long packet_size;
	PTP_USB *ptp_usb = (PTP_USB *) params->data;

	packet_size = ptp_usb->inep_maxpacket;

	/* read the header and potentially the first data */
	if (params->response_packet_size > 0) {
		/* If there is a buffered packet, just use it. */
		memcpy(packet, params->response_packet, params->response_packet_size);
		*rlen = params->response_packet_size;
		free(params->response_packet);
		params->response_packet = NULL;
		params->response_packet_size = 0;
		/* Here this signifies a "virtual read" */
		return PTP_RC_OK;
	}
	ptp_init_recv_memory_handler (&memhandler);
	ret = ptp_read_func(packet_size, &memhandler, params->data, rlen, 0);
	ptp_exit_recv_memory_handler (&memhandler, &x, rlen);
	if (x) {
		memcpy (packet, x, *rlen);
		free (x);
	}
	return ret;
}

uint16_t
ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
{
	uint16_t ret;
	PTPUSBBulkContainer usbdata;
	unsigned long	written;
	PTP_USB *ptp_usb = (PTP_USB *) params->data;
	int putfunc_ret;

	LIBMTP_USB_DEBUG("GET DATA PHASE\n");

	memset(&usbdata,0,sizeof(usbdata));
	do {
		unsigned long len, rlen;

		ret = ptp_usb_getpacket(params, &usbdata, &rlen);
		if (ret != PTP_RC_OK) {
			ret = PTP_ERROR_IO;
			break;
		}
		if (dtoh16(usbdata.type)!=PTP_USB_CONTAINER_DATA) {
			ret = PTP_ERROR_DATA_EXPECTED;
			break;
		}
		if (dtoh16(usbdata.code)!=ptp->Code) {
			if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
				libusb_glue_debug (params, "ptp2/ptp_usb_getdata: detected a broken "
					   "PTP header, code field insane, expect problems! (But continuing)");
				// Repair the header, so it won't wreak more havoc, don't just ignore it.
				// Typically these two fields will be broken.
				usbdata.code	 = htod16(ptp->Code);
				usbdata.trans_id = htod32(ptp->Transaction_ID);
				ret = PTP_RC_OK;
			} else {
				ret = dtoh16(usbdata.code);
				// This filters entirely insane garbage return codes, but still
				// makes it possible to return error codes in the code field when
				// getting data. It appears Windows ignores the contents of this
				// field entirely.
				if (ret < PTP_RC_Undefined || ret > PTP_RC_SpecificationOfDestinationUnsupported) {
					libusb_glue_debug (params, "ptp2/ptp_usb_getdata: detected a broken "
						   "PTP header, code field insane.");
					ret = PTP_ERROR_IO;
				}
				break;
			}
		}
		if (rlen == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) {
		  /* Copy first part of data to 'data' */
		  putfunc_ret =
		    handler->putfunc(
				     params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data,
				     &written
				     );
		  if (putfunc_ret != PTP_RC_OK)
		    return putfunc_ret;

		  /* stuff data directly to passed data handler */
		  while (1) {
		    unsigned long readdata;
		    uint16_t xret;

		    xret = ptp_read_func(
					 0x20000000,
					 handler,
					 params->data,
					 &readdata,
					 0
					 );
		    if (xret != PTP_RC_OK)
		      return xret;
		    if (readdata < 0x20000000)
		      break;
		  }
		  return PTP_RC_OK;
		}
		if (rlen > dtoh32(usbdata.length)) {
			/*
			 * Buffer the surplus response packet if it is >=
			 * PTP_USB_BULK_HDR_LEN
			 * (i.e. it is probably an entire package)
			 * else discard it as erroneous surplus data.
			 * This will even work if more than 2 packets appear
			 * in the same transaction, they will just be handled
			 * iteratively.
			 *
			 * Marcus observed stray bytes on iRiver devices;
			 * these are still discarded.
			 */
			unsigned int packlen = dtoh32(usbdata.length);
			unsigned int surplen = rlen - packlen;

			if (surplen >= PTP_USB_BULK_HDR_LEN) {
				params->response_packet = malloc(surplen);
				memcpy(params->response_packet,
				       (uint8_t *) &usbdata + packlen, surplen);
				params->response_packet_size = surplen;
			/* Ignore reading one extra byte if device flags have been set */
			} else if(!FLAG_NO_ZERO_READS(ptp_usb) &&
				  (rlen - dtoh32(usbdata.length) == 1)) {
			  libusb_glue_debug (params, "ptp2/ptp_usb_getdata: read %d bytes "
				     "too much, expect problems!",
				     rlen - dtoh32(usbdata.length));
			}
			rlen = packlen;
		}

		/* For most PTP devices rlen is 512 == sizeof(usbdata)
		 * here. For MTP devices splitting header and data it might
		 * be 12.
		 */
		/* Evaluate full data length. */
		len=dtoh32(usbdata.length)-PTP_USB_BULK_HDR_LEN;

		/* autodetect split header/data MTP devices */
		if (dtoh32(usbdata.length) > 12 && (rlen==12))
			params->split_header_data = 1;

		/* Copy first part of data to 'data' */
		putfunc_ret =
		  handler->putfunc(
				   params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN,
				   usbdata.payload.data,
				   &written
				   );
		if (putfunc_ret != PTP_RC_OK)
		  return putfunc_ret;

		if (FLAG_NO_ZERO_READS(ptp_usb) &&
		    len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) {

		  LIBMTP_USB_DEBUG("Reading in extra terminating byte\n");

		  // need to read in extra byte and discard it
		  int result = 0, xread;
		  unsigned char byte = 0;
                  result = USB_BULK_READ(ptp_usb->handle,
					 ptp_usb->inep,
					 &byte,
					 1,
                                         &xread,
					 ptp_usb->timeout);

		  if (result != 1)
		    LIBMTP_INFO("Could not read in extra byte for PTP_USB_BULK_HS_MAX_PACKET_LEN_READ long file, return value 0x%04x\n", result);
		} else if (len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ && params->split_header_data == 0) {
		  int zeroresult = 0, xread;
		  unsigned char zerobyte = 0;

		  LIBMTP_INFO("Reading in zero packet after header\n");

		  zeroresult = USB_BULK_READ(ptp_usb->handle,
					     ptp_usb->inep,
					     &zerobyte,
					     0,
					     &xread,
					     ptp_usb->timeout);

		  if (zeroresult != 0)
		    LIBMTP_INFO("LIBMTP panic: unable to read in zero packet, response 0x%04x", zeroresult);
		}

		/* Is that all of data? */
		if (len+PTP_USB_BULK_HDR_LEN<=rlen) {
		  break;
		}

		ret = ptp_read_func(len - (rlen - PTP_USB_BULK_HDR_LEN),
				    handler,
				    params->data, &rlen, 1);

		if (ret != PTP_RC_OK) {
		  break;
		}
	} while (0);
	return ret;
}

uint16_t
ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
{
	uint16_t ret;
	unsigned long rlen;
	PTPUSBBulkContainer usbresp;
	PTP_USB *ptp_usb = (PTP_USB *)(params->data);


	LIBMTP_USB_DEBUG("RESPONSE: ");

	memset(&usbresp,0,sizeof(usbresp));
	/* read response, it should never be longer than sizeof(usbresp) */
	ret = ptp_usb_getpacket(params, &usbresp, &rlen);

	// Fix for bevahiour reported by Scott Snyder on Samsung YP-U3. The player
	// sends a packet containing just zeroes of length 2 (up to 4 has been seen too)
	// after a NULL packet when it should send the response. This code ignores
	// such illegal packets.
	while (ret==PTP_RC_OK && rlen<PTP_USB_BULK_HDR_LEN && usbresp.length==0) {
	  libusb_glue_debug (params, "ptp_usb_getresp: detected short response "
		     "of %d bytes, expect problems! (re-reading "
		     "response), rlen");
	  ret = ptp_usb_getpacket(params, &usbresp, &rlen);
	}

	if (ret != PTP_RC_OK) {
		ret = PTP_ERROR_IO;
	} else
	if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {
		ret = PTP_ERROR_RESP_EXPECTED;
	} else
	if (dtoh16(usbresp.code)!=resp->Code) {
		ret = dtoh16(usbresp.code);
	}

	LIBMTP_USB_DEBUG("%04x\n", ret);

	if (ret != PTP_RC_OK) {
/*		libusb_glue_error (params,
		"PTP: request code 0x%04x getting resp error 0x%04x",
			resp->Code, ret);*/
		return ret;
	}
	/* build an appropriate PTPContainer */
	resp->Code=dtoh16(usbresp.code);
	resp->SessionID=params->session_id;
	resp->Transaction_ID=dtoh32(usbresp.trans_id);
	if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
		if (resp->Transaction_ID != params->transaction_id-1) {
			libusb_glue_debug (params, "ptp_usb_getresp: detected a broken "
				   "PTP header, transaction ID insane, expect "
				   "problems! (But continuing)");
			// Repair the header, so it won't wreak more havoc.
			resp->Transaction_ID = params->transaction_id-1;
		}
	}
	resp->Param1=dtoh32(usbresp.payload.params.param1);
	resp->Param2=dtoh32(usbresp.payload.params.param2);
	resp->Param3=dtoh32(usbresp.payload.params.param3);
	resp->Param4=dtoh32(usbresp.payload.params.param4);
	resp->Param5=dtoh32(usbresp.payload.params.param5);
	return ret;
}

/* Event handling functions */

/* PTP Events wait for or check mode */
#define PTP_EVENT_CHECK			0x0000	/* waits for */
#define PTP_EVENT_CHECK_FAST		0x0001	/* checks */

static inline uint16_t
ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
{
	uint16_t ret;
	int result, xread;
	unsigned long rlen;
	PTPUSBEventContainer usbevent;
	PTP_USB *ptp_usb;

	memset(&usbevent,0,sizeof(usbevent));

	if ((params==NULL) || (event==NULL))
		return PTP_ERROR_BADPARAM;
	ptp_usb = (PTP_USB *)(params->data);

	ret = PTP_RC_OK;
	switch(wait) {
	case PTP_EVENT_CHECK:
                result = USB_BULK_READ(ptp_usb->handle,
				     ptp_usb->intep,
				     (unsigned char *) &usbevent,
				     sizeof(usbevent),
				     &xread,
				     0);
		if (xread == 0)
		  result = USB_BULK_READ(ptp_usb->handle,
					 ptp_usb->intep,
					 (unsigned char *) &usbevent,
					 sizeof(usbevent),
				         &xread,
					 0);
		if (result < 0) ret = PTP_ERROR_IO;
		break;
	case PTP_EVENT_CHECK_FAST:
                result = USB_BULK_READ(ptp_usb->handle,
				     ptp_usb->intep,
				     (unsigned char *) &usbevent,
				     sizeof(usbevent),
				     &xread,
				     ptp_usb->timeout);
		if (xread == 0)
		  result = USB_BULK_READ(ptp_usb->handle,
					 ptp_usb->intep,
					 (unsigned char *) &usbevent,
					 sizeof(usbevent),
				         &xread,
					 ptp_usb->timeout);
		if (result < 0) ret = PTP_ERROR_IO;
		break;
	default:
		ret = PTP_ERROR_BADPARAM;
		break;
	}
	if (ret != PTP_RC_OK) {
		libusb_glue_error (params,
			"PTP: reading event an error 0x%04x occurred", ret);
		return PTP_ERROR_IO;
	}
	rlen = xread;
	if (rlen < 8) {
		libusb_glue_error (params,
			"PTP: reading event an short read of %ld bytes occurred", rlen);
		return PTP_ERROR_IO;
	}
	/* if we read anything over interrupt endpoint it must be an event */
	/* build an appropriate PTPContainer */
	event->Code=dtoh16(usbevent.code);
	event->SessionID=params->session_id;
	event->Transaction_ID=dtoh32(usbevent.trans_id);
	event->Param1=dtoh32(usbevent.param1);
	event->Param2=dtoh32(usbevent.param2);
	event->Param3=dtoh32(usbevent.param3);
	return ret;
}

uint16_t
ptp_usb_event_check (PTPParams* params, PTPContainer* event) {

	return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);
}

uint16_t
ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {

	return ptp_usb_event (params, event, PTP_EVENT_CHECK);
}

uint16_t
ptp_usb_control_cancel_request (PTPParams *params, uint32_t transactionid) {
	PTP_USB *ptp_usb = (PTP_USB *)(params->data);
	int ret;
	unsigned char buffer[6];

	htod16a(&buffer[0],PTP_EC_CancelTransaction);
	htod32a(&buffer[2],transactionid);
	ret = libusb_control_transfer(ptp_usb->handle,
			      LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
                              0x64, 0x0000, 0x0000,
			      buffer,
			      sizeof(buffer),
			      ptp_usb->timeout);
	if (ret < sizeof(buffer))
		return PTP_ERROR_IO;
	return PTP_RC_OK;
}

static int init_ptp_usb(PTPParams* params, PTP_USB* ptp_usb, libusb_device* dev)
{
  libusb_device_handle *device_handle;
  unsigned char buf[255];
  int ret, usbresult;
  struct libusb_config_descriptor *config;

  params->sendreq_func=ptp_usb_sendreq;
  params->senddata_func=ptp_usb_senddata;
  params->getresp_func=ptp_usb_getresp;
  params->getdata_func=ptp_usb_getdata;
  params->cancelreq_func=ptp_usb_control_cancel_request;
  params->data=ptp_usb;
  params->transaction_id=0;
  /*
   * This is hardcoded here since we have no devices whatsoever that are BE.
   * Change this the day we run into our first BE device (if ever).
   */
  params->byteorder = PTP_DL_LE;

  ptp_usb->timeout = get_timeout(ptp_usb);

  ret = libusb_open(dev, &device_handle);
  if (ret != LIBUSB_SUCCESS) {
    perror("libusb_open() failed!");
    return -1;
  }
  ptp_usb->handle = device_handle;

  /*
   * If this device is known to be wrongfully claimed by other kernel
   * drivers (such as mass storage), then try to unload it to make it
   * accessible from user space.
   */
  if (FLAG_UNLOAD_DRIVER(ptp_usb) &&
      libusb_kernel_driver_active(device_handle, ptp_usb->interface)
  ) {
      if (LIBUSB_SUCCESS != libusb_detach_kernel_driver(device_handle, ptp_usb->interface)) {
	perror("libusb_detach_kernel_driver() failed, continuing anyway...");
      }
  }

  /*
   * Check if the config is set to something else than what we want
   * to use. Only set the configuration if we absolutely have to.
   * Also do not bail out if we fail.
   *
   * Note that Darwin will not set the configuration for vendor-specific
   * devices so we need to go in and set it.
   */
  ret = libusb_get_active_config_descriptor(dev, &config);
  if (ret != LIBUSB_SUCCESS) {
    perror("libusb_get_active_config_descriptor(1) failed");
    fprintf(stderr, "no active configuration, trying to set configuration\n");
    if (libusb_set_configuration(device_handle, ptp_usb->config) != LIBUSB_SUCCESS) {
      perror("libusb_set_configuration() failed, continuing anyway...");
    }
    ret = libusb_get_active_config_descriptor(dev, &config);
    if (ret != LIBUSB_SUCCESS) {
      perror("libusb_get_active_config_descriptor(2) failed");
      return -1;
    }
  }
  if (config->bConfigurationValue != ptp_usb->config) {
    fprintf(stderr, "desired configuration different from current, trying to set configuration\n");
    if (libusb_set_configuration(device_handle, ptp_usb->config)) {
      perror("libusb_set_configuration() failed, continuing anyway...");
    }
    /* Re-fetch the config descriptor if we changed */
    libusb_free_config_descriptor(config);
    ret = libusb_get_active_config_descriptor(dev, &config);
    if (ret != LIBUSB_SUCCESS) {
      perror("libusb_get_active_config_descriptor(2) failed");
      return -1;
    }
  }

  /*
   * It seems like on kernel 2.6.31 if we already have it open on another
   * pthread in our app, we'll get an error if we try to claim it again,
   * but that error is harmless because our process already claimed the interface
   */
  usbresult = libusb_claim_interface(device_handle, ptp_usb->interface);

  if (usbresult != 0)
    fprintf(stderr, "ignoring libusb_claim_interface() = %d", usbresult);

  /*
   * If the altsetting is set to something different than we want, switch
   * it.
   *
   * FIXME: this seems to cause trouble on the Mac:s so disable it. Retry
   * this on the Mac now that it only sets this when the altsetting differs.
   */
#ifndef __APPLE__
#if 0 /* Disable this always, no idea on how to handle it */
  if (config->interface[].altsetting[].bAlternateSetting !=
      ptp_usb->altsetting) {
    fprintf(stderr, "desired altsetting different from current, trying to set altsetting\n");
    usbresult = libusb_set_interface_alt_setting(device_handle,
						 ptp_usb->interface,
						 ptp_usb->altsetting);
    if (usbresult != 0)
      fprintf(stderr, "ignoring libusb_set_interface_alt_setting() = %d\n", usbresult);
  }
#endif
#endif

  libusb_free_config_descriptor(config);

  if (FLAG_SWITCH_MODE_BLACKBERRY(ptp_usb)) {
    int ret;

    // FIXME : Only for BlackBerry Storm
    // What does it mean? Maybe switch mode...
    // This first control message is absolutely necessary
    usleep(1000);
    ret = libusb_control_transfer(device_handle,
                          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
                          0xaa, 0x00, 0x04, buf, 0x40, 1000);
    LIBMTP_USB_DEBUG("BlackBerry magic part 1:\n");
    LIBMTP_USB_DATA(buf, ret, 16);

    usleep(1000);
    // This control message is unnecessary
    ret = libusb_control_transfer(device_handle,
                          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
                          0xa5, 0x00, 0x01, buf, 0x02, 1000);
    LIBMTP_USB_DEBUG("BlackBerry magic part 2:\n");
    LIBMTP_USB_DATA(buf, ret, 16);

    usleep(1000);
    // This control message is unnecessary
    ret = libusb_control_transfer(device_handle,
                          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
                          0xa8, 0x00, 0x01, buf, 0x05, 1000);
    LIBMTP_USB_DEBUG("BlackBerry magic part 3:\n");
    LIBMTP_USB_DATA(buf, ret, 16);

    usleep(1000);
    // This control message is unnecessary
    ret = libusb_control_transfer(device_handle,
                          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
                          0xa8, 0x00, 0x01, buf, 0x11, 1000);
    LIBMTP_USB_DEBUG("BlackBerry magic part 4:\n");
    LIBMTP_USB_DATA(buf, ret, 16);

    usleep(1000);
  }
  return 0;
}

static void clear_stall(PTP_USB* ptp_usb)
{
  uint16_t status;
  int ret;

  /* check the inep status */
  status = 0;
  ret = usb_get_endpoint_status(ptp_usb,ptp_usb->inep,&status);
  if (ret<0) {
    perror ("inep: usb_get_endpoint_status()");
  } else if (status) {
    LIBMTP_INFO("Clearing stall on IN endpoint\n");
    ret = libusb_clear_halt (ptp_usb->handle, ptp_usb->inep);
    if (ret != LIBUSB_SUCCESS) {
      perror ("usb_clear_stall_feature()");
    }
  }

  /* check the outep status */
  status=0;
  ret = usb_get_endpoint_status(ptp_usb,ptp_usb->outep,&status);
  if (ret<0) {
    perror("outep: usb_get_endpoint_status()");
  } else if (status) {
    LIBMTP_INFO("Clearing stall on OUT endpoint\n");
    ret = libusb_clear_halt(ptp_usb->handle, ptp_usb->outep);
    if (ret != LIBUSB_SUCCESS) {
      perror("usb_clear_stall_feature()");
    }
  }

  /* TODO: do we need this for INTERRUPT (ptp_usb->intep) too? */
}

static void close_usb(PTP_USB* ptp_usb)
{
  if (!FLAG_NO_RELEASE_INTERFACE(ptp_usb)) {
    /*
     * Clear any stalled endpoints
     * On misbehaving devices designed for Windows/Mac, quote from:
     * http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
     * Device does Bad Things(tm) when it gets a GET_STATUS after CLEAR_HALT
     * (...) Windows, when clearing a stall, only sends the CLEAR_HALT command,
     * and presumes that the stall has cleared.  Some devices actually choke
     * if the CLEAR_HALT is followed by a GET_STATUS (used to determine if the
     * STALL is persistant or not).
     */
    clear_stall(ptp_usb);
    libusb_release_interface(ptp_usb->handle, (int) ptp_usb->interface);
  }
  if (FLAG_FORCE_RESET_ON_CLOSE(ptp_usb)) {
    /*
     * Some devices really love to get reset after being
     * disconnected. Again, since Windows never disconnects
     * a device closing behaviour is seldom or never exercised
     * on devices when engineered and often error prone.
     * Reset may help some.
     */
    libusb_reset_device (ptp_usb->handle);
  }
  libusb_close(ptp_usb->handle);
}

/**
 * Self-explanatory?
 */
static int find_interface_and_endpoints(libusb_device *dev,
					uint8_t *conf,
					uint8_t *interface,
					uint8_t *altsetting,
					int* inep,
					int* inep_maxpacket,
					int* outep,
					int *outep_maxpacket,
					int* intep)
{
  uint8_t i, ret;
  struct libusb_device_descriptor desc;

  ret = libusb_get_device_descriptor(dev, &desc);
  if (ret != LIBUSB_SUCCESS)
    return -1;

  // Loop over the device configurations
  for (i = 0; i < desc.bNumConfigurations; i++) {
    uint8_t j;
    struct libusb_config_descriptor *config;

    ret = libusb_get_config_descriptor(dev, i, &config);
    if (ret != LIBUSB_SUCCESS)
      continue;

    *conf = config->bConfigurationValue;

    // Loop over each configurations interfaces
    for (j = 0; j < config->bNumInterfaces; j++) {
      uint8_t k, l;
      uint8_t no_ep;
      int found_inep = 0;
      int found_outep = 0;
      int found_intep = 0;
      const struct libusb_endpoint_descriptor *ep;

      // Inspect the altsettings of this interface...
      for (k = 0; k < config->interface[j].num_altsetting; k++) {

	// MTP devices shall have 3 endpoints, ignore those interfaces
	// that haven't.
	no_ep = config->interface[j].altsetting[k].bNumEndpoints;
	if (no_ep != 3)
	  continue;

	*interface = config->interface[j].altsetting[k].bInterfaceNumber;
	*altsetting = config->interface[j].altsetting[k].bAlternateSetting;
	ep = config->interface[j].altsetting[k].endpoint;

	// Loop over the three endpoints to locate two bulk and
	// one interrupt endpoint and FAIL if we cannot, and continue.
	for (l = 0; l < no_ep; l++) {
	  if (ep[l].bmAttributes == LIBUSB_TRANSFER_TYPE_BULK) {
	    if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
		LIBUSB_ENDPOINT_DIR_MASK) {
	      *inep = ep[l].bEndpointAddress;
	      *inep_maxpacket = ep[l].wMaxPacketSize;
	      found_inep = 1;
	    }
	    if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == 0) {
	      *outep = ep[l].bEndpointAddress;
	      *outep_maxpacket = ep[l].wMaxPacketSize;
	      found_outep = 1;
	    }
	  } else if (ep[l].bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT) {
	    if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
		LIBUSB_ENDPOINT_DIR_MASK) {
	      *intep = ep[l].bEndpointAddress;
	      found_intep = 1;
	    }
	  }
	}
	if (found_inep && found_outep && found_intep) {
	  libusb_free_config_descriptor(config);
	  // We assigned the endpoints so return here.
	  return 0;
	}
      } // Next altsetting
    } // Next interface
    libusb_free_config_descriptor(config);
  } // Next config
  return -1;
}

/**
 * This function assigns params and usbinfo given a raw device
 * as input.
 * @param device the device to be assigned.
 * @param usbinfo a pointer to the new usbinfo.
 * @return an error code.
 */
LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
					   PTPParams *params,
					   void **usbinfo)
{
  PTP_USB *ptp_usb;
  libusb_device *ldevice;
  uint16_t ret = 0;
  int err, found = 0, i;
  ssize_t nrofdevs;
  libusb_device **devs = NULL;
  struct libusb_device_descriptor desc;
  LIBMTP_error_number_t init_usb_ret;

  /* See if we can find this raw device again... */
  init_usb_ret = init_usb();
  if (init_usb_ret != LIBMTP_ERROR_NONE)
    return init_usb_ret;

  nrofdevs = libusb_get_device_list(NULL, &devs);
  for (i = 0; i < nrofdevs ; i++) {
    if (libusb_get_bus_number(devs[i]) != device->bus_location)
      continue;
    if (libusb_get_device_address(devs[i]) != device->devnum)
      continue;

    ret = libusb_get_device_descriptor(devs[i], &desc);
    if (ret != LIBUSB_SUCCESS) continue;

    if(desc.idVendor  == device->device_entry.vendor_id &&
       desc.idProduct == device->device_entry.product_id ) {
	  ldevice = devs[i];
	  found = 1;
	  break;
    }
  }
  /* Device has gone since detecting raw devices! */
  if (!found) {
    libusb_free_device_list (devs, 0);
    return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
  }

  /* Allocate structs */
  ptp_usb = (PTP_USB *) malloc(sizeof(PTP_USB));
  if (ptp_usb == NULL) {
    libusb_free_device_list (devs, 0);
    return LIBMTP_ERROR_MEMORY_ALLOCATION;
  }
  /* Start with a blank slate (includes setting device_flags to 0) */
  memset(ptp_usb, 0, sizeof(PTP_USB));

  /* Copy the raw device */
  memcpy(&ptp_usb->rawdevice, device, sizeof(LIBMTP_raw_device_t));

  /*
   * Some devices must have their "OS Descriptor" massaged in order
   * to work.
   */
  if (FLAG_ALWAYS_PROBE_DESCRIPTOR(ptp_usb)) {
    // Massage the device descriptor
    (void) probe_device_descriptor(ldevice, NULL);
  }

  /* Assign interface and endpoints to usbinfo... */
  err = find_interface_and_endpoints(ldevice,
				     &ptp_usb->config,
				     &ptp_usb->interface,
				     &ptp_usb->altsetting,
				     &ptp_usb->inep,
				     &ptp_usb->inep_maxpacket,
				     &ptp_usb->outep,
				     &ptp_usb->outep_maxpacket,
				     &ptp_usb->intep);

  if (err) {
    libusb_free_device_list (devs, 0);
    LIBMTP_ERROR("LIBMTP PANIC: Unable to find interface & endpoints of device\n");
    return LIBMTP_ERROR_CONNECTING;
  }

  /* Copy USB version number */
  ptp_usb->bcdusb = desc.bcdUSB;

  /* Attempt to initialize this device */
  if (init_ptp_usb(params, ptp_usb, ldevice) < 0) {
    LIBMTP_ERROR("LIBMTP PANIC: Unable to initialize device\n");
    libusb_free_device_list (devs, 0);
    return LIBMTP_ERROR_CONNECTING;
  }

  /*
   * This works in situations where previous bad applications
   * have not used LIBMTP_Release_Device on exit
   */
  if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
    LIBMTP_ERROR("PTP_ERROR_IO: failed to open session, trying again after resetting USB interface\n");
    LIBMTP_ERROR("LIBMTP libusb: Attempt to reset device\n");
    libusb_reset_device (ptp_usb->handle);
    close_usb(ptp_usb);

    if(init_ptp_usb(params, ptp_usb, ldevice) <0) {
      LIBMTP_ERROR("LIBMTP PANIC: Could not init USB on second attempt\n");
      libusb_free_device_list (devs, 0);
      return LIBMTP_ERROR_CONNECTING;
    }

    /* Device has been reset, try again */
    if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
      LIBMTP_ERROR("LIBMTP PANIC: failed to open session on second attempt\n");
      libusb_free_device_list (devs, 0);
      return LIBMTP_ERROR_CONNECTING;
    }
  }

  /* Was the transaction id invalid? Try again */
  if (ret == PTP_RC_InvalidTransactionID) {
    LIBMTP_ERROR("LIBMTP WARNING: Transaction ID was invalid, increment and try again\n");
    params->transaction_id += 10;
    ret = ptp_opensession(params, 1);
  }

  if (ret != PTP_RC_SessionAlreadyOpened && ret != PTP_RC_OK) {
    LIBMTP_ERROR("LIBMTP PANIC: Could not open session! "
	    "(Return code %d)\n  Try to reset the device.\n",
	    ret);
    libusb_release_interface(ptp_usb->handle, ptp_usb->interface);
    libusb_free_device_list (devs, 0);
    return LIBMTP_ERROR_CONNECTING;
  }

  /* OK configured properly */
  *usbinfo = (void *) ptp_usb;
  libusb_free_device_list (devs, 0);
  return LIBMTP_ERROR_NONE;
}


void close_device (PTP_USB *ptp_usb, PTPParams *params)
{
  if (ptp_closesession(params)!=PTP_RC_OK)
    LIBMTP_ERROR("ERROR: Could not close session!\n");
  close_usb(ptp_usb);
}

void set_usb_device_timeout(PTP_USB *ptp_usb, int timeout)
{
  ptp_usb->timeout = timeout;
}

void get_usb_device_timeout(PTP_USB *ptp_usb, int *timeout)
{
  *timeout = ptp_usb->timeout;
}

int guess_usb_speed(PTP_USB *ptp_usb)
{
  int bytes_per_second;

  /*
   * We don't know the actual speeds so these are rough guesses
   * from the info you can find here:
   * http://en.wikipedia.org/wiki/USB#Transfer_rates
   * http://www.barefeats.com/usb2.html
   */
  switch (ptp_usb->bcdusb & 0xFF00) {
  case 0x0100:
    /* 1.x USB versions let's say 1MiB/s */
    bytes_per_second = 1*1024*1024;
    break;
  case 0x0200:
  case 0x0300:
    /* USB 2.0 nominal speed 18MiB/s */
    /* USB 3.0 won't be worse? */
    bytes_per_second = 18*1024*1024;
    break;
  default:
    /* Half-guess something? */
    bytes_per_second = 1*1024*1024;
    break;
  }
  return bytes_per_second;
}

static int usb_get_endpoint_status(PTP_USB* ptp_usb, int ep, uint16_t* status)
{
  return libusb_control_transfer(ptp_usb->handle,
			  LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_ENDPOINT,
			  LIBUSB_REQUEST_GET_STATUS,
                          USB_FEATURE_HALT,
			  ep,
			  (unsigned char *) status,
			  2,
			  ptp_usb->timeout);
}
