USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
confdescparser.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 #if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__)
18 #error "Never include confdescparser.h directly; include Usb.h instead"
19 #else
20 
21 #define __CONFDESCPARSER_H__
22 
23 
25 public:
26  //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
27  //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
28  virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep) = 0;
29 };
30 
31 #define CP_MASK_COMPARE_CLASS 1
32 #define CP_MASK_COMPARE_SUBCLASS 2
33 #define CP_MASK_COMPARE_PROTOCOL 4
34 #define CP_MASK_COMPARE_ALL 7
35 
36 // Configuration Descriptor Parser Class Template
37 
38 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
40  UsbConfigXtracter *theXtractor;
41  MultiValueBuffer theBuffer;
42  MultiByteValueParser valParser;
43  ByteSkipper theSkipper;
44  uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
45 
46  uint8_t stateParseDescr; // ParseDescriptor state
47 
48  uint8_t dscrLen; // Descriptor length
49  uint8_t dscrType; // Descriptor type
50 
51  bool isGoodInterface; // Apropriate interface flag
52  uint8_t confValue; // Configuration value
53  uint8_t protoValue; // Protocol value
54  uint8_t ifaceNumber; // Interface number
55  uint8_t ifaceAltSet; // Interface alternate settings
56 
57  bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
58 
59  void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
60 
61 public:
63  virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
64 };
65 
66 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
68 theXtractor(xtractor),
69 stateParseDescr(0),
70 dscrLen(0),
71 dscrType(0) {
72  theBuffer.pValue = varBuffer;
73  valParser.Initialize(&theBuffer);
74  theSkipper.Initialize(&theBuffer);
75 };
76 
77 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
78 void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) {
79  uint16_t cntdn = (uint16_t) len;
80  uint8_t *p = (uint8_t*) pbuf;
81 
82  while(cntdn)
83  if(!ParseDescriptor(&p, &cntdn))
84  return;
85 }
86 
87 /* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
88  compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
89 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
91  switch(stateParseDescr) {
92  case 0:
93  theBuffer.valueSize = 2;
94  valParser.Initialize(&theBuffer);
95  stateParseDescr = 1;
96  case 1:
97  if(!valParser.Parse(pp, pcntdn))
98  return false;
99  dscrLen = *((uint8_t*) theBuffer.pValue);
100  dscrType = *((uint8_t*) theBuffer.pValue + 1);
101  stateParseDescr = 2;
102  case 2:
103  // This is a sort of hack. Assuming that two bytes are all ready in the buffer
104  // the pointer is positioned two bytes ahead in order for the rest of descriptor
105  // to be read right after the size and the type fields.
106  // This should be used carefully. varBuffer should be used directly to handle data
107  // in the buffer.
108  theBuffer.pValue = varBuffer + 2;
109  stateParseDescr = 3;
110  case 3:
111  switch(dscrType) {
113  isGoodInterface = false;
115  theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
116  break;
118  theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
119  break;
120  case HID_DESCRIPTOR_HID:
121  theBuffer.valueSize = dscrLen - 2;
122  break;
123  }
124  valParser.Initialize(&theBuffer);
125  stateParseDescr = 4;
126  case 4:
127  switch(dscrType) {
129  if(!valParser.Parse(pp, pcntdn))
130  return false;
131  confValue = ((USB_CONFIGURATION_DESCRIPTOR*) varBuffer)->bConfigurationValue;
132  break;
134  if(!valParser.Parse(pp, pcntdn))
135  return false;
136  if((MASK & CP_MASK_COMPARE_CLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceClass != CLASS_ID)
137  break;
138  if((MASK & CP_MASK_COMPARE_SUBCLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceSubClass != SUBCLASS_ID)
139  break;
140  if((MASK & CP_MASK_COMPARE_PROTOCOL) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol != PROTOCOL_ID)
141  break;
142 
143  isGoodInterface = true;
144  ifaceNumber = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceNumber;
145  ifaceAltSet = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bAlternateSetting;
146  protoValue = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol;
147  break;
149  if(!valParser.Parse(pp, pcntdn))
150  return false;
151  if(isGoodInterface)
152  if(theXtractor)
153  theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer);
154  break;
155  //case HID_DESCRIPTOR_HID:
156  // if (!valParser.Parse(pp, pcntdn))
157  // return false;
158  // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
159  // break;
160  default:
161  if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
162  return false;
163  }
164  theBuffer.pValue = varBuffer;
165  stateParseDescr = 0;
166  }
167  return true;
168 }
169 
170 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
172  Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
173  Notify(PSTR("bDescLength:\t\t"), 0x80);
174  PrintHex<uint8_t > (pDesc->bLength, 0x80);
175 
176  Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
177  PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
178 
179  Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
180  PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
181 
182  Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
183  PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
184 
185  Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
186  PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
187 
188  //Notify(PSTR("\r\nbDescrType:\t\t"));
189  //PrintHex<uint8_t>(pDesc->bDescrType);
190  //
191  //Notify(PSTR("\r\nwDescriptorLength:\t"));
192  //PrintHex<uint16_t>(pDesc->wDescriptorLength);
193 
194  for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
196 
197  Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
198  PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
199 
200  Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
201  PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
202  }
203  Notify(PSTR("\r\n"), 0x80);
204 }
205 
206 
207 #endif // __CONFDESCPARSER_H__
#define CP_MASK_COMPARE_PROTOCOL
#define USB_DESCRIPTOR_ENDPOINT
Definition: usb_ch9.h:67
uint8_t bLength
Definition: usb_ch9.h:152
virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset)
#define CP_MASK_COMPARE_CLASS
#define USB_DESCRIPTOR_CONFIGURATION
Definition: usb_ch9.h:64
#define Notify(...)
Definition: message.h:44
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)=0
void Initialize(MultiValueBuffer *pbuf)
Definition: parsetools.h:60
uint8_t bCountryCode
Definition: usb_ch9.h:155
#define CP_MASK_COMPARE_SUBCLASS
uint8_t bNumDescriptors
Definition: usb_ch9.h:156
uint8_t bDescriptorType
Definition: usb_ch9.h:153
#define HID_DESCRIPTOR_HID
Definition: hid.h:74
ConfigDescParser(UsbConfigXtracter *xtractor)
void Initialize(MultiValueBuffer *const pbuf)
Definition: parsetools.h:42
uint16_t bcdHID
Definition: usb_ch9.h:154
uint8_t bDescrType
Definition: usb_ch9.h:157
#define USB_DESCRIPTOR_INTERFACE
Definition: usb_ch9.h:66