USB Host WAN Dongle library

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Mon Jul 30 13:51:34 2012 +0000
Parent:
7:c4483d48fe96
Child:
9:c9e9817c398c
Commit message:
Vodafone K3772-Z support!

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/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	Sat Jul 28 14:15:14 2012 +0000
+++ b/USB3GModule/WANDongle.cpp	Mon Jul 30 13:51:34 2012 +0000
@@ -65,7 +65,7 @@
           DBG("Enumerate");
           host->enumerate(dev, this);
           
-          DBG("Device has VID:%04x PID%04x", dev->getVid(), dev->getPid());
+          DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
                    
           if(m_pInitializer) //If an initializer has been found
           {
@@ -121,6 +121,18 @@
   return false;
 }
 
+WAN_DONGLE_TYPE WANDongle::getDongleType()
+{
+  if( m_pInitializer != NULL )
+  {
+    return m_pInitializer->getType();
+  }
+  else
+  {
+    return WAN_DONGLE_TYPE_UNKNOWN;
+  }
+}
+
 IUSBHostSerial& WANDongle::getSerial(int index)
 {
   return m_serial[index];
@@ -147,7 +159,7 @@
     //Load right initializer
           WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
           
-          while((*initializer))
+          while(*initializer)
           {
             DBG("*initializer=%p", *initializer);
             DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
@@ -164,7 +176,7 @@
               m_pInitializer = *initializer;
               break;
             }
-            (*initializer)++;
+            initializer++;
           } //while()
           if(m_pInitializer)
           {
--- a/USB3GModule/WANDongle.h	Sat Jul 28 14:15:14 2012 +0000
+++ b/USB3GModule/WANDongle.h	Mon Jul 30 13:51:34 2012 +0000
@@ -58,6 +58,8 @@
      * * @return true if connection was successful
      */
     bool tryConnect();
+       
+    WAN_DONGLE_TYPE getDongleType();
     
     IUSBHostSerial& getSerial(int index);
     int getSerialCount();
--- a/USB3GModule/WANDongleInitializer.cpp	Sat Jul 28 14:15:14 2012 +0000
+++ b/USB3GModule/WANDongleInitializer.cpp	Mon Jul 30 13:51:34 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__ 4 //Maximum verbosity
+#define __DEBUG__ 0 //Maximum verbosity
 #ifndef __MODULE__
 #define __MODULE__ "WANDongleInitializer.cpp"
 #endif
@@ -36,7 +36,8 @@
 WANDongleInitializer** WANDongleInitializer::getInitializers(USBHost* pHost)
 {
   static VodafoneK3770Initializer vodafoneK3770(pHost);
-  const static WANDongleInitializer* list[] = { &vodafoneK3770, NULL };
+  static VodafoneK3772ZInitializer vodafoneK3772Z(pHost);
+  const static WANDongleInitializer* list[] = { &vodafoneK3770, &vodafoneK3772Z, NULL };
   return (WANDongleInitializer**)list;
 }
 
@@ -46,14 +47,6 @@
     0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0x20, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-// NVIDIA (ICERA) /ZTE K3772-Z (Vodafone)
-// Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 06 1b 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00"
-static uint8_t vodafone_k3772_z_switch_packet[] = {
-    0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0x06, 0x1b, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-
-
 VodafoneK3770Initializer::VodafoneK3770Initializer(USBHost* pHost) : WANDongleInitializer(pHost)
 {
   
@@ -152,3 +145,121 @@
   }
   return false;
 }
+
+/*virtual*/ WAN_DONGLE_TYPE VodafoneK3770Initializer::getType()
+{
+  return WAN_DONGLE_TYPE_VODAFONEK3770;
+}
+
+// NVIDIA (ICERA) /ZTE K3772-Z (Vodafone)
+// Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 06 1b 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00"
+static uint8_t vodafone_k3772_z_switch_packet[] = {
+    0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0x06, 0x1b, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+VodafoneK3772ZInitializer::VodafoneK3772ZInitializer(USBHost* pHost) : WANDongleInitializer(pHost)
+{
+  
+}
+
+uint16_t VodafoneK3772ZInitializer::getMSDVid()      { return 0x19D2; }
+uint16_t VodafoneK3772ZInitializer::getMSDPid()      { return 0x1179; }
+
+uint16_t VodafoneK3772ZInitializer::getSerialVid()   { return 0x19D2; }
+uint16_t VodafoneK3772ZInitializer::getSerialPid()   { return 0x1181; }
+
+bool VodafoneK3772ZInitializer::switchMode(USBDeviceConnected* pDev)
+{
+  for (int i = 0; i < pDev->getNbInterface(); i++) 
+  {
+    if (pDev->getInterface(i)->intf_class == MSD_CLASS)
+    {
+      Endpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
+      if ( pEp != NULL ) 
+      {
+        DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
+        m_pHost->bulkWrite(pDev, pEp, vodafone_k3772_z_switch_packet, 31);
+        return true;
+      }
+    }  
+  }
+  return false;
+}
+
+Endpoint* VodafoneK3772ZInitializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
+{
+  return pDev->getEndpoint((serialPortNumber==1)?0:1, BULK_ENDPOINT, tx?OUT:IN, 0);
+}
+
+int VodafoneK3772ZInitializer::getSerialPortCount()
+{
+  return 2;
+}
+
+/*virtual*/ void VodafoneK3772ZInitializer::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 VodafoneK3772ZInitializer::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 )
+  {
+    DBG("Interface #%d; Class:%02x; SubClass:%02x; Protocol:%02x", intf_nb, intf_class, intf_subclass, intf_protocol);
+    if( intf_class == 0x0A )
+    {
+      if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 1) )
+      {
+        m_currentSerialIntf++;
+        return true;
+      }
+      m_currentSerialIntf++;
+    }
+  }
+  else
+  {
+    if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+/*virtual*/ bool VodafoneK3772ZInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+  if( m_hasSwitched )
+  {
+    DBG("Endpoint on Inteface #%d; Type:%d; Direction:%d", intf_nb, type, dir);
+    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;
+}
+
+
+/*virtual*/ WAN_DONGLE_TYPE VodafoneK3772ZInitializer::getType()
+{
+  return WAN_DONGLE_TYPE_VODAFONEK3772Z;
+}
--- a/USB3GModule/WANDongleInitializer.h	Sat Jul 28 14:15:14 2012 +0000
+++ b/USB3GModule/WANDongleInitializer.h	Mon Jul 30 13:51:34 2012 +0000
@@ -1,87 +1,130 @@
-/* Copyright (c) 2010-2011 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 WANDONGLEINITIALIZER_H
-#define WANDONGLEINITIALIZER_H
-
-#include <cstdint>
-using std::uint16_t;
-using std::uint32_t;
-
-#include "USBHost.h"
-#include "IUSBEnumerator.h"
-
-class WANDongleInitializer : public IUSBEnumerator
-{
-protected:
-    WANDongleInitializer(USBHost* pHost);
-    USBHost* m_pHost;
-    
-public:
-    virtual uint16_t getMSDVid() = 0;
-    virtual uint16_t getMSDPid() = 0;
-    
-    virtual uint16_t getSerialVid() = 0;
-    virtual uint16_t getSerialPid() = 0;
-    
-    virtual bool switchMode(USBDeviceConnected* pDev) = 0;
-    
-    virtual Endpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) = 0;
-    
-    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);
-};
-
-class VodafoneK3770Initializer : public WANDongleInitializer
-{
-public:
-    VodafoneK3770Initializer(USBHost* pHost);
-    
-    virtual uint16_t getMSDVid();
-    virtual uint16_t getMSDPid();
-    
-    virtual uint16_t getSerialVid();
-    virtual uint16_t getSerialPid();
-    
-    virtual bool switchMode(USBDeviceConnected* pDev);
-    
-    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
+/* Copyright (c) 2010-2011 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 WANDONGLEINITIALIZER_H
+#define WANDONGLEINITIALIZER_H
+
+#include <cstdint>
+using std::uint16_t;
+using std::uint32_t;
+
+#include "USBHost.h"
+#include "IUSBEnumerator.h"
+
+enum WAN_DONGLE_TYPE
+{
+  WAN_DONGLE_TYPE_UNKNOWN = -1,
+  WAN_DONGLE_TYPE_VODAFONEK3770 = 0,
+  WAN_DONGLE_TYPE_VODAFONEK3772Z = 1,
+};
+
+class WANDongleInitializer : public IUSBEnumerator
+{
+protected:
+    WANDongleInitializer(USBHost* pHost);
+    USBHost* m_pHost;
+    
+public:
+    virtual uint16_t getMSDVid() = 0;
+    virtual uint16_t getMSDPid() = 0;
+    
+    virtual uint16_t getSerialVid() = 0;
+    virtual uint16_t getSerialPid() = 0;
+    
+    virtual bool switchMode(USBDeviceConnected* pDev) = 0;
+    
+    virtual Endpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) = 0;
+    
+    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
+    
+    virtual WAN_DONGLE_TYPE getType() = 0;
+    
+    static WANDongleInitializer** getInitializers(USBHost* pHost);
+};
+
+class VodafoneK3770Initializer : public WANDongleInitializer
+{
+public:
+    VodafoneK3770Initializer(USBHost* pHost);
+    
+    virtual uint16_t getMSDVid();
+    virtual uint16_t getMSDPid();
+    
+    virtual uint16_t getSerialVid();
+    virtual uint16_t getSerialPid();
+    
+    virtual bool switchMode(USBDeviceConnected* pDev);
+    
+    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
+    
+    virtual WAN_DONGLE_TYPE getType();
+    
+private:
+
+  bool m_hasSwitched;
+  int m_currentSerialIntf;
+  int m_endpointsToFetch;
+};
+
+class VodafoneK3772ZInitializer : public WANDongleInitializer
+{
+public:
+    VodafoneK3772ZInitializer(USBHost* pHost);
+    
+    virtual uint16_t getMSDVid();
+    virtual uint16_t getMSDPid();
+    
+    virtual uint16_t getSerialVid();
+    virtual uint16_t getSerialPid();
+    
+    virtual bool switchMode(USBDeviceConnected* pDev);
+    
+    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
+    
+    virtual WAN_DONGLE_TYPE getType();
+    
+private:
+
+  bool m_hasSwitched;
+  int m_currentSerialIntf;
+  int m_endpointsToFetch;
+};
+
+#endif
--- a/USBHost/USBHost.cpp	Sat Jul 28 14:15:14 2012 +0000
+++ b/USBHost/USBHost.cpp	Mon Jul 30 13:51:34 2012 +0000
@@ -512,9 +512,9 @@
       DEVICE_DESCRIPTOR_LENGTH);
 }
 
-USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint8_t * len_conf_descr)  {
+USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t * len_conf_descr)  {
   USB_TYPE res;
-  uint8_t total_conf_descr_length = 0;
+  uint16_t total_conf_descr_length = 0;
 
   // fourth step: get the beginning of the configuration descriptor to have the total length of the conf descr
   res = controlRead(  dev,
@@ -559,8 +559,8 @@
 
 // enumerate a device with the control endpoint
 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)  {
-  uint8_t data[256];
-  uint8_t total_conf_descr_length = 0;
+  uint8_t data[384];
+  uint16_t total_conf_descr_length = 0;
   USB_TYPE res;
 
   DBG("data = %p", data);
--- a/USBHost/USBHost.h	Sat Jul 28 14:15:14 2012 +0000
+++ b/USBHost/USBHost.h	Mon Jul 30 13:51:34 2012 +0000
@@ -35,7 +35,7 @@
     static USBHost * getHostInst();
     
     USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf) ;
-    USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint8_t * len_conf_descr = NULL) ;
+    USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t * len_conf_descr = NULL) ;
     USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf) ;
     USB_TYPE getStringDescriptor(USBDeviceConnected * dev, uint8_t index, uint8_t * buf) ;
     USB_TYPE getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint8_t len) ;