USB Host Shield 2.0
Loading...
Searching...
No Matches
confdescparser.h
Go to the documentation of this file.
1/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
3This program is free software; you can redistribute it and/or modify
4it under the terms of the GNU General Public License as published by
5the Free Software Foundation; either version 2 of the License, or
6(at your option) any later version.
7
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License
14along with this program; if not, write to the Free Software
15Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17Contact information
18-------------------
19
20Circuits At Home, LTD
21Web : http://www.circuitsathome.com
22e-mail : support@circuitsathome.com
23 */
24#if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__)
25#error "Never include confdescparser.h directly; include Usb.h instead"
26#else
27
28#define __CONFDESCPARSER_H__
29
31public:
32 //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
33 //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
34
37};
38
39#define CP_MASK_COMPARE_CLASS 1
40#define CP_MASK_COMPARE_SUBCLASS 2
41#define CP_MASK_COMPARE_PROTOCOL 4
42#define CP_MASK_COMPARE_ALL 7
43
44// Configuration Descriptor Parser Class Template
45
46template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
48 UsbConfigXtracter *theXtractor;
49 MultiValueBuffer theBuffer;
50 MultiByteValueParser valParser;
51 ByteSkipper theSkipper;
52 uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
53
54 uint8_t stateParseDescr; // ParseDescriptor state
55
56 uint8_t dscrLen; // Descriptor length
57 uint8_t dscrType; // Descriptor type
58
59 bool isGoodInterface; // Apropriate interface flag
60 uint8_t confValue; // Configuration value
61 uint8_t protoValue; // Protocol value
62 uint8_t ifaceNumber; // Interface number
63 uint8_t ifaceAltSet; // Interface alternate settings
64
65 bool UseOr;
66 bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
67 void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
68
69public:
70
71 void SetOR(void) {
72 UseOr = true;
73 }
75 void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
76};
77
78template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
80theXtractor(xtractor),
81stateParseDescr(0),
82dscrLen(0),
83dscrType(0),
84UseOr(false) {
85 theBuffer.pValue = varBuffer;
86 valParser.Initialize(&theBuffer);
87 theSkipper.Initialize(&theBuffer);
88};
89
90template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
93 uint8_t *p = (uint8_t*)pbuf;
94
95 while(cntdn)
96 if(!ParseDescriptor(&p, &cntdn))
97 return;
98}
99
100/* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
101 compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
102template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
104 USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
105 USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
106 switch(stateParseDescr) {
107 case 0:
108 theBuffer.valueSize = 2;
109 valParser.Initialize(&theBuffer);
110 stateParseDescr = 1;
111 // fall through
112 case 1:
113 if(!valParser.Parse(pp, pcntdn))
114 return false;
115 dscrLen = *((uint8_t*)theBuffer.pValue);
116 dscrType = *((uint8_t*)theBuffer.pValue + 1);
117 stateParseDescr = 2;
118 // fall through
119 case 2:
120 // This is a sort of hack. Assuming that two bytes are all ready in the buffer
121 // the pointer is positioned two bytes ahead in order for the rest of descriptor
122 // to be read right after the size and the type fields.
123 // This should be used carefully. varBuffer should be used directly to handle data
124 // in the buffer.
125 theBuffer.pValue = varBuffer + 2;
126 stateParseDescr = 3;
127 // fall through
128 case 3:
129 switch(dscrType) {
131 isGoodInterface = false;
132 break;
136 break;
137 }
138 theBuffer.valueSize = dscrLen - 2;
139 valParser.Initialize(&theBuffer);
140 stateParseDescr = 4;
141 // fall through
142 case 4:
143 switch(dscrType) {
145 if(!valParser.Parse(pp, pcntdn))
146 return false;
147 confValue = ucd->bConfigurationValue;
148 break;
150 if(!valParser.Parse(pp, pcntdn))
151 return false;
152 if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID)
153 break;
154 if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID)
155 break;
156 if(UseOr) {
157 if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol)))
158 break;
159 } else {
160 if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID)
161 break;
162 }
163 isGoodInterface = true;
164 ifaceNumber = uid->bInterfaceNumber;
165 ifaceAltSet = uid->bAlternateSetting;
166 protoValue = uid->bInterfaceProtocol;
167 break;
169 if(!valParser.Parse(pp, pcntdn))
170 return false;
171 if(isGoodInterface)
172 if(theXtractor)
173 theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
174 break;
175 //case HID_DESCRIPTOR_HID:
176 // if (!valParser.Parse(pp, pcntdn))
177 // return false;
178 // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
179 // break;
180 default:
181 if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
182 return false;
183 }
184 theBuffer.pValue = varBuffer;
185 stateParseDescr = 0;
186 }
187 return true;
188}
189
190template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
192 Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
193 Notify(PSTR("bDescLength:\t\t"), 0x80);
194 PrintHex<uint8_t > (pDesc->bLength, 0x80);
195
196 Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
197 PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
198
199 Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
200 PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
201
202 Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
203 PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
204
205 Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
206 PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
207
208 for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
210
211 Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
212 PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
213
214 Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
215 PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
216 }
217 Notify(PSTR("\r\n"), 0x80);
218}
219
220
221#endif // __CONFDESCPARSER_H__
bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip)
Definition parsetools.h:77
void Initialize(MultiValueBuffer *pbuf)
Definition parsetools.h:72
void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset)
ConfigDescParser(UsbConfigXtracter *xtractor)
void Initialize(MultiValueBuffer *const pbuf)
Definition parsetools.h:54
bool Parse(uint8_t **pp, uint16_t *pcntdn)
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
#define CP_MASK_COMPARE_PROTOCOL
#define CP_MASK_COMPARE_SUBCLASS
#define CP_MASK_COMPARE_CLASS
#define Notify(...)
Definition message.h:51
uint8_t valueSize
Definition parsetools.h:31
#define USB_DESCRIPTOR_INTERFACE
Definition usb_ch9.h:73
#define HID_DESCRIPTOR_HID
Definition usb_ch9.h:80
#define USB_DESCRIPTOR_CONFIGURATION
Definition usb_ch9.h:71
#define USB_DESCRIPTOR_ENDPOINT
Definition usb_ch9.h:74
#define PSTR(str)