Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBHostWANDongle by
Revision 28:34cdecfff9f4, committed 2015-01-28
- Comitter:
- dmitryp
- Date:
- Wed Jan 28 11:38:44 2015 +0000
- Parent:
- 27:980fe31c14f7
- Commit message:
- Added support for Vodafone K4606, for more details refer to ; http://atmega.magictale.com/2215/hacking-vodafone-k4606-3g-hsdpa-usb-modem/
Changed in this revision
--- a/USB3GModule/WANDongle.cpp Fri Sep 20 10:40:15 2013 +0000 +++ b/USB3GModule/WANDongle.cpp Wed Jan 28 11:38:44 2015 +0000 @@ -30,6 +30,7 @@ WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0) { + m_lastDongle = NULL; host = USBHost::getHostInst(); init(); DBG("WANDongle object instantiated. getHostInst method called on USBHost."); @@ -112,7 +113,7 @@ } else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid())) { - DBG("Vodafone K3370 dongle detected in MSD mode"); + DBG("Vodafone dongle detected in MSD mode"); //Try to switch if( m_pInitializer->switchMode(dev) ) { @@ -192,6 +193,14 @@ while(*initializer) { + if (m_lastDongle) + { + DBG("Initializer has been already detected in previous step"); + m_pInitializer = m_lastDongle; + break; + } + + DBG("*initializer=%p", *initializer); DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid()); DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid()); @@ -205,6 +214,11 @@ { DBG("Vodafone K3370 dongle detected in MSD mode"); m_pInitializer = *initializer; + + //Store successfully detected modem type so that after switch to serial mode + //we can distinuguish modems with same Vid-Pid pairs + m_lastDongle = *initializer; + break; } initializer++;
--- a/USB3GModule/WANDongle.h Fri Sep 20 10:40:15 2013 +0000 +++ b/USB3GModule/WANDongle.h Wed Jan 28 11:38:44 2015 +0000 @@ -92,6 +92,7 @@ WANDongleSerialPort m_serial[WANDONGLE_MAX_SERIAL_PORTS]; int m_serialCount; + WANDongleInitializer* m_lastDongle; }; #endif
--- a/USB3GModule/WANDongleInitializer.cpp Fri Sep 20 10:40:15 2013 +0000 +++ b/USB3GModule/WANDongleInitializer.cpp Wed Jan 28 11:38:44 2015 +0000 @@ -28,9 +28,9 @@ #include "WANDongleInitializer.h" + WANDongleInitializer::WANDongleInitializer(USBHost* pHost) : m_pHost(pHost) { - } WANDongleInitializer** WANDongleInitializer::getInitializers(USBHost* pHost) @@ -41,6 +41,8 @@ static VodafoneK3773Initializer vodafoneK3773(pHost); static HuaweiMU509Initializer huaweiMU509(pHost); static UbloxLISAU200Initializer ubloxLISAU200(pHost); + static VodafoneK4606Initializer vodafoneK4606(pHost); + const static WANDongleInitializer* list[] = { &vodafoneK3770, &vodafoneK3772Z, @@ -48,6 +50,7 @@ &vodafoneK3773, &huaweiMU509, &ubloxLISAU200, + &vodafoneK4606, NULL }; return (WANDongleInitializer**)list; @@ -681,4 +684,118 @@ /*virtual*/ WAN_DONGLE_TYPE UbloxLISAU200Initializer::getType() { return WAN_DONGLE_TYPE_UBLOX_LISAU200; -} \ No newline at end of file +} + + +//----------------------------------------------------------------------- +// Huawei K4606 (Vodafone) +//----------------------------------------------------------------------- +// Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 00 11 06 20 00 00 01 00 00 00 00 00 00 00 00 00 00" +static uint8_t vodafone_k4606_switch_packet[] = { + 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0x00, 0, 0, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +VodafoneK4606Initializer::VodafoneK4606Initializer(USBHost* pHost) : WANDongleInitializer(pHost) +{ +} + +uint16_t VodafoneK4606Initializer::getMSDVid() { return 0x12D1; } +uint16_t VodafoneK4606Initializer::getMSDPid() { return 0x1F19; } + +uint16_t VodafoneK4606Initializer::getSerialVid() { return 0x12D1; } +uint16_t VodafoneK4606Initializer::getSerialPid() { return 0x1001;} + +bool VodafoneK4606Initializer::switchMode(USBDeviceConnected* pDev) +{ + for (int i = 0; i < pDev->getNbInterface(); i++) + { + if (pDev->getInterface(i)->intf_class == MSD_CLASS) + { + USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT); + if ( pEp != NULL ) + { + DBG("Vodafone K4606 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_k4606_switch_packet, 31); + return true; + } + } + } + return false; +} + +USBEndpoint* VodafoneK4606Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) +{ + return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0); +} + +int VodafoneK4606Initializer::getSerialPortCount() +{ + return 2; +} + +void VodafoneK4606Initializer::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; + } +} + +bool VodafoneK4606Initializer::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("*K4606 parsing intf %d, intf_class %d, m_currentSerialIntf %d", intf_nb, intf_class, m_currentSerialIntf); + + if( intf_class == 0x2 ) + { + if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 2) ) + { + m_currentSerialIntf++; + return true; + } + m_currentSerialIntf++; + } + } + else + { + if( (intf_nb == 0) && (intf_class == MSD_CLASS) ) + { + return true; + } + } + return false; +} + +bool VodafoneK4606Initializer::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; +} + + WAN_DONGLE_TYPE VodafoneK4606Initializer::getType() +{ + return WAN_DONGLE_TYPE_VODAFONE_K4606; +}
--- a/USB3GModule/WANDongleInitializer.h Fri Sep 20 10:40:15 2013 +0000 +++ b/USB3GModule/WANDongleInitializer.h Wed Jan 28 11:38:44 2015 +0000 @@ -34,7 +34,8 @@ WAN_DONGLE_TYPE_VODAFONE_K3772 = 2, WAN_DONGLE_TYPE_VODAFONE_K3773 = 3, WAN_DONGLE_TYPE_HUAWEI_MU509 = 4, - WAN_DONGLE_TYPE_UBLOX_LISAU200 = 5 + WAN_DONGLE_TYPE_UBLOX_LISAU200 = 5, + WAN_DONGLE_TYPE_VODAFONE_K4606 = 6 }; class WANDongleInitializer : public IUSBEnumerator @@ -262,5 +263,39 @@ int m_endpointsToFetch; }; + +class VodafoneK4606Initializer : public WANDongleInitializer +{ +public: + VodafoneK4606Initializer(USBHost* pHost); + + virtual uint16_t getMSDVid(); + virtual uint16_t getMSDPid(); + + virtual uint16_t getSerialVid(); + virtual uint16_t getSerialPid(); + + virtual bool switchMode(USBDeviceConnected* pDev); + + virtual USBEndpoint* 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