@@ -11,6 +11,8 @@ pub mod descriptor_type {
1111 pub const STRING : u8 = 3 ;
1212 pub const INTERFACE : u8 = 4 ;
1313 pub const ENDPOINT : u8 = 5 ;
14+ pub const BOS : u8 = 0x0f ;
15+ pub const CAPABILITY : u8 = 0x10 ;
1416}
1517
1618/// String descriptor language IDs.
@@ -21,6 +23,16 @@ pub mod lang_id {
2123 pub const ENGLISH_US : u16 = 0x0409 ;
2224}
2325
26+ /// Standard capability descriptor types
27+ #[ allow( missing_docs) ]
28+ pub mod capability_type {
29+ pub const WIRELESS_USB : u8 = 1 ;
30+ pub const USB_2_0_EXTENSION : u8 = 2 ;
31+ pub const SS_USB_DEVICE : u8 = 3 ;
32+ pub const CONTAINER_ID : u8 = 4 ;
33+ pub const PLATFORM : u8 = 5 ;
34+ }
35+
2436/// A writer for USB descriptors.
2537pub struct DescriptorWriter < ' a > {
2638 buf : & ' a mut [ u8 ] ,
@@ -29,6 +41,68 @@ pub struct DescriptorWriter<'a> {
2941 num_endpoints_mark : Option < usize > ,
3042}
3143
44+ /// A writer for Binary Object Store descriptor.
45+ pub struct BosWriter < ' w , ' a : ' w > {
46+ writer : & ' w mut DescriptorWriter < ' a > ,
47+ num_caps_mark : Option < usize > ,
48+ }
49+
50+ impl < ' w , ' a : ' w > BosWriter < ' w , ' a > {
51+ pub ( crate ) fn new ( writer : & ' w mut DescriptorWriter < ' a > ) -> Self {
52+ Self {
53+ writer : writer,
54+ num_caps_mark : None ,
55+ }
56+ }
57+
58+ pub ( crate ) fn bos ( & mut self ) -> Result < ( ) > {
59+ self . num_caps_mark = Some ( self . writer . position + 4 ) ;
60+ self . writer . write (
61+ descriptor_type:: BOS ,
62+ & [
63+ 0x00 , 0x00 , // wTotalLength
64+ 0x00 , // bNumDeviceCaps
65+ ] )
66+ }
67+
68+ /// Writes capability descriptor to a BOS
69+ ///
70+ /// # Arguments
71+ ///
72+ /// * `capability_type` - Type of a capability
73+ /// * `data` - Binary data of the descriptor
74+ pub fn capability ( & mut self , capability_type : u8 , data : & [ u8 ] ) -> Result < ( ) > {
75+ match self . num_caps_mark {
76+ Some ( mark) => self . writer . buf [ mark] += 1 ,
77+ None => return Err ( UsbError :: InvalidState ) ,
78+ }
79+
80+ let mut start = self . writer . position ;
81+ let blen = data. len ( ) ;
82+
83+ if start + blen + 3 > self . writer . buf . len ( )
84+ || ( blen + 3 ) > 255 {
85+ return Err ( UsbError :: BufferOverflow ) ;
86+ }
87+
88+ self . writer . buf [ start] = ( blen + 3 ) as u8 ;
89+ self . writer . buf [ start+1 ] = descriptor_type:: CAPABILITY ;
90+ self . writer . buf [ start+2 ] = capability_type;
91+
92+ start += 3 ;
93+ self . writer . buf [ start..start+blen] . copy_from_slice ( data) ;
94+ self . writer . position = start + blen;
95+
96+ Ok ( ( ) )
97+ }
98+
99+ pub ( crate ) fn end_bos ( & mut self ) {
100+ self . num_caps_mark = None ;
101+ let position = self . writer . position as u16 ;
102+ self . writer . buf [ 2 ..4 ] . copy_from_slice ( & position. to_le_bytes ( ) ) ;
103+ }
104+ }
105+
32106impl DescriptorWriter < ' _ > {
33107 pub ( crate ) fn new ( buf : & mut [ u8 ] ) -> DescriptorWriter < ' _ > {
34108 DescriptorWriter {
@@ -64,11 +138,12 @@ impl DescriptorWriter<'_> {
64138 Ok ( ( ) )
65139 }
66140
141+
67142 pub ( crate ) fn device ( & mut self , config : & device:: Config ) -> Result < ( ) > {
68143 self . write (
69144 descriptor_type:: DEVICE ,
70145 & [
71- 0x00 , 0x02 , // bcdUSB
146+ 0x10 , 0x02 , // bcdUSB 2.1
72147 config. device_class , // bDeviceClass
73148 config. device_sub_class , // bDeviceSubClass
74149 config. device_protocol , // bDeviceProtocol
0 commit comments