modified u-blox modem driver

Dependencies:   CellularUSBModem

Fork of UbloxUSBModem by mbed official

Committer:
mbed_official
Date:
Tue Mar 04 13:51:49 2014 +0000
Revision:
11:71550cccbe73
Parent:
5:60b48a013e86
Use latest version of CellularUSBModem

Who changed what in which revision?

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