/** Parses the list of installed USB descriptors and attempts to find the specified USB descriptor. @param [in] wTypeIndex Type and index of the descriptor @param [in] wLangID Language ID of the descriptor (currently unused) @param [out] *piLen Descriptor length @param [out] *ppbData Descriptor data @return TRUE if the descriptor was found, FALSE otherwise */ int USBGetDescriptor(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData) { U8 bType, bIndex; U8 *pab; int iCurIndex; ASSERT(pabDescrip != NULL); bType = GET_DESC_TYPE(wTypeIndex); bIndex = GET_DESC_INDEX(wTypeIndex); pab = (U8 *)pabDescrip; iCurIndex = 0; while (pab[DESC_bLength] != 0) { if (pab[DESC_bDescriptorType] == bType) { if (iCurIndex == bIndex) { // set data pointer *ppbData = pab; // get length from structure if (bType == DESC_CONFIGURATION) { // configuration descriptor is an exception, length is at offset 2 and 3 *piLen = (pab[CONF_DESC_wTotalLength]) | (pab[CONF_DESC_wTotalLength + 1] << 8); } else { // normally length is at offset 0 *piLen = pab[DESC_bLength]; } return TRUE; } iCurIndex++; } // skip to next descriptor pab += pab[DESC_bLength]; } // nothing found DBG("Desc %x not found!\n", wTypeIndex); return FALSE; }
/** * Local function to handle a standard device request * * @param [in] pSetup The setup packet * @param [in,out] *piLen Pointer to data length * @param [in,out] ppbData Data buffer. * * @return TRUE if the request was handled successfully */ uint8_t USBCTRL::HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, uint8_t **ppbData) { uint8_t *pbData = *ppbData; iResidue = 0; switch (pSetup->bRequest) { case REQ_GET_STATUS: iprintf("GET_STATUS\n"); // bit 0: self-powered // bit 1: remote wakeup = not supported pbData[0] = 0; pbData[1] = 0; *piLen = 2; break; case REQ_SET_ADDRESS: iprintf("USBADDR %d!\n", pSetup->wValue); HwSetAddress(pSetup->wValue); *piLen = 0; break; case REQ_GET_DESCRIPTOR: iprintf("GET DESCRIPTOR 0x%02X/0x%02X\n", GET_DESC_TYPE(pSetup->wValue), GET_DESC_INDEX(pSetup->wValue)); // DBG("D%x", pSetup->wValue); return GetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData); case REQ_GET_CONFIGURATION: iprintf("GET CONFIGURATION\n"); // indicate if we are configured pbData[0] = conf->bConfigurationValue; *piLen = 1; break; case REQ_SET_CONFIGURATION: iprintf("SET CONFIGURATION\n"); *piLen = 0; if (!SetConfiguration(pSetup->wValue & 0xFF, bAlternate)) { // DBG("USBSetConfiguration failed!\n"); return FALSE; } // configuration successful, update current configuration // bConfiguration = pSetup->wValue & 0xFF; break; case REQ_CLEAR_FEATURE: case REQ_SET_FEATURE: *piLen = 0; iprintf("CLEAR/SET FEATURE\n"); if (pSetup->wValue == FEA_REMOTE_WAKEUP) { // put DEVICE_REMOTE_WAKEUP code here } if (pSetup->wValue == FEA_TEST_MODE) { // put TEST_MODE code here } return FALSE; case REQ_SET_DESCRIPTOR: *piLen = 0; iprintf("SET DESCRIPTOR\n"); // DBG("Device req %d not implemented\n", pSetup->bRequest); return FALSE; default: *piLen = 0; iprintf("UNKNOWN: 0x%02X\n", pSetup->bRequest); // DBG("Illegal device req %d\n", pSetup->bRequest); return FALSE; } return TRUE; }
/** * Parses the list of installed USB descriptors and attempts to find * the specified USB descriptor. * * @param [in] wTypeIndex Type and index of the descriptor * @param [in] wLangID Language ID of the descriptor (currently unused) * @param [out] *piLen Descriptor length * @param [out] *ppbData Descriptor data * * @return TRUE if the descriptor was found, FALSE otherwise */ uint8_t USBCTRL::GetDescriptor(uint16_t wTypeIndex, uint16_t wLangID, int *piLen, uint8_t **ppbData) { uint8_t bType, bIndex; int iCurIndex; // ASSERT(pabDescrip != NULL); bType = GET_DESC_TYPE(wTypeIndex); bIndex = GET_DESC_INDEX(wTypeIndex); iCurIndex = 0; for (int i = 0; descriptors[i] != (usbdesc_base *) 0; i++) { if (descriptors[i]->bDescType == bType) { if (iCurIndex == bIndex) { *ppbData = (uint8_t *) descriptors[i]; if (bType == DT_CONFIGURATION) { confSize = ((usbdesc_configuration *) descriptors[i])->wTotalLength; confRemain = confSize; confIndex = i; confSubIndex = 0; *piLen = ((usbdesc_configuration *) descriptors[i])->wTotalLength; *ppbData = confBuffer; iprintf("Get Configuration: %d bytes!\n", *piLen); } else { *piLen = descriptors[i]->bLength; confRemain = 0; iprintf("Get 0x%02X: %d bytes\n", bIndex, *piLen); } return TRUE; } iCurIndex++; } } iprintf("Descriptor matching 0x%02X not found\n", wTypeIndex); // pab = (uint8_t *)pabDescrip; // iCurIndex = 0; // // while (pab[DESC_bLength] != 0) { // if (pab[DESC_bDescriptorType] == bType) { // if (iCurIndex == bIndex) { // // set data pointer // *ppbData = pab; // // get length from structure // if (bType == DESC_CONFIGURATION) { // // configuration descriptor is an exception, length is at offset 2 and 3 // *piLen = (pab[CONF_DESC_wTotalLength]) | // (pab[CONF_DESC_wTotalLength + 1] << 8); // } // else { // // normally length is at offset 0 // *piLen = pab[DESC_bLength]; // } // return TRUE; // } // iCurIndex++; // } // // skip to next descriptor // pab += pab[DESC_bLength]; // } // nothing found // DBG("Desc %x/%x not found!\n", GET_DESC_TYPE(wTypeIndex), GET_DESC_INDEX(wTypeIndex)); *piLen = 0; return TRUE; }