1use num_enum::TryFromPrimitive;
2use usb_device::class_prelude::*;
3use usb_device::control::RequestType;
4
5const fn u16_low(val: u16) -> u8 {
6 val.to_le_bytes()[0]
7}
8
9const fn u16_high(val: u16) -> u8 {
10 val.to_le_bytes()[1]
11}
12
13#[allow(non_snake_case)]
14#[repr(u16)]
15#[derive(TryFromPrimitive)]
16pub enum OSFeatureDescriptorType {
17 CompatibleID = 4,
18 Properties = 5,
19 Descriptor = 7,
20}
21
22const LEN: u16 = 330;
23
24const VENDOR_CODE: u8 = 0x41;
25
26const DAP_V2_INTERFACE: u8 = 3;
27const DFU_INTERFACE: u8 = 4;
28
29enum MsDescriptorTypes {
30 Header = 0x0,
31 HeaderConfiguration = 0x1,
32 HeaderFunction = 0x2,
33 CompatibleId = 0x3,
34 RegistryProperty = 0x4,
35}
36
37const MS_OS_DESCRIPTOR: [u8; LEN as usize] = [
47 0xa,
48 0x00, MsDescriptorTypes::Header as u8,
50 0x00, 0x00,
52 0x00,
53 0x03,
54 0x06, u16_low(LEN),
56 u16_high(LEN), 0x8,
59 0x0, MsDescriptorTypes::HeaderFunction as u8,
61 0x00,
62 DAP_V2_INTERFACE, 0x0, 8 + 20 + 132,
65 0x00, 20,
68 0x00, MsDescriptorTypes::CompatibleId as u8,
70 0x00,
71 b'W',
72 b'I',
73 b'N',
74 b'U',
75 b'S',
76 b'B',
77 0x00,
78 0x00, 0x00,
80 0x00,
81 0x00,
82 0x00,
83 0x00,
84 0x00,
85 0x00,
86 0x00, 80 + 2 + 42 + 2 + 2 + 2 + 2,
89 0x00, MsDescriptorTypes::RegistryProperty as u8,
91 0x00,
92 7,
93 0, 42,
95 0x00, b'D',
97 0,
98 b'e',
99 0,
100 b'v',
101 0,
102 b'i',
103 0,
104 b'c',
105 0,
106 b'e',
107 0,
108 b'I',
109 0,
110 b'n',
111 0,
112 b't',
113 0,
114 b'e',
115 0,
116 b'r',
117 0,
118 b'f',
119 0,
120 b'a',
121 0,
122 b'c',
123 0,
124 b'e',
125 0,
126 b'G',
127 0,
128 b'U',
129 0,
130 b'I',
131 0,
132 b'D',
133 0,
134 b's',
135 0,
136 0,
137 0,
138 80,
139 0x00, b'{',
141 0,
142 b'C',
143 0,
144 b'D',
145 0,
146 b'B',
147 0,
148 b'3',
149 0,
150 b'B',
151 0,
152 b'5',
153 0,
154 b'A',
155 0,
156 b'D',
157 0,
158 b'-',
159 0,
160 b'2',
161 0,
162 b'9',
163 0,
164 b'3',
165 0,
166 b'B',
167 0,
168 b'-',
169 0,
170 b'4',
171 0,
172 b'6',
173 0,
174 b'6',
175 0,
176 b'3',
177 0,
178 b'-',
179 0,
180 b'A',
181 0,
182 b'A',
183 0,
184 b'3',
185 0,
186 b'6',
187 0,
188 b'-',
189 0,
190 b'1',
191 0,
192 b'A',
193 0,
194 b'A',
195 0,
196 b'E',
197 0,
198 b'4',
199 0,
200 b'6',
201 0,
202 b'4',
203 0,
204 b'6',
205 0,
206 b'3',
207 0,
208 b'7',
209 0,
210 b'7',
211 0,
212 b'6',
213 0,
214 b'}',
215 0,
216 0,
217 0,
218 0,
219 0,
220 0x8,
222 0x0, MsDescriptorTypes::HeaderFunction as u8,
224 0x00,
225 DFU_INTERFACE, 0x0, 8 + 20 + 132, 0x00, 20,
231 0x00, MsDescriptorTypes::CompatibleId as u8,
233 0x00,
234 b'W',
235 b'I',
236 b'N',
237 b'U',
238 b'S',
239 b'B',
240 0x00,
241 0x00, 0x00,
243 0x00,
244 0x00,
245 0x00,
246 0x00,
247 0x00,
248 0x00,
249 0x00, 80 + 2 + 42 + 2 + 2 + 2 + 2,
252 0x00, MsDescriptorTypes::RegistryProperty as u8,
254 0x00,
255 7,
256 0, 42,
258 0x00, b'D',
260 0,
261 b'e',
262 0,
263 b'v',
264 0,
265 b'i',
266 0,
267 b'c',
268 0,
269 b'e',
270 0,
271 b'I',
272 0,
273 b'n',
274 0,
275 b't',
276 0,
277 b'e',
278 0,
279 b'r',
280 0,
281 b'f',
282 0,
283 b'a',
284 0,
285 b'c',
286 0,
287 b'e',
288 0,
289 b'G',
290 0,
291 b'U',
292 0,
293 b'I',
294 0,
295 b'D',
296 0,
297 b's',
298 0,
299 0,
300 0,
301 80,
302 0x00, b'{',
304 0,
305 b'A',
306 0,
307 b'5',
308 0,
309 b'D',
310 0,
311 b'C',
312 0,
313 b'B',
314 0,
315 b'F',
316 0,
317 b'1',
318 0,
319 b'0',
320 0,
321 b'-',
322 0,
323 b'6',
324 0,
325 b'5',
326 0,
327 b'3',
328 0,
329 b'0',
330 0,
331 b'-',
332 0,
333 b'1',
334 0,
335 b'1',
336 0,
337 b'D',
338 0,
339 b'2',
340 0,
341 b'-',
342 0,
343 b'9',
344 0,
345 b'0',
346 0,
347 b'1',
348 0,
349 b'F',
350 0,
351 b'-',
352 0,
353 b'0',
354 0,
355 b'0',
356 0,
357 b'C',
358 0,
359 b'0',
360 0,
361 b'4',
362 0,
363 b'F',
364 0,
365 b'B',
366 0,
367 b'9',
368 0,
369 b'5',
370 0,
371 b'1',
372 0,
373 b'E',
374 0,
375 b'D',
376 0,
377 b'}',
378 0,
379 0,
380 0,
381 0,
382 0,
383];
384
385pub struct MicrosoftDescriptors;
386
387impl<B: UsbBus> UsbClass<B> for MicrosoftDescriptors {
388 fn get_bos_descriptors(&self, writer: &mut BosWriter) -> usb_device::Result<()> {
389 writer.capability(
390 5, &[
392 0, 0xdf,
394 0x60,
395 0xdd,
396 0xd8,
397 0x89,
398 0x45,
399 0xc7,
400 0x4c,
401 0x9c,
402 0xd2,
403 0x65,
404 0x9d,
405 0x9e,
406 0x64,
407 0x8A,
408 0x9f, 0x00,
410 0x00,
411 0x03,
412 0x06, u16_low(LEN),
414 u16_high(LEN), VENDOR_CODE,
416 0x0, ],
418 )
419 }
420
421 fn control_in(&mut self, xfer: ControlIn<B>) {
422 let req = xfer.request();
423 if req.request_type != RequestType::Vendor {
424 return;
425 }
426
427 if req.request == VENDOR_CODE {
430 if req.index == 0x7 {
431 xfer.accept_with_static(&MS_OS_DESCRIPTOR).ok();
432 } else {
433 xfer.reject().ok();
434 }
435 }
436 }
437}