NetServices Stack source
Dependents: HelloWorld ServoInterfaceBoardExample1 4180_Lab4
UMTSStick.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "netCfg.h" 00025 #if NET_UMTS 00026 00027 #include "UMTSStick.h" 00028 00029 #define __DEBUG 00030 #include "dbg/dbg.h" 00031 00032 UMTSStick::UMTSStick() : m_host(), m_pDev(NULL) 00033 { 00034 00035 } 00036 00037 UMTSStick::~UMTSStick() 00038 { 00039 00040 } 00041 00042 00043 UMTSStickErr UMTSStick::getSerial(UsbSerial** ppUsbSerial) 00044 { 00045 m_host.init(); 00046 00047 UMTSStickErr rc; 00048 00049 rc = waitForDevice(); 00050 if(rc) 00051 return rc; 00052 00053 //Device is now enumerated, read table 00054 00055 uint16_t vid = m_pDev->getVid(); 00056 uint16_t pid = m_pDev->getPid(); 00057 00058 DBG("Configuration set: vid:%04x pid:%04x\n", vid, pid); 00059 00060 bool handled = false; 00061 bool cdfs = false; 00062 const UMTSSwitchingInfo* pInfo; 00063 for(int i = 0; i < UMTS_SWITCHING_COUNT; i++) 00064 { 00065 pInfo = &UMTSwitchingTable[i]; 00066 if( !checkDeviceState(pInfo, &cdfs) ) 00067 { 00068 handled = true; 00069 break; 00070 } 00071 00072 } //for(int i = 0; i < UMTS_SWITCHING_COUNT; i++) 00073 00074 if(!handled) 00075 { 00076 DBG("Don't know this device!\n"); 00077 return UMTSERR_NOTIMPLEMENTED; 00078 } 00079 00080 //Check if the device is in CDFS mode, in this case switch 00081 if(cdfs) 00082 { 00083 DBG("Switching the device by sending a magic packet\n"); 00084 00085 rc = switchMode(pInfo); 00086 if(rc) 00087 return rc; 00088 00089 DBG("Now wait for device to reconnect\n"); 00090 00091 m_host.releaseDevice(m_pDev); 00092 00093 //Wait for device to reconnect 00094 wait(3); 00095 rc = waitForDevice(); 00096 if(rc) 00097 return rc; 00098 } 00099 00100 rc = findSerial(ppUsbSerial); 00101 if(rc) 00102 return rc; 00103 00104 return UMTSERR_OK; 00105 } 00106 00107 UMTSStickErr UMTSStick::waitForDevice() 00108 { 00109 bool ready = false; 00110 while(!ready) 00111 { 00112 while(!m_host.devicesCount()) 00113 {} 00114 wait(1); 00115 if(m_host.devicesCount()) 00116 ready = true; 00117 } 00118 00119 wait(2); //Wait for device to be initialized 00120 00121 if(!m_host.devicesCount()) 00122 return UMTSERR_DISCONNECTED; 00123 00124 m_pDev = m_host.getDevice(0); 00125 00126 while(!m_pDev->enumerated()) 00127 { 00128 m_host.poll(); 00129 if(!m_host.devicesCount()) 00130 return UMTSERR_DISCONNECTED; 00131 } 00132 00133 return UMTSERR_OK; 00134 } 00135 00136 UMTSStickErr UMTSStick::checkDeviceState(const UMTSSwitchingInfo* pInfo, bool* pCdfs) 00137 { 00138 uint16_t vid = m_pDev->getVid(); 00139 uint16_t pid = m_pDev->getPid(); 00140 bool handled = false; 00141 if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) 00142 { 00143 DBG("Match on dongles list\n"); 00144 if( !pInfo->targetClass ) //No specific interface to check, vid/pid couple is specific to CDFS mode 00145 { 00146 DBG("Found device in CDFS mode\n"); 00147 handled = true; 00148 *pCdfs = true; 00149 } 00150 else //if( !pInfo->targetClass ) 00151 { 00152 //Has to check if there is an interface of class targetClass 00153 byte* desc = NULL; 00154 int c = 0; 00155 00156 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) 00157 { 00158 if( desc[5] == pInfo->targetClass ) 00159 { 00160 DBG("Found device in Serial mode\n"); 00161 handled = true; 00162 *pCdfs = false; 00163 break; 00164 } 00165 } 00166 00167 if(!handled) 00168 { 00169 //All interfaces were tried, so we are in CDFS mode 00170 DBG("Found device in CDFS mode\n"); 00171 handled = true; 00172 *pCdfs = true; 00173 } 00174 } //if( !pInfo->targetClass ) 00175 } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) 00176 else 00177 { 00178 //Try every vid/pid couple of the serial list 00179 for( int i = 0; i < 16 ; i++) 00180 { 00181 if(!pInfo->serialPidList[i]) 00182 break; 00183 if( (pInfo->serialVid == vid) && (pInfo->serialPidList[i] == pid) ) 00184 { 00185 DBG("Found device in Serial mode\n"); 00186 handled = true; 00187 *pCdfs = false; 00188 break; 00189 } 00190 } 00191 } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) 00192 00193 if(!handled) 00194 return UMTSERR_NOTFOUND; 00195 00196 return UMTSERR_OK; 00197 } 00198 00199 UMTSStickErr UMTSStick::switchMode(const UMTSSwitchingInfo* pInfo) 00200 { 00201 if(!pInfo->huaweiPacket) //Send SCSI packet on first bulk ep 00202 { 00203 //Find first bulk ep 00204 byte* desc = NULL; 00205 int c = 0; 00206 00207 UsbEndpoint *pEpOut = NULL; 00208 00209 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) 00210 { 00211 byte* p = desc; 00212 int epNum = 0; 00213 p = p + p[0]; //Move to next descriptor (which should be an ep descriptor) 00214 while (epNum < desc[4]) //Eps count in this if 00215 { 00216 if (p[1] != USB_DESCRIPTOR_TYPE_ENDPOINT) 00217 break; 00218 00219 if( (p[3] == 0x02) && !(p[2] & 0x80) ) //Bulk endpoint, out 00220 { 00221 DBG("Found bulk ep %02x\n", p[2]); 00222 pEpOut = new UsbEndpoint( m_pDev, p[2], false, USB_BULK, *((uint16_t*)&p[4]) ); 00223 break; 00224 } 00225 00226 p = p + p[0]; //Move to next ep desc 00227 epNum++; 00228 } 00229 if(pEpOut) 00230 break; 00231 } 00232 00233 if(!pEpOut) 00234 return UMTSERR_NOTFOUND; 00235 00236 //Send SCSI packet 00237 00238 DBG("Sending SCSI Packet to switch\n"); 00239 byte ramCdfsBuf[31]; 00240 memcpy(ramCdfsBuf, pInfo->cdfsPacket, 31); 00241 pEpOut->transfer((volatile byte*)ramCdfsBuf, 31); 00242 while(pEpOut->status() == USBERR_PROCESSING); 00243 int ret = pEpOut->status(); 00244 if((ret < 0) && (ret !=USBERR_DISCONNECTED)) //Packet was not transfered 00245 { 00246 DBG("Usb error %d\n", ret); 00247 delete pEpOut; 00248 return UMTSERR_USBERR; 00249 } 00250 00251 delete pEpOut; 00252 } 00253 else 00254 { 00255 UsbErr usbErr; 00256 //Send the Huawei-specific control packet 00257 usbErr = m_pDev->controlSend(0, 0x03, 1, 0, NULL, 0); 00258 if(usbErr && (usbErr != USBERR_DISCONNECTED)) 00259 return UMTSERR_USBERR; 00260 } 00261 00262 DBG("The stick should be switching in serial mode now\n"); 00263 00264 return UMTSERR_OK; 00265 } 00266 00267 UMTSStickErr UMTSStick::findSerial(UsbSerial** ppUsbSerial) 00268 { 00269 byte* desc = NULL; 00270 int c = 0; 00271 00272 int epOut = 0; 00273 int epIn = 0; 00274 00275 while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) 00276 { 00277 byte* p = desc; 00278 int epNum = 0; 00279 00280 DBG("Interface of type %02x\n", desc[5]); 00281 00282 if(desc[5] != 0xFF) //Not a serial-like if 00283 continue; 00284 00285 p = p + p[0]; //Move to next descriptor (which should be an ep descriptor) 00286 while (epNum < desc[4]) //Eps count in this if 00287 { 00288 if (p[1] == USB_DESCRIPTOR_TYPE_ENDPOINT) 00289 { 00290 if( (p[3] == 0x02) && !(p[2] & 0x80) && !epOut ) //Bulk endpoint, out 00291 { 00292 DBG("Found bulk out ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4])); 00293 epOut = p[2] & 0x7F; 00294 } 00295 00296 if( (p[3] == 0x02) && (p[2] & 0x80) && !epIn ) //Bulk endpoint, in 00297 { 00298 DBG("Found bulk in ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4])); 00299 epIn = p[2] & 0x7F; 00300 } 00301 00302 if(epOut && epIn) 00303 break; 00304 } 00305 00306 p = p + p[0]; //Move to next ep desc 00307 epNum++; 00308 } 00309 00310 if(epOut && epIn) 00311 break; 00312 } 00313 00314 if(!epOut || !epIn) 00315 return UMTSERR_NOTFOUND; 00316 00317 DBG("Endpoints found, create serial object\n"); 00318 00319 *ppUsbSerial = new UsbSerial(m_pDev, epIn, epOut); 00320 00321 DBG("UsbSerial object created\n"); 00322 00323 return UMTSERR_OK; 00324 } 00325 00326 #endif
Generated on Tue Jul 12 2022 11:52:58 by 1.7.2