local fork (temporary)

Dependents:   VodafoneUSBModem_bleedingedge2

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WANDongle.cpp Source File

WANDongle.cpp

00001 /* Copyright (c) 2010-2012 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004 * and associated documentation files (the "Software"), to deal in the Software without
00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00007 * Software is furnished to do so, subject to the following conditions:
00008 *
00009 * The above copyright notice and this permission notice shall be included in all copies or
00010 * substantial portions of the Software.
00011 *
00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 */
00018 
00019 #define __DEBUG__ 0
00020 #ifndef __MODULE__
00021 #define __MODULE__ "WANDongle.cpp"
00022 #endif
00023 
00024 #include "core/dbg.h"
00025 #include <cstdint>
00026 #include "rtos.h"
00027 
00028 #include "WANDongle.h"
00029 #include "WANDongleInitializer.h"
00030 
00031 WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0)
00032 {
00033     host = USBHost::getHostInst();
00034     init();
00035     DBG("WANDongle object instantiated. getHostInst method called on USBHost.");
00036 }
00037 
00038 
00039 bool WANDongle::connected() {
00040   return dev_connected;
00041 }
00042 
00043 bool WANDongle::tryConnect()
00044 {
00045   //FIXME should run on USB thread
00046 
00047   DBG("Trying to connect device");
00048 
00049   if (dev_connected) {
00050       return true;
00051   }
00052   
00053   m_pInitializer = NULL;
00054 
00055   host->lock();
00056 
00057   for (int i = 0; i < MAX_DEVICE_NB; i++)
00058   {
00059       if ((dev = host->getDevice(i)) != NULL)
00060       {
00061           m_pInitializer = NULL; //Will be set in setVidPid callback
00062       
00063           DBG("Found one device reset it");
00064           int ret = host->resetDevice(dev);
00065           if(ret)
00066           {
00067             host->unlock();
00068             return false;
00069           }
00070 
00071           DBG("Enumerate");
00072           ret = host->enumerate(dev, this);
00073           
00074           if(ret)
00075           {
00076             host->unlock();
00077             return false;
00078           }
00079           
00080           DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
00081                    
00082           if(m_pInitializer) //If an initializer has been found
00083           {
00084             DBG("m_pInitializer=%p", m_pInitializer);
00085             DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
00086             DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
00087             if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
00088             {
00089               DBG("The dongle is in virtual serial mode");
00090               host->registerDriver(dev, 0, this, &WANDongle::init);
00091               m_serialCount = m_pInitializer->getSerialPortCount();
00092               DBG("Num serial ports: %d",m_serialCount);
00093               if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
00094               {
00095                 DBG("setting serial count %d to %d",m_serialCount,WANDONGLE_MAX_SERIAL_PORTS);
00096                 m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
00097               }
00098               for(int j = 0; j < m_serialCount; j++)
00099               {
00100                 DBG("Connecting serial port #%d", j+1);
00101                 DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
00102                 DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
00103                 m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
00104               }
00105               
00106               DBG("Device connected");
00107               
00108               dev_connected = true;
00109               host->unlock();
00110               
00111               return true;
00112             }
00113             else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
00114             {
00115               DBG("Vodafone K3370 dongle detected in MSD mode");
00116               //Try to switch   
00117               if( m_pInitializer->switchMode(dev) )
00118               {
00119                 DBG("Switched OK");
00120                 host->unlock();
00121                 return false; //Will be connected on a next iteration
00122               }
00123               else
00124               {
00125                 ERR("Could not switch mode");
00126                 host->unlock();
00127                 return false;
00128               }
00129             }
00130           } //if()
00131       } //if()
00132       /*else
00133       {
00134         // 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.
00135         // Lets run the initilise routine again. Next time round the loop we might have a handle to an end point!
00136         DBG("Trying to initialise the USB stack since the getDevice method has returned a null pointer");
00137         init();
00138       }*/
00139   } //for()
00140   host->unlock();
00141   return false;
00142 }
00143 
00144 bool WANDongle::disconnect()
00145 {
00146   dev_connected = false;
00147   for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
00148   {
00149     m_serial[i].disconnect();
00150   }
00151   return true;
00152 }
00153 
00154 WAN_DONGLE_TYPE WANDongle::getDongleType()
00155 {
00156   if( m_pInitializer != NULL )
00157   {
00158     return m_pInitializer->getType();
00159   }
00160   else
00161   {
00162     return WAN_DONGLE_TYPE_UNKNOWN;
00163   }
00164 }
00165 
00166 IUSBHostSerial& WANDongle::getSerial(int index)
00167 {
00168   return m_serial[index];
00169 }
00170 
00171 int WANDongle::getSerialCount()
00172 {
00173   return m_serialCount;
00174 }
00175 
00176 //Private methods
00177 void WANDongle::init()
00178 {
00179   m_pInitializer = NULL;
00180   dev_connected = false;
00181   for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
00182   {
00183     m_serial[i].init(host);
00184   }
00185 }
00186 
00187 
00188 /*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
00189 {
00190     //Load right initializer
00191   WANDongleInitializer** initializer = WANDongleInitializer::getInitializers(host);
00192   
00193   while(*initializer)
00194   {
00195     DBG("*initializer=%p", *initializer);
00196     DBG("(*initializer)->getSerialVid()=%04x", (*initializer)->getSerialVid());
00197     DBG("(*initializer)->getSerialPid()=%04x", (*initializer)->getSerialPid());
00198     if ((dev->getVid() == (*initializer)->getSerialVid()) && (dev->getPid() == (*initializer)->getSerialPid()))
00199     {
00200       DBG("The dongle is in virtual serial mode");
00201       m_pInitializer = *initializer;
00202       break;
00203     }
00204     else if ((dev->getVid() == (*initializer)->getMSDVid()) && (dev->getPid() == (*initializer)->getMSDPid()))
00205     {
00206       DBG("Vodafone K3370 dongle detected in MSD mode");
00207       m_pInitializer = *initializer;
00208       break;
00209     }
00210     initializer++;
00211   } //while()
00212   if(m_pInitializer)
00213   {
00214     m_pInitializer->setVidPid(vid, pid);
00215   }
00216 }
00217 
00218 /*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
00219 {
00220   if(m_pInitializer)
00221   {
00222     return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
00223   }
00224   else
00225   {
00226     return false;
00227   }
00228 }
00229 
00230 /*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00231 {
00232   if(m_pInitializer)
00233   {
00234     return m_pInitializer->useEndpoint(intf_nb, type, dir);
00235   }
00236   else
00237   {
00238     return false;
00239   }
00240 }