mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 /* UbloxUSBGSMModem.cpp */
elessair 0:f269e3021894 2 /* Copyright (C) 2012 mbed.org, MIT License
elessair 0:f269e3021894 3 *
elessair 0:f269e3021894 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
elessair 0:f269e3021894 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
elessair 0:f269e3021894 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
elessair 0:f269e3021894 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
elessair 0:f269e3021894 8 * furnished to do so, subject to the following conditions:
elessair 0:f269e3021894 9 *
elessair 0:f269e3021894 10 * The above copyright notice and this permission notice shall be included in all copies or
elessair 0:f269e3021894 11 * substantial portions of the Software.
elessair 0:f269e3021894 12 *
elessair 0:f269e3021894 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
elessair 0:f269e3021894 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
elessair 0:f269e3021894 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
elessair 0:f269e3021894 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
elessair 0:f269e3021894 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
elessair 0:f269e3021894 18 */
elessair 0:f269e3021894 19
elessair 0:f269e3021894 20 #define __DEBUG__ 3
elessair 0:f269e3021894 21 #ifndef __MODULE__
elessair 0:f269e3021894 22 #define __MODULE__ "UbloxUSBGSMModem.cpp"
elessair 0:f269e3021894 23 #endif
elessair 0:f269e3021894 24
elessair 0:f269e3021894 25 #include "core/fwk.h"
elessair 0:f269e3021894 26
elessair 0:f269e3021894 27 #include "UbloxUSBGSMModem.h"
elessair 0:f269e3021894 28 #include "UbloxGSMModemInitializer.h"
elessair 0:f269e3021894 29 #include "USBHost.h"
elessair 0:f269e3021894 30
elessair 0:f269e3021894 31 UbloxUSBGSMModem::UbloxUSBGSMModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/) :
elessair 0:f269e3021894 32 m_dongle(), // Construct WANDongle: USB interface with two serial channels to the modem (USBSerialStream objects)
elessair 0:f269e3021894 33 m_atStream(m_dongle.getSerial(1)), // AT commands are sent down one serial channel.
elessair 0:f269e3021894 34 m_pppStream(m_dongle.getSerial(0)), // PPP connections are managed via another serial channel.
elessair 0:f269e3021894 35 m_at(&m_atStream), // Construct ATCommandsInterface with the AT serial channel
elessair 0:f269e3021894 36 m_sms(&m_at), // Construct SMSInterface with the ATCommandsInterface
elessair 0:f269e3021894 37 m_ussd(&m_at), // Construct USSDInterface with the ATCommandsInterface
elessair 0:f269e3021894 38 m_linkMonitor(&m_at), // Construct LinkMonitor with the ATCommandsInterface
elessair 0:f269e3021894 39 m_ppp(&m_pppStream), // Construct PPPIPInterface with the PPP serial channel
elessair 0:f269e3021894 40 m_dongleConnected(false), // Dongle is initially not ready for anything
elessair 0:f269e3021894 41 m_ipInit(false), // PPIPInterface connection is initially down
elessair 0:f269e3021894 42 m_smsInit(false), // SMSInterface starts un-initialised
elessair 0:f269e3021894 43 m_ussdInit(false), // USSDInterface starts un-initialised
elessair 0:f269e3021894 44 m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised
elessair 0:f269e3021894 45 m_atOpen(false), // ATCommandsInterface starts in a closed state
elessair 0:f269e3021894 46 m_powerGatingPin(powerGatingPin), // set power gating pin
elessair 0:f269e3021894 47 m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) // set state semantics for power gating pin
elessair 0:f269e3021894 48 {
elessair 0:f269e3021894 49 USBHost* host = USBHost::getHostInst();
elessair 0:f269e3021894 50 m_dongle.addInitializer(new UbloxGSMModemInitializer(host));
elessair 0:f269e3021894 51 if( m_powerGatingPin != NC )
elessair 0:f269e3021894 52 {
elessair 0:f269e3021894 53 power(false); //Dongle will have to be powered on manually
elessair 0:f269e3021894 54 }
elessair 0:f269e3021894 55 }
elessair 0:f269e3021894 56
elessair 0:f269e3021894 57 class CREGProcessor : public IATCommandsProcessor
elessair 0:f269e3021894 58 {
elessair 0:f269e3021894 59 public:
elessair 0:f269e3021894 60 CREGProcessor() : status(STATUS_REGISTERING)
elessair 0:f269e3021894 61 {
elessair 0:f269e3021894 62
elessair 0:f269e3021894 63 }
elessair 0:f269e3021894 64 enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED };
elessair 0:f269e3021894 65 REGISTERING_STATUS getStatus()
elessair 0:f269e3021894 66 {
elessair 0:f269e3021894 67 return status;
elessair 0:f269e3021894 68 }
elessair 0:f269e3021894 69 private:
elessair 0:f269e3021894 70 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
elessair 0:f269e3021894 71 {
elessair 0:f269e3021894 72 int r;
elessair 0:f269e3021894 73 if( sscanf(line, "+CREG: %*d,%d", &r) == 1 )
elessair 0:f269e3021894 74 {
elessair 0:f269e3021894 75 switch(r)
elessair 0:f269e3021894 76 {
elessair 0:f269e3021894 77 case 1:
elessair 0:f269e3021894 78 case 5:
elessair 0:f269e3021894 79 status = STATUS_OK;
elessair 0:f269e3021894 80 break;
elessair 0:f269e3021894 81 case 0:
elessair 0:f269e3021894 82 case 2:
elessair 0:f269e3021894 83 status = STATUS_REGISTERING;
elessair 0:f269e3021894 84 break;
elessair 0:f269e3021894 85 case 3:
elessair 0:f269e3021894 86 default:
elessair 0:f269e3021894 87 status = STATUS_FAILED;
elessair 0:f269e3021894 88 break;
elessair 0:f269e3021894 89 }
elessair 0:f269e3021894 90 }
elessair 0:f269e3021894 91 return OK;
elessair 0:f269e3021894 92 }
elessair 0:f269e3021894 93 virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
elessair 0:f269e3021894 94 {
elessair 0:f269e3021894 95 return OK;
elessair 0:f269e3021894 96 }
elessair 0:f269e3021894 97 volatile REGISTERING_STATUS status;
elessair 0:f269e3021894 98 };
elessair 0:f269e3021894 99
elessair 0:f269e3021894 100 #if 0
elessair 0:f269e3021894 101 class COPSProcessor : public IATCommandsProcessor
elessair 0:f269e3021894 102 {
elessair 0:f269e3021894 103 public:
elessair 0:f269e3021894 104 COPSProcessor() : valid(false)
elessair 0:f269e3021894 105 {
elessair 0:f269e3021894 106 network[0] = '\0';
elessair 0:f269e3021894 107 apn[0] = '\0';
elessair 0:f269e3021894 108 bearer[0] = '\0';
elessair 0:f269e3021894 109 }
elessair 0:f269e3021894 110 char* getNetwork()
elessair 0:f269e3021894 111 {
elessair 0:f269e3021894 112 return network;
elessair 0:f269e3021894 113 }
elessair 0:f269e3021894 114 char* getAPN()
elessair 0:f269e3021894 115 {
elessair 0:f269e3021894 116 return apn;
elessair 0:f269e3021894 117 }
elessair 0:f269e3021894 118 char* getBearer()
elessair 0:f269e3021894 119 {
elessair 0:f269e3021894 120 return bearer;
elessair 0:f269e3021894 121 }
elessair 0:f269e3021894 122 bool isValid()
elessair 0:f269e3021894 123 {
elessair 0:f269e3021894 124 return valid;
elessair 0:f269e3021894 125 }
elessair 0:f269e3021894 126 private:
elessair 0:f269e3021894 127 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
elessair 0:f269e3021894 128 {
elessair 0:f269e3021894 129 int networkId;
elessair 0:f269e3021894 130 int bearerId;
elessair 0:f269e3021894 131 int s = sscanf(line, "+COPS: %*d,%*d,\"%d\",%d", &networkId, &bearerId);
elessair 0:f269e3021894 132 if( s == 2 )
elessair 0:f269e3021894 133 {
elessair 0:f269e3021894 134 switch(networkId)
elessair 0:f269e3021894 135 {
elessair 0:f269e3021894 136 case 23415:
elessair 0:f269e3021894 137 strcpy(network, "Vodafone UK");
elessair 0:f269e3021894 138 strcpy(apn, "pp.vodafone.co.uk");
elessair 0:f269e3021894 139 valid = true;
elessair 0:f269e3021894 140 break;
elessair 0:f269e3021894 141 case 20810:
elessair 0:f269e3021894 142 strcpy(network, "SFR FR");
elessair 0:f269e3021894 143 strcpy(apn, "websfr");
elessair 0:f269e3021894 144 valid = true;
elessair 0:f269e3021894 145 break;
elessair 0:f269e3021894 146 default:
elessair 0:f269e3021894 147 break;
elessair 0:f269e3021894 148 }
elessair 0:f269e3021894 149 }
elessair 0:f269e3021894 150 else
elessair 0:f269e3021894 151 {
elessair 0:f269e3021894 152 return OK;
elessair 0:f269e3021894 153 }
elessair 0:f269e3021894 154 switch(bearerId)
elessair 0:f269e3021894 155 {
elessair 0:f269e3021894 156 case 0: strcpy(bearer, "GSM"); break;
elessair 0:f269e3021894 157 case 1: strcpy(bearer, "GSM Compact"); break;
elessair 0:f269e3021894 158 case 2: strcpy(bearer, "UTRAN"); break;
elessair 0:f269e3021894 159 case 3: strcpy(bearer, "GSM w/EGPRS"); break;
elessair 0:f269e3021894 160 case 4: strcpy(bearer, "UTRAN w/HSDPA"); break;
elessair 0:f269e3021894 161 case 5: strcpy(bearer, "UTRAN w/HSUPA"); break;
elessair 0:f269e3021894 162 case 6: strcpy(bearer, "UTRAN w/HSDPA and HSUPA"); break;
elessair 0:f269e3021894 163 case 7: strcpy(bearer, "E-UTRAN"); break;
elessair 0:f269e3021894 164
elessair 0:f269e3021894 165 default:
elessair 0:f269e3021894 166 break;
elessair 0:f269e3021894 167 }
elessair 0:f269e3021894 168 return OK;
elessair 0:f269e3021894 169 }
elessair 0:f269e3021894 170 virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
elessair 0:f269e3021894 171 {
elessair 0:f269e3021894 172 return OK;
elessair 0:f269e3021894 173 }
elessair 0:f269e3021894 174 char network[24];
elessair 0:f269e3021894 175 char bearer[24];
elessair 0:f269e3021894 176 char apn[24];
elessair 0:f269e3021894 177 volatile bool valid;
elessair 0:f269e3021894 178 };
elessair 0:f269e3021894 179 #endif
elessair 0:f269e3021894 180
elessair 0:f269e3021894 181 int UbloxUSBGSMModem::connect(const char* apn, const char* user, const char* password)
elessair 0:f269e3021894 182 {
elessair 0:f269e3021894 183 if( !m_ipInit )
elessair 0:f269e3021894 184 {
elessair 0:f269e3021894 185 m_ipInit = true;
elessair 0:f269e3021894 186 m_ppp.init();
elessair 0:f269e3021894 187 }
elessair 0:f269e3021894 188 m_ppp.setup(user, password, DEFAULT_MSISDN_GSM);
elessair 0:f269e3021894 189
elessair 0:f269e3021894 190 int ret = init();
elessair 0:f269e3021894 191 if(ret)
elessair 0:f269e3021894 192 {
elessair 0:f269e3021894 193 return ret;
elessair 0:f269e3021894 194 }
elessair 0:f269e3021894 195
elessair 0:f269e3021894 196 #if USE_ONE_PORT
elessair 0:f269e3021894 197 m_smsInit = false; //SMS status reset
elessair 0:f269e3021894 198 m_ussdInit = false; //USSD status reset
elessair 0:f269e3021894 199 m_linkMonitorInit = false; //Link monitor status reset
elessair 0:f269e3021894 200 #endif
elessair 0:f269e3021894 201
elessair 0:f269e3021894 202 ATCommandsInterface::ATResult result;
elessair 0:f269e3021894 203
elessair 0:f269e3021894 204 #if 0
elessair 0:f269e3021894 205 //Get network info & select corresponding APN
elessair 0:f269e3021894 206 COPSProcessor copsProcessor;
elessair 0:f269e3021894 207 DBG("Get network info & select APN from DB");
elessair 0:f269e3021894 208 ret = m_at.execute("AT+COPS=,2;+COPS?", &copsProcessor, &result); //Configure to get operator's info in numeric code & get operator's id
elessair 0:f269e3021894 209 DBG("Result of command: Err code=%d", ret);
elessair 0:f269e3021894 210 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
elessair 0:f269e3021894 211
elessair 0:f269e3021894 212 if(!copsProcessor.isValid())
elessair 0:f269e3021894 213 {
elessair 0:f269e3021894 214 WARN("Connected to an unknown network, try to connect with default parameters");
elessair 0:f269e3021894 215 DBG("Connected with %s", copsProcessor.getBearer());
elessair 0:f269e3021894 216 }
elessair 0:f269e3021894 217 else
elessair 0:f269e3021894 218 {
elessair 0:f269e3021894 219 DBG("Connected to %s with %s", copsProcessor.getNetwork(), copsProcessor.getBearer());
elessair 0:f269e3021894 220 char cmd[48];
elessair 0:f269e3021894 221 int tries = 3;
elessair 0:f269e3021894 222 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", copsProcessor.getAPN());
elessair 0:f269e3021894 223 do //Try 3 times because for some reasons it can fail with the K3772-Z dongle
elessair 0:f269e3021894 224 {
elessair 0:f269e3021894 225 ret = m_at.executeSimple(cmd, &result);
elessair 0:f269e3021894 226 DBG("Result of command: Err code=%d", ret);
elessair 0:f269e3021894 227 } while(ret && --tries);
elessair 0:f269e3021894 228 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
elessair 0:f269e3021894 229 DBG("APN set to %s", copsProcessor.getAPN());
elessair 0:f269e3021894 230 }
elessair 0:f269e3021894 231 #else
elessair 0:f269e3021894 232 if(apn != NULL)
elessair 0:f269e3021894 233 {
elessair 0:f269e3021894 234 char cmd[48];
elessair 0:f269e3021894 235 int tries = 30;
elessair 0:f269e3021894 236 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
elessair 0:f269e3021894 237 do //Try 30 times because for some reasons it can fail *a lot* with the K3772-Z dongle
elessair 0:f269e3021894 238 {
elessair 0:f269e3021894 239 ret = m_at.executeSimple(cmd, &result);
elessair 0:f269e3021894 240 DBG("Result of command: Err code=%d", ret);
elessair 0:f269e3021894 241 if(ret)
elessair 0:f269e3021894 242 {
elessair 0:f269e3021894 243 Thread::wait(500);
elessair 0:f269e3021894 244 }
elessair 0:f269e3021894 245 } while(ret && --tries);
elessair 0:f269e3021894 246 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
elessair 0:f269e3021894 247 DBG("APN set to %s", apn);
elessair 0:f269e3021894 248 }
elessair 0:f269e3021894 249 #endif
elessair 0:f269e3021894 250
elessair 0:f269e3021894 251
elessair 0:f269e3021894 252 //Connect
elessair 0:f269e3021894 253 DBG("Connecting");
elessair 0:f269e3021894 254 #if 0
elessair 0:f269e3021894 255 ret = m_at.executeSimple("ATDT *99#", &result);
elessair 0:f269e3021894 256 DBG("Result of command: Err code=%d", ret);
elessair 0:f269e3021894 257 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
elessair 0:f269e3021894 258 #endif
elessair 0:f269e3021894 259 #if USE_ONE_PORT
elessair 0:f269e3021894 260 m_at.close(); // Closing AT parser
elessair 0:f269e3021894 261 m_atOpen = false; //Will need to be reinitialized afterwards
elessair 0:f269e3021894 262 #endif
elessair 0:f269e3021894 263
elessair 0:f269e3021894 264 #if 0
elessair 0:f269e3021894 265 DBG("AT Parser closed");
elessair 0:f269e3021894 266 if( (ret!=NET_MOREINFO) || (result.result != ATCommandsInterface::ATResult::AT_CONNECT))
elessair 0:f269e3021894 267 {
elessair 0:f269e3021894 268 ERR("Could not connect");
elessair 0:f269e3021894 269 return ret; //Could not connect
elessair 0:f269e3021894 270 }
elessair 0:f269e3021894 271 #endif
elessair 0:f269e3021894 272 DBG("Connecting PPP");
elessair 0:f269e3021894 273
elessair 0:f269e3021894 274 ret = m_ppp.connect();
elessair 0:f269e3021894 275 DBG("Result of connect: Err code=%d", ret);
elessair 0:f269e3021894 276 return ret;
elessair 0:f269e3021894 277 }
elessair 0:f269e3021894 278
elessair 0:f269e3021894 279
elessair 0:f269e3021894 280 int UbloxUSBGSMModem::disconnect()
elessair 0:f269e3021894 281 {
elessair 0:f269e3021894 282 DBG("Disconnecting from PPP");
elessair 0:f269e3021894 283 int ret = m_ppp.disconnect();
elessair 0:f269e3021894 284 if(ret)
elessair 0:f269e3021894 285 {
elessair 0:f269e3021894 286 ERR("Disconnect returned %d, still trying to disconnect", ret);
elessair 0:f269e3021894 287 }
elessair 0:f269e3021894 288
elessair 0:f269e3021894 289 //Ugly but leave dongle time to recover
elessair 0:f269e3021894 290 Thread::wait(500);
elessair 0:f269e3021894 291
elessair 0:f269e3021894 292 #if USE_ONE_PORT
elessair 0:f269e3021894 293 ATCommandsInterface::ATResult result;
elessair 0:f269e3021894 294 DBG("Starting AT thread");
elessair 0:f269e3021894 295 ret = m_at.open();
elessair 0:f269e3021894 296 if(ret)
elessair 0:f269e3021894 297 {
elessair 0:f269e3021894 298 return ret;
elessair 0:f269e3021894 299 }
elessair 0:f269e3021894 300 #endif
elessair 0:f269e3021894 301
elessair 0:f269e3021894 302 DBG("Trying to hangup");
elessair 0:f269e3021894 303
elessair 0:f269e3021894 304 #if 0 //Does not appear to work
elessair 0:f269e3021894 305 int tries = 10;
elessair 0:f269e3021894 306 do
elessair 0:f269e3021894 307 {
elessair 0:f269e3021894 308 ret = m_at.executeSimple("+++", &result, 1000);
elessair 0:f269e3021894 309 DBG("Result of command: Err code=%d\n", ret);
elessair 0:f269e3021894 310 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
elessair 0:f269e3021894 311 } while(tries-- && ret);
elessair 0:f269e3021894 312 if(!ret)
elessair 0:f269e3021894 313 {
elessair 0:f269e3021894 314 ret = m_at.executeSimple("ATH", &result);
elessair 0:f269e3021894 315 DBG("Result of command: Err code=%d\n", ret);
elessair 0:f269e3021894 316 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
elessair 0:f269e3021894 317 }
elessair 0:f269e3021894 318 #endif
elessair 0:f269e3021894 319
elessair 0:f269e3021894 320 #if USE_ONE_PORT
elessair 0:f269e3021894 321 //Reinit AT parser
elessair 0:f269e3021894 322 ret = m_at.init();
elessair 0:f269e3021894 323 DBG("Result of command: Err code=%d\n", ret);
elessair 0:f269e3021894 324 if(ret)
elessair 0:f269e3021894 325 {
elessair 0:f269e3021894 326 m_at.close(); // Closing AT parser
elessair 0:f269e3021894 327 DBG("AT Parser closed, could not complete disconnection");
elessair 0:f269e3021894 328 return NET_TIMEOUT;
elessair 0:f269e3021894 329 }
elessair 0:f269e3021894 330
elessair 0:f269e3021894 331 #if 0
elessair 0:f269e3021894 332 m_at.close(); // Closing AT parser
elessair 0:f269e3021894 333 DBG("AT Parser closed");
elessair 0:f269e3021894 334 #endif
elessair 0:f269e3021894 335 #endif
elessair 0:f269e3021894 336 return OK;
elessair 0:f269e3021894 337 }
elessair 0:f269e3021894 338
elessair 0:f269e3021894 339 int UbloxUSBGSMModem::sendSM(const char* number, const char* message)
elessair 0:f269e3021894 340 {
elessair 0:f269e3021894 341 int ret = init();
elessair 0:f269e3021894 342 if(ret)
elessair 0:f269e3021894 343 {
elessair 0:f269e3021894 344 return ret;
elessair 0:f269e3021894 345 }
elessair 0:f269e3021894 346
elessair 0:f269e3021894 347 if(!m_smsInit)
elessair 0:f269e3021894 348 {
elessair 0:f269e3021894 349 ret = m_sms.init();
elessair 0:f269e3021894 350 if(ret)
elessair 0:f269e3021894 351 {
elessair 0:f269e3021894 352 return ret;
elessair 0:f269e3021894 353 }
elessair 0:f269e3021894 354 m_smsInit = true;
elessair 0:f269e3021894 355 }
elessair 0:f269e3021894 356
elessair 0:f269e3021894 357 ret = m_sms.send(number, message);
elessair 0:f269e3021894 358 if(ret)
elessair 0:f269e3021894 359 {
elessair 0:f269e3021894 360 return ret;
elessair 0:f269e3021894 361 }
elessair 0:f269e3021894 362
elessair 0:f269e3021894 363 return OK;
elessair 0:f269e3021894 364 }
elessair 0:f269e3021894 365
elessair 0:f269e3021894 366 int UbloxUSBGSMModem::getSM(char* number, char* message, size_t maxLength)
elessair 0:f269e3021894 367 {
elessair 0:f269e3021894 368 int ret = init();
elessair 0:f269e3021894 369 if(ret)
elessair 0:f269e3021894 370 {
elessair 0:f269e3021894 371 return ret;
elessair 0:f269e3021894 372 }
elessair 0:f269e3021894 373
elessair 0:f269e3021894 374 if(!m_smsInit)
elessair 0:f269e3021894 375 {
elessair 0:f269e3021894 376 ret = m_sms.init();
elessair 0:f269e3021894 377 if(ret)
elessair 0:f269e3021894 378 {
elessair 0:f269e3021894 379 return ret;
elessair 0:f269e3021894 380 }
elessair 0:f269e3021894 381 m_smsInit = true;
elessair 0:f269e3021894 382 }
elessair 0:f269e3021894 383
elessair 0:f269e3021894 384 ret = m_sms.get(number, message, maxLength);
elessair 0:f269e3021894 385 if(ret)
elessair 0:f269e3021894 386 {
elessair 0:f269e3021894 387 return ret;
elessair 0:f269e3021894 388 }
elessair 0:f269e3021894 389
elessair 0:f269e3021894 390 return OK;
elessair 0:f269e3021894 391 }
elessair 0:f269e3021894 392
elessair 0:f269e3021894 393 int UbloxUSBGSMModem::getSMCount(size_t* pCount)
elessair 0:f269e3021894 394 {
elessair 0:f269e3021894 395 int ret = init();
elessair 0:f269e3021894 396 if(ret)
elessair 0:f269e3021894 397 {
elessair 0:f269e3021894 398 return ret;
elessair 0:f269e3021894 399 }
elessair 0:f269e3021894 400
elessair 0:f269e3021894 401 if(!m_smsInit)
elessair 0:f269e3021894 402 {
elessair 0:f269e3021894 403 ret = m_sms.init();
elessair 0:f269e3021894 404 if(ret)
elessair 0:f269e3021894 405 {
elessair 0:f269e3021894 406 return ret;
elessair 0:f269e3021894 407 }
elessair 0:f269e3021894 408 m_smsInit = true;
elessair 0:f269e3021894 409 }
elessair 0:f269e3021894 410
elessair 0:f269e3021894 411 ret = m_sms.getCount(pCount);
elessair 0:f269e3021894 412 if(ret)
elessair 0:f269e3021894 413 {
elessair 0:f269e3021894 414 return ret;
elessair 0:f269e3021894 415 }
elessair 0:f269e3021894 416
elessair 0:f269e3021894 417 return OK;
elessair 0:f269e3021894 418 }
elessair 0:f269e3021894 419
elessair 0:f269e3021894 420 int UbloxUSBGSMModem::sendUSSD(const char* command, char* result, size_t maxLength)
elessair 0:f269e3021894 421 {
elessair 0:f269e3021894 422 int ret = init();
elessair 0:f269e3021894 423 if(ret)
elessair 0:f269e3021894 424 {
elessair 0:f269e3021894 425 return ret;
elessair 0:f269e3021894 426 }
elessair 0:f269e3021894 427
elessair 0:f269e3021894 428 if(!m_ussdInit)
elessair 0:f269e3021894 429 {
elessair 0:f269e3021894 430 ret = m_ussd.init();
elessair 0:f269e3021894 431 if(ret)
elessair 0:f269e3021894 432 {
elessair 0:f269e3021894 433 return ret;
elessair 0:f269e3021894 434 }
elessair 0:f269e3021894 435 m_ussdInit = true;
elessair 0:f269e3021894 436 }
elessair 0:f269e3021894 437
elessair 0:f269e3021894 438 ret = m_ussd.send(command, result, maxLength);
elessair 0:f269e3021894 439 if(ret)
elessair 0:f269e3021894 440 {
elessair 0:f269e3021894 441 return ret;
elessair 0:f269e3021894 442 }
elessair 0:f269e3021894 443
elessair 0:f269e3021894 444 return OK;
elessair 0:f269e3021894 445 }
elessair 0:f269e3021894 446
elessair 0:f269e3021894 447 int UbloxUSBGSMModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer)
elessair 0:f269e3021894 448 {
elessair 0:f269e3021894 449 int ret = init();
elessair 0:f269e3021894 450 if(ret)
elessair 0:f269e3021894 451 {
elessair 0:f269e3021894 452 return ret;
elessair 0:f269e3021894 453 }
elessair 0:f269e3021894 454
elessair 0:f269e3021894 455 if(!m_linkMonitorInit)
elessair 0:f269e3021894 456 {
elessair 0:f269e3021894 457 ret = m_linkMonitor.init();
elessair 0:f269e3021894 458 if(ret)
elessair 0:f269e3021894 459 {
elessair 0:f269e3021894 460 return ret;
elessair 0:f269e3021894 461 }
elessair 0:f269e3021894 462 m_linkMonitorInit = true;
elessair 0:f269e3021894 463 }
elessair 0:f269e3021894 464
elessair 0:f269e3021894 465 ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer);
elessair 0:f269e3021894 466 if(ret)
elessair 0:f269e3021894 467 {
elessair 0:f269e3021894 468 return ret;
elessair 0:f269e3021894 469 }
elessair 0:f269e3021894 470
elessair 0:f269e3021894 471 return OK;
elessair 0:f269e3021894 472 }
elessair 0:f269e3021894 473
elessair 0:f269e3021894 474
elessair 0:f269e3021894 475 ATCommandsInterface* UbloxUSBGSMModem::getATCommandsInterface()
elessair 0:f269e3021894 476 {
elessair 0:f269e3021894 477 return &m_at;
elessair 0:f269e3021894 478 }
elessair 0:f269e3021894 479
elessair 0:f269e3021894 480 int UbloxUSBGSMModem::power(bool enable)
elessair 0:f269e3021894 481 {
elessair 0:f269e3021894 482 if( m_powerGatingPin == NC )
elessair 0:f269e3021894 483 {
elessair 0:f269e3021894 484 return NET_INVALID; //A pin name has not been provided in the constructor
elessair 0:f269e3021894 485 }
elessair 0:f269e3021894 486
elessair 0:f269e3021894 487 if(!enable) //Will force components to re-init
elessair 0:f269e3021894 488 {
elessair 0:f269e3021894 489 cleanup();
elessair 0:f269e3021894 490 }
elessair 0:f269e3021894 491
elessair 0:f269e3021894 492 DigitalOut powerGatingOut(m_powerGatingPin);
elessair 0:f269e3021894 493 powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable;
elessair 0:f269e3021894 494
elessair 0:f269e3021894 495 return OK;
elessair 0:f269e3021894 496 }
elessair 0:f269e3021894 497
elessair 0:f269e3021894 498 bool UbloxUSBGSMModem::power()
elessair 0:f269e3021894 499 {
elessair 0:f269e3021894 500 if( m_powerGatingPin == NC )
elessair 0:f269e3021894 501 {
elessair 0:f269e3021894 502 return true; //Assume power is always on
elessair 0:f269e3021894 503 }
elessair 0:f269e3021894 504
elessair 0:f269e3021894 505 DigitalOut powerGatingOut(m_powerGatingPin);
elessair 0:f269e3021894 506 return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut;
elessair 0:f269e3021894 507 }
elessair 0:f269e3021894 508
elessair 0:f269e3021894 509 int UbloxUSBGSMModem::init()
elessair 0:f269e3021894 510 {
elessair 0:f269e3021894 511 if( !m_dongleConnected )
elessair 0:f269e3021894 512 {
elessair 0:f269e3021894 513 if(!power())
elessair 0:f269e3021894 514 {
elessair 0:f269e3021894 515 //Obviously cannot initialize the dongle if it is disconnected...
elessair 0:f269e3021894 516 ERR("Power is off");
elessair 0:f269e3021894 517 return NET_INVALID;
elessair 0:f269e3021894 518 }
elessair 0:f269e3021894 519 m_dongleConnected = true;
elessair 0:f269e3021894 520 while( !m_dongle.connected() )
elessair 0:f269e3021894 521 {
elessair 0:f269e3021894 522 m_dongle.tryConnect();
elessair 0:f269e3021894 523 Thread::wait(10);
elessair 0:f269e3021894 524 }
elessair 0:f269e3021894 525 }
elessair 0:f269e3021894 526
elessair 0:f269e3021894 527 if(m_atOpen)
elessair 0:f269e3021894 528 {
elessair 0:f269e3021894 529 return OK;
elessair 0:f269e3021894 530 }
elessair 0:f269e3021894 531
elessair 0:f269e3021894 532 DBG("Starting AT thread if needed");
elessair 0:f269e3021894 533 int ret = m_at.open();
elessair 0:f269e3021894 534 if(ret)
elessair 0:f269e3021894 535 {
elessair 0:f269e3021894 536 return ret;
elessair 0:f269e3021894 537 }
elessair 0:f269e3021894 538
elessair 0:f269e3021894 539 DBG("Sending initialisation commands");
elessair 0:f269e3021894 540 ret = m_at.init();
elessair 0:f269e3021894 541 if(ret)
elessair 0:f269e3021894 542 {
elessair 0:f269e3021894 543 return ret;
elessair 0:f269e3021894 544 }
elessair 0:f269e3021894 545
elessair 0:f269e3021894 546 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200)
elessair 0:f269e3021894 547 {
elessair 0:f269e3021894 548 INFO("Using a u-blox LISA-U");
elessair 0:f269e3021894 549 }
elessair 0:f269e3021894 550 else
elessair 0:f269e3021894 551 {
elessair 0:f269e3021894 552 WARN("Using an Unknown Dongle");
elessair 0:f269e3021894 553 }
elessair 0:f269e3021894 554
elessair 0:f269e3021894 555 ATCommandsInterface::ATResult result;
elessair 0:f269e3021894 556
elessair 0:f269e3021894 557 //Wait for network registration
elessair 0:f269e3021894 558 CREGProcessor cregProcessor;
elessair 0:f269e3021894 559 do
elessair 0:f269e3021894 560 {
elessair 0:f269e3021894 561 DBG("Waiting for network registration");
elessair 0:f269e3021894 562 ret = m_at.execute("AT+CREG?", &cregProcessor, &result);
elessair 0:f269e3021894 563 DBG("Result of command: Err code=%d\n", ret);
elessair 0:f269e3021894 564 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
elessair 0:f269e3021894 565 if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING)
elessair 0:f269e3021894 566 {
elessair 0:f269e3021894 567 Thread::wait(3000);
elessair 0:f269e3021894 568 }
elessair 0:f269e3021894 569 } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
elessair 0:f269e3021894 570 if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED)
elessair 0:f269e3021894 571 {
elessair 0:f269e3021894 572 ERR("Registration denied");
elessair 0:f269e3021894 573 return NET_AUTH;
elessair 0:f269e3021894 574 }
elessair 0:f269e3021894 575
elessair 0:f269e3021894 576 m_atOpen = true;
elessair 0:f269e3021894 577
elessair 0:f269e3021894 578 return OK;
elessair 0:f269e3021894 579 }
elessair 0:f269e3021894 580
elessair 0:f269e3021894 581 int UbloxUSBGSMModem::cleanup()
elessair 0:f269e3021894 582 {
elessair 0:f269e3021894 583 if(m_ppp.isConnected())
elessair 0:f269e3021894 584 {
elessair 0:f269e3021894 585 WARN("Data connection is still open"); //Try to encourage good behaviour from the user
elessair 0:f269e3021894 586 m_ppp.disconnect();
elessair 0:f269e3021894 587 }
elessair 0:f269e3021894 588
elessair 0:f269e3021894 589 m_smsInit = false;
elessair 0:f269e3021894 590 m_ussdInit = false;
elessair 0:f269e3021894 591 m_linkMonitorInit = false;
elessair 0:f269e3021894 592 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once
elessair 0:f269e3021894 593
elessair 0:f269e3021894 594 if(m_atOpen)
elessair 0:f269e3021894 595 {
elessair 0:f269e3021894 596 m_at.close();
elessair 0:f269e3021894 597 m_atOpen = false;
elessair 0:f269e3021894 598 }
elessair 0:f269e3021894 599
elessair 0:f269e3021894 600 m_dongle.disconnect();
elessair 0:f269e3021894 601 m_dongleConnected = false;
elessair 0:f269e3021894 602
elessair 0:f269e3021894 603 return OK;
elessair 0:f269e3021894 604 }
elessair 0:f269e3021894 605