int8_t app_unknown_setup_request_callback(const struct setup_packet *setup) { #define MIN(X,Y) ((X)<(Y)?(X):(Y)) /* This handler handles request 254/dest=other/type=vendor only.*/ if (setup->bRequest != 245 || setup->REQUEST.destination != 3 /*other*/ || setup->REQUEST.type != 2 /*vendor*/) return -1; if (setup->REQUEST.direction == 0/*OUT*/) { if (setup->wLength == 0) { /* There will be NO data stage. This sends back the * STATUS stage packet. */ usb_send_data_stage(NULL, 0, data_cb, NULL); } memset(buf,0,sizeof(buf)); /* Set up an OUT data stage (we will receive data) */ if (setup->wLength > sizeof(buf)) { /* wLength is too big. Return -1 to refuse this transfer*/ return -1; } usb_start_receive_ep0_data_stage(buf, setup->wLength, &data_cb, NULL); } else { /* Direction is 1 (IN) */ size_t i; for (i = 0; i < sizeof(buf); i++) { buf[i] = sizeof(buf)-i; } /* Set up an OUT data stage (we will receive data) */ if (setup->wLength > sizeof(buf)) { /* wLength is too big. Return -1 to refuse this transfer*/ return -1; } usb_send_data_stage(buf ,setup->wLength, data_cb, NULL); } return 0; /* 0 = can handle this request. */ #undef MIN }
uint8_t process_hid_setup_request(const struct setup_packet *setup) { /* The following comes from the HID spec 1.11, section 7.1.1 */ uint8_t interface = setup->wIndex; #ifdef MULTI_CLASS_DEVICE /* Check the interface first to make sure the destination is a * HID interface. Composite devices will need to call * hid_set_interface_list() first. */ uint8_t i; for (i = 0; i < num_hid_interfaces; i++) { if (interface == hid_interfaces[i]) break; } /* Return if interface is not in the list of HID interfaces. */ if (i == num_hid_interfaces) return -1; #endif if (setup->bRequest == GET_DESCRIPTOR && setup->REQUEST.bmRequestType == 0x81) { uint8_t descriptor = ((setup->wValue >> 8) & 0x00ff); const void *desc; int16_t len = -1; if (descriptor == DESC_HID) { len = USB_HID_DESCRIPTOR_FUNC(interface, &desc); } else if (descriptor == DESC_REPORT) { len = USB_HID_REPORT_DESCRIPTOR_FUNC(interface, &desc); } #ifdef USB_HID_PHYSICAL_DESCRIPTOR_FUNC else if (descriptor == DESC_PHYSICAL) { uint8_t descriptor_index = setup->wValue & 0x00ff; len = USB_HID_PHYSICAL_DESCRIPTOR_FUNC(interface, descriptor_index, &desc); } #endif if (len < 0) return -1; usb_send_data_stage((void*) desc, min(len, setup->wLength), NULL, NULL); return 0; }
int8_t process_msc_setup_request(const struct setup_packet *setup) { uint8_t interface = setup->wIndex; struct msc_application_data *msc; #ifdef MULTI_CLASS_DEVICE /* Check the interface first to make sure the destination is an * MSC interface. Multi-class devices will need to call * msc_set_interface_list() first. */ if (!interface_is_msc(interface)) return -1; #endif /* Get application data for this interface */ msc = get_app_data(interface); if (!msc) return -1; /* BOT 3.2 says the GET_MAX_LUN request is optional if there's only one * LUN, but stalling this request will cause Windows 7 to hang for 18 * seconds when a device is first connected. */ if (setup->bRequest == MSC_GET_MAX_LUN && setup->REQUEST.bmRequestType == 0xa1) { /* Stall invalid value/length */ if (setup->wValue != 0 || setup->wLength != 1) return -1; usb_send_data_stage((void*)&msc->max_lun, 1, NULL, 0); return 0; } if (setup->bRequest == MSC_BULK_ONLY_MASS_STORAGE_RESET && setup->REQUEST.bmRequestType == 0x21) { struct msc_application_data *d = get_app_data(interface); /* Stall invalid value/length */ if (setup->wValue != 0 || setup->wLength != 0) return -1; if (d) d->state = MSC_IDLE; else return -1; #ifdef MSC_BULK_ONLY_MASS_STORAGE_RESET_CALLBACK int8_t res = 0; res = MSC_BULK_ONLY_MASS_STORAGE_RESET_CALLBACK(interface); if (res < 0) return -1; #endif /* Clear the NEEDS_RESET_RECOVERY state */ msc->state = MSC_IDLE; /* Return zero-length packet. No data stage. */ usb_send_data_stage(NULL, 0, NULL, NULL); return 0; } return -1; }