WANDongle.cpp 6.6 KB

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