USB Host WAN Dongle library

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Fri Jul 27 16:14:07 2012 +0000
Parent:
5:3189db174f6b
Child:
7:c4483d48fe96
Commit message:
New enumeration model to only instantiate needed endpoints

Changed in this revision

USB3GModule/WANDongle.cpp Show annotated file Show diff for this revision Revisions of this file
USB3GModule/WANDongle.h Show annotated file Show diff for this revision Revisions of this file
USB3GModule/WANDongleInitializer.cpp Show annotated file Show diff for this revision Revisions of this file
USB3GModule/WANDongleInitializer.h Show annotated file Show diff for this revision Revisions of this file
USBHost/IUSBEnumerator.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBDeviceConnected.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHALHost.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHost.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHost.h Show annotated file Show diff for this revision Revisions of this file
--- a/USB3GModule/WANDongle.cpp	Wed Jul 25 11:13:50 2012 +0000
+++ b/USB3GModule/WANDongle.cpp	Fri Jul 27 16:14:07 2012 +0000
@@ -16,7 +16,7 @@
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#define __DEBUG__ 0 //Maximum verbosity
+#define __DEBUG__ 0
 #ifndef __MODULE__
 #define __MODULE__ "WANDongle.cpp"
 #endif
@@ -28,7 +28,7 @@
 #include "WANDongle.h"
 #include "WANDongleInitializer.h"
 
-WANDongle::WANDongle() : m_serialCount(0)
+WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0)
 {
     host = USBHost::getHostInst();
     init();
@@ -41,8 +41,6 @@
 
 bool WANDongle::tryConnect()
 {
-  bool found = false;
-
   //FIXME should run on USB thread
 
   DBG("Trying to connect device");
@@ -50,6 +48,8 @@
   if (dev_connected) {
       return true;
   }
+  
+  m_pInitializer = NULL;
 
   host->lock();
 
@@ -57,26 +57,26 @@
   {
       if ((dev = host->getDevice(i)) != NULL)
       {
-          DBG("Found one device, reset it");
+          m_pInitializer = NULL; //Will be set in setVidPid callback
+      
+          DBG("Found one device reset it");
           host->resetDevice(dev);
 
           DBG("Enumerate");
-          host->enumerate(dev);
+          host->enumerate(dev, this);
           
           DBG("Device has VID:%04x PID%04x", dev->getVid(), dev->getPid());
-          
-          WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
-          
-          while((*initializer))
+                   
+          if(m_pInitializer) //If an initializer has been found
           {
-            DBG("*initializer=%p", *initializer);
-            DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
-            DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid());
-            if ((dev->getVid() == (*initializer)->getSerialVid()) && (dev->getPid() == (*initializer)->getSerialPid()))
+            DBG("m_pInitializer=%p", m_pInitializer);
+            DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
+            DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
+            if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
             {
               DBG("The dongle is in virtual serial mode");
               host->registerDriver(dev, 0, this, &WANDongle::init);
-              m_serialCount = (*initializer)->getSerialPortCount();
+              m_serialCount = m_pInitializer->getSerialPortCount();
               if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
               {
                 m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
@@ -84,9 +84,9 @@
               for(int j = 0; j < m_serialCount; j++)
               {
                 DBG("Connecting serial port #%d", j+1);
-                DBG("Ep %p", (*initializer)->getEp(dev, j, false));
-                DBG("Ep %p", (*initializer)->getEp(dev, j, true));
-                m_serial[j].connect( dev, (*initializer)->getEp(dev, j, false), (*initializer)->getEp(dev, j, true) );
+                DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
+                DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
+                m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
               }
               
               DBG("Device connected");
@@ -97,11 +97,11 @@
               
               return true;
             }
-            else if ((dev->getVid() == (*initializer)->getMSDVid()) && (dev->getPid() == (*initializer)->getMSDPid()))
+            else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
             {
               DBG("Vodafone K3370 dongle detected in MSD mode");
               //Try to switch   
-              if( (*initializer)->switchMode(dev) )
+              if( m_pInitializer->switchMode(dev) )
               {
                 DBG("Switched OK");
                 host->unlock();
@@ -114,8 +114,7 @@
                 return false;
               }
             }
-            (*initializer)++;
-          } //while()
+          } //if()
       } //if()
   } //for()
   host->unlock();
@@ -141,3 +140,58 @@
     m_serial[i].init(host);
   }
 }
+
+
+/*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
+{
+    //Load right initializer
+          WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
+          
+          while((*initializer))
+          {
+            DBG("*initializer=%p", *initializer);
+            DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
+            DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid());
+            if ((dev->getVid() == (*initializer)->getSerialVid()) && (dev->getPid() == (*initializer)->getSerialPid()))
+            {
+              DBG("The dongle is in virtual serial mode");
+              m_pInitializer = *initializer;
+              break;
+            }
+            else if ((dev->getVid() == (*initializer)->getMSDVid()) && (dev->getPid() == (*initializer)->getMSDPid()))
+            {
+              DBG("Vodafone K3370 dongle detected in MSD mode");
+              m_pInitializer = *initializer;
+              break;
+            }
+            (*initializer)++;
+          } //while()
+          if(m_pInitializer)
+          {
+            m_pInitializer->setVidPid(vid, pid);
+          }
+}
+
+/*virtual*/ bool WANDongle::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+  if(m_pInitializer)
+  {
+    return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
+  }
+  else
+  {
+    return false;
+  }
+}
+
+/*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+  if(m_pInitializer)
+  {
+    return m_pInitializer->useEndpoint(intf_nb, type, dir);
+  }
+  else
+  {
+    return false;
+  }
+}
--- a/USB3GModule/WANDongle.h	Wed Jul 25 11:13:50 2012 +0000
+++ b/USB3GModule/WANDongle.h	Fri Jul 27 16:14:07 2012 +0000
@@ -25,6 +25,8 @@
 #include "rtos.h"
 
 #include "WANDongleSerialPort.h"
+#include "WANDongleInitializer.h"
+#include "IUSBEnumerator.h"
 
 #define WANDONGLE_MAX_OUTEP_SIZE 64
 #define WANDONGLE_MAX_INEP_SIZE 64
@@ -34,7 +36,7 @@
 /** A class to use a WAN (3G/LTE) access dongle
  *
  */
-class WANDongle {
+class WANDongle : public IUSBEnumerator {
 public:
     /*
     * Constructor
@@ -60,10 +62,20 @@
     IUSBHostSerial& getSerial(int index);
     int getSerialCount();
     
+    //From IUSBEnumerator
+    
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+    
 protected:
     USBHost * host;
     USBDeviceConnected * dev;
     bool dev_connected;
+    
+    WANDongleInitializer* m_pInitializer;
 
     void init();
     
--- a/USB3GModule/WANDongleInitializer.cpp	Wed Jul 25 11:13:50 2012 +0000
+++ b/USB3GModule/WANDongleInitializer.cpp	Fri Jul 27 16:14:07 2012 +0000
@@ -85,12 +85,70 @@
 
 Endpoint* VodafoneK3770Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
 {
-  const int intf[3] = {0,4,2};
-  return pDev->getEndpoint(intf[serialPortNumber], BULK_ENDPOINT, tx?OUT:IN, 0);
+  return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
 }
 
 int VodafoneK3770Initializer::getSerialPortCount()
 {
-  return 3;
+  return 2;
+}
+
+/*virtual*/ void VodafoneK3770Initializer::setVidPid(uint16_t vid, uint16_t pid)
+{
+    if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) )
+    {
+      m_hasSwitched = true;
+      m_currentSerialIntf = 0;
+      m_endpointsToFetch = 4;
+    }
+    else
+    {
+      m_hasSwitched = false;
+      m_endpointsToFetch = 1;
+    }
 }
 
+/*virtual*/ bool VodafoneK3770Initializer::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+  if( m_hasSwitched )
+  {
+    if( intf_class == 0xFF )
+    {
+      if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 4) )
+      {
+        m_currentSerialIntf++;
+        return true;
+      }
+      m_currentSerialIntf++;
+    }
+  }
+  else
+  {
+    if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+/*virtual*/ bool VodafoneK3770Initializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+  if( m_hasSwitched )
+  {
+    if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
+    {
+      m_endpointsToFetch--;
+      return true;
+    }
+  }
+  else
+  {
+    if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch )
+    {
+      m_endpointsToFetch--;
+      return true;
+    }
+  }
+  return false;
+}
--- a/USB3GModule/WANDongleInitializer.h	Wed Jul 25 11:13:50 2012 +0000
+++ b/USB3GModule/WANDongleInitializer.h	Fri Jul 27 16:14:07 2012 +0000
@@ -24,8 +24,9 @@
 using std::uint32_t;
 
 #include "USBHost.h"
+#include "IUSBEnumerator.h"
 
-class WANDongleInitializer
+class WANDongleInitializer : public IUSBEnumerator
 {
 protected:
     WANDongleInitializer(USBHost* pHost);
@@ -44,6 +45,12 @@
     
     virtual int getSerialPortCount() = 0;
     
+    virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
+    
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
+    
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
+    
     static WANDongleInitializer** getInitializers(USBHost* pHost);
 };
 
@@ -63,6 +70,18 @@
     virtual Endpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx);
     
     virtual int getSerialPortCount();
+    
+    virtual void setVidPid(uint16_t vid, uint16_t pid);
+    
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+    
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+    
+private:
+
+  bool m_hasSwitched;
+  int m_currentSerialIntf;
+  int m_endpointsToFetch;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHost/IUSBEnumerator.h	Fri Jul 27 16:14:07 2012 +0000
@@ -0,0 +1,41 @@
+/* Copyright (c) 2010-2012 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef IUSBENUMERATOR_H_
+#define IUSBENUMERATOR_H_
+
+#include "stdint.h"
+
+#include "Endpoint.h"
+
+/*
+Generic interface to implement for "smart" USB enumeration
+*/
+
+class IUSBEnumerator {
+public:
+
+    virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
+    
+    virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
+    
+    virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
+
+};
+
+#endif /*IUSBENUMERATOR_H_*/
\ No newline at end of file
--- a/USBHost/USBDeviceConnected.h	Wed Jul 25 11:13:50 2012 +0000
+++ b/USBHost/USBDeviceConnected.h	Fri Jul 27 16:14:07 2012 +0000
@@ -22,8 +22,8 @@
 #include "stdint.h"
 #include "Endpoint.h"
 
-#define MAX_ENDPOINT_PER_INTERFACE  4
-#define MAX_INTF                    5
+#define MAX_ENDPOINT_PER_INTERFACE  2
+#define MAX_INTF                    2
 
 typedef struct {
     bool in_use;
--- a/USBHost/USBHALHost.h	Wed Jul 25 11:13:50 2012 +0000
+++ b/USBHost/USBHALHost.h	Fri Jul 27 16:14:07 2012 +0000
@@ -23,7 +23,7 @@
 
 #include "USBHostTypes.h"
 
-#define MAX_ENDPOINT 16
+#define MAX_ENDPOINT 5
 #define MAX_TD (MAX_ENDPOINT*2)
 
 #define USBHALHOST_SIG_INIT 0x01
--- a/USBHost/USBHost.cpp	Wed Jul 25 11:13:50 2012 +0000
+++ b/USBHost/USBHost.cpp	Fri Jul 27 16:14:07 2012 +0000
@@ -29,7 +29,7 @@
 #include "rtos.h"
 
 
-#define NB_MAX_INTF 5
+#define NB_MAX_INTF 2
 
 USBHost * USBHost::instHost = NULL;
 
@@ -558,7 +558,7 @@
 
 
 // enumerate a device with the control endpoint
-USB_TYPE USBHost::enumerate(USBDeviceConnected * dev)  {
+USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)  {
   uint8_t data[256];
   uint8_t total_conf_descr_length = 0;
   USB_TYPE res;
@@ -585,7 +585,7 @@
   }
   dev->setSizeControlEndpoint(data[7]);
   DBG("size control Endpoint: %d", dev->getSizeControlEndpoint());
-
+  
 DBG("Now set addr");
   // second step: set an address to the device
   res = controlWrite( dev,
@@ -617,6 +617,8 @@
   dev->setVid(data[8] | (data[9] << 8));
   dev->setPid(data[10] | (data[11] << 8));
   DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8));
+  
+  pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
 
   res = getConfigurationDescriptor(dev, data, &total_conf_descr_length);
   if (res != USB_TYPE_OK) {
@@ -624,7 +626,7 @@
   }
 
   // Parse the configuration descriptor
-  parseConfDescr(dev, data, total_conf_descr_length);
+  parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
 
 
   // sixth step: set configuration (only 1 supported)
@@ -647,13 +649,14 @@
 }
 
 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
-void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len)  {
+void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)  {
   uint32_t index = 0;
   uint32_t len_desc = 0;
   uint8_t id = 0;
   int nb_endpoints_used = 0;
   Endpoint * ep = NULL;
   uint8_t intf_nb = 0;
+  bool parsing_intf = false;
 
   while (index < len) {
     len_desc = conf_descr[index];
@@ -662,33 +665,44 @@
     case CONFIGURATION_DESCRIPTOR:
       break;
     case INTERFACE_DESCRIPTOR:
-      if (intf_nb++ <= NB_MAX_INTF) {
-        dev->addInterface(intf_nb - 1, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
-        nb_endpoints_used = 0;
-        DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", intf_nb - 1, (void *)dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]);
-      } else {
-        DBG("Drop intf...");
+      if(pEnumerator->parseInterface(intf_nb, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]))
+      {
+        if (intf_nb++ <= NB_MAX_INTF) {
+          dev->addInterface(intf_nb - 1, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
+          nb_endpoints_used = 0;
+          DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", intf_nb - 1, (void *)dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]);
+        } else {
+          DBG("Drop intf...");
+        }
+        parsing_intf = true;
+      }
+      else
+      {
+        parsing_intf = false;
       }
       break;
     case ENDPOINT_DESCRIPTOR:
       DBG("Ep DESC");
-      if (intf_nb <= NB_MAX_INTF) {
+      if (parsing_intf && (intf_nb <= NB_MAX_INTF) ) {
         if (nb_endpoints_used < MAX_ENDPOINT_PER_INTERFACE) {
-          // if the endpoint is isochronous -> skip it (TODO: fix this)
-          if ((conf_descr[index + 3] & 0x03) != ISOCHRONOUS_ENDPOINT) {
-            ep = newEndpoint((ENDPOINT_TYPE)(conf_descr[index+3] & 0x03),
-                (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1),
-                conf_descr[index + 4] | (conf_descr[index + 5] << 8),
-                conf_descr[index + 2] & 0x0f);
-            DBG("ADD ENDPOINT %p, on interf %d on device %p", (void *)ep, intf_nb - 1, (void *)dev);
-            if (ep != NULL && dev != NULL) {
-              addEndpoint(dev, intf_nb - 1, ep);
+          if( pEnumerator->useEndpoint(intf_nb - 1, (ENDPOINT_TYPE)(conf_descr[index + 3] & 0x03), (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1)) )
+          {
+            // if the endpoint is isochronous -> skip it (TODO: fix this)
+            if ((conf_descr[index + 3] & 0x03) != ISOCHRONOUS_ENDPOINT) {
+              ep = newEndpoint((ENDPOINT_TYPE)(conf_descr[index+3] & 0x03),
+                  (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1),
+                  conf_descr[index + 4] | (conf_descr[index + 5] << 8),
+                  conf_descr[index + 2] & 0x0f);
+              DBG("ADD ENDPOINT %p, on interf %d on device %p", (void *)ep, intf_nb - 1, (void *)dev);
+              if (ep != NULL && dev != NULL) {
+                addEndpoint(dev, intf_nb - 1, ep);
+              } else {
+                DBG("EP NULL");
+              }
+              nb_endpoints_used++;
             } else {
-              DBG("EP NULL");
+              DBG("ISO ENDPOINT NOT SUPPORTED");
             }
-            nb_endpoints_used++;
-          } else {
-            DBG("ISO ENDPOINT NOT SUPPORTED");
           }
         }
       }
--- a/USBHost/USBHost.h	Wed Jul 25 11:13:50 2012 +0000
+++ b/USBHost/USBHost.h	Fri Jul 27 16:14:07 2012 +0000
@@ -22,6 +22,7 @@
 #include "USBHALHost.h"
 #include "USBDeviceConnected.h"
 #include "Endpoint.h"
+#include "IUSBEnumerator.h"
 
 #define MAX_DEVICE_NB 1
 
@@ -133,7 +134,7 @@
     *
     * @returns status of the enumeration
     */
-    USB_TYPE enumerate(USBDeviceConnected * dev) ;
+    USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator) ;
 
     /*
     * Get a device
@@ -228,7 +229,7 @@
     uint16_t  lenReportDescr;
 
     void fillControlBuf(uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, int len) ;
-    void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len) ;
+    void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
     void freeDevice(USBDeviceConnected * dev) ;
     int findDevice(USBDeviceConnected * dev) ;