Changes to support Vodafone K4606

Dependents:   VodafoneUSBModem

Fork of USBHostWANDongle by mbed official

Committer:
dmitryp
Date:
Wed Jan 28 11:38:44 2015 +0000
Revision:
28:34cdecfff9f4
Parent:
25:3184f71557bf
Added support for Vodafone K4606, for more details refer to ; http://atmega.magictale.com/2215/hacking-vodafone-k4606-3g-hsdpa-usb-modem/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 10:08bce4cd973a 1 /* Copyright (c) 2010-2012 mbed.org, MIT License
donatien 0:ae46a0638b2c 2 *
donatien 0:ae46a0638b2c 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
donatien 0:ae46a0638b2c 4 * and associated documentation files (the "Software"), to deal in the Software without
donatien 0:ae46a0638b2c 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
donatien 0:ae46a0638b2c 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
donatien 0:ae46a0638b2c 7 * Software is furnished to do so, subject to the following conditions:
donatien 0:ae46a0638b2c 8 *
donatien 0:ae46a0638b2c 9 * The above copyright notice and this permission notice shall be included in all copies or
donatien 0:ae46a0638b2c 10 * substantial portions of the Software.
donatien 0:ae46a0638b2c 11 *
donatien 0:ae46a0638b2c 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
donatien 0:ae46a0638b2c 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
donatien 0:ae46a0638b2c 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
donatien 0:ae46a0638b2c 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 0:ae46a0638b2c 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
donatien 0:ae46a0638b2c 17 */
donatien 0:ae46a0638b2c 18
donatien 19:6526d83aab9f 19 #define __DEBUG__ 0
donatien 0:ae46a0638b2c 20 #ifndef __MODULE__
donatien 0:ae46a0638b2c 21 #define __MODULE__ "WANDongle.cpp"
donatien 0:ae46a0638b2c 22 #endif
donatien 0:ae46a0638b2c 23
donatien 12:a712bad7a979 24 #include "core/dbg.h"
donatien 0:ae46a0638b2c 25 #include <cstdint>
donatien 0:ae46a0638b2c 26 #include "rtos.h"
donatien 0:ae46a0638b2c 27
donatien 0:ae46a0638b2c 28 #include "WANDongle.h"
donatien 2:a8b2d0cd9bbd 29 #include "WANDongleInitializer.h"
donatien 0:ae46a0638b2c 30
donatien 6:075e36a3463e 31 WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0)
donatien 0:ae46a0638b2c 32 {
dmitryp 28:34cdecfff9f4 33 m_lastDongle = NULL;
donatien 0:ae46a0638b2c 34 host = USBHost::getHostInst();
donatien 0:ae46a0638b2c 35 init();
nherriot 16:e1f5ba831485 36 DBG("WANDongle object instantiated. getHostInst method called on USBHost.");
donatien 0:ae46a0638b2c 37 }
donatien 0:ae46a0638b2c 38
donatien 0:ae46a0638b2c 39
donatien 0:ae46a0638b2c 40 bool WANDongle::connected() {
donatien 0:ae46a0638b2c 41 return dev_connected;
donatien 0:ae46a0638b2c 42 }
donatien 0:ae46a0638b2c 43
donatien 0:ae46a0638b2c 44 bool WANDongle::tryConnect()
donatien 0:ae46a0638b2c 45 {
donatien 0:ae46a0638b2c 46 //FIXME should run on USB thread
donatien 0:ae46a0638b2c 47
donatien 0:ae46a0638b2c 48 DBG("Trying to connect device");
donatien 0:ae46a0638b2c 49
donatien 0:ae46a0638b2c 50 if (dev_connected) {
donatien 0:ae46a0638b2c 51 return true;
donatien 0:ae46a0638b2c 52 }
donatien 6:075e36a3463e 53
donatien 6:075e36a3463e 54 m_pInitializer = NULL;
donatien 0:ae46a0638b2c 55
donatien 0:ae46a0638b2c 56 host->lock();
donatien 0:ae46a0638b2c 57
donatien 2:a8b2d0cd9bbd 58 for (int i = 0; i < MAX_DEVICE_NB; i++)
donatien 2:a8b2d0cd9bbd 59 {
donatien 2:a8b2d0cd9bbd 60 if ((dev = host->getDevice(i)) != NULL)
donatien 2:a8b2d0cd9bbd 61 {
donatien 6:075e36a3463e 62 m_pInitializer = NULL; //Will be set in setVidPid callback
donatien 6:075e36a3463e 63
donatien 6:075e36a3463e 64 DBG("Found one device reset it");
donatien 11:a0841fba0599 65 int ret = host->resetDevice(dev);
donatien 11:a0841fba0599 66 if(ret)
donatien 11:a0841fba0599 67 {
donatien 11:a0841fba0599 68 host->unlock();
donatien 11:a0841fba0599 69 return false;
donatien 11:a0841fba0599 70 }
donatien 0:ae46a0638b2c 71
donatien 0:ae46a0638b2c 72 DBG("Enumerate");
donatien 11:a0841fba0599 73 ret = host->enumerate(dev, this);
ashleymills 24:f4b676f61906 74
donatien 11:a0841fba0599 75 if(ret)
donatien 11:a0841fba0599 76 {
donatien 11:a0841fba0599 77 host->unlock();
donatien 11:a0841fba0599 78 return false;
donatien 11:a0841fba0599 79 }
donatien 2:a8b2d0cd9bbd 80
donatien 8:0d1ec493842c 81 DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
donatien 6:075e36a3463e 82
donatien 6:075e36a3463e 83 if(m_pInitializer) //If an initializer has been found
donatien 2:a8b2d0cd9bbd 84 {
donatien 6:075e36a3463e 85 DBG("m_pInitializer=%p", m_pInitializer);
donatien 6:075e36a3463e 86 DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
donatien 6:075e36a3463e 87 DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
donatien 6:075e36a3463e 88 if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
donatien 2:a8b2d0cd9bbd 89 {
donatien 3:4394986752db 90 DBG("The dongle is in virtual serial mode");
donatien 2:a8b2d0cd9bbd 91 host->registerDriver(dev, 0, this, &WANDongle::init);
donatien 6:075e36a3463e 92 m_serialCount = m_pInitializer->getSerialPortCount();
ashleymills 21:dcc8c866ccbb 93 DBG("Num serial ports: %d",m_serialCount);
donatien 3:4394986752db 94 if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
donatien 3:4394986752db 95 {
ashleymills 21:dcc8c866ccbb 96 DBG("setting serial count %d to %d",m_serialCount,WANDONGLE_MAX_SERIAL_PORTS);
donatien 3:4394986752db 97 m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
donatien 3:4394986752db 98 }
donatien 2:a8b2d0cd9bbd 99 for(int j = 0; j < m_serialCount; j++)
donatien 2:a8b2d0cd9bbd 100 {
donatien 3:4394986752db 101 DBG("Connecting serial port #%d", j+1);
donatien 6:075e36a3463e 102 DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
donatien 6:075e36a3463e 103 DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
donatien 6:075e36a3463e 104 m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
donatien 2:a8b2d0cd9bbd 105 }
donatien 3:4394986752db 106
donatien 3:4394986752db 107 DBG("Device connected");
donatien 3:4394986752db 108
donatien 2:a8b2d0cd9bbd 109 dev_connected = true;
donatien 2:a8b2d0cd9bbd 110 host->unlock();
donatien 3:4394986752db 111
donatien 2:a8b2d0cd9bbd 112 return true;
donatien 2:a8b2d0cd9bbd 113 }
donatien 6:075e36a3463e 114 else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
donatien 2:a8b2d0cd9bbd 115 {
dmitryp 28:34cdecfff9f4 116 DBG("Vodafone dongle detected in MSD mode");
donatien 2:a8b2d0cd9bbd 117 //Try to switch
donatien 6:075e36a3463e 118 if( m_pInitializer->switchMode(dev) )
donatien 2:a8b2d0cd9bbd 119 {
donatien 2:a8b2d0cd9bbd 120 DBG("Switched OK");
donatien 2:a8b2d0cd9bbd 121 host->unlock();
donatien 2:a8b2d0cd9bbd 122 return false; //Will be connected on a next iteration
donatien 0:ae46a0638b2c 123 }
donatien 2:a8b2d0cd9bbd 124 else
donatien 2:a8b2d0cd9bbd 125 {
donatien 2:a8b2d0cd9bbd 126 ERR("Could not switch mode");
donatien 0:ae46a0638b2c 127 host->unlock();
donatien 2:a8b2d0cd9bbd 128 return false;
donatien 0:ae46a0638b2c 129 }
donatien 2:a8b2d0cd9bbd 130 }
donatien 6:075e36a3463e 131 } //if()
donatien 2:a8b2d0cd9bbd 132 } //if()
nherriot 17:b8739fd10faf 133 /*else
nherriot 16:e1f5ba831485 134 {
nherriot 16:e1f5ba831485 135 // Looks like the getDevice method failed and returned a null pointer. Maybe there has been a power cut, modem pulled or something to stop the modem.
nherriot 16:e1f5ba831485 136 // Lets run the initilise routine again. Next time round the loop we might have a handle to an end point!
nherriot 17:b8739fd10faf 137 DBG("Trying to initialise the USB stack since the getDevice method has returned a null pointer");
nherriot 16:e1f5ba831485 138 init();
nherriot 17:b8739fd10faf 139 }*/
donatien 2:a8b2d0cd9bbd 140 } //for()
donatien 0:ae46a0638b2c 141 host->unlock();
donatien 0:ae46a0638b2c 142 return false;
donatien 0:ae46a0638b2c 143 }
donatien 0:ae46a0638b2c 144
donatien 10:08bce4cd973a 145 bool WANDongle::disconnect()
donatien 10:08bce4cd973a 146 {
donatien 10:08bce4cd973a 147 dev_connected = false;
donatien 10:08bce4cd973a 148 for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
donatien 10:08bce4cd973a 149 {
donatien 10:08bce4cd973a 150 m_serial[i].disconnect();
donatien 10:08bce4cd973a 151 }
donatien 10:08bce4cd973a 152 return true;
donatien 10:08bce4cd973a 153 }
donatien 10:08bce4cd973a 154
donatien 8:0d1ec493842c 155 WAN_DONGLE_TYPE WANDongle::getDongleType()
donatien 8:0d1ec493842c 156 {
donatien 8:0d1ec493842c 157 if( m_pInitializer != NULL )
donatien 8:0d1ec493842c 158 {
donatien 8:0d1ec493842c 159 return m_pInitializer->getType();
donatien 8:0d1ec493842c 160 }
donatien 8:0d1ec493842c 161 else
donatien 8:0d1ec493842c 162 {
donatien 8:0d1ec493842c 163 return WAN_DONGLE_TYPE_UNKNOWN;
donatien 8:0d1ec493842c 164 }
donatien 8:0d1ec493842c 165 }
donatien 8:0d1ec493842c 166
donatien 3:4394986752db 167 IUSBHostSerial& WANDongle::getSerial(int index)
donatien 0:ae46a0638b2c 168 {
donatien 2:a8b2d0cd9bbd 169 return m_serial[index];
donatien 0:ae46a0638b2c 170 }
donatien 0:ae46a0638b2c 171
donatien 2:a8b2d0cd9bbd 172 int WANDongle::getSerialCount()
donatien 0:ae46a0638b2c 173 {
donatien 2:a8b2d0cd9bbd 174 return m_serialCount;
donatien 0:ae46a0638b2c 175 }
donatien 0:ae46a0638b2c 176
donatien 0:ae46a0638b2c 177 //Private methods
donatien 0:ae46a0638b2c 178 void WANDongle::init()
donatien 0:ae46a0638b2c 179 {
donatien 10:08bce4cd973a 180 m_pInitializer = NULL;
donatien 0:ae46a0638b2c 181 dev_connected = false;
donatien 3:4394986752db 182 for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
donatien 3:4394986752db 183 {
donatien 3:4394986752db 184 m_serial[i].init(host);
donatien 3:4394986752db 185 }
donatien 0:ae46a0638b2c 186 }
donatien 6:075e36a3463e 187
donatien 6:075e36a3463e 188
donatien 6:075e36a3463e 189 /*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
donatien 6:075e36a3463e 190 {
donatien 6:075e36a3463e 191 //Load right initializer
donatien 10:08bce4cd973a 192 WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
donatien 10:08bce4cd973a 193
donatien 10:08bce4cd973a 194 while(*initializer)
donatien 10:08bce4cd973a 195 {
dmitryp 28:34cdecfff9f4 196 if (m_lastDongle)
dmitryp 28:34cdecfff9f4 197 {
dmitryp 28:34cdecfff9f4 198 DBG("Initializer has been already detected in previous step");
dmitryp 28:34cdecfff9f4 199 m_pInitializer = m_lastDongle;
dmitryp 28:34cdecfff9f4 200 break;
dmitryp 28:34cdecfff9f4 201 }
dmitryp 28:34cdecfff9f4 202
dmitryp 28:34cdecfff9f4 203
donatien 10:08bce4cd973a 204 DBG("*initializer=%p", *initializer);
donatien 10:08bce4cd973a 205 DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
donatien 10:08bce4cd973a 206 DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid());
donatien 10:08bce4cd973a 207 if ((dev->getVid() == (*initializer)->getSerialVid()) && (dev->getPid() == (*initializer)->getSerialPid()))
donatien 10:08bce4cd973a 208 {
donatien 10:08bce4cd973a 209 DBG("The dongle is in virtual serial mode");
donatien 10:08bce4cd973a 210 m_pInitializer = *initializer;
donatien 10:08bce4cd973a 211 break;
donatien 10:08bce4cd973a 212 }
donatien 10:08bce4cd973a 213 else if ((dev->getVid() == (*initializer)->getMSDVid()) && (dev->getPid() == (*initializer)->getMSDPid()))
donatien 10:08bce4cd973a 214 {
donatien 10:08bce4cd973a 215 DBG("Vodafone K3370 dongle detected in MSD mode");
donatien 10:08bce4cd973a 216 m_pInitializer = *initializer;
dmitryp 28:34cdecfff9f4 217
dmitryp 28:34cdecfff9f4 218 //Store successfully detected modem type so that after switch to serial mode
dmitryp 28:34cdecfff9f4 219 //we can distinuguish modems with same Vid-Pid pairs
dmitryp 28:34cdecfff9f4 220 m_lastDongle = *initializer;
dmitryp 28:34cdecfff9f4 221
donatien 10:08bce4cd973a 222 break;
donatien 10:08bce4cd973a 223 }
donatien 10:08bce4cd973a 224 initializer++;
donatien 10:08bce4cd973a 225 } //while()
donatien 10:08bce4cd973a 226 if(m_pInitializer)
donatien 10:08bce4cd973a 227 {
donatien 10:08bce4cd973a 228 m_pInitializer->setVidPid(vid, pid);
donatien 10:08bce4cd973a 229 }
donatien 6:075e36a3463e 230 }
donatien 6:075e36a3463e 231
donatien 6:075e36a3463e 232 /*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
donatien 6:075e36a3463e 233 {
donatien 6:075e36a3463e 234 if(m_pInitializer)
donatien 6:075e36a3463e 235 {
donatien 6:075e36a3463e 236 return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
donatien 6:075e36a3463e 237 }
donatien 6:075e36a3463e 238 else
donatien 6:075e36a3463e 239 {
donatien 6:075e36a3463e 240 return false;
donatien 6:075e36a3463e 241 }
donatien 6:075e36a3463e 242 }
donatien 6:075e36a3463e 243
donatien 6:075e36a3463e 244 /*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
donatien 6:075e36a3463e 245 {
donatien 6:075e36a3463e 246 if(m_pInitializer)
donatien 6:075e36a3463e 247 {
donatien 6:075e36a3463e 248 return m_pInitializer->useEndpoint(intf_nb, type, dir);
donatien 6:075e36a3463e 249 }
donatien 6:075e36a3463e 250 else
donatien 6:075e36a3463e 251 {
donatien 6:075e36a3463e 252 return false;
donatien 6:075e36a3463e 253 }
donatien 6:075e36a3463e 254 }