USB Host Library for Sprint Dongles

Fork of USBHostWANDongleSprint_bleedingedge by Donatien Garnier

Legacy Warning

This is an mbed 2 libary. To learn more about mbed OS 5, visit the docs.

Committer:
donatien
Date:
Wed Sep 12 08:15:02 2012 +0000
Revision:
0:bfed5767d0a5
Child:
2:34c976009b70
Initial Commit

Who changed what in which revision?

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