22static 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);
132static 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;
178int 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);
261static 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);
320static 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))
341static 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))
362static 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;
398static 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;
442int 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");
NuMicro peripheral access layer header file.
#define NULL
NULL pointer.
M480 MCU USB Host Audio Class header file.
USB Host library header file.
USB Host library exported header file.
USB Host UAC class driver header file.