/*
 * QEMU USB emulation
 *
 * Copyright (c) 2005 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "vl.h"

void usb_attach(USBPort *port, USBDevice *dev)
{
    port->attach(port, dev);
}

/**********************/
/* generic USB device helpers (you are not forced to use them when
   writing your USB device driver, but they help handling the
   protocol)
*/

#define SETUP_STATE_IDLE 0
#define SETUP_STATE_DATA 1
#define SETUP_STATE_ACK  2

int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
{
    int l, ret = 0;
    int len = p->len;
    uint8_t *data = p->data;

    switch(p->pid) {
    case USB_MSG_ATTACH:
        s->state = USB_STATE_ATTACHED;
        break;
    case USB_MSG_DETACH:
        s->state = USB_STATE_NOTATTACHED;
        break;
    case USB_MSG_RESET:
        s->remote_wakeup = 0;
        s->addr = 0;
        s->state = USB_STATE_DEFAULT;
        s->handle_reset(s);
        break;
    case USB_TOKEN_SETUP:
        if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
            return USB_RET_NODEV;
        if (len != 8)
            goto fail;
        memcpy(s->setup_buf, data, 8);
        s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
        s->setup_index = 0;
        if (s->setup_buf[0] & USB_DIR_IN) {
            ret = s->handle_control(s,
                                    (s->setup_buf[0] << 8) | s->setup_buf[1],
                                    (s->setup_buf[3] << 8) | s->setup_buf[2],
                                    (s->setup_buf[5] << 8) | s->setup_buf[4],
                                    s->setup_len,
                                    s->data_buf);
            if (ret < 0)
                return ret;
            if (ret < s->setup_len)
                s->setup_len = ret;
            s->setup_state = SETUP_STATE_DATA;
        } else {
            if (s->setup_len == 0)
                s->setup_state = SETUP_STATE_ACK;
            else
                s->setup_state = SETUP_STATE_DATA;
        }
        break;
    case USB_TOKEN_IN:
        if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
            return USB_RET_NODEV;
        switch(p->devep) {
        case 0:
            switch(s->setup_state) {
            case SETUP_STATE_ACK:
                if (!(s->setup_buf[0] & USB_DIR_IN)) {
                    s->setup_state = SETUP_STATE_IDLE;
                    ret = s->handle_control(s,
                                      (s->setup_buf[0] << 8) | s->setup_buf[1],
                                      (s->setup_buf[3] << 8) | s->setup_buf[2],
                                      (s->setup_buf[5] << 8) | s->setup_buf[4],
                                      s->setup_len,
                                      s->data_buf);
                    if (ret > 0)
                        ret = 0;
                } else {
                    /* return 0 byte */
                }
                break;
            case SETUP_STATE_DATA:
                if (s->setup_buf[0] & USB_DIR_IN) {
                    l = s->setup_len - s->setup_index;
                    if (l > len)
                        l = len;
                    memcpy(data, s->data_buf + s->setup_index, l);
                    s->setup_index += l;
                    if (s->setup_index >= s->setup_len)
                        s->setup_state = SETUP_STATE_ACK;
                    ret = l;
                } else {
                    s->setup_state = SETUP_STATE_IDLE;
                    goto fail;
                }
                break;
            default:
                goto fail;
            }
            break;
        default:
            ret = s->handle_data(s, p);
            break;
        }
        break;
    case USB_TOKEN_OUT:
        if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
            return USB_RET_NODEV;
        switch(p->devep) {
        case 0:
            switch(s->setup_state) {
            case SETUP_STATE_ACK:
                if (s->setup_buf[0] & USB_DIR_IN) {
                    s->setup_state = SETUP_STATE_IDLE;
                    /* transfer OK */
                } else {
                    /* ignore additional output */
                }
                break;
            case SETUP_STATE_DATA:
                if (!(s->setup_buf[0] & USB_DIR_IN)) {
                    l = s->setup_len - s->setup_index;
                    if (l > len)
                        l = len;
                    memcpy(s->data_buf + s->setup_index, data, l);
                    s->setup_index += l;
                    if (s->setup_index >= s->setup_len)
                        s->setup_state = SETUP_STATE_ACK;
                    ret = l;
                } else {
                    s->setup_state = SETUP_STATE_IDLE;
                    goto fail;
                }
                break;
            default:
                goto fail;
            }
            break;
        default:
            ret = s->handle_data(s, p);
            break;
        }
        break;
    default:
    fail:
        ret = USB_RET_STALL;
        break;
    }
    return ret;
}

/* XXX: fix overflow */
int set_usb_string(uint8_t *buf, const char *str)
{
    int len, i;
    uint8_t *q;

    q = buf;
    len = strlen(str);
    *q++ = 2 * len + 2;
    *q++ = 3;
    for(i = 0; i < len; i++) {
        *q++ = str[i];
        *q++ = 0;
    }
    return q - buf;
}

/* Send an internal message to a USB device.  */
void usb_send_msg(USBDevice *dev, int msg)
{
    USBPacket p;
    memset(&p, 0, sizeof(p));
    p.pid = msg;
    dev->handle_packet(dev, &p);
}

