22 static int uac_parse_ac_interface(
UAC_DEV_T *uac, uint8_t *bptr)
27 UAC_DBGMSG(
"Parse AC - [%d] [0x%x] [0x%x]\n", ((CS_HDR_T *)bptr)->bLength, ((CS_HDR_T *)bptr)->bDescriptorType, ((CS_HDR_T *)bptr)->bDescriptorSubtype);
29 switch (((CS_HDR_T *)bptr)->bDescriptorSubtype)
31 case AC_DESCRIPTOR_UNDEFINED:
32 UAC_DBGMSG(
"AC: AC_DESCRIPTOR_UNDEFINED\n");
37 UAC_DBGMSG(
"AC: HEADER\n");
41 ac_itd = (AC_IT_T *)bptr;
42 UAC_DBGMSG(
"AC: INPUT_TERMINAL\n");
43 if (ac_itd->wTerminalType == UAC_TT_USB_STREAMING)
45 UAC_DBGMSG(
"USB streaming terminal found, ID=0x%x\n", ac_itd->bTerminalID);
47 else if ((ac_itd->wTerminalType & 0x200) == 0x200)
49 UAC_DBGMSG(
"MICROPHONE input terminal found, ID=0x%x\n", ac_itd->bTerminalID);
54 UAC_DBGMSG(
"Unsupported INPUT TERMINAL, ignore it!\n");
56 UAC_DBGMSG(
" bTerminalID: 0%x\n", ac_itd->bTerminalID);
57 UAC_DBGMSG(
" wTerminalType: 0%x\n", ac_itd->wTerminalType);
58 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", ac_itd->bAssocTerminal);
59 UAC_DBGMSG(
" bNrChannels: 0%x\n", ac_itd->bNrChannels);
60 UAC_DBGMSG(
" wChannelConfig: 0%x\n", ac_itd->wChannelConfig);
64 ac_otd = (AC_OT_T *)bptr;
65 UAC_DBGMSG(
"AC: OUTPUT_TERMINAL\n");
66 if (ac_otd->wTerminalType == UAC_TT_USB_STREAMING)
68 UAC_DBGMSG(
"USB streaming terminal found, ID=0x%x\n", ac_otd->bTerminalID);
70 else if ((ac_otd->wTerminalType & 0x300) == 0x300)
72 UAC_DBGMSG(
"SPEAKER output terminal found, ID=0x%x\n", ac_otd->bTerminalID);
78 UAC_DBGMSG(
"Unsupported OUTPUT TERMINAL, ignore it!\n");
80 UAC_DBGMSG(
" bTerminalID: 0%x\n", ac_otd->bTerminalID);
81 UAC_DBGMSG(
" wTerminalType: 0%x\n", ac_otd->wTerminalType);
82 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", ac_otd->bAssocTerminal);
83 UAC_DBGMSG(
" bSourceID: 0%x\n", ac_otd->bSourceID);
88 UAC_DBGMSG(
"AC: MIXER_UNIT\n");
89 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_MXR_T *)bptr)->bUnitID);
90 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_MXR_T *)bptr)->bNrInPins);
96 UAC_DBGMSG(
"AC: SELECTOR_UNIT\n");
97 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_SU_T *)bptr)->bUnitID);
98 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_SU_T *)bptr)->bNrInPins);
105 UAC_DBGMSG(
"AC: FEATURE_UNIT\n");
106 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_FU_T *)bptr)->bUnitID);
107 UAC_DBGMSG(
" bSourceID: 0%x\n", ((AC_FU_T *)bptr)->bSourceID);
108 UAC_DBGMSG(
" bControlSize: 0%x\n", ((AC_FU_T *)bptr)->bControlSize);
112 case PROCESSING_UNIT:
114 UAC_DBGMSG(
"AC: PROCESSING_UNIT\n");
115 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_PU_T *)bptr)->bUnitID);
116 UAC_DBGMSG(
" wProcessType: 0%x\n", ((AC_PU_T *)bptr)->wProcessType);
117 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_PU_T *)bptr)->bNrInPins);
122 UAC_DBGMSG(
"AC: EXTENSION_UNIT\n");
126 UAC_ERRMSG(
"uac_parse_ac_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
132 static int uac_set_microphone_feature_unit(
UAC_DEV_T *uac)
140 bptr = uac->
udev->cfd_buff;
141 config = (DESC_CONF_T *)bptr;
144 bptr += config->bLength;
145 size = config->wTotalLength - config->bLength;
150 while (size >=
sizeof(DESC_IF_T))
152 hdr = (AC_FU_T *)bptr;
154 if ((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
155 (hdr->bSourceID == bTerminalID))
161 if (hdr->bLength == 0)
164 bptr += hdr->bLength;
165 size -= hdr->bLength;
178 int uac_parse_control_interface(
UAC_DEV_T *uac, IFACE_T *iface)
186 if_num = iface->if_num;
188 UAC_DBGMSG(
"UAC parsing audio control (AC) interface %d...\n", if_num);
190 memset(&uac->
acif, 0,
sizeof(uac->
acif));
193 bptr = uac->
udev->cfd_buff;
194 config = (DESC_CONF_T *)bptr;
197 bptr += config->bLength;
198 size = config->wTotalLength - config->bLength;
203 while (size >=
sizeof(DESC_IF_T))
205 ifd = (DESC_IF_T *)bptr;
207 if ((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == if_num) &&
208 (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOCONTROL))
211 if (ifd->bLength == 0)
214 bptr += ifd->bLength;
215 size -= ifd->bLength;
218 if (size <
sizeof(DESC_IF_T))
220 UAC_ERRMSG(
"UAC_RET_PARSER! - AC standard not found!\n");
224 bptr += ifd->bLength;
225 size -= ifd->bLength;
230 while (size >
sizeof(DESC_HDR_T))
232 ifd = (DESC_IF_T *)bptr;
234 if (ifd->bDescriptorType != CS_INTERFACE)
237 ret = uac_parse_ac_interface(uac, bptr);
240 UAC_ERRMSG(
"UAC_RET_PARSER! - parsing CS\n");
244 if (ifd->bLength == 0)
247 bptr += ifd->bLength;
248 size -= ifd->bLength;
251 uac_set_microphone_feature_unit(uac);
253 UAC_DBGMSG(
" Microphone Input Terminal ID: 0x%x\n", uac->
acif.
mic_id);
254 UAC_DBGMSG(
" Microphone Feature Unit ID: 0x%x\n", uac->
acif.
mic_fuid);
255 UAC_DBGMSG(
" Speaker Output Terminal ID: 0x%x\n", uac->
acif.
speaker_id);
261 static int uac_parse_as_interface(
AS_IF_T *asif, uint8_t *bptr)
263 ALT_IFACE_T *aif = asif->
iface->aif;
266 if (((CS_HDR_T *)bptr)->bDescriptorType == USB_DT_ENDPOINT)
268 for (i = 0; i < aif->ifd->bNumEndpoints; i++)
270 if (aif->ep[i].bEndpointAddress == ((DESC_EP_T *)bptr)->bEndpointAddress)
272 asif->
ep = &(asif->
iface->aif->ep[i]);
276 if (i >= aif->ifd->bNumEndpoints)
278 UAC_ERRMSG(
"Endpoint 0x%x parsing error!\n", ((DESC_EP_T *)bptr)->bEndpointAddress);
284 if (((CS_HDR_T *)bptr)->bDescriptorType == CS_ENDPOINT)
286 asif->
cs_epd = (CS_EP_T *)bptr;
290 switch (((CS_HDR_T *)bptr)->bDescriptorSubtype)
292 case AS_DESCRIPTOR_UNDEFINED:
293 UAC_DBGMSG(
"AS: AS_DESCRIPTOR_UNDEFINED\n");
297 asif->
as_gen = (AS_GEN_T *)bptr;
298 UAC_DBGMSG(
"AS: AS_GENERAL\n");
299 UAC_DBGMSG(
" bTerminalLink: 0%x\n", asif->
as_gen->bTerminalLink);
300 UAC_DBGMSG(
" wFormatTag: 0%x\n", asif->
as_gen->wFormatTag);
304 asif->
ft = (AS_FT1_T *)bptr;
305 UAC_DBGMSG(
"AS: FORMAT_TYPE\n");
308 case FORMAT_SPECIFIC:
309 UAC_DBGMSG(
"AS: FORMAT_SPECIFIC\n");
313 UAC_ERRMSG(
"uac_parse_as_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
320 static int iface_have_iso_in_ep(IFACE_T *iface)
325 for (i = 0; i < iface->num_alt; i++)
327 for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
329 ep = &(iface->alt[i].ep[j]);
332 if (((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
333 ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN))
341 static int iface_have_iso_out_ep(IFACE_T *iface)
346 for (i = 0; i < iface->num_alt; i++)
348 for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
350 ep = &(iface->alt[i].ep[j]);
353 if (((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
354 ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT))
362 static void * uac_find_terminal(
UAC_DEV_T *uac, uint8_t bTerminalID)
369 bptr = uac->
udev->cfd_buff;
370 config = (DESC_CONF_T *)bptr;
373 bptr += config->bLength;
374 size = config->wTotalLength - config->bLength;
379 while (size >=
sizeof(DESC_IF_T))
381 hdr = (AC_OT_T *)bptr;
383 if ((hdr->bDescriptorType == CS_INTERFACE) &&
384 ((hdr->bDescriptorSubtype == INPUT_TERMINAL) || (hdr->bDescriptorSubtype == OUTPUT_TERMINAL)) &&
385 (hdr->bTerminalID == bTerminalID))
388 if (hdr->bLength == 0)
391 bptr += hdr->bLength;
392 size -= hdr->bLength;
398 static void * uac_find_feature_unit(
UAC_DEV_T *uac, uint8_t bUnitID)
405 bptr = uac->
udev->cfd_buff;
406 config = (DESC_CONF_T *)bptr;
409 bptr += config->bLength;
410 size = config->wTotalLength - config->bLength;
415 while (size >=
sizeof(DESC_IF_T))
417 hdr = (AC_FU_T *)bptr;
419 if ((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
420 (hdr->bUnitID == bUnitID))
423 if (hdr->bLength == 0)
426 bptr += hdr->bLength;
427 size -= hdr->bLength;
442 int uac_parse_streaming_interface(
UAC_DEV_T *uac, IFACE_T *iface, uint8_t bAlternateSetting)
451 if_num = iface->if_num;
453 UAC_DBGMSG(
"UAC parsing audio stream (AS) interface %d, alt %d...\n", if_num, bAlternateSetting);
455 memset(&asif, 0,
sizeof(asif));
458 bptr = uac->
udev->cfd_buff;
459 config = (DESC_CONF_T *)bptr;
462 bptr += config->bLength;
463 size = config->wTotalLength - config->bLength;
468 while (size >=
sizeof(DESC_IF_T))
470 ifd = (DESC_IF_T *)bptr;
472 if ((ifd->bDescriptorType == USB_DT_INTERFACE) &&
473 (ifd->bInterfaceNumber == if_num) && (ifd->bAlternateSetting == bAlternateSetting) &&
474 (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOSTREAMING))
477 if (ifd->bLength == 0)
480 bptr += ifd->bLength;
481 size -= ifd->bLength;
484 if (size <
sizeof(DESC_IF_T))
486 UAC_ERRMSG(
"UAC_RET_PARSER! - AC standard not found!\n");
490 if (ifd->bNumEndpoints == 0)
492 UAC_DBGMSG(
"This alternative interface is an idle interface.\n");
496 bptr += ifd->bLength;
497 size -= ifd->bLength;
502 while (size >
sizeof(DESC_HDR_T))
504 ifd = (DESC_IF_T *)bptr;
508 if ((ifd->bDescriptorType != CS_INTERFACE) &&
509 (ifd->bDescriptorType != USB_DT_ENDPOINT) &&
510 (ifd->bDescriptorType != CS_ENDPOINT))
514 ret = uac_parse_as_interface(&asif, bptr);
517 UAC_ERRMSG(
"UAC_RET_PARSER! - parsing CS\n");
521 if (ifd->bLength == 0)
524 bptr += ifd->bLength;
525 size -= ifd->bLength;
530 UAC_ERRMSG(
"UAC_RET_PARSER! - AS_GEN not found!\n");
534 if (iface_have_iso_in_ep(iface))
537 asif.
ot = (AC_OT_T *)uac_find_terminal(uac, asif.
as_gen->bTerminalLink);
540 UAC_DBGMSG(
"Audio in Terminal ID: 0%x\n", asif.
ot->bTerminalID);
541 UAC_DBGMSG(
" bDescriptorSubtype: 0%x\n", asif.
ot->bDescriptorSubtype);
542 UAC_DBGMSG(
" wTerminalType: 0%x\n", asif.
ot->wTerminalType);
543 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", asif.
ot->bAssocTerminal);
544 UAC_DBGMSG(
" bSourceID: 0%x\n", asif.
ot->bSourceID);
548 UAC_ERRMSG(
"Cannot find audio in Output Terminal %d!\n", asif.
as_gen->bTerminalLink);
550 memcpy(&uac->
asif_in, &asif,
sizeof(asif));
552 else if (iface_have_iso_out_ep(iface))
554 asif.
it = (AC_IT_T *)uac_find_terminal(uac, asif.
as_gen->bTerminalLink);
557 UAC_DBGMSG(
"Audio out Terminal ID: 0%x\n", asif.
it->bTerminalID);
558 UAC_DBGMSG(
" bDescriptorSubtype: 0%x\n", asif.
it->bDescriptorSubtype);
559 UAC_DBGMSG(
" wTerminalType: 0%x\n", asif.
it->wTerminalType);
560 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", asif.
it->bAssocTerminal);
564 UAC_ERRMSG(
"Cannot find audio in Output Terminal %d!\n", asif.
as_gen->bTerminalLink);
566 memcpy(&uac->
asif_out, &asif,
sizeof(asif));
570 UAC_ERRMSG(
"Interface cannot find iso endpoints!\n");
574 UAC_DBGMSG(
"\n\nAudio stream interface parsing done =>\n");
575 UAC_DBGMSG(
" Interface: %d, Alt: %d (iface = 0x%x)\n", if_num, bAlternateSetting, asif.
iface);
577 UAC_DBGMSG(
" Endpoint: 0x%x, wMaxPacketSize: %d\n", asif.
ep->bEndpointAddress, asif.
ep->wMaxPacketSize);
578 UAC_DBGMSG(
" as_gen: %s\n", (asif.
as_gen ==
NULL) ?
"Not Found" :
"OK");
579 UAC_DBGMSG(
" it: %s\n", (asif.
it ==
NULL) ?
"Not Found" :
"OK");
580 UAC_DBGMSG(
" ot: %s\n", (asif.
ot ==
NULL) ?
"Not Found" :
"OK");
581 UAC_DBGMSG(
" ft: %s\n", (asif.
ft ==
NULL) ?
"Not Found" :
"OK");
582 UAC_DBGMSG(
" cs_epd: %s\n", (asif.
cs_epd ==
NULL) ?
"Not Found" :
"OK");
USB Host UAC class driver header file.
NuMicro peripheral access layer header file.
M480 MCU USB Host Audio Class header file.
USB Host library exported header file.
USB Host library header file.
#define NULL
NULL pointer.