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:
Mon Dec 10 18:18:35 2012 +0000
Revision:
9:2a7b7333245f
Parent:
7:3fdc32f938d9
Parent:
8:65cd51339647
Merge

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 3:9ec92dd8a8cb 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 2:34c976009b70 66 WARN("Could not reset it");
donatien 0:bfed5767d0a5 67 host->unlock();
donatien 0:bfed5767d0a5 68 return false;
donatien 0:bfed5767d0a5 69 }
donatien 0:bfed5767d0a5 70
donatien 0:bfed5767d0a5 71 DBG("Enumerate");
donatien 0:bfed5767d0a5 72 ret = host->enumerate(dev, this);
donatien 0:bfed5767d0a5 73 if(ret)
donatien 0:bfed5767d0a5 74 {
donatien 2:34c976009b70 75 WARN("Could not enumerate");
donatien 0:bfed5767d0a5 76 host->unlock();
donatien 0:bfed5767d0a5 77 return false;
donatien 0:bfed5767d0a5 78 }
donatien 0:bfed5767d0a5 79
donatien 0:bfed5767d0a5 80 DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
donatien 0:bfed5767d0a5 81
donatien 0:bfed5767d0a5 82 if(m_pInitializer) //If an initializer has been found
donatien 0:bfed5767d0a5 83 {
donatien 0:bfed5767d0a5 84 DBG("m_pInitializer=%p", m_pInitializer);
donatien 0:bfed5767d0a5 85 DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
donatien 0:bfed5767d0a5 86 DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
donatien 0:bfed5767d0a5 87 if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
donatien 0:bfed5767d0a5 88 {
donatien 0:bfed5767d0a5 89 DBG("The dongle is in virtual serial mode");
donatien 0:bfed5767d0a5 90 host->registerDriver(dev, 0, this, &WANDongle::init);
donatien 0:bfed5767d0a5 91 m_serialCount = m_pInitializer->getSerialPortCount();
donatien 0:bfed5767d0a5 92 if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
donatien 0:bfed5767d0a5 93 {
donatien 0:bfed5767d0a5 94 m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
donatien 0:bfed5767d0a5 95 }
donatien 0:bfed5767d0a5 96 for(int j = 0; j < m_serialCount; j++)
donatien 0:bfed5767d0a5 97 {
donatien 0:bfed5767d0a5 98 DBG("Connecting serial port #%d", j+1);
donatien 0:bfed5767d0a5 99 DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
donatien 0:bfed5767d0a5 100 DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
donatien 0:bfed5767d0a5 101 m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
donatien 0:bfed5767d0a5 102 }
donatien 0:bfed5767d0a5 103
donatien 0:bfed5767d0a5 104 DBG("Device connected");
donatien 0:bfed5767d0a5 105
donatien 0:bfed5767d0a5 106 dev_connected = true;
donatien 0:bfed5767d0a5 107 host->unlock();
donatien 0:bfed5767d0a5 108
donatien 0:bfed5767d0a5 109
donatien 0:bfed5767d0a5 110 return true;
donatien 0:bfed5767d0a5 111 }
donatien 0:bfed5767d0a5 112 else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
donatien 0:bfed5767d0a5 113 {
donatien 2:34c976009b70 114 DBG("Dongle detected in MSD mode");
donatien 0:bfed5767d0a5 115 //Try to switch
donatien 0:bfed5767d0a5 116 if( m_pInitializer->switchMode(dev) )
donatien 0:bfed5767d0a5 117 {
donatien 0:bfed5767d0a5 118 DBG("Switched OK");
donatien 0:bfed5767d0a5 119 host->unlock();
donatien 0:bfed5767d0a5 120 return false; //Will be connected on a next iteration
donatien 0:bfed5767d0a5 121 }
donatien 0:bfed5767d0a5 122 else
donatien 0:bfed5767d0a5 123 {
donatien 0:bfed5767d0a5 124 ERR("Could not switch mode");
donatien 0:bfed5767d0a5 125 host->unlock();
donatien 0:bfed5767d0a5 126 return false;
donatien 0:bfed5767d0a5 127 }
donatien 0:bfed5767d0a5 128 }
donatien 0:bfed5767d0a5 129 } //if()
donatien 0:bfed5767d0a5 130 } //if()
donatien 0:bfed5767d0a5 131 } //for()
donatien 0:bfed5767d0a5 132 host->unlock();
donatien 0:bfed5767d0a5 133 return false;
donatien 0:bfed5767d0a5 134 }
donatien 0:bfed5767d0a5 135
donatien 0:bfed5767d0a5 136 bool WANDongle::disconnect()
donatien 0:bfed5767d0a5 137 {
donatien 0:bfed5767d0a5 138 dev_connected = false;
donatien 0:bfed5767d0a5 139 for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
donatien 0:bfed5767d0a5 140 {
donatien 0:bfed5767d0a5 141 m_serial[i].disconnect();
donatien 0:bfed5767d0a5 142 }
donatien 0:bfed5767d0a5 143 return true;
donatien 0:bfed5767d0a5 144 }
donatien 0:bfed5767d0a5 145
donatien 0:bfed5767d0a5 146 WAN_DONGLE_TYPE WANDongle::getDongleType()
donatien 0:bfed5767d0a5 147 {
donatien 0:bfed5767d0a5 148 if( m_pInitializer != NULL )
donatien 0:bfed5767d0a5 149 {
donatien 0:bfed5767d0a5 150 return m_pInitializer->getType();
donatien 0:bfed5767d0a5 151 }
donatien 0:bfed5767d0a5 152 else
donatien 0:bfed5767d0a5 153 {
donatien 0:bfed5767d0a5 154 return WAN_DONGLE_TYPE_UNKNOWN;
donatien 0:bfed5767d0a5 155 }
donatien 0:bfed5767d0a5 156 }
donatien 0:bfed5767d0a5 157
donatien 0:bfed5767d0a5 158 IUSBHostSerial& WANDongle::getSerial(int index)
donatien 0:bfed5767d0a5 159 {
donatien 0:bfed5767d0a5 160 return m_serial[index];
donatien 0:bfed5767d0a5 161 }
donatien 0:bfed5767d0a5 162
donatien 0:bfed5767d0a5 163 int WANDongle::getSerialCount()
donatien 0:bfed5767d0a5 164 {
donatien 0:bfed5767d0a5 165 return m_serialCount;
donatien 0:bfed5767d0a5 166 }
donatien 0:bfed5767d0a5 167
donatien 0:bfed5767d0a5 168 //Private methods
donatien 0:bfed5767d0a5 169 void WANDongle::init()
donatien 0:bfed5767d0a5 170 {
donatien 0:bfed5767d0a5 171 m_pInitializer = NULL;
donatien 0:bfed5767d0a5 172 dev_connected = false;
donatien 0:bfed5767d0a5 173 for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
donatien 0:bfed5767d0a5 174 {
donatien 0:bfed5767d0a5 175 m_serial[i].init(host);
donatien 0:bfed5767d0a5 176 }
donatien 0:bfed5767d0a5 177 }
donatien 0:bfed5767d0a5 178
donatien 0:bfed5767d0a5 179
donatien 0:bfed5767d0a5 180 /*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
donatien 0:bfed5767d0a5 181 {
donatien 8:65cd51339647 182 //Load right initializer
donatien 0:bfed5767d0a5 183 WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
donatien 0:bfed5767d0a5 184
donatien 0:bfed5767d0a5 185 while(*initializer)
donatien 0:bfed5767d0a5 186 {
donatien 0:bfed5767d0a5 187 DBG("*initializer=%p", *initializer);
donatien 0:bfed5767d0a5 188 DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
donatien 0:bfed5767d0a5 189 DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid());
donatien 0:bfed5767d0a5 190 if ((dev->getVid() == (*initializer)->getSerialVid()) && (dev->getPid() == (*initializer)->getSerialPid()))
donatien 0:bfed5767d0a5 191 {
donatien 0:bfed5767d0a5 192 DBG("The dongle is in virtual serial mode");
donatien 0:bfed5767d0a5 193 m_pInitializer = *initializer;
donatien 0:bfed5767d0a5 194 break;
donatien 0:bfed5767d0a5 195 }
donatien 0:bfed5767d0a5 196 else if ((dev->getVid() == (*initializer)->getMSDVid()) && (dev->getPid() == (*initializer)->getMSDPid()))
donatien 0:bfed5767d0a5 197 {
mbed_official 7:3fdc32f938d9 198 DBG("Dongle detected in MSD mode");
donatien 0:bfed5767d0a5 199 m_pInitializer = *initializer;
donatien 0:bfed5767d0a5 200 break;
donatien 0:bfed5767d0a5 201 }
donatien 0:bfed5767d0a5 202 initializer++;
donatien 0:bfed5767d0a5 203 } //while()
donatien 0:bfed5767d0a5 204 if(m_pInitializer)
donatien 0:bfed5767d0a5 205 {
donatien 0:bfed5767d0a5 206 m_pInitializer->setVidPid(vid, pid);
donatien 0:bfed5767d0a5 207 }
donatien 0:bfed5767d0a5 208 }
donatien 0:bfed5767d0a5 209
donatien 0:bfed5767d0a5 210 /*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 211 {
donatien 0:bfed5767d0a5 212 if(m_pInitializer)
donatien 0:bfed5767d0a5 213 {
donatien 0:bfed5767d0a5 214 return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
donatien 0:bfed5767d0a5 215 }
donatien 0:bfed5767d0a5 216 else
donatien 0:bfed5767d0a5 217 {
donatien 0:bfed5767d0a5 218 return false;
donatien 0:bfed5767d0a5 219 }
donatien 0:bfed5767d0a5 220 }
donatien 0:bfed5767d0a5 221
donatien 0:bfed5767d0a5 222 /*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 223 {
donatien 0:bfed5767d0a5 224 if(m_pInitializer)
donatien 0:bfed5767d0a5 225 {
donatien 0:bfed5767d0a5 226 return m_pInitializer->useEndpoint(intf_nb, type, dir);
donatien 0:bfed5767d0a5 227 }
donatien 0:bfed5767d0a5 228 else
donatien 0:bfed5767d0a5 229 {
donatien 0:bfed5767d0a5 230 return false;
donatien 0:bfed5767d0a5 231 }
donatien 0:bfed5767d0a5 232 }