A library for talking to Multi-Tech's Cellular SocketModem Devices.

Dependents:   M2X_dev axeda_wrapper_dev MTS_M2x_Example1 MTS_Cellular_Connect_Example ... more

Committer:
sgodinez
Date:
Fri Dec 13 23:02:50 2013 +0000
Revision:
13:0af863114629
Parent:
12:40ac31a09132
Child:
17:2d7c4ea7491b
Successfully setup PPP connection

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jengbrecht 0:563b70517320 1 #ifndef CELLULAR_CPP
jengbrecht 0:563b70517320 2 #define CELLULAR_CPP
jengbrecht 0:563b70517320 3
jengbrecht 0:563b70517320 4 #include "Cellular.h"
sgodinez 4:6561c9128c6f 5 #include "MTSText.h"
sgodinez 11:134435d8a2d5 6 #include <sstream>
jengbrecht 0:563b70517320 7
sgodinez 11:134435d8a2d5 8 Cellular::Cellular(MTSBufferedIO& io)
sgodinez 11:134435d8a2d5 9 : io(io)
sgodinez 13:0af863114629 10 , echoMode(true)
sgodinez 11:134435d8a2d5 11 , pppConnected(false)
sgodinez 11:134435d8a2d5 12 , mode(TCP)
sgodinez 11:134435d8a2d5 13 , socketOpened(false)
sgodinez 11:134435d8a2d5 14 , local_port(0)
sgodinez 11:134435d8a2d5 15 , host_port(0)
jengbrecht 0:563b70517320 16 {
jengbrecht 0:563b70517320 17 }
jengbrecht 0:563b70517320 18
jengbrecht 0:563b70517320 19 Cellular::~Cellular()
jengbrecht 0:563b70517320 20 {
jengbrecht 0:563b70517320 21 }
jengbrecht 0:563b70517320 22
sgodinez 11:134435d8a2d5 23 bool Cellular::connect() {
sgodinez 13:0af863114629 24 //Check if socket is open
sgodinez 13:0af863114629 25 if(socketOpened) {
sgodinez 13:0af863114629 26 return true;
sgodinez 13:0af863114629 27 }
sgodinez 13:0af863114629 28
sgodinez 11:134435d8a2d5 29 //Run Test first to validate a good state
sgodinez 13:0af863114629 30 if(isConnected()) {
sgodinez 13:0af863114629 31 return true;
sgodinez 13:0af863114629 32 }
sgodinez 13:0af863114629 33
sgodinez 11:134435d8a2d5 34 //Check RSSI: AT+CSQ
sgodinez 13:0af863114629 35 int rssi = getSignalStrength();
sgodinez 13:0af863114629 36 printf("[DEBUG] Signal strength: %d\n", rssi);
sgodinez 13:0af863114629 37
sgodinez 11:134435d8a2d5 38 //Check Registration: AT+CREG? == 0,1
sgodinez 13:0af863114629 39 Registration registration = getRegistration();
sgodinez 13:0af863114629 40 if(registration != REGISTERED) {
sgodinez 13:0af863114629 41 printf("[WARNING] Not Registered [%d]\n", (int)registration);
sgodinez 13:0af863114629 42 }
sgodinez 11:134435d8a2d5 43
sgodinez 11:134435d8a2d5 44 //AT#CONNECTIONSTART: Make a PPP connection
sgodinez 13:0af863114629 45 printf("[DEBUG] Making PPP Connection Attempt. APN[%s]\n", apn.c_str());
sgodinez 13:0af863114629 46 std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
sgodinez 13:0af863114629 47
sgodinez 13:0af863114629 48 printf("[DEBUG] PPP CONNECT RESULT [%s]\n", pppResult.c_str());
sgodinez 13:0af863114629 49
sgodinez 13:0af863114629 50 std::vector<std::string> parts = Text::split(pppResult, "\r\n");
sgodinez 13:0af863114629 51 for(uint32_t i = 0; i < parts.size(); i++) {
sgodinez 13:0af863114629 52 printf("[%d] [%s]\r\n", i, parts[i].c_str());
sgodinez 13:0af863114629 53 }
sgodinez 11:134435d8a2d5 54
sgodinez 13:0af863114629 55
sgodinez 13:0af863114629 56 if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
sgodinez 13:0af863114629 57 if(parts.size() >= 2) {
sgodinez 13:0af863114629 58 local_address = parts[1];
sgodinez 13:0af863114629 59 }
sgodinez 13:0af863114629 60 printf("[INFO] PPP Connection Established: IP[%s]\n", local_address.c_str());
sgodinez 13:0af863114629 61 pppConnected = true;
sgodinez 13:0af863114629 62
sgodinez 13:0af863114629 63 } else {
sgodinez 13:0af863114629 64 pppConnected = false;
sgodinez 13:0af863114629 65 }
sgodinez 11:134435d8a2d5 66
sgodinez 13:0af863114629 67 return pppConnected;
sgodinez 11:134435d8a2d5 68 }
sgodinez 11:134435d8a2d5 69
sgodinez 11:134435d8a2d5 70 void Cellular::disconnect() {
sgodinez 11:134435d8a2d5 71
sgodinez 11:134435d8a2d5 72 }
sgodinez 11:134435d8a2d5 73
sgodinez 11:134435d8a2d5 74 bool Cellular::isConnected() {
sgodinez 11:134435d8a2d5 75 //1) Check if APN was set
sgodinez 11:134435d8a2d5 76 if(apn.size() == 0) {
sgodinez 11:134435d8a2d5 77 printf("[DEBUG] APN is not set\n");
sgodinez 11:134435d8a2d5 78 return false;
sgodinez 11:134435d8a2d5 79 }
sgodinez 11:134435d8a2d5 80
sgodinez 11:134435d8a2d5 81 //1) Check that we do not have a live connection up
sgodinez 11:134435d8a2d5 82 if(socketOpened) {
sgodinez 11:134435d8a2d5 83 printf("[DEBUG] Socket is opened\n");
sgodinez 11:134435d8a2d5 84 return true;
sgodinez 11:134435d8a2d5 85 }
sgodinez 11:134435d8a2d5 86 //2) Query the radio
sgodinez 11:134435d8a2d5 87 pppConnected = false;
sgodinez 11:134435d8a2d5 88 std::string result = sendCommand("AT#VSTATE", 1000);
sgodinez 11:134435d8a2d5 89 if(result.find("CONNECTED") != std::string::npos) {
sgodinez 11:134435d8a2d5 90 pppConnected = true;
sgodinez 11:134435d8a2d5 91 }
sgodinez 11:134435d8a2d5 92
sgodinez 11:134435d8a2d5 93 return pppConnected;
sgodinez 11:134435d8a2d5 94 }
sgodinez 11:134435d8a2d5 95
sgodinez 11:134435d8a2d5 96 bool Cellular::bind(unsigned int port) {
sgodinez 11:134435d8a2d5 97 return false;
sgodinez 11:134435d8a2d5 98 }
sgodinez 11:134435d8a2d5 99
sgodinez 11:134435d8a2d5 100 bool Cellular::open(const std::string& address, unsigned int port, Mode mode) {
sgodinez 11:134435d8a2d5 101 Code portCode, addressCode;
sgodinez 11:134435d8a2d5 102
sgodinez 11:134435d8a2d5 103 //1) Check that we do not have a live connection up
sgodinez 11:134435d8a2d5 104 if(socketOpened) {
sgodinez 11:134435d8a2d5 105 printf("[DEBUG] Socket already opened\n");
sgodinez 11:134435d8a2d5 106 return true;
sgodinez 11:134435d8a2d5 107 }
sgodinez 11:134435d8a2d5 108
sgodinez 11:134435d8a2d5 109 //2) Check PPP connection
sgodinez 11:134435d8a2d5 110 if(!isConnected()) {
sgodinez 11:134435d8a2d5 111 printf("[ERROR] PPP not established. Attempting to connect\n");
sgodinez 11:134435d8a2d5 112 if(!connect()) {
sgodinez 11:134435d8a2d5 113 printf("[ERROR] PPP connection failed\n");
sgodinez 11:134435d8a2d5 114 return false;
sgodinez 11:134435d8a2d5 115 } else {
sgodinez 11:134435d8a2d5 116 printf("[DEBUG] PPP connection established\n");
sgodinez 11:134435d8a2d5 117 }
sgodinez 11:134435d8a2d5 118 }
sgodinez 11:134435d8a2d5 119
sgodinez 11:134435d8a2d5 120 //Setup IP Connection
sgodinez 11:134435d8a2d5 121 std::stringstream ss;
sgodinez 11:134435d8a2d5 122 if(mode == TCP) {
sgodinez 11:134435d8a2d5 123 ss << "AT#TCPPORT=1," << port;
sgodinez 11:134435d8a2d5 124 portCode = sendBasicCommand(ss.str(), 1000);
sgodinez 11:134435d8a2d5 125 addressCode = sendBasicCommand("AT#TCPSERV=1," + address, 1000);
sgodinez 11:134435d8a2d5 126 } else {
sgodinez 11:134435d8a2d5 127 ss << "AT#UDPPORT=1," << port;
sgodinez 11:134435d8a2d5 128 portCode = sendBasicCommand(ss.str(), 1000);
sgodinez 11:134435d8a2d5 129 addressCode = sendBasicCommand("AT#UDPSERV=1," + address, 1000);
sgodinez 11:134435d8a2d5 130 }
sgodinez 11:134435d8a2d5 131
sgodinez 11:134435d8a2d5 132 if(portCode == OK) {
sgodinez 11:134435d8a2d5 133 host_port = port;
sgodinez 11:134435d8a2d5 134 } else {
sgodinez 11:134435d8a2d5 135 printf("[ERROR] Host port could not be set\n");
sgodinez 11:134435d8a2d5 136 }
sgodinez 11:134435d8a2d5 137
sgodinez 11:134435d8a2d5 138 if(addressCode == OK) {
sgodinez 11:134435d8a2d5 139 host_address = address;
sgodinez 11:134435d8a2d5 140 } else {
sgodinez 11:134435d8a2d5 141 printf("[ERROR] Host address could not be set\n");
sgodinez 11:134435d8a2d5 142 }
sgodinez 11:134435d8a2d5 143
sgodinez 13:0af863114629 144 // Try and Connect
sgodinez 13:0af863114629 145 string response = sendCommand("AT#OTCP=1", 30000);
sgodinez 13:0af863114629 146 if (response.find("Ok_Info_WaitingForData") != string::npos) {
sgodinez 13:0af863114629 147 printf("[INFO] Opened TCP Socket [%s:%d]\n", address.c_str(), port);
sgodinez 13:0af863114629 148 socketOpened = true;
sgodinez 13:0af863114629 149 } else {
sgodinez 13:0af863114629 150 printf("[WARNING] Unable to open TCP Socket [%s:%d]\n", address.c_str(), port);
sgodinez 13:0af863114629 151 socketOpened = false;
sgodinez 13:0af863114629 152 }
sgodinez 11:134435d8a2d5 153
sgodinez 13:0af863114629 154 return socketOpened;
sgodinez 11:134435d8a2d5 155 }
sgodinez 11:134435d8a2d5 156
sgodinez 11:134435d8a2d5 157 bool Cellular::isOpen() {
sgodinez 11:134435d8a2d5 158 return false;
sgodinez 11:134435d8a2d5 159 }
sgodinez 11:134435d8a2d5 160
sgodinez 11:134435d8a2d5 161 void Cellular::close() {
sgodinez 13:0af863114629 162 if(!socketOpened) {
sgodinez 13:0af863114629 163 return;
sgodinez 13:0af863114629 164 }
sgodinez 11:134435d8a2d5 165
sgodinez 13:0af863114629 166 //Build Escape Message => DLE ETX
sgodinez 13:0af863114629 167 char buffer[3] = { 0x10, 0x03, 0x00 };
sgodinez 13:0af863114629 168 Code code = sendBasicCommand(buffer, 1000, NONE);
sgodinez 13:0af863114629 169 if(code != OK) {
sgodinez 13:0af863114629 170 printf("[WARNING] Radio did not accept close socket command");
sgodinez 13:0af863114629 171 //Handle cleanup
sgodinez 13:0af863114629 172 }
sgodinez 13:0af863114629 173 socketOpened = false;
sgodinez 11:134435d8a2d5 174 }
sgodinez 11:134435d8a2d5 175
sgodinez 11:134435d8a2d5 176 int Cellular::read(char* data, int max, int timeout) {
sgodinez 11:134435d8a2d5 177 return -1;
sgodinez 11:134435d8a2d5 178 }
sgodinez 11:134435d8a2d5 179
sgodinez 11:134435d8a2d5 180 int Cellular::write(char* data, int length, int timeout) {
sgodinez 11:134435d8a2d5 181 return -1;
sgodinez 11:134435d8a2d5 182 }
sgodinez 11:134435d8a2d5 183
sgodinez 11:134435d8a2d5 184 unsigned int Cellular::readable() {
sgodinez 11:134435d8a2d5 185 return 0;
sgodinez 11:134435d8a2d5 186 }
sgodinez 11:134435d8a2d5 187
sgodinez 11:134435d8a2d5 188 unsigned int Cellular::writeable() {
sgodinez 11:134435d8a2d5 189 return 0;
sgodinez 11:134435d8a2d5 190 }
sgodinez 11:134435d8a2d5 191
sgodinez 11:134435d8a2d5 192 void Cellular::reset() {
sgodinez 11:134435d8a2d5 193
sgodinez 11:134435d8a2d5 194 }
sgodinez 11:134435d8a2d5 195
sgodinez 11:134435d8a2d5 196 Cellular::Code Cellular::test()
jengbrecht 0:563b70517320 197 {
sgodinez 11:134435d8a2d5 198 Code code = sendBasicCommand("AT", 1000);
sgodinez 11:134435d8a2d5 199
sgodinez 11:134435d8a2d5 200 if(code != OK) {
sgodinez 11:134435d8a2d5 201 printf("[Error] Failed basic AT command");
sgodinez 11:134435d8a2d5 202 return code;
sgodinez 11:134435d8a2d5 203 }
sgodinez 11:134435d8a2d5 204
sgodinez 11:134435d8a2d5 205 //AT#VSTATE != "CHECKING"
sgodinez 11:134435d8a2d5 206
sgodinez 11:134435d8a2d5 207 //AT#GPRSMODE ==
sgodinez 12:40ac31a09132 208 return OK;
jengbrecht 0:563b70517320 209 }
jengbrecht 0:563b70517320 210
jengbrecht 0:563b70517320 211 Cellular::Code Cellular::echoOff(bool state)
jengbrecht 0:563b70517320 212 {
sgodinez 13:0af863114629 213 Code code;
jengbrecht 0:563b70517320 214 if (state) {
sgodinez 13:0af863114629 215 code = sendBasicCommand("ATE0", 1000);
sgodinez 13:0af863114629 216 echoMode = (code == OK) ? false : echoMode;
jengbrecht 0:563b70517320 217 } else {
sgodinez 13:0af863114629 218 code = sendBasicCommand("ATE1", 1000);
sgodinez 13:0af863114629 219 echoMode = (code == OK) ? true : echoMode;
jengbrecht 0:563b70517320 220 }
sgodinez 13:0af863114629 221 return code;
jengbrecht 0:563b70517320 222 }
jengbrecht 0:563b70517320 223
jengbrecht 0:563b70517320 224 int Cellular::getSignalStrength()
jengbrecht 0:563b70517320 225 {
jengbrecht 0:563b70517320 226 string response = sendCommand("AT+CSQ", 1000);
jengbrecht 0:563b70517320 227 if (response.find("OK") == string::npos) {
jengbrecht 0:563b70517320 228 return -1;
jengbrecht 0:563b70517320 229 }
jengbrecht 0:563b70517320 230 int start = response.find(':');
jengbrecht 0:563b70517320 231 int stop = response.find(',', start);
jengbrecht 0:563b70517320 232 string signal = response.substr(start + 2, stop - start - 2);
jengbrecht 0:563b70517320 233 int value;
jengbrecht 0:563b70517320 234 sscanf(signal.c_str(), "%d", &value);
jengbrecht 0:563b70517320 235 return value;
jengbrecht 0:563b70517320 236 }
jengbrecht 0:563b70517320 237
sgodinez 5:93e889a5abc6 238 std::string Cellular::getPhoneNumber() {
sgodinez 5:93e889a5abc6 239 return "unknown";
sgodinez 5:93e889a5abc6 240 }
sgodinez 5:93e889a5abc6 241
jengbrecht 0:563b70517320 242 Cellular::Registration Cellular::getRegistration()
jengbrecht 0:563b70517320 243 {
jengbrecht 0:563b70517320 244 string response = sendCommand("AT+CREG?", 1000);
jengbrecht 0:563b70517320 245 if (response.find("OK") == string::npos) {
jengbrecht 0:563b70517320 246 return UNKNOWN;
jengbrecht 0:563b70517320 247 }
jengbrecht 0:563b70517320 248 int start = response.find(',');
jengbrecht 0:563b70517320 249 int stop = response.find(' ', start);
jengbrecht 0:563b70517320 250 string regStat = response.substr(start + 1, stop - start - 1);
jengbrecht 0:563b70517320 251 int value;
jengbrecht 0:563b70517320 252 sscanf(regStat.c_str(), "%d", &value);
jengbrecht 0:563b70517320 253 switch (value) {
jengbrecht 0:563b70517320 254 case 0:
jengbrecht 0:563b70517320 255 return NOT_REGISTERED;
jengbrecht 0:563b70517320 256 case 1:
jengbrecht 0:563b70517320 257 return REGISTERED;
jengbrecht 0:563b70517320 258 case 2:
jengbrecht 0:563b70517320 259 return SEARCHING;
jengbrecht 0:563b70517320 260 case 3:
jengbrecht 0:563b70517320 261 return DENIED;
jengbrecht 0:563b70517320 262 case 4:
jengbrecht 0:563b70517320 263 return UNKNOWN;
jengbrecht 0:563b70517320 264 case 5:
jengbrecht 0:563b70517320 265 return ROAMING;
jengbrecht 0:563b70517320 266 }
sgodinez 4:6561c9128c6f 267 return UNKNOWN;
jengbrecht 0:563b70517320 268 }
jengbrecht 0:563b70517320 269
jengbrecht 0:563b70517320 270 Cellular::Code Cellular::sendBasicCommand(string command, int timeoutMillis, ESC_CHAR esc)
jengbrecht 0:563b70517320 271 {
jengbrecht 0:563b70517320 272 string response = sendCommand(command, timeoutMillis, esc);
jengbrecht 0:563b70517320 273 if (response.size() == 0) {
jengbrecht 0:563b70517320 274 return NO_RESPONSE;
jengbrecht 0:563b70517320 275 } else if (response.find("OK") != string::npos) {
jengbrecht 0:563b70517320 276 return OK;
jengbrecht 0:563b70517320 277 } else if (response.find("ERROR") != string::npos) {
jengbrecht 0:563b70517320 278 return ERROR;
jengbrecht 0:563b70517320 279 } else {
jengbrecht 0:563b70517320 280 return FAILURE;
jengbrecht 0:563b70517320 281 }
jengbrecht 0:563b70517320 282 }
jengbrecht 0:563b70517320 283
sgodinez 11:134435d8a2d5 284 Cellular::Code Cellular::setApn(const std::string& apn) {
sgodinez 11:134435d8a2d5 285 Code code = sendBasicCommand("AT#APNSERV=\"" + apn + "\"", 1000);
sgodinez 11:134435d8a2d5 286 if (code != OK) {
sgodinez 11:134435d8a2d5 287 return code;
sgodinez 11:134435d8a2d5 288 }
sgodinez 11:134435d8a2d5 289 this->apn = apn;
sgodinez 11:134435d8a2d5 290 return code;
sgodinez 11:134435d8a2d5 291 }
sgodinez 11:134435d8a2d5 292
sgodinez 11:134435d8a2d5 293 Cellular::Code Cellular::setDns(const std::string& apn) {
sgodinez 12:40ac31a09132 294 return FAILURE;
sgodinez 11:134435d8a2d5 295 }
sgodinez 11:134435d8a2d5 296
sgodinez 4:6561c9128c6f 297 Cellular::Code Cellular::sendSMS(const Sms& sms) {
sgodinez 4:6561c9128c6f 298 return sendSMS(sms.phoneNumber, sms.message);
sgodinez 4:6561c9128c6f 299 }
sgodinez 4:6561c9128c6f 300
sgodinez 4:6561c9128c6f 301 Cellular::Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message)
jengbrecht 0:563b70517320 302 {
jengbrecht 0:563b70517320 303 Code code = sendBasicCommand("AT+CMGF=1", 1000);
jengbrecht 0:563b70517320 304 if (code != OK) {
jengbrecht 0:563b70517320 305 return code;
jengbrecht 0:563b70517320 306 }
jengbrecht 0:563b70517320 307 string cmd = "AT+CMGS=\"+";
jengbrecht 0:563b70517320 308 cmd.append(phoneNumber);
jengbrecht 0:563b70517320 309 cmd.append("\"");
jengbrecht 0:563b70517320 310 string response1 = sendCommand(cmd, 1000);
jengbrecht 0:563b70517320 311 if (response1.find('>') == string::npos) {
jengbrecht 0:563b70517320 312 return NO_RESPONSE;
jengbrecht 0:563b70517320 313 }
jengbrecht 0:563b70517320 314 wait(.2);
jengbrecht 0:563b70517320 315 string response2 = sendCommand(message, 4000, CTRL_Z);
sgodinez 4:6561c9128c6f 316 printf("SMS Response: %s\n", response2.c_str());
jengbrecht 0:563b70517320 317 if (response2.find("+CMGS:") == string::npos) {
jengbrecht 0:563b70517320 318 return FAILURE;
jengbrecht 0:563b70517320 319 }
jengbrecht 0:563b70517320 320 return OK;
jengbrecht 0:563b70517320 321 }
jengbrecht 0:563b70517320 322
sgodinez 4:6561c9128c6f 323 std::vector<Cellular::Sms> Cellular::getReceivedSms() {
sgodinez 9:5b12c5a8dde4 324 int smsNumber = 0;
sgodinez 4:6561c9128c6f 325 std::vector<Sms> vSms;
sgodinez 4:6561c9128c6f 326 std::string received = sendCommand("AT+CMGL=\"ALL\"", 4000);
sgodinez 5:93e889a5abc6 327 size_t pos = received.find("+CMGL: ");
sgodinez 4:6561c9128c6f 328
sgodinez 5:93e889a5abc6 329 while (pos != std::string::npos) {
sgodinez 4:6561c9128c6f 330 Cellular::Sms sms;
sgodinez 4:6561c9128c6f 331 std::string line(Text::getLine(received, pos, pos));
sgodinez 9:5b12c5a8dde4 332 //printf("[DEBUG] Top of SMS Parse Loop. LINE[%s]\n", line.c_str());
sgodinez 9:5b12c5a8dde4 333 if(line.find("+CMGL: ") == std::string::npos) {
sgodinez 4:6561c9128c6f 334 continue;
sgodinez 4:6561c9128c6f 335 }
sgodinez 4:6561c9128c6f 336
sgodinez 4:6561c9128c6f 337 //Start of SMS message
sgodinez 4:6561c9128c6f 338 std::vector<std::string> vSmsParts = Text::split(line, ',');
sgodinez 4:6561c9128c6f 339 if(vSmsParts.size() != 6) {
sgodinez 9:5b12c5a8dde4 340 printf("[WARNING] Expected 6 commas. SMS[%d] DATA[%s]. Continuing ...\n", smsNumber, line.c_str());
sgodinez 4:6561c9128c6f 341 continue;
sgodinez 4:6561c9128c6f 342 }
sgodinez 4:6561c9128c6f 343
sgodinez 4:6561c9128c6f 344 sms.phoneNumber = vSmsParts[2];
sgodinez 4:6561c9128c6f 345 sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5];
sgodinez 4:6561c9128c6f 346
sgodinez 8:3fe68d6130a8 347 if(pos == std::string::npos) {
sgodinez 9:5b12c5a8dde4 348 printf("[WARNING] Expected SMS body. SMS[%d]. Leaving ...\n", smsNumber);
sgodinez 8:3fe68d6130a8 349 break;
sgodinez 8:3fe68d6130a8 350 }
sgodinez 9:5b12c5a8dde4 351 //Check for the start of the next SMS message
sgodinez 9:5b12c5a8dde4 352 size_t bodyEnd = received.find("\r\n+CMGL: ", pos);
sgodinez 8:3fe68d6130a8 353 if(bodyEnd == std::string::npos) {
sgodinez 9:5b12c5a8dde4 354 //printf("[DEBUG] Parsing Last SMS. SMS[%d]\n", smsNumber);
sgodinez 9:5b12c5a8dde4 355 //This must be the last SMS message
sgodinez 9:5b12c5a8dde4 356 bodyEnd = received.find("\r\n\r\nOK", pos);
sgodinez 8:3fe68d6130a8 357 }
sgodinez 9:5b12c5a8dde4 358
sgodinez 9:5b12c5a8dde4 359 //Safety check that we found the boundary of this current SMS message
sgodinez 9:5b12c5a8dde4 360 if(bodyEnd != std::string::npos) {
sgodinez 9:5b12c5a8dde4 361 sms.message = received.substr(pos, bodyEnd - pos);
sgodinez 9:5b12c5a8dde4 362 } else {
sgodinez 8:3fe68d6130a8 363 sms.message = received.substr(pos);
sgodinez 9:5b12c5a8dde4 364 printf("[WARNING] Expected to find end of SMS list. SMS[%d] DATA[%s].\n", smsNumber, sms.message.c_str());
sgodinez 8:3fe68d6130a8 365 }
sgodinez 5:93e889a5abc6 366 vSms.push_back(sms);
sgodinez 4:6561c9128c6f 367 pos = bodyEnd;
sgodinez 9:5b12c5a8dde4 368 //printf("[DEBUG] Parsed SMS[%d]. Starting Next at position [%d]\n", smsNumber, pos);
sgodinez 9:5b12c5a8dde4 369 smsNumber++;
sgodinez 4:6561c9128c6f 370 }
sgodinez 9:5b12c5a8dde4 371 printf("Received %d SMS\n", smsNumber);
sgodinez 4:6561c9128c6f 372 return vSms;
sgodinez 4:6561c9128c6f 373 }
sgodinez 4:6561c9128c6f 374
sgodinez 4:6561c9128c6f 375 Cellular::Code Cellular::deleteOnlyReceivedReadSms() {
sgodinez 4:6561c9128c6f 376 return sendBasicCommand("AT+CMGD=1,1", 1000);
sgodinez 4:6561c9128c6f 377 }
sgodinez 4:6561c9128c6f 378
sgodinez 4:6561c9128c6f 379 Cellular::Code Cellular::deleteAllReceivedSms() {
sgodinez 4:6561c9128c6f 380 return sendBasicCommand("AT+CMGD=1,4", 1000);
sgodinez 4:6561c9128c6f 381 }
sgodinez 4:6561c9128c6f 382
sgodinez 4:6561c9128c6f 383
jengbrecht 0:563b70517320 384 string Cellular::sendCommand(string command, int timeoutMillis, ESC_CHAR esc)
jengbrecht 0:563b70517320 385 {
jengbrecht 0:563b70517320 386 int size = command.size() + 1;
jengbrecht 0:563b70517320 387 char cmd[size];
jengbrecht 0:563b70517320 388 strcpy(cmd, command.c_str());
jengbrecht 0:563b70517320 389 if (esc == CR) {
jengbrecht 0:563b70517320 390 cmd[size -1] = '\r';
jengbrecht 0:563b70517320 391 } else if (esc == CTRL_Z) {
jengbrecht 0:563b70517320 392 cmd[size -1] = 0x1A;
sgodinez 13:0af863114629 393 } else if(esc == NONE) {
sgodinez 13:0af863114629 394 cmd[size -1] = '\0';
jengbrecht 0:563b70517320 395 }
jengbrecht 0:563b70517320 396
sgodinez 4:6561c9128c6f 397 io.rxClear();
sgodinez 4:6561c9128c6f 398 io.txClear();
sgodinez 8:3fe68d6130a8 399 std::string result;
sgodinez 4:6561c9128c6f 400 int status = io.write(cmd, size);
sgodinez 4:6561c9128c6f 401 int available = io.rxAvailable();
jengbrecht 0:563b70517320 402 int previous = -1;
jengbrecht 0:563b70517320 403 int timer = 0;
sgodinez 8:3fe68d6130a8 404 char tmp[256];
sgodinez 8:3fe68d6130a8 405 tmp[255] = 0;
sgodinez 13:0af863114629 406 bool started = !echoMode;
sgodinez 13:0af863114629 407 bool done = false;
sgodinez 8:3fe68d6130a8 408 do {
jengbrecht 0:563b70517320 409 wait(.1);
jengbrecht 0:563b70517320 410 timer = timer + 100;
jengbrecht 0:563b70517320 411 previous = available;
sgodinez 4:6561c9128c6f 412 available = io.rxAvailable();
sgodinez 8:3fe68d6130a8 413
sgodinez 8:3fe68d6130a8 414 int size = io.read(tmp,255); //1 less than allocated
sgodinez 8:3fe68d6130a8 415 if(size > 0) {
sgodinez 8:3fe68d6130a8 416 result.append(tmp, size);
sgodinez 8:3fe68d6130a8 417 }
sgodinez 13:0af863114629 418
sgodinez 13:0af863114629 419 if(!started) {
sgodinez 13:0af863114629 420 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
sgodinez 13:0af863114629 421 if(result.size() > command.size() + 2) {
sgodinez 13:0af863114629 422 started = true;
sgodinez 13:0af863114629 423 }
sgodinez 13:0af863114629 424 } else {
sgodinez 13:0af863114629 425 done = (available == previous);
sgodinez 13:0af863114629 426 }
sgodinez 13:0af863114629 427 if(timer >= timeoutMillis) {
sgodinez 13:0af863114629 428 printf("[WARNING] sendCommand timed out after %d milliseconds\n", timeoutMillis);
sgodinez 13:0af863114629 429 done = true;
sgodinez 13:0af863114629 430 }
sgodinez 13:0af863114629 431 } while (!done);
sgodinez 8:3fe68d6130a8 432
sgodinez 8:3fe68d6130a8 433 return result;
jengbrecht 0:563b70517320 434 }
jengbrecht 0:563b70517320 435
jengbrecht 0:563b70517320 436 #endif /* CELLULAR_CPP */