static int usbredir_handle_interrupt_data(USBRedirDevice *dev,

                                           USBPacket *p, uint8_t ep)

{

    if (ep & USB_DIR_IN) {

        /* Input interrupt endpoint, buffered packet input */

        struct buf_packet *intp;

        int status, len;



        if (!dev->endpoint[EP2I(ep)].interrupt_started &&

                !dev->endpoint[EP2I(ep)].interrupt_error) {

            struct usb_redir_start_interrupt_receiving_header start_int = {

                .endpoint = ep,

            };

            /* No id, we look at the ep when receiving a status back */

            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,

                                                          &start_int);

            usbredirparser_do_write(dev->parser);

            DPRINTF("interrupt recv started ep %02X\n", ep);

            dev->endpoint[EP2I(ep)].interrupt_started = 1;

            /* We don't really want to drop interrupt packets ever, but

               having some upper limit to how much we buffer is good. */

            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;

            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;

        }



        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);

        if (intp == NULL) {

            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);

            /* Check interrupt_error for stream errors */

            status = dev->endpoint[EP2I(ep)].interrupt_error;

            dev->endpoint[EP2I(ep)].interrupt_error = 0;

            if (status) {

                return usbredir_handle_status(dev, status, 0);

            }

            return USB_RET_NAK;

        }

        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,

                intp->status, intp->len);



        status = intp->status;

        if (status != usb_redir_success) {

            bufp_free(dev, intp, ep);

            return usbredir_handle_status(dev, status, 0);

        }



        len = intp->len;

        if (len > p->iov.size) {

            ERROR("received int data is larger then packet ep %02X\n", ep);

            bufp_free(dev, intp, ep);

            return USB_RET_BABBLE;

        }

        usb_packet_copy(p, intp->data, len);

        bufp_free(dev, intp, ep);

        return len;

    } else {

        /* Output interrupt endpoint, normal async operation */

        AsyncURB *aurb = async_alloc(dev, p);

        struct usb_redir_interrupt_packet_header interrupt_packet;

        uint8_t buf[p->iov.size];



        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,

                aurb->packet_id);



        interrupt_packet.endpoint  = ep;

        interrupt_packet.length    = p->iov.size;

        aurb->interrupt_packet     = interrupt_packet;



        usb_packet_copy(p, buf, p->iov.size);

        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);

        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,

                                        &interrupt_packet, buf, p->iov.size);

        usbredirparser_do_write(dev->parser);

        return USB_RET_ASYNC;

    }

}

static int usbredir_handle_interrupt_data(USBRedirDevice *dev,

                                           USBPacket *p, uint8_t ep)

{

    if (ep & USB_DIR_IN) {

        

        struct buf_packet *intp;

        int status, len;



        if (!dev->endpoint[EP2I(ep)].interrupt_started &&

                !dev->endpoint[EP2I(ep)].interrupt_error) {

            struct usb_redir_start_interrupt_receiving_header start_int = {

                .endpoint = ep,

            };

            

            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,

                                                          &start_int);

            usbredirparser_do_write(dev->parser);

            DPRINTF("interrupt recv started ep %02X\n", ep);

            dev->endpoint[EP2I(ep)].interrupt_started = 1;

            



            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;

            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;

        }



        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);

        if (intp == NULL) {

            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);

            

            status = dev->endpoint[EP2I(ep)].interrupt_error;

            dev->endpoint[EP2I(ep)].interrupt_error = 0;

            if (status) {

                return usbredir_handle_status(dev, status, 0);

            }

            return USB_RET_NAK;

        }

        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,

                intp->status, intp->len);



        status = intp->status;

        if (status != usb_redir_success) {

            bufp_free(dev, intp, ep);

            return usbredir_handle_status(dev, status, 0);

        }



        len = intp->len;

        if (len > p->iov.size) {

            ERROR("received int data is larger then packet ep %02X\n", ep);

            bufp_free(dev, intp, ep);

            return USB_RET_BABBLE;

        }

        usb_packet_copy(p, intp->data, len);

        bufp_free(dev, intp, ep);

        return len;

    } else {

        

        AsyncURB *aurb = async_alloc(dev, p);

        struct usb_redir_interrupt_packet_header interrupt_packet;

        uint8_t buf[p->iov.size];



        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,

                aurb->packet_id);



        interrupt_packet.endpoint  = ep;

        interrupt_packet.length    = p->iov.size;

        aurb->interrupt_packet     = interrupt_packet;



        usb_packet_copy(p, buf, p->iov.size);

        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);

        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,

                                        &interrupt_packet, buf, p->iov.size);

        usbredirparser_do_write(dev->parser);

        return USB_RET_ASYNC;

    }

}

static int FUNC_0(USBRedirDevice *VAR_0,

                                           USBPacket *VAR_1, uint8_t VAR_2)

{

    if (VAR_2 & USB_DIR_IN) {

        

        struct buf_packet *VAR_3;

        int VAR_4, VAR_5;



        if (!VAR_0->endpoint[EP2I(VAR_2)].interrupt_started &&

                !VAR_0->endpoint[EP2I(VAR_2)].interrupt_error) {

            struct usb_redir_start_interrupt_receiving_header VAR_6 = {

                .endpoint = VAR_2,

            };

            

            usbredirparser_send_start_interrupt_receiving(VAR_0->parser, 0,

                                                          &VAR_6);

            usbredirparser_do_write(VAR_0->parser);

            DPRINTF("interrupt recv started VAR_2 %02X\n", VAR_2);

            VAR_0->endpoint[EP2I(VAR_2)].interrupt_started = 1;

            



            VAR_0->endpoint[EP2I(VAR_2)].bufpq_target_size = 1000;

            VAR_0->endpoint[EP2I(VAR_2)].bufpq_dropping_packets = 0;

        }



        VAR_3 = QTAILQ_FIRST(&VAR_0->endpoint[EP2I(VAR_2)].bufpq);

        if (VAR_3 == NULL) {

            DPRINTF2("interrupt-token-in VAR_2 %02X, no VAR_3\n", VAR_2);

            

            VAR_4 = VAR_0->endpoint[EP2I(VAR_2)].interrupt_error;

            VAR_0->endpoint[EP2I(VAR_2)].interrupt_error = 0;

            if (VAR_4) {

                return usbredir_handle_status(VAR_0, VAR_4, 0);

            }

            return USB_RET_NAK;

        }

        DPRINTF("interrupt-token-in VAR_2 %02X VAR_4 %d VAR_5 %d\n", VAR_2,

                VAR_3->VAR_4, VAR_3->VAR_5);



        VAR_4 = VAR_3->VAR_4;

        if (VAR_4 != usb_redir_success) {

            bufp_free(VAR_0, VAR_3, VAR_2);

            return usbredir_handle_status(VAR_0, VAR_4, 0);

        }



        VAR_5 = VAR_3->VAR_5;

        if (VAR_5 > VAR_1->iov.size) {

            ERROR("received int data is larger then packet VAR_2 %02X\n", VAR_2);

            bufp_free(VAR_0, VAR_3, VAR_2);

            return USB_RET_BABBLE;

        }

        usb_packet_copy(VAR_1, VAR_3->data, VAR_5);

        bufp_free(VAR_0, VAR_3, VAR_2);

        return VAR_5;

    } else {

        

        AsyncURB *aurb = async_alloc(VAR_0, VAR_1);

        struct usb_redir_interrupt_packet_header VAR_7;

        uint8_t buf[VAR_1->iov.size];



        DPRINTF("interrupt-out VAR_2 %02X VAR_5 %zd id %u\n", VAR_2, VAR_1->iov.size,

                aurb->packet_id);



        VAR_7.endpoint  = VAR_2;

        VAR_7.length    = VAR_1->iov.size;

        aurb->VAR_7     = VAR_7;



        usb_packet_copy(VAR_1, buf, VAR_1->iov.size);

        usbredir_log_data(VAR_0, "interrupt data out:", buf, VAR_1->iov.size);

        usbredirparser_send_interrupt_packet(VAR_0->parser, aurb->packet_id,

                                        &VAR_7, buf, VAR_1->iov.size);

        usbredirparser_do_write(VAR_0->parser);

        return USB_RET_ASYNC;

    }

}

static int FUNC_0(USBRedirDevice *VAR_0,
USBPacket *VAR_1, uint8_t VAR_2)
{ if (VAR_2 & USB_DIR_IN) { struct buf_packet *VAR_3; int VAR_4, VAR_5; if (!VAR_0->endpoint[EP2I(VAR_2)].interrupt_started &&
!VAR_0->endpoint[EP2I(VAR_2)].interrupt_error) { struct usb_redir_start_interrupt_receiving_header VAR_6 = { .endpoint = VAR_2,
}; usbredirparser_send_start_interrupt_receiving(VAR_0->parser, 0,
&VAR_6); usbredirparser_do_write(VAR_0->parser); DPRINTF("interrupt recv started VAR_2 %02X\n", VAR_2); VAR_0->endpoint[EP2I(VAR_2)].interrupt_started = 1; VAR_0->endpoint[EP2I(VAR_2)].bufpq_target_size = 1000; VAR_0->endpoint[EP2I(VAR_2)].bufpq_dropping_packets = 0; } VAR_3 = QTAILQ_FIRST(&VAR_0->endpoint[EP2I(VAR_2)].bufpq); if (VAR_3 == NULL) { DPRINTF2("interrupt-token-in VAR_2 %02X, no VAR_3\n", VAR_2); VAR_4 = VAR_0->endpoint[EP2I(VAR_2)].interrupt_error; VAR_0->endpoint[EP2I(VAR_2)].interrupt_error = 0; if (VAR_4) { return usbredir_handle_status(VAR_0, VAR_4, 0); } return USB_RET_NAK; } DPRINTF("interrupt-token-in VAR_2 %02X VAR_4 %d VAR_5 %d\n", VAR_2,
VAR_3->VAR_4, VAR_3->VAR_5); VAR_4 = VAR_3->VAR_4; if (VAR_4 != usb_redir_success) { bufp_free(VAR_0, VAR_3, VAR_2); return usbredir_handle_status(VAR_0, VAR_4, 0); } VAR_5 = VAR_3->VAR_5; if (VAR_5 > VAR_1->iov.size) { ERROR("received int data is larger then packet VAR_2 %02X\n", VAR_2); bufp_free(VAR_0, VAR_3, VAR_2); return USB_RET_BABBLE; } usb_packet_copy(VAR_1, VAR_3->data, VAR_5); bufp_free(VAR_0, VAR_3, VAR_2); return VAR_5; } else { AsyncURB *aurb = async_alloc(VAR_0, VAR_1); struct usb_redir_interrupt_packet_header VAR_7; uint8_t buf[VAR_1->iov.size]; DPRINTF("interrupt-out VAR_2 %02X VAR_5 %zd id %u\n", VAR_2, VAR_1->iov.size,
aurb->packet_id); VAR_7.endpoint  = VAR_2; VAR_7.length    = VAR_1->iov.size; aurb->VAR_7     = VAR_7; usb_packet_copy(VAR_1, buf, VAR_1->iov.size); usbredir_log_data(VAR_0, "interrupt data out:", buf, VAR_1->iov.size); usbredirparser_send_interrupt_packet(VAR_0->parser, aurb->packet_id,
&VAR_7, buf, VAR_1->iov.size); usbredirparser_do_write(VAR_0->parser); return USB_RET_ASYNC; } }