Vodafone K3770/K3772-Z modems driver & networking library

Dependencies:   Socket USBHostWANDongle lwip-sys lwip

Dependents:   VodafoneUSBModemHTTPClientTest VodafoneUSBModemNTPClientTest VodafoneUSBModemSMSTest VodafoneUSBModemUSSDTest ... more

Fork of VodafoneUSBModem_bleedingedge by Donatien Garnier

This is the driver for the Vodafone K3700 & K3772-Z Dongles:

K3770

More details and instructions can be found here.

Committer:
ashleymills
Date:
Fri Sep 20 10:40:58 2013 +0000
Revision:
91:7b311719374d
Parent:
88:51dc1f37cc9a
Child:
92:ed0443728c60
Added support for Ublox LISA U200 module. Fixed bug for modules that throw away blocked unsolicited messages.

Who changed what in which revision?

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