/*
 * 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(void)
{
    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 = (int) 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 = (int) 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 = (unsigned char) requestType;
    ctrl.bRequest = (unsigned char) request;
    ctrl.wValue = (unsigned short) value;
    ctrl.wIndex = (unsigned short) index;
    ctrl.wLength = (unsigned short) 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 = (int) 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);
}
