@@ -11,6 +11,7 @@ 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 IAD : u8 = 11 ;
1415 pub const BOS : u8 = 15 ;
1516 pub const CAPABILITY : u8 = 16 ;
1617}
@@ -39,6 +40,7 @@ pub struct DescriptorWriter<'a> {
3940 position : usize ,
4041 num_interfaces_mark : Option < usize > ,
4142 num_endpoints_mark : Option < usize > ,
43+ write_iads : bool ,
4244}
4345
4446impl DescriptorWriter < ' _ > {
@@ -48,6 +50,7 @@ impl DescriptorWriter<'_> {
4850 position : 0 ,
4951 num_interfaces_mark : None ,
5052 num_endpoints_mark : None ,
53+ write_iads : false ,
5154 }
5255 }
5356
@@ -98,6 +101,8 @@ impl DescriptorWriter<'_> {
98101 pub ( crate ) fn configuration ( & mut self , config : & device:: Config ) -> Result < ( ) > {
99102 self . num_interfaces_mark = Some ( self . position + 4 ) ;
100103
104+ self . write_iads = config. composite_with_iads ;
105+
101106 self . write (
102107 descriptor_type:: CONFIGURATION ,
103108 & [
@@ -121,6 +126,42 @@ impl DescriptorWriter<'_> {
121126 self . buf [ 2 ..4 ] . copy_from_slice ( & position. to_le_bytes ( ) ) ;
122127 }
123128
129+ /// Writes a interface association descriptor. Call from `UsbClass::get_configuration_descriptors`
130+ /// before writing the USB class or function's interface descriptors if your class has more than
131+ /// one interface and wants to play nicely with composite devices on Windows. If the USB device
132+ /// hosting the class was not configured as composite with IADs enabled, calling this function
133+ /// does nothing, so it is safe to call from libraries.
134+ ///
135+ /// # Arguments
136+ ///
137+ /// * `first_interface` - Number of the function's first interface, previously allocated with
138+ /// [`UsbBusAllocator::interface`](crate::bus::UsbBusAllocator::interface).
139+ /// * `interface_count` - Number of interfaces in the function.
140+ /// * `function_class` - Class code assigned by USB.org. Use `0xff` for vendor-specific devices
141+ /// that do not conform to any class.
142+ /// * `function_sub_class` - Sub-class code. Depends on class.
143+ /// * `function_protocol` - Protocol code. Depends on class and sub-class.
144+ pub fn iad ( & mut self , first_interface : InterfaceNumber , interface_count : u8 ,
145+ function_class : u8 , function_sub_class : u8 , function_protocol : u8 ) -> Result < ( ) >
146+ {
147+ if !self . write_iads {
148+ return Ok ( ( ) ) ;
149+ }
150+
151+ self . write (
152+ descriptor_type:: IAD ,
153+ & [
154+ first_interface. into ( ) , // bFirstInterface
155+ interface_count, // bInterfaceCount
156+ function_class,
157+ function_sub_class,
158+ function_protocol,
159+ 0
160+ ] ) ?;
161+
162+ Ok ( ( ) )
163+ }
164+
124165 /// Writes a interface descriptor.
125166 ///
126167 /// # Arguments
0 commit comments