BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Revision:
3:6ae9a03a6145
Parent:
2:c10029b87439
Child:
4:41ff237a64ec
--- a/UvcCam/UvcCam.cpp	Tue Dec 11 15:28:00 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,566 +0,0 @@
-// UvcCam.cpp 2012/12/9
-#include "mbed.h"
-#include "rtos.h"
-#include "BaseUsbHost.h"
-#define DEBUG
-#include "BaseUsbHostDebug.h"
-#define TEST
-#include "BaseUsbHostTest.h"
-#include "UvcCam.h"
-
-UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp)
-{
-    uint8_t buf[34];
-    int rc;
-    int alt;
-    int cfg2;
-    
-    if (ctlEp == NULL) { // root hub
-        DBG_OHCI(LPC_USB->HcRhPortStatus1);
-        TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
-        ctlEp = new ControlEp();
-        TEST_ASSERT_TRUE(ctlEp);
-    }
-    bool r = check(ctlEp);
-    TEST_ASSERT(r);
-    m_ctlEp = ctlEp;
-    
-    UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp);
-    TEST_ASSERT(cfg);
-
-    int param_len = 34;
-    TEST_ASSERT(cfg->bcdUVC >= 0x0100);
-    if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0
-        param_len = 26;
-    }
-    
-    int addr = m_ctlEp->GetAddr();
-    m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize);
-    TEST_ASSERT_TRUE(m_isoEp);
-
-//#define USE_PROBE
-
-#ifdef USE_PROBE
-    rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_INFO Prob", buf, 1);
-
-    rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_DEF Probe", buf, param_len);
-
-    rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_MIN Probe", buf, param_len);
-
-    rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_MAX Probe", buf, param_len);
-
-    rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_CUR Probe", buf, param_len);
-#endif // USE_PROBE
-
-    rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1);
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("GET_INFO Commit", buf, 1);
-
-    memset(buf, 0, param_len);
-    buf[2] = cfg->FormatIndex;
-    buf[3] = cfg->FrameIndex;
-    *reinterpret_cast<uint32_t*>(buf+4) = interval;
-    
-    DBG_BYTES("SET_CUR Commit", buf, param_len);
-    rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-
-    rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
-    TEST_ASSERT(rc == USB_OK);
-    TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex);
-    TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex);
-    TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval);
-    DBG_BYTES("GET_CUR Commit", buf, param_len);
-
-    rc = m_ctlEp->GetConfiguration(&cfg2);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-    DBG("config: %d\n", cfg2);
-
-    rc = m_ctlEp->SetConfiguration(1);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-
-    rc = m_ctlEp->GetConfiguration(&cfg2);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-    DBG("config: %d\n", cfg2);
-    TEST_ASSERT_EQUAL(cfg2, 1);
-
-    rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-    DBG("alt: %d\n", alt);
-
-    rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-
-    rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
-    TEST_ASSERT_EQUAL(rc, USB_OK);
-    DBG("alt: %d\n", alt);
-    TEST_ASSERT_EQUAL(alt, cfg->bAlternate);
-    delete cfg;
-    
-    for(int i = 0; i < 16; i++) {
-        report_cc_count[i] = 0;
-        report_ps_cc_count[i] = 0;
-    }
-  
-    LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
-    LPC_USB->HcControl |= OR_CONTROL_IE;  // IsochronousEnable
-}
-
-bool UvcCam::check(ControlEp* ctlEp)
-{
-    if (ctlEp == NULL) {
-        return false;
-    }
-    uint8_t buf[18];
-    int r = ctlEp->GetDescriptor(1, 0, buf, 8);
-    if (r != USB_OK) {
-        return false;
-    }
-    DBG_HEX(buf, 8);
-    const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01};
-    if (memcmp(buf, desc, sizeof(desc)) != 0) {
-        return false;
-    }
-    r = ctlEp->GetDescriptor(1, 0, buf, 18);
-    if (r != USB_OK) {
-        return false;
-    }
-    DBG_HEX(buf, 18);
-    return true;
-}
-
-#define  DESCRIPTOR_TYPE_DEVICE        1
-#define  DESCRIPTOR_TYPE_CONFIGURATION 2
-#define  DESCRIPTOR_TYPE_STRING        3
-#define  DESCRIPTOR_TYPE_INTERFACE     4
-#define  DESCRIPTOR_TYPE_ENDPOINT      5
-
-#define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b
-
-#define DESCRIPTOR_TYPE_HID          0x21
-#define DESCRIPTOR_TYPE_REPORT       0x22
-#define DESCRIPTOR_TYPE_PHYSICAL     0x23
-#define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
-#define DESCRIPTOR_TYPE_CS_ENDPOINT  0x25
-#define DESCRIPTOR_TYPE_HUB          0x29
-
-#define CLASS_AUDIO 0x02
-#define CLASS_HUB   0x09
-
-#define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A);
-#define ENDIF }
-
-#define CC_AUDIO 0x01
-#define SC_AUDIOCONTROL   0x01
-#define SC_AUDIOSTREAMING 0x02
-
-#define AC_HEADER          0x01
-#define AC_INPUT_TERMINAL  0x02
-#define AC_OUTPUT_TERMINAL 0x03
-#define AC_FEATURE_UNIT    0x06
-
-// Input Terminal Types
-#define ITT_CAMERA 0x0201
-
-static int LE16(const uint8_t* d)
-{
-    return d[0] | (d[1] << 8);
-}
-
-static int LE24(const uint8_t* d) {
-    return d[0] | (d[1]<<8) | (d[2] << 16);
-}
-
-static int LE32(const uint8_t* d) {
-    return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ;
-}
-
-UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0)
-{
-    TEST_ASSERT(ctlEp);
-    switch(formatIndex) {
-        case UVC_MJPEG: _payload = UVC_MJPEG; break;
-        case UVC_YUY2:  _payload = UVC_YUY2; break;
-        default:        _payload = UVC_MJPEG; break;
-    }
-
-    switch(frameIndex) {
-        case UVC_160x120: _width = 160; _height = 120; break;
-        case UVC_176x144: _width = 176; _height = 144; break;
-        case UVC_320x176: _width = 320; _height = 176; break;
-        case UVC_320x240: _width = 320; _height = 240; break;
-        case UVC_352x288: _width = 352; _height = 288; break;
-        case UVC_432x240: _width = 432; _height = 240; break;
-        case UVC_640x480: _width = 640; _height = 480; break;
-        case UVC_544x288: _width = 544; _height = 288; break;
-        case UVC_640x360: _width = 640; _height = 360; break;
-        case UVC_752x416: _width = 752; _height = 416; break;
-        case UVC_800x448: _width = 800; _height = 448; break;
-        case UVC_800x600: _width = 800; _height = 600; break;
-        default:          _width = 160; _height = 120; break;
-    }
-    int index = 0;
-    uint8_t temp[4];
-    int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp));
-    TEST_ASSERT(rc == USB_OK);
-    DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp));
-    TEST_ASSERT(temp[0] == 9);
-    TEST_ASSERT(temp[1] == 0x02);
-    int TotalLength = LE16(temp+2);
-    DBG("TotalLength: %d\n", TotalLength);
-
-    uint8_t* buf = new uint8_t[TotalLength];
-    TEST_ASSERT(buf);
-    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength);
-    TEST_ASSERT(rc == USB_OK);
-    if (rc != USB_OK) {
-        delete[] buf;
-        return;
-    }
-    _parserConfigurationDescriptor(buf, TotalLength);
-    delete[] buf;
-}
-
-void UvcCfg::_parserAudioControl(uint8_t* buf, int len) {
-    int subtype = buf[2];
-    IF_EQ_THEN_PRINTF(AC_HEADER, subtype)
-    VERBOSE("ADC: %04x\n", LE16(buf+3));
-    VERBOSE("TotalLength: %d\n", LE16(buf+5));
-    VERBOSE("InCollection: %d\n", buf[7]);
-    for (int n = 1; n <= buf[7]; n++) {
-        VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]);
-    }
-    ENDIF
-    IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype)
-    VERBOSE("TerminalID: %d\n", buf[3]);
-    VERBOSE("TerminalType: %04X\n", LE16(buf+4));
-    VERBOSE("AssocTermianl: %d\n", buf[6]);
-    VERBOSE("NrChannels: %d\n", buf[7]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype)
-    VERBOSE("TerminalID: %d\n", buf[3]);
-    VERBOSE("TerminalType: %04X\n", LE16(buf+4));
-    VERBOSE("AssocTermianl: %d\n", buf[6]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype)
-    VERBOSE("UnitID: %d\n", buf[3]);
-    VERBOSE("SourceID: %d\n", buf[4]);
-    VERBOSE("ControlSize: %d\n", buf[5]);
-    ENDIF
-}
-
-#define AS_GENERAL     0x01
-#define AS_FORMAT_TYPE 0x02
-
-void UvcCfg::_parserAudioStream(uint8_t* buf, int len) {
-    int subtype = buf[2];
-    IF_EQ_THEN_PRINTF(AS_GENERAL, subtype)
-    VERBOSE("TerminalLink: %d\n", buf[3]);
-    VERBOSE("Delay: %d\n", buf[4]);
-    VERBOSE("FormatTag: %04x\n", LE16(buf+5));
-    ENDIF
-    IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype)
-    VERBOSE("FormatType: %d\n", buf[3]);
-    VERBOSE("NrChannels: %d\n", buf[4]);
-    VERBOSE("SubFrameSize: %d\n", buf[5]);
-    VERBOSE("BitResolution: %d\n", buf[6]);
-    VERBOSE("SamFreqType: %d\n", buf[7]);
-    VERBOSE("SamFreq(1): %d\n", LE24(buf+8));
-    ENDIF
-}
-
-#define CC_VIDEO 0x0e
-
-#define SC_VIDEOCONTROL   0x01
-#define SC_VIDEOSTREAMING 0x02
-
-#define VC_HEADER          0x01
-#define VC_INPUT_TERMINAL  0x02
-#define VC_OUTPUT_TERMINAL 0x03
-#define VC_SELECTOR_UNIT   0x04
-#define VC_PROCESSING_UNIT 0x05
-#define VC_EXTENSION_UNIT  0x06
-
-void UvcCfg::_parserVideoControl(uint8_t* buf, int len) {
-    int subtype = buf[2];
-    IF_EQ_THEN_PRINTF(VC_HEADER, subtype)
-        bcdUVC = LE16(buf+3);
-        VERBOSE("UVC: %04x\n", bcdUVC);
-        VERBOSE("TotalLength: %d\n", LE16(buf+5));
-        VERBOSE("ClockFrequency: %d\n", LE32(buf+7));
-        VERBOSE("InCollection: %d\n", buf[11]);
-        VERBOSE("aInterfaceNr(1): %d\n", buf[12]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype)
-        VERBOSE("TerminalID: %d\n", buf[3]);
-        uint16_t tt = LE16(buf+4);
-        VERBOSE("TerminalType: %04X\n", tt);
-        VERBOSE("AssocTerminal: %d\n", buf[6]);
-        VERBOSE("Terminal: %d\n", buf[7]);
-        if (tt == ITT_CAMERA) { // camera
-            int bControlSize = buf[14];
-            VERBOSE("ControlSize: %d\n", bControlSize);
-            for(int i = 0; i < bControlSize; i++) {
-            uint8_t bControls = buf[15+i];
-                VERBOSE("Controls(%d): %02X\n", i, bControls); 
-            }
-        }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype)
-        VERBOSE("TerminalID: %d\n", buf[3]);
-        VERBOSE("TerminalType: %04X\n", LE16(buf+4));
-        VERBOSE("AssocTerminal: %d\n", buf[6]);
-        VERBOSE("SourceID: %d\n", buf[7]);
-        VERBOSE("Terminal: %d\n", buf[8]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype)
-        VERBOSE("UnitID: %d\n", buf[3]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype)
-        VERBOSE("UnitID: %d\n", buf[3]);
-        VERBOSE("SourceID: %d\n", buf[4]);
-        VERBOSE("MaxMultiplier: %d\n", LE16(buf+5));
-        VERBOSE("ControlSize: %d\n", buf[7]);
-        int pos = 8;
-        for (int n = 1; n <= buf[7]; n++) {
-            VERBOSE("Controls(%d): %02X\n", n , buf[pos]);
-            pos++;
-        }
-        VERBOSE("Processing: %d\n", buf[pos]);
-        pos++;
-        VERBOSE("VideoStanders: %02X\n", buf[pos]);
-    ENDIF
-    IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype)
-        VERBOSE("UnitID: %d\n", buf[3]);
-    ENDIF
-}
-
-#define VS_INPUT_HEADER 0x01
-#define VS_STILL_FRAME  0x03
-#define VS_FORMAT_UNCOMPRESSED 0x04
-#define VS_FRAME_UNCOMPRESSED 0x05
-#define VS_FORMAT_MJPEG 0x06
-#define VS_FRAME_MJPEG  0x07
-#define VS_COLOR_FORMAT 0x0d
-
-void UvcCfg::_parserVideoStream(uint8_t* buf, int len) {
-    int subtype = buf[2];
-    IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype)
-        VERBOSE("NumFormats: %d\n", buf[3]);
-        VERBOSE("TotalLength: %d\n", LE16(buf+4));
-        VERBOSE("EndpointAddress: %02X\n", buf[6]);
-        VERBOSE("Info: %02X\n", buf[7]);
-        VERBOSE("TerminalLink: %d\n", buf[8]);
-        VERBOSE("StillCaptureMethod: %d\n", buf[9]);
-        VERBOSE("TriggerSupport: %d\n", buf[10]);
-        VERBOSE("TriggerUsage: %d\n", buf[11]);
-        VERBOSE("ControlSize: %d\n", buf[12]);
-        int pos = 13;
-        for (int n = 1; n <= buf[12]; n++) {
-            VERBOSE("Controls(%d): %02X\n", n, buf[pos]);
-            pos++;
-        }
-        bEndpointAddress = buf[6];
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype)
-    VERBOSE("EndpointAdress: %02X\n", buf[3]);
-    VERBOSE("NumImageSizePatterns: %d\n", buf[4]);
-    int ptn = buf[4];
-    int pos = 5;
-    for (int n = 1; n <= ptn; n++) {
-        VERBOSE("Width(%d): %d\n", n, LE16(buf+pos));
-        VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2));
-        pos += 4;
-    }
-    VERBOSE("NumCompressPtn: %d\n", buf[pos]);
-    ptn = buf[pos++];
-    for (int n = 1; n <= ptn; n++) {
-        VERBOSE("Compress(%d): %d\n", n, buf[pos]);
-        pos++;
-    }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype)
-        VERBOSE("FormatIndex: %d\n", buf[3]);
-        VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
-        uint32_t guid = LE32(buf+5);
-        if (guid == 0x32595559) {
-            VERBOSE("GUID: YUY2\n");
-        } else if (guid == 0x3231564e) {
-            VERBOSE("GUID: NV12\n");
-        } else {
-            VERBOSE("GUID: %08x\n", guid);
-        }
-        VERBOSE("DefaultFrameIndex: %d\n", buf[22]);
-        if (_payload == UVC_YUY2) {
-            FormatIndex = buf[3];
-        }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype)
-        VERBOSE("FrameIndex: %d\n", buf[3]);
-        VERBOSE("Capabilites: %d\n", buf[4]);
-        VERBOSE("Width: %d\n", LE16(buf+5));
-        VERBOSE("Height: %d\n", LE16(buf+7));
-        VERBOSE("MinBitRate: %d\n", LE32(buf+9));
-        VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
-        VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
-        VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
-        VERBOSE("FrameIntervalType: %d\n", buf[25]);
-        int it = buf[25];
-        uint32_t max_fi = 333333; // 30.0fps
-        if (it == 0) {
-            VERBOSE("FrameMinInterval: %d\n", buf[26]);
-            VERBOSE("FrameMaxInterval: %d\n", buf[30]);
-            VERBOSE("FrameIntervalStep: %d\n", buf[34]);
-        } else {
-            int pos = 26;
-            for (int n = 1; n <= it; n++) {
-                uint32_t fi = LE32(buf+pos);
-                if (fi >= max_fi) {
-                    max_fi = fi;
-                }
-                float fps = 1e+7 / fi;
-                VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
-                pos += 4;
-            }
-        }
-        if (_payload == UVC_YUY2) {
-            if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
-                FrameIndex = buf[3];
-            }
-            if (dwFrameInterval == 0) {
-                dwFrameInterval = max_fi;
-            }
-        }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype)
-        VERBOSE("FormatIndex: %d\n", buf[3]);
-        VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
-        VERBOSE("Flags: %d\n", buf[5]);
-        VERBOSE("DefaultFrameIndex: %d\n", buf[6]);
-        if (_payload == UVC_MJPEG) {
-            FormatIndex = buf[3];
-        }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype)
-        VERBOSE("FrameIndex: %d\n", buf[3]);
-        VERBOSE("Capabilites: %d\n", buf[4]);
-        VERBOSE("Width: %d\n", LE16(buf+5));
-        VERBOSE("Height: %d\n", LE16(buf+7));
-        VERBOSE("MinBitRate: %d\n", LE32(buf+9));
-        VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
-        VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
-        VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
-        VERBOSE("FrameIntervalType: %d\n", buf[25]);
-        int it = buf[25];
-        uint32_t max_fi = 333333; // 30.0fps
-        if (it == 0) {
-            VERBOSE("FrameMinInterval: %d\n", buf[26]);
-            VERBOSE("FrameMaxInterval: %d\n", buf[30]);
-            VERBOSE("FrameIntervalStep: %d\n", buf[34]);
-        } else {
-            int pos = 26;
-            for (int n = 1; n <= it; n++) {
-                uint32_t fi = LE32(buf+pos);
-                if (fi >= max_fi) {
-                    max_fi = fi;
-                }
-                float fps = 1e+7 / fi;
-                VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
-                pos += 4;
-            }
-        }
-        if (_payload == UVC_MJPEG) {
-            if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
-                FrameIndex = buf[3];
-            }
-            if (dwFrameInterval == 0) {
-                dwFrameInterval = max_fi;
-            }
-        }
-    ENDIF
-    IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype)
-    ENDIF
-}
-
-void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) {
-    int pos = 0;
-    _IfClass = 0;
-    _IfSubClass = 0;
-    while (pos < len) {
-        int type = buf[pos+1];
-        //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]);
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type)
-            VERBOSE("NumInterfaces: %d\n", buf[pos+4]);
-        ENDIF
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type)
-            VERBOSE("FirstInterface: %d\n", buf[pos+2]);
-            VERBOSE("InterfaceCount: %d\n", buf[pos+3]);
-            VERBOSE("FunctionClass: %02X\n", buf[pos+4]);
-            VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]);
-            VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]);
-            VERBOSE("Function: %d\n", buf[pos+7]);
-        ENDIF
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type)
-            VERBOSE("InterfaceNumber: %d\n", buf[pos+2]);
-            VERBOSE("AlternateSetting: %d\n", buf[pos+3]);
-            VERBOSE("NumEndpoint: %d\n", buf[pos+4]);
-            VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
-            VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
-            VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
-            VERBOSE("Interface: %d\n", buf[pos+8]);
-            _If         = buf[pos+2];
-            _Ifalt      = buf[pos+3];
-            _IfClass    = buf[pos+5];
-            _IfSubClass = buf[pos+6];
-        ENDIF
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type)
-            VERBOSE("EndpointAddress: %02X\n", buf[pos+2]);
-            VERBOSE("Attributes: %02X\n", buf[pos+3]);
-            VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4));
-            VERBOSE("Interval: %d\n", buf[pos+6]);
-            if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) {
-                if (bEndpointAddress == buf[pos+2]) {
-                    if (wMaxPacketSize == 0) {
-                        wMaxPacketSize = LE16(buf+pos+4);
-                    }    
-                    if (wMaxPacketSize == LE16(buf+pos+4)) {
-                        bInterface = _If;
-                        bAlternate = _Ifalt;
-                    }
-                }
-            }
-        ENDIF
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type)
-            IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass)
-                IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass)
-                    _parserVideoControl(buf+pos, buf[pos]);
-                ENDIF
-                IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass)
-                    _parserVideoStream(buf+pos, buf[pos]);
-                ENDIF
-            ENDIF
-            IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass)
-                IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass)
-                    _parserAudioControl(buf+pos, buf[pos]);
-                ENDIF 
-                IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass)
-                    _parserAudioStream(buf+pos, buf[pos]);
-                ENDIF
-            ENDIF
-        ENDIF
-        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type)
-        ENDIF
-        pos += buf[pos];
-    }
-}
-