@@ -197,7 +197,6 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint
197197//--------------------------------------------------------------------+
198198bool midih_open (uint8_t rhport , uint8_t dev_addr , tusb_desc_interface_t const * desc_itf , uint16_t max_len ) {
199199 (void ) rhport ;
200-
201200 TU_VERIFY (TUSB_CLASS_AUDIO == desc_itf -> bInterfaceClass );
202201 const uint8_t * p_end = ((const uint8_t * ) desc_itf ) + max_len ;
203202 const uint8_t * p_desc = (const uint8_t * ) desc_itf ;
@@ -211,7 +210,15 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
211210 desc_cb .jack_num = 0 ;
212211
213212 // There can be just a MIDI or an Audio + MIDI interface
214- // If there is Audio Control Interface + Audio Header descriptor, skip it
213+ // If there is Audio Control Interface + Audio Header descriptor, then skip it.
214+ // If there is an Audio Control Interface + Audio Streaming Interface, then
215+ // ignore the Audio Streaming Interface.
216+ // Future:
217+ // Note that if this driver is used with an USB Audio Streaming host driver,
218+ // then call that driver first. If the MIDI interface comes before the
219+ // audio streaming interface, then the audio driver will have to call this
220+ // driver after parsing the audio control interface and then resume parsing
221+ // the streaming audio interface.
215222 if (AUDIO_SUBCLASS_CONTROL == desc_itf -> bInterfaceSubClass ) {
216223 TU_VERIFY (max_len > 2 * sizeof (tusb_desc_interface_t ) + sizeof (audio_desc_cs_ac_interface_t ));
217224
@@ -222,12 +229,21 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
222229
223230 p_desc = tu_desc_next (p_desc );
224231 desc_itf = (const tusb_desc_interface_t * )p_desc ;
225- TU_VERIFY (TUSB_CLASS_AUDIO == desc_itf -> bInterfaceClass );
226232 p_midi -> itf_count = 1 ;
227- }
233+ // See issue #3159
234+ while ((p_desc < p_end ) && (tu_desc_next (p_desc ) <= p_end ) && (desc_itf -> bDescriptorType != TUSB_DESC_INTERFACE || (desc_itf -> bInterfaceClass == TUSB_CLASS_AUDIO && desc_itf -> bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING )))
235+ {
236+ if (desc_itf -> bDescriptorType == TUSB_DESC_INTERFACE && desc_itf -> bAlternateSetting == 0 ) {
237+ p_midi -> itf_count ++ ;
238+ }
239+ p_desc = tu_desc_next (p_desc );
240+ desc_itf = (tusb_desc_interface_t const * )p_desc ;
241+ }
242+ TU_VERIFY (p_desc < p_end ); // If MIDI interface comes after Audio Streaming, then max_len did not include the MIDI interface descriptor
243+ TU_VERIFY (TUSB_CLASS_AUDIO == desc_itf -> bInterfaceClass );
244+ }
228245 TU_VERIFY (AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf -> bInterfaceSubClass );
229-
230- TU_LOG_DRV ("MIDI opening Interface %u (addr = %u)\r\n" , desc_itf -> bInterfaceNumber , dev_addr );
246+
231247 p_midi -> bInterfaceNumber = desc_itf -> bInterfaceNumber ;
232248 p_midi -> iInterface = desc_itf -> iInterface ;
233249 p_midi -> itf_count ++ ;
@@ -236,6 +252,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
236252 p_desc = tu_desc_next (p_desc ); // next to CS Header
237253
238254 bool found_new_interface = false;
255+ printf ("%p %p %p\r\n" , p_desc , tu_desc_next (p_desc ), p_end );
239256 while ((p_desc < p_end ) && (tu_desc_next (p_desc ) <= p_end ) && !found_new_interface ) {
240257 switch (tu_desc_type (p_desc )) {
241258 case TUSB_DESC_INTERFACE :
0 commit comments