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:
Tue Jan 15 17:24:37 2013 +0000
Revision:
80:c0e63c16306e
Parent:
79:a6ac8206a58d
Child:
81:da03da068398
Turn of read receipts in MU509;

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 77:6083cb11f170 20 #define __DEBUG__ 4
donatien 8:04b6a042595f 21 #ifndef __MODULE__
donatien 22:06fb2a93a1f6 22 #define __MODULE__ "VodafoneUSBModem.cpp"
donatien 8:04b6a042595f 23 #endif
donatien 8:04b6a042595f 24
donatien 8:04b6a042595f 25 #include "core/fwk.h"
donatien 8:04b6a042595f 26
donatien 22:06fb2a93a1f6 27 #include "VodafoneUSBModem.h"
donatien 8:04b6a042595f 28
ashleymills 41:8bec5a8ea878 29 VodafoneUSBModem::VodafoneUSBModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/) :
ashleymills 41:8bec5a8ea878 30 m_dongle(), // Construct WANDongle: USB interface with two serial channels to the modem (USBSerialStream objects)
ashleymills 41:8bec5a8ea878 31 m_atStream(m_dongle.getSerial(1)), // AT commands are sent down one serial channel.
ashleymills 41:8bec5a8ea878 32 m_pppStream(m_dongle.getSerial(0)), // PPP connections are managed via another serial channel.
ashleymills 41:8bec5a8ea878 33 m_at(&m_atStream), // Construct ATCommandsInterface with the AT serial channel
ashleymills 41:8bec5a8ea878 34 m_sms(&m_at), // Construct SMSInterface with the ATCommandsInterface
ashleymills 41:8bec5a8ea878 35 m_ussd(&m_at), // Construct USSDInterface with the ATCommandsInterface
ashleymills 41:8bec5a8ea878 36 m_linkMonitor(&m_at), // Construct LinkMonitor with the ATCommandsInterface
ashleymills 79:a6ac8206a58d 37 m_ppp(&m_pppStream,&m_atStream,&m_at,false), // Construct PPPIPInterface with the PPP serial channel
ashleymills 41:8bec5a8ea878 38 m_dongleConnected(false), // Dongle is initially not ready for anything
ashleymills 41:8bec5a8ea878 39 m_ipInit(false), // PPIPInterface connection is initially down
ashleymills 41:8bec5a8ea878 40 m_smsInit(false), // SMSInterface starts un-initialised
ashleymills 41:8bec5a8ea878 41 m_ussdInit(false), // USSDInterface starts un-initialised
ashleymills 41:8bec5a8ea878 42 m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised
ashleymills 41:8bec5a8ea878 43 m_atOpen(false), // ATCommandsInterface starts in a closed state
ashleymills 41:8bec5a8ea878 44 m_powerGatingPin(powerGatingPin), // set power gating pin
ashleymills 41:8bec5a8ea878 45 m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh) // set state semantics for power gating pin
donatien 8:04b6a042595f 46 {
donatien 26:d37501dc6c61 47 if( m_powerGatingPin != NC )
donatien 26:d37501dc6c61 48 {
donatien 26:d37501dc6c61 49 power(false); //Dongle will have to be powered on manually
donatien 26:d37501dc6c61 50 }
donatien 8:04b6a042595f 51 }
donatien 8:04b6a042595f 52
donatien 8:04b6a042595f 53 class CREGProcessor : public IATCommandsProcessor
donatien 8:04b6a042595f 54 {
donatien 8:04b6a042595f 55 public:
donatien 8:04b6a042595f 56 CREGProcessor() : status(STATUS_REGISTERING)
donatien 8:04b6a042595f 57 {
donatien 8:04b6a042595f 58
donatien 8:04b6a042595f 59 }
donatien 8:04b6a042595f 60 enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED };
donatien 8:04b6a042595f 61 REGISTERING_STATUS getStatus()
donatien 8:04b6a042595f 62 {
donatien 8:04b6a042595f 63 return status;
donatien 8:04b6a042595f 64 }
donatien 8:04b6a042595f 65 private:
donatien 8:04b6a042595f 66 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
donatien 8:04b6a042595f 67 {
donatien 8:04b6a042595f 68 int r;
donatien 8:04b6a042595f 69 if( sscanf(line, "+CREG: %*d,%d", &r) == 1 )
donatien 8:04b6a042595f 70 {
donatien 8:04b6a042595f 71 switch(r)
donatien 8:04b6a042595f 72 {
donatien 8:04b6a042595f 73 case 1:
donatien 8:04b6a042595f 74 case 5:
donatien 8:04b6a042595f 75 status = STATUS_OK;
donatien 8:04b6a042595f 76 break;
donatien 8:04b6a042595f 77 case 0:
donatien 8:04b6a042595f 78 case 2:
donatien 8:04b6a042595f 79 status = STATUS_REGISTERING;
donatien 8:04b6a042595f 80 break;
donatien 8:04b6a042595f 81 case 3:
donatien 8:04b6a042595f 82 default:
donatien 8:04b6a042595f 83 status = STATUS_FAILED;
donatien 8:04b6a042595f 84 break;
donatien 8:04b6a042595f 85 }
donatien 8:04b6a042595f 86 }
donatien 8:04b6a042595f 87 return OK;
donatien 8:04b6a042595f 88 }
donatien 8:04b6a042595f 89 virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
donatien 8:04b6a042595f 90 {
donatien 8:04b6a042595f 91 return OK;
donatien 8:04b6a042595f 92 }
donatien 8:04b6a042595f 93 volatile REGISTERING_STATUS status;
donatien 8:04b6a042595f 94 };
donatien 8:04b6a042595f 95
donatien 12:66dc2c8eba2d 96 #if 0
donatien 8:04b6a042595f 97 class COPSProcessor : public IATCommandsProcessor
donatien 8:04b6a042595f 98 {
donatien 8:04b6a042595f 99 public:
donatien 8:04b6a042595f 100 COPSProcessor() : valid(false)
donatien 8:04b6a042595f 101 {
donatien 8:04b6a042595f 102 network[0] = '\0';
donatien 8:04b6a042595f 103 apn[0] = '\0';
donatien 8:04b6a042595f 104 bearer[0] = '\0';
donatien 8:04b6a042595f 105 }
donatien 8:04b6a042595f 106 char* getNetwork()
donatien 8:04b6a042595f 107 {
donatien 8:04b6a042595f 108 return network;
donatien 8:04b6a042595f 109 }
donatien 8:04b6a042595f 110 char* getAPN()
donatien 8:04b6a042595f 111 {
donatien 8:04b6a042595f 112 return apn;
donatien 8:04b6a042595f 113 }
donatien 8:04b6a042595f 114 char* getBearer()
donatien 8:04b6a042595f 115 {
donatien 8:04b6a042595f 116 return bearer;
donatien 8:04b6a042595f 117 }
donatien 8:04b6a042595f 118 bool isValid()
donatien 8:04b6a042595f 119 {
donatien 8:04b6a042595f 120 return valid;
donatien 8:04b6a042595f 121 }
donatien 8:04b6a042595f 122 private:
donatien 8:04b6a042595f 123 virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
donatien 8:04b6a042595f 124 {
donatien 8:04b6a042595f 125 int networkId;
donatien 8:04b6a042595f 126 int bearerId;
donatien 8:04b6a042595f 127 int s = sscanf(line, "+COPS: %*d,%*d,\"%d\",%d", &networkId, &bearerId);
donatien 8:04b6a042595f 128 if( s == 2 )
donatien 8:04b6a042595f 129 {
donatien 8:04b6a042595f 130 switch(networkId)
donatien 8:04b6a042595f 131 {
donatien 8:04b6a042595f 132 case 23415:
donatien 8:04b6a042595f 133 strcpy(network, "Vodafone UK");
donatien 8:04b6a042595f 134 strcpy(apn, "pp.vodafone.co.uk");
donatien 8:04b6a042595f 135 valid = true;
donatien 8:04b6a042595f 136 break;
donatien 8:04b6a042595f 137 case 20810:
donatien 8:04b6a042595f 138 strcpy(network, "SFR FR");
donatien 8:04b6a042595f 139 strcpy(apn, "websfr");
donatien 8:04b6a042595f 140 valid = true;
donatien 8:04b6a042595f 141 break;
donatien 8:04b6a042595f 142 default:
donatien 8:04b6a042595f 143 break;
donatien 8:04b6a042595f 144 }
donatien 8:04b6a042595f 145 }
donatien 8:04b6a042595f 146 else
donatien 8:04b6a042595f 147 {
donatien 8:04b6a042595f 148 return OK;
donatien 8:04b6a042595f 149 }
donatien 8:04b6a042595f 150 switch(bearerId)
donatien 8:04b6a042595f 151 {
donatien 8:04b6a042595f 152 case 0: strcpy(bearer, "GSM"); break;
donatien 8:04b6a042595f 153 case 1: strcpy(bearer, "GSM Compact"); break;
donatien 8:04b6a042595f 154 case 2: strcpy(bearer, "UTRAN"); break;
donatien 8:04b6a042595f 155 case 3: strcpy(bearer, "GSM w/EGPRS"); break;
donatien 8:04b6a042595f 156 case 4: strcpy(bearer, "UTRAN w/HSDPA"); break;
donatien 8:04b6a042595f 157 case 5: strcpy(bearer, "UTRAN w/HSUPA"); break;
donatien 8:04b6a042595f 158 case 6: strcpy(bearer, "UTRAN w/HSDPA and HSUPA"); break;
donatien 8:04b6a042595f 159 case 7: strcpy(bearer, "E-UTRAN"); break;
donatien 8:04b6a042595f 160
donatien 8:04b6a042595f 161 default:
donatien 8:04b6a042595f 162 break;
donatien 8:04b6a042595f 163 }
donatien 8:04b6a042595f 164 return OK;
donatien 8:04b6a042595f 165 }
donatien 8:04b6a042595f 166 virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
donatien 8:04b6a042595f 167 {
donatien 8:04b6a042595f 168 return OK;
donatien 8:04b6a042595f 169 }
donatien 8:04b6a042595f 170 char network[24];
donatien 8:04b6a042595f 171 char bearer[24];
donatien 8:04b6a042595f 172 char apn[24];
donatien 8:04b6a042595f 173 volatile bool valid;
donatien 8:04b6a042595f 174 };
donatien 12:66dc2c8eba2d 175 #endif
donatien 8:04b6a042595f 176
donatien 22:06fb2a93a1f6 177 int VodafoneUSBModem::connect(const char* apn, const char* user, const char* password)
donatien 8:04b6a042595f 178 {
donatien 8:04b6a042595f 179 if( !m_ipInit )
donatien 8:04b6a042595f 180 {
donatien 8:04b6a042595f 181 m_ipInit = true;
donatien 8:04b6a042595f 182 m_ppp.init();
donatien 8:04b6a042595f 183 }
donatien 8:04b6a042595f 184 m_ppp.setup(user, password);
donatien 8:04b6a042595f 185
donatien 8:04b6a042595f 186 int ret = init();
donatien 8:04b6a042595f 187 if(ret)
donatien 8:04b6a042595f 188 {
donatien 8:04b6a042595f 189 return ret;
donatien 8:04b6a042595f 190 }
donatien 8:04b6a042595f 191
donatien 9:3f077dde13c9 192 #if USE_ONE_PORT
donatien 8:04b6a042595f 193 m_smsInit = false; //SMS status reset
donatien 8:04b6a042595f 194 m_ussdInit = false; //USSD status reset
donatien 12:66dc2c8eba2d 195 m_linkMonitorInit = false; //Link monitor status reset
donatien 9:3f077dde13c9 196 #endif
donatien 8:04b6a042595f 197
donatien 8:04b6a042595f 198 ATCommandsInterface::ATResult result;
donatien 8:04b6a042595f 199
donatien 9:3f077dde13c9 200 #if 0
donatien 8:04b6a042595f 201 //Get network info & select corresponding APN
donatien 8:04b6a042595f 202 COPSProcessor copsProcessor;
donatien 8:04b6a042595f 203 DBG("Get network info & select APN from DB");
donatien 8:04b6a042595f 204 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 205 DBG("Result of command: Err code=%d", ret);
donatien 8:04b6a042595f 206 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
donatien 8:04b6a042595f 207
donatien 8:04b6a042595f 208 if(!copsProcessor.isValid())
donatien 8:04b6a042595f 209 {
donatien 8:04b6a042595f 210 WARN("Connected to an unknown network, try to connect with default parameters");
donatien 8:04b6a042595f 211 DBG("Connected with %s", copsProcessor.getBearer());
donatien 8:04b6a042595f 212 }
donatien 8:04b6a042595f 213 else
donatien 8:04b6a042595f 214 {
donatien 8:04b6a042595f 215 DBG("Connected to %s with %s", copsProcessor.getNetwork(), copsProcessor.getBearer());
donatien 8:04b6a042595f 216 char cmd[48];
donatien 61:0bcb8c5216d4 217 int tries = 3;
donatien 8:04b6a042595f 218 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", copsProcessor.getAPN());
donatien 61:0bcb8c5216d4 219 do //Try 3 times because for some reasons it can fail with the K3772-Z dongle
donatien 61:0bcb8c5216d4 220 {
donatien 61:0bcb8c5216d4 221 ret = m_at.executeSimple(cmd, &result);
donatien 61:0bcb8c5216d4 222 DBG("Result of command: Err code=%d", ret);
donatien 61:0bcb8c5216d4 223 } while(ret && --tries);
donatien 8:04b6a042595f 224 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
donatien 8:04b6a042595f 225 DBG("APN set to %s", copsProcessor.getAPN());
donatien 8:04b6a042595f 226 }
donatien 8:04b6a042595f 227 #else
donatien 8:04b6a042595f 228 if(apn != NULL)
donatien 8:04b6a042595f 229 {
donatien 8:04b6a042595f 230 char cmd[48];
donatien 61:0bcb8c5216d4 231 int tries = 30;
donatien 8:04b6a042595f 232 sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
donatien 61:0bcb8c5216d4 233 do //Try 30 times because for some reasons it can fail *a lot* with the K3772-Z dongle
donatien 61:0bcb8c5216d4 234 {
donatien 61:0bcb8c5216d4 235 ret = m_at.executeSimple(cmd, &result);
donatien 61:0bcb8c5216d4 236 DBG("Result of command: Err code=%d", ret);
donatien 61:0bcb8c5216d4 237 if(ret)
donatien 61:0bcb8c5216d4 238 {
donatien 61:0bcb8c5216d4 239 Thread::wait(500);
donatien 61:0bcb8c5216d4 240 }
donatien 61:0bcb8c5216d4 241 } while(ret && --tries);
donatien 8:04b6a042595f 242 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
donatien 8:04b6a042595f 243 DBG("APN set to %s", apn);
donatien 8:04b6a042595f 244 }
donatien 8:04b6a042595f 245 #endif
donatien 8:04b6a042595f 246
donatien 8:04b6a042595f 247
donatien 8:04b6a042595f 248 //Connect
donatien 8:04b6a042595f 249 DBG("Connecting");
donatien 9:3f077dde13c9 250 #if 0
donatien 8:04b6a042595f 251 ret = m_at.executeSimple("ATDT *99#", &result);
donatien 8:04b6a042595f 252 DBG("Result of command: Err code=%d", ret);
donatien 8:04b6a042595f 253 DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
donatien 9:3f077dde13c9 254 #endif
donatien 9:3f077dde13c9 255 #if USE_ONE_PORT
donatien 8:04b6a042595f 256 m_at.close(); // Closing AT parser
donatien 8:04b6a042595f 257 m_atOpen = false; //Will need to be reinitialized afterwards
donatien 9:3f077dde13c9 258 #endif
donatien 8:04b6a042595f 259
donatien 9:3f077dde13c9 260 #if 0
donatien 8:04b6a042595f 261 DBG("AT Parser closed");
donatien 8:04b6a042595f 262 if( (ret!=NET_MOREINFO) || (result.result != ATCommandsInterface::ATResult::AT_CONNECT))
donatien 8:04b6a042595f 263 {
donatien 8:04b6a042595f 264 ERR("Could not connect");
donatien 8:04b6a042595f 265 return ret; //Could not connect
donatien 8:04b6a042595f 266 }
donatien 9:3f077dde13c9 267 #endif
donatien 8:04b6a042595f 268 DBG("Connecting PPP");
donatien 8:04b6a042595f 269
donatien 12:66dc2c8eba2d 270 ret = m_ppp.connect();
donatien 8:04b6a042595f 271 DBG("Result of connect: Err code=%d", ret);
donatien 8:04b6a042595f 272 return ret;
donatien 8:04b6a042595f 273 }
donatien 8:04b6a042595f 274
donatien 8:04b6a042595f 275
donatien 22:06fb2a93a1f6 276 int VodafoneUSBModem::disconnect()
donatien 8:04b6a042595f 277 {
donatien 8:04b6a042595f 278 DBG("Disconnecting from PPP");
donatien 8:04b6a042595f 279 int ret = m_ppp.disconnect();
donatien 8:04b6a042595f 280 if(ret)
donatien 8:04b6a042595f 281 {
donatien 8:04b6a042595f 282 ERR("Disconnect returned %d, still trying to disconnect", ret);
donatien 8:04b6a042595f 283 }
donatien 8:04b6a042595f 284
donatien 8:04b6a042595f 285 //Ugly but leave dongle time to recover
donatien 8:04b6a042595f 286 Thread::wait(500);
donatien 8:04b6a042595f 287
donatien 9:3f077dde13c9 288 #if USE_ONE_PORT
donatien 8:04b6a042595f 289 ATCommandsInterface::ATResult result;
donatien 8:04b6a042595f 290 DBG("Starting AT thread");
donatien 8:04b6a042595f 291 ret = m_at.open();
donatien 8:04b6a042595f 292 if(ret)
donatien 8:04b6a042595f 293 {
donatien 8:04b6a042595f 294 return ret;
donatien 8:04b6a042595f 295 }
donatien 9:3f077dde13c9 296 #endif
donatien 8:04b6a042595f 297
donatien 8:04b6a042595f 298 DBG("Trying to hangup");
donatien 8:04b6a042595f 299
donatien 9:3f077dde13c9 300 #if 0 //Does not appear to work
donatien 8:04b6a042595f 301 int tries = 10;
donatien 8:04b6a042595f 302 do
donatien 8:04b6a042595f 303 {
donatien 8:04b6a042595f 304 ret = m_at.executeSimple("+++", &result, 1000);
donatien 8:04b6a042595f 305 DBG("Result of command: Err code=%d\n", ret);
donatien 8:04b6a042595f 306 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
donatien 8:04b6a042595f 307 } while(tries-- && ret);
donatien 8:04b6a042595f 308 if(!ret)
donatien 8:04b6a042595f 309 {
donatien 8:04b6a042595f 310 ret = m_at.executeSimple("ATH", &result);
donatien 8:04b6a042595f 311 DBG("Result of command: Err code=%d\n", ret);
donatien 8:04b6a042595f 312 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
donatien 8:04b6a042595f 313 }
donatien 9:3f077dde13c9 314 #endif
donatien 8:04b6a042595f 315
donatien 9:3f077dde13c9 316 #if USE_ONE_PORT
donatien 8:04b6a042595f 317 //Reinit AT parser
donatien 8:04b6a042595f 318 ret = m_at.init();
donatien 8:04b6a042595f 319 DBG("Result of command: Err code=%d\n", ret);
donatien 8:04b6a042595f 320 if(ret)
donatien 8:04b6a042595f 321 {
donatien 8:04b6a042595f 322 m_at.close(); // Closing AT parser
donatien 8:04b6a042595f 323 DBG("AT Parser closed, could not complete disconnection");
donatien 8:04b6a042595f 324 return NET_TIMEOUT;
donatien 8:04b6a042595f 325 }
donatien 8:04b6a042595f 326
donatien 9:3f077dde13c9 327 #if 0
donatien 8:04b6a042595f 328 m_at.close(); // Closing AT parser
donatien 8:04b6a042595f 329 DBG("AT Parser closed");
donatien 9:3f077dde13c9 330 #endif
donatien 9:3f077dde13c9 331 #endif
donatien 8:04b6a042595f 332 return OK;
donatien 8:04b6a042595f 333 }
donatien 8:04b6a042595f 334
donatien 22:06fb2a93a1f6 335 int VodafoneUSBModem::sendSM(const char* number, const char* message)
donatien 8:04b6a042595f 336 {
donatien 8:04b6a042595f 337 int ret = init();
donatien 8:04b6a042595f 338 if(ret)
donatien 8:04b6a042595f 339 {
donatien 8:04b6a042595f 340 return ret;
donatien 8:04b6a042595f 341 }
donatien 8:04b6a042595f 342
donatien 8:04b6a042595f 343 if(!m_smsInit)
donatien 8:04b6a042595f 344 {
donatien 8:04b6a042595f 345 ret = m_sms.init();
donatien 8:04b6a042595f 346 if(ret)
donatien 8:04b6a042595f 347 {
donatien 8:04b6a042595f 348 return ret;
donatien 8:04b6a042595f 349 }
donatien 8:04b6a042595f 350 m_smsInit = true;
donatien 8:04b6a042595f 351 }
donatien 8:04b6a042595f 352
donatien 8:04b6a042595f 353 ret = m_sms.send(number, message);
donatien 8:04b6a042595f 354 if(ret)
donatien 8:04b6a042595f 355 {
donatien 8:04b6a042595f 356 return ret;
donatien 8:04b6a042595f 357 }
donatien 8:04b6a042595f 358
donatien 8:04b6a042595f 359 return OK;
donatien 8:04b6a042595f 360 }
donatien 8:04b6a042595f 361
donatien 22:06fb2a93a1f6 362 int VodafoneUSBModem::getSM(char* number, char* message, size_t maxLength)
donatien 8:04b6a042595f 363 {
donatien 8:04b6a042595f 364 int ret = init();
donatien 8:04b6a042595f 365 if(ret)
donatien 8:04b6a042595f 366 {
donatien 8:04b6a042595f 367 return ret;
donatien 8:04b6a042595f 368 }
donatien 8:04b6a042595f 369
donatien 8:04b6a042595f 370 if(!m_smsInit)
donatien 8:04b6a042595f 371 {
donatien 8:04b6a042595f 372 ret = m_sms.init();
donatien 8:04b6a042595f 373 if(ret)
donatien 8:04b6a042595f 374 {
donatien 8:04b6a042595f 375 return ret;
donatien 8:04b6a042595f 376 }
donatien 8:04b6a042595f 377 m_smsInit = true;
donatien 8:04b6a042595f 378 }
donatien 8:04b6a042595f 379
donatien 8:04b6a042595f 380 ret = m_sms.get(number, message, maxLength);
donatien 8:04b6a042595f 381 if(ret)
donatien 8:04b6a042595f 382 {
donatien 8:04b6a042595f 383 return ret;
donatien 8:04b6a042595f 384 }
donatien 8:04b6a042595f 385
donatien 8:04b6a042595f 386 return OK;
donatien 8:04b6a042595f 387 }
donatien 8:04b6a042595f 388
donatien 22:06fb2a93a1f6 389 int VodafoneUSBModem::getSMCount(size_t* pCount)
donatien 8:04b6a042595f 390 {
donatien 8:04b6a042595f 391 int ret = init();
donatien 8:04b6a042595f 392 if(ret)
donatien 8:04b6a042595f 393 {
donatien 8:04b6a042595f 394 return ret;
donatien 8:04b6a042595f 395 }
donatien 8:04b6a042595f 396
donatien 8:04b6a042595f 397 if(!m_smsInit)
donatien 8:04b6a042595f 398 {
donatien 8:04b6a042595f 399 ret = m_sms.init();
donatien 8:04b6a042595f 400 if(ret)
donatien 8:04b6a042595f 401 {
donatien 8:04b6a042595f 402 return ret;
donatien 8:04b6a042595f 403 }
donatien 8:04b6a042595f 404 m_smsInit = true;
donatien 8:04b6a042595f 405 }
donatien 8:04b6a042595f 406
donatien 8:04b6a042595f 407 ret = m_sms.getCount(pCount);
donatien 8:04b6a042595f 408 if(ret)
donatien 8:04b6a042595f 409 {
donatien 8:04b6a042595f 410 return ret;
donatien 8:04b6a042595f 411 }
donatien 8:04b6a042595f 412
donatien 8:04b6a042595f 413 return OK;
donatien 8:04b6a042595f 414 }
donatien 8:04b6a042595f 415
donatien 22:06fb2a93a1f6 416 int VodafoneUSBModem::sendUSSD(const char* command, char* result, size_t maxLength)
donatien 8:04b6a042595f 417 {
donatien 8:04b6a042595f 418 int ret = init();
donatien 8:04b6a042595f 419 if(ret)
donatien 8:04b6a042595f 420 {
donatien 8:04b6a042595f 421 return ret;
donatien 8:04b6a042595f 422 }
donatien 8:04b6a042595f 423
donatien 8:04b6a042595f 424 if(!m_ussdInit)
donatien 8:04b6a042595f 425 {
donatien 8:04b6a042595f 426 ret = m_ussd.init();
donatien 8:04b6a042595f 427 if(ret)
donatien 8:04b6a042595f 428 {
donatien 8:04b6a042595f 429 return ret;
donatien 8:04b6a042595f 430 }
donatien 8:04b6a042595f 431 m_ussdInit = true;
donatien 8:04b6a042595f 432 }
donatien 8:04b6a042595f 433
donatien 8:04b6a042595f 434 ret = m_ussd.send(command, result, maxLength);
donatien 8:04b6a042595f 435 if(ret)
donatien 8:04b6a042595f 436 {
donatien 8:04b6a042595f 437 return ret;
donatien 8:04b6a042595f 438 }
donatien 8:04b6a042595f 439
donatien 8:04b6a042595f 440 return OK;
donatien 8:04b6a042595f 441 }
donatien 8:04b6a042595f 442
donatien 22:06fb2a93a1f6 443 int VodafoneUSBModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer)
donatien 12:66dc2c8eba2d 444 {
donatien 12:66dc2c8eba2d 445 int ret = init();
donatien 12:66dc2c8eba2d 446 if(ret)
donatien 12:66dc2c8eba2d 447 {
donatien 12:66dc2c8eba2d 448 return ret;
donatien 12:66dc2c8eba2d 449 }
donatien 12:66dc2c8eba2d 450
donatien 12:66dc2c8eba2d 451 if(!m_linkMonitorInit)
donatien 12:66dc2c8eba2d 452 {
donatien 12:66dc2c8eba2d 453 ret = m_linkMonitor.init();
donatien 12:66dc2c8eba2d 454 if(ret)
donatien 12:66dc2c8eba2d 455 {
donatien 12:66dc2c8eba2d 456 return ret;
donatien 12:66dc2c8eba2d 457 }
donatien 12:66dc2c8eba2d 458 m_linkMonitorInit = true;
donatien 12:66dc2c8eba2d 459 }
donatien 12:66dc2c8eba2d 460
donatien 12:66dc2c8eba2d 461 ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer);
donatien 12:66dc2c8eba2d 462 if(ret)
donatien 12:66dc2c8eba2d 463 {
donatien 12:66dc2c8eba2d 464 return ret;
donatien 12:66dc2c8eba2d 465 }
donatien 12:66dc2c8eba2d 466
donatien 12:66dc2c8eba2d 467 return OK;
donatien 12:66dc2c8eba2d 468 }
donatien 12:66dc2c8eba2d 469
donatien 12:66dc2c8eba2d 470
donatien 22:06fb2a93a1f6 471 ATCommandsInterface* VodafoneUSBModem::getATCommandsInterface()
donatien 8:04b6a042595f 472 {
donatien 8:04b6a042595f 473 return &m_at;
donatien 8:04b6a042595f 474 }
donatien 8:04b6a042595f 475
donatien 26:d37501dc6c61 476 int VodafoneUSBModem::power(bool enable)
donatien 26:d37501dc6c61 477 {
donatien 26:d37501dc6c61 478 if( m_powerGatingPin == NC )
donatien 26:d37501dc6c61 479 {
donatien 26:d37501dc6c61 480 return NET_INVALID; //A pin name has not been provided in the constructor
donatien 26:d37501dc6c61 481 }
donatien 27:37d3ac289e86 482
donatien 27:37d3ac289e86 483 if(!enable) //Will force components to re-init
donatien 26:d37501dc6c61 484 {
donatien 27:37d3ac289e86 485 cleanup();
donatien 26:d37501dc6c61 486 }
donatien 26:d37501dc6c61 487
donatien 26:d37501dc6c61 488 DigitalOut powerGatingOut(m_powerGatingPin);
donatien 33:f505faeda8e7 489 powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable;
donatien 27:37d3ac289e86 490
donatien 26:d37501dc6c61 491 return OK;
donatien 26:d37501dc6c61 492 }
donatien 26:d37501dc6c61 493
donatien 26:d37501dc6c61 494 bool VodafoneUSBModem::power()
donatien 26:d37501dc6c61 495 {
donatien 26:d37501dc6c61 496 if( m_powerGatingPin == NC )
donatien 26:d37501dc6c61 497 {
donatien 26:d37501dc6c61 498 return true; //Assume power is always on
donatien 26:d37501dc6c61 499 }
donatien 26:d37501dc6c61 500
donatien 26:d37501dc6c61 501 DigitalOut powerGatingOut(m_powerGatingPin);
donatien 33:f505faeda8e7 502 return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut;
donatien 26:d37501dc6c61 503 }
donatien 26:d37501dc6c61 504
donatien 22:06fb2a93a1f6 505 int VodafoneUSBModem::init()
donatien 8:04b6a042595f 506 {
donatien 8:04b6a042595f 507 if( !m_dongleConnected )
donatien 8:04b6a042595f 508 {
donatien 26:d37501dc6c61 509 if(!power())
donatien 26:d37501dc6c61 510 {
donatien 26:d37501dc6c61 511 //Obviously cannot initialize the dongle if it is disconnected...
donatien 26:d37501dc6c61 512 ERR("Power is off");
donatien 26:d37501dc6c61 513 return NET_INVALID;
donatien 26:d37501dc6c61 514 }
donatien 8:04b6a042595f 515 m_dongleConnected = true;
donatien 8:04b6a042595f 516 while( !m_dongle.connected() )
donatien 8:04b6a042595f 517 {
donatien 8:04b6a042595f 518 m_dongle.tryConnect();
donatien 8:04b6a042595f 519 Thread::wait(10);
donatien 8:04b6a042595f 520 }
donatien 8:04b6a042595f 521 }
donatien 8:04b6a042595f 522
donatien 8:04b6a042595f 523 if(m_atOpen)
donatien 8:04b6a042595f 524 {
donatien 8:04b6a042595f 525 return OK;
donatien 8:04b6a042595f 526 }
donatien 59:593fb493172f 527
donatien 8:04b6a042595f 528 DBG("Starting AT thread if needed");
donatien 8:04b6a042595f 529 int ret = m_at.open();
donatien 8:04b6a042595f 530 if(ret)
donatien 8:04b6a042595f 531 {
donatien 8:04b6a042595f 532 return ret;
donatien 8:04b6a042595f 533 }
donatien 59:593fb493172f 534
donatien 8:04b6a042595f 535 DBG("Sending initialisation commands");
donatien 8:04b6a042595f 536 ret = m_at.init();
donatien 8:04b6a042595f 537 if(ret)
donatien 8:04b6a042595f 538 {
donatien 8:04b6a042595f 539 return ret;
donatien 8:04b6a042595f 540 }
donatien 8:04b6a042595f 541
donatien 23:21046ba01b7b 542 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3770)
donatien 8:04b6a042595f 543 {
donatien 18:1789a11d1892 544 INFO("Using a Vodafone K3770 Dongle");
donatien 18:1789a11d1892 545 #if USE_ONE_PORT
donatien 18:1789a11d1892 546 DBG("Configuring unsolicited result codes support properly");
donatien 18:1789a11d1892 547 //Configuring port to enable 3GPP-compliant unsollicited response codes but disable Huawei-specific unsollicited response codes
donatien 18:1789a11d1892 548 ret = m_at.executeSimple("AT^CURC=0;^PORTSEL=1", NULL); //Huawei-specific, not 3GPP-compliant
donatien 18:1789a11d1892 549 if(ret != OK)
donatien 18:1789a11d1892 550 {
donatien 18:1789a11d1892 551 return NET_PROTOCOL;
donatien 18:1789a11d1892 552 }
donatien 18:1789a11d1892 553 #else
donatien 18:1789a11d1892 554 //Configuring port to disable Huawei-specific unsollicited response codes
donatien 18:1789a11d1892 555 ret = m_at.executeSimple("AT^CURC=0", NULL); //Huawei-specific, not 3GPP-compliant
donatien 18:1789a11d1892 556 if(ret != OK)
donatien 18:1789a11d1892 557 {
donatien 18:1789a11d1892 558 return NET_PROTOCOL;
donatien 18:1789a11d1892 559 }
donatien 18:1789a11d1892 560 #endif
donatien 8:04b6a042595f 561 }
donatien 18:1789a11d1892 562 else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3772Z)
donatien 12:66dc2c8eba2d 563 {
donatien 18:1789a11d1892 564 INFO("Using a Vodafone K3772-Z Dongle");
donatien 18:1789a11d1892 565 //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 566 /*
donatien 18:1789a11d1892 567 //Configuring modem to directly boot into modem mode
donatien 18:1789a11d1892 568 ret = m_at.executeSimple("AT%USBMODEM=0", NULL); //Icera-specific, not 3GPP-compliant
donatien 18:1789a11d1892 569 if(ret != OK)
donatien 18:1789a11d1892 570 {
donatien 18:1789a11d1892 571 return NET_PROTOCOL;
donatien 18:1789a11d1892 572 }
donatien 18:1789a11d1892 573 */
donatien 18:1789a11d1892 574 }
ashleymills 79:a6ac8206a58d 575 else if(m_dongle.getDongleType()== WAN_DONGLE_TYPE_VODAFONEK3773)
ashleymills 79:a6ac8206a58d 576 {
ashleymills 79:a6ac8206a58d 577 INFO("Using a Vodafone K3773 M2M dongle.");
ashleymills 79:a6ac8206a58d 578 }
ashleymills 79:a6ac8206a58d 579 else if(m_dongle.getDongleType()== WAN_DONGLE_TYPE_VODAFONEMU509)
ashleymills 79:a6ac8206a58d 580 {
ashleymills 79:a6ac8206a58d 581 INFO("Using a Huawei MU509 module.");
ashleymills 79:a6ac8206a58d 582 m_ppp.setHangupViaATPort(true);
ashleymills 80:c0e63c16306e 583
ashleymills 80:c0e63c16306e 584 // this modem defaults to sending a delivery receipt to the SM storage area
ashleymills 80:c0e63c16306e 585 // need to disable this for the current library to work in a sensible manner
ashleymills 80:c0e63c16306e 586 ret = m_at.executeSimple("at+csmp=1,,0,0",NULL);
ashleymills 80:c0e63c16306e 587 if(ret!=0) {
ashleymills 80:c0e63c16306e 588 return NET_PROTOCOL;
ashleymills 80:c0e63c16306e 589 }
ashleymills 79:a6ac8206a58d 590 }
donatien 18:1789a11d1892 591 else
donatien 18:1789a11d1892 592 {
donatien 18:1789a11d1892 593 WARN("Using an Unknown Dongle");
donatien 18:1789a11d1892 594 }
donatien 8:04b6a042595f 595
donatien 8:04b6a042595f 596 ATCommandsInterface::ATResult result;
donatien 8:04b6a042595f 597
donatien 8:04b6a042595f 598 //Wait for network registration
donatien 8:04b6a042595f 599 CREGProcessor cregProcessor;
donatien 8:04b6a042595f 600 do
donatien 8:04b6a042595f 601 {
donatien 8:04b6a042595f 602 DBG("Waiting for network registration");
donatien 8:04b6a042595f 603 ret = m_at.execute("AT+CREG?", &cregProcessor, &result);
donatien 8:04b6a042595f 604 DBG("Result of command: Err code=%d\n", ret);
donatien 8:04b6a042595f 605 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
donatien 8:04b6a042595f 606 if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING)
donatien 8:04b6a042595f 607 {
donatien 8:04b6a042595f 608 Thread::wait(3000);
donatien 8:04b6a042595f 609 }
donatien 8:04b6a042595f 610 } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
donatien 8:04b6a042595f 611 if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED)
donatien 8:04b6a042595f 612 {
donatien 8:04b6a042595f 613 ERR("Registration denied");
donatien 8:04b6a042595f 614 return NET_AUTH;
donatien 8:04b6a042595f 615 }
donatien 8:04b6a042595f 616
donatien 8:04b6a042595f 617 m_atOpen = true;
donatien 8:04b6a042595f 618
donatien 8:04b6a042595f 619 return OK;
donatien 8:04b6a042595f 620 }
donatien 8:04b6a042595f 621
donatien 27:37d3ac289e86 622 int VodafoneUSBModem::cleanup()
donatien 27:37d3ac289e86 623 {
donatien 27:37d3ac289e86 624 if(m_ppp.isConnected())
donatien 27:37d3ac289e86 625 {
donatien 27:37d3ac289e86 626 WARN("Data connection is still open"); //Try to encourage good behaviour from the user
donatien 27:37d3ac289e86 627 m_ppp.disconnect();
donatien 27:37d3ac289e86 628 }
donatien 27:37d3ac289e86 629
donatien 27:37d3ac289e86 630 m_smsInit = false;
donatien 27:37d3ac289e86 631 m_ussdInit = false;
donatien 27:37d3ac289e86 632 m_linkMonitorInit = false;
donatien 27:37d3ac289e86 633 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once
donatien 27:37d3ac289e86 634
donatien 27:37d3ac289e86 635 if(m_atOpen)
donatien 27:37d3ac289e86 636 {
donatien 27:37d3ac289e86 637 m_at.close();
donatien 27:37d3ac289e86 638 m_atOpen = false;
donatien 27:37d3ac289e86 639 }
donatien 27:37d3ac289e86 640
donatien 27:37d3ac289e86 641 m_dongle.disconnect();
donatien 27:37d3ac289e86 642 m_dongleConnected = false;
donatien 27:37d3ac289e86 643
donatien 27:37d3ac289e86 644 return OK;
donatien 27:37d3ac289e86 645 }
donatien 8:04b6a042595f 646