Ticket #10238: 0001-LISTUSB-Implemented-human-readable-dump-for-audiocon.patch

File 0001-LISTUSB-Implemented-human-readable-dump-for-audiocon.patch, 12.8 KB (added by Ezodev, 10 years ago)
  • src/bin/listusb.cpp

    From 28b818ef2c29025bb77b0b11e8e43373c1b36425 Mon Sep 17 00:00:00 2001
    From: Ezo <ezo.dev@gmail.com>
    Date: Sun, 24 Nov 2013 13:21:24 +0000
    Subject: [PATCH] LISTUSB: Implemented human-readable dump for audiocontrol
     interface descriptors (USB audio 1.0)
    
    ---
     src/bin/listusb.cpp | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++--
     1 file changed, 375 insertions(+), 8 deletions(-)
    
    diff --git a/src/bin/listusb.cpp b/src/bin/listusb.cpp
    index 6bf394a..b0df4c4 100644
    a b  
    1212#include <String.h>
    1313#include <USBKit.h>
    1414#include <stdio.h>
     15#include <usb/USB_audio.h>
    1516
    1617#include "usbspec_private.h"
    1718#include "usb-utils.h"
    ClassName(int classNumber) {  
    6465};
    6566
    6667
     68void
     69DumpDescriptorData(const usb_generic_descriptor* descriptor)
     70{
     71    printf("                    Type ............. 0x%02x\n",
     72        descriptor->descriptor_type);
     73
     74    printf("                    Data ............. ");
     75    //len includes len and descriptor_type field
     76    for (int32 i = 0; i < descriptor->length - 2; i++)
     77        printf("%02x ", descriptor->data[i]);
     78    printf("\n");
     79}
     80
     81
     82void
     83DumpAudioCSInterfaceDescriptorHeader(
     84    const usb_audiocontrol_header_descriptor* descriptor)
     85{
     86    printf("                    Type .............. %u (CS_INTERFACE)\n",
     87        descriptor->descriptor_type);
     88
     89    printf("                    Subtype ........... %u (HEADER)\n",
     90        descriptor->descriptor_subtype);
     91    printf("                    bcdADC Release date 0x%04x\n",
     92        descriptor->bcd_release_no);
     93    printf("                    Total Length ...... %u\n",
     94        descriptor->r1.total_length);
     95    printf("                    In Collection ..... %u\n",
     96        descriptor->r1.in_collection);
     97
     98    for (uint8 i = 0; i < descriptor->r1.in_collection; i++)
     99        printf("                    Interface nr.%u ... %u\n",
     100            i + 1, descriptor->r1.interface_numbers[i]);
     101}
     102
     103
     104void
     105DumpChannelConfig(uint32 wChannelConfig)
     106{
     107    const char* kChannelConfigStrings[] = {
     108        "Left Front (L)",
     109        "Right Front (R)",
     110        "Ceter Front (C)",
     111        "Low Frequency Enchancement (LFE)",
     112        "Left Surround (Ls)",
     113        "Right Surround (Rs)",
     114        "Left of Center (Lc)",
     115        "Right of Center (Rc)",
     116        "Surround (S)",
     117        "Side Left (Sl)",
     118        "Side Right (Sr)",
     119        "Top (T)"
     120    };
     121
     122    int mask = 1;
     123    for (uint8 i = 0; i < 13; i++) {
     124        if (wChannelConfig & mask)
     125            printf("                        %s\n", kChannelConfigStrings[i]);
     126        mask <<= 1;
     127    }
     128}
     129
     130
     131const char*
     132TerminalTypeName(uint16 terminalType)
     133{
     134    switch (terminalType) {
     135        case USB_AUDIO_UNDEFINED_USB_IO:
     136            return "USB Undefined";
     137        case USB_AUDIO_STREAMING_USB_IO:
     138            return "USB Streaming";
     139        case USB_AUDIO_VENDOR_USB_IO:
     140            return "USB vendor specific";
     141       
     142        case USB_AUDIO_UNDEFINED_IN:
     143            return "Undefined";
     144        case USB_AUDIO_MICROPHONE_IN:
     145            return "Microphone";
     146        case USB_AUDIO_DESKTOP_IN:
     147            return "Desktop microphone";
     148        case USB_AUDIO_PERSONALMIC_IN:
     149            return "Personal microphone";
     150        case USB_AUDIO_OMNI_MIC_IN:
     151            return "Omni-directional microphone";
     152        case USB_AUDIO_MICS_ARRAY_IN:
     153            return "Microphone array";
     154        case USB_AUDIO_PROC_MICS_ARRAY_IN:
     155            return "Processing microphone array";
     156
     157        case USB_AUDIO_UNDEFINED_OUT:
     158            return "Undefined";
     159        case USB_AUDIO_SPEAKER_OUT:
     160            return "Speaker";
     161        case USB_ADUIO_HEAD_PHONES_OUT:
     162            return "Headphones";
     163        case USB_AUDIO_HMD_AUDIO_OUT:
     164            return "Head Mounted Display Audio";
     165        case USB_AUDIO_DESKTOP_SPEAKER:
     166            return "Desktop speaker";
     167        case USB_AUDIO_ROOM_SPEAKER:
     168            return "Room speaker";
     169        case USB_AUDIO_COMM_SPEAKER:
     170            return "Communication speaker";
     171        case USB_AUDIO_LFE_SPEAKER:
     172            return "Low frequency effects speaker";
     173           
     174        default:
     175            return "Unknown";
     176    }
     177}
     178
     179
     180void
     181DumpAudioCSInterfaceDescriptorInputTerminal(
     182    const usb_audio_input_terminal_descriptor* descriptor)
     183{
     184    printf("                    Type .............. %u (CS_INTERFACE)\n",
     185        descriptor->descriptor_type);
     186    printf("                    Subtype ........... %u (INPUT_TERMINAL)\n",
     187        descriptor->descriptor_subtype);
     188    printf("                    Terminal ID ....... %u\n",
     189        descriptor->terminal_id);
     190    printf("                    Terminal Type ..... %u (%s)\n",
     191        descriptor->terminal_type,
     192            InputTerminalTypeName(descriptor->terminal_type));
     193    printf("                    Associated Terminal %u\n",
     194        descriptor->assoc_terminal);
     195    printf("                    Nr Channels ....... %u\n",
     196        descriptor->r1.num_channels);
     197    printf("                    Channel Config .... %u\n",
     198        descriptor->r1.channel_config);
     199    DumpChannelConfig(descriptor->r1.channel_config);
     200
     201    printf("                    Channel Names ..... %u\n",
     202        descriptor->r1.channel_names);
     203    printf("                    Terminal .......... %u\n",
     204        descriptor->r1.terminal);
     205}
     206
     207
     208void
     209DumpAudioCSInterfaceDescriptorOutputTerminal(
     210    const usb_audio_output_terminal_descriptor* descriptor)
     211{
     212    printf("                    Type .............. %u (CS_INTERFACE)\n",
     213        descriptor->descriptor_type);
     214    printf("                    Subtype ........... %u (OUTPUT_TERMINAL)\n",
     215        descriptor->descriptor_subtype);
     216    printf("                    Terminal ID ....... %u\n",
     217        descriptor->terminal_id);
     218    printf("                    Terminal Type ..... %u (%s)\n",
     219        descriptor->terminal_type,
     220            InputTerminalTypeName(descriptor->terminal_type));
     221    printf("                    Associated Terminal %u\n",
     222        descriptor->assoc_terminal);
     223    printf("                    Source ID ......... %u\n",
     224        descriptor->source_id);
     225    printf("                    Terminal .......... %u\n",
     226        descriptor->r1.terminal);
     227}
     228
     229
     230void
     231DumpAudioCSInterfaceDescriptorMixerUnit(
     232    const usb_audio_mixer_unit_descriptor* descriptor)
     233{
     234    printf("                    Type .............. %u (CS_INTERFACE)\n",
     235        descriptor->descriptor_type);
     236    printf("                    Subtype ........... %u (MIXER_UNIT)\n",
     237        descriptor->descriptor_subtype);
     238    printf("                    Unit ID ........... %u\n",
     239        descriptor->unit_id);
     240
     241    printf("                    Input Pins ........ %u\n",
     242        descriptor->num_input_pins);
     243    for (uint8 i = 0; i < descriptor->num_input_pins; i++)
     244        printf("                    Source ID %u ...... %u\n",
     245                i + 1, descriptor->input_pins[i]);
     246
     247    usb_audio_output_channels_descriptor_r1* channels =
     248        (usb_audio_output_channels_descriptor_r1*)
     249            descriptor + descriptor->num_input_pins + 5;
     250    printf("                    Channels .......... %u\n",
     251        channels->num_output_pins);
     252    printf("                    Channel Config .... %u\n",
     253            channels->channel_config);
     254    DumpChannelConfig(channels->channel_config);
     255    printf("                    Channel Names ..... %u\n",
     256        channels->channel_names);
     257
     258    usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
     259    uint8 idx = 7 + descriptor->num_input_pins;
     260    for (uint i = 1; idx < descriptor->length - 3; idx++, i++)
     261        printf("                    Bitmap Control .... %u: %u\n", i,
     262                (uint8)generic->data[idx]);
     263
     264    printf("                    Mixer ............. %u\n",
     265            generic->data[generic->length - 3]);
     266}
     267
     268
     269void
     270DumpAudioCSInterfaceDescriptorSelectorUnit(
     271    const usb_audio_selector_unit_descriptor* descriptor)
     272{
     273    printf("                    Type .............. %u (CS_INTERFACE)\n",
     274        descriptor->descriptor_type);
     275    printf("                    Subtype ........... %u (SELECTOR_UNIT)\n",
     276        descriptor->descriptor_subtype);
     277    printf("                    Unit ID ........... %u\n",
     278        descriptor->unit_id);
     279
     280    printf("                    Input Pins ........ %u\n",
     281        descriptor->num_input_pins);
     282    for (uint8 i = 0; i < descriptor->num_input_pins; i++)
     283        printf("                    Source ID %u .. %u\n",
     284                i + 1, descriptor->input_pins[i]);
     285
     286    usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
     287    printf("                    Selector .......... %u\n",
     288        (uint8)generic->data[descriptor->num_input_pins+2]);
     289}
     290
     291
     292void
     293DumpBMAControl(uint16 bma)
     294{
     295    const char* BMAControlStrings[] = {
     296        "Mute",
     297        "Volume",
     298        "Bass",
     299        "Mid",
     300        "Treble",
     301        "Graphic Equalizer",
     302        "Automatic Gain",
     303        "Delay",
     304        "Bass Boost",
     305        "Loudness"
     306    };
     307
     308    int mask = 1;
     309    for (uint8 i = 0; i < 11; i++) {
     310        if(bma & mask)
     311            printf("                         %s\n", BMAControlStrings[i]);
     312        mask <<= 1;
     313    }
     314}
     315
     316
     317void
     318DumpAudioCSInterfaceDescriptorFeatureUnit(
     319    const usb_audio_feature_unit_descriptor* descriptor)
     320{
     321    printf("                    Type .............. %u (CS_INTERFACE)\n",
     322            descriptor->descriptor_type);
     323    printf("                    Subtype ........... %u (FEATURE_UNIT)\n",
     324        descriptor->descriptor_subtype);
     325    printf("                    Unit ID ........... %u\n",
     326            descriptor->unit_id);
     327    printf("                    Source ID ......... %u\n",
     328            descriptor->source_id);
     329
     330    printf("                    Control Size ...... %u\n",
     331            descriptor->r1.control_size);
     332    uint8 channels = (descriptor->length - 6) / descriptor->r1.control_size;
     333    if (descriptor->r1.control_size == 1) {
     334        for (uint8 i = 0; i < channels; i++) {
     335            printf("                    BMA Control %u .... %u\n",
     336                i + 1, (uint8)descriptor->r1.bma_controls[i]);
     337            DumpBMAControl((uint8)descriptor->r1.bma_controls[i]);
     338        }
     339    } else if (descriptor->r1.control_size == 2) {
     340        for (uint8 i = 0; i < channels; i++) {
     341            printf("                    BMA Control %u .... %u\n",
     342                i + 1, (uint16)descriptor->r1.bma_controls[i * 2]);
     343            DumpBMAControl((uint16)descriptor->r1.bma_controls[i * 2]);
     344        }
     345    } else {
     346        for (uint8 i = 0; i < channels; i++) {
     347            printf("                    BMA Control Raw ... ");
     348            for(uint8 j = 0; j < descriptor->r1.control_size; j++) {
     349                printf("%02x ", descriptor->r1.bma_controls[i+j]);
     350            }   
     351        }
     352    }
     353   
     354    usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
     355    printf("                    Feature ........... %u\n",
     356            (uint8)generic->data[descriptor->length - 3]);
     357}
     358
     359
     360void
     361DumpAudioCSInterfaceDescriptorAssociated(
     362    const usb_generic_descriptor* descriptor)
     363{
     364    printf("                    Type .............. %u (CS_INTERFACE)\n",
     365        descriptor->descriptor_type);
     366    printf("                    Subtype ........... %u (ASSOC_INTERFACE)\n",
     367         (uint8)descriptor->data[0]);
     368    printf("                    Interface ......... %u\n",
     369        (uint8)descriptor->data[1]);
     370
     371    printf("                    Data .............. ");
     372    for (uint8 i = 0; i < descriptor->length - 2; i++)
     373        printf("%02x ", descriptor->data[i]);
     374}
     375
     376
     377void
     378DumpAudioCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
     379{
     380    uint16 descriptorSubtype = descriptor->data[0];
     381    switch (descriptorSubtype) {
     382        case USB_AUDIO_AC_HEADER:
     383            DumpAudioCSInterfaceDescriptorHeader(
     384                (usb_audiocontrol_header_descriptor*)descriptor);
     385            break;
     386        case USB_AUDIO_AC_INPUT_TERMINAL:
     387            DumpAudioCSInterfaceDescriptorInputTerminal(
     388                (usb_audio_input_terminal_descriptor*)descriptor);
     389            break;
     390        case USB_AUDIO_AC_OUTPUT_TERMINAL:
     391            DumpAudioCSInterfaceDescriptorOutputTerminal(
     392                (usb_audio_output_terminal_descriptor*)descriptor);
     393            break;
     394        case USB_AUDIO_AC_MIXER_UNIT:
     395            DumpAudioCSInterfaceDescriptorMixerUnit(
     396                (usb_audio_mixer_unit_descriptor*)descriptor);
     397            break;
     398        case USB_AUDIO_AC_SELECTOR_UNIT:
     399            DumpAudioCSInterfaceDescriptorSelectorUnit(
     400                (usb_audio_selector_unit_descriptor*)descriptor);
     401            break;
     402        case USB_AUDIO_AC_FEATURE_UNIT:
     403            DumpAudioCSInterfaceDescriptorFeatureUnit(
     404                (usb_audio_feature_unit_descriptor*)descriptor);
     405            break;
     406        case USB_AUDIO_AC_EXTENSION_UNIT:
     407            DumpAudioCSInterfaceDescriptorAssociated(descriptor);
     408            break;
     409        default:
     410            DumpDescriptorData(descriptor);
     411    }
     412}
     413
     414
     415void
     416DumpAudioDescriptor(const usb_generic_descriptor* descriptor)
     417{
     418    switch (descriptor->descriptor_type) {
     419        case USB_AUDIO_CS_INTERFACE:
     420            DumpAudioCSInterfaceDescriptor(descriptor);
     421            break;
     422        default:
     423            DumpDescriptorData(descriptor);
     424    }
     425}
     426
     427
     428void
     429DumpDescriptor(const usb_generic_descriptor* descriptor, int classNum)
     430{
     431    switch (classNum) {
     432        case 1:
     433            DumpAudioDescriptor(descriptor);
     434            break;
     435        default:
     436            DumpDescriptorData(descriptor);
     437    }
     438}
     439
     440
    67441static void
    68442DumpInterface(const BUSBInterface *interface)
    69443{
    DumpInterface(const BUSBInterface *interface)  
    109483    usb_descriptor *generic = (usb_descriptor *)buffer;
    110484    for (uint32 i = 0; interface->OtherDescriptorAt(i, generic, 256) == B_OK; i++) {
    111485        printf("                [Descriptor %lu]\n", i);
    112         printf("                    Type ............. 0x%02x\n",
    113             generic->generic.descriptor_type);
    114         printf("                    Data ............. ");
    115         // the length includes the length and descriptor_type field
    116         for(int32 j = 0; j < generic->generic.length - 2; j++)
    117             printf("%02x ", generic->generic.data[j]);
    118         printf("\n");
     486        DumpDescriptor(&generic->generic, interface->Class());
    119487    }
    120488}
    121489
    122 
    123490static void
    124491DumpConfiguration(const BUSBConfiguration *configuration)
    125492{