blob: 6463ba465b5c2b78e25c01dc96a41df3609c904f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#ifndef USB_STRINGS_H
#define USB_STRINGS_H
#include <usb/usb.h>
uint32_t serial_num() {
uint32_t* uid = (uint32_t*)0x1ffff7ac;
return uid[0] * uid[1] * uid[2];
}
class USB_strings : public USB_class_driver {
private:
USB_generic& usb;
const uint8_t* label;
public:
USB_strings(USB_generic& usbd, const uint8_t* l) : usb(usbd), label(l) {
usb.register_driver(this);
}
protected:
virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) {
// Get string descriptor.
if(bmRequestType == 0x80 && bRequest == 0x06 && (wValue & 0xff00) == 0x0300) {
const void* desc = nullptr;
uint16_t buf[64] = {0x300};
uint32_t i = 1;
switch(wValue & 0xff) {
case 0:
desc = u"\u0304\u0409";
break;
case 1:
desc = u"\u0308zyp";
break;
case 2:
for(const char* p = "arcin"; *p; p++) {
buf[i++] = *p;
}
if(label[0]) {
buf[i++] = ' ';
buf[i++] = '(';
for(const uint8_t* p = label; *p; p++) {
buf[i++] = *p;
}
buf[i++] = ')';
}
buf[0] |= i * 2;
desc = buf;
break;
case 3:
{
buf[0] = 0x0312;
uint32_t id = serial_num();
for(int i = 8; i > 0; i--) {
buf[i] = (id & 0xf) > 9 ? 'A' + (id & 0xf) - 0xa : '0' + (id & 0xf);
id >>= 4;
}
desc = buf;
}
break;
}
if(!desc) {
return SetupStatus::Unhandled;
}
uint8_t len = *(uint8_t*)desc;
if(len > wLength) {
len = wLength;
}
usb.write(0, (uint32_t*)desc, len);
return SetupStatus::Ok;
}
return SetupStatus::Unhandled;
}
};
#endif
|