/*
 * 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 <linux/usb/ch9.h>
#include <linux/usb/functionfs.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <sys/epoll.h>

#include "sysdeps.h"

#define   TRACE_TAG  TRACE_USB
#include "adb.h"

#define MAX_PACKET_SIZE_FS	64
#define MAX_PACKET_SIZE_HS	512
#define MAX_PACKET_SIZE_SS	1024

//#define cpu_to_le16(x)  htole16(x)
//#define cpu_to_le32(x)  htole32(x)
/*
 * cpu_to_le16/32 are used when initializing structures, a context where a
 * function call is not allowed. To solve this, we code cpu_to_le16/32 in a way
 * that allows them to be used when initializing structures.
 */

#if __BYTE_ORDER == __LITTLE_ENDIAN
#define cpu_to_le16(x)  (x)
#define cpu_to_le32(x)  (x)
#else
#define cpu_to_le16(x)  ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
#define cpu_to_le32(x)  \
    ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >>  8) | \
    (((x) & 0x0000ff00u) <<  8) | (((x) & 0x000000ffu) << 24))
#endif

#define FFS_CONTOL_MAX_EPOLL_EVENT 50
#define DEBUG   0

struct usb_handle
{
    adb_cond_t notify;
    adb_mutex_t lock;

    int (*write)(usb_handle *h, const void *data, int len);
    int (*read)(usb_handle *h, void *data, int len);
    void (*kick)(usb_handle *h);

    // Legacy f_adb
    int fd;

    // FunctionFS
    int control;
    int bulk_out; /* "out" from the host's perspective => source for adbd */
    int bulk_in;  /* "in" from the host's perspective => sink for adbd */
    bool ffs_control_thread_created;
};

static const struct {
    __le32 magic;
    __le32 length;
    __le32 flags;
    __le32 fs_count;
    __le32 hs_count;
    __le32 ss_count;
    struct {
        struct usb_interface_descriptor intf;
        struct usb_endpoint_descriptor_no_audio source;
        struct usb_endpoint_descriptor_no_audio sink;
    } __attribute__((packed)) fs_descs, hs_descs;
    struct {
        struct usb_interface_descriptor intf;
        struct usb_endpoint_descriptor_no_audio source;
        struct usb_ss_ep_comp_descriptor source_comp;
        struct usb_endpoint_descriptor_no_audio sink;
        struct usb_ss_ep_comp_descriptor sink_comp;
    } __attribute__((packed)) ss_descs;
} __attribute__((packed)) descriptors = {
    .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
    .length = cpu_to_le32(sizeof(descriptors)),
    .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
                         FUNCTIONFS_HAS_HS_DESC |
                         FUNCTIONFS_HAS_SS_DESC),
    .fs_count = 3,
    .hs_count = 3,
    .ss_count = 5,
    .fs_descs = {
        .intf = {
            .bLength = sizeof(descriptors.fs_descs.intf),
            .bDescriptorType = USB_DT_INTERFACE,
            .bInterfaceNumber = 0,
            .bNumEndpoints = 2,
            .bInterfaceClass = ADB_CLASS,
            .bInterfaceSubClass = ADB_SUBCLASS,
            .bInterfaceProtocol = ADB_PROTOCOL,
            .iInterface = 1, /* first string from the provided table */
        },
        .source = {
            .bLength = sizeof(descriptors.fs_descs.source),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 1 | USB_DIR_OUT,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
        },
        .sink = {
            .bLength = sizeof(descriptors.fs_descs.sink),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 2 | USB_DIR_IN,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
        },
    },
    .hs_descs = {
        .intf = {
            .bLength = sizeof(descriptors.hs_descs.intf),
            .bDescriptorType = USB_DT_INTERFACE,
            .bInterfaceNumber = 0,
            .bNumEndpoints = 2,
            .bInterfaceClass = ADB_CLASS,
            .bInterfaceSubClass = ADB_SUBCLASS,
            .bInterfaceProtocol = ADB_PROTOCOL,
            .iInterface = 1, /* first string from the provided table */
        },
        .source = {
            .bLength = sizeof(descriptors.hs_descs.source),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 1 | USB_DIR_OUT,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
        },
        .sink = {
            .bLength = sizeof(descriptors.hs_descs.sink),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 2 | USB_DIR_IN,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
        },
    },
    .ss_descs = {
        .intf = {
            .bLength = sizeof(descriptors.ss_descs.intf),
            .bDescriptorType = USB_DT_INTERFACE,
            .bInterfaceNumber = 0,
            .bNumEndpoints = 2,
            .bInterfaceClass = ADB_CLASS,
            .bInterfaceSubClass = ADB_SUBCLASS,
            .bInterfaceProtocol = ADB_PROTOCOL,
            .iInterface = 1, /* first string from the provided table */
        },
        .source = {
            .bLength = sizeof(descriptors.ss_descs.source),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 1 | USB_DIR_OUT,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_SS,
        },
        .source_comp = {
            .bLength = sizeof(descriptors.ss_descs.source_comp),
            .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
        },
        .sink = {
            .bLength = sizeof(descriptors.ss_descs.sink),
            .bDescriptorType = USB_DT_ENDPOINT,
            .bEndpointAddress = 2 | USB_DIR_IN,
            .bmAttributes = USB_ENDPOINT_XFER_BULK,
            .wMaxPacketSize = MAX_PACKET_SIZE_SS,
        },
        .sink_comp = {
            .bLength = sizeof(descriptors.ss_descs.sink_comp),
            .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
        },
    },
};

#define STR_INTERFACE_ "ADB Interface"

static const struct {
    struct usb_functionfs_strings_head header;
    struct {
        __le16 code;
        const char str1[sizeof(STR_INTERFACE_)];
    } __attribute__((packed)) lang0;
} __attribute__((packed)) strings = {
    .header = {
        .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
        .length = cpu_to_le32(sizeof(strings)),
        .str_count = cpu_to_le32(1),
        .lang_count = cpu_to_le32(1),
    },
    .lang0 = {
        cpu_to_le16(0x0409), /* en-us */
        STR_INTERFACE_,
    },
};

static void *usb_adb_open_thread(void *x)
{
    struct usb_handle *usb = (struct usb_handle *)x;
    int fd;

    while (1) {
        // wait until the USB device needs opening
        adb_mutex_lock(&usb->lock);
        while (usb->fd != -1)
            adb_cond_wait(&usb->notify, &usb->lock);
        adb_mutex_unlock(&usb->lock);

        D("[ usb_thread - opening device ]\n");
        do {
            /* XXX use inotify? */
            fd = unix_open("/dev/android_adb", O_RDWR);
            if (fd < 0) {
                // to support older kernels
                fd = unix_open("/dev/android", O_RDWR);
            }
            if (fd < 0) {
                adb_sleep_ms(1000);
            }
        } while (fd < 0);
        D("[ opening device succeeded ]\n");

        close_on_exec(fd);
        usb->fd = fd;

        D("[ usb_thread - registering device ]\n");
        register_usb_transport(usb, 0, 0, 1);
    }

    // never gets here
    return 0;
}

static int usb_adb_write(usb_handle *h, const void *data, int len)
{
    int n;

    D("about to write (fd=%d, len=%d)\n", h->fd, len);
    n = adb_write(h->fd, data, len);
    if(n != len) {
        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
            h->fd, n, errno, strerror(errno));
        return -1;
    }
    D("[ done fd=%d ]\n", h->fd);
    return 0;
}

static int usb_adb_read(usb_handle *h, void *data, int len)
{
    int n;

    D("about to read (fd=%d, len=%d)\n", h->fd, len);
    n = adb_read(h->fd, data, len);
    if(n != len) {
        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
            h->fd, n, errno, strerror(errno));
        return -1;
    }
    D("[ done fd=%d ]\n", h->fd);
    return 0;
}

static void usb_adb_kick(usb_handle *h)
{
    D("usb_kick\n");
    adb_mutex_lock(&h->lock);
    adb_close(h->fd);
    h->fd = -1;

    // notify usb_adb_open_thread that we are disconnected
    adb_cond_signal(&h->notify);
    adb_mutex_unlock(&h->lock);
}

static void usb_adb_init()
{
    usb_handle *h;
    adb_thread_t tid;
    int fd;

    h = calloc(1, sizeof(usb_handle));
    if (h == 0) {
        fatal("cannot allocate usb_handle");
        return;
    }

    h->write = usb_adb_write;
    h->read = usb_adb_read;
    h->kick = usb_adb_kick;
    h->bulk_in = -1;
    h->bulk_out = -1;
    h->control = -1;
    h->ffs_control_thread_created = false;
    h->fd = -1;

    adb_cond_init(&h->notify, 0);
    adb_mutex_init(&h->lock, 0);

    // Open the file /dev/android_adb_enable to trigger
    // the enabling of the adb USB function in the kernel.
    // We never touch this file again - just leave it open
    // indefinitely so the kernel will know when we are running
    // and when we are not.
    fd = unix_open("/dev/android_adb_enable", O_RDWR);
    if (fd < 0) {
       D("failed to open /dev/android_adb_enable\n");
    } else {
        close_on_exec(fd);
    }

    D("[ usb_init - starting thread ]\n");
    if(adb_thread_create(&tid, usb_adb_open_thread, h)){
        fatal_errno("cannot create usb thread");
    }
}

static void *ffs_control_read_msg_thread(void *_h)
{
    usb_handle *h = _h;
    int fd = h->control;

    char buf[MAX_PACKET_SIZE_FS];
    int size = 0;//event.u.setup.wLength;
    if (DEBUG) D("FUNCTIONFS_SETUP acking host-to-device control transfer size=%d", size);
    if (size+1 > MAX_PACKET_SIZE_FS) {
        D("package size larger than MAX_PACKET_SIZE_FS");
        return 0;
    }

    if (DEBUG) D("FUNCTIONFS_SETUP before get host-to-device msg size:%d", size);
    int rc = adb_read(fd, buf, size);
    if (DEBUG) D("FUNCTIONFS_SETUP after get host-to-device msg rc:%d", rc);
    if (rc != size) {
        D("Read %d bytes when trying to read control request, expected %d", rc, size);
    }
    return 0;
}

static char* ffs_get_event_type_code(int type) {
    char* code;
    switch(type) {
        case FUNCTIONFS_BIND:
            code = "BIND";
            break;
        case FUNCTIONFS_UNBIND:
            code = "UNBIND";
            break;
        case FUNCTIONFS_ENABLE:
            code = "ENABLE";
            break;
        case FUNCTIONFS_DISABLE:
            code = "DISABLE";
            break;
        case FUNCTIONFS_SETUP:
            code = "SETUP";
            break;
        case FUNCTIONFS_SUSPEND:
            code = "SUSPEND";
            break;
        case FUNCTIONFS_RESUME:
            code = "RESUME";
            break;
        default:
            code = "UNKNOWN";
            break;
        }
    return code;
}

static void ffs_control_event_handler(usb_handle *h) {
    int fd = h->control;
    struct usb_functionfs_event event;
    int ret = 0;

    if (DEBUG) D("start remote usb read control fd:%d size=%d\n", fd, (int)sizeof(event));
    ret = adb_read(fd, &event, sizeof(event));
    if (DEBUG) D("done remote usb read control ret=%d size=%d\n", ret, (int)sizeof(event));
    if (ret != sizeof(event)) {
        if (DEBUG) D("remote usb: read size:%d not expect to event size:%d\n", ret, (int)sizeof(event));
        return;
    }

    D("event.type: %s\n", ffs_get_event_type_code(event.type));

    switch (event.type) {
        case FUNCTIONFS_SETUP: {
            D("received FUNCTIONFS_SETUP");
            D("bRequestType = %d",(int)(event.u.setup.bRequestType));
            D("bRequest = %d\n", (int)(event.u.setup.bRequest));
            D("wValue = %d\n", (int)(event.u.setup.wValue));
            D("wIndex = %d\n", (int)(event.u.setup.wIndex));
            D("wLength = %d\n", (int)(event.u.setup.wLength));

            if ((event.u.setup.bRequestType & USB_DIR_IN)) {
                if (DEBUG) D("FUNCTIONFS_SETUP acking device-to-host control transfer");
                int rc = adb_write(fd, "", 0);
                if (rc != 0) {
                    D("Failed to write empty packet to host");
                    break;
                }
            } else {
                adb_thread_t ffs_control_read_msg_thread_ptr;

                if(adb_thread_create(&ffs_control_read_msg_thread_ptr, ffs_control_read_msg_thread, h)) {
                    fatal_errno("cannot create control thread");
                }


                if (DEBUG) D("Wait 100ms before kill read msg thread");
                adb_sleep_ms(100);
                int ret = pthread_cancel(ffs_control_read_msg_thread_ptr);
                D("Done kill the read msg thread ret=%d", ret);
            }
        }
    }
}

// -1 means failure
static int epoll_add_fd(int epfd, int fd) {
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.data.fd = fd;
    ev.events = EPOLLIN;
    // don't set the fd to edge trigger
    // the some event like accept may be lost if two or more clients are connecting to server at the same time
    // level trigger is preferred to avoid event lost
    // do not set EPOLLOUT due to it will always trigger when write is available
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        D("epoll_add_fd3() epoll_ctl() failed reason=[%s]%d epfd=%d fd=%d",
            strerror(errno), errno, epfd, fd);
        return -1;
    }
    return 0;
}

static void *ffs_control_thread(void *_h)
{
    usb_handle *h = _h;
    int control_fd = h->control;
    struct epoll_event events[FFS_CONTOL_MAX_EPOLL_EVENT];

    int epfd = epoll_create(FFS_CONTOL_MAX_EPOLL_EVENT);
    if(epfd == -1) {
        D("ERR: epoll_create() fail reason=[%s]", strerror(errno));
        return 0;
    }

    epoll_add_fd(epfd, control_fd);

    while(1) {
        int i;
        int n;

        D("Before ffs control thread epoll_wait");
        n = epoll_wait(epfd, events, FFS_CONTOL_MAX_EPOLL_EVENT , -1);

        for(i = 0; i < n; i++) {
            if(events[i].data.fd == control_fd) {
                if(events[i].events & EPOLLIN) {
                    if (DEBUG) D("control_fd event triggered");
                    ffs_control_event_handler(h);
                }
            }
        }
    }
}

void ffs_create_control_thread(usb_handle *h) {
    if (h->control >= 0) {  // only for ffs usb
        if (!h->ffs_control_thread_created) {
            adb_thread_t ffs_control_thread_ptr;

            if(adb_thread_create(&ffs_control_thread_ptr, ffs_control_thread, h)){
                fatal_errno("cannot create ffs_control_thread");
            } else {
                h->ffs_control_thread_created = true;
                if (DEBUG) D("Created ffs_control_thread success");
            }
        }
    }
}

static void init_functionfs(struct usb_handle *h)
{
    ssize_t ret;

    if (h->control < 0) { // might have already done this before
        D("OPENING %s\n", USB_FFS_ADB_EP0);
        h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
        if (h->control < 0) {
            D("[ %s: cannot open control endpoint: errno=%d]\n", USB_FFS_ADB_EP0, errno);
            goto err;
        }

        ret = adb_write(h->control, &descriptors, sizeof(descriptors));
        if (ret < 0) {
            D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
            goto err;
        }

        ret = adb_write(h->control, &strings, sizeof(strings));
        if (ret < 0) {
            D("[ %s: writing strings failed: errno=%d]\n", USB_FFS_ADB_EP0, errno);
            goto err;
        }
    }

    h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
    if (h->bulk_out < 0) {
        D("[ %s: cannot open bulk-out ep: errno=%d ]\n", USB_FFS_ADB_OUT, errno);
        goto err;
    }

    h->bulk_in = adb_open(USB_FFS_ADB_IN, O_RDWR);
    if (h->bulk_in < 0) {
        D("[ %s: cannot open bulk-in ep: errno=%d ]\n", USB_FFS_ADB_IN, errno);
        goto err;
    }

    ffs_create_control_thread(h);
    return;

err:
    if (h->bulk_in > 0) {
        adb_close(h->bulk_in);
        h->bulk_in = -1;
    }
    if (h->bulk_out > 0) {
        adb_close(h->bulk_out);
        h->bulk_out = -1;
    }
    if (h->control > 0) {
        adb_close(h->control);
        h->control = -1;
    }
    return;
}

static void *usb_ffs_open_thread(void *x)
{
    struct usb_handle *usb = (struct usb_handle *)x;

    while (1) {
        // wait until the USB device needs opening
        adb_mutex_lock(&usb->lock);
        while (usb->control != -1 && usb->bulk_in != -1 && usb->bulk_out != -1)
            adb_cond_wait(&usb->notify, &usb->lock);
        adb_mutex_unlock(&usb->lock);

        while (1) {
            init_functionfs(usb);

            if (usb->control >= 0 && usb->bulk_in >= 0 && usb->bulk_out >= 0)
                break;

            adb_sleep_ms(1000);
        }

        D("[ usb_thread - registering device ]\n");
        register_usb_transport(usb, 0, 0, 1);
    }

    // never gets here
    return 0;
}

static int bulk_write(int bulk_in, const char *buf, size_t length)
{
    size_t count = 0;
    int ret;

    do {
        ret = adb_write(bulk_in, buf + count, length - count);
        if (ret < 0) {
            if (errno != EINTR)
                return ret;
        } else {
            count += ret;
        }
    } while (count < length);

    D("[ bulk_write done fd=%d ]\n", bulk_in);
    return count;
}

static int usb_ffs_write(usb_handle *h, const void *data, int len)
{
    int n;

    D("about to write (fd=%d, len=%d)\n", h->bulk_in, len);
    n = bulk_write(h->bulk_in, data, len);
    if (n != len) {
        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
            h->bulk_in, n, errno, strerror(errno));
        return -1;
    }
    D("[ done fd=%d ]\n", h->bulk_in);
    return 0;
}

static int bulk_read(int bulk_out, char *buf, size_t length)
{
    size_t count = 0;
    int ret;

    do {
        ret = adb_read(bulk_out, buf + count, length - count);
        if (ret < 0) {
            if (errno != EINTR) {
                D("[ bulk_read failed fd=%d length=%zu count=%zu ]\n",
                                           bulk_out, length, count);
                return ret;
            }
        } else {
            count += ret;
        }
    } while (count < length);

    return count;
}

static int usb_ffs_read(usb_handle *h, void *data, int len)
{
    int n;

    D("about to read (fd=%d, len=%d)\n", h->bulk_out, len);
    n = bulk_read(h->bulk_out, data, len);
    if (n != len) {
        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
            h->bulk_out, n, errno, strerror(errno));
        return -1;
    }
    D("[ done fd=%d ]\n", h->bulk_out);
    return 0;
}

static void usb_ffs_kick(usb_handle *h)
{
    int err;

    err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
    if (err < 0)
        D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);

    err = ioctl(h->bulk_out, FUNCTIONFS_CLEAR_HALT);
    if (err < 0)
        D("[ kick: sink (fd=%d) clear halt failed (%d) ]", h->bulk_out, errno);

    adb_mutex_lock(&h->lock);

    // don't close ep0 here, since we may not need to reinitialize it with
    // the same descriptors again. if however ep1/ep2 fail to re-open in
    // init_functionfs, only then would we close and open ep0 again.
    adb_close(h->bulk_out);
    adb_close(h->bulk_in);
    h->bulk_out = h->bulk_in = -1;

    // notify usb_ffs_open_thread that we are disconnected
    adb_cond_signal(&h->notify);
    adb_mutex_unlock(&h->lock);
}

static void usb_ffs_init()
{
    usb_handle *h;
    adb_thread_t tid;

    D("[ usb_init - using FunctionFS ]\n");

    h = calloc(1, sizeof(usb_handle));
    if (h == 0) {
        fatal("cannot allocate usb_handle");
        return;
    }

    h->write = usb_ffs_write;
    h->read = usb_ffs_read;
    h->kick = usb_ffs_kick;

    h->control  = -1;
    h->bulk_out = -1;
    h->bulk_out = -1;
    h->ffs_control_thread_created = false;

    adb_cond_init(&h->notify, 0);
    adb_mutex_init(&h->lock, 0);

    D("[ usb_init - starting thread ]\n");
    if (adb_thread_create(&tid, usb_ffs_open_thread, h)){
        fatal_errno("[ cannot create usb thread ]\n");
    }
}

void usb_init()
{
    if (access(USB_FFS_ADB_EP0, F_OK) == 0)
        usb_ffs_init();
    else
        usb_adb_init();
}

void usb_cleanup()
{
}

int usb_write(usb_handle *h, const void *data, int len)
{
    return h->write(h, data, len);
}

int usb_read(usb_handle *h, void *data, int len)
{
    return h->read(h, data, len);
}
int usb_close(usb_handle *h)
{
    return 0;
}

void usb_kick(usb_handle *h)
{
    h->kick(h);
}
