summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorZixun LI <[email protected]>2025-12-02 14:52:03 +0100
committerZixun LI <[email protected]>2025-12-02 17:42:06 +0100
commit686e975e4737e668577a66213910841036422752 (patch)
treef73bc509b66f5192ed9a96caf24b6b9236ab696e /src/class
parent7ee288bc223db393d68c7bdb09bf7c05ffd2eb03 (diff)
audio: fix audiod_open with midi interfaces
Signed-off-by: Zixun LI <[email protected]>
Diffstat (limited to 'src/class')
-rw-r--r--src/class/audio/audio_device.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 1dda8af99..19676234c 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -843,20 +843,44 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint
(void) max_len;
TU_VERIFY(TUSB_CLASS_AUDIO == itf_desc->bInterfaceClass &&
- AUDIO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass);
+ AUDIO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass, 0);
// Verify version is correct - this check can be omitted
TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V1 ||
- itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2);
+ itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2, 0);
+
+ // Verify 2nd interface descriptor is Audio Streaming to avoid mess with MIDI class
+ // Audio Control interface is followed by Audio Streaming interface(s)
+ // MIDI class also starts with Audio Control but is followed by MIDI Streaming
+ {
+ uint8_t const *p_desc = (uint8_t const *) itf_desc;
+ uint8_t const *p_desc_end = p_desc + max_len;
+
+ // Advance to next interface descriptor
+ p_desc = tu_desc_next(p_desc);
+ while (tu_desc_in_bounds(p_desc, p_desc_end) && tu_desc_type(p_desc) != TUSB_DESC_INTERFACE) {
+ p_desc = tu_desc_next(p_desc);
+ }
+
+ // Verify next interface is Audio Streaming (subclass 2), not MIDI Streaming (subclass 3)
+ if (p_desc_end - p_desc >= (int)sizeof(tusb_desc_interface_t)) {
+ tusb_desc_interface_t const *next_itf = (tusb_desc_interface_t const *) p_desc;
+ TU_VERIFY(next_itf->bInterfaceClass == TUSB_CLASS_AUDIO &&
+ next_itf->bInterfaceSubClass == AUDIO_SUBCLASS_STREAMING, 0);
+ } else {
+ // No further interface found or not enough bytes for interface descriptor
+ return 0;
+ }
+ }
// Verify interrupt control EP is enabled if demanded by descriptor
- TU_ASSERT(itf_desc->bNumEndpoints <= 1);// 0 or 1 EPs are allowed
+ TU_ASSERT(itf_desc->bNumEndpoints <= 1, 0);// 0 or 1 EPs are allowed
if (itf_desc->bNumEndpoints == 1) {
- TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP);
+ TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP, 0);
}
// Alternate setting MUST be zero - this check can be omitted
- TU_VERIFY(itf_desc->bAlternateSetting == 0);
+ TU_VERIFY(itf_desc->bAlternateSetting == 0, 0);
// Find available audio driver interface
uint8_t i;