/*
 * \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-2011 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 <usb.h>

#include "ptp-pack.c"

/* Aha, older libusb does not have USB_CLASS_PTP */
#ifndef USB_CLASS_PTP
#define USB_CLASS_PTP 6
#endif

/*
 * 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 {
    openusb_dev_handle_t 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 void init_usb();
static void close_usb(PTP_USB* ptp_usb);
static int find_interface_and_endpoints(openusb_dev_handle_t *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, openusb_dev_handle_t * 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);

// Local USB handles.
static openusb_handle_t libmtp_openusb_handle;

/**
 * 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 void init_usb() {
    openusb_init(NULL, &libmtp_openusb_handle);
}

/**
 * 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,
        openusb_dev_handle_t *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 libopenusb.
 * @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(openusb_dev_handle_t *dev, FILE *dumpfile) {
    openusb_dev_handle_t *devh = NULL;
    unsigned char buf[1024], cmd;
    uint8_t *bufptr = (uint8_t *) &buf;
    unsigned int buffersize = sizeof(buf);
    int i;
    int ret;
    /* This is to indicate if we find some vendor interface */
    int found_vendor_spec_interface = 0;
    struct usb_device_desc desc;
    struct usb_interface_desc ifcdesc;

    ret = openusb_parse_device_desc(libmtp_openusb_handle, *dev, NULL, 0, &desc);
    if (ret != OPENUSB_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 == USB_CLASS_PER_INTERFACE ||
            desc.bDeviceClass == USB_CLASS_COMM ||
            desc.bDeviceClass == USB_CLASS_PTP ||
            desc.bDeviceClass == 0xEF || /* Intf. Association Desc.*/
            desc.bDeviceClass == USB_CLASS_VENDOR_SPEC)) {
        return 0;
    }

    /* Attempt to open Device on this port */
    ret = openusb_open_device(libmtp_openusb_handle, NULL, USB_INIT_DEFAULT, devh);
    if (ret != OPENUSB_SUCCESS) {
        /* Could not open this device */
        return 0;
    }

    /*
     * This sometimes crashes on the j for loop below
     * I think it is because config is NULL yet
     * dev->descriptor.bNumConfigurations > 0
     * this check should stop this
     */
    /*
     * 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 usb_config_desc config;

        ret = openusb_parse_config_desc(libmtp_openusb_handle, *dev, NULL, 0, 0, &config);
        if (ret != OPENUSB_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 = 0;

            while (openusb_parse_interface_desc(libmtp_openusb_handle, *dev, NULL, 0, 0, j, k++, &ifcdesc) == 0) {
                /* Current interface descriptor */

                /*
                 * MTP interfaces have three endpoints, two bulk and one
                 * interrupt. Don't probe anything else.
                 */
                if (ifcdesc.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 (ifcdesc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
                    found_vendor_spec_interface = 1;
                }

                /*
                 * Check for Still Image Capture class with PIMA 15740 protocol,
                 * also known as PTP
                 */

                /*
                 * Next we search for the MTP substring in the interface name.
                 * For example : "RIM MS/MTP" should work.
                 */
                buf[0] = '\0';
                // FIXME: DK: Find out how to get the string descriptor for an interface?
                /*
                                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);
                    openusb_close_device(*devh);
                    return 1;
                }
            }
        }
    }

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

        /* Read the special descriptor */
        //ret = libusb_get_descriptor(devh, 0x03, 0xee, buf, sizeof (buf));
        ret = openusb_get_raw_desc(libmtp_openusb_handle, *dev, USB_DESC_TYPE_STRING, 0xee, 0, &bufptr, (unsigned short *)&buffersize);
        /*
         * 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);
            openusb_close_device(*devh);
            openusb_free_raw_desc(buf);
            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) {
            openusb_close_device(*devh);
            openusb_free_raw_desc(buf);
            return 0;
        }

        /* Check if this device has a Microsoft Descriptor */
        if (!((buf[2] == 'M') && (buf[4] == 'S') &&
                (buf[6] == 'F') && (buf[8] == 'T'))) {
            openusb_close_device(*devh);
            openusb_free_raw_desc(buf);
            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);
         */
        struct openusb_ctrl_request ctrl;
        ctrl.setup.bmRequestType = USB_ENDPOINT_IN | USB_RECIP_DEVICE | USB_REQ_TYPE_VENDOR;
        ctrl.setup.bRequest = cmd;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 4;
        ctrl.payload = bufptr; // Out
        ctrl.length = sizeof (buf);
        ctrl.timeout = USB_TIMEOUT_DEFAULT;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(*devh, 0, USB_ENDPOINT_IN, &ctrl);


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

        /* If this is true, the device either isn't MTP or there was an error */
        if (ctrl.result.transferred_bytes <= 0x15) {
            /* TODO: If there was an error, flag it and let the user know somehow */
            /* if(ret == -1) {} */
            openusb_close_device(*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')) {
            openusb_close_device(*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);
         */
        //struct openusb_ctrl_request ctrl;
        ctrl.setup.bmRequestType = USB_ENDPOINT_IN | USB_RECIP_DEVICE | USB_REQ_TYPE_VENDOR;
        ctrl.setup.bRequest = cmd;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 5;
        ctrl.payload = bufptr; // Out
        ctrl.length = sizeof (buf);
        ctrl.timeout = USB_TIMEOUT_DEFAULT;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(*devh, 0, USB_ENDPOINT_IN, &ctrl);

        // Dump it, if requested
        if (dumpfile != NULL && ctrl.result.transferred_bytes > 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 (ctrl.result.transferred_bytes < 0) {
            /* 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 && ctrl.result.transferred_bytes == 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 */
        openusb_close_device(*devh);
        return 1;
    }

    /* Close the USB device handle */
    openusb_close_device(*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) {
    int nrofdevs = 0;
    openusb_devid_t *devs = NULL;
    struct usb_device_desc desc;
    int ret, i;

    init_usb();
    ret = openusb_get_devids_by_bus(libmtp_openusb_handle, 0, &devs, &nrofdevs);


    for (i = 0; i < nrofdevs; i++) {
        openusb_devid_t dev = devs[i];

        ret = openusb_parse_device_desc(libmtp_openusb_handle, dev, NULL, 0, &desc);
        if (ret != OPENUSB_SUCCESS) continue;
        
        if (desc.bDeviceClass != USB_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, 0);
                    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, 0);
            //    }
                /*
                 * 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);
                  }
                }
                 */
            //}
        }
    }

    /* 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) {
    unsigned int nrofdevs;
    openusb_devid_t **devs = NULL;
    int i;

    init_usb();

    openusb_get_devids_by_bus(libmtp_openusb_handle, 0, devs, &nrofdevs);
    for (i = 0; i < nrofdevs; i++) {
        /*
            if (bus->location != busno)
              continue;
            if (dev->devnum != 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 usb_device_desc desc;

        openusb_parse_device_desc(libmtp_openusb_handle, dev->device, NULL, 0, &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 = 0;
        retdevs[i].devnum = openusb_get_devid(libmtp_openusb_handle, &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) {
    struct usb_device_desc desc;

    openusb_parse_device_desc(libmtp_openusb_handle, *ptp_usb->handle, NULL, 0, &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);
    // TODO: (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) {
    static char creative_pl_extension[] = ".zpl";
    static char default_pl_extension[] = ".pla";
    struct usb_device_desc desc;
    openusb_parse_device_desc(libmtp_openusb_handle, *ptp_usb->handle, NULL, 0, &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;
	    }
    }
    struct openusb_bulk_request bulk;
    // 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);
         */
        bulk.payload = bytes;
        bulk.length = toread;
        bulk.timeout = ptp_usb->timeout;
        bulk.flags = 0;
        bulk.next = NULL;
        ret = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->inep, &bulk);
        xread = bulk.result.transferred_bytes;
        LIBMTP_USB_DEBUG("Result of read: 0x%04x (%d bytes)\n", ret, xread);

        if (ret != OPENUSB_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);
        LIBMTP_USB_DEBUG("handler->putfunc ret = 0x%x\n", putfunc_ret);
        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);
    LIBMTP_USB_DEBUG("Pointer Updated\n");
    // 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);
         */
        bulk.payload = &temp;
        bulk.length = 0;
        bulk.timeout = ptp_usb->timeout;
        bulk.flags = 0;
        bulk.next = NULL;
        ret = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->inep, &bulk);
        xread = bulk.result.transferred_bytes;
        if (zeroresult != OPENUSB_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;

    struct openusb_bulk_request bulk;

    // 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;

        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)
            return getfunc_ret;
        while (usbwritten < towrite) {
            /*
                        ret = USB_BULK_WRITE(ptp_usb->handle,
                                ptp_usb->outep,
                                bytes + usbwritten,
                                towrite - usbwritten,
                                &xwritten,
                                ptp_usb->timeout);
             */
            bulk.payload = bytes + usbwritten;
            bulk.length = towrite - usbwritten;
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            ret = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->outep, &bulk);
            xwritten = bulk.result.transferred_bytes;

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

            if (ret != OPENUSB_SUCCESS) {
                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) {
                    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);
             */
            bulk.payload = (unsigned char *) "x";
            bulk.length = 0;
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            ret = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->outep, &bulk);
            xwritten = bulk.result.transferred_bytes;
        }
    }

    if (ret != OPENUSB_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
        ) {
    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;
    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, int dataphase) {
    uint16_t ret;
    PTPUSBBulkContainer usbreq;
    PTPDataHandler memhandler;
    unsigned long written = 0;
    unsigned long towrite;

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

    /* 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;
    unsigned long packet_size;
    PTP_USB *ptp_usb = (PTP_USB *) params->data;

    packet_size = ptp_usb->outep_maxpacket;

    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) {
	unsigned long max_long_transfer = ULONG_MAX + 1 - packet_size;
	ret = ptp_write_func (bytes_left_to_transfer > max_long_transfer ? max_long_transfer : 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");

    struct openusb_bulk_request bulk;

    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->inep_maxpacket) {
            /* Copy first part of data to 'data' */
            putfunc_ret =
                    handler->putfunc(
                    params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data
                    );
            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
                );
        if (putfunc_ret != PTP_RC_OK)
            return putfunc_ret;

        if (FLAG_NO_ZERO_READS(ptp_usb) &&
                len + PTP_USB_BULK_HDR_LEN == ptp_usb->inep_maxpacket) {

            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);
             */

            bulk.payload = &byte;
            bulk.length = 1;
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            result = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->inep, &bulk);
            xread = bulk.result.transferred_bytes;

            if (result != 1)
                LIBMTP_INFO("Could not read in extra byte for %d bytes long file, return value 0x%04x\n", ptp_usb->inep_maxpacket, result);
        } else if (len + PTP_USB_BULK_HDR_LEN == ptp_usb->inep_maxpacket && 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);
             */

            bulk.payload = &zerobyte;
            bulk.length = 0;
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            zeroresult = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->inep, &bulk);
            xread = bulk.result.transferred_bytes;

            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 = (PTP_USB *) (params->data);

    struct openusb_bulk_request bulk;

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

    if ((params == NULL) || (event == NULL))
        return PTP_ERROR_BADPARAM;
    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);
             */
            bulk.payload = (unsigned char *) &usbevent;
            bulk.length = sizeof (usbevent);
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            result = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->intep, &bulk);
            xread = bulk.result.transferred_bytes;

            if (result == 0) {
                /*
                                result = USB_BULK_READ(ptp_usb->handle,
                                    ptp_usb->intep,
                                    (unsigned char *) &usbevent,
                                    sizeof (usbevent),
                                    &xread,
                                    0);
                 */
                bulk.payload = (unsigned char *) &usbevent;
                bulk.length = sizeof (usbevent);
                bulk.timeout = ptp_usb->timeout;
                bulk.flags = 0;
                bulk.next = NULL;
                result = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->intep, &bulk);
                xread = bulk.result.transferred_bytes;
            }
            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);
             */
            bulk.payload = (unsigned char *) &usbevent;
            bulk.length = sizeof (usbevent);
            bulk.timeout = ptp_usb->timeout;
            bulk.flags = 0;
            bulk.next = NULL;
            result = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->intep, &bulk);
            xread = bulk.result.transferred_bytes;

            if (result == 0) {
                /*
                                result = USB_BULK_READ(ptp_usb->handle,
                                        ptp_usb->intep,
                                        (unsigned char *) &usbevent,
                                        sizeof (usbevent),
                                        &xread,
                                        ptp_usb->timeout);
                 */
                bulk.payload = (unsigned char *) &usbevent;
                bulk.length = sizeof (usbevent);
                bulk.timeout = ptp_usb->timeout;
                bulk.flags = 0;
                bulk.next = NULL;
                result = openusb_bulk_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->intep, &bulk);
                xread = bulk.result.transferred_bytes;
            }
            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 = result;
    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_event_async (PTPParams* params, PTPEventCbFn cb, void *user_data) {
	/* Unsupported */
	return PTP_ERROR_CANCEL;
}

int LIBMTP_Handle_Events_Timeout_Completed(struct timeval *tv, int *completed) {
	/* Unsupported */
	return -12;
}

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);
     */
    struct openusb_ctrl_request ctrl;
    ctrl.setup.bmRequestType = USB_REQ_TYPE_CLASS | USB_RECIP_INTERFACE;
    ctrl.setup.bRequest = 0x64;
    ctrl.setup.wValue = 0;
    ctrl.setup.wIndex = 0;
    ctrl.payload = (unsigned char *)&buffer; // Out
    ctrl.length = sizeof (buffer);
    ctrl.timeout = ptp_usb->timeout;
    ctrl.next = NULL;
    ctrl.flags = 0;

    ret = openusb_ctrl_xfer(*ptp_usb->handle, ptp_usb->interface, ptp_usb->outep, &ctrl);
    if (ctrl.result.transferred_bytes < sizeof (buffer))
        return PTP_ERROR_IO;
    return PTP_RC_OK;
}

static int init_ptp_usb(PTPParams* params, PTP_USB* ptp_usb, openusb_dev_handle_t* dev) {
    openusb_dev_handle_t device_handle;
    unsigned char buf[255];
    int ret, usbresult;

    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 = openusb_open_device(libmtp_openusb_handle, *dev, USB_INIT_DEFAULT, &device_handle);
    if (ret != OPENUSB_SUCCESS) {
        perror("usb_open()");
        return -1;
    }
    ptp_usb->handle = malloc(sizeof(openusb_dev_handle_t));
    *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.
     * Note: OpenUSB doesn't support this type of operation?
     */
    /*
      if (FLAG_UNLOAD_DRIVER(ptp_usb) &&
          libusb_kernel_driver_active (device_handle, ptp_usb->interface)
      ) {
          if (OPENUSB_SUCCESS != libusb_detach_kernel_driver (device_handle, ptp_usb->interface)) {
            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 = openusb_claim_interface(device_handle, ptp_usb->interface, USB_INIT_DEFAULT);

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

    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);
         */
        struct openusb_ctrl_request ctrl;
        ctrl.setup.bmRequestType = USB_REQ_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
        ctrl.setup.bRequest = 0xaa;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 4;
        ctrl.payload = (unsigned char *)&buf; // Out
        ctrl.length = 0x40;
        ctrl.timeout = 1000;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(device_handle, ptp_usb->interface, ptp_usb->outep, &ctrl);
        LIBMTP_USB_DEBUG("BlackBerry magic part 1:\n");
        LIBMTP_USB_DATA(buf, ctrl.result.transferred_bytes, 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);
         */
        ctrl.setup.bmRequestType = USB_REQ_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
        ctrl.setup.bRequest = 0xa5;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 1;
        ctrl.payload = (unsigned char *)&buf; // Out
        ctrl.length = 0x02;
        ctrl.timeout = 1000;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(device_handle, ptp_usb->interface, ptp_usb->outep, &ctrl);
        LIBMTP_USB_DEBUG("BlackBerry magic part 2:\n");
        LIBMTP_USB_DATA(buf, ctrl.result.transferred_bytes, 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);
         */
        ctrl.setup.bmRequestType = USB_REQ_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
        ctrl.setup.bRequest = 0xa8;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 1;
        ctrl.payload = (unsigned char *)&buf; // Out
        ctrl.length = 0x05;
        ctrl.timeout = 1000;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(device_handle, ptp_usb->interface, ptp_usb->outep, &ctrl);
        LIBMTP_USB_DEBUG("BlackBerry magic part 3:\n");
        LIBMTP_USB_DATA(buf, ctrl.result.transferred_bytes, 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);
         */
        ctrl.setup.bmRequestType = USB_REQ_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
        ctrl.setup.bRequest = 0xa8;
        ctrl.setup.wValue = 0;
        ctrl.setup.wIndex = 1;
        ctrl.payload = (unsigned char *)&buf; // Out
        ctrl.length = 0x11;
        ctrl.timeout = 1000;
        ctrl.next = NULL;
        ctrl.flags = 0;

        ret = openusb_ctrl_xfer(device_handle, ptp_usb->interface, ptp_usb->outep, &ctrl);
        LIBMTP_USB_DEBUG("BlackBerry magic part 4:\n");
        LIBMTP_USB_DATA(buf, ctrl.result.transferred_bytes, 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 != OPENUSB_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 != OPENUSB_SUCCESS) {
            perror("usb_clear_stall_feature()");
        }
    }
     */

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

static void clear_halt(PTP_USB* ptp_usb) {
    int ret;

    /*
        ret = libusb_clear_halt(ptp_usb->handle, ptp_usb->inep);
        if (ret < 0) {
            perror("usb_clear_halt() on IN endpoint");
        }
        ret = libusb_clear_halt(ptp_usb->handle, ptp_usb->outep);
        if (ret < 0) {
            perror("usb_clear_halt() on OUT endpoint");
        }
        ret = libusb_clear_halt(ptp_usb->handle, ptp_usb->intep);
        if (ret < 0) {
            perror("usb_clear_halt() on INTERRUPT endpoint");
        }
     */
}

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);
        // Clear halts on any endpoints
        clear_halt(ptp_usb);
        // Added to clear some stuff on the OUT endpoint
        // TODO: is this good on the Mac too?
        // HINT: some devices may need that you comment these two out too.
        //libusb_clear_halt(ptp_usb->handle, ptp_usb->outep);
        //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.
         */
        openusb_reset(*ptp_usb->handle);
    }
    openusb_close_device(*ptp_usb->handle);
}

/**
 * Self-explanatory?
 */
static int find_interface_and_endpoints(openusb_dev_handle_t *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;
    int ret;
    struct usb_device_desc desc;

    ret = openusb_parse_device_desc(libmtp_openusb_handle, *dev, NULL, 0, &desc);
    if (ret != OPENUSB_SUCCESS) return -1;

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

        ret = openusb_parse_config_desc(libmtp_openusb_handle, *dev, NULL, 0, i, &config);
        if (ret != OPENUSB_SUCCESS) continue;
	*conf = desc.bConfigurationValue;
        // Loop over each configurations interfaces
        for (j = 0; j < config.bNumInterfaces; j++) {
            uint8_t k;
            uint8_t no_ep;
            int found_inep = 0;
            int found_outep = 0;
            int found_intep = 0;
            struct usb_endpoint_desc ep;
            struct usb_interface_desc ifcdesc;
            openusb_parse_interface_desc(libmtp_openusb_handle, *dev, NULL, 0, i, j, 0, &ifcdesc);
            // MTP devices shall have 3 endpoints, ignore those interfaces
            // that haven't.
            no_ep = ifcdesc.bNumEndpoints;
            if (no_ep != 3)
                continue;
            *interface = ifcdesc.bInterfaceNumber;
	    *altsetting = ifcdesc.bAlternateSetting;
            // Loop over the three endpoints to locate two bulk and
            // one interrupt endpoint and FAIL if we cannot, and continue.
            for (k = 0; k < no_ep; k++) {
                openusb_parse_endpoint_desc(libmtp_openusb_handle, *dev, NULL, 0, i, j, 0, k, &ep);
                if (ep.bmAttributes == USB_ENDPOINT_TYPE_BULK) {
                    if ((ep.bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                            USB_ENDPOINT_DIR_MASK) {
                        *inep = ep.bEndpointAddress;
                        *inep_maxpacket = ep.wMaxPacketSize;
                        found_inep = 1;
                    }
                    if ((ep.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 0) {
                        *outep = ep.bEndpointAddress;
                        *outep_maxpacket = ep.wMaxPacketSize;
                        found_outep = 1;
                    }
                } else if (ep.bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT) {
                    if ((ep.bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
                            USB_ENDPOINT_DIR_MASK) {
                        *intep = ep.bEndpointAddress;
                        found_intep = 1;
                    }
                }
            }
            if (found_inep && found_outep && found_intep) {
                // We assigned the endpoints so return here.
                return 0;
            }
            // Else loop to next interface/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;
    openusb_devid_t *ldevice;
    uint16_t ret = 0;
    int err, found = 0, i;
    unsigned int nrofdevs;
    openusb_devid_t *devs = NULL;
    struct usb_device_desc desc;

    /* See if we can find this raw device again... */
    init_usb();

    openusb_get_devids_by_bus(libmtp_openusb_handle, 0, &devs, &nrofdevs);
    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 = openusb_parse_device_desc(libmtp_openusb_handle, devs[i], NULL, 0, &desc);
        if (ret != OPENUSB_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) {
        openusb_free_devid_list(devs);
        return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
    }

    /* Allocate structs */
    ptp_usb = (PTP_USB *) malloc(sizeof (PTP_USB));
    if (ptp_usb == NULL) {
        openusb_free_devid_list(devs);
        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->conf,
            &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) {
        openusb_free_devid_list(devs);
        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");
        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");
        openusb_reset(*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");
            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");
            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);
        openusb_release_interface(*ptp_usb->handle, ptp_usb->interface);
        return LIBMTP_ERROR_CONNECTING;
    }

    /* OK configured properly */
    *usbinfo = (void *) ptp_usb;
    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);
     */
    struct openusb_ctrl_request ctrl;
    ctrl.flags = 0;
    ctrl.length = 2;
    ctrl.payload = (unsigned char *)status;
    ctrl.timeout = ptp_usb->timeout;
    ctrl.next = NULL;
    ctrl.setup.bRequest = USB_REQ_GET_STATUS;
    ctrl.setup.bmRequestType = USB_ENDPOINT_IN | USB_RECIP_ENDPOINT;
    ctrl.setup.wIndex = ep;
    ctrl.setup.wValue = USB_FEATURE_HALT;
    openusb_ctrl_xfer(*ptp_usb->handle, ptp_usb->interface, ep, &ctrl);
    return ctrl.result.status;

}
