00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include "private.h"
00036 #include <usb/dev/request.h>
00037 #include <usb/debug.h>
00038 #include <assert.h>
00039 #include <errno.h>
00040
00051 int process_control_transfer(usbvirt_device_t *dev,
00052 usbvirt_control_request_handler_t *control_handlers,
00053 usb_device_request_setup_packet_t *setup,
00054 uint8_t *data, size_t *data_sent_size)
00055 {
00056 assert(dev);
00057 assert(setup);
00058
00059 if (control_handlers == NULL) {
00060 return EFORWARD;
00061 }
00062
00063 usb_direction_t direction = setup->request_type & 128 ?
00064 USB_DIRECTION_IN : USB_DIRECTION_OUT;
00065 usb_request_recipient_t req_recipient = setup->request_type & 31;
00066 usb_request_type_t req_type = (setup->request_type >> 5) & 3;
00067
00068 usbvirt_control_request_handler_t *handler = control_handlers;
00069 while (handler->callback != NULL) {
00070 if (handler->req_direction != direction) {
00071 goto next;
00072 }
00073 if (handler->req_recipient != req_recipient) {
00074 goto next;
00075 }
00076 if (handler->req_type != req_type) {
00077 goto next;
00078 }
00079 if (handler->request != setup->request) {
00080 goto next;
00081 }
00082
00083 usb_log_debug("Control transfer: %s(%s)\n", handler->name,
00084 usb_debug_str_buffer((uint8_t*) setup, sizeof(*setup), 0));
00085 int rc = handler->callback(dev, setup, data, data_sent_size);
00086 if (rc == EFORWARD) {
00087 goto next;
00088 }
00089
00090 return rc;
00091
00092 next:
00093 handler++;
00094 }
00095
00096 return EFORWARD;
00097 }
00098
00099