Changes to support Vodafone K4606

Dependencies:   Socket USBHostWANDongle lwip-sys lwip

Fork of VodafoneUSBModem by mbed official

Committer:
ashleymills
Date:
Wed Mar 26 17:15:23 2014 +0000
Revision:
94:c5d90f929f8d
Parent:
92:ed0443728c60
Added a message for K3772

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 {
ashleymills 94:c5d90f929f8d 601 INFO("Using a Vodafone K3772 Dongle");
ashleymills 94:c5d90f929f8d 602 }
ashleymills 94:c5d90f929f8d 603 else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONE_K3772Z)
ashleymills 94:c5d90f929f8d 604 {
donatien 18:1789a11d1892 605 INFO("Using a Vodafone K3772-Z Dongle");
donatien 18:1789a11d1892 606 //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 607 /*
donatien 18:1789a11d1892 608 //Configuring modem to directly boot into modem mode
donatien 18:1789a11d1892 609 ret = m_at.executeSimple("AT%USBMODEM=0", NULL); //Icera-specific, not 3GPP-compliant
donatien 18:1789a11d1892 610 if(ret != OK)
donatien 18:1789a11d1892 611 {
donatien 18:1789a11d1892 612 return NET_PROTOCOL;
donatien 18:1789a11d1892 613 }
donatien 18:1789a11d1892 614 */
donatien 18:1789a11d1892 615 }
ashleymills 91:7b311719374d 616 else if(m_dongle.getDongleType()== WAN_DONGLE_TYPE_VODAFONE_K3773)
ashleymills 79:a6ac8206a58d 617 {
ashleymills 79:a6ac8206a58d 618 INFO("Using a Vodafone K3773 M2M dongle.");
ashleymills 82:ab4d6263f25c 619 INFO("Disabling sim toolkit notifications");
ashleymills 81:da03da068398 620 ret = m_at.executeSimple("at^stsf=0",NULL);
ashleymills 82:ab4d6263f25c 621 if(ret!=0) {
ashleymills 82:ab4d6263f25c 622 return NET_PROTOCOL;
ashleymills 82:ab4d6263f25c 623 }
ashleymills 82:ab4d6263f25c 624 INFO("Disabling other unsolicited notifications");
ashleymills 81:da03da068398 625 ret = m_at.executeSimple("at^curc=0",NULL);
ashleymills 81:da03da068398 626 if(ret!=0) {
ashleymills 81:da03da068398 627 return NET_PROTOCOL;
ashleymills 81:da03da068398 628 }
ashleymills 79:a6ac8206a58d 629 }
ashleymills 91:7b311719374d 630 else if(m_dongle.getDongleType()== WAN_DONGLE_TYPE_HUAWEI_MU509)
ashleymills 79:a6ac8206a58d 631 {
ashleymills 79:a6ac8206a58d 632 INFO("Using a Huawei MU509 module.");
ashleymills 79:a6ac8206a58d 633 m_ppp.setHangupViaATPort(true);
ashleymills 80:c0e63c16306e 634
ashleymills 80:c0e63c16306e 635 // this modem defaults to sending a delivery receipt to the SM storage area
ashleymills 80:c0e63c16306e 636 // need to disable this for the current library to work in a sensible manner
ashleymills 83:897a0de9d668 637 INFO("Disabling SMS delivery receipts");
ashleymills 80:c0e63c16306e 638 ret = m_at.executeSimple("at+csmp=1,,0,0",NULL);
ashleymills 80:c0e63c16306e 639 if(ret!=0) {
ashleymills 80:c0e63c16306e 640 return NET_PROTOCOL;
ashleymills 80:c0e63c16306e 641 }
ashleymills 83:897a0de9d668 642 INFO("Disabling unsolicitied notifications");
ashleymills 83:897a0de9d668 643 ret = m_at.executeSimple("AT^CURC=0", NULL); //Huawei-specific, not 3GPP-compliant
ashleymills 83:897a0de9d668 644 if(ret != OK)
ashleymills 83:897a0de9d668 645 {
ashleymills 83:897a0de9d668 646 return NET_PROTOCOL;
ashleymills 83:897a0de9d668 647 }
ashleymills 79:a6ac8206a58d 648 }
ashleymills 91:7b311719374d 649 else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200)
ashleymills 91:7b311719374d 650 {
ashleymills 91:7b311719374d 651 INFO("Using a u-blox LISA-U");
ashleymills 91:7b311719374d 652
ashleymills 91:7b311719374d 653 /*
ashleymills 91:7b311719374d 654 // change SMS storage to SIM
ashleymills 91:7b311719374d 655 ret = m_at.executeSimple("at+cpms=\"mt\",\"mt\",\"sm\"",NULL);
ashleymills 91:7b311719374d 656 if(ret!=0) {
ashleymills 91:7b311719374d 657 return NET_PROTOCOL;
ashleymills 91:7b311719374d 658 }
ashleymills 91:7b311719374d 659 */
ashleymills 91:7b311719374d 660 }
donatien 18:1789a11d1892 661 else
donatien 18:1789a11d1892 662 {
donatien 18:1789a11d1892 663 WARN("Using an Unknown Dongle");
donatien 18:1789a11d1892 664 }
donatien 8:04b6a042595f 665
donatien 8:04b6a042595f 666 ATCommandsInterface::ATResult result;
donatien 8:04b6a042595f 667
donatien 8:04b6a042595f 668 //Wait for network registration
donatien 8:04b6a042595f 669 CREGProcessor cregProcessor;
donatien 8:04b6a042595f 670 do
donatien 8:04b6a042595f 671 {
donatien 8:04b6a042595f 672 DBG("Waiting for network registration");
donatien 8:04b6a042595f 673 ret = m_at.execute("AT+CREG?", &cregProcessor, &result);
donatien 8:04b6a042595f 674 DBG("Result of command: Err code=%d\n", ret);
donatien 8:04b6a042595f 675 DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
donatien 8:04b6a042595f 676 if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING)
donatien 8:04b6a042595f 677 {
donatien 8:04b6a042595f 678 Thread::wait(3000);
donatien 8:04b6a042595f 679 }
donatien 8:04b6a042595f 680 } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
donatien 8:04b6a042595f 681 if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED)
donatien 8:04b6a042595f 682 {
donatien 8:04b6a042595f 683 ERR("Registration denied");
donatien 8:04b6a042595f 684 return NET_AUTH;
donatien 8:04b6a042595f 685 }
donatien 8:04b6a042595f 686
donatien 8:04b6a042595f 687 m_atOpen = true;
donatien 8:04b6a042595f 688
donatien 8:04b6a042595f 689 return OK;
donatien 8:04b6a042595f 690 }
donatien 8:04b6a042595f 691
donatien 27:37d3ac289e86 692 int VodafoneUSBModem::cleanup()
donatien 27:37d3ac289e86 693 {
donatien 27:37d3ac289e86 694 if(m_ppp.isConnected())
donatien 27:37d3ac289e86 695 {
donatien 27:37d3ac289e86 696 WARN("Data connection is still open"); //Try to encourage good behaviour from the user
donatien 27:37d3ac289e86 697 m_ppp.disconnect();
donatien 27:37d3ac289e86 698 }
donatien 27:37d3ac289e86 699
donatien 27:37d3ac289e86 700 m_smsInit = false;
donatien 27:37d3ac289e86 701 m_ussdInit = false;
donatien 27:37d3ac289e86 702 m_linkMonitorInit = false;
donatien 27:37d3ac289e86 703 //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once
donatien 27:37d3ac289e86 704
donatien 27:37d3ac289e86 705 if(m_atOpen)
donatien 27:37d3ac289e86 706 {
donatien 27:37d3ac289e86 707 m_at.close();
donatien 27:37d3ac289e86 708 m_atOpen = false;
donatien 27:37d3ac289e86 709 }
donatien 27:37d3ac289e86 710
donatien 27:37d3ac289e86 711 m_dongle.disconnect();
donatien 27:37d3ac289e86 712 m_dongleConnected = false;
donatien 27:37d3ac289e86 713
donatien 27:37d3ac289e86 714 return OK;
donatien 27:37d3ac289e86 715 }
donatien 8:04b6a042595f 716
ashleymills 92:ed0443728c60 717 char* VodafoneUSBModem::getIPAddress()
ashleymills 92:ed0443728c60 718 {
ashleymills 92:ed0443728c60 719 return m_ppp.getIPAddress();
ashleymills 92:ed0443728c60 720 }