/*
 * Copyright (C) 2007 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.
 */

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

#include <sys/ioctl.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>

#include <linux/usbdevice_fs.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
#include <linux/usb/ch9.h>
#else
#include <linux/usb_ch9.h>
#endif
#include <asm/byteorder.h>

#include "sysdeps.h"

#define   TRACE_TAG  TRACE_USB
#include "adb.h"


/* usb scan debugging is waaaay too verbose */
#define DBGX(x...)

static adb_mutex_t usb_lock = ADB_MUTEX_INITIALIZER;

struct usb_handle
{
    usb_handle *prev;
    usb_handle *next;

    char fname[64];
    int desc;
    unsigned char ep_in;
    unsigned char ep_out;

    unsigned zero_mask;

    struct usbdevfs_urb urb_in;
    struct usbdevfs_urb urb_out;

    int urb_in_busy;
    int urb_out_busy;
    int dead;

    adb_cond_t notify;
    adb_mutex_t lock;

    // for garbage collecting disconnected devices
    int mark;

    // ID of thread currently in REAPURB
    pthread_t reaper_thread;
};

static usb_handle handle_list = {
    .prev = &handle_list,
    .next = &handle_list,
};

static int known_device(const char *dev_name)
{
    usb_handle *usb;

    adb_mutex_lock(&usb_lock);
    for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
        if(!strcmp(usb->fname, dev_name)) {
            // set mark flag to indicate this device is still alive
            usb->mark = 1;
            adb_mutex_unlock(&usb_lock);
            return 1;
        }
    }
    adb_mutex_unlock(&usb_lock);
    return 0;
}

static void kick_disconnected_devices()
{
    usb_handle *usb;

    adb_mutex_lock(&usb_lock);
    // kick any devices in the device list that were not found in the device scan
    for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
        if (usb->mark == 0) {
            usb_kick(usb);
        } else {
            usb->mark = 0;
        }
    }
    adb_mutex_unlock(&usb_lock);

}

static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out,
                            int ifc, const char *serial, unsigned zero_mask);

static inline int badname(const char *name)
{
    while(*name) {
        if(!isdigit(*name++)) return 1;
    }
    return 0;
}

static int find_usb_device(const char *base,
                           void (*register_device_callback) (const char *, unsigned char, unsigned char, int, const char *, unsigned))
{
    char busname[32], devname[32];
    unsigned char local_ep_in, local_ep_out;
    DIR *busdir , *devdir ;
    struct dirent *de;
    int fd ;
    int found_device = 0;
    char serial[256];

    busdir = opendir(base);
    if(busdir == 0) return 0;

    while((de = readdir(busdir)) != 0) {
        if(badname(de->d_name)) continue;

        snprintf(busname, sizeof busname, "%s/%s", base, de->d_name);
        devdir = opendir(busname);
        if(devdir == 0) continue;

//        DBGX("[ scanning %s ]\n", busname);
        while((de = readdir(devdir))) {
            unsigned char devdesc[256];
            unsigned char* bufptr = devdesc;
            struct usb_device_descriptor* device;
            struct usb_config_descriptor* config;
            struct usb_interface_descriptor* interface;
            struct usb_endpoint_descriptor *ep1, *ep2;
            unsigned zero_mask = 0;
            unsigned vid, pid;
            int i, interfaces;
            size_t desclength;

            if(badname(de->d_name)) continue;
            snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);

            if(known_device(devname)) {
                DBGX("skipping %s\n", devname);
                continue;
            }

//            DBGX("[ scanning %s ]\n", devname);
            if((fd = unix_open(devname, O_RDWR)) < 0) {
                continue;
            }

            desclength = adb_read(fd, devdesc, sizeof(devdesc));

                // should have device and configuration descriptors, and atleast two endpoints
            if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
                D("desclength %d is too small\n", desclength);
                adb_close(fd);
                continue;
            }

            device = (struct usb_device_descriptor*)bufptr;
            bufptr += USB_DT_DEVICE_SIZE;

            if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) {
                adb_close(fd);
                continue;
            }

            vid = __le16_to_cpu(device->idVendor);
            pid = __le16_to_cpu(device->idProduct);
            pid = devdesc[10] | (devdesc[11] << 8);
            DBGX("[ %s is V:%04x P:%04x ]\n", devname, vid, pid);

                // should have config descriptor next
            config = (struct usb_config_descriptor *)bufptr;
            bufptr += USB_DT_CONFIG_SIZE;
            if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
                D("usb_config_descriptor not found\n");
                adb_close(fd);
                continue;
            }

                // loop through all the interfaces and look for the ADB interface
            interfaces = config->bNumInterfaces;
            for (i = 0; i < interfaces; i++) {
                if (bufptr + USB_DT_ENDPOINT_SIZE > devdesc + desclength)
                    break;

                interface = (struct usb_interface_descriptor *)bufptr;
                bufptr += USB_DT_INTERFACE_SIZE;
                if (interface->bLength != USB_DT_INTERFACE_SIZE ||
                    interface->bDescriptorType != USB_DT_INTERFACE) {
                    D("usb_interface_descriptor not found\n");
                    break;
                }

                DBGX("bInterfaceClass: %d,  bInterfaceSubClass: %d,"
                     "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
                     interface->bInterfaceClass, interface->bInterfaceSubClass,
                     interface->bInterfaceProtocol, interface->bNumEndpoints);

                if (interface->bNumEndpoints == 2 &&
                        is_adb_interface(vid, pid, interface->bInterfaceClass,
                        interface->bInterfaceSubClass, interface->bInterfaceProtocol))  {

                    DBGX("looking for bulk endpoints\n");
                        // looks like ADB...
                    ep1 = (struct usb_endpoint_descriptor *)bufptr;
                    bufptr += USB_DT_ENDPOINT_SIZE;
                    ep2 = (struct usb_endpoint_descriptor *)bufptr;
                    bufptr += USB_DT_ENDPOINT_SIZE;

                    if (bufptr > devdesc + desclength ||
                        ep1->bLength != USB_DT_ENDPOINT_SIZE ||
                        ep1->bDescriptorType != USB_DT_ENDPOINT ||
                        ep2->bLength != USB_DT_ENDPOINT_SIZE ||
                        ep2->bDescriptorType != USB_DT_ENDPOINT) {
                        D("endpoints not found\n");
                        break;
                    }

                        // both endpoints should be bulk
                    if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
                        ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
                        D("bulk endpoints not found\n");
                        continue;
                    }

                        /* aproto 01 needs 0 termination */
                    if(interface->bInterfaceProtocol == 0x01) {
                        zero_mask = ep1->wMaxPacketSize - 1;
                    }

                        // we have a match.  now we just need to figure out which is in and which is out.
                    if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
                        local_ep_in = ep1->bEndpointAddress;
                        local_ep_out = ep2->bEndpointAddress;
                    } else {
                        local_ep_in = ep2->bEndpointAddress;
                        local_ep_out = ep1->bEndpointAddress;
                    }

                        // read the device's serial number
                    serial[0] = 0;
                    memset(serial, 0, sizeof(serial));
                    if (device->iSerialNumber) {
                        struct usbdevfs_ctrltransfer  ctrl;
                        __u16 buffer[128];
                        __u16 languages[128];
                        int i, result;
                        int languageCount = 0;

                        memset(languages, 0, sizeof(languages));
                        memset(&ctrl, 0, sizeof(ctrl));

                            // read list of supported languages
                        ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
                        ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
                        ctrl.wValue = (USB_DT_STRING << 8) | 0;
                        ctrl.wIndex = 0;
                        ctrl.wLength = sizeof(languages);
                        ctrl.data = languages;

                        result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
                        if (result > 0)
                            languageCount = (result - 2) / 2;

                        for (i = 1; i <= languageCount; i++) {
                            memset(buffer, 0, sizeof(buffer));
                            memset(&ctrl, 0, sizeof(ctrl));

                            ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE;
                            ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
                            ctrl.wValue = (USB_DT_STRING << 8) | device->iSerialNumber;
                            ctrl.wIndex = languages[i];
                            ctrl.wLength = sizeof(buffer);
                            ctrl.data = buffer;

                            result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
                            if (result > 0) {
                                int i;
                                    // skip first word, and copy the rest to the serial string, changing shorts to bytes.
                                result /= 2;
                                for (i = 1; i < result; i++)
                                    serial[i - 1] = buffer[i];
                                serial[i - 1] = 0;
                                break;
                            }
                        }
                    }

                    register_device_callback(devname, local_ep_in, local_ep_out,
                            interface->bInterfaceNumber, serial, zero_mask);

                    found_device = 1;
                    break;
                } else {
                    // seek next interface descriptor
                    if (i < interfaces - 1) {
                        while (bufptr[1] != USB_DT_INTERFACE) {
                            bufptr += bufptr[0];
                        }
                    }
                 }
            } // end of for

            adb_close(fd);
        } // end of devdir while
        closedir(devdir);
    } //end of busdir while
    closedir(busdir);

    return found_device;
}

void usb_cleanup()
{
}

static int usb_bulk_write(usb_handle *h, const void *data, int len)
{
    struct usbdevfs_urb *urb = &h->urb_out;
    int res;

    memset(urb, 0, sizeof(*urb));
    urb->type = USBDEVFS_URB_TYPE_BULK;
    urb->endpoint = h->ep_out;
    urb->status = -1;
    urb->buffer = (void*) data;
    urb->buffer_length = len;

    D("++ write ++\n");

    adb_mutex_lock(&h->lock);
    if(h->dead) {
        res = -1;
        goto fail;
    }
    do {
        res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb);
    } while((res < 0) && (errno == EINTR));

    if(res < 0) {
        goto fail;
    }

    res = -1;
    h->urb_out_busy = 1;
    for(;;) {
        adb_cond_wait(&h->notify, &h->lock);
        if(h->dead) {
            break;
        }
        if(h->urb_out_busy == 0) {
            if(urb->status == 0) {
                res = urb->actual_length;
            }
            break;
        }
    }
fail:
    adb_mutex_unlock(&h->lock);
    D("-- write --\n");
    return res;
}

static int usb_bulk_read(usb_handle *h, void *data, int len)
{
    struct usbdevfs_urb *urb = &h->urb_in;
    struct usbdevfs_urb *out = NULL;
    int res;

    memset(urb, 0, sizeof(*urb));
    urb->type = USBDEVFS_URB_TYPE_BULK;
    urb->endpoint = h->ep_in;
    urb->status = -1;
    urb->buffer = data;
    urb->buffer_length = len;


    adb_mutex_lock(&h->lock);
    if(h->dead) {
        res = -1;
        goto fail;
    }
    do {
        res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb);
    } while((res < 0) && (errno == EINTR));

    if(res < 0) {
        goto fail;
    }

    h->urb_in_busy = 1;
    for(;;) {
        D("[ reap urb - wait ]\n");
        h->reaper_thread = pthread_self();
        adb_mutex_unlock(&h->lock);
        res = ioctl(h->desc, USBDEVFS_REAPURB, &out);
        adb_mutex_lock(&h->lock);
        h->reaper_thread = 0;
        if(h->dead) {
            res = -1;
            break;
        }
        if(res < 0) {
            if(errno == EINTR) {
                continue;
            }
            D("[ reap urb - error ]\n");
            break;
        }
        D("[ urb @%p status = %d, actual = %d ]\n",
            out, out->status, out->actual_length);

        if(out == &h->urb_in) {
            D("[ reap urb - IN complete ]\n");
            h->urb_in_busy = 0;
            if(urb->status == 0) {
                res = urb->actual_length;
            } else {
                res = -1;
            }
            break;
        }
        if(out == &h->urb_out) {
            D("[ reap urb - OUT compelete ]\n");
            h->urb_out_busy = 0;
            adb_cond_broadcast(&h->notify);
        }
    }
fail:
    adb_mutex_unlock(&h->lock);
    return res;
}


int usb_write(usb_handle *h, const void *_data, int len)
{
    unsigned char *data = (unsigned char*) _data;
    int n;
    int need_zero = 0;

    if(h->zero_mask) {
            /* if we need 0-markers and our transfer
            ** is an even multiple of the packet size,
            ** we make note of it
            */
        if(!(len & h->zero_mask)) {
            need_zero = 1;
        }
    }

    while(len > 0) {
        int xfer = (len > 4096) ? 4096 : len;

        n = usb_bulk_write(h, data, xfer);
        if(n != xfer) {
            D("ERROR: n = %d, errno = %d (%s)\n",
                n, errno, strerror(errno));
            return -1;
        }

        len -= xfer;
        data += xfer;
    }

    if(need_zero){
        n = usb_bulk_write(h, _data, 0);
        return n;
    }

    return 0;
}

int usb_read(usb_handle *h, void *_data, int len)
{
    unsigned char *data = (unsigned char*) _data;
    int n;

    D("++ usb_read ++\n");
    while(len > 0) {
        int xfer = (len > 4096) ? 4096 : len;

        D("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
        n = usb_bulk_read(h, data, xfer);
        D("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname);
        if(n != xfer) {
            if((errno == ETIMEDOUT) && (h->desc != -1)) {
                D("[ timeout ]\n");
                if(n > 0){
                    data += n;
                    len -= n;
                }
                continue;
            }
            D("ERROR: n = %d, errno = %d (%s)\n",
                n, errno, strerror(errno));
            return -1;
        }

        len -= xfer;
        data += xfer;
    }

    D("-- usb_read --\n");
    return 0;
}

void usb_kick(usb_handle *h)
{
    D("[ kicking %p (fd = %d) ]\n", h, h->desc);
    adb_mutex_lock(&h->lock);
    if(h->dead == 0) {
        h->dead = 1;

        /* HACK ALERT!
        ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB).
        ** This is a workaround for that problem.
        */
        if (h->reaper_thread) {
            pthread_kill(h->reaper_thread, SIGALRM);
        }

        /* cancel any pending transactions
        ** these will quietly fail if the txns are not active,
        ** but this ensures that a reader blocked on REAPURB
        ** will get unblocked
        */
        ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in);
        ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out);
        h->urb_in.status = -ENODEV;
        h->urb_out.status = -ENODEV;
        h->urb_in_busy = 0;
        h->urb_out_busy = 0;
        adb_cond_broadcast(&h->notify);
    }
    adb_mutex_unlock(&h->lock);
}

int usb_close(usb_handle *h)
{
    D("[ usb close ... ]\n");
    adb_mutex_lock(&usb_lock);
    h->next->prev = h->prev;
    h->prev->next = h->next;
    h->prev = 0;
    h->next = 0;

    adb_close(h->desc);
    D("[ usb closed %p (fd = %d) ]\n", h, h->desc);
    adb_mutex_unlock(&usb_lock);

    free(h);
    return 0;
}

static void register_device(const char *dev_name,
                            unsigned char ep_in, unsigned char ep_out,
                            int interface,
                            const char *serial, unsigned zero_mask)
{
    usb_handle* usb = 0;
    int n = 0;

        /* Since Linux will not reassign the device ID (and dev_name)
        ** as long as the device is open, we can add to the list here
        ** once we open it and remove from the list when we're finally
        ** closed and everything will work out fine.
        **
        ** If we have a usb_handle on the list 'o handles with a matching
        ** name, we have no further work to do.
        */
    adb_mutex_lock(&usb_lock);
    for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
        if(!strcmp(usb->fname, dev_name)) {
            adb_mutex_unlock(&usb_lock);
            return;
        }
    }
    adb_mutex_unlock(&usb_lock);

    D("[ usb located new device %s (%d/%d/%d) ]\n",
        dev_name, ep_in, ep_out, interface);
    usb = calloc(1, sizeof(usb_handle));
    strcpy(usb->fname, dev_name);
    usb->ep_in = ep_in;
    usb->ep_out = ep_out;
    usb->zero_mask = zero_mask;

    adb_cond_init(&usb->notify, 0);
    adb_mutex_init(&usb->lock, 0);
    /* initialize mark to 1 so we don't get garbage collected after the device scan */
    usb->mark = 1;
    usb->reaper_thread = 0;

    usb->desc = unix_open(usb->fname, O_RDWR);
    if(usb->desc < 0) goto fail;
    D("[ usb open %s fd = %d]\n", usb->fname, usb->desc);
    n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface);
    if(n != 0) goto fail;

        /* add to the end of the active handles */
    adb_mutex_lock(&usb_lock);
    usb->next = &handle_list;
    usb->prev = handle_list.prev;
    usb->prev->next = usb;
    usb->next->prev = usb;
    adb_mutex_unlock(&usb_lock);

    register_usb_transport(usb, serial);
    return;

fail:
    D("[ usb open %s error=%d, err_str = %s]\n",
        usb->fname,  errno, strerror(errno));
    if(usb->desc >= 0) {
        adb_close(usb->desc);
    }
    free(usb);
}

void* device_poll_thread(void* unused)
{
    D("Created device thread\n");
    for(;;) {
            /* XXX use inotify */
        find_usb_device("/dev/bus/usb", register_device);
        kick_disconnected_devices();
        sleep(1);
    }
    return NULL;
}

static void sigalrm_handler(int signo)
{
    // don't need to do anything here
}

void usb_init()
{
    adb_thread_t tid;
    struct sigaction    actions;

    memset(&actions, 0, sizeof(actions));
    sigemptyset(&actions.sa_mask);
    actions.sa_flags = 0;
    actions.sa_handler = sigalrm_handler;
    sigaction(SIGALRM,& actions, NULL);

    if(adb_thread_create(&tid, device_poll_thread, NULL)){
        fatal_errno("cannot create input thread");
    }
}

