Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UsbHostMAX3421E_Hello
confdescparser.h
00001 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 00017 Contact information 00018 ------------------- 00019 00020 Circuits At Home, LTD 00021 Web : http://www.circuitsathome.com 00022 e-mail : support@circuitsathome.com 00023 */ 00024 #if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__) 00025 #error "Never include confdescparser.h directly; include Usb.h instead" 00026 #else 00027 00028 #define __CONFDESCPARSER_H__ 00029 00030 class UsbConfigXtracter { 00031 public: 00032 //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0; 00033 //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0; 00034 00035 virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) { 00036 }; 00037 }; 00038 00039 #define CP_MASK_COMPARE_CLASS 1 00040 #define CP_MASK_COMPARE_SUBCLASS 2 00041 #define CP_MASK_COMPARE_PROTOCOL 4 00042 #define CP_MASK_COMPARE_ALL 7 00043 00044 // Configuration Descriptor Parser Class Template 00045 00046 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> 00047 class ConfigDescParser : public USBReadParser { 00048 UsbConfigXtracter *theXtractor; 00049 MultiValueBuffer theBuffer; 00050 MultiByteValueParser valParser; 00051 ByteSkipper theSkipper; 00052 uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/]; 00053 00054 uint8_t stateParseDescr; // ParseDescriptor state 00055 00056 uint8_t dscrLen; // Descriptor length 00057 uint8_t dscrType; // Descriptor type 00058 00059 bool isGoodInterface; // Apropriate interface flag 00060 uint8_t confValue; // Configuration value 00061 uint8_t protoValue; // Protocol value 00062 uint8_t ifaceNumber; // Interface number 00063 uint8_t ifaceAltSet; // Interface alternate settings 00064 00065 bool UseOr; 00066 bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn); 00067 void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc); 00068 00069 public: 00070 00071 void SetOR(void) { 00072 UseOr = true; 00073 } 00074 ConfigDescParser(UsbConfigXtracter *xtractor); 00075 void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset); 00076 }; 00077 00078 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> 00079 ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ConfigDescParser(UsbConfigXtracter *xtractor) : 00080 theXtractor(xtractor), 00081 stateParseDescr(0), 00082 dscrLen(0), 00083 dscrType(0), 00084 UseOr(false) { 00085 theBuffer.pValue = varBuffer; 00086 valParser.Initialize(&theBuffer); 00087 theSkipper.Initialize(&theBuffer); 00088 }; 00089 00090 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> 00091 void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset __attribute__((unused))) { 00092 uint16_t cntdn = (uint16_t)len; 00093 uint8_t *p = (uint8_t*)pbuf; 00094 00095 while(cntdn) 00096 if(!ParseDescriptor(&p, &cntdn)) 00097 return; 00098 } 00099 00100 /* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and 00101 compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ 00102 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> 00103 bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) { 00104 USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer); 00105 USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer); 00106 switch(stateParseDescr) { 00107 case 0: 00108 theBuffer.valueSize = 2; 00109 valParser.Initialize(&theBuffer); 00110 stateParseDescr = 1; 00111 case 1: 00112 if(!valParser.Parse(pp, pcntdn)) 00113 return false; 00114 dscrLen = *((uint8_t*)theBuffer.pValue); 00115 dscrType = *((uint8_t*)theBuffer.pValue + 1); 00116 stateParseDescr = 2; 00117 case 2: 00118 // This is a sort of hack. Assuming that two bytes are all ready in the buffer 00119 // the pointer is positioned two bytes ahead in order for the rest of descriptor 00120 // to be read right after the size and the type fields. 00121 // This should be used carefully. varBuffer should be used directly to handle data 00122 // in the buffer. 00123 theBuffer.pValue = varBuffer + 2; 00124 stateParseDescr = 3; 00125 case 3: 00126 switch(dscrType) { 00127 case USB_DESCRIPTOR_INTERFACE: 00128 isGoodInterface = false; 00129 break; 00130 case USB_DESCRIPTOR_CONFIGURATION: 00131 case USB_DESCRIPTOR_ENDPOINT: 00132 case HID_DESCRIPTOR_HID: 00133 break; 00134 } 00135 theBuffer.valueSize = dscrLen - 2; 00136 valParser.Initialize(&theBuffer); 00137 stateParseDescr = 4; 00138 case 4: 00139 switch(dscrType) { 00140 case USB_DESCRIPTOR_CONFIGURATION: 00141 if(!valParser.Parse(pp, pcntdn)) 00142 return false; 00143 confValue = ucd->bConfigurationValue; 00144 break; 00145 case USB_DESCRIPTOR_INTERFACE: 00146 if(!valParser.Parse(pp, pcntdn)) 00147 return false; 00148 if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID) 00149 break; 00150 if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID) 00151 break; 00152 if(UseOr) { 00153 if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol))) 00154 break; 00155 } else { 00156 if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID) 00157 break; 00158 } 00159 isGoodInterface = true; 00160 ifaceNumber = uid->bInterfaceNumber; 00161 ifaceAltSet = uid->bAlternateSetting; 00162 protoValue = uid->bInterfaceProtocol; 00163 break; 00164 case USB_DESCRIPTOR_ENDPOINT: 00165 if(!valParser.Parse(pp, pcntdn)) 00166 return false; 00167 if(isGoodInterface) 00168 if(theXtractor) 00169 theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); 00170 break; 00171 //case HID_DESCRIPTOR_HID: 00172 // if (!valParser.Parse(pp, pcntdn)) 00173 // return false; 00174 // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer); 00175 // break; 00176 default: 00177 if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2)) 00178 return false; 00179 } 00180 theBuffer.pValue = varBuffer; 00181 stateParseDescr = 0; 00182 } 00183 return true; 00184 } 00185 00186 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> 00187 void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) { 00188 Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80); 00189 Notify(PSTR("bDescLength:\t\t"), 0x80); 00190 PrintHex<uint8_t > (pDesc->bLength, 0x80); 00191 00192 Notify(PSTR("\r\nbDescriptorType:\t"), 0x80); 00193 PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80); 00194 00195 Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80); 00196 PrintHex<uint16_t > (pDesc->bcdHID, 0x80); 00197 00198 Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80); 00199 PrintHex<uint8_t > (pDesc->bCountryCode, 0x80); 00200 00201 Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80); 00202 PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80); 00203 00204 for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) { 00205 HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType); 00206 00207 Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); 00208 PrintHex<uint8_t > (pLT[i].bDescrType, 0x80); 00209 00210 Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80); 00211 PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80); 00212 } 00213 Notify(PSTR("\r\n"), 0x80); 00214 } 00215 00216 00217 #endif // __CONFDESCPARSER_H__
Generated on Tue Jul 12 2022 18:12:04 by
1.7.2