local fork (temporary)

Dependents:   VodafoneUSBModem_bleedingedge2

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WANDongleInitializer.cpp Source File

WANDongleInitializer.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__ "WANDongleInitializer.cpp"
00022 #endif
00023 
00024 #include "core/dbg.h"
00025 
00026 #include <cstdint>
00027 using std::uint16_t;
00028 
00029 #include "WANDongleInitializer.h"
00030 
00031 WANDongleInitializer::WANDongleInitializer(USBHost* pHost) : m_pHost(pHost)
00032 {
00033 
00034 }
00035 
00036 WANDongleInitializer** WANDongleInitializer::getInitializers(USBHost* pHost)
00037 {
00038   static VodafoneK3770Initializer vodafoneK3770(pHost);
00039   static VodafoneK3772ZInitializer vodafoneK3772Z(pHost);
00040   static VodafoneK3772Initializer vodafoneK3772(pHost);
00041   static VodafoneK3773Initializer vodafoneK3773(pHost);
00042   static VodafoneMU509Initializer vodafoneMU509(pHost);
00043   const static WANDongleInitializer* list[] = {
00044      &vodafoneK3770,
00045      &vodafoneK3772Z,
00046      &vodafoneK3772,
00047      &vodafoneK3773,
00048      &vodafoneMU509,
00049      NULL
00050   };
00051   return (WANDongleInitializer**)list;
00052 }
00053 
00054 //Huawei K3770 (Vodafone)
00055 // Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 00 11 06 20 00 00 01 00 00 00 00 00 00 00 00 00 00"
00056 static uint8_t vodafone_k3770_switch_packet[] = {
00057     0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0x20, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00058 };
00059 
00060 VodafoneK3770Initializer::VodafoneK3770Initializer(USBHost* pHost) : WANDongleInitializer(pHost)
00061 {
00062   
00063 }
00064 
00065 uint16_t VodafoneK3770Initializer::getMSDVid()      { return 0x12D1; }
00066 uint16_t VodafoneK3770Initializer::getMSDPid()      { return 0x14D1; }
00067 
00068 uint16_t VodafoneK3770Initializer::getSerialVid()   { return 0x12D1; }
00069 uint16_t VodafoneK3770Initializer::getSerialPid()   { return 0x14C9; }
00070 
00071 bool VodafoneK3770Initializer::switchMode(USBDeviceConnected* pDev)
00072 {
00073   for (int i = 0; i < pDev->getNbInterface(); i++) 
00074   {
00075     if (pDev->getInterface(i)->intf_class == MSD_CLASS)
00076     {
00077       USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
00078       if ( pEp != NULL ) 
00079       {
00080         DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
00081         m_pHost->bulkWrite(pDev, pEp, vodafone_k3770_switch_packet, 31);
00082         return true;
00083       }
00084     }  
00085   }
00086   return false;
00087 }
00088 
00089 USBEndpoint* VodafoneK3770Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
00090 {
00091   return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
00092 }
00093 
00094 int VodafoneK3770Initializer::getSerialPortCount()
00095 {
00096   return 2;
00097 }
00098 
00099 /*virtual*/ void VodafoneK3770Initializer::setVidPid(uint16_t vid, uint16_t pid)
00100 {
00101     if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) )
00102     {
00103       m_hasSwitched = true;
00104       m_currentSerialIntf = 0;
00105       m_endpointsToFetch = 4;
00106     }
00107     else
00108     {
00109       m_hasSwitched = false;
00110       m_endpointsToFetch = 1;
00111     }
00112 }
00113 
00114 /*virtual*/ bool VodafoneK3770Initializer::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
00115 {
00116   if( m_hasSwitched )
00117   {
00118     if( intf_class == 0xFF )
00119     {
00120       if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 4) )
00121       {
00122         m_currentSerialIntf++;
00123         return true;
00124       }
00125       m_currentSerialIntf++;
00126     }
00127   }
00128   else
00129   {
00130     if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
00131     {
00132       return true;
00133     }
00134   }
00135   return false;
00136 }
00137 
00138 /*virtual*/ bool VodafoneK3770Initializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00139 {
00140   if( m_hasSwitched )
00141   {
00142     if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
00143     {
00144       m_endpointsToFetch--;
00145       return true;
00146     }
00147   }
00148   else
00149   {
00150     if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch )
00151     {
00152       m_endpointsToFetch--;
00153       return true;
00154     }
00155   }
00156   return false;
00157 }
00158 
00159 /*virtual*/ WAN_DONGLE_TYPE VodafoneK3770Initializer::getType()
00160 {
00161   return WAN_DONGLE_TYPE_VODAFONEK3770;
00162 }
00163 
00164 //Huawei MU509 (Module)
00165 
00166 VodafoneMU509Initializer::VodafoneMU509Initializer(USBHost* pHost) : WANDongleInitializer(pHost)
00167 {
00168   
00169 }
00170 
00171 uint16_t VodafoneMU509Initializer::getMSDVid()      { return 0x12D1; }
00172 uint16_t VodafoneMU509Initializer::getMSDPid()      { return 0x0000; } //No MSD mode (presumably)
00173 
00174 uint16_t VodafoneMU509Initializer::getSerialVid()   { return 0x12D1; }
00175 uint16_t VodafoneMU509Initializer::getSerialPid()   { return 0x1001; }
00176 
00177 bool VodafoneMU509Initializer::switchMode(USBDeviceConnected* pDev)
00178 {
00179   return true; //No MSD mode
00180 }
00181 
00182 USBEndpoint* VodafoneMU509Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
00183 {
00184   /*
00185   int sPort = serialPortNumber;
00186   if(sPort==1)
00187      sPort = 0;
00188   if(sPort==2)
00189      sPort = 1;
00190   if(sPort==0)
00191      sPort = 2;
00192   return pDev->getEndpoint(sPort, BULK_ENDPOINT, tx?OUT:IN, 0);
00193   */
00194   return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
00195   //return pDev->getEndpoint((serialPortNumber==1)?0:1, BULK_ENDPOINT, tx?OUT:IN, 0);
00196 }
00197 
00198 int VodafoneMU509Initializer::getSerialPortCount()
00199 {
00200   return 2;
00201 }
00202 
00203 /*virtual*/ void VodafoneMU509Initializer::setVidPid(uint16_t vid, uint16_t pid)
00204 {
00205   m_currentSerialIntf = 0;
00206   m_endpointsToFetch = 4;
00207 }
00208 
00209 /*virtual*/ bool VodafoneMU509Initializer::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
00210 {
00211   if( intf_class == 0xFF )
00212   {
00213     if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 2) )
00214     {
00215       m_currentSerialIntf++;
00216       return true;
00217     }
00218     m_currentSerialIntf++;
00219   }
00220   return false;
00221 }
00222 
00223 /*virtual*/ bool VodafoneMU509Initializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00224 {
00225   if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
00226   {
00227     DBG("new endpoint");
00228     m_endpointsToFetch--;
00229     return true;
00230   }
00231   return false;
00232 }
00233 
00234 /*virtual*/ WAN_DONGLE_TYPE VodafoneMU509Initializer::getType()
00235 {
00236   return WAN_DONGLE_TYPE_VODAFONEMU509;
00237 }
00238 
00239 //Huawei K3773 (Vodafone)
00240 // Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 00 11 06 20 00 00 01 00 00 00 00 00 00 00 00 00 00"
00241 static uint8_t vodafone_k3773_switch_packet[] = {
00242     0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0x20, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00243 };
00244 
00245 VodafoneK3773Initializer::VodafoneK3773Initializer(USBHost* pHost) : WANDongleInitializer(pHost)
00246 {
00247   
00248 }
00249 
00250 uint16_t VodafoneK3773Initializer::getMSDVid()      { return 0x12D1; }
00251 uint16_t VodafoneK3773Initializer::getMSDPid()      { return 0x1506; }
00252 
00253 uint16_t VodafoneK3773Initializer::getSerialVid()   { return 0x12D1; }
00254 uint16_t VodafoneK3773Initializer::getSerialPid()   { return 0x1506; }
00255 
00256 bool VodafoneK3773Initializer::switchMode(USBDeviceConnected* pDev)
00257 {
00258   for (int i = 0; i < pDev->getNbInterface(); i++) 
00259   {
00260     if (pDev->getInterface(i)->intf_class == MSD_CLASS)
00261     {
00262       USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
00263       if ( pEp != NULL ) 
00264       {
00265         DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
00266         m_pHost->bulkWrite(pDev, pEp, vodafone_k3773_switch_packet, 31);
00267         return true;
00268       }
00269     }  
00270   }
00271   return false;
00272 }
00273 
00274 USBEndpoint* VodafoneK3773Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
00275 {
00276   return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
00277 }
00278 
00279 int VodafoneK3773Initializer::getSerialPortCount()
00280 {
00281   return 2;
00282 }
00283 
00284 /*virtual*/ void VodafoneK3773Initializer::setVidPid(uint16_t vid, uint16_t pid)
00285 {
00286     if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) )
00287     {
00288       m_hasSwitched = true;
00289       m_currentSerialIntf = 0;
00290       m_endpointsToFetch = 4;
00291     }
00292     else
00293     {
00294       m_hasSwitched = false;
00295       m_endpointsToFetch = 1;
00296     }
00297 }
00298 
00299 /*virtual*/ bool VodafoneK3773Initializer::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
00300 {
00301   if( m_hasSwitched )
00302   {
00303     if( intf_class == 0xFF )
00304     {
00305       if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 4) )
00306       {
00307         m_currentSerialIntf++;
00308         return true;
00309       }
00310       m_currentSerialIntf++;
00311     }
00312   }
00313   else
00314   {
00315     if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
00316     {
00317       return true;
00318     }
00319   }
00320   return false;
00321 }
00322 
00323 /*virtual*/ bool VodafoneK3773Initializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00324 {
00325   if( m_hasSwitched )
00326   {
00327     if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
00328     {
00329       m_endpointsToFetch--;
00330       return true;
00331     }
00332   }
00333   else
00334   {
00335     if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch )
00336     {
00337       m_endpointsToFetch--;
00338       return true;
00339     }
00340   }
00341   return false;
00342 }
00343 
00344 /*virtual*/ WAN_DONGLE_TYPE VodafoneK3773Initializer::getType()
00345 {
00346   return WAN_DONGLE_TYPE_VODAFONEK3773;
00347 }
00348 
00349 // NVIDIA (ICERA) /ZTE K3772-Z (Vodafone)
00350 // Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 00 00 00 00 00 06 1b 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00"
00351 static uint8_t vodafone_k3772_z_switch_packet[] = {
00352     0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0x06, 0x1b, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00353 };
00354 
00355 VodafoneK3772ZInitializer::VodafoneK3772ZInitializer(USBHost* pHost) : WANDongleInitializer(pHost)
00356 {
00357   
00358 }
00359 
00360 uint16_t VodafoneK3772ZInitializer::getMSDVid()      { return 0x19D2; }
00361 uint16_t VodafoneK3772ZInitializer::getMSDPid()      { return 0x1179; }
00362 
00363 uint16_t VodafoneK3772ZInitializer::getSerialVid()   { return 0x19D2; }
00364 uint16_t VodafoneK3772ZInitializer::getSerialPid()   { return 0x1181; }
00365 
00366 bool VodafoneK3772ZInitializer::switchMode(USBDeviceConnected* pDev)
00367 {
00368   for (int i = 0; i < pDev->getNbInterface(); i++) 
00369   {
00370     if (pDev->getInterface(i)->intf_class == MSD_CLASS)
00371     {
00372       USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
00373       if ( pEp != NULL ) 
00374       {
00375         DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
00376         m_pHost->bulkWrite(pDev, pEp, vodafone_k3772_z_switch_packet, 31);
00377         return true;
00378       }
00379     }  
00380   }
00381   return false;
00382 }
00383 
00384 USBEndpoint* VodafoneK3772ZInitializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
00385 {
00386   return pDev->getEndpoint((serialPortNumber==1)?0:1, BULK_ENDPOINT, tx?OUT:IN, 0);
00387 }
00388 
00389 int VodafoneK3772ZInitializer::getSerialPortCount()
00390 {
00391   return 2;
00392 }
00393 
00394 /*virtual*/ void VodafoneK3772ZInitializer::setVidPid(uint16_t vid, uint16_t pid)
00395 {
00396     if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) )
00397     {
00398       m_hasSwitched = true;
00399       m_currentSerialIntf = 0;
00400       m_endpointsToFetch = 4;
00401     }
00402     else
00403     {
00404       m_hasSwitched = false;
00405       m_endpointsToFetch = 1;
00406     }
00407 }
00408 
00409 /*virtual*/ bool VodafoneK3772ZInitializer::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
00410 {
00411   if( m_hasSwitched )
00412   {
00413     DBG("Interface #%d; Class:%02x; SubClass:%02x; Protocol:%02x", intf_nb, intf_class, intf_subclass, intf_protocol);
00414     if( intf_class == 0x0A )
00415     {
00416       if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 1) )
00417       {
00418         m_currentSerialIntf++;
00419         return true;
00420       }
00421       m_currentSerialIntf++;
00422     }
00423   }
00424   else
00425   {
00426     if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
00427     {
00428       return true;
00429     }
00430   }
00431   return false;
00432 }
00433 
00434 /*virtual*/ bool VodafoneK3772ZInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00435 {
00436   if( m_hasSwitched )
00437   {
00438     DBG("USBEndpoint on Inteface #%d; Type:%d; Direction:%d", intf_nb, type, dir);
00439     if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
00440     {
00441       m_endpointsToFetch--;
00442       return true;
00443     }
00444   }
00445   else
00446   {
00447     if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch )
00448     {
00449       m_endpointsToFetch--;
00450       return true;
00451     }
00452   }
00453   return false;
00454 }
00455 
00456 
00457 /*virtual*/ WAN_DONGLE_TYPE VodafoneK3772ZInitializer::getType()
00458 {
00459   return WAN_DONGLE_TYPE_VODAFONEK3772Z;
00460 }
00461 
00462 //Huawei K3772 (Vodafone)
00463 // Switching from mass storage device string is: "55 53 42 43 12 34 56 78 00 02 00 00 80 00 0a 11 06 20 00 00 00 00 00 01 00 00 00 00 00 00 00"
00464 static uint8_t vodafone_k3772_switch_packet[] = {
00465     0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0x02, 0, 0, 0x80, 0, 0x0a, 0x11, 0x06, 0x20, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0
00466 };
00467 
00468 
00469 VodafoneK3772Initializer::VodafoneK3772Initializer(USBHost* pHost) : WANDongleInitializer(pHost)
00470 {
00471   
00472 }
00473 
00474 uint16_t VodafoneK3772Initializer::getMSDVid()      { return 0x12D1; }
00475 uint16_t VodafoneK3772Initializer::getMSDPid()      { return 0x1526; }
00476 
00477 uint16_t VodafoneK3772Initializer::getSerialVid()   { return 0x12D1; }
00478 uint16_t VodafoneK3772Initializer::getSerialPid()   { return 0x14CF; }
00479 
00480 bool VodafoneK3772Initializer::switchMode(USBDeviceConnected* pDev)
00481 {
00482   for (int i = 0; i < pDev->getNbInterface(); i++) 
00483   {
00484     if (pDev->getInterface(i)->intf_class == MSD_CLASS)
00485     {
00486       USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
00487       if ( pEp != NULL ) 
00488       {
00489         DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
00490         m_pHost->bulkWrite(pDev, pEp, vodafone_k3772_switch_packet, 31);
00491         return true;
00492       }
00493     }  
00494   }
00495   return false;
00496 }
00497 
00498 USBEndpoint* VodafoneK3772Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
00499 {
00500   return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
00501 }
00502 
00503 int VodafoneK3772Initializer::getSerialPortCount()
00504 {
00505   return 2;
00506 }
00507 
00508 /*virtual*/ void VodafoneK3772Initializer::setVidPid(uint16_t vid, uint16_t pid)
00509 {
00510     if( (vid == getSerialVid() ) && ( pid == getSerialPid() ) )
00511     {
00512       m_hasSwitched = true;
00513       m_currentSerialIntf = 0;
00514       m_endpointsToFetch = 4;
00515     }
00516     else
00517     {
00518       m_hasSwitched = false;
00519       m_endpointsToFetch = 1;
00520     }
00521 }
00522 
00523 /*virtual*/ bool VodafoneK3772Initializer::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
00524 {
00525   if( m_hasSwitched )
00526   {
00527     if( intf_class == 0xFF )
00528     {
00529       if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 2) )
00530       {
00531         m_currentSerialIntf++;
00532         return true;
00533       }
00534       m_currentSerialIntf++;
00535     }
00536   }
00537   else
00538   {
00539     if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
00540     {
00541       return true;
00542     }
00543   }
00544   return false;
00545 }
00546 
00547 /*virtual*/ bool VodafoneK3772Initializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00548 {
00549   if( m_hasSwitched )
00550   {
00551     if( (type == BULK_ENDPOINT) && m_endpointsToFetch )
00552     {
00553       m_endpointsToFetch--;
00554       return true;
00555     }
00556   }
00557   else
00558   {
00559     if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch )
00560     {
00561       m_endpointsToFetch--;
00562       return true;
00563     }
00564   }
00565   return false;
00566 }
00567 
00568 /*virtual*/ WAN_DONGLE_TYPE VodafoneK3772Initializer::getType()
00569 {
00570   return WAN_DONGLE_TYPE_VODAFONEK3772;
00571 }