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