/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
// #define DEBUG 1
#if DEBUG
#ifdef USE_LIBLOG
#define LOG_TAG "usbhost"
#include "log/log.h"
#define D ALOGD
#else
#define D printf
#endif
#else
#define D(...)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/inotify.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <poll.h>
#include <pthread.h>
#include <linux/usbdevice_fs.h>
#include <asm/byteorder.h>
#include "usbhost/usbhost.h"
#define DEV_DIR             "/dev"
#define DEV_BUS_DIR         DEV_DIR "/bus"
#define USB_FS_DIR          DEV_BUS_DIR "/usb"
#define USB_FS_ID_SCANNER   USB_FS_DIR "/%d/%d"
#define USB_FS_ID_FORMAT    USB_FS_DIR "/%03d/%03d"
// Some devices fail to send string descriptors if we attempt reading > 255 bytes
#define MAX_STRING_DESCRIPTOR_LENGTH    255
#define MAX_USBFS_WD_COUNT      10
struct usb_host_context {
    int                         fd;
    usb_device_added_cb         cb_added;
    usb_device_removed_cb       cb_removed;
    void                        *data;
    int                         wds[MAX_USBFS_WD_COUNT];
    int                         wdd;
    int                         wddbus;
};
#define MAX_DESCRIPTORS_LENGTH 4096
struct usb_device {
    char dev_name[64];
    unsigned char desc[MAX_DESCRIPTORS_LENGTH];
    int desc_length;
    int fd;
    int writeable;
};
static inline int badname(const char *name)
{
    while(*name) {
        if(!isdigit(*name++)) return 1;
    }
    return 0;
}
static int find_existing_devices_bus(char *busname,
                                     usb_device_added_cb added_cb,
                                     void *client_data)
{
    char devname[32];
    DIR *devdir;
    struct dirent *de;
    int done = 0;
    devdir = opendir(busname);
    if(devdir == 0) return 0;
    while ((de = readdir(devdir)) && !done) {
        if(badname(de->d_name)) continue;
        snprintf(devname, sizeof(devname), "%s/%s", busname, de->d_name);
        done = added_cb(devname, client_data);
    } // end of devdir while
    closedir(devdir);
    return done;
}
/* returns true if one of the callbacks indicates we are done */
static int find_existing_devices(usb_device_added_cb added_cb,
                                  void *client_data)
{
    char busname[32];
    DIR *busdir;
    struct dirent *de;
    int done = 0;
    busdir = opendir(USB_FS_DIR);
    if(busdir == 0) return 0;
    while ((de = readdir(busdir)) != 0 && !done) {
        if(badname(de->d_name)) continue;
        snprintf(busname, sizeof(busname), USB_FS_DIR "/%s", de->d_name);
        done = find_existing_devices_bus(busname, added_cb,
                                         client_data);
    } //end of busdir while
    closedir(busdir);
    return done;
}
static void watch_existing_subdirs(struct usb_host_context *context,
                                   int *wds, int wd_count)
{
    char path[100];
    int i, ret;
    wds[0] = inotify_add_watch(context->fd, USB_FS_DIR, IN_CREATE | IN_DELETE);
    if (wds[0] < 0)
        return;
    /* watch existing subdirectories of USB_FS_DIR */
    for (i = 1; i < wd_count; i++) {
        snprintf(path, sizeof(path), USB_FS_DIR "/%03d", i);
        ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
        if (ret >= 0)
            wds[i] = ret;
    }
}
struct usb_host_context *usb_host_init()
{
    struct usb_host_context *context = calloc(1, sizeof(struct usb_host_context));
    if (!context) {
        fprintf(stderr, "out of memory in usb_host_context\n");
        return NULL;
    }
    context->fd = inotify_init();
    if (context->fd < 0) {
        fprintf(stderr, "inotify_init failed\n");
        free(context);
        return NULL;
    }
    return context;
}
void usb_host_cleanup(struct usb_host_context *context)
{
    close(context->fd);
    free(context);
}
int usb_host_get_fd(struct usb_host_context *context)
{
    return context->fd;
} /* usb_host_get_fd() */
int usb_host_load(struct usb_host_context *context,
                  usb_device_added_cb added_cb,
                  usb_device_removed_cb removed_cb,
                  usb_discovery_done_cb discovery_done_cb,
                  void *client_data)
{
    int done = 0;
    int i;
    context->cb_added = added_cb;
    context->cb_removed = removed_cb;
    context->data = client_data;
    D("Created device discovery thread\n");
    /* watch for files added and deleted within USB_FS_DIR */
    context->wddbus = -1;
    for (i = 0; i < MAX_USBFS_WD_COUNT; i++)
        context->wds[i] = -1;
    /* watch the root for new subdirectories */
    context->wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE);
    if (context->wdd < 0) {
        fprintf(stderr, "inotify_add_watch failed\n");
        if (discovery_done_cb)
            discovery_done_cb(client_data);
        return done;
    }
    watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
    /* check for existing devices first, after we have inotify set up */
    done = find_existing_devices(added_cb, client_data);
    if (discovery_done_cb)
        done |= discovery_done_cb(client_data);
    return done;
} /* usb_host_load() */
int usb_host_read_event(struct usb_host_context *context)
{
    struct inotify_event* event;
    char event_buf[512];
    char path[100];
    int i, ret, done = 0;
    int offset = 0;
    int wd;
    ret = read(context->fd, event_buf, sizeof(event_buf));
    if (ret >= (int)sizeof(struct inotify_event)) {
        while (offset < ret && !done) {
            event = (struct inotify_event*)&event_buf[offset];
            done = 0;
            wd = event->wd;
            if (wd == context->wdd) {
                if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
                    context->wddbus = inotify_add_watch(context->fd, DEV_BUS_DIR, IN_CREATE | IN_DELETE);
                    if (context->wddbus < 0) {
                        done = 1;
                    } else {
                        watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
                        done = find_existing_devices(context->cb_added, context->data);
                    }
                }
            } else if (wd == context->wddbus) {
                if ((event->mask & IN_CREATE) && !strcmp(event->name, "usb")) {
                    watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
                    done = find_existing_devices(context->cb_added, context->data);
                } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "usb")) {
                    for (i = 0; i < MAX_USBFS_WD_COUNT; i++) {
                        if (context->wds[i] >= 0) {
                            inotify_rm_watch(context->fd, context->wds[i]);
                            context->wds[i] = -1;
                        }
                    }
                }
            } else if (wd == context->wds[0]) {
                i = atoi(event->name);
                snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name);
                D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
                        "new" : "gone", path, i);
                if (i > 0 && i < MAX_USBFS_WD_COUNT) {
                    int local_ret = 0;
                    if (event->mask & IN_CREATE) {
                        local_ret = inotify_add_watch(context->fd, path,
                                IN_CREATE | IN_DELETE);
                        if (local_ret >= 0)
                            context->wds[i] = local_ret;
                        done = find_existing_devices_bus(path, context->cb_added,
                                context->data);
                    } else if (event->mask & IN_DELETE) {
                        inotify_rm_watch(context->fd, context->wds[i]);
                        context->wds[i] = -1;
                    }
                }
            } else {
                for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) {
                    if (wd == context->wds[i]) {
                        snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name);
                        if (event->mask == IN_CREATE) {
                            D("new device %s\n", path);
                            done = context->cb_added(path, context->data);
                        } else if (event->mask == IN_DELETE) {
                            D("gone device %s\n", path);
                            done = context->cb_removed(path, context->data);
                        }
                    }
                }
            }
            offset += sizeof(struct inotify_event) + event->len;
        }
    }
    return done;
} /* usb_host_read_event() */
void usb_host_run(struct usb_host_context *context,
                  usb_device_added_cb added_cb,
                  usb_device_removed_cb removed_cb,
                  usb_discovery_done_cb discovery_done_cb,
                  void *client_data)
{
    int done;
    done = usb_host_load(context, added_cb, removed_cb, discovery_done_cb, client_data);
    while (!done) {
        done = usb_host_read_event(context);
    }
} /* usb_host_run() */
struct usb_device *usb_device_open(const char *dev_name)
{
    int fd, attempts, writeable = 1;
    const int SLEEP_BETWEEN_ATTEMPTS_US = 100000; /* 100 ms */
    const int64_t MAX_ATTEMPTS = 10;              /* 1s */
    D("usb_device_open %s\n", dev_name);
    /* Hack around waiting for permissions to be set on the USB device node.
     * Should really be a timeout instead of attempt count, and should REALLY
     * be triggered by the perm change via inotify rather than polling.
     */
    for (attempts = 0; attempts < MAX_ATTEMPTS; ++attempts) {
        if (access(dev_name, R_OK | W_OK) == 0) {
            writeable = 1;
            break;
        } else {
            if (access(dev_name, R_OK) == 0) {
                /* double check that write permission didn't just come along too! */
                writeable = (access(dev_name, R_OK | W_OK) == 0);
                break;
            }
        }
        /* not writeable or readable - sleep and try again. */
        D("usb_device_open no access sleeping\n");
        usleep(SLEEP_BETWEEN_ATTEMPTS_US);
    }
    if (writeable) {
        fd = open(dev_name, O_RDWR);
    } else {
        fd = open(dev_name, O_RDONLY);
    }
    D("usb_device_open open returned %d writeable %d errno %d\n", fd, writeable, errno);
    if (fd < 0) return NULL;
    struct usb_device* result = usb_device_new(dev_name, fd);
    if (result)
        result->writeable = writeable;
    return result;
}
void usb_device_close(struct usb_device *device)
{
    close(device->fd);
    free(device);
}
struct usb_device *usb_device_new(const char *dev_name, int fd)
{
    struct usb_device *device = calloc(1, sizeof(struct usb_device));
    int length;
    D("usb_device_new %s fd: %d\n", dev_name, fd);
    if (lseek(fd, 0, SEEK_SET) != 0)
        goto failed;
    length = read(fd, device->desc, sizeof(device->desc));
    D("usb_device_new read returned %d errno %d\n", length, errno);
    if (length < 0)
        goto failed;
    strncpy(device->dev_name, dev_name, sizeof(device->dev_name) - 1);
    device->fd = fd;
    device->desc_length = length;
    // assume we are writeable, since usb_device_get_fd will only return writeable fds
    device->writeable = 1;
    return device;
failed:
    // TODO It would be more appropriate to have callers do this
    // since this function doesn't "own" this file descriptor.
    close(fd);
    free(device);
    return NULL;
}
static int usb_device_reopen_writeable(struct usb_device *device)
{
    if (device->writeable)
        return 1;
    int fd = open(device->dev_name, O_RDWR);
    if (fd >= 0) {
        close(device->fd);
        device->fd = fd;
        device->writeable = 1;
        return 1;
    }
    D("usb_device_reopen_writeable failed errno %d\n", errno);
    return 0;
}
int usb_device_get_fd(struct usb_device *device)
{
    if (!usb_device_reopen_writeable(device))
        return -1;
    return device->fd;
}
const char* usb_device_get_name(struct usb_device *device)
{
    return device->dev_name;
}
int usb_device_get_unique_id(struct usb_device *device)
{
    int bus = 0, dev = 0;
    sscanf(device->dev_name, USB_FS_ID_SCANNER, &bus, &dev);
    return bus * 1000 + dev;
}
int usb_device_get_unique_id_from_name(const char* name)
{
    int bus = 0, dev = 0;
    sscanf(name, USB_FS_ID_SCANNER, &bus, &dev);
    return bus * 1000 + dev;
}
char* usb_device_get_name_from_unique_id(int id)
{
    int bus = id / 1000;
    int dev = id % 1000;
    char* result = (char *)calloc(1, strlen(USB_FS_ID_FORMAT));
    snprintf(result, strlen(USB_FS_ID_FORMAT) - 1, USB_FS_ID_FORMAT, bus, dev);
    return result;
}
uint16_t usb_device_get_vendor_id(struct usb_device *device)
{
    struct usb_device_descriptor* desc = (struct usb_device_descriptor*)device->desc;
    return __le16_to_cpu(desc->idVendor);
}
uint16_t usb_device_get_product_id(struct usb_device *device)
{
    struct usb_device_descriptor* desc = (struct usb_device_descriptor*)device->desc;
    return __le16_to_cpu(desc->idProduct);
}
const struct usb_device_descriptor* usb_device_get_device_descriptor(struct usb_device* device) {
    return (struct usb_device_descriptor*)device->desc;
}
size_t usb_device_get_descriptors_length(const struct usb_device* device) {
    return device->desc_length;
}
const unsigned char* usb_device_get_raw_descriptors(const struct usb_device* device) {
    return device->desc;
}
/* Returns a USB descriptor string for the given string ID.
 * Return value: < 0 on error.  0 on success.
 * The string is returned in ucs2_out in USB-native UCS-2 encoding.
 *
 * parameters:
 *  id - the string descriptor index.
 *  timeout - in milliseconds (see Documentation/driver-api/usb/usb.rst)
 *  ucs2_out - Must point to null on call.
 *             Will be filled in with a buffer on success.
 *             If this is non-null on return, it must be free()d.
 *  response_size - size, in bytes, of ucs-2 string in ucs2_out.
 *                  The size isn't guaranteed to include null termination.
 * Call free() to free the result when you are done with it.
 */
int usb_device_get_string_ucs2(struct usb_device* device, int id, int timeout, void** ucs2_out,
                               size_t* response_size) {
    __u16 languages[MAX_STRING_DESCRIPTOR_LENGTH / sizeof(__u16)];
    char response[MAX_STRING_DESCRIPTOR_LENGTH];
    int result;
    int languageCount = 0;
    if (id == 0) return -1;
    if (*ucs2_out != NULL) return -1;
    memset(languages, 0, sizeof(languages));
    // read list of supported languages
    result = usb_device_control_transfer(device,
            USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE, USB_REQ_GET_DESCRIPTOR,
            (USB_DT_STRING << 8) | 0, 0, languages, sizeof(languages),
            timeout);
    if (result > 0)
        languageCount = (result - 2) / 2;
    for (int i = 1; i <= languageCount; i++) {
        memset(response, 0, sizeof(response));
        result = usb_device_control_transfer(
            device, USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, USB_REQ_GET_DESCRIPTOR,
            (USB_DT_STRING << 8) | id, languages[i], response, sizeof(response), timeout);
        if (result >= 2) {  // string contents begin at offset 2.
            int descriptor_len = result - 2;
            char* out = malloc(descriptor_len + 3);
            if (out == NULL) {
                return -1;
            }
            memcpy(out, response + 2, descriptor_len);
            // trail with three additional NULLs, so that there's guaranteed
            // to be a UCS-2 NULL character beyond whatever USB returned.
            // The returned string length is still just what USB returned.
            memset(out + descriptor_len, '\0', 3);
            *ucs2_out = (void*)out;
            *response_size = descriptor_len;
            return 0;
        }
    }
    return -1;
}
/* Warning: previously this blindly returned the lower 8 bits of
 * every UCS-2 character in a USB descriptor.  Now it will replace
 * values > 127 with ascii '?'.
 */
char* usb_device_get_string(struct usb_device* device, int id, int timeout) {
    char* ascii_string = NULL;
    size_t raw_string_len = 0;
    size_t i;
    if (usb_device_get_string_ucs2(device, id, timeout, (void**)&ascii_string, &raw_string_len) < 0)
        return NULL;
    if (ascii_string == NULL) return NULL;
    for (i = 0; i < raw_string_len / 2; ++i) {
        // wire format for USB is always little-endian.
        char lower = ascii_string[2 * i];
        char upper = ascii_string[2 * i + 1];
        if (upper || (lower & 0x80)) {
            ascii_string[i] = '?';
        } else {
            ascii_string[i] = lower;
        }
    }
    ascii_string[i] = '\0';
    return ascii_string;
}
char* usb_device_get_manufacturer_name(struct usb_device *device, int timeout)
{
    struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc;
    return usb_device_get_string(device, desc->iManufacturer, timeout);
}
char* usb_device_get_product_name(struct usb_device *device, int timeout)
{
    struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc;
    return usb_device_get_string(device, desc->iProduct, timeout);
}
int usb_device_get_version(struct usb_device *device)
{
    struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc;
    return desc->bcdUSB;
}
char* usb_device_get_serial(struct usb_device *device, int timeout)
{
    struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc;
    return usb_device_get_string(device, desc->iSerialNumber, timeout);
}
int usb_device_is_writeable(struct usb_device *device)
{
    return device->writeable;
}
void usb_descriptor_iter_init(struct usb_device *device, struct usb_descriptor_iter *iter)
{
    iter->config = device->desc;
    iter->config_end = device->desc + device->desc_length;
    iter->curr_desc = device->desc;
}
struct usb_descriptor_header *usb_descriptor_iter_next(struct usb_descriptor_iter *iter)
{
    struct usb_descriptor_header* next;
    if (iter->curr_desc >= iter->config_end)
        return NULL;
    next = (struct usb_descriptor_header*)iter->curr_desc;
    iter->curr_desc += next->bLength;
    return next;
}
int usb_device_claim_interface(struct usb_device *device, unsigned int interface)
{
    return ioctl(device->fd, USBDEVFS_CLAIMINTERFACE, &interface);
}
int usb_device_release_interface(struct usb_device *device, unsigned int interface)
{
    return ioctl(device->fd, USBDEVFS_RELEASEINTERFACE, &interface);
}
int usb_device_connect_kernel_driver(struct usb_device *device,
        unsigned int interface, int connect)
{
    struct usbdevfs_ioctl ctl;
    ctl.ifno = interface;
    ctl.ioctl_code = (connect ? USBDEVFS_CONNECT : USBDEVFS_DISCONNECT);
    ctl.data = NULL;
    return ioctl(device->fd, USBDEVFS_IOCTL, &ctl);
}
int usb_device_set_configuration(struct usb_device *device, int configuration)
{
    return ioctl(device->fd, USBDEVFS_SETCONFIGURATION, &configuration);
}
int usb_device_set_interface(struct usb_device *device, unsigned int interface,
                            unsigned int alt_setting)
{
    struct usbdevfs_setinterface ctl;
    ctl.interface = interface;
    ctl.altsetting = alt_setting;
    return ioctl(device->fd, USBDEVFS_SETINTERFACE, &ctl);
}
int usb_device_control_transfer(struct usb_device *device,
                            int requestType,
                            int request,
                            int value,
                            int index,
                            void* buffer,
                            int length,
                            unsigned int timeout)
{
    struct usbdevfs_ctrltransfer  ctrl;
    // this usually requires read/write permission
    if (!usb_device_reopen_writeable(device))
        return -1;
    memset(&ctrl, 0, sizeof(ctrl));
    ctrl.bRequestType = requestType;
    ctrl.bRequest = request;
    ctrl.wValue = value;
    ctrl.wIndex = index;
    ctrl.wLength = length;
    ctrl.data = buffer;
    ctrl.timeout = timeout;
    return ioctl(device->fd, USBDEVFS_CONTROL, &ctrl);
}
int usb_device_bulk_transfer(struct usb_device *device,
                            int endpoint,
                            void* buffer,
                            unsigned int length,
                            unsigned int timeout)
{
    struct usbdevfs_bulktransfer  ctrl;
    memset(&ctrl, 0, sizeof(ctrl));
    ctrl.ep = endpoint;
    ctrl.len = length;
    ctrl.data = buffer;
    ctrl.timeout = timeout;
    return ioctl(device->fd, USBDEVFS_BULK, &ctrl);
}
int usb_device_reset(struct usb_device *device)
{
    return ioctl(device->fd, USBDEVFS_RESET);
}
struct usb_request *usb_request_new(struct usb_device *dev,
        const struct usb_endpoint_descriptor *ep_desc)
{
    struct usbdevfs_urb *urb = calloc(1, sizeof(struct usbdevfs_urb));
    if (!urb)
        return NULL;
    if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
        urb->type = USBDEVFS_URB_TYPE_BULK;
    else if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
        urb->type = USBDEVFS_URB_TYPE_INTERRUPT;
    else {
        D("Unsupported endpoint type %d", ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
        free(urb);
        return NULL;
    }
    urb->endpoint = ep_desc->bEndpointAddress;
    struct usb_request *req = calloc(1, sizeof(struct usb_request));
    if (!req) {
        free(urb);
        return NULL;
    }
    req->dev = dev;
    req->max_packet_size = __le16_to_cpu(ep_desc->wMaxPacketSize);
    req->private_data = urb;
    req->endpoint = urb->endpoint;
    urb->usercontext = req;
    return req;
}
void usb_request_free(struct usb_request *req)
{
    free(req->private_data);
    free(req);
}
int usb_request_queue(struct usb_request *req)
{
    struct usbdevfs_urb *urb = (struct usbdevfs_urb*)req->private_data;
    int res;
    urb->status = -1;
    urb->buffer = req->buffer;
    urb->buffer_length = req->buffer_length;
    do {
        res = ioctl(req->dev->fd, USBDEVFS_SUBMITURB, urb);
    } while((res < 0) && (errno == EINTR));
    return res;
}
struct usb_request *usb_request_wait(struct usb_device *dev, int timeoutMillis)
{
    // Poll until a request becomes available if there is a timeout
    if (timeoutMillis > 0) {
        struct pollfd p = {.fd = dev->fd, .events = POLLOUT, .revents = 0};
        int res = poll(&p, 1, timeoutMillis);
        if (res != 1 || p.revents != POLLOUT) {
            D("[ poll - event %d, error %d]\n", p.revents, errno);
            return NULL;
        }
    }
    // Read the request. This should usually succeed as we polled before, but it can fail e.g. when
    // two threads are reading usb requests at the same time and only a single request is available.
    struct usbdevfs_urb *urb = NULL;
    int res = TEMP_FAILURE_RETRY(ioctl(dev->fd, timeoutMillis == -1 ? USBDEVFS_REAPURB :
                                       USBDEVFS_REAPURBNDELAY, &urb));
    D("%s returned %d\n", timeoutMillis == -1 ? "USBDEVFS_REAPURB" : "USBDEVFS_REAPURBNDELAY", res);
    if (res < 0) {
        D("[ reap urb - error %d]\n", errno);
        return NULL;
    } else {
        D("[ urb @%p status = %d, actual = %d ]\n", urb, urb->status, urb->actual_length);
        struct usb_request *req = (struct usb_request*)urb->usercontext;
        req->actual_length = urb->actual_length;
        return req;
    }
}
int usb_request_cancel(struct usb_request *req)
{
    struct usbdevfs_urb *urb = ((struct usbdevfs_urb*)req->private_data);
    return ioctl(req->dev->fd, USBDEVFS_DISCARDURB, urb);
}
