@@ -37,12 +37,47 @@ int HID_::getInterface(uint8_t* interfaceCount)
37
37
};
38
38
return USB_SendControl (0 , &hidInterface, sizeof (hidInterface));
39
39
}
40
+ // Send a USB descriptor string. The string is stored in PROGMEM as a
41
+ // plain ASCII string but is sent out as UTF-16 with the correct 2-byte
42
+ // prefix
43
+ static bool USB_SendStringDescriptor (const char * string_P, u8 string_len, uint8_t flags) {
44
+
45
+ u8 c[2 ] = {(u8 )(2 + string_len * 2 ), 3 };
46
+
47
+ USB_SendControl (0 ,&c,2 );
48
+
49
+ bool pgm = flags & TRANSFER_PGM;
50
+ for (u8 i = 0 ; i < string_len; i++) {
51
+ c[0 ] = pgm ? pgm_read_byte (&string_P[i]) : string_P[i];
52
+ c[1 ] = 0 ;
53
+ int r = USB_SendControl (0 ,&c,2 );
54
+ if (!r) {
55
+ return false ;
56
+ }
57
+ }
58
+ return true ;
59
+ }
40
60
41
61
int HID_::getDescriptor (USBSetup& setup)
42
62
{
63
+
64
+ u8 t = setup.wValueH ;
65
+
66
+ if (USB_STRING_DESCRIPTOR_TYPE == t) {
67
+
68
+ // we place all strings in the 0xFF00-0xFFFE range
69
+ HIDReport* rep = GetFeature (0xFF00 | setup.wValueL );
70
+ if (rep) {
71
+ return USB_SendStringDescriptor ((char *)rep->data , strlen_P ((char *)rep->data ), TRANSFER_PGM);
72
+ }
73
+ else {
74
+ return 0 ;
75
+ }
76
+ }
77
+
43
78
// Check if this is a HID Class Descriptor request
44
79
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0 ; }
45
- if (setup. wValueH != HID_REPORT_DESCRIPTOR_TYPE ) { return 0 ; }
80
+ if (HID_REPORT_DESCRIPTOR_TYPE != t ) { return 0 ; }
46
81
47
82
// In a HID Class Descriptor wIndex cointains the interface number
48
83
if (setup.wIndex != pluggedInterface) { return 0 ; }
@@ -65,12 +100,23 @@ int HID_::getDescriptor(USBSetup& setup)
65
100
66
101
uint8_t HID_::getShortName (char *name)
67
102
{
103
+ if (serial) {
104
+ for (byte i=0 ; i<strlen_P (serial); i++) {
105
+ name[i] = pgm_read_byte_near (serial + i);
106
+ }
107
+ return strlen_P (serial);
108
+ }
109
+ else {
110
+
111
+ // default serial number
112
+
68
113
name[0 ] = ' H' ;
69
114
name[1 ] = ' I' ;
70
115
name[2 ] = ' D' ;
71
116
name[3 ] = ' A' + (descriptorSize & 0x0F );
72
117
name[4 ] = ' A' + ((descriptorSize >> 4 ) & 0x0F );
73
118
return 5 ;
119
+ }
74
120
}
75
121
76
122
void HID_::AppendDescriptor (HIDSubDescriptor *node)
@@ -87,7 +133,7 @@ void HID_::AppendDescriptor(HIDSubDescriptor *node)
87
133
descriptorSize += node->length ;
88
134
}
89
135
90
- int HID_::SetFeature (uint8_t id, const void * data, int len)
136
+ int HID_::SetFeature (uint16_t id, const void * data, int len)
91
137
{
92
138
if (!rootReport) {
93
139
rootReport = new HIDReport (id, data, len);
@@ -111,7 +157,7 @@ int HID_::SetFeature(uint8_t id, const void* data, int len)
111
157
return reportCount;
112
158
}
113
159
114
- bool HID_::LockFeature (uint8_t id, bool lock) {
160
+ bool HID_::LockFeature (uint16_t id, bool lock) {
115
161
if (rootReport) {
116
162
HIDReport* current;
117
163
for (current = rootReport;current; current=current->next ) {
@@ -125,7 +171,7 @@ bool HID_::LockFeature(uint8_t id, bool lock) {
125
171
}
126
172
127
173
128
- int HID_::SendReport (uint8_t id, const void * data, int len)
174
+ int HID_::SendReport (uint16_t id, const void * data, int len)
129
175
{
130
176
auto ret = USB_Send (HID_TX, &id, 1 );
131
177
if (ret < 0 ) return ret;
@@ -134,6 +180,18 @@ int HID_::SendReport(uint8_t id, const void* data, int len)
134
180
return ret + ret2;
135
181
}
136
182
183
+ HIDReport* HID_::GetFeature (uint16_t id)
184
+ {
185
+ HIDReport* current;
186
+ int i=0 ;
187
+ for (current=rootReport; current && i<reportCount; current=current->next , i++) {
188
+ if (id == current->id ) {
189
+ return current;
190
+ }
191
+ }
192
+ return (HIDReport*) NULL ;
193
+ }
194
+
137
195
bool HID_::setup (USBSetup& setup)
138
196
{
139
197
if (pluggedInterface != setup.wIndex ) {
@@ -149,25 +207,16 @@ bool HID_::setup(USBSetup& setup)
149
207
150
208
if (setup.wValueH == HID_REPORT_TYPE_FEATURE)
151
209
{
152
- // dbg->print(setup.wValueL);
153
- HIDReport* current;
154
- int i=0 ;
155
- for (current=rootReport; current && i<reportCount; current=current->next , i++) {
156
- // dbg->print(":");
157
- // dbg->print(current->id);
158
- // dbg->print(" ");
159
- // dbg->print(current->length);
160
- // dbg->print(" ");
161
- if (setup.wValueL == current->id ) {
162
- if (USB_SendControl (0 , &(current->id ), 1 )<0 ||
163
- USB_SendControl (0 , current->data , current->length )<0 )
164
- return false ;
165
-
166
- break ;
167
- }
168
- // dbg->println("");
210
+
211
+ HIDReport* current = GetFeature (setup.wValueL );
212
+ if (current){
213
+ if (USB_SendControl (0 , &(current->id ), 1 )>0 &&
214
+ USB_SendControl (0 , current->data , current->length )>0 )
215
+ return true ;
169
216
}
170
217
218
+ return false ;
219
+
171
220
}
172
221
return true ;
173
222
}
@@ -193,14 +242,22 @@ bool HID_::setup(USBSetup& setup)
193
242
return true ;
194
243
}
195
244
if (request == HID_SET_REPORT)
196
- {
197
- // uint8_t reportID = setup.wValueL;
198
- // uint16_t length = setup.wLength;
199
- // uint8_t data[length];
200
- // Make sure to not read more data than USB_EP_SIZE.
201
- // You can read multiple times through a loop.
202
- // The first byte (may!) contain the reportID on a multreport.
203
- // USB_RecvControl(data, length);
245
+ {
246
+ if (setup.wValueH == HID_REPORT_TYPE_FEATURE)
247
+ {
248
+
249
+ HIDReport* current = GetFeature (setup.wValueL );
250
+ if (!current) return false ;
251
+ if (setup.wLength != current->length + 1 ) return false ;
252
+ uint8_t * data = new uint8_t [setup.wLength ];
253
+ USB_RecvControl (data, setup.wLength );
254
+ if (*data != current->id ) return false ;
255
+ memcpy ((uint8_t *)current->data , data+1 , current->length );
256
+ delete[] data;
257
+ return true ;
258
+
259
+ }
260
+
204
261
}
205
262
}
206
263
0 commit comments