/** Default handler for standard ('chapter 9') requests @param [in] pSetup The setup packet @param [in,out] *piLen Pointer to data length @param [in] ppbData Data buffer. @return TRUE if the request was handled successfully */ int USBHandleStandardRequest_FPV_usb_reqhdlr(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) { switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) { case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData); case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData); case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData); default: return FALSE; } }
/** * Default handler for standard ('chapter 9') requests * * If a custom request handler was installed, this handler is called first. * * @param [in] pSetup The setup packet * @param [in,out] *piLen Pointer to data length * @param [in] ppbData Data buffer. * * @return TRUE if the request was handled successfully */ uint8_t USBCTRL::HandleStandardRequest(TSetupPacket *pSetup, int *piLen, uint8_t **ppbData) { // try the custom request handler first if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) { return TRUE; } switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) { case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData); case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData); case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData); default: return FALSE; } }
void USBCTRL::EPIntHandler(USBHW *u, uint8_t bEP, uint8_t bEPStatus) { iprintf("E0x%02X:0x%02X\t", bEP, bEPStatus); if (bEP == 0x00) { if (bEPStatus & EP_STATUS_SETUP) { // defaults for data pointer and residue HwEPRead(bEP, (uint8_t *) &Setup, sizeof(Setup)); uint8_t iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = &apbDataStore[iType][0]; iResidue = Setup.wLength; iLen = Setup.wLength; if ((Setup.wLength == 0) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { switch(REQTYPE_GET_TYPE(Setup.bmRequestType)) { case REQTYPE_TYPE_STANDARD: { // iprintf("STDREQ:%02X,%02X,%04X,%04X,%04x\n", Setup.bmRequestType, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength); uint8_t r = 0; switch (REQTYPE_GET_RECIP(Setup.bmRequestType)) { case REQTYPE_RECIP_DEVICE: { iprintf("StdDevReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength); r = HandleStdDeviceReq(&Setup, &iLen, &pbData); iprintf("Reply:%d bytes, max this packet: %d\n", iLen, Setup.wLength); break; } case REQTYPE_RECIP_INTERFACE: { iprintf("StdIntReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength); r = HandleStdInterfaceReq(&Setup, &iLen, &pbData); break; } case REQTYPE_RECIP_ENDPOINT: { iprintf("StdEPReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength); r = HandleStdEndPointReq(&Setup, &iLen, &pbData); break; } case REQTYPE_RECIP_OTHER: { iprintf("StdReq?:RqType=%02x;Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bmRequestType, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength); break; } } if (!r) { iprintf("STALL!\n"); HwEPStall(0x80, TRUE); return; } iResidue = iLen; if (iResidue > Setup.wLength) iResidue = Setup.wLength; DataIn(); return; }; } } iprintf("Unknown Setup ReqType %d - ignored\n", Setup.bmRequestType); iprintf("bRequest: %d (0x%02X), wValue: %d, wIndex: %d (0x%X), wLength: %d\n", Setup.bRequest, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wIndex, Setup.wLength); iprintf("Dir: %s, ", (REQTYPE_GET_DIR(Setup.bmRequestType)?"Device->Host":"Host->Device")); if (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_DEVICE) { iResidue = Setup.wLength; } else { iResidue = 0; } switch (REQTYPE_GET_TYPE(Setup.bmRequestType)) { case REQTYPE_TYPE_STANDARD: iprintf("Type: Standard, "); break; case REQTYPE_TYPE_CLASS: iprintf("Type: Class , "); break; case REQTYPE_TYPE_VENDOR: iprintf("Type: Vendor , "); break; default: iprintf("Type: Reserved, "); break; } switch (REQTYPE_GET_RECIP(Setup.bmRequestType)) { case 0: iprintf("Recip: Device\n"); break; case 1: iprintf("Recip: Interface 0x%X\n", Setup.wIndex); break; case 2: iprintf("Recip: Endpoint 0x%X\n", Setup.wIndex); break; case 3: iprintf("Recip: Other\n"); break; default: iprintf("Recip: unknown\n"); break; } // if (REQTYPE_GET_TYPE(Setup.bmRequestType) == REQTYPE_TYPE_CLASS) { // // find interface // int i; // for (i = 0; descriptors[i] != ((usbdesc_base *) 0); i++) { // if ((descriptors[i]->bDescType == DT_INTERFACE) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_INTERFACE)) { // usbdesc_interface *inf = (usbdesc_interface *) descriptors[i]; // if (inf->bInterfaceNumber == Setup.wIndex) { // iprintf("Firing Interface's setup handler: %p\n", inf->setupReceiver); // if (inf->setupReceiver) { // inf->setupReceiver->SetupHandler(u, bEP, &Setup); // break; // } // } // } // if ((descriptors[i]->bDescType == DT_ENDPOINT) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_ENDPOINT)) { // usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; // if (ep->bEndpointAddress == bEP) { // iprintf("Firing Endpoint's setup handler: %p\n", ep->setupReceiver); // if (ep->setupReceiver) // ep->setupReceiver->SetupHandler(u, bEP, &Setup); // } // } // } // } } else { int iChunk; if (iResidue > 0) { // store data iChunk = HwEPRead(0x00, pbData, iResidue); iprintf("G:%db\n", iChunk); if (iChunk < 0) { HwEPStall(0x80, TRUE); return; } pbData += iChunk; iResidue -= iChunk; if (iResidue == 0) { // received all, send data to handler uint8_t iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = apbDataStore[iType]; iprintf("HANDLE 0x%02X with %db\n", iType, iLen); // if (!_HandleRequest(&Setup, &iLen, &pbData)) { // DBG("_HandleRequest2 failed\n"); // StallControlPipe(bEPStat); // return; // } // send status to host DataIn(); } } else { // absorb zero-length status message iChunk = HwEPRead(0x00, NULL, 0); iprintf("g%db\n", iChunk); // acknowledge HwEPWrite(0x80, 0, 0); // DBG(iChunk > 0 ? "?" : ""); } } if (REQTYPE_GET_TYPE(Setup.bmRequestType) == REQTYPE_TYPE_CLASS) { if ((iResidue == Setup.wLength) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { // find interface int i; for (i = 0; descriptors[i] != ((usbdesc_base *) 0); i++) { if ((descriptors[i]->bDescType == DT_INTERFACE) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_INTERFACE)) { usbdesc_interface *inf = (usbdesc_interface *) descriptors[i]; if (inf->bInterfaceNumber == Setup.wIndex) { iprintf("Firing Interface's setup handler: %p\n", inf->setupReceiver); if (inf->setupReceiver) { inf->setupReceiver->SetupHandler(u, bEP, &Setup); break; } } } if ((descriptors[i]->bDescType == DT_ENDPOINT) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_ENDPOINT)) { usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; if (ep->bEndpointAddress == bEP) { iprintf("Firing Endpoint's setup handler: %p\n", ep->setupReceiver); if (ep->setupReceiver) ep->setupReceiver->SetupHandler(u, bEP, &Setup); } } } } } } else if (bEP == 0x80) { DataIn(); } else { int i; usbdesc_base *descriptor; for (i = 0; i < 32; i++) { descriptor = descriptors[i]; if (descriptor->bDescType == DT_ENDPOINT) { usbdesc_endpoint *endpoint = (usbdesc_endpoint *) descriptor; if (endpoint->bEndpointAddress == bEP) { endpoint->callbackReceiver->EPIntHandler(u, bEP, bEPStatus); } } } } }