Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems

Dependents:   mtsas mtsas mtsas mtsas

Committer:
Vanger
Date:
Mon Aug 11 16:03:19 2014 +0000
Revision:
52:2cb58398a4f9
Parent:
51:ffc556ba33f7
Child:
55:85c04afa939a
Removed parse response '>' from sendCommand() under Cellular.cpp, changed sendSMS() to verify sending SMS message under Cellular.cpp, changed disconnect() to have better flow under EasyIP.cpp, changed isConnected() to be simpler under EasyIP.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike Fiore 4:1f63354b8d1b 1 #include "mbed.h"
Mike Fiore 1:f155d94d6f3a 2 #include "Cellular.h"
Mike Fiore 1:f155d94d6f3a 3 #include "MTSText.h"
Mike Fiore 4:1f63354b8d1b 4 #include "MTSLog.h"
Mike Fiore 1:f155d94d6f3a 5
Mike Fiore 1:f155d94d6f3a 6 using namespace mts;
Mike Fiore 1:f155d94d6f3a 7
Mike Fiore 8:2d7259d244d1 8 bool Cellular::init(MTSBufferedIO* io)
Mike Fiore 8:2d7259d244d1 9 {
Mike Fiore 8:2d7259d244d1 10 if (io == NULL) {
Mike Fiore 8:2d7259d244d1 11 return false;
Mike Fiore 8:2d7259d244d1 12 }
Mike Fiore 8:2d7259d244d1 13 this->io = io;
Mike Fiore 8:2d7259d244d1 14
Mike Fiore 8:2d7259d244d1 15 return true;
Mike Fiore 8:2d7259d244d1 16 }
Mike Fiore 8:2d7259d244d1 17
Mike Fiore 9:1a03e3f3e7fe 18 bool Cellular::configureSignals(unsigned int DCD, unsigned int DTR, unsigned int RESET)
Mike Fiore 9:1a03e3f3e7fe 19 {
Mike Fiore 9:1a03e3f3e7fe 20 //Set DCD - The radio will raise and lower this line
Mike Fiore 9:1a03e3f3e7fe 21 if (DCD != NC) {
Mike Fiore 9:1a03e3f3e7fe 22 dcd = new DigitalIn(PinName(DCD));
Mike Fiore 9:1a03e3f3e7fe 23 }
Mike Fiore 9:1a03e3f3e7fe 24 /* Set DTR - This line should be lowered when we want to talk to the radio and raised when we're done
Mike Fiore 9:1a03e3f3e7fe 25 * for now we will lower it in the constructor and raise it in the destructor.
Mike Fiore 9:1a03e3f3e7fe 26 */
Mike Fiore 9:1a03e3f3e7fe 27 if (DTR != NC) {
Mike Fiore 9:1a03e3f3e7fe 28 dtr = new DigitalOut(PinName(DTR));
Mike Fiore 9:1a03e3f3e7fe 29 dtr->write(0);
Mike Fiore 9:1a03e3f3e7fe 30 }
Mike Fiore 9:1a03e3f3e7fe 31 //Set RESET - Set the hardware reset line to the radio
Mike Fiore 9:1a03e3f3e7fe 32 if (RESET != NC) {
Mike Fiore 9:1a03e3f3e7fe 33 resetLine = new DigitalOut(PinName(RESET));
Mike Fiore 9:1a03e3f3e7fe 34 }
Mike Fiore 9:1a03e3f3e7fe 35 return true;
Mike Fiore 9:1a03e3f3e7fe 36 }
Mike Fiore 9:1a03e3f3e7fe 37
Mike Fiore 1:f155d94d6f3a 38 std::string Cellular::getRegistrationNames(Registration registration)
Mike Fiore 1:f155d94d6f3a 39 {
Mike Fiore 1:f155d94d6f3a 40 switch(registration) {
Mike Fiore 1:f155d94d6f3a 41 case NOT_REGISTERED:
Mike Fiore 1:f155d94d6f3a 42 return "NOT_REGISTERED";
Mike Fiore 1:f155d94d6f3a 43 case REGISTERED:
Mike Fiore 1:f155d94d6f3a 44 return "REGISTERED";
Mike Fiore 1:f155d94d6f3a 45 case SEARCHING:
Mike Fiore 1:f155d94d6f3a 46 return "SEARCHING";
Mike Fiore 1:f155d94d6f3a 47 case DENIED:
Mike Fiore 1:f155d94d6f3a 48 return "DENIED";
Mike Fiore 1:f155d94d6f3a 49 case UNKNOWN:
Mike Fiore 1:f155d94d6f3a 50 return "UNKNOWN";
Mike Fiore 1:f155d94d6f3a 51 case ROAMING:
Mike Fiore 1:f155d94d6f3a 52 return "ROAMING";
Mike Fiore 1:f155d94d6f3a 53 default:
Mike Fiore 1:f155d94d6f3a 54 return "UNKNOWN ENUM";
Mike Fiore 1:f155d94d6f3a 55 }
Mike Fiore 1:f155d94d6f3a 56 }
Mike Fiore 1:f155d94d6f3a 57
Mike Fiore 11:4e428f689069 58 std::string Cellular::getRadioNames(Radio radio) {
Mike Fiore 11:4e428f689069 59 switch(radio) {
Mike Fiore 11:4e428f689069 60 case MTSMC_H5:
Mike Fiore 11:4e428f689069 61 return "MTSMC-H5";
Mike Fiore 11:4e428f689069 62 case MTSMC_EV3:
Mike Fiore 11:4e428f689069 63 return "MTSMC-EV3";
Mike Fiore 11:4e428f689069 64 case MTSMC_G3:
Mike Fiore 11:4e428f689069 65 return "MTSMC-G3";
Mike Fiore 11:4e428f689069 66 case MTSMC_C2:
Mike Fiore 11:4e428f689069 67 return "MTSMC-C2";
Mike Fiore 11:4e428f689069 68 case MTSMC_H5_IP:
Mike Fiore 11:4e428f689069 69 return "MTSMC-H5-IP";
Mike Fiore 11:4e428f689069 70 case MTSMC_EV3_IP:
Mike Fiore 11:4e428f689069 71 return "MTSMC-EV3-IP";
Mike Fiore 11:4e428f689069 72 case MTSMC_C2_IP:
Mike Fiore 11:4e428f689069 73 return "MTSMC-C2-IP";
Mike Fiore 11:4e428f689069 74 default:
Mike Fiore 11:4e428f689069 75 return "UNKNOWN ENUM";
Mike Fiore 11:4e428f689069 76 }
Mike Fiore 11:4e428f689069 77 }
Mike Fiore 11:4e428f689069 78
Mike Fiore 1:f155d94d6f3a 79 Code Cellular::test()
Mike Fiore 1:f155d94d6f3a 80 {
Mike Fiore 1:f155d94d6f3a 81 int i = 0;
mfiore 18:fa0d8120f81f 82 while (sendBasicCommand("AT", 1000) != MTS_SUCCESS) {
Mike Fiore 1:f155d94d6f3a 83 i++;
Mike Fiore 1:f155d94d6f3a 84 if (i >= 30) {
Mike Fiore 4:1f63354b8d1b 85 logError("Could not talk to radio after 30 tries");
Mike Fiore 1:f155d94d6f3a 86 i = 0;
Mike Fiore 1:f155d94d6f3a 87 }
Mike Fiore 1:f155d94d6f3a 88 wait(1);
Mike Fiore 1:f155d94d6f3a 89 }
mfiore 18:fa0d8120f81f 90 return MTS_SUCCESS;
Mike Fiore 1:f155d94d6f3a 91 }
Mike Fiore 1:f155d94d6f3a 92
Mike Fiore 1:f155d94d6f3a 93 int Cellular::getSignalStrength()
Mike Fiore 1:f155d94d6f3a 94 {
Mike Fiore 1:f155d94d6f3a 95 string response = sendCommand("AT+CSQ", 1000);
Mike Fiore 1:f155d94d6f3a 96 if (response.find("OK") == string::npos) {
Mike Fiore 1:f155d94d6f3a 97 return -1;
Mike Fiore 1:f155d94d6f3a 98 }
Mike Fiore 1:f155d94d6f3a 99 int start = response.find(':');
Mike Fiore 1:f155d94d6f3a 100 int stop = response.find(',', start);
Mike Fiore 1:f155d94d6f3a 101 string signal = response.substr(start + 2, stop - start - 2);
Mike Fiore 1:f155d94d6f3a 102 int value;
Mike Fiore 1:f155d94d6f3a 103 sscanf(signal.c_str(), "%d", &value);
Mike Fiore 1:f155d94d6f3a 104 return value;
Mike Fiore 1:f155d94d6f3a 105 }
Mike Fiore 1:f155d94d6f3a 106
Mike Fiore 1:f155d94d6f3a 107 Cellular::Registration Cellular::getRegistration()
Mike Fiore 1:f155d94d6f3a 108 {
Mike Fiore 1:f155d94d6f3a 109 string response = sendCommand("AT+CREG?", 5000);
Mike Fiore 1:f155d94d6f3a 110 if (response.find("OK") == string::npos) {
Mike Fiore 1:f155d94d6f3a 111 return UNKNOWN;
Mike Fiore 1:f155d94d6f3a 112 }
Mike Fiore 1:f155d94d6f3a 113 int start = response.find(',');
Mike Fiore 1:f155d94d6f3a 114 int stop = response.find(' ', start);
Mike Fiore 1:f155d94d6f3a 115 string regStat = response.substr(start + 1, stop - start - 1);
Mike Fiore 1:f155d94d6f3a 116 int value;
Mike Fiore 1:f155d94d6f3a 117 sscanf(regStat.c_str(), "%d", &value);
Mike Fiore 1:f155d94d6f3a 118 switch (value) {
Mike Fiore 1:f155d94d6f3a 119 case 0:
Mike Fiore 1:f155d94d6f3a 120 return NOT_REGISTERED;
Mike Fiore 1:f155d94d6f3a 121 case 1:
Mike Fiore 1:f155d94d6f3a 122 return REGISTERED;
Mike Fiore 1:f155d94d6f3a 123 case 2:
Mike Fiore 1:f155d94d6f3a 124 return SEARCHING;
Mike Fiore 1:f155d94d6f3a 125 case 3:
Mike Fiore 1:f155d94d6f3a 126 return DENIED;
Mike Fiore 1:f155d94d6f3a 127 case 4:
Mike Fiore 1:f155d94d6f3a 128 return UNKNOWN;
Mike Fiore 1:f155d94d6f3a 129 case 5:
Mike Fiore 1:f155d94d6f3a 130 return ROAMING;
Mike Fiore 1:f155d94d6f3a 131 }
Mike Fiore 1:f155d94d6f3a 132 return UNKNOWN;
Mike Fiore 1:f155d94d6f3a 133 }
Mike Fiore 7:0ee8e69a3e9c 134
Mike Fiore 8:2d7259d244d1 135 Code Cellular::setDns(const std::string& primary, const std::string& secondary)
Mike Fiore 8:2d7259d244d1 136 {
Mike Fiore 8:2d7259d244d1 137 return sendBasicCommand("AT#DNS=1," + primary + "," + secondary, 1000);
Mike Fiore 8:2d7259d244d1 138 }
Mike Fiore 8:2d7259d244d1 139
Mike Fiore 7:0ee8e69a3e9c 140 Code Cellular::sendSMS(const Sms& sms)
Mike Fiore 7:0ee8e69a3e9c 141 {
Mike Fiore 7:0ee8e69a3e9c 142 return sendSMS(sms.phoneNumber, sms.message);
Mike Fiore 7:0ee8e69a3e9c 143 }
Mike Fiore 7:0ee8e69a3e9c 144
Mike Fiore 10:c188cc05aed5 145 Code Cellular::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc)
Mike Fiore 10:c188cc05aed5 146 {
Mike Fiore 10:c188cc05aed5 147 if(socketOpened) {
Mike Fiore 10:c188cc05aed5 148 logError("socket is open. Can not send AT commands");
mfiore 18:fa0d8120f81f 149 return MTS_ERROR;
Mike Fiore 10:c188cc05aed5 150 }
Mike Fiore 10:c188cc05aed5 151
Mike Fiore 10:c188cc05aed5 152 string response = sendCommand(command, timeoutMillis, esc);
Mike Fiore 10:c188cc05aed5 153 if (response.size() == 0) {
mfiore 18:fa0d8120f81f 154 return MTS_NO_RESPONSE;
Mike Fiore 10:c188cc05aed5 155 } else if (response.find("OK") != string::npos) {
mfiore 18:fa0d8120f81f 156 return MTS_SUCCESS;
Mike Fiore 10:c188cc05aed5 157 } else if (response.find("ERROR") != string::npos) {
mfiore 18:fa0d8120f81f 158 return MTS_ERROR;
Mike Fiore 10:c188cc05aed5 159 } else {
mfiore 18:fa0d8120f81f 160 return MTS_FAILURE;
Mike Fiore 10:c188cc05aed5 161 }
Mike Fiore 10:c188cc05aed5 162 }
Mike Fiore 10:c188cc05aed5 163
Mike Fiore 10:c188cc05aed5 164 string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
Mike Fiore 10:c188cc05aed5 165 {
Mike Fiore 10:c188cc05aed5 166 if(io == NULL) {
Mike Fiore 10:c188cc05aed5 167 logError("MTSBufferedIO not set");
Mike Fiore 10:c188cc05aed5 168 return "";
Mike Fiore 10:c188cc05aed5 169 }
Mike Fiore 10:c188cc05aed5 170 if(socketOpened) {
Mike Fiore 10:c188cc05aed5 171 logError("socket is open. Can not send AT commands");
Mike Fiore 10:c188cc05aed5 172 return "";
Mike Fiore 10:c188cc05aed5 173 }
Mike Fiore 10:c188cc05aed5 174
Mike Fiore 10:c188cc05aed5 175 io->rxClear();
Mike Fiore 10:c188cc05aed5 176 io->txClear();
Mike Fiore 10:c188cc05aed5 177 std::string result;
Mike Fiore 10:c188cc05aed5 178
Mike Fiore 10:c188cc05aed5 179 //Attempt to write command
Mike Fiore 10:c188cc05aed5 180 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
Mike Fiore 10:c188cc05aed5 181 //Failed to write command
Mike Fiore 10:c188cc05aed5 182 if (command != "AT" && command != "at") {
Mike Fiore 10:c188cc05aed5 183 logError("failed to send command to radio within %d milliseconds", timeoutMillis);
Mike Fiore 10:c188cc05aed5 184 }
Mike Fiore 10:c188cc05aed5 185 return "";
Mike Fiore 10:c188cc05aed5 186 }
Mike Fiore 10:c188cc05aed5 187
Mike Fiore 10:c188cc05aed5 188 //Send Escape Character
Mike Fiore 10:c188cc05aed5 189 if (esc != 0x00) {
Mike Fiore 10:c188cc05aed5 190 if(io->write(esc, timeoutMillis) != 1) {
Mike Fiore 10:c188cc05aed5 191 if (command != "AT" && command != "at") {
Mike Fiore 10:c188cc05aed5 192 logError("failed to send character '%c' (0x%02X) to radio within %d milliseconds", esc, esc, timeoutMillis);
Mike Fiore 10:c188cc05aed5 193 }
Mike Fiore 10:c188cc05aed5 194 return "";
Mike Fiore 10:c188cc05aed5 195 }
Mike Fiore 10:c188cc05aed5 196 }
Vanger 41:8b9b5098696f 197 mbed::Timer tmr;
Mike Fiore 10:c188cc05aed5 198 char tmp[256];
Mike Fiore 10:c188cc05aed5 199 tmp[255] = 0;
Mike Fiore 10:c188cc05aed5 200 bool done = false;
Vanger 41:8b9b5098696f 201 tmr.start();
Mike Fiore 10:c188cc05aed5 202 do {
Mike Fiore 10:c188cc05aed5 203 //Make a non-blocking read call by passing timeout of zero
Mike Fiore 10:c188cc05aed5 204 int size = io->read(tmp,255,0); //1 less than allocated (timeout is instant)
Mike Fiore 10:c188cc05aed5 205 if(size > 0) {
Mike Fiore 10:c188cc05aed5 206 result.append(tmp, size);
Mike Fiore 10:c188cc05aed5 207 }
Vanger 41:8b9b5098696f 208
Vanger 45:b9ead235ab7c 209 //Check for a response to signify the completion of the AT command
Vanger 41:8b9b5098696f 210 //OK, ERROR, CONNECT are the 3 most likely responses
Vanger 41:8b9b5098696f 211 if(result.size() > (command.size() + 2)) {
Vanger 52:2cb58398a4f9 212 if(result.find("OK\r\n",command.size()) != std::string::npos) {
Vanger 45:b9ead235ab7c 213 done = true;
Vanger 52:2cb58398a4f9 214 } else if (result.find("ERROR\r\n") != std::string::npos) {
Vanger 45:b9ead235ab7c 215 done = true;
Vanger 52:2cb58398a4f9 216 } else if (result.find("NO CARRIER\r\n") != std::string::npos) {
Vanger 52:2cb58398a4f9 217 done = true;
Vanger 48:3f9d82915e83 218 }
Vanger 48:3f9d82915e83 219
Vanger 45:b9ead235ab7c 220 if(type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_EV3 || type == MTSMC_C2) {
Vanger 52:2cb58398a4f9 221 if (result.find("CONNECT\r\n") != std::string::npos) {
Vanger 45:b9ead235ab7c 222 done = true;
Vanger 45:b9ead235ab7c 223 }
Vanger 45:b9ead235ab7c 224 } else if (type == MTSMC_H5_IP || type == MTSMC_EV3_IP || type == MTSMC_C2_IP) {
Vanger 52:2cb58398a4f9 225 if (result.find("Ok_Info_WaitingForData\r\n") != std::string::npos) {
Vanger 51:ffc556ba33f7 226 done = true;
Vanger 52:2cb58398a4f9 227 } else if (result.find("Ok_Info_SocketClosed\r\n") != std::string::npos) {
Vanger 51:ffc556ba33f7 228 done = true;
Vanger 52:2cb58398a4f9 229 } else if (result.find("Ok_Info_PPP\r\n") != std::string::npos) {
Vanger 51:ffc556ba33f7 230 done = true;
Vanger 52:2cb58398a4f9 231 } else if (result.find("Ok_Info_GprsActivation\r\n") != std::string::npos) {
Vanger 51:ffc556ba33f7 232 done = true;
Vanger 52:2cb58398a4f9 233 } else if (result.find("alive") != std::string::npos) {
Vanger 45:b9ead235ab7c 234 done = true;
Vanger 52:2cb58398a4f9 235 }
Vanger 45:b9ead235ab7c 236 }
Mike Fiore 10:c188cc05aed5 237 }
Vanger 41:8b9b5098696f 238
Vanger 41:8b9b5098696f 239 if(tmr.read_ms() >= timeoutMillis) {
Mike Fiore 10:c188cc05aed5 240 if (command != "AT" && command != "at") {
Mike Fiore 10:c188cc05aed5 241 logWarning("sendCommand [%s] timed out after %d milliseconds", command.c_str(), timeoutMillis);
Mike Fiore 10:c188cc05aed5 242 }
Mike Fiore 10:c188cc05aed5 243 done = true;
Mike Fiore 10:c188cc05aed5 244 }
Mike Fiore 10:c188cc05aed5 245 } while (!done);
Vanger 52:2cb58398a4f9 246
Mike Fiore 10:c188cc05aed5 247 return result;
Mike Fiore 10:c188cc05aed5 248 }
Mike Fiore 10:c188cc05aed5 249
Mike Fiore 7:0ee8e69a3e9c 250 Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message)
Mike Fiore 7:0ee8e69a3e9c 251 {
mfiore 16:1bc3e44d4746 252 string csmp;
mfiore 16:1bc3e44d4746 253
mfiore 16:1bc3e44d4746 254 if (type == MTSMC_H5_IP || type == MTSMC_H5) {
mfiore 16:1bc3e44d4746 255 csmp = "AT+CSMP=17,167,0,0";
mfiore 16:1bc3e44d4746 256 } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2) {
mfiore 16:1bc3e44d4746 257 csmp = "AT+CSMP=,4098,0,2";
mfiore 16:1bc3e44d4746 258 } else if (type == MTSMC_G3) {
mfiore 16:1bc3e44d4746 259 } else {
mfiore 16:1bc3e44d4746 260 logError("unknown radio type [%d]", type);
mfiore 18:fa0d8120f81f 261 return MTS_FAILURE;
mfiore 16:1bc3e44d4746 262 }
mfiore 16:1bc3e44d4746 263
Mike Fiore 7:0ee8e69a3e9c 264 Code code = sendBasicCommand("AT+CMGF=1", 1000);
mfiore 18:fa0d8120f81f 265 if (code != MTS_SUCCESS) {
mfiore 16:1bc3e44d4746 266 logError("CMGF failed");
mfiore 16:1bc3e44d4746 267 return code;
mfiore 16:1bc3e44d4746 268 }
Vanger 52:2cb58398a4f9 269
mfiore 16:1bc3e44d4746 270 code = sendBasicCommand(csmp, 1000);
mfiore 18:fa0d8120f81f 271 if (code != MTS_SUCCESS) {
mfiore 16:1bc3e44d4746 272 logError("CSMP failed [%s]", getRadioNames(type).c_str());
Mike Fiore 7:0ee8e69a3e9c 273 return code;
Mike Fiore 7:0ee8e69a3e9c 274 }
Vanger 52:2cb58398a4f9 275
Vanger 35:257eb41405e1 276 string cmd = "AT+CMGS=\"";
Vanger 38:b2088faa8bfd 277 cmd.append("+");
Mike Fiore 7:0ee8e69a3e9c 278 cmd.append(phoneNumber);
Vanger 36:948d06b3e23c 279 cmd.append("\",145");
mfiore 23:8333593dd86f 280 for (int i = 0; i < 5; i++) {
Vanger 48:3f9d82915e83 281 string response1 = sendCommand(cmd, 2000);
mfiore 23:8333593dd86f 282 if (response1.find('>') != string::npos) {
mfiore 23:8333593dd86f 283 break;
mfiore 23:8333593dd86f 284 }
mfiore 23:8333593dd86f 285 if (i >= 5) {
mfiore 23:8333593dd86f 286 logError("CMGS phone number failed");
mfiore 23:8333593dd86f 287 return MTS_NO_RESPONSE;
mfiore 23:8333593dd86f 288 }
mfiore 23:8333593dd86f 289 wait(1);
Mike Fiore 7:0ee8e69a3e9c 290 }
Mike Fiore 7:0ee8e69a3e9c 291 wait(.2);
Vanger 52:2cb58398a4f9 292
Vanger 52:2cb58398a4f9 293 for (int i = 0; i < 5; i++) {
Vanger 52:2cb58398a4f9 294 string response2 = sendCommand(message, 4000, CTRL_Z);
Vanger 52:2cb58398a4f9 295 if (response2.find("+CMGS:") != string::npos) {
Vanger 52:2cb58398a4f9 296 break;
Vanger 52:2cb58398a4f9 297 }
Vanger 52:2cb58398a4f9 298 if (i >= 5) {
Vanger 52:2cb58398a4f9 299 logError("CMGS message failed");
Vanger 52:2cb58398a4f9 300 return MTS_FAILURE;
Vanger 52:2cb58398a4f9 301 }
Vanger 52:2cb58398a4f9 302 wait(1);
Mike Fiore 7:0ee8e69a3e9c 303 }
mfiore 18:fa0d8120f81f 304 return MTS_SUCCESS;
Mike Fiore 7:0ee8e69a3e9c 305 }
Mike Fiore 7:0ee8e69a3e9c 306
Mike Fiore 7:0ee8e69a3e9c 307 std::vector<Cellular::Sms> Cellular::getReceivedSms()
Mike Fiore 7:0ee8e69a3e9c 308 {
Mike Fiore 7:0ee8e69a3e9c 309 int smsNumber = 0;
Mike Fiore 7:0ee8e69a3e9c 310 std::vector<Sms> vSms;
mfiore 16:1bc3e44d4746 311 std::string received;
mfiore 16:1bc3e44d4746 312 size_t pos;
mfiore 16:1bc3e44d4746 313
mfiore 16:1bc3e44d4746 314 Code code = sendBasicCommand("AT+CMGF=1", 1000);
mfiore 18:fa0d8120f81f 315 if (code != MTS_SUCCESS) {
mfiore 16:1bc3e44d4746 316 logError("CMGF failed");
mfiore 16:1bc3e44d4746 317 return vSms;
mfiore 16:1bc3e44d4746 318 }
mfiore 16:1bc3e44d4746 319
Vanger 35:257eb41405e1 320 received = sendCommand("AT+CMGL=\"ALL\"", 5000);
mfiore 16:1bc3e44d4746 321 pos = received.find("+CMGL: ");
Mike Fiore 7:0ee8e69a3e9c 322
Mike Fiore 7:0ee8e69a3e9c 323 while (pos != std::string::npos) {
Mike Fiore 7:0ee8e69a3e9c 324 Cellular::Sms sms;
Mike Fiore 7:0ee8e69a3e9c 325 std::string line(Text::getLine(received, pos, pos));
Mike Fiore 7:0ee8e69a3e9c 326 if(line.find("+CMGL: ") == std::string::npos) {
Mike Fiore 7:0ee8e69a3e9c 327 continue;
Mike Fiore 7:0ee8e69a3e9c 328 }
Mike Fiore 7:0ee8e69a3e9c 329 //Start of SMS message
Mike Fiore 7:0ee8e69a3e9c 330 std::vector<std::string> vSmsParts = Text::split(line, ',');
mfiore 16:1bc3e44d4746 331 if (type == MTSMC_H5_IP || type == MTSMC_H5) {
mfiore 16:1bc3e44d4746 332 /* format for H5 and H5-IP radios
mfiore 16:1bc3e44d4746 333 * <index>, <status>, <oa>, <alpha>, <scts>
mfiore 16:1bc3e44d4746 334 * scts contains a comma, so splitting on commas should give us 6 items
mfiore 16:1bc3e44d4746 335 */
mfiore 16:1bc3e44d4746 336 if(vSmsParts.size() != 6) {
mfiore 16:1bc3e44d4746 337 logWarning("Expected 5 commas. SMS[%d] DATA[%s]. Continuing ...", smsNumber, line.c_str());
mfiore 16:1bc3e44d4746 338 continue;
mfiore 16:1bc3e44d4746 339 }
mfiore 16:1bc3e44d4746 340
mfiore 16:1bc3e44d4746 341 sms.phoneNumber = vSmsParts[2];
mfiore 16:1bc3e44d4746 342 sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5];
mfiore 16:1bc3e44d4746 343 } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2) {
mfiore 16:1bc3e44d4746 344 /* format for EV3 and EV3-IP radios
mfiore 16:1bc3e44d4746 345 * <index>, <status>, <oa>, <callback>, <date>
mfiore 16:1bc3e44d4746 346 * splitting on commas should give us 5 items
mfiore 16:1bc3e44d4746 347 */
mfiore 16:1bc3e44d4746 348 if(vSmsParts.size() != 5) {
mfiore 16:1bc3e44d4746 349 logWarning("Expected 4 commas. SMS[%d] DATA[%s]. Continuing ...", smsNumber, line.c_str());
mfiore 16:1bc3e44d4746 350 continue;
mfiore 16:1bc3e44d4746 351 }
mfiore 16:1bc3e44d4746 352
mfiore 16:1bc3e44d4746 353 sms.phoneNumber = vSmsParts[2];
mfiore 16:1bc3e44d4746 354 /* timestamp is in a nasty format
mfiore 16:1bc3e44d4746 355 * YYYYMMDDHHMMSS
mfiore 16:1bc3e44d4746 356 * nobody wants to try and decipher that, so format it nicely
mfiore 16:1bc3e44d4746 357 * YY/MM/DD,HH:MM:SS
mfiore 16:1bc3e44d4746 358 */
mfiore 16:1bc3e44d4746 359 string s = vSmsParts[4];
mfiore 16:1bc3e44d4746 360 sms.timestamp = s.substr(2,2) + "/" + s.substr(4,2) + "/" + s.substr(6,2) + ", " + s.substr(8,2) + ":" + s.substr(10,2) + ":" + s.substr(12,2);
Mike Fiore 7:0ee8e69a3e9c 361 }
Mike Fiore 7:0ee8e69a3e9c 362
Mike Fiore 7:0ee8e69a3e9c 363 if(pos == std::string::npos) {
Mike Fiore 7:0ee8e69a3e9c 364 logWarning("Expected SMS body. SMS[%d]. Leaving ...", smsNumber);
Mike Fiore 7:0ee8e69a3e9c 365 break;
Mike Fiore 7:0ee8e69a3e9c 366 }
Mike Fiore 7:0ee8e69a3e9c 367 //Check for the start of the next SMS message
Vanger 48:3f9d82915e83 368 size_t bodyEnd = received.find("\r\n+CMGL:", pos);
Mike Fiore 7:0ee8e69a3e9c 369 if(bodyEnd == std::string::npos) {
Mike Fiore 7:0ee8e69a3e9c 370 //This must be the last SMS message
Mike Fiore 7:0ee8e69a3e9c 371 bodyEnd = received.find("\r\n\r\nOK", pos);
Mike Fiore 7:0ee8e69a3e9c 372 }
Mike Fiore 7:0ee8e69a3e9c 373 //Safety check that we found the boundary of this current SMS message
Mike Fiore 7:0ee8e69a3e9c 374 if(bodyEnd != std::string::npos) {
Mike Fiore 7:0ee8e69a3e9c 375 sms.message = received.substr(pos, bodyEnd - pos);
Mike Fiore 7:0ee8e69a3e9c 376 } else {
Mike Fiore 7:0ee8e69a3e9c 377 sms.message = received.substr(pos);
Mike Fiore 7:0ee8e69a3e9c 378 logWarning("Expected to find end of SMS list. SMS[%d] DATA[%s].", smsNumber, sms.message.c_str());
Mike Fiore 7:0ee8e69a3e9c 379 }
Mike Fiore 7:0ee8e69a3e9c 380 vSms.push_back(sms);
Mike Fiore 7:0ee8e69a3e9c 381 pos = bodyEnd;
Mike Fiore 7:0ee8e69a3e9c 382 smsNumber++;
Mike Fiore 7:0ee8e69a3e9c 383 }
Mike Fiore 7:0ee8e69a3e9c 384 logInfo("Received %d SMS", smsNumber);
Mike Fiore 7:0ee8e69a3e9c 385 return vSms;
Mike Fiore 7:0ee8e69a3e9c 386 }
Mike Fiore 7:0ee8e69a3e9c 387
Mike Fiore 7:0ee8e69a3e9c 388 Code Cellular::deleteOnlyReceivedReadSms()
Mike Fiore 7:0ee8e69a3e9c 389 {
Mike Fiore 7:0ee8e69a3e9c 390 return sendBasicCommand("AT+CMGD=1,1", 1000);
Mike Fiore 7:0ee8e69a3e9c 391 }
Mike Fiore 7:0ee8e69a3e9c 392
Mike Fiore 7:0ee8e69a3e9c 393 Code Cellular::deleteAllReceivedSms()
Mike Fiore 7:0ee8e69a3e9c 394 {
Mike Fiore 7:0ee8e69a3e9c 395 return sendBasicCommand("AT+CMGD=1,4", 1000);
Mike Fiore 7:0ee8e69a3e9c 396 }