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

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

    From 4a736980369d8671a5ee9ca829678e9410f0f1c8 Mon Sep 17 00:00:00 2001
    From: Ezo <ezo.dev@gmail.com>
    Date: Sun, 24 Nov 2013 20:09:52 +0000
    Subject: [PATCH] listusb: added human-readable dumps for audiostreaming
     descriptors (USB 1.0)
    
    ---
     src/bin/listusb.cpp | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++--
     1 file changed, 373 insertions(+), 10 deletions(-)
    
    diff --git a/src/bin/listusb.cpp b/src/bin/listusb.cpp
    index 813615a..680c484 100644
    a b 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_generic_descriptor* descriptor)
     434{
     435    printf("                    Type .............. %u (CS_INTERFACE)\n",
     436        descriptor->descriptor_type);
     437    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     438        descriptor->data[0]);
     439    printf("                    Format Type ....... %u (FORMAT_TYPE_I)\n",
     440        descriptor->data[1]);
     441    printf("                    Channels .......... %u\n",
     442        descriptor->data[2]);
     443    printf("                    Subframe size ..... %u\n",
     444        descriptor->data[3]);
     445    printf("                    Bit resoultion .... %u\n",
     446        descriptor->data[4]);
     447
     448    uint8 samFreqType = descriptor->data[5];
     449    printf("                    Sample Freq Type .. %u\n",
     450        samFreqType);
     451
     452    if (samFreqType == 0) {
     453        printf("                    Lower Sample Freq . %02x %02x %02x\n",
     454            descriptor->data[6], descriptor->data[7], descriptor->data[8]);
     455        printf("                    Upper Sample Freq . %02x %02x %02x\n",
     456            descriptor->data[9], descriptor->data[10], descriptor->data[11]);
     457    } else {
     458        for (uint8 i = 0; i < samFreqType; i++)
     459            printf("                    Sample Freq %u .... %02x %02x %02x\n",
     460                i + 1, descriptor->data[6 + i * 3],
     461                    descriptor->data[6 + i * 3 + 1],
     462                        descriptor->data[6 + i * 3 + 2]);
     463    }
     464}
     465
     466
     467void
     468DumpASFormatTypeIII(const usb_generic_descriptor* descriptor)
     469{
     470    printf("                    Type .............. %u (CS_INTERFACE)\n",
     471        descriptor->descriptor_type);
     472    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     473        descriptor->data[0]);
     474    printf("                    Format Type ....... %u (FORMAT_TYPE_III)\n",
     475        descriptor->data[1]);
     476    printf("                    Channels .......... %u\n",
     477        descriptor->data[2]);
     478    printf("                    Subframe size ..... %u\n",
     479        descriptor->data[3]);
     480    printf("                    Bit resoultion .... %u\n",
     481        descriptor->data[4]);
     482
     483    uint8 samFreqType = descriptor->data[5];
     484    printf("                    Sample Freq Type .. %u\n",
     485        samFreqType);
     486
     487    if (samFreqType == 0) {
     488        printf("                    Lower Sample Freq . %02x %02x %02x\n",
     489            descriptor->data[6], descriptor->data[7], descriptor->data[8]);
     490        printf("                    Upper Sample Freq . %02x %02x %02x\n",
     491            descriptor->data[9], descriptor->data[10], descriptor->data[11]);
     492    } else {
     493        for (uint8 i = 0; i < samFreqType; i++)
     494            printf("                    Sample Freq %u .... %02x %02x %02x\n",
     495                i + 1, descriptor->data[6 + i * 3],
     496                    descriptor->data[6 + i * 3 + 1],
     497                        descriptor->data[6 + i * 3 + 2]);
     498    }
     499}
     500
     501
     502void
     503DumpASFormatTypeII(const usb_generic_descriptor* descriptor)
     504{
     505    printf("                    Type .............. %u (CS_INTERFACE)\n",
     506        descriptor->descriptor_type);
     507    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     508        descriptor->data[0]);
     509    printf("                    Format Type ....... %u (FORMAT_TYPE_II)\n",
     510        descriptor->data[1]);
     511    printf("                    Max Bitrate ....... %u\n",
     512        *(uint16*)&descriptor->data[2]);
     513    printf("                    Samples per Frame . %u\n",
     514        *(uint16*)&descriptor->data[4]);
     515
     516    uint8 samFreqType = descriptor->data[6];
     517    printf("                    Sample Freq type .. %u\n",
     518        samFreqType);
     519
     520    if (samFreqType == 0) {
     521        printf("                    Lower Sample Freq . %02x %02x %02x\n",
     522            descriptor->data[7], descriptor->data[8], descriptor->data[9]);
     523        printf("                    Upper Sample Freq . %02x %02x %02x\n",
     524            descriptor->data[10], descriptor->data[11], descriptor->data[12]);
     525    } else {
     526        for (uint8 i = 0; i < samFreqType; i++)
     527            printf("                    Sample Freq %u .... %02x %02x %02x\n",
     528                i + 1, descriptor->data[7 + i * 3],
     529                    descriptor->data[7 + i * 3 + 1],
     530                        descriptor->data[7 + i * 3 + 2]);
     531    }
     532}
     533
     534
     535void
     536DumpASFmtType(const usb_generic_descriptor* descriptor)
     537{
     538    enum {
     539        FORMAT_TYPE_UNDEFINED = 0x00,
     540        FORMAT_TYPE_I = 0x01,
     541        FORMAT_TYPE_II = 0x02,
     542        FORMAT_TYPE_III = 0x03
     543    };
     544
     545    uint8 format = descriptor->data[1];
     546    switch (format) {
     547        case FORMAT_TYPE_I:
     548            DumpASFormatTypeI(descriptor);
     549            break;
     550        case FORMAT_TYPE_II:
     551            DumpASFormatTypeII(descriptor);
     552            break;
     553        case FORMAT_TYPE_III:
     554            DumpASFormatTypeIII(descriptor);
    421555            break;
    422556        default:
    423557            DumpDescriptorData(descriptor);
    DumpAudioDescriptor(const usb_generic_descriptor* descriptor)  
    426560
    427561
    428562void
    429 DumpDescriptor(const usb_generic_descriptor* descriptor, int classNum)
     563DumpMPEGCapabilities(uint16 capabilities)
    430564{
    431     switch (classNum) {
     565    const char* MPEGCapabilities[] = {
     566        "Layer I",
     567        "Layer II",
     568        "Layer III",
     569       
     570        "MPEG-1 only",
     571        "MPEG-1 dual-channel",
     572        "MPEG-2 second stereo",
     573        "MPEG-2 7.1 channel augumentation",
     574        "Adaptive multi-channel predicion"
     575    };
     576
     577    uint16 mask = 1;
     578    for (uint8 i = 0; i < sizeof(MPEGCapabilities) / sizeof(char*); i++) {
     579        if(capabilities & mask)
     580            printf("                         %s\n", MPEGCapabilities[i]);
     581        mask <<= 1;
     582    }
     583   
     584    mask = 0x300; //bits 8 and 9
     585    uint16 multilingualSupport = (capabilities & mask) >> 8;
     586    switch (multilingualSupport) {
     587        case 0:
     588            printf("                         No Multilingual support\n");
     589            break;
    432590        case 1:
    433             DumpAudioDescriptor(descriptor);
     591            printf("                         Supported at Fs\n");
     592            break;
     593        case 3:
     594            printf("                         Supported at Fs and 1/2Fs\n");
     595               
     596    }
     597}
     598
     599
     600void
     601DumpMPEGFeatures(uint8 features)
     602{
     603    uint8 mask = 0x30; //bits 4 and 5
     604    uint8 dynRangeControl = (features & mask) >> 4;
     605    switch (dynRangeControl) {
     606        case 0:
     607            printf("                         Not supported\n");
     608            break;
     609        case 1:
     610            printf("                         Supported, not scaleable\n");
     611            break;
     612        case 2:
     613            printf("                         Scaleable, common boost, "
     614                "cut scaling value\n");
     615            break;
     616        case 3:
     617            printf("                         Scaleable, separate boost, "
     618                "cut scaling value\n");
     619               
     620    }   
     621}
     622
     623
     624void
     625DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor)
     626{
     627    printf("                    Type .............. %u (CS_INTERFACE)\n",
     628        descriptor->descriptor_type);
     629    printf("                    Subtype ........... %u (FORMAT_SPECIFIC)\n",
     630        descriptor->data[0]);
     631    printf("                    Format Tag ........ %u\n",
     632        *(uint16*)&descriptor->data[1]);
     633    printf("                    MPEG Capabilities . %u\n",
     634        *(uint16*)&descriptor->data[3]);
     635    DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]);
     636    printf("                    MPEG Features ..... %u\n",
     637        descriptor->data[5]);
     638    DumpMPEGFeatures(descriptor->data[5]);
     639}
     640
     641
     642void
     643DumpAC_3Features(uint8 features)
     644{
     645    const char* featuresStr[] = {
     646        "RF mode",
     647        "Line mode",
     648        "Custom0 mode",
     649        "Custom1 mode",
     650    };
     651
     652    uint8 mask = 1;
     653    for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) {
     654        if(features & mask)
     655            printf("                         %s\n", featuresStr[i]);
     656        mask <<= 1;
     657    }
     658   
     659    mask = 0x30; //bits 4 and 5
     660    uint8 dynRangeControl = (features & mask) >> 4;
     661    switch (dynRangeControl) {
     662        case 0:
     663            printf("                         Not supported\n");
     664            break;
     665        case 1:
     666            printf("                         Supported, not scaleable\n");
     667            break;
     668        case 2:
     669            printf("                         Scaleable, common boost, "
     670                "cut scaling value\n");
     671        case 3:
     672            printf("                         Scaleable, separate boost, "
     673                "cut scaling value\n");
     674               
     675    }
     676}
     677
     678
     679void
     680DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor)
     681{
     682    printf("                    Type .............. %u (CS_INTERFACE)\n",
     683        descriptor->descriptor_type);
     684    printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
     685        descriptor->data[0]);
     686    printf("                    Format Tag ........ %u\n",
     687        *(uint16*)&descriptor->data[1]);
     688    printf("                    BSID .............. %xl\n",
     689        *(uint32*)&descriptor->data[2]);
     690    printf("                    AC3 Features ...... %u\n",
     691        descriptor->data[6]);
     692    DumpAC_3Features(descriptor->data[6]);
     693}
     694
     695
     696void
     697DumpASFmtSpecific(const usb_generic_descriptor* descriptor)
     698{
     699    enum {
     700        TYPE_II_UNDEFINED = 0x1000,
     701        MPEG =              0x1001,
     702        AC_3 =              0x1002
     703    };
     704
     705    uint16 formatTag = *(uint16*)&descriptor->data[1];
     706    switch (formatTag) {
     707        case MPEG:
     708            DumpASFmtSpecificMPEG(descriptor);
     709            break;
     710        case AC_3:
     711            DumpASFmtSpecificAC_3(descriptor);
     712            break;
     713        default:
     714            DumpDescriptorData(descriptor);
     715    }
     716}
     717
     718
     719void
     720DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     721{
     722    uint8 subtype = descriptor->data[0];
     723    switch (subtype) {
     724        case USB_AUDIO_AS_GENERAL:
     725            DumpGeneralASInterfaceDescriptor(
     726                (usb_audio_streaming_interface_descriptor*)descriptor);
     727            break;
     728        case USB_AUDIO_AS_FORMAT_TYPE:
     729            DumpASFmtType(descriptor);
     730            break;
     731        case USB_AUDIO_AS_FORMAT_SPECIFIC:
     732            DumpASFmtSpecific(descriptor);
     733            break;
     734        default:
     735            DumpDescriptorData(descriptor);
     736    }
     737}
     738
     739
     740void
     741DumpAudioStreamInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     742{
     743    printf("                    Type .............. %u (INTERFACE)\n",
     744        descriptor->descriptor_type);
     745    printf("                    Interface ........... %u\n",
     746        descriptor->data[0]);
     747    printf("                    Alternate setting ... %u\n",
     748        descriptor->data[1]);
     749    printf("                    Endpoints ........... %u\n",
     750        descriptor->data[2]);
     751    printf("                    Interface class ..... %u (AUDIO)\n",
     752        descriptor->data[3]);
     753    printf("                    Interface subclass .. %u (AUDIO_STREAMING)\n",
     754        descriptor->data[4]);
     755    printf("                    Interface ........... %u\n",
     756        descriptor->data[6]);
     757}
     758
     759
     760void
     761DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass)
     762{
     763    const uint8 USB_AUDIO_INTERFACE = 0x04;
     764
     765    switch (subclass) {
     766        case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS:
     767            switch (descriptor->descriptor_type) {
     768                case USB_AUDIO_CS_INTERFACE:
     769                    DumpAudioControlCSInterfaceDescriptor(descriptor);
     770                    break;
     771                default:
     772                    DumpDescriptorData(descriptor);
     773            }
     774            break;
     775        case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS:
     776            switch (descriptor->descriptor_type) {
     777                case USB_AUDIO_INTERFACE:
     778                    DumpAudioStreamInterfaceDescriptor(descriptor);
     779                    break;
     780                case USB_AUDIO_CS_INTERFACE:
     781                    DumpAudioStreamCSInterfaceDescriptor(descriptor);
     782                    break;
     783                default:
     784                    DumpDescriptorData(descriptor);
     785            }
     786            break;
     787    }
     788}
     789
     790
     791void
     792DumpDescriptor(const usb_generic_descriptor* descriptor, int classNum, int subclass)
     793{
     794    switch (classNum) {
     795        case USB_AUDIO_DEVICE_CLASS:
     796            DumpAudioDescriptor(descriptor, subclass);
    434797            break;
    435798        default:
    436799            DumpDescriptorData(descriptor);
    DumpInterface(const BUSBInterface *interface)  
    483846    usb_descriptor *generic = (usb_descriptor *)buffer;
    484847    for (uint32 i = 0; interface->OtherDescriptorAt(i, generic, 256) == B_OK; i++) {
    485848        printf("                [Descriptor %lu]\n", i);
    486         DumpDescriptor(&generic->generic, interface->Class());
     849        DumpDescriptor(&generic->generic, interface->Class(), interface->Subclass());
    487850    }
    488851}
    489852