mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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