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