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 <assert.h>
00038 #include <errno.h>
00039
00051 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet,
00052 uint8_t *data, size_t *act_size,
00053 void *actual_data, size_t actual_data_size)
00054 {
00055 size_t expected_size = setup_packet->length;
00056 if (expected_size < actual_data_size) {
00057 actual_data_size = expected_size;
00058 }
00059
00060 memcpy(data, actual_data, actual_data_size);
00061
00062 if (act_size != NULL) {
00063 *act_size = actual_data_size;
00064 }
00065 }
00066
00068 static int req_get_descriptor(usbvirt_device_t *device,
00069 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
00070 {
00071 uint8_t type = setup_packet->value_high;
00072 uint8_t index = setup_packet->value_low;
00073
00074
00075
00076
00077 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) {
00078 if (device->descriptors && device->descriptors->device) {
00079 usbvirt_control_reply_helper(setup_packet, data, act_size,
00080 device->descriptors->device,
00081 device->descriptors->device->length);
00082 return EOK;
00083 } else {
00084 return EFORWARD;
00085 }
00086 }
00087
00088
00089
00090
00091
00092 if (type == USB_DESCTYPE_CONFIGURATION) {
00093 if (!device->descriptors) {
00094 return EFORWARD;
00095 }
00096 if (index >= device->descriptors->configuration_count) {
00097 return EFORWARD;
00098 }
00099
00100 usbvirt_device_configuration_t *config = &device->descriptors
00101 ->configuration[index];
00102 uint8_t *all_data = malloc(config->descriptor->total_length);
00103 if (all_data == NULL) {
00104 return ENOMEM;
00105 }
00106
00107 uint8_t *ptr = all_data;
00108 memcpy(ptr, config->descriptor, config->descriptor->length);
00109 ptr += config->descriptor->length;
00110 size_t i;
00111 for (i = 0; i < config->extra_count; i++) {
00112 usbvirt_device_configuration_extras_t *extra
00113 = &config->extra[i];
00114 memcpy(ptr, extra->data, extra->length);
00115 ptr += extra->length;
00116 }
00117
00118 usbvirt_control_reply_helper(setup_packet, data, act_size,
00119 all_data, config->descriptor->total_length);
00120
00121 free(all_data);
00122
00123 return EOK;
00124 }
00125
00126 return EFORWARD;
00127 }
00128
00129 static int req_set_address(usbvirt_device_t *device,
00130 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
00131 {
00132 uint16_t new_address = setup_packet->value;
00133 uint16_t zero1 = setup_packet->index;
00134 uint16_t zero2 = setup_packet->length;
00135
00136 if ((zero1 != 0) || (zero2 != 0)) {
00137 return EINVAL;
00138 }
00139
00140 if (new_address > 127) {
00141 return EINVAL;
00142 }
00143
00144 device->address = new_address;
00145
00146 return EOK;
00147 }
00148
00149 static int req_set_configuration(usbvirt_device_t *device,
00150 const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
00151 {
00152 uint16_t configuration_value = setup_packet->value;
00153 uint16_t zero1 = setup_packet->index;
00154 uint16_t zero2 = setup_packet->length;
00155
00156 if ((zero1 != 0) || (zero2 != 0)) {
00157 return EINVAL;
00158 }
00159
00160
00161
00162
00163 if (configuration_value > 255) {
00164 return EINVAL;
00165 }
00166
00167
00168
00169
00170
00171 if (device->state == USBVIRT_STATE_DEFAULT) {
00172 return EOK;
00173 }
00174
00175 usbvirt_device_state_t new_state;
00176 if (configuration_value == 0) {
00177 new_state = USBVIRT_STATE_ADDRESS;
00178 } else {
00179
00180 new_state = USBVIRT_STATE_CONFIGURED;
00181 }
00182
00183 if (device->ops && device->ops->state_changed) {
00184 device->ops->state_changed(device, device->state, new_state);
00185 }
00186 device->state = new_state;
00187
00188 return EOK;
00189 }
00190
00192 usbvirt_control_request_handler_t library_handlers[] = {
00193 {
00194 .req_direction = USB_DIRECTION_OUT,
00195 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
00196 .req_type = USB_REQUEST_TYPE_STANDARD,
00197 .request = USB_DEVREQ_SET_ADDRESS,
00198 .name = "SetAddress",
00199 .callback = req_set_address
00200 },
00201 {
00202 .req_direction = USB_DIRECTION_IN,
00203 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
00204 .req_type = USB_REQUEST_TYPE_STANDARD,
00205 .request = USB_DEVREQ_GET_DESCRIPTOR,
00206 .name = "GetDescriptor",
00207 .callback = req_get_descriptor
00208 },
00209 {
00210 .req_direction = USB_DIRECTION_OUT,
00211 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
00212 .req_type = USB_REQUEST_TYPE_STANDARD,
00213 .request = USB_DEVREQ_SET_CONFIGURATION,
00214 .name = "SetConfiguration",
00215 .callback = req_set_configuration
00216 },
00217
00218 { .callback = NULL }
00219 };
00220