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:
Thu Dec 19 21:16:30 2013 +0000
Revision:
41:81d035fb0b6a
Parent:
35:f28acb1be52d
Child:
43:3cacf019ed7d
Added echo client test

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 19:38794784e009 6 #include "MTSSerial.h"
jengbrecht 0:563b70517320 7
sgodinez 19:38794784e009 8 Cellular* Cellular::instance = NULL;
sgodinez 19:38794784e009 9
sgodinez 19:38794784e009 10 Cellular* Cellular::getInstance() {
sgodinez 19:38794784e009 11 if(instance == NULL) {
sgodinez 19:38794784e009 12 instance = new Cellular(NULL);
sgodinez 19:38794784e009 13 }
sgodinez 19:38794784e009 14 return instance;
sgodinez 19:38794784e009 15 }
sgodinez 19:38794784e009 16
sgodinez 19:38794784e009 17
sgodinez 19:38794784e009 18 Cellular* Cellular::getInstance(MTSBufferedIO* io) {
sgodinez 19:38794784e009 19 if(instance == NULL) {
sgodinez 19:38794784e009 20 instance = new Cellular(io);
sgodinez 41:81d035fb0b6a 21 } else {
sgodinez 41:81d035fb0b6a 22 instance->io = io;
sgodinez 19:38794784e009 23 }
sgodinez 19:38794784e009 24 return instance;
sgodinez 19:38794784e009 25 }
sgodinez 19:38794784e009 26
sgodinez 19:38794784e009 27 Cellular::Cellular(MTSBufferedIO* io)
sgodinez 11:134435d8a2d5 28 : io(io)
sgodinez 13:0af863114629 29 , echoMode(true)
sgodinez 11:134435d8a2d5 30 , pppConnected(false)
sgodinez 11:134435d8a2d5 31 , mode(TCP)
sgodinez 11:134435d8a2d5 32 , socketOpened(false)
sgodinez 41:81d035fb0b6a 33 , socketCloseable(true)
sgodinez 11:134435d8a2d5 34 , local_port(0)
sgodinez 11:134435d8a2d5 35 , host_port(0)
jengbrecht 0:563b70517320 36 {
mfiore 29:7408b1bdad37 37 // the radio's DCD signal is mapped to PTA4
mfiore 29:7408b1bdad37 38 // the radio will raise and lower this line
mfiore 29:7408b1bdad37 39 dcd = new DigitalIn(PTA4);
mfiore 29:7408b1bdad37 40 // the DTR line to the radio is mapped PTC9
mfiore 29:7408b1bdad37 41 // this line should be lowered when we want to talk to the radio and raised when we're done
mfiore 29:7408b1bdad37 42 // for now we will lower it in the constructor and raise it in the destructor
mfiore 29:7408b1bdad37 43 dtr = new DigitalOut(PTC9);
mfiore 29:7408b1bdad37 44 dtr->write(0);
jengbrecht 0:563b70517320 45 }
jengbrecht 0:563b70517320 46
jengbrecht 0:563b70517320 47 Cellular::~Cellular()
jengbrecht 0:563b70517320 48 {
mfiore 29:7408b1bdad37 49 dtr->write(1);
jengbrecht 0:563b70517320 50 }
jengbrecht 0:563b70517320 51
sgodinez 11:134435d8a2d5 52 bool Cellular::connect() {
sgodinez 13:0af863114629 53 //Check if socket is open
sgodinez 13:0af863114629 54 if(socketOpened) {
sgodinez 13:0af863114629 55 return true;
sgodinez 13:0af863114629 56 }
sgodinez 13:0af863114629 57
sgodinez 11:134435d8a2d5 58 //Run Test first to validate a good state
sgodinez 13:0af863114629 59 if(isConnected()) {
sgodinez 13:0af863114629 60 return true;
sgodinez 13:0af863114629 61 }
sgodinez 13:0af863114629 62
sgodinez 11:134435d8a2d5 63 //Check RSSI: AT+CSQ
sgodinez 13:0af863114629 64 int rssi = getSignalStrength();
sgodinez 17:2d7c4ea7491b 65 printf("[DEBUG] Signal strength: %d\r\n", rssi);
sgodinez 13:0af863114629 66
sgodinez 11:134435d8a2d5 67 //Check Registration: AT+CREG? == 0,1
sgodinez 13:0af863114629 68 Registration registration = getRegistration();
sgodinez 13:0af863114629 69 if(registration != REGISTERED) {
sgodinez 17:2d7c4ea7491b 70 printf("[WARNING] Not Registered [%d]\r\n", (int)registration);
sgodinez 13:0af863114629 71 }
sgodinez 11:134435d8a2d5 72
sgodinez 11:134435d8a2d5 73 //AT#CONNECTIONSTART: Make a PPP connection
sgodinez 17:2d7c4ea7491b 74 printf("[DEBUG] Making PPP Connection Attempt. APN[%s]\r\n", apn.c_str());
sgodinez 13:0af863114629 75 std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
sgodinez 17:2d7c4ea7491b 76 std::vector<std::string> parts = Text::split(pppResult, "\r\n");
sgodinez 13:0af863114629 77
sgodinez 17:2d7c4ea7491b 78 //printf("[DEBUG] PPP CONNECT RESULT [%s]\r\n", pppResult.c_str());
sgodinez 17:2d7c4ea7491b 79 // for(uint32_t i = 0; i < parts.size(); i++) {
sgodinez 17:2d7c4ea7491b 80 // printf("[%d] [%s]\r\n", i, parts[i].c_str());
sgodinez 17:2d7c4ea7491b 81 // }
sgodinez 13:0af863114629 82
sgodinez 13:0af863114629 83 if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
sgodinez 13:0af863114629 84 if(parts.size() >= 2) {
sgodinez 13:0af863114629 85 local_address = parts[1];
sgodinez 13:0af863114629 86 }
sgodinez 17:2d7c4ea7491b 87 printf("[INFO] PPP Connection Established: IP[%s]\r\n", local_address.c_str());
sgodinez 13:0af863114629 88 pppConnected = true;
sgodinez 13:0af863114629 89
sgodinez 13:0af863114629 90 } else {
sgodinez 13:0af863114629 91 pppConnected = false;
sgodinez 13:0af863114629 92 }
sgodinez 11:134435d8a2d5 93
sgodinez 13:0af863114629 94 return pppConnected;
sgodinez 11:134435d8a2d5 95 }
sgodinez 11:134435d8a2d5 96
sgodinez 11:134435d8a2d5 97 void Cellular::disconnect() {
sgodinez 17:2d7c4ea7491b 98 //AT#CONNECTIONSTOP: Close a PPP connection
sgodinez 17:2d7c4ea7491b 99 printf("[DEBUG] Closing PPP Connection\r\n");
sgodinez 11:134435d8a2d5 100
sgodinez 17:2d7c4ea7491b 101 if(socketOpened) {
sgodinez 17:2d7c4ea7491b 102 close();
sgodinez 17:2d7c4ea7491b 103 }
sgodinez 17:2d7c4ea7491b 104
sgodinez 17:2d7c4ea7491b 105 Code code = sendBasicCommand("AT#CONNECTIONSTOP", 10000);
sgodinez 17:2d7c4ea7491b 106 if(code == OK) {
sgodinez 17:2d7c4ea7491b 107 printf("[DEBUG] Successfully closed PPP Connection\r\n");
sgodinez 17:2d7c4ea7491b 108 } else {
sgodinez 17:2d7c4ea7491b 109 printf("[ERROR] Closing PPP Connection [%d]. Continuing ...\r\n", (int)code);
sgodinez 17:2d7c4ea7491b 110 }
sgodinez 17:2d7c4ea7491b 111
sgodinez 17:2d7c4ea7491b 112 pppConnected = false;
sgodinez 11:134435d8a2d5 113 }
sgodinez 11:134435d8a2d5 114
sgodinez 11:134435d8a2d5 115 bool Cellular::isConnected() {
sgodinez 11:134435d8a2d5 116 //1) Check if APN was set
sgodinez 11:134435d8a2d5 117 if(apn.size() == 0) {
sgodinez 17:2d7c4ea7491b 118 printf("[DEBUG] APN is not set\r\n");
sgodinez 11:134435d8a2d5 119 return false;
sgodinez 11:134435d8a2d5 120 }
sgodinez 11:134435d8a2d5 121
sgodinez 11:134435d8a2d5 122 //1) Check that we do not have a live connection up
sgodinez 11:134435d8a2d5 123 if(socketOpened) {
sgodinez 17:2d7c4ea7491b 124 printf("[DEBUG] Socket is opened\r\n");
sgodinez 11:134435d8a2d5 125 return true;
sgodinez 11:134435d8a2d5 126 }
sgodinez 11:134435d8a2d5 127 //2) Query the radio
sgodinez 11:134435d8a2d5 128 pppConnected = false;
sgodinez 11:134435d8a2d5 129 std::string result = sendCommand("AT#VSTATE", 1000);
sgodinez 11:134435d8a2d5 130 if(result.find("CONNECTED") != std::string::npos) {
sgodinez 11:134435d8a2d5 131 pppConnected = true;
sgodinez 11:134435d8a2d5 132 }
sgodinez 11:134435d8a2d5 133
sgodinez 11:134435d8a2d5 134 return pppConnected;
sgodinez 11:134435d8a2d5 135 }
sgodinez 11:134435d8a2d5 136
sgodinez 11:134435d8a2d5 137 bool Cellular::bind(unsigned int port) {
sgodinez 11:134435d8a2d5 138 return false;
sgodinez 11:134435d8a2d5 139 }
sgodinez 11:134435d8a2d5 140
sgodinez 11:134435d8a2d5 141 bool Cellular::open(const std::string& address, unsigned int port, Mode mode) {
sgodinez 17:2d7c4ea7491b 142 char buffer[256] = {0};
sgodinez 11:134435d8a2d5 143 Code portCode, addressCode;
sgodinez 17:2d7c4ea7491b 144 printf("[DEBUG] Attempting to Open Socket\r\n");
sgodinez 11:134435d8a2d5 145
sgodinez 11:134435d8a2d5 146 //1) Check that we do not have a live connection up
sgodinez 11:134435d8a2d5 147 if(socketOpened) {
sgodinez 41:81d035fb0b6a 148 //Check that the address, port, and mode match
sgodinez 41:81d035fb0b6a 149 if(host_address != address || host_port != port || this->mode != mode) {
sgodinez 41:81d035fb0b6a 150 if(this->mode == TCP) {
sgodinez 41:81d035fb0b6a 151 printf("[ERROR] TCP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
sgodinez 41:81d035fb0b6a 152 } else {
sgodinez 41:81d035fb0b6a 153 printf("[ERROR] UDP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
sgodinez 41:81d035fb0b6a 154 }
sgodinez 41:81d035fb0b6a 155 return false;
sgodinez 41:81d035fb0b6a 156 }
sgodinez 41:81d035fb0b6a 157
sgodinez 17:2d7c4ea7491b 158 printf("[DEBUG] Socket already opened\r\n");
sgodinez 11:134435d8a2d5 159 return true;
sgodinez 11:134435d8a2d5 160 }
sgodinez 11:134435d8a2d5 161
sgodinez 11:134435d8a2d5 162 //2) Check PPP connection
sgodinez 11:134435d8a2d5 163 if(!isConnected()) {
sgodinez 17:2d7c4ea7491b 164 printf("[ERROR] PPP not established. Attempting to connect\r\n");
sgodinez 11:134435d8a2d5 165 if(!connect()) {
sgodinez 17:2d7c4ea7491b 166 printf("[ERROR] PPP connection failed\r\n");
sgodinez 11:134435d8a2d5 167 return false;
sgodinez 11:134435d8a2d5 168 } else {
sgodinez 17:2d7c4ea7491b 169 printf("[DEBUG] PPP connection established\r\n");
sgodinez 11:134435d8a2d5 170 }
sgodinez 11:134435d8a2d5 171 }
sgodinez 11:134435d8a2d5 172
sgodinez 17:2d7c4ea7491b 173 ////Setup IP Connection
sgodinez 11:134435d8a2d5 174 if(mode == TCP) {
sgodinez 17:2d7c4ea7491b 175 if(socketCloseable) {
sgodinez 17:2d7c4ea7491b 176 Code code = sendBasicCommand("AT#DLEMODE=1,0", 1000);
sgodinez 17:2d7c4ea7491b 177 if(code != OK) {
sgodinez 17:2d7c4ea7491b 178 printf("[WARNING] Unable to set socket closeable [%d]\r\n", (int) code);
sgodinez 17:2d7c4ea7491b 179 }
sgodinez 17:2d7c4ea7491b 180 }
sgodinez 17:2d7c4ea7491b 181 sprintf(buffer, "AT#TCPPORT=1,%d", port);
sgodinez 17:2d7c4ea7491b 182 portCode = sendBasicCommand(buffer, 1000);
sgodinez 17:2d7c4ea7491b 183 addressCode = sendBasicCommand("AT#TCPSERV=1,\"" + address + "\"", 1000);
sgodinez 11:134435d8a2d5 184 } else {
sgodinez 17:2d7c4ea7491b 185 if(socketCloseable) {
sgodinez 17:2d7c4ea7491b 186 Code code = sendBasicCommand("AT#UDPDLEMODE=1", 1000);
sgodinez 17:2d7c4ea7491b 187 if(code != OK) {
sgodinez 17:2d7c4ea7491b 188 printf("[WARNING] Unable to set socket closeable [%d]\r\n", (int) code);
sgodinez 17:2d7c4ea7491b 189 }
sgodinez 17:2d7c4ea7491b 190 }
sgodinez 17:2d7c4ea7491b 191 sprintf(buffer, "AT#UDPPORT=1,%d", port);
sgodinez 17:2d7c4ea7491b 192 portCode = sendBasicCommand(buffer, 1000);
sgodinez 17:2d7c4ea7491b 193 addressCode = sendBasicCommand("AT#UDPSERV=1,\"" + address + "\"", 1000);
sgodinez 11:134435d8a2d5 194 }
sgodinez 11:134435d8a2d5 195
sgodinez 11:134435d8a2d5 196 if(portCode == OK) {
sgodinez 11:134435d8a2d5 197 host_port = port;
sgodinez 11:134435d8a2d5 198 } else {
sgodinez 17:2d7c4ea7491b 199 printf("[ERROR] Host port could not be set\r\n");
sgodinez 11:134435d8a2d5 200 }
sgodinez 11:134435d8a2d5 201
sgodinez 11:134435d8a2d5 202 if(addressCode == OK) {
sgodinez 11:134435d8a2d5 203 host_address = address;
sgodinez 11:134435d8a2d5 204 } else {
sgodinez 17:2d7c4ea7491b 205 printf("[ERROR] Host address could not be set\r\n");
sgodinez 11:134435d8a2d5 206 }
sgodinez 11:134435d8a2d5 207
sgodinez 13:0af863114629 208 // Try and Connect
sgodinez 13:0af863114629 209 string response = sendCommand("AT#OTCP=1", 30000);
sgodinez 13:0af863114629 210 if (response.find("Ok_Info_WaitingForData") != string::npos) {
sgodinez 17:2d7c4ea7491b 211 printf("[INFO] Opened TCP Socket [%s:%d]\r\n", address.c_str(), port);
sgodinez 13:0af863114629 212 socketOpened = true;
sgodinez 13:0af863114629 213 } else {
sgodinez 17:2d7c4ea7491b 214 printf("[WARNING] Unable to open TCP Socket [%s:%d]\r\n", address.c_str(), port);
sgodinez 13:0af863114629 215 socketOpened = false;
sgodinez 13:0af863114629 216 }
sgodinez 11:134435d8a2d5 217
sgodinez 13:0af863114629 218 return socketOpened;
sgodinez 11:134435d8a2d5 219 }
sgodinez 11:134435d8a2d5 220
sgodinez 11:134435d8a2d5 221 bool Cellular::isOpen() {
sgodinez 17:2d7c4ea7491b 222 return socketOpened;
sgodinez 11:134435d8a2d5 223 }
sgodinez 11:134435d8a2d5 224
sgodinez 17:2d7c4ea7491b 225 bool Cellular::close() {
sgodinez 35:f28acb1be52d 226 if(io == NULL) {
sgodinez 35:f28acb1be52d 227 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 17:2d7c4ea7491b 228 return false;
sgodinez 13:0af863114629 229 }
sgodinez 35:f28acb1be52d 230
sgodinez 35:f28acb1be52d 231 if(!socketOpened) {
sgodinez 35:f28acb1be52d 232 printf("[WARNING] Socket close() called, but socket was not open\r\n");
sgodinez 35:f28acb1be52d 233 return true;
sgodinez 35:f28acb1be52d 234 }
sgodinez 35:f28acb1be52d 235
sgodinez 17:2d7c4ea7491b 236 if(!socketCloseable) {
sgodinez 17:2d7c4ea7491b 237 printf("[ERROR] Socket is not closeable\r\n");
sgodinez 17:2d7c4ea7491b 238 return false;
sgodinez 17:2d7c4ea7491b 239 }
sgodinez 17:2d7c4ea7491b 240
sgodinez 35:f28acb1be52d 241 Timer tmr;
sgodinez 35:f28acb1be52d 242 int timeout = 1000;
sgodinez 35:f28acb1be52d 243 int written = 0;
sgodinez 35:f28acb1be52d 244 tmr.start();
sgodinez 35:f28acb1be52d 245 do {
sgodinez 35:f28acb1be52d 246 written = io->write(ETX);
sgodinez 35:f28acb1be52d 247 if(written < 0) {
sgodinez 35:f28acb1be52d 248 printf("[ERROR] Failed to write to MTSBufferedIO\r\n");
sgodinez 35:f28acb1be52d 249 return false;
sgodinez 35:f28acb1be52d 250 }
sgodinez 35:f28acb1be52d 251 wait(0.05);
sgodinez 35:f28acb1be52d 252 } while(tmr.read_ms() <= timeout && written != 1);
sgodinez 35:f28acb1be52d 253
sgodinez 35:f28acb1be52d 254 if(written != 1) {
sgodinez 35:f28acb1be52d 255 printf("[ERROR] Timed out attempting to close socket\r\n");
sgodinez 17:2d7c4ea7491b 256 return false;
sgodinez 13:0af863114629 257 }
sgodinez 35:f28acb1be52d 258
sgodinez 17:2d7c4ea7491b 259 socketOpened = false;
sgodinez 17:2d7c4ea7491b 260 return true;
sgodinez 11:134435d8a2d5 261 }
sgodinez 11:134435d8a2d5 262
sgodinez 11:134435d8a2d5 263 int Cellular::read(char* data, int max, int timeout) {
sgodinez 19:38794784e009 264 if(io == NULL) {
sgodinez 19:38794784e009 265 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 19:38794784e009 266 return -1;
sgodinez 19:38794784e009 267 }
sgodinez 19:38794784e009 268
sgodinez 17:2d7c4ea7491b 269 if(!socketOpened) {
sgodinez 17:2d7c4ea7491b 270 printf("[ERROR] Socket is not open\r\n");
sgodinez 17:2d7c4ea7491b 271 return -1;
sgodinez 17:2d7c4ea7491b 272 }
sgodinez 17:2d7c4ea7491b 273 int bytesRead = 0;
sgodinez 32:629e6b1c8e22 274
sgodinez 17:2d7c4ea7491b 275 if(timeout >= 0) {
sgodinez 17:2d7c4ea7491b 276 Timer tmr;
sgodinez 17:2d7c4ea7491b 277 tmr.start();
sgodinez 35:f28acb1be52d 278 do {
sgodinez 32:629e6b1c8e22 279 int available = io->readable();
sgodinez 32:629e6b1c8e22 280 if (available > 0) {
sgodinez 32:629e6b1c8e22 281 int size = MIN(available, max - bytesRead);
sgodinez 32:629e6b1c8e22 282 bytesRead += io->read(&data[bytesRead], size);
sgodinez 17:2d7c4ea7491b 283 } else {
sgodinez 17:2d7c4ea7491b 284 wait(0.05);
sgodinez 17:2d7c4ea7491b 285 }
sgodinez 35:f28acb1be52d 286 } while (tmr.read_ms() <= timeout && bytesRead < max);
sgodinez 17:2d7c4ea7491b 287 } else {
sgodinez 19:38794784e009 288 bytesRead = io->read(data, max);
sgodinez 17:2d7c4ea7491b 289 }
sgodinez 17:2d7c4ea7491b 290
sgodinez 32:629e6b1c8e22 291 if(bytesRead > 0 && socketCloseable) {
sgodinez 32:629e6b1c8e22 292 //Remove escape characters
sgodinez 32:629e6b1c8e22 293 int index = 0;
sgodinez 32:629e6b1c8e22 294 bool escapeFlag = false;
sgodinez 32:629e6b1c8e22 295 for(int i = 0; i < bytesRead; i++) {
sgodinez 32:629e6b1c8e22 296 if(data[i] == DLE || data[i] == ETX) {
sgodinez 32:629e6b1c8e22 297 if(escapeFlag == true) {
sgodinez 32:629e6b1c8e22 298 //This character has been escaped
sgodinez 32:629e6b1c8e22 299 escapeFlag = false;
sgodinez 32:629e6b1c8e22 300 } else if(data[bytesRead] == DLE) {
sgodinez 32:629e6b1c8e22 301 //Found escape character
sgodinez 32:629e6b1c8e22 302 escapeFlag = true;
sgodinez 32:629e6b1c8e22 303 continue;
sgodinez 32:629e6b1c8e22 304 } else {
sgodinez 32:629e6b1c8e22 305 //ETX sent without escape -> Socket closed
sgodinez 32:629e6b1c8e22 306 printf("[INFO] Read ETX character without DLE escape. Socket closed\r\n");
sgodinez 32:629e6b1c8e22 307 socketOpened = false;
sgodinez 32:629e6b1c8e22 308 continue;
sgodinez 32:629e6b1c8e22 309 }
sgodinez 32:629e6b1c8e22 310 }
sgodinez 32:629e6b1c8e22 311
sgodinez 32:629e6b1c8e22 312 if(index != i) {
sgodinez 32:629e6b1c8e22 313 data[index] = data[i];
sgodinez 32:629e6b1c8e22 314 }
sgodinez 32:629e6b1c8e22 315 index++;
sgodinez 32:629e6b1c8e22 316 }
sgodinez 32:629e6b1c8e22 317 bytesRead = index;
sgodinez 32:629e6b1c8e22 318 }
sgodinez 32:629e6b1c8e22 319
sgodinez 32:629e6b1c8e22 320 printf("[DEBUG] Scanning received data for socket closed message\r\n");
sgodinez 32:629e6b1c8e22 321 //Scan for socket closed message
sgodinez 32:629e6b1c8e22 322 for(size_t i = 0; i < bytesRead; i++) {
sgodinez 32:629e6b1c8e22 323 if(data[i] == 'O') {
sgodinez 32:629e6b1c8e22 324 if(strstr(&data[i], "Ok_Info_SocketClosed")) {
sgodinez 32:629e6b1c8e22 325 printf("[INFO] Found socket closed message. Socket closed\r\n");
sgodinez 32:629e6b1c8e22 326 //Close socket and Cut Off End of Message
sgodinez 32:629e6b1c8e22 327 socketOpened = false;
sgodinez 32:629e6b1c8e22 328 data[i] = '\0';
sgodinez 32:629e6b1c8e22 329 bytesRead = i;
sgodinez 32:629e6b1c8e22 330 break;
sgodinez 32:629e6b1c8e22 331 }
sgodinez 32:629e6b1c8e22 332 }
sgodinez 32:629e6b1c8e22 333 }
sgodinez 17:2d7c4ea7491b 334 return bytesRead;
sgodinez 11:134435d8a2d5 335 }
sgodinez 11:134435d8a2d5 336
sgodinez 41:81d035fb0b6a 337 int Cellular::write(const char* data, int length, int timeout) {
sgodinez 19:38794784e009 338 if(io == NULL) {
sgodinez 19:38794784e009 339 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 19:38794784e009 340 return -1;
sgodinez 19:38794784e009 341 }
sgodinez 19:38794784e009 342
sgodinez 17:2d7c4ea7491b 343 if(!socketOpened) {
sgodinez 17:2d7c4ea7491b 344 printf("[ERROR] Socket is not open\r\n");
sgodinez 17:2d7c4ea7491b 345 return -1;
sgodinez 17:2d7c4ea7491b 346 }
sgodinez 17:2d7c4ea7491b 347
sgodinez 35:f28acb1be52d 348 //In order to avoid allocating another buffer, capture indices of
sgodinez 35:f28acb1be52d 349 //characters to escape during write
sgodinez 35:f28acb1be52d 350 int specialWritten = 0;
sgodinez 35:f28acb1be52d 351 std::vector<int> vSpecial;
sgodinez 35:f28acb1be52d 352 if(socketCloseable) {
sgodinez 35:f28acb1be52d 353 for(int i = 0; i < length; i++) {
sgodinez 35:f28acb1be52d 354 if(data[i] == ETX || data[i] == DLE) {
sgodinez 35:f28acb1be52d 355 //Push back index of special characters
sgodinez 35:f28acb1be52d 356 vSpecial.push_back(i);
sgodinez 35:f28acb1be52d 357 }
sgodinez 35:f28acb1be52d 358 }
sgodinez 35:f28acb1be52d 359 }
sgodinez 35:f28acb1be52d 360
sgodinez 17:2d7c4ea7491b 361 int bytesWritten = 0;
sgodinez 17:2d7c4ea7491b 362 if(timeout >= 0) {
sgodinez 17:2d7c4ea7491b 363 Timer tmr;
sgodinez 17:2d7c4ea7491b 364 tmr.start();
sgodinez 35:f28acb1be52d 365 do {
sgodinez 35:f28acb1be52d 366 int capacity = io->writeable();
sgodinez 35:f28acb1be52d 367 if (capacity > 0) {
sgodinez 35:f28acb1be52d 368 if(specialWritten < vSpecial.size()) {
sgodinez 35:f28acb1be52d 369 //Check if current index is at a special character
sgodinez 35:f28acb1be52d 370 if(bytesWritten == vSpecial[specialWritten]) {
sgodinez 35:f28acb1be52d 371 if(capacity < 2) {
sgodinez 35:f28acb1be52d 372 //Requires at least two bytes of space
sgodinez 35:f28acb1be52d 373 wait(0.05);
sgodinez 35:f28acb1be52d 374 continue;
sgodinez 35:f28acb1be52d 375 }
sgodinez 35:f28acb1be52d 376 //Ready to write special character
sgodinez 35:f28acb1be52d 377 if(io->write(DLE)) {
sgodinez 35:f28acb1be52d 378 specialWritten++;
sgodinez 35:f28acb1be52d 379 if(io->write(data[bytesWritten])) {
sgodinez 35:f28acb1be52d 380 bytesWritten++;
sgodinez 35:f28acb1be52d 381 }
sgodinez 35:f28acb1be52d 382 } else {
sgodinez 35:f28acb1be52d 383 //Unable to write escape character, try again next round
sgodinez 35:f28acb1be52d 384 wait(0.05);
sgodinez 35:f28acb1be52d 385 }
sgodinez 35:f28acb1be52d 386 } else {
sgodinez 35:f28acb1be52d 387 //We want to write all the way up to the next special character
sgodinez 35:f28acb1be52d 388 int relativeIndex = vSpecial[specialWritten] - bytesWritten;
sgodinez 35:f28acb1be52d 389 int size = MIN(capacity, relativeIndex);
sgodinez 35:f28acb1be52d 390 bytesWritten += io->write(&data[bytesWritten], size);
sgodinez 35:f28acb1be52d 391 }
sgodinez 35:f28acb1be52d 392 } else {
sgodinez 35:f28acb1be52d 393 int size = MIN(capacity, length - bytesWritten);
sgodinez 35:f28acb1be52d 394 bytesWritten += io->write(&data[bytesWritten], size);
sgodinez 17:2d7c4ea7491b 395 }
sgodinez 17:2d7c4ea7491b 396 } else {
sgodinez 35:f28acb1be52d 397 wait(0.05);
sgodinez 35:f28acb1be52d 398 }
sgodinez 35:f28acb1be52d 399 } while (tmr.read_ms() <= timeout && bytesWritten < length);
sgodinez 35:f28acb1be52d 400 } else {
sgodinez 35:f28acb1be52d 401 for(int i = 0; i < vSpecial.size(); i++) {
sgodinez 35:f28acb1be52d 402 //Write up to the special character, then write the special character
sgodinez 35:f28acb1be52d 403 int size = vSpecial[i] - bytesWritten;
sgodinez 35:f28acb1be52d 404 int currentWritten = io->write(&data[bytesWritten], size);
sgodinez 35:f28acb1be52d 405 bytesWritten += currentWritten;
sgodinez 35:f28acb1be52d 406 if(currentWritten != size) {
sgodinez 35:f28acb1be52d 407 //Failed to write up to the special character.
sgodinez 35:f28acb1be52d 408 return bytesWritten;
sgodinez 35:f28acb1be52d 409 }
sgodinez 35:f28acb1be52d 410 if(io->write(DLE) && io->write(data[bytesWritten])) {
sgodinez 35:f28acb1be52d 411 bytesWritten++;
sgodinez 35:f28acb1be52d 412 } else {
sgodinez 35:f28acb1be52d 413 //Failed to write the special character.
sgodinez 35:f28acb1be52d 414 return bytesWritten;
sgodinez 17:2d7c4ea7491b 415 }
sgodinez 17:2d7c4ea7491b 416 }
sgodinez 35:f28acb1be52d 417
sgodinez 35:f28acb1be52d 418 bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
sgodinez 17:2d7c4ea7491b 419 }
sgodinez 17:2d7c4ea7491b 420
sgodinez 17:2d7c4ea7491b 421 return bytesWritten;
sgodinez 11:134435d8a2d5 422 }
sgodinez 11:134435d8a2d5 423
sgodinez 11:134435d8a2d5 424 unsigned int Cellular::readable() {
sgodinez 19:38794784e009 425 if(io == NULL) {
sgodinez 19:38794784e009 426 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 19:38794784e009 427 return 0;
sgodinez 19:38794784e009 428 }
sgodinez 17:2d7c4ea7491b 429 if(!socketOpened) {
sgodinez 17:2d7c4ea7491b 430 printf("[ERROR] Socket is not open\r\n");
sgodinez 17:2d7c4ea7491b 431 return 0;
sgodinez 17:2d7c4ea7491b 432 }
sgodinez 19:38794784e009 433 return io->readable();
sgodinez 11:134435d8a2d5 434 }
sgodinez 11:134435d8a2d5 435
sgodinez 11:134435d8a2d5 436 unsigned int Cellular::writeable() {
sgodinez 19:38794784e009 437 if(io == NULL) {
sgodinez 19:38794784e009 438 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 19:38794784e009 439 return 0;
sgodinez 19:38794784e009 440 }
sgodinez 17:2d7c4ea7491b 441 if(!socketOpened) {
sgodinez 17:2d7c4ea7491b 442 printf("[ERROR] Socket is not open\r\n");
sgodinez 17:2d7c4ea7491b 443 return 0;
sgodinez 17:2d7c4ea7491b 444 }
sgodinez 17:2d7c4ea7491b 445
sgodinez 19:38794784e009 446 return io->writeable();
sgodinez 11:134435d8a2d5 447 }
sgodinez 11:134435d8a2d5 448
sgodinez 11:134435d8a2d5 449 void Cellular::reset() {
mfiore 29:7408b1bdad37 450 disconnect();
mfiore 29:7408b1bdad37 451 Code code = sendBasicCommand("AT#RESET=0", 10000);
mfiore 29:7408b1bdad37 452 if(code != OK) {
mfiore 29:7408b1bdad37 453 printf("[ERROR] Socket Modem did not accept RESET command\n\r");
mfiore 29:7408b1bdad37 454 } else {
mfiore 29:7408b1bdad37 455 printf("[WARNING] Socket Modem is resetting, allow 30 seconds for it to come back\n\r");
mfiore 29:7408b1bdad37 456 }
sgodinez 11:134435d8a2d5 457 }
sgodinez 11:134435d8a2d5 458
sgodinez 11:134435d8a2d5 459 Cellular::Code Cellular::test()
jengbrecht 0:563b70517320 460 {
sgodinez 11:134435d8a2d5 461 Code code = sendBasicCommand("AT", 1000);
sgodinez 11:134435d8a2d5 462
sgodinez 11:134435d8a2d5 463 if(code != OK) {
sgodinez 11:134435d8a2d5 464 printf("[Error] Failed basic AT command");
sgodinez 11:134435d8a2d5 465 return code;
sgodinez 11:134435d8a2d5 466 }
sgodinez 11:134435d8a2d5 467
sgodinez 11:134435d8a2d5 468 //AT#VSTATE != "CHECKING"
sgodinez 11:134435d8a2d5 469
sgodinez 11:134435d8a2d5 470 //AT#GPRSMODE ==
sgodinez 12:40ac31a09132 471 return OK;
jengbrecht 0:563b70517320 472 }
jengbrecht 0:563b70517320 473
mfiore 29:7408b1bdad37 474 Cellular::Code Cellular::echo(bool state)
jengbrecht 0:563b70517320 475 {
sgodinez 13:0af863114629 476 Code code;
jengbrecht 0:563b70517320 477 if (state) {
sgodinez 13:0af863114629 478 code = sendBasicCommand("ATE0", 1000);
sgodinez 13:0af863114629 479 echoMode = (code == OK) ? false : echoMode;
jengbrecht 0:563b70517320 480 } else {
sgodinez 13:0af863114629 481 code = sendBasicCommand("ATE1", 1000);
sgodinez 13:0af863114629 482 echoMode = (code == OK) ? true : echoMode;
jengbrecht 0:563b70517320 483 }
sgodinez 13:0af863114629 484 return code;
jengbrecht 0:563b70517320 485 }
jengbrecht 0:563b70517320 486
jengbrecht 0:563b70517320 487 int Cellular::getSignalStrength()
jengbrecht 0:563b70517320 488 {
jengbrecht 0:563b70517320 489 string response = sendCommand("AT+CSQ", 1000);
jengbrecht 0:563b70517320 490 if (response.find("OK") == string::npos) {
jengbrecht 0:563b70517320 491 return -1;
jengbrecht 0:563b70517320 492 }
jengbrecht 0:563b70517320 493 int start = response.find(':');
jengbrecht 0:563b70517320 494 int stop = response.find(',', start);
jengbrecht 0:563b70517320 495 string signal = response.substr(start + 2, stop - start - 2);
jengbrecht 0:563b70517320 496 int value;
jengbrecht 0:563b70517320 497 sscanf(signal.c_str(), "%d", &value);
jengbrecht 0:563b70517320 498 return value;
jengbrecht 0:563b70517320 499 }
jengbrecht 0:563b70517320 500
sgodinez 5:93e889a5abc6 501 std::string Cellular::getPhoneNumber() {
sgodinez 5:93e889a5abc6 502 return "unknown";
sgodinez 5:93e889a5abc6 503 }
sgodinez 5:93e889a5abc6 504
jengbrecht 0:563b70517320 505 Cellular::Registration Cellular::getRegistration()
jengbrecht 0:563b70517320 506 {
jengbrecht 0:563b70517320 507 string response = sendCommand("AT+CREG?", 1000);
jengbrecht 0:563b70517320 508 if (response.find("OK") == string::npos) {
jengbrecht 0:563b70517320 509 return UNKNOWN;
jengbrecht 0:563b70517320 510 }
jengbrecht 0:563b70517320 511 int start = response.find(',');
jengbrecht 0:563b70517320 512 int stop = response.find(' ', start);
jengbrecht 0:563b70517320 513 string regStat = response.substr(start + 1, stop - start - 1);
jengbrecht 0:563b70517320 514 int value;
jengbrecht 0:563b70517320 515 sscanf(regStat.c_str(), "%d", &value);
jengbrecht 0:563b70517320 516 switch (value) {
jengbrecht 0:563b70517320 517 case 0:
jengbrecht 0:563b70517320 518 return NOT_REGISTERED;
jengbrecht 0:563b70517320 519 case 1:
jengbrecht 0:563b70517320 520 return REGISTERED;
jengbrecht 0:563b70517320 521 case 2:
jengbrecht 0:563b70517320 522 return SEARCHING;
jengbrecht 0:563b70517320 523 case 3:
jengbrecht 0:563b70517320 524 return DENIED;
jengbrecht 0:563b70517320 525 case 4:
jengbrecht 0:563b70517320 526 return UNKNOWN;
jengbrecht 0:563b70517320 527 case 5:
jengbrecht 0:563b70517320 528 return ROAMING;
jengbrecht 0:563b70517320 529 }
sgodinez 4:6561c9128c6f 530 return UNKNOWN;
jengbrecht 0:563b70517320 531 }
jengbrecht 0:563b70517320 532
jengbrecht 0:563b70517320 533 Cellular::Code Cellular::sendBasicCommand(string command, int timeoutMillis, ESC_CHAR esc)
jengbrecht 0:563b70517320 534 {
sgodinez 17:2d7c4ea7491b 535 if(socketOpened) {
sgodinez 17:2d7c4ea7491b 536 printf("[ERROR] socket is open. Can not send AT commands\r\n");
sgodinez 17:2d7c4ea7491b 537 return ERROR;
sgodinez 17:2d7c4ea7491b 538 }
sgodinez 17:2d7c4ea7491b 539
jengbrecht 0:563b70517320 540 string response = sendCommand(command, timeoutMillis, esc);
jengbrecht 0:563b70517320 541 if (response.size() == 0) {
jengbrecht 0:563b70517320 542 return NO_RESPONSE;
jengbrecht 0:563b70517320 543 } else if (response.find("OK") != string::npos) {
jengbrecht 0:563b70517320 544 return OK;
jengbrecht 0:563b70517320 545 } else if (response.find("ERROR") != string::npos) {
jengbrecht 0:563b70517320 546 return ERROR;
jengbrecht 0:563b70517320 547 } else {
jengbrecht 0:563b70517320 548 return FAILURE;
jengbrecht 0:563b70517320 549 }
jengbrecht 0:563b70517320 550 }
jengbrecht 0:563b70517320 551
sgodinez 11:134435d8a2d5 552 Cellular::Code Cellular::setApn(const std::string& apn) {
sgodinez 11:134435d8a2d5 553 Code code = sendBasicCommand("AT#APNSERV=\"" + apn + "\"", 1000);
sgodinez 11:134435d8a2d5 554 if (code != OK) {
sgodinez 11:134435d8a2d5 555 return code;
sgodinez 11:134435d8a2d5 556 }
sgodinez 11:134435d8a2d5 557 this->apn = apn;
sgodinez 11:134435d8a2d5 558 return code;
sgodinez 11:134435d8a2d5 559 }
sgodinez 11:134435d8a2d5 560
sgodinez 41:81d035fb0b6a 561 Cellular::Code Cellular::setDns(const std::string& primary, const std::string& secondary) {
sgodinez 41:81d035fb0b6a 562 return sendBasicCommand("AT#DNS=1," + primary + "," + secondary, 1000);
sgodinez 11:134435d8a2d5 563 }
sgodinez 11:134435d8a2d5 564
jengbrecht 23:bc6f98a1eb22 565 bool Cellular::ping(const std::string& address) {
jengbrecht 23:bc6f98a1eb22 566 char buffer[256] = {0};
jengbrecht 23:bc6f98a1eb22 567 Code code;
jengbrecht 23:bc6f98a1eb22 568
jengbrecht 23:bc6f98a1eb22 569 code = sendBasicCommand("AT#PINGREMOTE=\"" + address + "\"", 1000);
jengbrecht 23:bc6f98a1eb22 570 if (code != OK) {
jengbrecht 23:bc6f98a1eb22 571 return false;
jengbrecht 23:bc6f98a1eb22 572 }
jengbrecht 23:bc6f98a1eb22 573
jengbrecht 23:bc6f98a1eb22 574 sprintf(buffer, "AT#PINGNUM=%d", 1);
jengbrecht 23:bc6f98a1eb22 575 code = sendBasicCommand(buffer , 1000);
jengbrecht 23:bc6f98a1eb22 576 if (code != OK) {
jengbrecht 23:bc6f98a1eb22 577 return false;
jengbrecht 23:bc6f98a1eb22 578 }
jengbrecht 23:bc6f98a1eb22 579
jengbrecht 23:bc6f98a1eb22 580 sprintf(buffer, "AT#PINGDELAY=%d", PINGDELAY);
jengbrecht 23:bc6f98a1eb22 581 code = sendBasicCommand(buffer , 1000);
jengbrecht 23:bc6f98a1eb22 582 if (code != OK) {
jengbrecht 23:bc6f98a1eb22 583 return false;
jengbrecht 23:bc6f98a1eb22 584 }
jengbrecht 23:bc6f98a1eb22 585
jengbrecht 23:bc6f98a1eb22 586 std::string response;
jengbrecht 23:bc6f98a1eb22 587 for (int i = 0; i < PINGNUM; i++) {
jengbrecht 23:bc6f98a1eb22 588 response = sendCommand("AT#PING", PINGDELAY * 1000);
jengbrecht 23:bc6f98a1eb22 589 if (response.find("alive") != std::string::npos) {
jengbrecht 23:bc6f98a1eb22 590 return true;
jengbrecht 23:bc6f98a1eb22 591 }
jengbrecht 23:bc6f98a1eb22 592 }
jengbrecht 23:bc6f98a1eb22 593 return false;
jengbrecht 23:bc6f98a1eb22 594 }
jengbrecht 23:bc6f98a1eb22 595
sgodinez 17:2d7c4ea7491b 596 Cellular::Code Cellular::setSocketCloseable(bool enabled) {
sgodinez 17:2d7c4ea7491b 597 if(socketCloseable == enabled) {
sgodinez 17:2d7c4ea7491b 598 return OK;
sgodinez 17:2d7c4ea7491b 599 }
sgodinez 17:2d7c4ea7491b 600
sgodinez 17:2d7c4ea7491b 601 if(socketOpened) {
sgodinez 17:2d7c4ea7491b 602 printf("[ERROR] socket is already opened. Can not set closeable\r\n");
sgodinez 17:2d7c4ea7491b 603 return ERROR;
sgodinez 17:2d7c4ea7491b 604 }
sgodinez 17:2d7c4ea7491b 605
sgodinez 17:2d7c4ea7491b 606 socketCloseable = enabled;
sgodinez 17:2d7c4ea7491b 607
sgodinez 17:2d7c4ea7491b 608 return OK;
sgodinez 17:2d7c4ea7491b 609 }
sgodinez 17:2d7c4ea7491b 610
sgodinez 4:6561c9128c6f 611 Cellular::Code Cellular::sendSMS(const Sms& sms) {
sgodinez 4:6561c9128c6f 612 return sendSMS(sms.phoneNumber, sms.message);
sgodinez 4:6561c9128c6f 613 }
sgodinez 4:6561c9128c6f 614
sgodinez 4:6561c9128c6f 615 Cellular::Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message)
sgodinez 17:2d7c4ea7491b 616 {
jengbrecht 0:563b70517320 617 Code code = sendBasicCommand("AT+CMGF=1", 1000);
jengbrecht 0:563b70517320 618 if (code != OK) {
jengbrecht 0:563b70517320 619 return code;
jengbrecht 0:563b70517320 620 }
jengbrecht 0:563b70517320 621 string cmd = "AT+CMGS=\"+";
jengbrecht 0:563b70517320 622 cmd.append(phoneNumber);
jengbrecht 0:563b70517320 623 cmd.append("\"");
jengbrecht 0:563b70517320 624 string response1 = sendCommand(cmd, 1000);
jengbrecht 0:563b70517320 625 if (response1.find('>') == string::npos) {
jengbrecht 0:563b70517320 626 return NO_RESPONSE;
jengbrecht 0:563b70517320 627 }
jengbrecht 0:563b70517320 628 wait(.2);
jengbrecht 0:563b70517320 629 string response2 = sendCommand(message, 4000, CTRL_Z);
sgodinez 17:2d7c4ea7491b 630 printf("SMS Response: %s\r\n", response2.c_str());
jengbrecht 0:563b70517320 631 if (response2.find("+CMGS:") == string::npos) {
jengbrecht 0:563b70517320 632 return FAILURE;
jengbrecht 0:563b70517320 633 }
jengbrecht 0:563b70517320 634 return OK;
jengbrecht 0:563b70517320 635 }
jengbrecht 0:563b70517320 636
sgodinez 4:6561c9128c6f 637 std::vector<Cellular::Sms> Cellular::getReceivedSms() {
sgodinez 9:5b12c5a8dde4 638 int smsNumber = 0;
sgodinez 4:6561c9128c6f 639 std::vector<Sms> vSms;
sgodinez 4:6561c9128c6f 640 std::string received = sendCommand("AT+CMGL=\"ALL\"", 4000);
sgodinez 5:93e889a5abc6 641 size_t pos = received.find("+CMGL: ");
sgodinez 4:6561c9128c6f 642
sgodinez 5:93e889a5abc6 643 while (pos != std::string::npos) {
sgodinez 4:6561c9128c6f 644 Cellular::Sms sms;
sgodinez 4:6561c9128c6f 645 std::string line(Text::getLine(received, pos, pos));
sgodinez 17:2d7c4ea7491b 646 //printf("[DEBUG] Top of SMS Parse Loop. LINE[%s]\r\n", line.c_str());
sgodinez 9:5b12c5a8dde4 647 if(line.find("+CMGL: ") == std::string::npos) {
sgodinez 4:6561c9128c6f 648 continue;
sgodinez 4:6561c9128c6f 649 }
sgodinez 4:6561c9128c6f 650
sgodinez 4:6561c9128c6f 651 //Start of SMS message
sgodinez 4:6561c9128c6f 652 std::vector<std::string> vSmsParts = Text::split(line, ',');
sgodinez 4:6561c9128c6f 653 if(vSmsParts.size() != 6) {
sgodinez 17:2d7c4ea7491b 654 printf("[WARNING] Expected 6 commas. SMS[%d] DATA[%s]. Continuing ...\r\n", smsNumber, line.c_str());
sgodinez 4:6561c9128c6f 655 continue;
sgodinez 4:6561c9128c6f 656 }
sgodinez 4:6561c9128c6f 657
sgodinez 4:6561c9128c6f 658 sms.phoneNumber = vSmsParts[2];
sgodinez 4:6561c9128c6f 659 sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5];
sgodinez 4:6561c9128c6f 660
sgodinez 8:3fe68d6130a8 661 if(pos == std::string::npos) {
sgodinez 17:2d7c4ea7491b 662 printf("[WARNING] Expected SMS body. SMS[%d]. Leaving ...\r\n", smsNumber);
sgodinez 8:3fe68d6130a8 663 break;
sgodinez 8:3fe68d6130a8 664 }
sgodinez 9:5b12c5a8dde4 665 //Check for the start of the next SMS message
sgodinez 9:5b12c5a8dde4 666 size_t bodyEnd = received.find("\r\n+CMGL: ", pos);
sgodinez 8:3fe68d6130a8 667 if(bodyEnd == std::string::npos) {
sgodinez 17:2d7c4ea7491b 668 //printf("[DEBUG] Parsing Last SMS. SMS[%d]\r\n", smsNumber);
sgodinez 9:5b12c5a8dde4 669 //This must be the last SMS message
sgodinez 9:5b12c5a8dde4 670 bodyEnd = received.find("\r\n\r\nOK", pos);
sgodinez 8:3fe68d6130a8 671 }
sgodinez 9:5b12c5a8dde4 672
sgodinez 9:5b12c5a8dde4 673 //Safety check that we found the boundary of this current SMS message
sgodinez 9:5b12c5a8dde4 674 if(bodyEnd != std::string::npos) {
sgodinez 9:5b12c5a8dde4 675 sms.message = received.substr(pos, bodyEnd - pos);
sgodinez 9:5b12c5a8dde4 676 } else {
sgodinez 8:3fe68d6130a8 677 sms.message = received.substr(pos);
sgodinez 17:2d7c4ea7491b 678 printf("[WARNING] Expected to find end of SMS list. SMS[%d] DATA[%s].\r\n", smsNumber, sms.message.c_str());
sgodinez 8:3fe68d6130a8 679 }
sgodinez 5:93e889a5abc6 680 vSms.push_back(sms);
sgodinez 4:6561c9128c6f 681 pos = bodyEnd;
sgodinez 17:2d7c4ea7491b 682 //printf("[DEBUG] Parsed SMS[%d]. Starting Next at position [%d]\r\n", smsNumber, pos);
sgodinez 9:5b12c5a8dde4 683 smsNumber++;
sgodinez 4:6561c9128c6f 684 }
sgodinez 17:2d7c4ea7491b 685 printf("Received %d SMS\r\n", smsNumber);
sgodinez 4:6561c9128c6f 686 return vSms;
sgodinez 4:6561c9128c6f 687 }
sgodinez 4:6561c9128c6f 688
sgodinez 4:6561c9128c6f 689 Cellular::Code Cellular::deleteOnlyReceivedReadSms() {
sgodinez 4:6561c9128c6f 690 return sendBasicCommand("AT+CMGD=1,1", 1000);
sgodinez 4:6561c9128c6f 691 }
sgodinez 4:6561c9128c6f 692
sgodinez 4:6561c9128c6f 693 Cellular::Code Cellular::deleteAllReceivedSms() {
sgodinez 4:6561c9128c6f 694 return sendBasicCommand("AT+CMGD=1,4", 1000);
sgodinez 4:6561c9128c6f 695 }
sgodinez 4:6561c9128c6f 696
sgodinez 4:6561c9128c6f 697
jengbrecht 0:563b70517320 698 string Cellular::sendCommand(string command, int timeoutMillis, ESC_CHAR esc)
jengbrecht 0:563b70517320 699 {
sgodinez 19:38794784e009 700 if(io == NULL) {
sgodinez 19:38794784e009 701 printf("[ERROR] MTSBufferedIO not set\r\n");
sgodinez 19:38794784e009 702 return "";
sgodinez 19:38794784e009 703 }
sgodinez 17:2d7c4ea7491b 704 if(socketOpened) {
sgodinez 17:2d7c4ea7491b 705 printf("[ERROR] socket is open. Can not send AT commands\r\n");
sgodinez 17:2d7c4ea7491b 706 return "";
sgodinez 17:2d7c4ea7491b 707 }
sgodinez 17:2d7c4ea7491b 708
jengbrecht 0:563b70517320 709 int size = command.size() + 1;
jengbrecht 0:563b70517320 710 char cmd[size];
jengbrecht 0:563b70517320 711 strcpy(cmd, command.c_str());
jengbrecht 0:563b70517320 712 if (esc == CR) {
jengbrecht 0:563b70517320 713 cmd[size -1] = '\r';
jengbrecht 0:563b70517320 714 } else if (esc == CTRL_Z) {
jengbrecht 0:563b70517320 715 cmd[size -1] = 0x1A;
sgodinez 13:0af863114629 716 } else if(esc == NONE) {
sgodinez 13:0af863114629 717 cmd[size -1] = '\0';
jengbrecht 0:563b70517320 718 }
jengbrecht 0:563b70517320 719
sgodinez 19:38794784e009 720 io->rxClear();
sgodinez 19:38794784e009 721 io->txClear();
sgodinez 8:3fe68d6130a8 722 std::string result;
sgodinez 19:38794784e009 723 int status = io->write(cmd, size);
sgodinez 19:38794784e009 724 int available = io->rxAvailable();
jengbrecht 0:563b70517320 725 int previous = -1;
jengbrecht 0:563b70517320 726 int timer = 0;
sgodinez 8:3fe68d6130a8 727 char tmp[256];
sgodinez 8:3fe68d6130a8 728 tmp[255] = 0;
sgodinez 13:0af863114629 729 bool started = !echoMode;
sgodinez 13:0af863114629 730 bool done = false;
sgodinez 8:3fe68d6130a8 731 do {
jengbrecht 0:563b70517320 732 wait(.1);
jengbrecht 0:563b70517320 733 timer = timer + 100;
jengbrecht 0:563b70517320 734 previous = available;
sgodinez 19:38794784e009 735 available = io->rxAvailable();
sgodinez 8:3fe68d6130a8 736
sgodinez 19:38794784e009 737 int size = io->read(tmp,255); //1 less than allocated
sgodinez 8:3fe68d6130a8 738 if(size > 0) {
sgodinez 8:3fe68d6130a8 739 result.append(tmp, size);
sgodinez 8:3fe68d6130a8 740 }
sgodinez 13:0af863114629 741
sgodinez 13:0af863114629 742 if(!started) {
sgodinez 13:0af863114629 743 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
sgodinez 13:0af863114629 744 if(result.size() > command.size() + 2) {
sgodinez 13:0af863114629 745 started = true;
sgodinez 13:0af863114629 746 }
sgodinez 13:0af863114629 747 } else {
sgodinez 13:0af863114629 748 done = (available == previous);
sgodinez 13:0af863114629 749 }
sgodinez 13:0af863114629 750 if(timer >= timeoutMillis) {
sgodinez 17:2d7c4ea7491b 751 printf("[WARNING] sendCommand timed out after %d milliseconds\r\n", timeoutMillis);
sgodinez 13:0af863114629 752 done = true;
sgodinez 13:0af863114629 753 }
sgodinez 13:0af863114629 754 } while (!done);
sgodinez 8:3fe68d6130a8 755
sgodinez 8:3fe68d6130a8 756 return result;
jengbrecht 0:563b70517320 757 }
jengbrecht 0:563b70517320 758
jengbrecht 0:563b70517320 759 #endif /* CELLULAR_CPP */