-
Notifications
You must be signed in to change notification settings - Fork 2
/
usbdevice.h
82 lines (67 loc) · 1.77 KB
/
usbdevice.h
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
#ifndef USBDEVICE_H
#define USBDEVICE_H
#include <codecvt>
#include <locale>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <linux/usb/ch9.h>
/* Although the max len supported is 65536,
* libusb rejects anything over 4096 as "Windows does not support it".
* *facedesk*
*/
#define USB_MAX_CTRL_SIZE 4096
constexpr size_t epAddrToIndex(uint8_t a)
{
return (a & 0x80 >> 3) | (a & 0xF);
}
constexpr uint8_t stringIndex(uint32_t str)
{
return str & 0xFF;
}
constexpr uint16_t stringLangID(uint32_t str)
{
return str >> 16;
}
constexpr uint32_t makeString(uint16_t langid, uint8_t index)
{
return langid << 16 | index;
}
struct USBEndpoint {
usb_endpoint_descriptor desc;
};
struct USBInterface {
usb_interface_descriptor desc;
/* Addresses of endpoints.
* Use epAddrToIndex to get the index into USBDevice::endpoints. */
std::vector<uint8_t> endpoints;
};
struct USBConfiguration {
usb_config_descriptor desc;
std::vector<USBInterface> interfaces;
/* The whole blob receviced, containing IFs, EPs
* and unrecognized descriptors */
std::vector<uint8_t> full_desc;
};
struct USBStrings {
std::set<uint16_t> langs;
// Use makeString as index
std::map<uint32_t, std::u16string> strings;
std::string getUTF8(uint16_t lang, uint8_t index) const
{
auto key = makeString(lang, index);
if(index == 0 || strings.count(key) == 0)
return {};
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv;
return conv.to_bytes(strings.at(key));
}
};
struct USBDevice {
usb_device_descriptor desc;
uint8_t active_config;
std::vector<USBConfiguration> configs;
USBEndpoint endpoints[32];
USBStrings strings;
};
#endif // USBDEVICE_H