static uint8_t USBD_Composite_Setup(void* pdev, USB_SETUP_REQ* req) { if (req->bRequest == 0xee && req->bmRequest == 0b11000001 && req->wIndex == 0x0005) { return USBD_Composite_Handle_Msft_Request(pdev, req); } for(USBD_Composite_Class_Data* c = s_Classes; c != NULL; c = c->next) { if (c->active && req->wIndex >= c->firstInterface && req->wIndex < (c->firstInterface + c->interfaces)) { if(c->cb->Setup) { return c->cb->Setup(pdev, c, req); } } } return USBD_OK; }
uint8_t HAL_USB_Handle_Vendor_Request(USB_SETUP_REQ* req, uint8_t dataStage) { uint8_t ret = USBD_OK; // Forward Microsoft vendor requests to Composite driver if (req != NULL && req->bRequest == 0xee && req->wIndex == 0x0004 && req->wValue == 0x0000) { return USBD_Composite_Handle_Msft_Request(&USB_OTG_dev, req); } if (USB_Vendor_Request_Callback == NULL) return USBD_FAIL; if (req != NULL) { USB_SetupRequest.bmRequestType = req->bmRequest; USB_SetupRequest.bRequest = req->bRequest; USB_SetupRequest.wValue = req->wValue; USB_SetupRequest.wIndex = req->wIndex; USB_SetupRequest.wLength = req->wLength; if (req->wLength) { // Setup request with data stage if (req->bmRequest & 0x80) { // Device -> Host if (req->wLength <= USBD_EP0_MAX_PACKET_SIZE) USB_SetupRequest.data = USB_SetupRequest_Data; else USB_SetupRequest.data = NULL; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); if (ret == USBD_OK && USB_SetupRequest.data != NULL && USB_SetupRequest.wLength) { if (USB_SetupRequest.data != USB_SetupRequest_Data && USB_SetupRequest.wLength <= USBD_EP0_MAX_PACKET_SIZE) { // Don't use user buffer if wLength <= USBD_EP0_MAX_PACKET_SIZE // and copy into internal buffer memcpy(USB_SetupRequest_Data, USB_SetupRequest.data, USB_SetupRequest.wLength); } USBD_CtlSendData (&USB_OTG_dev, USB_SetupRequest_Data, USB_SetupRequest.wLength); } else { ret = USBD_FAIL; } } else { // Host -> Device USB_InSetupRequest = 1; if (req->wLength <= USBD_EP0_MAX_PACKET_SIZE) { // Use internal buffer USB_SetupRequest.data = USB_SetupRequest_Data; USBD_CtlPrepareRx(&USB_OTG_dev, USB_SetupRequest_Data, req->wLength); } else { // Try to request the buffer USB_SetupRequest.data = NULL; USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); if (USB_SetupRequest.data != NULL && USB_SetupRequest.wLength >= req->wLength) { USB_SetupRequest.wLength = req->wLength; USBD_CtlPrepareRx(&USB_OTG_dev, USB_SetupRequest.data, req->wLength); } else { ret = USBD_FAIL; } } } } else { // Setup request without data stage USB_SetupRequest.data = NULL; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); } } else if (dataStage && USB_InSetupRequest) { // Data stage completed USB_InSetupRequest = 0; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); } else { ret = USBD_FAIL; } return ret ? USBD_FAIL : USBD_OK; }