21static int uac_parse_ac_interface(
UAC_DEV_T *uac, uint8_t *bptr)
26 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);
28 switch(((CS_HDR_T *)bptr)->bDescriptorSubtype)
30 case AC_DESCRIPTOR_UNDEFINED:
31 UAC_DBGMSG(
"AC: AC_DESCRIPTOR_UNDEFINED\n");
36 UAC_DBGMSG(
"AC: HEADER\n");
40 ac_itd = (AC_IT_T *)bptr;
41 UAC_DBGMSG(
"AC: INPUT_TERMINAL\n");
42 if(ac_itd->wTerminalType == UAC_TT_USB_STREAMING)
44 UAC_DBGMSG(
"USB streaming terminal found, ID=0x%x\n", ac_itd->bTerminalID);
46 else if((ac_itd->wTerminalType & 0x200) == 0x200)
48 UAC_DBGMSG(
"MICROPHONE input terminal found, ID=0x%x\n", ac_itd->bTerminalID);
53 UAC_DBGMSG(
"Unsupported INPUT TERMINAL, ignore it!\n");
55 UAC_DBGMSG(
" bTerminalID: 0%x\n", ac_itd->bTerminalID);
56 UAC_DBGMSG(
" wTerminalType: 0%x\n", ac_itd->wTerminalType);
57 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", ac_itd->bAssocTerminal);
58 UAC_DBGMSG(
" bNrChannels: 0%x\n", ac_itd->bNrChannels);
59 UAC_DBGMSG(
" wChannelConfig: 0%x\n", ac_itd->wChannelConfig);
63 ac_otd = (AC_OT_T *)bptr;
64 UAC_DBGMSG(
"AC: OUTPUT_TERMINAL\n");
65 if(ac_otd->wTerminalType == UAC_TT_USB_STREAMING)
67 UAC_DBGMSG(
"USB streaming terminal found, ID=0x%x\n", ac_otd->bTerminalID);
69 else if((ac_otd->wTerminalType & 0x300) == 0x300)
71 UAC_DBGMSG(
"SPEAKER output terminal found, ID=0x%x\n", ac_otd->bTerminalID);
77 UAC_DBGMSG(
"Unsupported OUTPUT TERMINAL, ignore it!\n");
79 UAC_DBGMSG(
" bTerminalID: 0%x\n", ac_otd->bTerminalID);
80 UAC_DBGMSG(
" wTerminalType: 0%x\n", ac_otd->wTerminalType);
81 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", ac_otd->bAssocTerminal);
82 UAC_DBGMSG(
" bSourceID: 0%x\n", ac_otd->bSourceID);
87 UAC_DBGMSG(
"AC: MIXER_UNIT\n");
88 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_MXR_T *)bptr)->bUnitID);
89 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_MXR_T *)bptr)->bNrInPins);
95 UAC_DBGMSG(
"AC: SELECTOR_UNIT\n");
96 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_SU_T *)bptr)->bUnitID);
97 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_SU_T *)bptr)->bNrInPins);
104 UAC_DBGMSG(
"AC: FEATURE_UNIT\n");
105 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_FU_T *)bptr)->bUnitID);
106 UAC_DBGMSG(
" bSourceID: 0%x\n", ((AC_FU_T *)bptr)->bSourceID);
107 UAC_DBGMSG(
" bControlSize: 0%x\n", ((AC_FU_T *)bptr)->bControlSize);
111 case PROCESSING_UNIT:
113 UAC_DBGMSG(
"AC: PROCESSING_UNIT\n");
114 UAC_DBGMSG(
" bUnitID: 0%x\n", ((AC_PU_T *)bptr)->bUnitID);
115 UAC_DBGMSG(
" wProcessType: 0%x\n", ((AC_PU_T *)bptr)->wProcessType);
116 UAC_DBGMSG(
" bNrInPins: 0%x\n", ((AC_PU_T *)bptr)->bNrInPins);
121 UAC_DBGMSG(
"AC: EXTENSION_UNIT\n");
125 UAC_ERRMSG(
"uac_parse_ac_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
131static int uac_set_microphone_feature_unit(
UAC_DEV_T *uac)
139 bptr = uac->
udev->cfd_buff;
140 config = (DESC_CONF_T *)bptr;
143 bptr += config->bLength;
144 size = config->wTotalLength - config->bLength;
149 while(size >=
sizeof(DESC_IF_T))
151 hdr = (AC_FU_T *)bptr;
153 if((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
154 (hdr->bSourceID == bTerminalID))
160 if(hdr->bLength == 0)
163 bptr += hdr->bLength;
164 size -= hdr->bLength;
177int uac_parse_control_interface(
UAC_DEV_T *uac, IFACE_T *iface)
185 if_num = iface->if_num;
187 UAC_DBGMSG(
"UAC parsing audio control (AC) interface %d...\n", if_num);
189 memset(&uac->
acif, 0,
sizeof(uac->
acif));
192 bptr = uac->
udev->cfd_buff;
193 config = (DESC_CONF_T *)bptr;
196 bptr += config->bLength;
197 size = config->wTotalLength - config->bLength;
202 while(size >=
sizeof(DESC_IF_T))
204 ifd = (DESC_IF_T *)bptr;
206 if((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == if_num) &&
207 (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOCONTROL))
210 if(ifd->bLength == 0)
213 bptr += ifd->bLength;
214 size -= ifd->bLength;
217 if(size <
sizeof(DESC_IF_T))
219 UAC_ERRMSG(
"UAC_RET_PARSER! - AC standard not found!\n");
223 bptr += ifd->bLength;
224 size -= ifd->bLength;
229 while(size >
sizeof(DESC_HDR_T))
231 ifd = (DESC_IF_T *)bptr;
233 if(ifd->bDescriptorType != CS_INTERFACE)
236 ret = uac_parse_ac_interface(uac, bptr);
239 UAC_ERRMSG(
"UAC_RET_PARSER! - parsing CS\n");
243 if(ifd->bLength == 0)
246 bptr += ifd->bLength;
247 size -= ifd->bLength;
250 uac_set_microphone_feature_unit(uac);
252 UAC_DBGMSG(
" Microphone Input Terminal ID: 0x%x\n", uac->
acif.
mic_id);
253 UAC_DBGMSG(
" Microphone Feature Unit ID: 0x%x\n", uac->
acif.
mic_fuid);
254 UAC_DBGMSG(
" Speaker Output Terminal ID: 0x%x\n", uac->
acif.
speaker_id);
260static int uac_parse_as_interface(
AS_IF_T *asif, uint8_t *bptr)
262 ALT_IFACE_T *aif = asif->
iface->aif;
265 if(((CS_HDR_T *)bptr)->bDescriptorType == USB_DT_ENDPOINT)
267 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
269 if(aif->ep[i].bEndpointAddress == ((DESC_EP_T *)bptr)->bEndpointAddress)
271 asif->
ep = &(asif->
iface->aif->ep[i]);
275 if(i >= aif->ifd->bNumEndpoints)
277 UAC_ERRMSG(
"Endpoint 0x%x parsing error!\n", ((DESC_EP_T *)bptr)->bEndpointAddress);
283 if(((CS_HDR_T *)bptr)->bDescriptorType == CS_ENDPOINT)
285 asif->
cs_epd = (CS_EP_T *)bptr;
289 switch(((CS_HDR_T *)bptr)->bDescriptorSubtype)
291 case AS_DESCRIPTOR_UNDEFINED:
292 UAC_DBGMSG(
"AS: AS_DESCRIPTOR_UNDEFINED\n");
296 asif->
as_gen = (AS_GEN_T *)bptr;
297 UAC_DBGMSG(
"AS: AS_GENERAL\n");
298 UAC_DBGMSG(
" bTerminalLink: 0%x\n", asif->
as_gen->bTerminalLink);
299 UAC_DBGMSG(
" wFormatTag: 0%x\n", asif->
as_gen->wFormatTag);
303 asif->
ft = (AS_FT1_T *)bptr;
304 UAC_DBGMSG(
"AS: FORMAT_TYPE\n");
307 case FORMAT_SPECIFIC:
308 UAC_DBGMSG(
"AS: FORMAT_SPECIFIC\n");
312 UAC_ERRMSG(
"uac_parse_as_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
319static int iface_have_iso_in_ep(IFACE_T *iface)
324 for(i = 0; i < iface->num_alt; i++)
326 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
328 ep = &(iface->alt[i].ep[j]);
331 if(((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
332 ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN))
340static int iface_have_iso_out_ep(IFACE_T *iface)
345 for(i = 0; i < iface->num_alt; i++)
347 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
349 ep = &(iface->alt[i].ep[j]);
352 if(((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
353 ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT))
361static void * uac_find_terminal(
UAC_DEV_T *uac, uint8_t bTerminalID)
368 bptr = uac->
udev->cfd_buff;
369 config = (DESC_CONF_T *)bptr;
372 bptr += config->bLength;
373 size = config->wTotalLength - config->bLength;
378 while(size >=
sizeof(DESC_IF_T))
380 hdr = (AC_OT_T *)bptr;
382 if((hdr->bDescriptorType == CS_INTERFACE) &&
383 ((hdr->bDescriptorSubtype == INPUT_TERMINAL) || (hdr->bDescriptorSubtype == OUTPUT_TERMINAL)) &&
384 (hdr->bTerminalID == bTerminalID))
387 if(hdr->bLength == 0)
390 bptr += hdr->bLength;
391 size -= hdr->bLength;
397static void * uac_find_feature_unit(
UAC_DEV_T *uac, uint8_t bUnitID)
404 bptr = uac->
udev->cfd_buff;
405 config = (DESC_CONF_T *)bptr;
408 bptr += config->bLength;
409 size = config->wTotalLength - config->bLength;
414 while(size >=
sizeof(DESC_IF_T))
416 hdr = (AC_FU_T *)bptr;
418 if((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
419 (hdr->bUnitID == bUnitID))
422 if(hdr->bLength == 0)
425 bptr += hdr->bLength;
426 size -= hdr->bLength;
441int uac_parse_streaming_interface(
UAC_DEV_T *uac, IFACE_T *iface, uint8_t bAlternateSetting)
450 if_num = iface->if_num;
452 UAC_DBGMSG(
"UAC parsing audio stream (AS) interface %d, alt %d...\n", if_num, bAlternateSetting);
454 memset(&asif, 0,
sizeof(asif));
457 bptr = uac->
udev->cfd_buff;
458 config = (DESC_CONF_T *)bptr;
461 bptr += config->bLength;
462 size = config->wTotalLength - config->bLength;
467 while(size >=
sizeof(DESC_IF_T))
469 ifd = (DESC_IF_T *)bptr;
471 if((ifd->bDescriptorType == USB_DT_INTERFACE) &&
472 (ifd->bInterfaceNumber == if_num) && (ifd->bAlternateSetting == bAlternateSetting) &&
473 (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOSTREAMING))
476 if(ifd->bLength == 0)
479 bptr += ifd->bLength;
480 size -= ifd->bLength;
483 if(size <
sizeof(DESC_IF_T))
485 UAC_ERRMSG(
"UAC_RET_PARSER! - AC standard not found!\n");
489 if(ifd->bNumEndpoints == 0)
491 UAC_DBGMSG(
"This alternative interface is an idle interface.\n");
495 bptr += ifd->bLength;
496 size -= ifd->bLength;
501 while(size >
sizeof(DESC_HDR_T))
503 ifd = (DESC_IF_T *)bptr;
507 if((ifd->bDescriptorType != CS_INTERFACE) &&
508 (ifd->bDescriptorType != USB_DT_ENDPOINT) &&
509 (ifd->bDescriptorType != CS_ENDPOINT))
513 ret = uac_parse_as_interface(&asif, bptr);
516 UAC_ERRMSG(
"UAC_RET_PARSER! - parsing CS\n");
520 if(ifd->bLength == 0)
523 bptr += ifd->bLength;
524 size -= ifd->bLength;
529 UAC_ERRMSG(
"UAC_RET_PARSER! - AS_GEN not found!\n");
533 if(iface_have_iso_in_ep(iface))
536 asif.
ot = (AC_OT_T *)uac_find_terminal(uac, asif.
as_gen->bTerminalLink);
539 UAC_DBGMSG(
"Audio in Terminal ID: 0%x\n", asif.
ot->bTerminalID);
540 UAC_DBGMSG(
" bDescriptorSubtype: 0%x\n", asif.
ot->bDescriptorSubtype);
541 UAC_DBGMSG(
" wTerminalType: 0%x\n", asif.
ot->wTerminalType);
542 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", asif.
ot->bAssocTerminal);
543 UAC_DBGMSG(
" bSourceID: 0%x\n", asif.
ot->bSourceID);
547 UAC_ERRMSG(
"Cannot find audio in Output Terminal %d!\n", asif.
as_gen->bTerminalLink);
549 memcpy(&uac->
asif_in, &asif,
sizeof(asif));
551 else if(iface_have_iso_out_ep(iface))
553 asif.
it = (AC_IT_T *)uac_find_terminal(uac, asif.
as_gen->bTerminalLink);
556 UAC_DBGMSG(
"Audio out Terminal ID: 0%x\n", asif.
it->bTerminalID);
557 UAC_DBGMSG(
" bDescriptorSubtype: 0%x\n", asif.
it->bDescriptorSubtype);
558 UAC_DBGMSG(
" wTerminalType: 0%x\n", asif.
it->wTerminalType);
559 UAC_DBGMSG(
" bAssocTerminal: 0%x\n", asif.
it->bAssocTerminal);
563 UAC_ERRMSG(
"Cannot find audio in Output Terminal %d!\n", asif.
as_gen->bTerminalLink);
565 memcpy(&uac->
asif_out, &asif,
sizeof(asif));
569 UAC_ERRMSG(
"Interface cannot find iso endpoints!\n");
573 UAC_DBGMSG(
"\n\nAudio stream interface parsing done =>\n");
574 UAC_DBGMSG(
" Interface: %d, Alt: %d (iface = 0x%x)\n", if_num, bAlternateSetting, asif.
iface);
576 UAC_DBGMSG(
" Endpoint: 0x%x, wMaxPacketSize: %d\n", asif.
ep->bEndpointAddress, asif.
ep->wMaxPacketSize);
577 UAC_DBGMSG(
" as_gen: %s\n", (asif.
as_gen ==
NULL) ?
"Not Found" :
"OK");
578 UAC_DBGMSG(
" it: %s\n", (asif.
it ==
NULL) ?
"Not Found" :
"OK");
579 UAC_DBGMSG(
" ot: %s\n", (asif.
ot ==
NULL) ?
"Not Found" :
"OK");
580 UAC_DBGMSG(
" ft: %s\n", (asif.
ft ==
NULL) ?
"Not Found" :
"OK");
581 UAC_DBGMSG(
" cs_epd: %s\n", (asif.
cs_epd ==
NULL) ?
"Not Found" :
"OK");
NuMicro peripheral access layer header file.
USB Host Audio Class header file.
USB Host library header file.
USB Host library exported header file.
USB Host UAC class driver header file.