capsules_extra/usb/
descriptors.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Platform-independent USB 2.0 protocol library.
6//!
7//! Mostly data types for USB descriptors.
8
9use core::cell::Cell;
10use core::cmp::min;
11use core::fmt;
12
13use kernel::hil::usb::TransferType;
14use kernel::utilities::cells::VolatileCell;
15
16// On Nordic, USB buffers must be 32-bit aligned, with a power-of-2 size. For
17// now we apply these constraints on all platforms.
18#[derive(Default)]
19#[repr(align(4))]
20pub struct Buffer8 {
21    pub buf: [VolatileCell<u8>; 8],
22}
23
24#[repr(align(4))]
25pub struct Buffer64 {
26    pub buf: [VolatileCell<u8>; 64],
27}
28
29impl Default for Buffer64 {
30    fn default() -> Self {
31        Self {
32            buf: [(); 64].map(|()| VolatileCell::default()),
33        }
34    }
35}
36
37/// The data structure sent in a SETUP handshake.
38#[derive(Debug, Copy, Clone)]
39pub struct SetupData {
40    pub request_type: DeviceRequestType,
41    pub request_code: u8,
42    pub value: u16,
43    pub index: u16,
44    pub length: u16,
45}
46
47impl SetupData {
48    /// Create a `SetupData` structure from a packet received from the wire
49    pub fn get(p: &[VolatileCell<u8>]) -> Option<Self> {
50        if p.len() < 8 {
51            return None;
52        }
53        Some(SetupData {
54            request_type: DeviceRequestType(p[0].get()),
55            request_code: p[1].get(),
56            value: get_u16(p[2].get(), p[3].get()),
57            index: get_u16(p[4].get(), p[5].get()),
58            length: get_u16(p[6].get(), p[7].get()),
59        })
60    }
61
62    /// If the `SetupData` represents a standard device request, return it
63    pub fn get_standard_request(&self) -> Option<StandardRequest> {
64        match self.request_type.request_type() {
65            RequestType::Standard => match self.request_code {
66                0 => Some(StandardRequest::GetStatus {
67                    recipient_index: self.index,
68                }),
69                1 => Some(StandardRequest::ClearFeature {
70                    feature: FeatureSelector::get(self.value),
71                    recipient_index: self.index,
72                }),
73                3 => Some(StandardRequest::SetFeature {
74                    feature: FeatureSelector::get(self.value),
75                    test_mode: (self.index >> 8) as u8,
76                    recipient_index: self.index & 0xff,
77                }),
78                5 => Some(StandardRequest::SetAddress {
79                    device_address: self.value,
80                }),
81                6 => get_descriptor_type((self.value >> 8) as u8).map_or(None, |dt| {
82                    Some(StandardRequest::GetDescriptor {
83                        descriptor_type: dt,
84                        descriptor_index: (self.value & 0xff) as u8,
85                        lang_id: self.index,
86                        requested_length: self.length,
87                    })
88                }),
89                7 => get_set_descriptor_type((self.value >> 8) as u8).map_or(None, |dt| {
90                    Some(StandardRequest::SetDescriptor {
91                        descriptor_type: dt,
92                        descriptor_index: (self.value & 0xff) as u8,
93                        lang_id: self.index,
94                        descriptor_length: self.length,
95                    })
96                }),
97                8 => Some(StandardRequest::GetConfiguration),
98                9 => Some(StandardRequest::SetConfiguration {
99                    configuration_value: (self.value & 0xff) as u8,
100                }),
101                10 => Some(StandardRequest::GetInterface {
102                    interface: self.index,
103                }),
104                11 => Some(StandardRequest::SetInterface),
105                12 => Some(StandardRequest::SynchFrame),
106                _ => None,
107            },
108            _ => None,
109        }
110    }
111}
112
113#[derive(Debug)]
114pub enum StandardRequest {
115    GetStatus {
116        recipient_index: u16,
117    },
118    ClearFeature {
119        feature: FeatureSelector,
120        recipient_index: u16,
121    },
122    SetFeature {
123        feature: FeatureSelector,
124        test_mode: u8,
125        recipient_index: u16,
126    },
127    SetAddress {
128        device_address: u16,
129    },
130    GetDescriptor {
131        descriptor_type: DescriptorType,
132        descriptor_index: u8,
133        lang_id: u16,
134        requested_length: u16,
135    },
136    SetDescriptor {
137        descriptor_type: DescriptorType,
138        descriptor_index: u8,
139        lang_id: u16,
140        descriptor_length: u16,
141    },
142    GetConfiguration,
143    SetConfiguration {
144        configuration_value: u8,
145    },
146    GetInterface {
147        interface: u16,
148    },
149    SetInterface,
150    SynchFrame,
151}
152
153#[derive(Copy, Clone, Debug)]
154pub enum DescriptorType {
155    Device = 1,
156    Configuration,
157    String,
158    Interface,
159    Endpoint,
160    DeviceQualifier,
161    OtherSpeedConfiguration,
162    InterfacePower,
163    HID = 0x21,
164    Report = 0x22,
165    CdcInterface = 0x24,
166}
167
168fn get_descriptor_type(byte: u8) -> Option<DescriptorType> {
169    match byte {
170        1 => Some(DescriptorType::Device),
171        2 => Some(DescriptorType::Configuration),
172        3 => Some(DescriptorType::String),
173        4 => Some(DescriptorType::Interface),
174        5 => Some(DescriptorType::Endpoint),
175        6 => Some(DescriptorType::DeviceQualifier),
176        7 => Some(DescriptorType::OtherSpeedConfiguration),
177        8 => Some(DescriptorType::InterfacePower),
178        0x21 => Some(DescriptorType::HID),
179        0x22 => Some(DescriptorType::Report),
180        0x24 => Some(DescriptorType::CdcInterface),
181        _ => None,
182    }
183}
184
185/// Get a descriptor type that is legal in a SetDescriptor request
186fn get_set_descriptor_type(byte: u8) -> Option<DescriptorType> {
187    match get_descriptor_type(byte) {
188        dt @ Some(DescriptorType::Device) => dt,
189        dt @ Some(DescriptorType::Configuration) => dt,
190        dt @ Some(DescriptorType::String) => dt,
191        _ => None,
192    }
193}
194
195#[derive(Copy, Clone)]
196pub struct DeviceRequestType(u8);
197
198impl DeviceRequestType {
199    pub fn transfer_direction(self) -> TransferDirection {
200        match self.0 & (1 << 7) {
201            0 => TransferDirection::HostToDevice,
202            _ => TransferDirection::DeviceToHost,
203        }
204    }
205
206    pub fn request_type(self) -> RequestType {
207        match (self.0 & (0b11 << 5)) >> 5 {
208            0 => RequestType::Standard,
209            1 => RequestType::Class,
210            2 => RequestType::Vendor,
211            _ => RequestType::Reserved,
212        }
213    }
214
215    pub fn recipient(self) -> Recipient {
216        match self.0 & 0b11111 {
217            0 => Recipient::Device,
218            1 => Recipient::Interface,
219            2 => Recipient::Endpoint,
220            3 => Recipient::Other,
221            _ => Recipient::Reserved,
222        }
223    }
224}
225
226impl fmt::Debug for DeviceRequestType {
227    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
228        write!(
229            f,
230            "{{{:?}, {:?}, {:?}}}",
231            self.transfer_direction(),
232            self.request_type(),
233            self.recipient()
234        )
235    }
236}
237
238#[derive(Debug)]
239pub enum TransferDirection {
240    HostToDevice = 0,
241    DeviceToHost = 1,
242}
243
244#[derive(Debug)]
245pub enum RequestType {
246    Standard,
247    Class,
248    Vendor,
249    Reserved,
250}
251
252#[derive(Debug)]
253pub enum Recipient {
254    Device,
255    Interface,
256    Endpoint,
257    Other,
258    Reserved,
259}
260
261#[derive(Debug)]
262pub enum FeatureSelector {
263    DeviceRemoteWakeup,
264    EndpointHalt,
265    TestMode,
266    Unknown,
267}
268
269impl FeatureSelector {
270    fn get(value: u16) -> Self {
271        match value {
272            1 => FeatureSelector::DeviceRemoteWakeup,
273            0 => FeatureSelector::EndpointHalt,
274            2 => FeatureSelector::TestMode,
275            _ => FeatureSelector::Unknown,
276        }
277    }
278}
279
280pub trait Descriptor {
281    /// Serialized size of Descriptor
282    fn size(&self) -> usize;
283
284    /// Serialize the descriptor to a buffer for transmission on the bus
285    fn write_to(&self, buf: &[Cell<u8>]) -> usize {
286        if self.size() > buf.len() {
287            0
288        } else {
289            self.write_to_unchecked(buf)
290        }
291    }
292
293    /// Same as `write_to()`, but doesn't check that `buf` is long enough
294    /// before indexing into it.  This should be used only if the result
295    /// of `size()` is first consulted.
296    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize;
297}
298
299pub struct DeviceDescriptor {
300    /// Valid values include 0x0100 (USB1.0), 0x0110 (USB1.1) and 0x0200 (USB2.0)
301    pub usb_release: u16,
302
303    /// 0x00 means each interface defines its own class.
304    /// 0xFF means the class behavior is defined by the vendor.
305    /// All other values have meaning assigned by USB-IF
306    pub class: u8,
307
308    /// Assigned by USB-IF if `class` is
309    pub subclass: u8,
310
311    /// Assigned by USB-IF if `class` is
312    pub protocol: u8,
313
314    /// Max packet size for endpoint 0.  Must be 8, 16, 32 or 64
315    pub max_packet_size_ep0: u8,
316
317    /// Obtained from USB-IF
318    pub vendor_id: u16,
319
320    /// Together with `vendor_id`, this must be unique to the product
321    pub product_id: u16,
322
323    /// Device release number in binary coded decimal (BCD)
324    pub device_release: u16,
325
326    /// Index of the string descriptor describing manufacturer, or 0 if none
327    pub manufacturer_string: u8,
328
329    /// Index of the string descriptor describing product, or 0 if none
330    pub product_string: u8,
331
332    /// Index of the string descriptor giving device serial number, or 0 if none
333    pub serial_number_string: u8,
334
335    /// Number of configurations the device supports.  Must be at least one
336    pub num_configurations: u8,
337}
338
339impl Default for DeviceDescriptor {
340    fn default() -> Self {
341        DeviceDescriptor {
342            usb_release: 0x0200,
343            class: 0,
344            subclass: 0,
345            protocol: 0,
346            max_packet_size_ep0: 8,
347            vendor_id: 0x6667,
348            product_id: 0xabcd,
349            device_release: 0x0001,
350            manufacturer_string: 0,
351            product_string: 0,
352            serial_number_string: 0,
353            num_configurations: 1,
354        }
355    }
356}
357
358impl Descriptor for DeviceDescriptor {
359    fn size(&self) -> usize {
360        18
361    }
362
363    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
364        buf[0].set(18); // Size of descriptor
365        buf[1].set(DescriptorType::Device as u8);
366        put_u16(&buf[2..4], self.usb_release);
367        buf[4].set(self.class);
368        buf[5].set(self.subclass);
369        buf[6].set(self.protocol);
370        buf[7].set(self.max_packet_size_ep0);
371        put_u16(&buf[8..10], self.vendor_id);
372        put_u16(&buf[10..12], self.product_id);
373        put_u16(&buf[12..14], self.device_release);
374        buf[14].set(self.manufacturer_string);
375        buf[15].set(self.product_string);
376        buf[16].set(self.serial_number_string);
377        buf[17].set(self.num_configurations);
378        18
379    }
380}
381
382/// Buffer for holding the device descriptor.
383// TODO it's dumb that these are Cells, but doing otherwise would require
384// rewriting the `write_to` functions
385pub struct DeviceBuffer {
386    pub buf: [Cell<u8>; 19],
387    pub len: usize,
388}
389
390impl DeviceBuffer {
391    pub fn write_to(&self, buf: &[Cell<u8>]) -> usize {
392        for i in 0..self.len {
393            buf[i].set(self.buf[i].get());
394        }
395        self.len
396    }
397}
398
399/// Buffer for holding the configuration, interface(s), and endpoint(s)
400/// descriptors. Also includes class-specific functional descriptors.
401pub struct DescriptorBuffer {
402    pub buf: [Cell<u8>; 128],
403    pub len: usize,
404}
405
406impl DescriptorBuffer {
407    pub fn write_to(&self, buf: &[Cell<u8>]) -> usize {
408        for i in 0..self.len {
409            buf[i].set(self.buf[i].get());
410        }
411        self.len
412    }
413}
414
415/// Transform descriptor structs into descriptor buffers that can be
416/// passed into the control endpoint handler.
417///
418/// Each endpoint descriptor list corresponds to the matching index in
419/// the interface descriptor list. For example, if the interface
420/// descriptor list contains `[ID1, ID2, ID3]`, and the endpoint
421/// descriptors list is `[[ED1, ED2], [ED3, ED4, ED5], [ED6]]`, then
422/// the third interface descriptor (`ID3`) has one corresponding
423/// endpoint descriptor (`ED6`).
424pub fn create_descriptor_buffers(
425    device_descriptor: DeviceDescriptor,
426    mut configuration_descriptor: ConfigurationDescriptor,
427    interface_descriptor: &mut [InterfaceDescriptor],
428    endpoint_descriptors: &[&[EndpointDescriptor]],
429    hid_descriptor: Option<&HIDDescriptor>,
430    cdc_descriptor: Option<&[CdcInterfaceDescriptor]>,
431) -> (DeviceBuffer, DescriptorBuffer) {
432    // Create device descriptor buffer and fill.
433    // Cell doesn't implement Copy, so here we are.
434    let mut dev_buf = DeviceBuffer {
435        buf: [
436            Cell::default(),
437            Cell::default(),
438            Cell::default(),
439            Cell::default(),
440            Cell::default(),
441            Cell::default(),
442            Cell::default(),
443            Cell::default(),
444            Cell::default(),
445            Cell::default(),
446            Cell::default(),
447            Cell::default(),
448            Cell::default(),
449            Cell::default(),
450            Cell::default(),
451            Cell::default(),
452            Cell::default(),
453            Cell::default(),
454            Cell::default(),
455        ],
456        len: 0,
457    };
458    dev_buf.len = device_descriptor.write_to(&dev_buf.buf);
459
460    // Create other descriptors buffer.
461    // For the moment, the Default trait is not implemented for arrays
462    // of length > 32, and the Cell type is not Copy, so we have to
463    // initialize each element manually.
464    let mut other_buf = DescriptorBuffer {
465        #[rustfmt::skip]
466        buf: [
467            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
468            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
469            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
470            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
471            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
472            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
473            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
474            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
475            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
476            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
477            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
478            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
479            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
480            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
481            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
482            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
483            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
484            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
485            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
486            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
487            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
488            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
489            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
490            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
491            Cell::default(), Cell::default(), Cell::default(), Cell::default(), Cell::default(),
492            Cell::default(), Cell::default(), Cell::default(),
493        ],
494        len: 0,
495    };
496
497    // Setup certain descriptor fields since now we know the tree of
498    // descriptors.
499
500    // Configuration Descriptor. We assume there is only one configuration
501    // descriptor, since this is very common for most USB devices.
502    configuration_descriptor.num_interfaces = interface_descriptor.len() as u8;
503
504    // Calculate the length of all dependent descriptors.
505    // TODO should we be erroring here if len > 128? Otherwise we'll probably
506    // buffer overrun and panic.
507    configuration_descriptor.related_descriptor_length =
508        interface_descriptor.iter().map(|d| d.size()).sum::<usize>()
509            + endpoint_descriptors
510                .iter()
511                .map(|descs| descs.iter().map(|d| d.size()).sum::<usize>())
512                .sum::<usize>()
513            + hid_descriptor.map_or(0, |d| d.size())
514            + cdc_descriptor.map_or(0, |ds| ds.iter().map(|d| d.size()).sum::<usize>());
515
516    // Set the number of endpoints for each interface descriptor.
517    for (i, d) in interface_descriptor.iter_mut().enumerate() {
518        d.num_endpoints = endpoint_descriptors[i].len() as u8;
519    }
520
521    // Fill a single configuration into the buffer and track length.
522    let mut len = 0;
523    len += configuration_descriptor.write_to(&other_buf.buf[len..]);
524
525    // Fill in the interface descriptor and its associated endpoints.
526    for (i, d) in interface_descriptor.iter().enumerate() {
527        // Add the interface descriptor.
528        len += d.write_to(&other_buf.buf[len..]);
529
530        // If there is a HID descriptor, we include
531        // it with the first interface descriptor.
532        if i == 0 {
533            // HID descriptor, if any.
534            if let Some(dh) = hid_descriptor {
535                len += dh.write_to(&other_buf.buf[len..]);
536            }
537        }
538
539        // If there is a CDC descriptor array, we include
540        // it with the first interface descriptor.
541        if i == 0 {
542            // CDC descriptor, if any.
543            if let Some(dcdc) = cdc_descriptor {
544                for dcs in dcdc {
545                    len += dcs.write_to(&other_buf.buf[len..]);
546                }
547            }
548        }
549
550        // Endpoints for each interface.
551        for de in endpoint_descriptors[i] {
552            len += de.write_to(&other_buf.buf[len..]);
553        }
554    }
555    other_buf.len = min(len, other_buf.buf.len());
556
557    // return the two buffers
558    (dev_buf, other_buf)
559}
560
561pub struct ConfigurationDescriptor {
562    pub num_interfaces: u8,
563    pub configuration_value: u8,
564    pub string_index: u8,
565    pub attributes: ConfigurationAttributes,
566    pub max_power: u8, // in 2mA units
567    pub related_descriptor_length: usize,
568}
569
570impl Default for ConfigurationDescriptor {
571    fn default() -> Self {
572        ConfigurationDescriptor {
573            num_interfaces: 1,
574            configuration_value: 1,
575            string_index: 0,
576            attributes: ConfigurationAttributes::new(true, false),
577            max_power: 0, // in 2mA units
578            related_descriptor_length: 0,
579        }
580    }
581}
582
583impl Descriptor for ConfigurationDescriptor {
584    fn size(&self) -> usize {
585        9
586    }
587
588    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
589        buf[0].set(9); // Size of descriptor
590        buf[1].set(DescriptorType::Configuration as u8);
591        put_u16(&buf[2..4], (9 + self.related_descriptor_length) as u16);
592        buf[4].set(self.num_interfaces);
593        buf[5].set(self.configuration_value);
594        buf[6].set(self.string_index);
595        buf[7].set(From::from(self.attributes));
596        buf[8].set(self.max_power);
597        9
598    }
599}
600
601#[derive(Copy, Clone)]
602pub struct ConfigurationAttributes(u8);
603
604impl ConfigurationAttributes {
605    pub fn new(is_self_powered: bool, supports_remote_wakeup: bool) -> Self {
606        ConfigurationAttributes(
607            (1 << 7)
608                | if is_self_powered { 1 << 6 } else { 0 }
609                | if supports_remote_wakeup { 1 << 5 } else { 0 },
610        )
611    }
612}
613
614impl From<ConfigurationAttributes> for u8 {
615    fn from(ca: ConfigurationAttributes) -> u8 {
616        ca.0
617    }
618}
619
620pub struct InterfaceDescriptor {
621    pub interface_number: u8,
622    pub alternate_setting: u8,
623    pub num_endpoints: u8,
624    pub interface_class: u8,
625    pub interface_subclass: u8,
626    pub interface_protocol: u8,
627    pub string_index: u8,
628}
629
630impl Default for InterfaceDescriptor {
631    fn default() -> Self {
632        InterfaceDescriptor {
633            interface_number: 0,
634            alternate_setting: 0,
635            num_endpoints: 0,      // (exluding default control endpoint)
636            interface_class: 0xff, // vendor_specific
637            interface_subclass: 0xab,
638            interface_protocol: 0,
639            string_index: 0,
640        }
641    }
642}
643
644impl Descriptor for InterfaceDescriptor {
645    fn size(&self) -> usize {
646        9
647    }
648
649    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
650        buf[0].set(9); // Size of descriptor
651        buf[1].set(DescriptorType::Interface as u8);
652        buf[2].set(self.interface_number);
653        buf[3].set(self.alternate_setting);
654        buf[4].set(self.num_endpoints);
655        buf[5].set(self.interface_class);
656        buf[6].set(self.interface_subclass);
657        buf[7].set(self.interface_protocol);
658        buf[8].set(self.string_index);
659        9
660    }
661}
662
663pub struct EndpointAddress(u8);
664
665impl EndpointAddress {
666    pub fn new(endpoint: usize, direction: TransferDirection) -> Self {
667        EndpointAddress(
668            endpoint as u8 & 0xf
669                | match direction {
670                    TransferDirection::HostToDevice => 0,
671                    TransferDirection::DeviceToHost => 1,
672                } << 7,
673        )
674    }
675
676    // TODO: Until https://github.com/rust-lang/rust/issues/49146 is resolved, we cannot use `match`
677    // in const functions. As we need to initialize static endpoint addresses for the USB client
678    // capsule, this function offers a workaround to have a const constructor.
679    pub const fn new_const(endpoint: usize, direction: TransferDirection) -> Self {
680        EndpointAddress(endpoint as u8 & 0xf | (direction as u8) << 7)
681    }
682}
683
684pub struct EndpointDescriptor {
685    pub endpoint_address: EndpointAddress,
686    pub transfer_type: TransferType,
687    pub max_packet_size: u16,
688    // Poll for device data every `interval` frames
689    pub interval: u8,
690}
691
692impl Descriptor for EndpointDescriptor {
693    fn size(&self) -> usize {
694        7
695    }
696
697    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
698        let len = self.size();
699        buf[0].set(len as u8);
700        buf[1].set(DescriptorType::Endpoint as u8);
701        buf[2].set(self.endpoint_address.0);
702        // The below implicitly sets Synchronization Type to "No Synchronization" and
703        // Usage Type to "Data endpoint"
704        buf[3].set(self.transfer_type as u8);
705        put_u16(&buf[4..6], self.max_packet_size & 0x7ff_u16);
706        buf[6].set(self.interval);
707        len
708    }
709}
710
711#[derive(Copy, Clone)]
712pub enum HIDCountryCode {
713    NotSupported = 0,
714    Arabic,
715    Belgian,
716    CanadianBilingual,
717    CanadianFrench,
718    CzechRepublic,
719    Danish,
720    Finnish,
721    French,
722    German,
723    Greek,
724    Hebrew,
725    Hungary,
726    InternationalISO,
727    Italian,
728    JapanKatakana,
729    Korean,
730    LatinAmerican,
731    NetherlandsDutch,
732    Norwegian,
733    PersianFarsi,
734    Poland,
735    Portuguese,
736    Russia,
737    Slovakia,
738    Spanish,
739    Swedish,
740    SwissFrench,
741    SwissGerman,
742    Switzerland,
743    Taiwan,
744    TurkishQ,
745    UK,
746    US,
747    Yugoslavia,
748    TurkishF,
749}
750
751pub struct HIDDescriptor<'a> {
752    pub hid_class: u16,
753    pub country_code: HIDCountryCode,
754    pub sub_descriptors: &'a [HIDSubordinateDescriptor],
755}
756
757pub struct HIDSubordinateDescriptor {
758    pub typ: DescriptorType,
759    pub len: u16,
760}
761
762impl Descriptor for HIDDescriptor<'_> {
763    fn size(&self) -> usize {
764        6 + (3 * self.sub_descriptors.len())
765    }
766
767    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
768        let len = self.size();
769        buf[0].set(len as u8);
770        buf[1].set(DescriptorType::HID as u8);
771        put_u16(&buf[2..4], self.hid_class);
772        buf[4].set(self.country_code as u8);
773        buf[5].set(self.sub_descriptors.len() as u8);
774        for (i, desc) in self.sub_descriptors.iter().enumerate() {
775            buf[6 + 3 * i].set(desc.typ as u8);
776            put_u16(&buf[7 + (3 * i)..9 + (3 * i)], desc.len);
777        }
778        len
779    }
780}
781
782pub struct ReportDescriptor<'a> {
783    pub desc: &'a [u8],
784}
785
786impl Descriptor for ReportDescriptor<'_> {
787    fn size(&self) -> usize {
788        self.desc.len()
789    }
790
791    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
792        for (i, x) in self.desc.iter().enumerate() {
793            buf[i].set(*x);
794        }
795        self.size()
796    }
797}
798
799//
800// For CDC
801//
802
803#[derive(Copy, Clone)]
804pub enum CdcInterfaceDescriptorSubType {
805    Header = 0x00,
806    CallManagement = 0x01,
807    AbstractControlManagement = 0x02,
808    DirectLineManagement = 0x03,
809    TelephoneRinger = 0x04,
810    TelephoneCallLineStateReportingCapbailities = 0x05,
811    Union = 0x06,
812    CountrySelection = 0x07,
813    TelephoneOperationalModes = 0x08,
814    UsbTerminal = 0x09,
815    NetworkChannelTerminal = 0x0a,
816    ProtocolUnit = 0x0b,
817    ExtensionUnity = 0x0c,
818    MultiChannelManagement = 0x0d,
819    CapiControlManagement = 0x0e,
820    EthernetNetworking = 0x0f,
821    AtmNetworking = 0x10,
822}
823
824pub struct CdcInterfaceDescriptor {
825    pub subtype: CdcInterfaceDescriptorSubType,
826    pub field1: u8,
827    pub field2: u8,
828}
829
830impl Descriptor for CdcInterfaceDescriptor {
831    fn size(&self) -> usize {
832        3 + match self.subtype {
833            CdcInterfaceDescriptorSubType::Header => 2,
834            CdcInterfaceDescriptorSubType::CallManagement => 2,
835            CdcInterfaceDescriptorSubType::AbstractControlManagement => 1,
836            CdcInterfaceDescriptorSubType::DirectLineManagement => 1,
837            CdcInterfaceDescriptorSubType::TelephoneRinger => 2,
838            CdcInterfaceDescriptorSubType::TelephoneCallLineStateReportingCapbailities => 4,
839            CdcInterfaceDescriptorSubType::Union => 2,
840            CdcInterfaceDescriptorSubType::CountrySelection => 2,
841            CdcInterfaceDescriptorSubType::TelephoneOperationalModes => 1,
842            CdcInterfaceDescriptorSubType::UsbTerminal => 1,
843            CdcInterfaceDescriptorSubType::NetworkChannelTerminal => 1,
844            CdcInterfaceDescriptorSubType::ProtocolUnit => 1,
845            CdcInterfaceDescriptorSubType::ExtensionUnity => 1,
846            CdcInterfaceDescriptorSubType::MultiChannelManagement => 1,
847            CdcInterfaceDescriptorSubType::CapiControlManagement => 1,
848            CdcInterfaceDescriptorSubType::EthernetNetworking => 1,
849            CdcInterfaceDescriptorSubType::AtmNetworking => 1,
850        }
851    }
852
853    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
854        let len = self.size();
855        buf[0].set(len as u8);
856        buf[1].set(DescriptorType::CdcInterface as u8);
857        buf[2].set(self.subtype as u8);
858        if len >= 4 {
859            buf[3].set(self.field1);
860        }
861        if len >= 5 {
862            buf[4].set(self.field2);
863        }
864        len
865    }
866}
867
868/// The data structure sent in a CDC-ACM Set Line Coding message.
869#[derive(Debug, Copy, Clone)]
870pub struct CdcAcmSetLineCodingData {
871    pub baud_rate: u32,
872    pub stop_bits: u8,
873    pub parity: u8,
874    pub data_bits: u8,
875}
876
877impl CdcAcmSetLineCodingData {
878    /// Create a `CdcAcmSetLineCodingData` structure from a packet received
879    /// after the ctrl endpoint setup.
880    pub fn get(p: &[VolatileCell<u8>]) -> Option<Self> {
881        if p.len() < 7 {
882            return None;
883        }
884        Some(CdcAcmSetLineCodingData {
885            baud_rate: get_u32(p[0].get(), p[1].get(), p[2].get(), p[3].get()),
886            stop_bits: p[4].get(),
887            parity: p[5].get(),
888            data_bits: p[6].get(),
889        })
890    }
891}
892
893pub struct LanguagesDescriptor<'a> {
894    pub langs: &'a [u16],
895}
896
897impl Descriptor for LanguagesDescriptor<'_> {
898    fn size(&self) -> usize {
899        2 + (2 * self.langs.len())
900    }
901
902    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
903        let len = self.size();
904        buf[0].set(len as u8);
905        buf[1].set(DescriptorType::String as u8);
906        for (i, lang) in self.langs.iter().enumerate() {
907            put_u16(&buf[2 + (2 * i)..4 + (2 * i)], *lang);
908        }
909        len
910    }
911}
912
913pub struct StringDescriptor<'a> {
914    pub string: &'a str,
915}
916
917impl Descriptor for StringDescriptor<'_> {
918    fn size(&self) -> usize {
919        let mut len = 2;
920        for ch in self.string.chars() {
921            len += 2 * ch.len_utf16();
922        }
923        len
924    }
925
926    // Encode as utf16-le
927    fn write_to_unchecked(&self, buf: &[Cell<u8>]) -> usize {
928        buf[1].set(DescriptorType::String as u8);
929        let mut i = 2;
930        for ch in self.string.chars() {
931            let mut chbuf = [0; 2];
932            for w in ch.encode_utf16(&mut chbuf) {
933                put_u16(&buf[i..i + 2], *w);
934                i += 2;
935            }
936        }
937        buf[0].set(i as u8);
938        i
939    }
940}
941
942/// Parse a `u16` from two bytes as received on the bus
943fn get_u16(b0: u8, b1: u8) -> u16 {
944    (b0 as u16) | ((b1 as u16) << 8)
945}
946
947/// Parse a `u32` from four bytes as received on the bus
948fn get_u32(b0: u8, b1: u8, b2: u8, b3: u8) -> u32 {
949    (b0 as u32) | ((b1 as u32) << 8) | ((b2 as u32) << 16) | ((b3 as u32) << 24)
950}
951
952/// Write a `u16` to a buffer for transmission on the bus
953fn put_u16(buf: &[Cell<u8>], n: u16) {
954    buf[0].set((n & 0xff) as u8);
955    buf[1].set((n >> 8) as u8);
956}