u-blox USB modems (GSM and CDMA)
Dependencies: CellularUSBModem
Dependents: C027_CANInterfaceComm C027_ModemTransparentUSBCDC_revb UbloxModemHTTPClientTest C027_HTTPClientTest ... more
UbloxUSBCDMAModem.cpp
00001 /* UbloxUSBCDMAModem.cpp */ 00002 /* Copyright (C) 2012 mbed.org, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 #define __DEBUG__ 4 00021 #ifndef __MODULE__ 00022 #define __MODULE__ "UbloxUSBCDMAModem.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include "UbloxUSBCDMAModem.h" 00028 #include "UbloxCDMAModemInitializer.h" 00029 #include "USBHost.h" 00030 00031 #define USE_ONE_PORT 1 00032 00033 UbloxUSBCDMAModem::UbloxUSBCDMAModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/, int serial /* 0 */) : m_dongle(), 00034 m_stream(m_dongle.getSerial(serial)), 00035 m_at(&m_stream), 00036 m_sms(&m_at), m_ppp(&m_stream), 00037 m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false), 00038 m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) 00039 { 00040 USBHost* host = USBHost::getHostInst(); 00041 m_dongle.addInitializer(new UbloxCDMAModemInitializer(host)); 00042 if( m_powerGatingPin != NC ) 00043 { 00044 power(false); //Dongle will have to be powered on manually 00045 } 00046 } 00047 00048 class CSSProcessor : public IATCommandsProcessor 00049 { 00050 public: 00051 CSSProcessor() : status(STATUS_REGISTERING) 00052 { 00053 00054 } 00055 enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK }; 00056 REGISTERING_STATUS getStatus() 00057 { 00058 return status; 00059 } 00060 private: 00061 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00062 { 00063 char b; 00064 char bc[3] = ""; 00065 int sid = 99999; 00066 00067 //if( sscanf(line, "%*d, %c", &r) == 1 ) 00068 if(sscanf(line, "%*s %c,%2s,%d", &b,bc,&sid)==3) 00069 { 00070 if(strcmp("Z", bc) == 0) 00071 status = STATUS_REGISTERING; 00072 else 00073 status = STATUS_OK; 00074 } 00075 return OK; 00076 } 00077 virtual int onNewEntryPrompt(ATCommandsInterface* pInst) 00078 { 00079 return OK; 00080 } 00081 volatile REGISTERING_STATUS status; 00082 }; 00083 00084 int UbloxUSBCDMAModem::connect(const char* apn, const char* user, const char* password) 00085 { 00086 if( !m_ipInit ) 00087 { 00088 m_ipInit = true; 00089 m_ppp.init(); 00090 } 00091 m_ppp.setup(user, password, DEFAULT_MSISDN_CDMA); 00092 00093 int ret = init(); 00094 if(ret) 00095 { 00096 return ret; 00097 } 00098 00099 #if USE_ONE_PORT 00100 m_smsInit = false; //SMS status reset 00101 //m_ussdInit = false; //USSD status reset 00102 //m_linkMonitorInit = false; //Link monitor status reset 00103 #endif 00104 00105 ATCommandsInterface::ATResult result; 00106 00107 if(apn != NULL) 00108 { 00109 char cmd[48]; 00110 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); 00111 ret = m_at.executeSimple(cmd, &result); 00112 DBG("Result of command: Err code=%d", ret); 00113 DBG("ATResult: AT return=%d (code %d)", result.result, result.code); 00114 DBG("APN set to %s", apn); 00115 } 00116 00117 00118 //Connect 00119 DBG("Connecting"); 00120 #if USE_ONE_PORT 00121 m_at.close(); // Closing AT parser 00122 m_atOpen = false; //Will need to be reinitialized afterwards 00123 #endif 00124 00125 DBG("Connecting PPP"); 00126 00127 ret = m_ppp.connect(); 00128 DBG("Result of connect: Err code=%d", ret); 00129 return ret; 00130 } 00131 00132 00133 int UbloxUSBCDMAModem::disconnect() 00134 { 00135 DBG("Disconnecting from PPP"); 00136 int ret = m_ppp.disconnect(); 00137 if(ret) 00138 { 00139 ERR("Disconnect returned %d, still trying to disconnect", ret); 00140 } 00141 00142 //Ugly but leave dongle time to recover 00143 Thread::wait(500); 00144 00145 #if USE_ONE_PORT 00146 ATCommandsInterface::ATResult result; 00147 DBG("Starting AT thread"); 00148 ret = m_at.open(); 00149 if(ret) 00150 { 00151 return ret; 00152 } 00153 #endif 00154 00155 DBG("Trying to hangup"); 00156 00157 #if 0 //Does not appear to work 00158 int tries = 10; 00159 do 00160 { 00161 ret = m_at.executeSimple("+++", &result, 1000); 00162 DBG("Result of command: Err code=%d\n", ret); 00163 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00164 } while(tries-- && ret); 00165 if(!ret) 00166 { 00167 ret = m_at.executeSimple("ATH", &result); 00168 DBG("Result of command: Err code=%d\n", ret); 00169 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00170 } 00171 #endif 00172 00173 #if USE_ONE_PORT 00174 //Reinit AT parser 00175 ret = m_at.init(); 00176 DBG("Result of command: Err code=%d\n", ret); 00177 if(ret) 00178 { 00179 m_at.close(); // Closing AT parser 00180 DBG("AT Parser closed, could not complete disconnection"); 00181 return NET_TIMEOUT; 00182 } 00183 00184 #if 0 00185 m_at.close(); // Closing AT parser 00186 DBG("AT Parser closed"); 00187 #endif 00188 #endif 00189 return OK; 00190 } 00191 00192 int UbloxUSBCDMAModem::sendSM(const char* number, const char* message) 00193 { 00194 int ret = init(); 00195 if(ret) 00196 { 00197 return ret; 00198 } 00199 00200 if(!m_smsInit) 00201 { 00202 ret = m_sms.init(); 00203 if(ret) 00204 { 00205 return ret; 00206 } 00207 m_smsInit = true; 00208 } 00209 00210 ret = m_sms.send(number, message); 00211 if(ret) 00212 { 00213 return ret; 00214 } 00215 00216 return OK; 00217 } 00218 00219 int UbloxUSBCDMAModem::getSM(char* number, char* message, size_t maxLength) 00220 { 00221 int ret = init(); 00222 if(ret) 00223 { 00224 return ret; 00225 } 00226 00227 if(!m_smsInit) 00228 { 00229 ret = m_sms.init(); 00230 if(ret) 00231 { 00232 return ret; 00233 } 00234 m_smsInit = true; 00235 } 00236 00237 ret = m_sms.get(number, message, maxLength); 00238 if(ret) 00239 { 00240 return ret; 00241 } 00242 00243 return OK; 00244 } 00245 00246 int UbloxUSBCDMAModem::getSMCount(size_t* pCount) 00247 { 00248 int ret = init(); 00249 if(ret) 00250 { 00251 return ret; 00252 } 00253 00254 if(!m_smsInit) 00255 { 00256 ret = m_sms.init(); 00257 if(ret) 00258 { 00259 return ret; 00260 } 00261 m_smsInit = true; 00262 } 00263 00264 ret = m_sms.getCount(pCount); 00265 if(ret) 00266 { 00267 return ret; 00268 } 00269 00270 return OK; 00271 } 00272 00273 ATCommandsInterface* UbloxUSBCDMAModem::getATCommandsInterface() 00274 { 00275 return &m_at; 00276 } 00277 00278 int UbloxUSBCDMAModem::power(bool enable) 00279 { 00280 if( m_powerGatingPin == NC ) 00281 { 00282 return NET_INVALID; //A pin name has not been provided in the constructor 00283 } 00284 00285 if(!enable) //Will force components to re-init 00286 { 00287 cleanup(); 00288 } 00289 00290 DigitalOut powerGatingOut(m_powerGatingPin); 00291 powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable; 00292 00293 return OK; 00294 } 00295 00296 bool UbloxUSBCDMAModem::power() 00297 { 00298 if( m_powerGatingPin == NC ) 00299 { 00300 return true; //Assume power is always on 00301 } 00302 00303 DigitalOut powerGatingOut(m_powerGatingPin); 00304 return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut; 00305 } 00306 00307 int UbloxUSBCDMAModem::init() 00308 { 00309 if( !m_dongleConnected ) 00310 { 00311 if(!power()) 00312 { 00313 //Obviously cannot initialize the dongle if it is disconnected... 00314 ERR("Power is off"); 00315 return NET_INVALID; 00316 } 00317 m_dongleConnected = true; 00318 while( !m_dongle.connected() ) 00319 { 00320 m_dongle.tryConnect(); 00321 Thread::wait(100); 00322 } 00323 } 00324 00325 if(m_atOpen) 00326 { 00327 return OK; 00328 } 00329 00330 DBG("Starting AT thread if needed"); 00331 int ret = m_at.open(); 00332 if(ret) 00333 { 00334 return ret; 00335 } 00336 00337 DBG("Sending initialisation commands"); 00338 ret = m_at.init(); 00339 if(ret) 00340 { 00341 return ret; 00342 } 00343 00344 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200) 00345 { 00346 INFO("Using a UBLOX C200 Dongle"); 00347 } 00348 else 00349 { 00350 WARN("Using an Unknown Dongle"); 00351 } 00352 00353 ATCommandsInterface::ATResult result; 00354 00355 //Wait for network registration 00356 CSSProcessor cssProcessor; 00357 do 00358 { 00359 DBG("Waiting for network registration"); 00360 ret = m_at.execute("AT+CSS?", &cssProcessor, &result); 00361 DBG("Result of command: Err code=%d\n", ret); 00362 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00363 if(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING) 00364 { 00365 Thread::wait(3000); 00366 } 00367 } while(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING); 00368 00369 m_atOpen = true; 00370 00371 return OK; 00372 } 00373 00374 int UbloxUSBCDMAModem::cleanup() 00375 { 00376 if(m_ppp.isConnected()) 00377 { 00378 WARN("Data connection is still open"); //Try to encourage good behaviour from the user 00379 m_ppp.disconnect(); 00380 } 00381 00382 m_smsInit = false; 00383 // m_linkMonitorInit = false; 00384 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once 00385 00386 if(m_atOpen) 00387 { 00388 m_at.close(); 00389 m_atOpen = false; 00390 } 00391 00392 m_dongle.disconnect(); 00393 m_dongleConnected = false; 00394 00395 return OK; 00396 } 00397 00398
Generated on Tue Jul 12 2022 19:17:01 by 1.7.2