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 
24 public:
25  //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
26  //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
27  virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep) = 0;
28 };
29 
30 #define CP_MASK_COMPARE_CLASS 1
31 #define CP_MASK_COMPARE_SUBCLASS 2
32 #define CP_MASK_COMPARE_PROTOCOL 4
33 #define CP_MASK_COMPARE_ALL 7
34 
35 // Configuration Descriptor Parser Class Template
36 
37 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
39  UsbConfigXtracter *theXtractor;
40  MultiValueBuffer theBuffer;
41  MultiByteValueParser valParser;
42  ByteSkipper theSkipper;
43  uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
44 
45  uint8_t stateParseDescr; // ParseDescriptor state
46 
47  uint8_t dscrLen; // Descriptor length
48  uint8_t dscrType; // Descriptor type
49 
50  bool isGoodInterface; // Apropriate interface flag
51  uint8_t confValue; // Configuration value
52  uint8_t protoValue; // Protocol value
53  uint8_t ifaceNumber; // Interface number
54  uint8_t ifaceAltSet; // Interface alternate settings
55 
56  bool UseOr;
57  bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
58  void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
59 
60 public:
61 
62  void SetOR(void) {
63  UseOr = true;
64  }
66  virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
67 };
68 
69 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
71 theXtractor(xtractor),
72 stateParseDescr(0),
73 dscrLen(0),
74 dscrType(0),
75 UseOr(false) {
76  theBuffer.pValue = varBuffer;
77  valParser.Initialize(&theBuffer);
78  theSkipper.Initialize(&theBuffer);
79 };
80 
81 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
82 void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) {
83  uint16_t cntdn = (uint16_t)len;
84  uint8_t *p = (uint8_t*)pbuf;
85 
86  while(cntdn)
87  if(!ParseDescriptor(&p, &cntdn))
88  return;
89 }
90 
91 /* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
92  compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
93 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
95  USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
96  USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
97  switch(stateParseDescr) {
98  case 0:
99  theBuffer.valueSize = 2;
100  valParser.Initialize(&theBuffer);
101  stateParseDescr = 1;
102  case 1:
103  if(!valParser.Parse(pp, pcntdn))
104  return false;
105  dscrLen = *((uint8_t*)theBuffer.pValue);
106  dscrType = *((uint8_t*)theBuffer.pValue + 1);
107  stateParseDescr = 2;
108  case 2:
109  // This is a sort of hack. Assuming that two bytes are all ready in the buffer
110  // the pointer is positioned two bytes ahead in order for the rest of descriptor
111  // to be read right after the size and the type fields.
112  // This should be used carefully. varBuffer should be used directly to handle data
113  // in the buffer.
114  theBuffer.pValue = varBuffer + 2;
115  stateParseDescr = 3;
116  case 3:
117  switch(dscrType) {
119  isGoodInterface = false;
121  theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2;
122  break;
124  theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2;
125  break;
126  case HID_DESCRIPTOR_HID:
127  theBuffer.valueSize = dscrLen - 2;
128  break;
129  }
130  valParser.Initialize(&theBuffer);
131  stateParseDescr = 4;
132  case 4:
133  switch(dscrType) {
135  if(!valParser.Parse(pp, pcntdn))
136  return false;
137  confValue = ucd->bConfigurationValue;
138  break;
140  if(!valParser.Parse(pp, pcntdn))
141  return false;
142  if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID)
143  break;
144  if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID)
145  break;
146  if(UseOr) {
147  if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol)))
148  break;
149  } else {
150  if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID)
151  break;
152  }
153  isGoodInterface = true;
154  ifaceNumber = uid->bInterfaceNumber;
155  ifaceAltSet = uid->bAlternateSetting;
156  protoValue = uid->bInterfaceProtocol;
157  break;
159  if(!valParser.Parse(pp, pcntdn))
160  return false;
161  if(isGoodInterface)
162  if(theXtractor)
163  theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
164  break;
165  //case HID_DESCRIPTOR_HID:
166  // if (!valParser.Parse(pp, pcntdn))
167  // return false;
168  // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
169  // break;
170  default:
171  if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
172  return false;
173  }
174  theBuffer.pValue = varBuffer;
175  stateParseDescr = 0;
176  }
177  return true;
178 }
179 
180 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
182  Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
183  Notify(PSTR("bDescLength:\t\t"), 0x80);
184  PrintHex<uint8_t > (pDesc->bLength, 0x80);
185 
186  Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
187  PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
188 
189  Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
190  PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
191 
192  Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
193  PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
194 
195  Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
196  PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
197 
198  //Notify(PSTR("\r\nbDescrType:\t\t"));
199  //PrintHex<uint8_t>(pDesc->bDescrType);
200  //
201  //Notify(PSTR("\r\nwDescriptorLength:\t"));
202  //PrintHex<uint16_t>(pDesc->wDescriptorLength);
203 
204  for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
206 
207  Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
208  PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
209 
210  Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
211  PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
212  }
213  Notify(PSTR("\r\n"), 0x80);
214 }
215 
216 
217 #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
void SetOR(void)
uint8_t bNumDescriptors
Definition: usb_ch9.h:156
uint8_t bDescriptorType
Definition: usb_ch9.h:153
#define HID_DESCRIPTOR_HID
Definition: hid.h:77
ConfigDescParser(UsbConfigXtracter *xtractor)
void Initialize(MultiValueBuffer *const pbuf)
Definition: parsetools.h:42
uint8_t bInterfaceSubClass
Definition: usb_ch9.h:135
uint16_t bcdHID
Definition: usb_ch9.h:154
uint8_t bInterfaceProtocol
Definition: usb_ch9.h:136
uint8_t bDescrType
Definition: usb_ch9.h:157
#define USB_DESCRIPTOR_INTERFACE
Definition: usb_ch9.h:66