Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SprintUSBModemHTTPClientTest by
SprintUSBModem.cpp
00001 /* SprintUSBModem.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__ "SprintUSBModem.cpp" 00023 #endif 00024 00025 #include "core/fwk.h" 00026 00027 #include "SprintUSBModem.h" 00028 00029 #define USE_ONE_PORT 1 00030 00031 SprintUSBModem::SprintUSBModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/, int serial /* 0 */) : m_dongle(), 00032 m_stream(m_dongle.getSerial(serial)), 00033 m_at(&m_stream), 00034 m_sms(&m_at), m_ppp(&m_stream), 00035 m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false), 00036 m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) 00037 { 00038 if( m_powerGatingPin != NC ) 00039 { 00040 power(false); //Dongle will have to be powered on manually 00041 } 00042 } 00043 00044 class CSSProcessor : public IATCommandsProcessor 00045 { 00046 public: 00047 CSSProcessor() : status(STATUS_REGISTERING) 00048 { 00049 00050 } 00051 enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK }; 00052 REGISTERING_STATUS getStatus() 00053 { 00054 return status; 00055 } 00056 private: 00057 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) 00058 { 00059 char b; 00060 char bc[3] = ""; 00061 int sid = 99999; 00062 00063 //if( sscanf(line, "%*d, %c", &r) == 1 ) 00064 if(sscanf(line, "%*s %c,%2s,%d", &b,bc,&sid)==3) 00065 { 00066 if(strcmp("Z", bc) == 0) 00067 status = STATUS_REGISTERING; 00068 else 00069 status = STATUS_OK; 00070 } 00071 return OK; 00072 } 00073 virtual int onNewEntryPrompt(ATCommandsInterface* pInst) 00074 { 00075 return OK; 00076 } 00077 volatile REGISTERING_STATUS status; 00078 }; 00079 00080 int SprintUSBModem::connect(const char* apn, const char* user, const char* password) 00081 { 00082 if( !m_ipInit ) 00083 { 00084 m_ipInit = true; 00085 m_ppp.init(); 00086 } 00087 m_ppp.setup(user, password); 00088 00089 int ret = init(); 00090 if(ret) 00091 { 00092 return ret; 00093 } 00094 00095 #if USE_ONE_PORT 00096 m_smsInit = false; //SMS status reset 00097 //m_ussdInit = false; //USSD status reset 00098 //m_linkMonitorInit = false; //Link monitor status reset 00099 #endif 00100 00101 ATCommandsInterface::ATResult result; 00102 00103 if(apn != NULL) 00104 { 00105 char cmd[48]; 00106 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); 00107 ret = m_at.executeSimple(cmd, &result); 00108 DBG("Result of command: Err code=%d", ret); 00109 DBG("ATResult: AT return=%d (code %d)", result.result, result.code); 00110 DBG("APN set to %s", apn); 00111 } 00112 00113 00114 //Connect 00115 DBG("Connecting"); 00116 #if USE_ONE_PORT 00117 m_at.close(); // Closing AT parser 00118 m_atOpen = false; //Will need to be reinitialized afterwards 00119 #endif 00120 00121 DBG("Connecting PPP"); 00122 00123 ret = m_ppp.connect(); 00124 DBG("Result of connect: Err code=%d", ret); 00125 return ret; 00126 } 00127 00128 00129 int SprintUSBModem::disconnect() 00130 { 00131 DBG("Disconnecting from PPP"); 00132 int ret = m_ppp.disconnect(); 00133 if(ret) 00134 { 00135 ERR("Disconnect returned %d, still trying to disconnect", ret); 00136 } 00137 00138 //Ugly but leave dongle time to recover 00139 Thread::wait(500); 00140 00141 #if USE_ONE_PORT 00142 ATCommandsInterface::ATResult result; 00143 DBG("Starting AT thread"); 00144 ret = m_at.open(); 00145 if(ret) 00146 { 00147 return ret; 00148 } 00149 #endif 00150 00151 DBG("Trying to hangup"); 00152 00153 #if 0 //Does not appear to work 00154 int tries = 10; 00155 do 00156 { 00157 ret = m_at.executeSimple("+++", &result, 1000); 00158 DBG("Result of command: Err code=%d\n", ret); 00159 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00160 } while(tries-- && ret); 00161 if(!ret) 00162 { 00163 ret = m_at.executeSimple("ATH", &result); 00164 DBG("Result of command: Err code=%d\n", ret); 00165 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00166 } 00167 #endif 00168 00169 #if USE_ONE_PORT 00170 //Reinit AT parser 00171 ret = m_at.init(); 00172 DBG("Result of command: Err code=%d\n", ret); 00173 if(ret) 00174 { 00175 m_at.close(); // Closing AT parser 00176 DBG("AT Parser closed, could not complete disconnection"); 00177 return NET_TIMEOUT; 00178 } 00179 00180 #if 0 00181 m_at.close(); // Closing AT parser 00182 DBG("AT Parser closed"); 00183 #endif 00184 #endif 00185 return OK; 00186 } 00187 00188 int SprintUSBModem::sendSM(const char* number, const char* message) 00189 { 00190 int ret = init(); 00191 if(ret) 00192 { 00193 return ret; 00194 } 00195 00196 if(!m_smsInit) 00197 { 00198 ret = m_sms.init(); 00199 if(ret) 00200 { 00201 return ret; 00202 } 00203 m_smsInit = true; 00204 } 00205 00206 ret = m_sms.send(number, message); 00207 if(ret) 00208 { 00209 return ret; 00210 } 00211 00212 return OK; 00213 } 00214 00215 int SprintUSBModem::getSM(char* number, char* message, size_t maxLength) 00216 { 00217 int ret = init(); 00218 if(ret) 00219 { 00220 return ret; 00221 } 00222 00223 if(!m_smsInit) 00224 { 00225 ret = m_sms.init(); 00226 if(ret) 00227 { 00228 return ret; 00229 } 00230 m_smsInit = true; 00231 } 00232 00233 ret = m_sms.get(number, message, maxLength); 00234 if(ret) 00235 { 00236 return ret; 00237 } 00238 00239 return OK; 00240 } 00241 00242 int SprintUSBModem::getSMCount(size_t* pCount) 00243 { 00244 int ret = init(); 00245 if(ret) 00246 { 00247 return ret; 00248 } 00249 00250 if(!m_smsInit) 00251 { 00252 ret = m_sms.init(); 00253 if(ret) 00254 { 00255 return ret; 00256 } 00257 m_smsInit = true; 00258 } 00259 00260 ret = m_sms.getCount(pCount); 00261 if(ret) 00262 { 00263 return ret; 00264 } 00265 00266 return OK; 00267 } 00268 00269 ATCommandsInterface* SprintUSBModem::getATCommandsInterface() 00270 { 00271 return &m_at; 00272 } 00273 00274 int SprintUSBModem::power(bool enable) 00275 { 00276 if( m_powerGatingPin == NC ) 00277 { 00278 return NET_INVALID; //A pin name has not been provided in the constructor 00279 } 00280 00281 if(!enable) //Will force components to re-init 00282 { 00283 cleanup(); 00284 } 00285 00286 DigitalOut powerGatingOut(m_powerGatingPin); 00287 powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable; 00288 00289 return OK; 00290 } 00291 00292 bool SprintUSBModem::power() 00293 { 00294 if( m_powerGatingPin == NC ) 00295 { 00296 return true; //Assume power is always on 00297 } 00298 00299 DigitalOut powerGatingOut(m_powerGatingPin); 00300 return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut; 00301 } 00302 00303 int SprintUSBModem::init() 00304 { 00305 if( !m_dongleConnected ) 00306 { 00307 if(!power()) 00308 { 00309 //Obviously cannot initialize the dongle if it is disconnected... 00310 ERR("Power is off"); 00311 return NET_INVALID; 00312 } 00313 m_dongleConnected = true; 00314 while( !m_dongle.connected() ) 00315 { 00316 m_dongle.tryConnect(); 00317 Thread::wait(100); 00318 } 00319 } 00320 00321 if(m_atOpen) 00322 { 00323 return OK; 00324 } 00325 00326 DBG("Starting AT thread if needed"); 00327 int ret = m_at.open(); 00328 if(ret) 00329 { 00330 return ret; 00331 } 00332 00333 DBG("Sending initialisation commands"); 00334 ret = m_at.init(); 00335 if(ret) 00336 { 00337 return ret; 00338 } 00339 00340 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_SPRINT598U) 00341 { 00342 INFO("Using a Sprint 598U Dongle"); 00343 } 00344 else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_SPRINTMC5728V) 00345 { 00346 INFO("Using a Sprint MC5728V Dongle"); 00347 } 00348 else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOXC200) 00349 { 00350 INFO("Using a UBLOX C200 Dongle"); 00351 } 00352 else 00353 { 00354 WARN("Using an Unknown Dongle"); 00355 } 00356 00357 ATCommandsInterface::ATResult result; 00358 00359 //Wait for network registration 00360 CSSProcessor cssProcessor; 00361 do 00362 { 00363 DBG("Waiting for network registration"); 00364 ret = m_at.execute("AT+CSS?", &cssProcessor, &result); 00365 DBG("Result of command: Err code=%d\n", ret); 00366 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code); 00367 if(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING) 00368 { 00369 Thread::wait(3000); 00370 } 00371 } while(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING); 00372 00373 m_atOpen = true; 00374 00375 return OK; 00376 } 00377 00378 int SprintUSBModem::cleanup() 00379 { 00380 if(m_ppp.isConnected()) 00381 { 00382 WARN("Data connection is still open"); //Try to encourage good behaviour from the user 00383 m_ppp.disconnect(); 00384 } 00385 00386 m_smsInit = false; 00387 // m_linkMonitorInit = false; 00388 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once 00389 00390 if(m_atOpen) 00391 { 00392 m_at.close(); 00393 m_atOpen = false; 00394 } 00395 00396 m_dongle.disconnect(); 00397 m_dongleConnected = false; 00398 00399 return OK; 00400 } 00401
Generated on Tue Jul 12 2022 13:16:06 by
1.7.2
