Ticket #10238: 0001-listusb-added-human-readable-dumps-for-audiostreamin.2.patch

File 0001-listusb-added-human-readable-dumps-for-audiostreamin.2.patch, 15.6 KB (added by Ezodev, 10 years ago)
  • src/bin/listusb.cpp

    From 3540092460ef8b8e93c495ce3628b4a744b4c1ca Mon Sep 17 00:00:00 2001
    From: Ezo <ezo.dev@gmail.com>
    Date: Sun, 24 Nov 2013 22:43:16 +0000
    Subject: [PATCH] listusb: added human-readable dumps for audiostreaming
     descriptors
    
    ---
     src/bin/listusb.cpp | 406 +++++++++++++++++++++++++++++++++++++++++++++++++---
     1 file changed, 388 insertions(+), 18 deletions(-)
    
    diff --git a/src/bin/listusb.cpp b/src/bin/listusb.cpp
    index 813615a..552ad83 100644
    a b DumpAudioCSInterfaceDescriptorMixerUnit(  
    244244        printf("                    Source ID %u ...... %u\n",
    245245                i + 1, descriptor->input_pins[i]);
    246246
    247     usb_audio_output_channels_descriptor_r1* channels =
    248         (usb_audio_output_channels_descriptor_r1*)
     247    usb_audio_output_channels_descriptor_r1* channels
     248        = (usb_audio_output_channels_descriptor_r1*)
    249249            descriptor + descriptor->num_input_pins + 5;
    250250    printf("                    Channels .......... %u\n",
    251251        channels->num_output_pins);
    DumpAudioCSInterfaceDescriptorSelectorUnit(  
    285285
    286286    usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
    287287    printf("                    Selector .......... %u\n",
    288         (uint8)generic->data[descriptor->num_input_pins+2]);
     288        (uint8)generic->data[descriptor->num_input_pins + 2]);
    289289}
    290290
    291291
    DumpBMAControl(uint16 bma)  
    307307
    308308    int mask = 1;
    309309    for (uint8 i = 0; i < 11; i++) {
    310         if(bma & mask)
     310        if (bma & mask)
    311311            printf("                         %s\n", BMAControlStrings[i]);
    312312        mask <<= 1;
    313313    }
    DumpAudioCSInterfaceDescriptorFeatureUnit(  
    345345    } else {
    346346        for (uint8 i = 0; i < channels; i++) {
    347347            printf("                    BMA Control Raw ... ");
    348             for(uint8 j = 0; j < descriptor->r1.control_size; j++) {
    349                 printf("%02x ", descriptor->r1.bma_controls[i+j]);
     348            for (uint8 j = 0; j < descriptor->r1.control_size; j++) {
     349                printf("%02x ", descriptor->r1.bma_controls[i + j]);
    350350            }   
    351351        }
    352352    }
    DumpAudioCSInterfaceDescriptorAssociated(  
    364364    printf("                    Type .............. %u (CS_INTERFACE)\n",
    365365        descriptor->descriptor_type);
    366366    printf("                    Subtype ........... %u (ASSOC_INTERFACE)\n",
    367          (uint8)descriptor->data[0]);
     367        (uint8)descriptor->data[0]);
    368368    printf("                    Interface ......... %u\n",
    369369        (uint8)descriptor->data[1]);
    370370
    DumpAudioCSInterfaceDescriptorAssociated(  
    375375
    376376
    377377void
    378 DumpAudioCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     378DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
    379379{
    380     uint16 descriptorSubtype = descriptor->data[0];
     380    uint8 descriptorSubtype = descriptor->data[0];
    381381    switch (descriptorSubtype) {
    382382        case USB_AUDIO_AC_HEADER:
    383383            DumpAudioCSInterfaceDescriptorHeader(
    DumpAudioCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)  
    413413
    414414
    415415void
    416 DumpAudioDescriptor(const usb_generic_descriptor* descriptor)
     416DumpGeneralASInterfaceDescriptor(
     417    const usb_audio_streaming_interface_descriptor* descriptor)
    417418{
    418     switch (descriptor->descriptor_type) {
    419         case USB_AUDIO_CS_INTERFACE:
    420             DumpAudioCSInterfaceDescriptor(descriptor);
     419    printf("                    Type .............. %u (CS_INTERFACE)\n",
     420        descriptor->descriptor_type);
     421    printf("                    Subtype ........... %u (AS_GENERAL)\n",
     422        descriptor->descriptor_subtype);
     423    printf("                    Terminal link ..... %u\n",
     424        descriptor->terminal_link);
     425    printf("                    Delay ............. %u\n",
     426        descriptor->r1.delay);
     427    printf("                    Format tag ........ %u\n",
     428        descriptor->r1.format_tag);
     429}
     430
     431
     432void
     433DumpASFormatTypeI(const usb_audio_format_descriptor* descriptor)
     434{
     435    printf("                    Type .............. %u (CS_INTERFACE)\n",
     436        descriptor->descriptor_type);
     437    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     438        descriptor->descriptor_subtype);
     439    printf("                    Format Type ....... %u (FORMAT_TYPE_I)\n",
     440        descriptor->format_type);
     441    printf("                    Channels .......... %u\n",
     442        descriptor->typeI.nr_channels);
     443    printf("                    Subframe size ..... %u\n",
     444        descriptor->typeI.subframe_size);
     445    printf("                    Bit resoultion .... %u\n",
     446        descriptor->typeI.bit_resolution);
     447
     448    uint8 samFreqType = descriptor->typeI.sam_freq_type;
     449    printf("                    Sample Freq Type .. %u\n",
     450        samFreqType);
     451
     452    if (samFreqType == 0) {
     453        printf("                    Lower Sample Freq . %u\n",
     454            descriptor->typeI.sam_freqs[0].bytes[0]
     455                | (descriptor->typeI.sam_freqs[0].bytes[1] << 8)
     456                    | (descriptor->typeI.sam_freqs[0].bytes[2] << 16));
     457        printf("                    Upper Sample Freq . %u\n",
     458            descriptor->typeI.sam_freqs[1].bytes[0]
     459                | (descriptor->typeI.sam_freqs[1].bytes[1] << 8)
     460                    | (descriptor->typeI.sam_freqs[1].bytes[2] << 16));
     461    } else {
     462        for (uint8 i = 0; i < samFreqType; i++)
     463            printf("                    Sample Freq %u .... %u\n",
     464                i + 1, descriptor->typeI.sam_freqs[i].bytes[0]
     465                    | (descriptor->typeI.sam_freqs[i].bytes[1] << 8)
     466                        | (descriptor->typeI.sam_freqs[i].bytes[2] << 16));
     467    }
     468}
     469
     470
     471void
     472DumpASFormatTypeIII(const usb_audio_format_descriptor* descriptor)
     473{
     474    printf("                    Type .............. %u (CS_INTERFACE)\n",
     475        descriptor->descriptor_type);
     476    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     477        descriptor->descriptor_subtype);
     478    printf("                    Format Type ....... %u (FORMAT_TYPE_III)\n",
     479        descriptor->format_type);
     480    printf("                    Channels .......... %u\n",
     481        descriptor->typeIII.nr_channels);
     482    printf("                    Subframe size ..... %u\n",
     483        descriptor->typeIII.subframe_size);
     484    printf("                    Bit resoultion .... %u\n",
     485        descriptor->typeIII.bit_resolution);
     486
     487    uint8 samFreqType = descriptor->typeIII.sam_freq_type;
     488    printf("                    Sample Freq Type .. %u\n",
     489        samFreqType);
     490
     491    if (samFreqType == 0) {
     492        printf("                    Lower Sample Freq . %u\n",
     493            descriptor->typeIII.sam_freqs[0].bytes[0]
     494                | (descriptor->typeIII.sam_freqs[0].bytes[1] << 8)
     495                    | (descriptor->typeIII.sam_freqs[0].bytes[2] << 16));
     496        printf("                    Upper Sample Freq . %u\n",
     497            descriptor->typeIII.sam_freqs[1].bytes[0]
     498                | (descriptor->typeIII.sam_freqs[1].bytes[1] << 8)
     499                    | (descriptor->typeIII.sam_freqs[1].bytes[2] << 16));
     500    } else {
     501        for (uint8 i = 0; i < samFreqType; i++)
     502            printf("                    Sample Freq %u .... %u\n",
     503                i + 1, descriptor->typeIII.sam_freqs[i].bytes[0]
     504                    | (descriptor->typeIII.sam_freqs[i].bytes[1] << 8)
     505                        | (descriptor->typeIII.sam_freqs[i].bytes[2] << 16));
     506    }
     507}
     508
     509
     510void
     511DumpASFormatTypeII(const usb_audio_format_descriptor* descriptor)
     512{
     513    printf("                    Type .............. %u (CS_INTERFACE)\n",
     514        descriptor->descriptor_type);
     515    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     516        descriptor->descriptor_subtype);
     517    printf("                    Format Type ....... %u (FORMAT_TYPE_II)\n",
     518        descriptor->format_type);
     519    printf("                    Max Bitrate ....... %u\n",
     520        descriptor->typeII.max_bit_rate);
     521    printf("                    Samples per Frame . %u\n",
     522        descriptor->typeII.samples_per_frame);
     523
     524    uint8 samFreqType = descriptor->typeII.sam_freq_type;
     525    printf("                    Sample Freq type .. %u\n",
     526        samFreqType);
     527
     528    if (samFreqType == 0) {
     529        printf("                    Lower Sample Freq . %u\n",
     530            descriptor->typeII.sam_freqs[0].bytes[0]
     531                | (descriptor->typeII.sam_freqs[0].bytes[1] << 8)
     532                    | (descriptor->typeII.sam_freqs[0].bytes[2] << 16));
     533        printf("                    Upper Sample Freq . %u\n",
     534            descriptor->typeII.sam_freqs[1].bytes[0]
     535                | (descriptor->typeII.sam_freqs[1].bytes[1] << 8)
     536                    | (descriptor->typeII.sam_freqs[1].bytes[2] << 16));
     537    } else {
     538        for (uint8 i = 0; i < samFreqType; i++)
     539            printf("                    Sample Freq %u .... %u\n",
     540                i + 1, descriptor->typeII.sam_freqs[i].bytes[0]
     541                    | (descriptor->typeII.sam_freqs[i].bytes[1] << 8)
     542                        | (descriptor->typeII.sam_freqs[i].bytes[2] << 16));
     543    }
     544}
     545
     546
     547void
     548DumpASFmtType(const usb_audio_format_descriptor* descriptor)
     549{
     550    uint8 format = descriptor->format_type;
     551    switch (format) {
     552        case USB_AUDIO_FORMAT_TYPE_I:
     553            DumpASFormatTypeI(descriptor);
     554            break;
     555        case USB_AUDIO_FORMAT_TYPE_II:
     556            DumpASFormatTypeII(descriptor);
     557            break;
     558        case USB_AUDIO_FORMAT_TYPE_III:
     559            DumpASFormatTypeIII(descriptor);
     560            break;
     561        default:
     562            DumpDescriptorData((usb_generic_descriptor*)descriptor);   
     563    }
     564}
     565
     566
     567void
     568DumpMPEGCapabilities(uint16 capabilities)
     569{
     570    const char* MPEGCapabilities[] = {
     571        "Layer I",
     572        "Layer II",
     573        "Layer III",
     574       
     575        "MPEG-1 only",
     576        "MPEG-1 dual-channel",
     577        "MPEG-2 second stereo",
     578        "MPEG-2 7.1 channel augumentation",
     579        "Adaptive multi-channel predicion"
     580    };
     581
     582    uint16 mask = 1;
     583    for (uint8 i = 0; i < sizeof(MPEGCapabilities) / sizeof(char*); i++) {
     584        if (capabilities & mask)
     585            printf("                         %s\n", MPEGCapabilities[i]);
     586        mask <<= 1;
     587    }
     588   
     589    mask = 0x300; // bits 8 and 9
     590    uint16 multilingualSupport = (capabilities & mask) >> 8;
     591    switch (multilingualSupport) {
     592        case 0:
     593            printf("                         No Multilingual support\n");
     594            break;
     595        case 1:
     596            printf("                         Supported at Fs\n");
     597            break;
     598        case 3:
     599            printf("                         Supported at Fs and 1/2Fs\n");
     600               
     601    }
     602}
     603
     604
     605void
     606DumpMPEGFeatures(uint8 features)
     607{
     608    uint8 mask = 0x30; // bits 4 and 5
     609    uint8 dynRangeControl = (features & mask) >> 4;
     610    switch (dynRangeControl) {
     611        case 0:
     612            printf("                         Not supported\n");
     613            break;
     614        case 1:
     615            printf("                         Supported, not scaleable\n");
     616            break;
     617        case 2:
     618            printf("                         Scaleable, common boost, "
     619                "cut scaling value\n");
     620            break;
     621        case 3:
     622            printf("                         Scaleable, separate boost, "
     623                "cut scaling value\n");
     624               
     625    }   
     626}
     627
     628
     629void
     630DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor)
     631{
     632    printf("                    Type .............. %u (CS_INTERFACE)\n",
     633        descriptor->descriptor_type);
     634    printf("                    Subtype ........... %u (FORMAT_SPECIFIC)\n",
     635        descriptor->data[0]);
     636    printf("                    Format Tag ........ %u\n",
     637        *(uint16*)&descriptor->data[1]);
     638    printf("                    MPEG Capabilities . %u\n",
     639        *(uint16*)&descriptor->data[3]);
     640    DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]);
     641    printf("                    MPEG Features ..... %u\n",
     642        descriptor->data[5]);
     643    DumpMPEGFeatures(descriptor->data[5]);
     644}
     645
     646
     647void
     648DumpAC_3Features(uint8 features)
     649{
     650    const char* featuresStr[] = {
     651        "RF mode",
     652        "Line mode",
     653        "Custom0 mode",
     654        "Custom1 mode",
     655    };
     656
     657    uint8 mask = 1;
     658    for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) {
     659        if (features & mask)
     660            printf("                         %s\n", featuresStr[i]);
     661        mask <<= 1;
     662    }
     663   
     664    mask = 0x30; // bits 4 and 5
     665    uint8 dynRangeControl = (features & mask) >> 4;
     666    switch (dynRangeControl) {
     667        case 0:
     668            printf("                         Not supported\n");
     669            break;
     670        case 1:
     671            printf("                         Supported, not scaleable\n");
     672            break;
     673        case 2:
     674            printf("                         Scaleable, common boost, "
     675                "cut scaling value\n");
     676        case 3:
     677            printf("                         Scaleable, separate boost, "
     678                "cut scaling value\n");
     679               
     680    }
     681}
     682
     683
     684void
     685DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor)
     686{
     687    printf("                    Type .............. %u (CS_INTERFACE)\n",
     688        descriptor->descriptor_type);
     689    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     690        descriptor->data[0]);
     691    printf("                    Format Tag ........ %u\n",
     692        *(uint16*)&descriptor->data[1]);
     693    printf("                    BSID .............. %lx\n",
     694        *(uint32*)&descriptor->data[2]);
     695    printf("                    AC3 Features ...... %u\n",
     696        descriptor->data[6]);
     697    DumpAC_3Features(descriptor->data[6]);
     698}
     699
     700
     701void
     702DumpASFmtSpecific(const usb_generic_descriptor* descriptor)
     703{
     704    enum {
     705        TYPE_II_UNDEFINED = 0x1000,
     706        MPEG =              0x1001,
     707        AC_3 =              0x1002
     708    };
     709
     710    uint16 formatTag = *(uint16*)&descriptor->data[1];
     711    switch (formatTag) {
     712        case MPEG:
     713            DumpASFmtSpecificMPEG(descriptor);
     714            break;
     715        case AC_3:
     716            DumpASFmtSpecificAC_3(descriptor);
    421717            break;
    422718        default:
    423719            DumpDescriptorData(descriptor);
    DumpAudioDescriptor(const usb_generic_descriptor* descriptor)  
    426722
    427723
    428724void
    429 DumpDescriptor(const usb_generic_descriptor* descriptor, int classNum)
     725DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     726{
     727    uint8 subtype = descriptor->data[0];
     728    switch (subtype) {
     729        case USB_AUDIO_AS_GENERAL:
     730            DumpGeneralASInterfaceDescriptor(
     731                (usb_audio_streaming_interface_descriptor*)descriptor);
     732            break;
     733        case USB_AUDIO_AS_FORMAT_TYPE:
     734            DumpASFmtType(
     735                (usb_audio_format_descriptor*)descriptor);
     736            break;
     737        case USB_AUDIO_AS_FORMAT_SPECIFIC:
     738            DumpASFmtSpecific(descriptor);
     739            break;
     740        default:
     741            DumpDescriptorData(descriptor);
     742    }
     743}
     744
     745
     746void
     747DumpAudioStreamInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     748{
     749    printf("                    Type .............. %u (INTERFACE)\n",
     750        descriptor->descriptor_type);
     751    printf("                    Interface ........... %u\n",
     752        descriptor->data[0]);
     753    printf("                    Alternate setting ... %u\n",
     754        descriptor->data[1]);
     755    printf("                    Endpoints ........... %u\n",
     756        descriptor->data[2]);
     757    printf("                    Interface class ..... %u (AUDIO)\n",
     758        descriptor->data[3]);
     759    printf("                    Interface subclass .. %u (AUDIO_STREAMING)\n",
     760        descriptor->data[4]);
     761    printf("                    Interface ........... %u\n",
     762        descriptor->data[6]);
     763}
     764
     765
     766void
     767DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass)
     768{
     769    const uint8 USB_AUDIO_INTERFACE = 0x04;
     770
     771    switch (subclass) {
     772        case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS:
     773            switch (descriptor->descriptor_type) {
     774                case USB_AUDIO_CS_INTERFACE:
     775                    DumpAudioControlCSInterfaceDescriptor(descriptor);
     776                    break;
     777                default:
     778                    DumpDescriptorData(descriptor);
     779            }
     780            break;
     781        case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS:
     782            switch (descriptor->descriptor_type) {
     783                case USB_AUDIO_INTERFACE:
     784                    DumpAudioStreamInterfaceDescriptor(descriptor);
     785                    break;
     786                case USB_AUDIO_CS_INTERFACE:
     787                    DumpAudioStreamCSInterfaceDescriptor(descriptor);
     788                    break;
     789                default:
     790                    DumpDescriptorData(descriptor);
     791            }
     792            break;
     793    }
     794}
     795
     796
     797void
     798DumpDescriptor(const usb_generic_descriptor* descriptor,
     799    int classNum, int subclass)
    430800{
    431801    switch (classNum) {
    432         case 1:
    433             DumpAudioDescriptor(descriptor);
     802        case USB_AUDIO_DEVICE_CLASS:
     803            DumpAudioDescriptor(descriptor, subclass);
    434804            break;
    435805        default:
    436806            DumpDescriptorData(descriptor);
    DumpInterface(const BUSBInterface *interface)  
    473843        else if (endpoint->IsInterrupt())
    474844            printf("                    Type ............. Interrupt\n");
    475845
    476         if(endpoint->IsInput())
     846        if (endpoint->IsInput())
    477847            printf("                    Direction ........ Input\n");
    478848        else
    479849            printf("                    Direction ........ Output\n");
    DumpInterface(const BUSBInterface *interface)  
    483853    usb_descriptor *generic = (usb_descriptor *)buffer;
    484854    for (uint32 i = 0; interface->OtherDescriptorAt(i, generic, 256) == B_OK; i++) {
    485855        printf("                [Descriptor %lu]\n", i);
    486         DumpDescriptor(&generic->generic, interface->Class());
     856        DumpDescriptor(&generic->generic, interface->Class(), interface->Subclass());
    487857    }
    488858}
    489859