@@ -194,123 +194,108 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
194194
195195 midih_interface_t * p_midi = find_new_midi ();
196196 TU_VERIFY (p_midi != NULL );
197-
198197 TU_VERIFY (TUSB_CLASS_AUDIO == desc_itf -> bInterfaceClass );
199- // There can be just a MIDI interface or an audio and a MIDI interface. Only open the MIDI interface
198+
199+ // There can be just a MIDI or an Audio + MIDI interface
200+ // const uint8_t* p_start = ((uint8_t const*) desc_itf);
201+ const uint8_t * p_end = ((uint8_t const * ) desc_itf ) + max_len ;
200202 uint8_t const * p_desc = (uint8_t const * ) desc_itf ;
201203 uint16_t len_parsed = 0 ;
204+
205+ tuh_midi_descriptor_cb_t desc_cb = { 0 };
206+ desc_cb .jack_num = 0 ;
207+
208+ // If there is Audio Control Interface + Audio Header descriptor, skip it
202209 if (AUDIO_SUBCLASS_CONTROL == desc_itf -> bInterfaceSubClass ) {
203- // This driver does not support audio streaming. However, if this is the audio control interface
204- // there might be a MIDI interface following it. Search through every descriptor until a MIDI
205- // interface is found or the end of the descriptor is found
206- while (len_parsed < max_len &&
207- (desc_itf -> bInterfaceClass != TUSB_CLASS_AUDIO || desc_itf -> bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING )) {
208- len_parsed += desc_itf -> bLength ;
209- p_desc = tu_desc_next (p_desc );
210- desc_itf = (tusb_desc_interface_t const * )p_desc ;
211- }
210+ TU_VERIFY (max_len > 2 * sizeof (tusb_desc_interface_t ) + sizeof (audio_desc_cs_ac_interface_t ));
212211
212+ p_desc = tu_desc_next (p_desc );
213+ TU_VERIFY (tu_desc_type (p_desc ) == TUSB_DESC_CS_INTERFACE &&
214+ tu_desc_subtype (p_desc ) == AUDIO_CS_AC_INTERFACE_HEADER );
215+
216+ p_desc = tu_desc_next (p_desc );
217+ desc_itf = (tusb_desc_interface_t const * )p_desc ;
213218 TU_VERIFY (TUSB_CLASS_AUDIO == desc_itf -> bInterfaceClass );
214219 }
215220 TU_VERIFY (AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf -> bInterfaceSubClass );
221+ desc_cb .desc_interface = desc_itf ;
222+
216223 len_parsed += desc_itf -> bLength ;
217224
218225 TU_LOG_DRV ("MIDI opening Interface %u (addr = %u)\r\n" , desc_itf -> bInterfaceNumber , dev_addr );
219226 p_midi -> itf_num = desc_itf -> bInterfaceNumber ;
220-
221- // CS Header descriptor
222227 p_desc = tu_desc_next (p_desc );
223- midi_desc_header_t const * p_mdh = (midi_desc_header_t const * ) p_desc ;
224- TU_VERIFY (p_mdh -> bDescriptorType == TUSB_DESC_CS_INTERFACE &&
225- p_mdh -> bDescriptorSubType == MIDI_CS_INTERFACE_HEADER );
226- TU_LOG_DRV (" Interface Header descriptor\r\n" );
227-
228- // p_desc = tu_desc_next(p_desc);
229- uint8_t prev_ep_addr = 0 ; // the CS endpoint descriptor is associated with the previous endpoint descriptor
230- tusb_desc_endpoint_t const * in_desc = NULL ;
231- tusb_desc_endpoint_t const * out_desc = NULL ;
232- while (len_parsed < max_len ) {
233- TU_VERIFY ((p_mdh -> bDescriptorType == TUSB_DESC_CS_INTERFACE ) ||
234- (p_mdh -> bDescriptorType == TUSB_DESC_CS_ENDPOINT && p_mdh -> bDescriptorSubType == MIDI_CS_ENDPOINT_GENERAL ) ||
235- p_mdh -> bDescriptorType == TUSB_DESC_ENDPOINT );
236-
237- if (p_mdh -> bDescriptorType == TUSB_DESC_CS_INTERFACE ) {
238- // The USB host doesn't really need this information unless it uses
239- // the string descriptor for a jack or Element
240-
241- // assume it is an input jack
242- midi_desc_in_jack_t const * p_mdij = (midi_desc_in_jack_t const * ) p_desc ;
243- if (p_mdij -> bDescriptorSubType == MIDI_CS_INTERFACE_HEADER ) {
244- TU_LOG_DRV (" Interface Header descriptor\r\n" );
245- } else if (p_mdij -> bDescriptorSubType == MIDI_CS_INTERFACE_IN_JACK ) {
246- // Then it is an in jack.
247- TU_LOG_DRV (" IN Jack %s descriptor \r\n" , p_mdij -> bJackType == MIDI_JACK_EXTERNAL ? "External" : "Embedded" );
248- } else if (p_mdij -> bDescriptorSubType == MIDI_CS_INTERFACE_OUT_JACK ) {
249- // then it is an out jack
250- TU_LOG_DRV (" OUT Jack %s descriptor\r\n" , p_mdij -> bJackType == MIDI_JACK_EXTERNAL ? "External" : "Embedded" );
251- } else if (p_mdij -> bDescriptorSubType == MIDI_CS_INTERFACE_ELEMENT ) {
252- // the it is an element;
253- TU_LOG_DRV ("Found element\r\n" );
254- } else {
255- TU_LOG_DRV (" Unknown CS Interface sub-type %u\r\n" , p_mdij -> bDescriptorSubType );
256- TU_VERIFY (false);// unknown CS Interface sub-type
257- }
258- len_parsed += p_mdij -> bLength ;
259- } else if (p_mdh -> bDescriptorType == TUSB_DESC_CS_ENDPOINT ) {
260- TU_LOG_DRV (" CS_ENDPOINT descriptor\r\n" );
261- TU_VERIFY (prev_ep_addr != 0 );
262- // parse out the mapping between the device's embedded jacks and the endpoints
263- // Each embedded IN jack is associated with an OUT endpoint
264- midi_desc_cs_endpoint_t const * p_csep = (midi_desc_cs_endpoint_t const * ) p_mdh ;
265- if (tu_edpt_dir (prev_ep_addr ) == TUSB_DIR_OUT ) {
266- TU_VERIFY (p_midi -> ep_out == prev_ep_addr );
267- TU_VERIFY (p_midi -> num_cables_tx == 0 );
268- p_midi -> num_cables_tx = p_csep -> bNumEmbMIDIJack ;
269- } else {
270- TU_VERIFY (p_midi -> ep_in == prev_ep_addr );
271- TU_VERIFY (p_midi -> num_cables_rx == 0 );
272- p_midi -> num_cables_rx = p_csep -> bNumEmbMIDIJack ;
273- }
274- len_parsed += p_csep -> bLength ;
275- prev_ep_addr = 0 ;
276- } else if (p_mdh -> bDescriptorType == TUSB_DESC_ENDPOINT ) {
277- // parse out the bulk endpoint info
278- tusb_desc_endpoint_t const * p_ep = (tusb_desc_endpoint_t const * ) p_mdh ;
279- TU_LOG_DRV (" Endpoint descriptor %02x\r\n" , p_ep -> bEndpointAddress );
280- if (tu_edpt_dir (p_ep -> bEndpointAddress ) == TUSB_DIR_OUT ) {
281- TU_VERIFY (p_midi -> ep_out == 0 );
282- TU_VERIFY (p_midi -> num_cables_tx == 0 );
283- p_midi -> ep_out = p_ep -> bEndpointAddress ;
284- prev_ep_addr = p_midi -> ep_out ;
285- out_desc = p_ep ;
286- } else {
287- TU_VERIFY (p_midi -> ep_in == 0 );
288- TU_VERIFY (p_midi -> num_cables_rx == 0 );
289- p_midi -> ep_in = p_ep -> bEndpointAddress ;
290- prev_ep_addr = p_midi -> ep_in ;
291- in_desc = p_ep ;
228+
229+ bool found_new_interface = false;
230+ while ((p_desc < p_end ) && (tu_desc_next (p_desc ) <= p_end ) && !found_new_interface ) {
231+ switch (tu_desc_type (p_desc )) {
232+ case TUSB_DESC_INTERFACE :
233+ found_new_interface = true;
234+ break ;
235+
236+ case TUSB_DESC_CS_INTERFACE :
237+ switch (tu_desc_subtype (p_desc )) {
238+ case MIDI_CS_INTERFACE_HEADER :
239+ TU_LOG_DRV (" Interface Header descriptor\r\n" );
240+ desc_cb .desc_header = p_desc ;
241+ break ;
242+
243+ case MIDI_CS_INTERFACE_IN_JACK :
244+ case MIDI_CS_INTERFACE_OUT_JACK : {
245+ TU_LOG_DRV (" Jack %s %s descriptor \r\n" ,
246+ tu_desc_subtype (p_desc ) == MIDI_CS_INTERFACE_IN_JACK ? "IN" : "OUT" ,
247+ p_desc [3 ] == MIDI_JACK_EXTERNAL ? "External" : "Embedded" );
248+ desc_cb .desc_jack [desc_cb .jack_num ++ ] = p_desc ;
249+ break ;
250+ }
251+
252+ case MIDI_CS_INTERFACE_ELEMENT :
253+ TU_LOG_DRV (" Element descriptor\r\n" );
254+ desc_cb .desc_element = p_desc ;
255+ break ;
256+
257+ default :
258+ TU_LOG_DRV (" Unknown CS Interface sub-type %u\r\n" , tu_desc_subtype (p_desc ));
259+ break ;
260+ }
261+ break ;
262+
263+ case TUSB_DESC_ENDPOINT : {
264+ tusb_desc_endpoint_t const * p_ep = (tusb_desc_endpoint_t const * ) p_desc ;
265+ p_desc = tu_desc_next (p_desc ); // next to CS endpoint
266+ TU_VERIFY (p_desc < p_end && tu_desc_next (p_desc ) <= p_end );
267+ midi_desc_cs_endpoint_t const * p_csep = (midi_desc_cs_endpoint_t const * ) p_desc ;
268+
269+ TU_LOG_DRV (" Endpoint and CS_Endpoint descriptor %02x\r\n" , p_ep -> bEndpointAddress );
270+ if (tu_edpt_dir (p_ep -> bEndpointAddress ) == TUSB_DIR_OUT ) {
271+ p_midi -> ep_out = p_ep -> bEndpointAddress ;
272+ p_midi -> num_cables_tx = p_csep -> bNumEmbMIDIJack ;
273+ desc_cb .desc_epout = p_ep ;
274+
275+ TU_ASSERT (tuh_edpt_open (dev_addr , p_ep ));
276+ tu_edpt_stream_open (& p_midi -> ep_stream .tx , p_ep );
277+ } else {
278+ p_midi -> ep_in = p_ep -> bEndpointAddress ;
279+ p_midi -> num_cables_rx = p_csep -> bNumEmbMIDIJack ;
280+ desc_cb .desc_epin = p_ep ;
281+
282+ TU_ASSERT (tuh_edpt_open (dev_addr , p_ep ));
283+ tu_edpt_stream_open (& p_midi -> ep_stream .rx , p_ep );
284+ }
285+ break ;
292286 }
293- len_parsed += p_mdh -> bLength ;
287+
288+ default : break ; // skip unknown descriptor
294289 }
295290 p_desc = tu_desc_next (p_desc );
296- p_mdh = (midi_desc_header_t const * ) p_desc ;
297291 }
298- TU_VERIFY ((p_midi -> ep_out != 0 && p_midi -> num_cables_tx != 0 ) ||
299- (p_midi -> ep_in != 0 && p_midi -> num_cables_rx != 0 ));
292+ desc_cb .desc_interface_len = (uint16_t ) ((uintptr_t )p_desc - (uintptr_t ) desc_itf );
300293
301- if (in_desc ) {
302- TU_ASSERT (tuh_edpt_open (dev_addr , in_desc ));
303- tu_edpt_stream_open (& p_midi -> ep_stream .rx , in_desc );
304- }
305- if (out_desc ) {
306- TU_ASSERT (tuh_edpt_open (dev_addr , out_desc ));
307- tu_edpt_stream_open (& p_midi -> ep_stream .tx , out_desc );
308- }
309294 p_midi -> dev_addr = dev_addr ;
310295
311- // if (tuh_midi_interface_descriptor_cb ) {
312- // tuh_midi_interface_descriptor_cb (dev_addr, desc_itf, );
313- // }
296+ if (tuh_midi_descriptor_cb ) {
297+ tuh_midi_descriptor_cb (dev_addr , & desc_cb );
298+ }
314299
315300 return true;
316301}
0 commit comments