Axeda Ready Demo for Freescale FRDM-KL46Z as accident alert system

Dependencies:   FRDM_MMA8451Q KL46Z-USBHost MAG3110 SocketModem TSI mbed FATFileSystem

Fork of AxedaGo-Freescal_FRDM-KL46Z by Axeda Corp

Committer:
AxedaCorp
Date:
Wed Jul 02 19:57:37 2014 +0000
Revision:
2:2f9019c5a9fc
Parent:
0:65004368569c
ip switch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AxedaCorp 0:65004368569c 1 /* Universal Socket Modem Interface Library
AxedaCorp 0:65004368569c 2 * Copyright (c) 2013 Multi-Tech Systems
AxedaCorp 0:65004368569c 3 *
AxedaCorp 0:65004368569c 4 * Licensed under the Apache License, Version 2.0 (the "License");
AxedaCorp 0:65004368569c 5 * you may not use this file except in compliance with the License.
AxedaCorp 0:65004368569c 6 * You may obtain a copy of the License at
AxedaCorp 0:65004368569c 7 *
AxedaCorp 0:65004368569c 8 * http://www.apache.org/licenses/LICENSE-2.0
AxedaCorp 0:65004368569c 9 *
AxedaCorp 0:65004368569c 10 * Unless required by applicable law or agreed to in writing, software
AxedaCorp 0:65004368569c 11 * distributed under the License is distributed on an "AS IS" BASIS,
AxedaCorp 0:65004368569c 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AxedaCorp 0:65004368569c 13 * See the License for the specific language governing permissions and
AxedaCorp 0:65004368569c 14 * limitations under the License.
AxedaCorp 0:65004368569c 15 */
AxedaCorp 0:65004368569c 16
AxedaCorp 0:65004368569c 17
AxedaCorp 0:65004368569c 18 #include "Cellular.h"
AxedaCorp 0:65004368569c 19 #include "MTSText.h"
AxedaCorp 0:65004368569c 20 #include "MTSSerial.h"
AxedaCorp 0:65004368569c 21
AxedaCorp 0:65004368569c 22 using namespace mts;
AxedaCorp 0:65004368569c 23
AxedaCorp 0:65004368569c 24 Cellular* Cellular::instance = NULL;
AxedaCorp 0:65004368569c 25
AxedaCorp 0:65004368569c 26 Cellular* Cellular::getInstance()
AxedaCorp 0:65004368569c 27 {
AxedaCorp 0:65004368569c 28 if(instance == NULL) {
AxedaCorp 0:65004368569c 29 instance = new Cellular(NULL);
AxedaCorp 0:65004368569c 30 }
AxedaCorp 0:65004368569c 31 return instance;
AxedaCorp 0:65004368569c 32 }
AxedaCorp 0:65004368569c 33
AxedaCorp 0:65004368569c 34 Cellular::Cellular(MTSBufferedIO* io)
AxedaCorp 0:65004368569c 35 : io(io)
AxedaCorp 0:65004368569c 36 , echoMode(true)
AxedaCorp 0:65004368569c 37 , pppConnected(false)
AxedaCorp 0:65004368569c 38 , mode(TCP)
AxedaCorp 0:65004368569c 39 , socketOpened(false)
AxedaCorp 0:65004368569c 40 , socketCloseable(true)
AxedaCorp 0:65004368569c 41 , local_port(0)
AxedaCorp 0:65004368569c 42 , local_address("")
AxedaCorp 0:65004368569c 43 , host_port(0)
AxedaCorp 0:65004368569c 44 , dcd(NULL)
AxedaCorp 0:65004368569c 45 , dtr(NULL)
AxedaCorp 0:65004368569c 46 {
AxedaCorp 0:65004368569c 47 }
AxedaCorp 0:65004368569c 48
AxedaCorp 0:65004368569c 49 Cellular::~Cellular()
AxedaCorp 0:65004368569c 50 {
AxedaCorp 0:65004368569c 51 if (dtr != NULL) {
AxedaCorp 0:65004368569c 52 dtr->write(1);
AxedaCorp 0:65004368569c 53 }
AxedaCorp 0:65004368569c 54
AxedaCorp 0:65004368569c 55 delete dcd;
AxedaCorp 0:65004368569c 56 delete dtr;
AxedaCorp 0:65004368569c 57 }
AxedaCorp 0:65004368569c 58
AxedaCorp 0:65004368569c 59 bool Cellular::init(MTSBufferedIO* io, PinName DCD, PinName DTR)
AxedaCorp 0:65004368569c 60 {
AxedaCorp 0:65004368569c 61 if (io == NULL) {
AxedaCorp 0:65004368569c 62 return false;
AxedaCorp 0:65004368569c 63 }
AxedaCorp 0:65004368569c 64
AxedaCorp 0:65004368569c 65 if(dcd) {
AxedaCorp 0:65004368569c 66 delete dcd;
AxedaCorp 0:65004368569c 67 dcd = NULL;
AxedaCorp 0:65004368569c 68 }
AxedaCorp 0:65004368569c 69 if(dtr) {
AxedaCorp 0:65004368569c 70 delete dtr;
AxedaCorp 0:65004368569c 71 dtr = NULL;
AxedaCorp 0:65004368569c 72 }
AxedaCorp 0:65004368569c 73
AxedaCorp 0:65004368569c 74 if (DCD != NC) {
AxedaCorp 0:65004368569c 75 // the radio will raise and lower this line
AxedaCorp 0:65004368569c 76 dcd = new DigitalIn(DCD); //PTA4 - KL46
AxedaCorp 0:65004368569c 77 }
AxedaCorp 0:65004368569c 78 if (DTR != NC) {
AxedaCorp 0:65004368569c 79 dtr = new DigitalOut(DTR); //PTC9 - KL46
AxedaCorp 0:65004368569c 80 /* This line should be lowered when we want to talk to the radio and raised when we're done
AxedaCorp 0:65004368569c 81 for now we will lower it in the constructor and raise it in the destructor
AxedaCorp 0:65004368569c 82 */
AxedaCorp 0:65004368569c 83 dtr->write(0);
AxedaCorp 0:65004368569c 84 }
AxedaCorp 0:65004368569c 85 instance->io = io;
AxedaCorp 0:65004368569c 86
AxedaCorp 0:65004368569c 87 test();
AxedaCorp 0:65004368569c 88 // Reset radio to make sure it's in a good state and wait for it to come back
AxedaCorp 0:65004368569c 89 reset();
AxedaCorp 0:65004368569c 90 test();
AxedaCorp 0:65004368569c 91
AxedaCorp 0:65004368569c 92 return SUCCESS;
AxedaCorp 0:65004368569c 93 }
AxedaCorp 0:65004368569c 94
AxedaCorp 0:65004368569c 95
AxedaCorp 0:65004368569c 96 bool Cellular::connect()
AxedaCorp 0:65004368569c 97 {
AxedaCorp 0:65004368569c 98 //Check if socket is open
AxedaCorp 0:65004368569c 99 if(socketOpened) {
AxedaCorp 0:65004368569c 100 return true;
AxedaCorp 0:65004368569c 101 }
AxedaCorp 0:65004368569c 102
AxedaCorp 0:65004368569c 103 //Check if already connected
AxedaCorp 0:65004368569c 104 if(isConnected()) {
AxedaCorp 0:65004368569c 105 return true;
AxedaCorp 0:65004368569c 106 }
AxedaCorp 0:65004368569c 107
AxedaCorp 0:65004368569c 108 Timer tmr;
AxedaCorp 0:65004368569c 109
AxedaCorp 0:65004368569c 110 //Check Registration: AT+CREG? == 0,1
AxedaCorp 0:65004368569c 111 tmr.start();
AxedaCorp 0:65004368569c 112 do {
AxedaCorp 0:65004368569c 113 Registration registration = getRegistration();
AxedaCorp 0:65004368569c 114 if(registration != REGISTERED) {
AxedaCorp 0:65004368569c 115 printf("[WARNING] Not Registered [%d] ... waiting\r\n", (int)registration);
AxedaCorp 0:65004368569c 116 wait(1);
AxedaCorp 0:65004368569c 117 } else {
AxedaCorp 0:65004368569c 118 break;
AxedaCorp 0:65004368569c 119 }
AxedaCorp 0:65004368569c 120 } while(tmr.read() < 30);
AxedaCorp 0:65004368569c 121
AxedaCorp 0:65004368569c 122 //Check RSSI: AT+CSQ
AxedaCorp 0:65004368569c 123 tmr.reset();
AxedaCorp 0:65004368569c 124 do {
AxedaCorp 0:65004368569c 125 int rssi = getSignalStrength();
AxedaCorp 0:65004368569c 126 printf("[DEBUG] Signal strength: %d\r\n", rssi);
AxedaCorp 0:65004368569c 127 if(rssi == 99) {
AxedaCorp 0:65004368569c 128 printf("[WARNING] No Signal ... waiting\r\n");
AxedaCorp 0:65004368569c 129 wait(1);
AxedaCorp 0:65004368569c 130 } else {
AxedaCorp 0:65004368569c 131 break;
AxedaCorp 0:65004368569c 132 }
AxedaCorp 0:65004368569c 133 } while(tmr.read() < 30);
AxedaCorp 0:65004368569c 134
AxedaCorp 0:65004368569c 135 //AT#CONNECTIONSTART: Make a PPP connection
AxedaCorp 0:65004368569c 136 printf("[DEBUG] Making PPP Connection Attempt. APN[%s]\r\n", apn.c_str());
AxedaCorp 0:65004368569c 137 std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
AxedaCorp 0:65004368569c 138 std::vector<std::string> parts = Text::split(pppResult, "\r\n");
AxedaCorp 0:65004368569c 139
AxedaCorp 0:65004368569c 140 if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
AxedaCorp 0:65004368569c 141 if(parts.size() >= 2) {
AxedaCorp 0:65004368569c 142 local_address = parts[1];
AxedaCorp 0:65004368569c 143 }
AxedaCorp 0:65004368569c 144 printf("[INFO] PPP Connection Established: IP[%s]\r\n", local_address.c_str());
AxedaCorp 0:65004368569c 145 pppConnected = true;
AxedaCorp 0:65004368569c 146
AxedaCorp 0:65004368569c 147 } else {
AxedaCorp 0:65004368569c 148 pppConnected = false;
AxedaCorp 0:65004368569c 149 }
AxedaCorp 0:65004368569c 150
AxedaCorp 0:65004368569c 151 return pppConnected;
AxedaCorp 0:65004368569c 152 }
AxedaCorp 0:65004368569c 153
AxedaCorp 0:65004368569c 154 void Cellular::disconnect()
AxedaCorp 0:65004368569c 155 {
AxedaCorp 0:65004368569c 156 //AT#CONNECTIONSTOP: Close a PPP connection
AxedaCorp 0:65004368569c 157 printf("[DEBUG] Closing PPP Connection\r\n");
AxedaCorp 0:65004368569c 158
AxedaCorp 0:65004368569c 159 if(socketOpened) {
AxedaCorp 0:65004368569c 160 close();
AxedaCorp 0:65004368569c 161 }
AxedaCorp 0:65004368569c 162
AxedaCorp 0:65004368569c 163 Code code = sendBasicCommand("AT#CONNECTIONSTOP", 10000);
AxedaCorp 0:65004368569c 164 if(code == SUCCESS) {
AxedaCorp 0:65004368569c 165 printf("[DEBUG] Successfully closed PPP Connection\r\n");
AxedaCorp 0:65004368569c 166 } else {
AxedaCorp 0:65004368569c 167 printf("[ERROR] Closing PPP Connection [%d]. Continuing ...\r\n", (int)code);
AxedaCorp 0:65004368569c 168 }
AxedaCorp 0:65004368569c 169
AxedaCorp 0:65004368569c 170 pppConnected = false;
AxedaCorp 0:65004368569c 171 }
AxedaCorp 0:65004368569c 172
AxedaCorp 0:65004368569c 173 bool Cellular::isConnected()
AxedaCorp 0:65004368569c 174 {
AxedaCorp 0:65004368569c 175 //1) Check if APN was set
AxedaCorp 0:65004368569c 176 if(apn.size() == 0) {
AxedaCorp 0:65004368569c 177 printf("[DEBUG] APN is not set\r\n");
AxedaCorp 0:65004368569c 178 return false;
AxedaCorp 0:65004368569c 179 }
AxedaCorp 0:65004368569c 180
AxedaCorp 0:65004368569c 181 //1) Check that we do not have a live connection up
AxedaCorp 0:65004368569c 182 if(socketOpened) {
AxedaCorp 0:65004368569c 183 printf("[DEBUG] Socket is opened\r\n");
AxedaCorp 0:65004368569c 184 return true;
AxedaCorp 0:65004368569c 185 }
AxedaCorp 0:65004368569c 186 //2) Query the radio
AxedaCorp 0:65004368569c 187 std::string result = sendCommand("AT#VSTATE", 3000);
AxedaCorp 0:65004368569c 188 if(result.find("CONNECTED") != std::string::npos) {
AxedaCorp 0:65004368569c 189 if(pppConnected == false) {
AxedaCorp 0:65004368569c 190 printf("[WARNING] Internal PPP state tracking differs from radio (DISCONNECTED:CONNECTED)\r\n");
AxedaCorp 0:65004368569c 191 }
AxedaCorp 0:65004368569c 192 pppConnected = true;
AxedaCorp 0:65004368569c 193 } else {
AxedaCorp 0:65004368569c 194 if(pppConnected == true) {
AxedaCorp 0:65004368569c 195 //Find out what state is
AxedaCorp 0:65004368569c 196 size_t pos = result.find("STATE:");
AxedaCorp 0:65004368569c 197 if(pos != std::string::npos) {
AxedaCorp 0:65004368569c 198 result = Text::getLine(result, pos + sizeof("STATE:"), pos);
AxedaCorp 0:65004368569c 199 printf("[WARNING] Internal PPP state tracking differs from radio (CONNECTED:%s)\r\n", result.c_str());
AxedaCorp 0:65004368569c 200 } else {
AxedaCorp 0:65004368569c 201 printf("[ERROR] Unable to parse radio state: [%s]\r\n", result.c_str());
AxedaCorp 0:65004368569c 202 }
AxedaCorp 0:65004368569c 203
AxedaCorp 0:65004368569c 204 }
AxedaCorp 0:65004368569c 205 pppConnected = false;
AxedaCorp 0:65004368569c 206 }
AxedaCorp 0:65004368569c 207
AxedaCorp 0:65004368569c 208 return pppConnected;
AxedaCorp 0:65004368569c 209 }
AxedaCorp 0:65004368569c 210
AxedaCorp 0:65004368569c 211 bool Cellular::bind(unsigned int port)
AxedaCorp 0:65004368569c 212 {
AxedaCorp 0:65004368569c 213 if(socketOpened) {
AxedaCorp 0:65004368569c 214 printf("[ERROR] socket is open. Can not set local port\r\n");
AxedaCorp 0:65004368569c 215 return false;
AxedaCorp 0:65004368569c 216 }
AxedaCorp 0:65004368569c 217 if(port > 65535) {
AxedaCorp 0:65004368569c 218 printf("[ERROR] port out of range (0-65535)\r\n");
AxedaCorp 0:65004368569c 219 return false;
AxedaCorp 0:65004368569c 220 }
AxedaCorp 0:65004368569c 221 local_port = port;
AxedaCorp 0:65004368569c 222 return true;
AxedaCorp 0:65004368569c 223 }
AxedaCorp 0:65004368569c 224
AxedaCorp 0:65004368569c 225 bool Cellular::open(const std::string& address, unsigned int port, Mode mode)
AxedaCorp 0:65004368569c 226 {
AxedaCorp 0:65004368569c 227 char buffer[256] = {0};
AxedaCorp 0:65004368569c 228 Code portCode, addressCode;
AxedaCorp 0:65004368569c 229
AxedaCorp 0:65004368569c 230 //1) Check that we do not have a live connection up
AxedaCorp 0:65004368569c 231 if(socketOpened) {
AxedaCorp 0:65004368569c 232 //Check that the address, port, and mode match
AxedaCorp 0:65004368569c 233 if(host_address != address || host_port != port || this->mode != mode) {
AxedaCorp 0:65004368569c 234 if(this->mode == TCP) {
AxedaCorp 0:65004368569c 235 printf("[ERROR] TCP socket already opened [%s:%d]\r\n", host_address.c_str(), host_port);
AxedaCorp 0:65004368569c 236 } else {
AxedaCorp 0:65004368569c 237 printf("[ERROR] UDP socket already opened [%s:%d]\r\n", host_address.c_str(), host_port);
AxedaCorp 0:65004368569c 238 }
AxedaCorp 0:65004368569c 239 return false;
AxedaCorp 0:65004368569c 240 }
AxedaCorp 0:65004368569c 241
AxedaCorp 0:65004368569c 242 printf("[DEBUG] Socket already opened\r\n");
AxedaCorp 0:65004368569c 243 return true;
AxedaCorp 0:65004368569c 244 }
AxedaCorp 0:65004368569c 245
AxedaCorp 0:65004368569c 246 //2) Check Parameters
AxedaCorp 0:65004368569c 247 if(port > 65535) {
AxedaCorp 0:65004368569c 248 printf("[ERROR] port out of range (0-65535)\r\n");
AxedaCorp 0:65004368569c 249 return false;
AxedaCorp 0:65004368569c 250 }
AxedaCorp 0:65004368569c 251
AxedaCorp 0:65004368569c 252 //3) Check PPP connection
AxedaCorp 0:65004368569c 253 if(!isConnected()) {
AxedaCorp 0:65004368569c 254 printf("[ERROR] PPP not established. Attempting to connect\r\n");
AxedaCorp 0:65004368569c 255 if(!connect()) {
AxedaCorp 0:65004368569c 256 printf("[ERROR] PPP connection failed\r\n");
AxedaCorp 0:65004368569c 257 return false;
AxedaCorp 0:65004368569c 258 } else {
AxedaCorp 0:65004368569c 259 printf("[DEBUG] PPP connection established\r\n");
AxedaCorp 0:65004368569c 260 }
AxedaCorp 0:65004368569c 261 }
AxedaCorp 0:65004368569c 262
AxedaCorp 0:65004368569c 263 //Set Local Port
AxedaCorp 0:65004368569c 264 if(local_port != 0) {
AxedaCorp 0:65004368569c 265 //Attempt to set local port
AxedaCorp 0:65004368569c 266 sprintf(buffer, "AT#OUTPORT=%d", local_port);
AxedaCorp 0:65004368569c 267 Code code = sendBasicCommand(buffer, 1000);
AxedaCorp 0:65004368569c 268 if(code != SUCCESS) {
AxedaCorp 0:65004368569c 269 printf("[WARNING] Unable to set local port (%d) [%d]\r\n", local_port, (int) code);
AxedaCorp 0:65004368569c 270 }
AxedaCorp 0:65004368569c 271 }
AxedaCorp 0:65004368569c 272
AxedaCorp 0:65004368569c 273 //Set TCP/UDP parameters
AxedaCorp 0:65004368569c 274 if(mode == TCP) {
AxedaCorp 0:65004368569c 275 if(socketCloseable) {
AxedaCorp 0:65004368569c 276 Code code = sendBasicCommand("AT#DLEMODE=1,1", 1000);
AxedaCorp 0:65004368569c 277 if(code != SUCCESS) {
AxedaCorp 0:65004368569c 278 printf("[WARNING] Unable to set socket closeable [%d]\r\n", (int) code);
AxedaCorp 0:65004368569c 279 }
AxedaCorp 0:65004368569c 280 }
AxedaCorp 0:65004368569c 281 sprintf(buffer, "AT#TCPPORT=1,%d", port);
AxedaCorp 0:65004368569c 282 portCode = sendBasicCommand(buffer, 1000);
AxedaCorp 0:65004368569c 283 addressCode = sendBasicCommand("AT#TCPSERV=1,\"" + address + "\"", 1000);
AxedaCorp 0:65004368569c 284 } else {
AxedaCorp 0:65004368569c 285 if(socketCloseable) {
AxedaCorp 0:65004368569c 286 Code code = sendBasicCommand("AT#UDPDLEMODE=1", 1000);
AxedaCorp 0:65004368569c 287 if(code != SUCCESS) {
AxedaCorp 0:65004368569c 288 printf("[WARNING] Unable to set socket closeable [%d]\r\n", (int) code);
AxedaCorp 0:65004368569c 289 }
AxedaCorp 0:65004368569c 290 }
AxedaCorp 0:65004368569c 291 sprintf(buffer, "AT#UDPPORT=%d", port);
AxedaCorp 0:65004368569c 292 portCode = sendBasicCommand(buffer, 1000);
AxedaCorp 0:65004368569c 293 addressCode = sendBasicCommand("AT#UDPSERV=\"" + address + "\"", 1000);
AxedaCorp 0:65004368569c 294 }
AxedaCorp 0:65004368569c 295
AxedaCorp 0:65004368569c 296 if(portCode == SUCCESS) {
AxedaCorp 0:65004368569c 297 host_port = port;
AxedaCorp 0:65004368569c 298 } else {
AxedaCorp 0:65004368569c 299 printf("[ERROR] Host port could not be set\r\n");
AxedaCorp 0:65004368569c 300 }
AxedaCorp 0:65004368569c 301
AxedaCorp 0:65004368569c 302 if(addressCode == SUCCESS) {
AxedaCorp 0:65004368569c 303 host_address = address;
AxedaCorp 0:65004368569c 304 } else {
AxedaCorp 0:65004368569c 305 printf("[ERROR] Host address could not be set\r\n");
AxedaCorp 0:65004368569c 306 }
AxedaCorp 0:65004368569c 307
AxedaCorp 0:65004368569c 308 // Try and Connect
AxedaCorp 0:65004368569c 309 std::string sMode;
AxedaCorp 0:65004368569c 310 std::string sOpenSocketCmd;
AxedaCorp 0:65004368569c 311 if(mode == TCP) {
AxedaCorp 0:65004368569c 312 sOpenSocketCmd = "AT#OTCP=1";
AxedaCorp 0:65004368569c 313 sMode = "TCP";
AxedaCorp 0:65004368569c 314 } else {
AxedaCorp 0:65004368569c 315 sOpenSocketCmd = "AT#OUDP";
AxedaCorp 0:65004368569c 316 sMode = "UDP";
AxedaCorp 0:65004368569c 317 }
AxedaCorp 0:65004368569c 318
AxedaCorp 0:65004368569c 319 string response = sendCommand(sOpenSocketCmd, 30000);
AxedaCorp 0:65004368569c 320 if (response.find("Ok_Info_WaitingForData") != string::npos) {
AxedaCorp 0:65004368569c 321 printf("[INFO] Opened %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
AxedaCorp 0:65004368569c 322 socketOpened = true;
AxedaCorp 0:65004368569c 323 } else {
AxedaCorp 0:65004368569c 324 printf("[WARNING] Unable to open %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
AxedaCorp 0:65004368569c 325 socketOpened = false;
AxedaCorp 0:65004368569c 326 }
AxedaCorp 0:65004368569c 327
AxedaCorp 0:65004368569c 328 return socketOpened;
AxedaCorp 0:65004368569c 329 }
AxedaCorp 0:65004368569c 330
AxedaCorp 0:65004368569c 331 bool Cellular::isOpen()
AxedaCorp 0:65004368569c 332 {
AxedaCorp 0:65004368569c 333 if(io->readable()) {
AxedaCorp 0:65004368569c 334 printf("[DEBUG] Assuming open, data available to read.\n\r");
AxedaCorp 0:65004368569c 335 return true;
AxedaCorp 0:65004368569c 336 }
AxedaCorp 0:65004368569c 337 return socketOpened;
AxedaCorp 0:65004368569c 338 }
AxedaCorp 0:65004368569c 339
AxedaCorp 0:65004368569c 340 bool Cellular::close()
AxedaCorp 0:65004368569c 341 {
AxedaCorp 0:65004368569c 342 if(io == NULL) {
AxedaCorp 0:65004368569c 343 printf("[ERROR] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 344 return false;
AxedaCorp 0:65004368569c 345 }
AxedaCorp 0:65004368569c 346
AxedaCorp 0:65004368569c 347 if(!socketOpened) {
AxedaCorp 0:65004368569c 348 printf("[WARNING] Socket close() called, but socket was not open\r\n");
AxedaCorp 0:65004368569c 349 return true;
AxedaCorp 0:65004368569c 350 }
AxedaCorp 0:65004368569c 351
AxedaCorp 0:65004368569c 352 if(!socketCloseable) {
AxedaCorp 0:65004368569c 353 printf("[ERROR] Socket is not closeable\r\n");
AxedaCorp 0:65004368569c 354 return false;
AxedaCorp 0:65004368569c 355 }
AxedaCorp 0:65004368569c 356
AxedaCorp 0:65004368569c 357
AxedaCorp 0:65004368569c 358
AxedaCorp 0:65004368569c 359 if(io->write(ETX, 1000) != 1) {
AxedaCorp 0:65004368569c 360 printf("[ERROR] Timed out attempting to close socket\r\n");
AxedaCorp 0:65004368569c 361 return false;
AxedaCorp 0:65004368569c 362 }
AxedaCorp 0:65004368569c 363
AxedaCorp 0:65004368569c 364 Timer tmr;
AxedaCorp 0:65004368569c 365 int counter = 0;
AxedaCorp 0:65004368569c 366 char tmp[256];
AxedaCorp 0:65004368569c 367 tmr.start();
AxedaCorp 0:65004368569c 368 do {
AxedaCorp 0:65004368569c 369 if(socketOpened == false) {
AxedaCorp 0:65004368569c 370 break;
AxedaCorp 0:65004368569c 371 }
AxedaCorp 0:65004368569c 372 read(tmp, 256, 1000);
AxedaCorp 0:65004368569c 373 } while(counter++ < 10);
AxedaCorp 0:65004368569c 374
AxedaCorp 0:65004368569c 375 io->rxClear();
AxedaCorp 0:65004368569c 376 io->txClear();
AxedaCorp 0:65004368569c 377
AxedaCorp 0:65004368569c 378 socketOpened = false;
AxedaCorp 0:65004368569c 379 return true;
AxedaCorp 0:65004368569c 380 }
AxedaCorp 0:65004368569c 381
AxedaCorp 0:65004368569c 382 int Cellular::read(char* data, int max, int timeout)
AxedaCorp 0:65004368569c 383 {
AxedaCorp 0:65004368569c 384 if(io == NULL) {
AxedaCorp 0:65004368569c 385 printf("[ERROR] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 386 return -1;
AxedaCorp 0:65004368569c 387 }
AxedaCorp 0:65004368569c 388
AxedaCorp 0:65004368569c 389 //Check that nothing is in the rx buffer
AxedaCorp 0:65004368569c 390 if(!socketOpened && !io->readable()) {
AxedaCorp 0:65004368569c 391 printf("[ERROR] Socket is not open\r\n");
AxedaCorp 0:65004368569c 392 return -1;
AxedaCorp 0:65004368569c 393 }
AxedaCorp 0:65004368569c 394
AxedaCorp 0:65004368569c 395 int bytesRead = 0;
AxedaCorp 0:65004368569c 396
AxedaCorp 0:65004368569c 397 if(timeout >= 0) {
AxedaCorp 0:65004368569c 398 bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
AxedaCorp 0:65004368569c 399 } else {
AxedaCorp 0:65004368569c 400 bytesRead = io->read(data, max);
AxedaCorp 0:65004368569c 401 }
AxedaCorp 0:65004368569c 402
AxedaCorp 0:65004368569c 403 if(bytesRead > 0 && socketCloseable) {
AxedaCorp 0:65004368569c 404 //Remove escape characters
AxedaCorp 0:65004368569c 405 int index = 0;
AxedaCorp 0:65004368569c 406 bool escapeFlag = false;
AxedaCorp 0:65004368569c 407 for(int i = 0; i < bytesRead; i++) {
AxedaCorp 0:65004368569c 408 if(data[i] == DLE || data[i] == ETX) {
AxedaCorp 0:65004368569c 409 if(escapeFlag == true) {
AxedaCorp 0:65004368569c 410 //This character has been escaped
AxedaCorp 0:65004368569c 411 escapeFlag = false;
AxedaCorp 0:65004368569c 412 } else if(data[bytesRead] == DLE) {
AxedaCorp 0:65004368569c 413 //Found escape character
AxedaCorp 0:65004368569c 414 escapeFlag = true;
AxedaCorp 0:65004368569c 415 continue;
AxedaCorp 0:65004368569c 416 } else {
AxedaCorp 0:65004368569c 417 //ETX sent without escape -> Socket closed
AxedaCorp 0:65004368569c 418 printf("[INFO] Read ETX character without DLE escape. Socket closed\r\n");
AxedaCorp 0:65004368569c 419 socketOpened = false;
AxedaCorp 0:65004368569c 420 continue;
AxedaCorp 0:65004368569c 421 }
AxedaCorp 0:65004368569c 422 }
AxedaCorp 0:65004368569c 423
AxedaCorp 0:65004368569c 424 if(index != i) {
AxedaCorp 0:65004368569c 425 data[index] = data[i];
AxedaCorp 0:65004368569c 426 }
AxedaCorp 0:65004368569c 427 index++;
AxedaCorp 0:65004368569c 428 }
AxedaCorp 0:65004368569c 429 bytesRead = index;
AxedaCorp 0:65004368569c 430 }
AxedaCorp 0:65004368569c 431
AxedaCorp 0:65004368569c 432 //Scan for socket closed message
AxedaCorp 0:65004368569c 433 for(size_t i = 0; i < bytesRead; i++) {
AxedaCorp 0:65004368569c 434 if(data[i] == 'O') {
AxedaCorp 0:65004368569c 435 if(strstr(&data[i], "Ok_Info_SocketClosed")) {
AxedaCorp 0:65004368569c 436 printf("[INFO] Found socket closed message. Socket closed\r\n");
AxedaCorp 0:65004368569c 437 //Close socket and Cut Off End of Message
AxedaCorp 0:65004368569c 438 socketOpened = false;
AxedaCorp 0:65004368569c 439 data[i] = '\0';
AxedaCorp 0:65004368569c 440 bytesRead = i;
AxedaCorp 0:65004368569c 441 break;
AxedaCorp 0:65004368569c 442 }
AxedaCorp 0:65004368569c 443 }
AxedaCorp 0:65004368569c 444 }
AxedaCorp 0:65004368569c 445 return bytesRead;
AxedaCorp 0:65004368569c 446 }
AxedaCorp 0:65004368569c 447
AxedaCorp 0:65004368569c 448 int Cellular::write(const char* data, int length, int timeout)
AxedaCorp 0:65004368569c 449 {
AxedaCorp 0:65004368569c 450 if(io == NULL) {
AxedaCorp 0:65004368569c 451 printf("[ERROR] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 452 return -1;
AxedaCorp 0:65004368569c 453 }
AxedaCorp 0:65004368569c 454
AxedaCorp 0:65004368569c 455 if(!socketOpened) {
AxedaCorp 0:65004368569c 456 printf("[ERROR] Socket is not open\r\n");
AxedaCorp 0:65004368569c 457 return -1;
AxedaCorp 0:65004368569c 458 }
AxedaCorp 0:65004368569c 459
AxedaCorp 0:65004368569c 460 //In order to avoid allocating another buffer, capture indices of
AxedaCorp 0:65004368569c 461 //characters to escape during write
AxedaCorp 0:65004368569c 462 int specialWritten = 0;
AxedaCorp 0:65004368569c 463 std::vector<int> vSpecial;
AxedaCorp 0:65004368569c 464 if(socketCloseable) {
AxedaCorp 0:65004368569c 465 for(int i = 0; i < length; i++) {
AxedaCorp 0:65004368569c 466 if(data[i] == ETX || data[i] == DLE) {
AxedaCorp 0:65004368569c 467 //Push back index of special characters
AxedaCorp 0:65004368569c 468 vSpecial.push_back(i);
AxedaCorp 0:65004368569c 469 }
AxedaCorp 0:65004368569c 470 }
AxedaCorp 0:65004368569c 471 }
AxedaCorp 0:65004368569c 472
AxedaCorp 0:65004368569c 473 int bytesWritten = 0;
AxedaCorp 0:65004368569c 474 if(timeout >= 0) {
AxedaCorp 0:65004368569c 475 Timer tmr;
AxedaCorp 0:65004368569c 476 tmr.start();
AxedaCorp 0:65004368569c 477 do {
AxedaCorp 0:65004368569c 478 int available = io->writeable();
AxedaCorp 0:65004368569c 479 if (available > 0) {
AxedaCorp 0:65004368569c 480 if(specialWritten < vSpecial.size()) {
AxedaCorp 0:65004368569c 481 //Check if current index is at a special character
AxedaCorp 0:65004368569c 482 if(bytesWritten == vSpecial[specialWritten]) {
AxedaCorp 0:65004368569c 483 if(available < 2) {
AxedaCorp 0:65004368569c 484 //Requires at least two bytes of space
AxedaCorp 0:65004368569c 485 wait(0.05);
AxedaCorp 0:65004368569c 486 continue;
AxedaCorp 0:65004368569c 487 }
AxedaCorp 0:65004368569c 488 //Ready to write special character
AxedaCorp 0:65004368569c 489 if(io->write(DLE)) {
AxedaCorp 0:65004368569c 490 specialWritten++;
AxedaCorp 0:65004368569c 491 if(io->write(data[bytesWritten])) {
AxedaCorp 0:65004368569c 492 bytesWritten++;
AxedaCorp 0:65004368569c 493 }
AxedaCorp 0:65004368569c 494 } else {
AxedaCorp 0:65004368569c 495 //Unable to write escape character, try again next round
AxedaCorp 0:65004368569c 496 wait(0.05);
AxedaCorp 0:65004368569c 497 }
AxedaCorp 0:65004368569c 498 } else {
AxedaCorp 0:65004368569c 499 //We want to write all the way up to the next special character
AxedaCorp 0:65004368569c 500 int relativeIndex = vSpecial[specialWritten] - bytesWritten;
AxedaCorp 0:65004368569c 501 int size = MIN(available, relativeIndex);
AxedaCorp 0:65004368569c 502 bytesWritten += io->write(&data[bytesWritten], size);
AxedaCorp 0:65004368569c 503 }
AxedaCorp 0:65004368569c 504 } else {
AxedaCorp 0:65004368569c 505 int size = MIN(available, length - bytesWritten);
AxedaCorp 0:65004368569c 506 bytesWritten += io->write(&data[bytesWritten], size);
AxedaCorp 0:65004368569c 507 }
AxedaCorp 0:65004368569c 508 } else {
AxedaCorp 0:65004368569c 509 wait(0.05);
AxedaCorp 0:65004368569c 510 }
AxedaCorp 0:65004368569c 511 } while (tmr.read_ms() <= timeout && bytesWritten < length);
AxedaCorp 0:65004368569c 512 } else {
AxedaCorp 0:65004368569c 513 for(int i = 0; i < vSpecial.size(); i++) {
AxedaCorp 0:65004368569c 514 //Write up to the special character, then write the special character
AxedaCorp 0:65004368569c 515 int size = vSpecial[i] - bytesWritten;
AxedaCorp 0:65004368569c 516 int currentWritten = io->write(&data[bytesWritten], size);
AxedaCorp 0:65004368569c 517 bytesWritten += currentWritten;
AxedaCorp 0:65004368569c 518 if(currentWritten != size) {
AxedaCorp 0:65004368569c 519 //Failed to write up to the special character.
AxedaCorp 0:65004368569c 520 return bytesWritten;
AxedaCorp 0:65004368569c 521 }
AxedaCorp 0:65004368569c 522 if(io->write(DLE) && io->write(data[bytesWritten])) {
AxedaCorp 0:65004368569c 523 bytesWritten++;
AxedaCorp 0:65004368569c 524 } else {
AxedaCorp 0:65004368569c 525 //Failed to write the special character.
AxedaCorp 0:65004368569c 526 return bytesWritten;
AxedaCorp 0:65004368569c 527 }
AxedaCorp 0:65004368569c 528 }
AxedaCorp 0:65004368569c 529
AxedaCorp 0:65004368569c 530 bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
AxedaCorp 0:65004368569c 531 }
AxedaCorp 0:65004368569c 532
AxedaCorp 0:65004368569c 533 return bytesWritten;
AxedaCorp 0:65004368569c 534 }
AxedaCorp 0:65004368569c 535
AxedaCorp 0:65004368569c 536 unsigned int Cellular::readable()
AxedaCorp 0:65004368569c 537 {
AxedaCorp 0:65004368569c 538 if(io == NULL) {
AxedaCorp 0:65004368569c 539 printf("[WARNING] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 540 return 0;
AxedaCorp 0:65004368569c 541 }
AxedaCorp 0:65004368569c 542 if(!socketOpened && !io->readable()) {
AxedaCorp 0:65004368569c 543 printf("[WARNING] Socket is not open\r\n");
AxedaCorp 0:65004368569c 544 return 0;
AxedaCorp 0:65004368569c 545 }
AxedaCorp 0:65004368569c 546 return io->readable();
AxedaCorp 0:65004368569c 547 }
AxedaCorp 0:65004368569c 548
AxedaCorp 0:65004368569c 549 unsigned int Cellular::writeable()
AxedaCorp 0:65004368569c 550 {
AxedaCorp 0:65004368569c 551 if(io == NULL) {
AxedaCorp 0:65004368569c 552 printf("[WARNING] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 553 return 0;
AxedaCorp 0:65004368569c 554 }
AxedaCorp 0:65004368569c 555 if(!socketOpened) {
AxedaCorp 0:65004368569c 556 printf("[WARNING] Socket is not open\r\n");
AxedaCorp 0:65004368569c 557 return 0;
AxedaCorp 0:65004368569c 558 }
AxedaCorp 0:65004368569c 559
AxedaCorp 0:65004368569c 560 return io->writeable();
AxedaCorp 0:65004368569c 561 }
AxedaCorp 0:65004368569c 562
AxedaCorp 0:65004368569c 563 void Cellular::reset()
AxedaCorp 0:65004368569c 564 {
AxedaCorp 0:65004368569c 565 disconnect();
AxedaCorp 0:65004368569c 566 Code code = sendBasicCommand("AT#RESET=0", 10000);
AxedaCorp 0:65004368569c 567 if(code != SUCCESS) {
AxedaCorp 0:65004368569c 568 printf("[ERROR] Socket Modem did not accept RESET command\n\r");
AxedaCorp 0:65004368569c 569 } else {
AxedaCorp 0:65004368569c 570 printf("[WARNING] Socket Modem is resetting, allow 30 seconds for it to come back\n\r");
AxedaCorp 0:65004368569c 571 }
AxedaCorp 0:65004368569c 572 }
AxedaCorp 0:65004368569c 573
AxedaCorp 0:65004368569c 574 std::string Cellular::getDeviceIP()
AxedaCorp 0:65004368569c 575 {
AxedaCorp 0:65004368569c 576 return local_address;
AxedaCorp 0:65004368569c 577 }
AxedaCorp 0:65004368569c 578
AxedaCorp 0:65004368569c 579 Code Cellular::test()
AxedaCorp 0:65004368569c 580 {
AxedaCorp 0:65004368569c 581 Code code;
AxedaCorp 0:65004368569c 582 int i = 0;
AxedaCorp 0:65004368569c 583 while (sendBasicCommand("AT", 1000) != SUCCESS) {
AxedaCorp 0:65004368569c 584 i++;
AxedaCorp 0:65004368569c 585 if (i >= 30) {
AxedaCorp 0:65004368569c 586 printf("[ERROR] Could not talk to radio after 30 tries\r\n");
AxedaCorp 0:65004368569c 587 i = 0;
AxedaCorp 0:65004368569c 588 }
AxedaCorp 0:65004368569c 589 wait(1);
AxedaCorp 0:65004368569c 590 }
AxedaCorp 0:65004368569c 591
AxedaCorp 0:65004368569c 592 return SUCCESS;
AxedaCorp 0:65004368569c 593 }
AxedaCorp 0:65004368569c 594
AxedaCorp 0:65004368569c 595 Code Cellular::echo(bool state)
AxedaCorp 0:65004368569c 596 {
AxedaCorp 0:65004368569c 597 Code code;
AxedaCorp 0:65004368569c 598 if (state) {
AxedaCorp 0:65004368569c 599 code = sendBasicCommand("ATE0", 1000);
AxedaCorp 0:65004368569c 600 echoMode = (code == SUCCESS) ? false : echoMode;
AxedaCorp 0:65004368569c 601 } else {
AxedaCorp 0:65004368569c 602 code = sendBasicCommand("ATE1", 1000);
AxedaCorp 0:65004368569c 603 echoMode = (code == SUCCESS) ? true : echoMode;
AxedaCorp 0:65004368569c 604 }
AxedaCorp 0:65004368569c 605 return code;
AxedaCorp 0:65004368569c 606 }
AxedaCorp 0:65004368569c 607
AxedaCorp 0:65004368569c 608 int Cellular::getSignalStrength()
AxedaCorp 0:65004368569c 609 {
AxedaCorp 0:65004368569c 610 string response = sendCommand("AT+CSQ", 1000);
AxedaCorp 0:65004368569c 611 if (response.find("OK") == string::npos) {
AxedaCorp 0:65004368569c 612 return -1;
AxedaCorp 0:65004368569c 613 }
AxedaCorp 0:65004368569c 614 int start = response.find(':');
AxedaCorp 0:65004368569c 615 int stop = response.find(',', start);
AxedaCorp 0:65004368569c 616 string signal = response.substr(start + 2, stop - start - 2);
AxedaCorp 0:65004368569c 617 int value;
AxedaCorp 0:65004368569c 618 sscanf(signal.c_str(), "%d", &value);
AxedaCorp 0:65004368569c 619 return value;
AxedaCorp 0:65004368569c 620 }
AxedaCorp 0:65004368569c 621
AxedaCorp 0:65004368569c 622 Cellular::Registration Cellular::getRegistration()
AxedaCorp 0:65004368569c 623 {
AxedaCorp 0:65004368569c 624 string response = sendCommand("AT+CREG?", 5000);
AxedaCorp 0:65004368569c 625 if (response.find("OK") == string::npos) {
AxedaCorp 0:65004368569c 626 return UNKNOWN;
AxedaCorp 0:65004368569c 627 }
AxedaCorp 0:65004368569c 628 int start = response.find(',');
AxedaCorp 0:65004368569c 629 int stop = response.find(' ', start);
AxedaCorp 0:65004368569c 630 string regStat = response.substr(start + 1, stop - start - 1);
AxedaCorp 0:65004368569c 631 int value;
AxedaCorp 0:65004368569c 632 sscanf(regStat.c_str(), "%d", &value);
AxedaCorp 0:65004368569c 633 switch (value) {
AxedaCorp 0:65004368569c 634 case 0:
AxedaCorp 0:65004368569c 635 return NOT_REGISTERED;
AxedaCorp 0:65004368569c 636 case 1:
AxedaCorp 0:65004368569c 637 return REGISTERED;
AxedaCorp 0:65004368569c 638 case 2:
AxedaCorp 0:65004368569c 639 return SEARCHING;
AxedaCorp 0:65004368569c 640 case 3:
AxedaCorp 0:65004368569c 641 return DENIED;
AxedaCorp 0:65004368569c 642 case 4:
AxedaCorp 0:65004368569c 643 return UNKNOWN;
AxedaCorp 0:65004368569c 644 case 5:
AxedaCorp 0:65004368569c 645 return ROAMING;
AxedaCorp 0:65004368569c 646 }
AxedaCorp 0:65004368569c 647 return UNKNOWN;
AxedaCorp 0:65004368569c 648 }
AxedaCorp 0:65004368569c 649
AxedaCorp 0:65004368569c 650 Code Cellular::setApn(const std::string& apn)
AxedaCorp 0:65004368569c 651 {
AxedaCorp 0:65004368569c 652 Code code = sendBasicCommand("AT#APNSERV=\"" + apn + "\"", 1000);
AxedaCorp 0:65004368569c 653 if (code != SUCCESS) {
AxedaCorp 0:65004368569c 654 return code;
AxedaCorp 0:65004368569c 655 }
AxedaCorp 0:65004368569c 656 this->apn = apn;
AxedaCorp 0:65004368569c 657 return code;
AxedaCorp 0:65004368569c 658 }
AxedaCorp 0:65004368569c 659
AxedaCorp 0:65004368569c 660
AxedaCorp 0:65004368569c 661 Code Cellular::setDns(const std::string& primary, const std::string& secondary)
AxedaCorp 0:65004368569c 662 {
AxedaCorp 0:65004368569c 663 return sendBasicCommand("AT#DNS=1," + primary + "," + secondary, 1000);
AxedaCorp 0:65004368569c 664 }
AxedaCorp 0:65004368569c 665
AxedaCorp 0:65004368569c 666 bool Cellular::ping(const std::string& address)
AxedaCorp 0:65004368569c 667 {
AxedaCorp 0:65004368569c 668 char buffer[256] = {0};
AxedaCorp 0:65004368569c 669 Code code;
AxedaCorp 0:65004368569c 670
AxedaCorp 0:65004368569c 671 code = sendBasicCommand("AT#PINGREMOTE=\"" + address + "\"", 1000);
AxedaCorp 0:65004368569c 672 if (code != SUCCESS) {
AxedaCorp 0:65004368569c 673 return false;
AxedaCorp 0:65004368569c 674 }
AxedaCorp 0:65004368569c 675
AxedaCorp 0:65004368569c 676 sprintf(buffer, "AT#PINGNUM=%d", 1);
AxedaCorp 0:65004368569c 677 code = sendBasicCommand(buffer , 1000);
AxedaCorp 0:65004368569c 678 if (code != SUCCESS) {
AxedaCorp 0:65004368569c 679 return false;
AxedaCorp 0:65004368569c 680 }
AxedaCorp 0:65004368569c 681
AxedaCorp 0:65004368569c 682 sprintf(buffer, "AT#PINGDELAY=%d", PINGDELAY);
AxedaCorp 0:65004368569c 683 code = sendBasicCommand(buffer , 1000);
AxedaCorp 0:65004368569c 684 if (code != SUCCESS) {
AxedaCorp 0:65004368569c 685 return false;
AxedaCorp 0:65004368569c 686 }
AxedaCorp 0:65004368569c 687
AxedaCorp 0:65004368569c 688 std::string response;
AxedaCorp 0:65004368569c 689 for (int i = 0; i < PINGNUM; i++) {
AxedaCorp 0:65004368569c 690 response = sendCommand("AT#PING", PINGDELAY * 1000);
AxedaCorp 0:65004368569c 691 if (response.find("alive") != std::string::npos) {
AxedaCorp 0:65004368569c 692 return true;
AxedaCorp 0:65004368569c 693 }
AxedaCorp 0:65004368569c 694 }
AxedaCorp 0:65004368569c 695 return false;
AxedaCorp 0:65004368569c 696 }
AxedaCorp 0:65004368569c 697
AxedaCorp 0:65004368569c 698 Code Cellular::setSocketCloseable(bool enabled)
AxedaCorp 0:65004368569c 699 {
AxedaCorp 0:65004368569c 700 if(socketCloseable == enabled) {
AxedaCorp 0:65004368569c 701 return SUCCESS;
AxedaCorp 0:65004368569c 702 }
AxedaCorp 0:65004368569c 703
AxedaCorp 0:65004368569c 704 if(socketOpened) {
AxedaCorp 0:65004368569c 705 printf("[ERROR] socket is already opened. Can not set closeable\r\n");
AxedaCorp 0:65004368569c 706 return ERROR;
AxedaCorp 0:65004368569c 707 }
AxedaCorp 0:65004368569c 708
AxedaCorp 0:65004368569c 709 socketCloseable = enabled;
AxedaCorp 0:65004368569c 710
AxedaCorp 0:65004368569c 711 return SUCCESS;
AxedaCorp 0:65004368569c 712 }
AxedaCorp 0:65004368569c 713
AxedaCorp 0:65004368569c 714 Code Cellular::sendSMS(const Sms& sms)
AxedaCorp 0:65004368569c 715 {
AxedaCorp 0:65004368569c 716 return sendSMS(sms.phoneNumber, sms.message);
AxedaCorp 0:65004368569c 717 }
AxedaCorp 0:65004368569c 718
AxedaCorp 0:65004368569c 719 Code Cellular::sendSMS(const std::string& phoneNumber, const std::string& message)
AxedaCorp 0:65004368569c 720 {
AxedaCorp 0:65004368569c 721 Code code = sendBasicCommand("AT+CMGF=1", 1000);
AxedaCorp 0:65004368569c 722 if (code != SUCCESS) {
AxedaCorp 0:65004368569c 723 return code;
AxedaCorp 0:65004368569c 724 }
AxedaCorp 0:65004368569c 725 string cmd = "AT+CMGS=\"+";
AxedaCorp 0:65004368569c 726 cmd.append(phoneNumber);
AxedaCorp 0:65004368569c 727 cmd.append("\"");
AxedaCorp 0:65004368569c 728 string response1 = sendCommand(cmd, 1000);
AxedaCorp 0:65004368569c 729 if (response1.find('>') == string::npos) {
AxedaCorp 0:65004368569c 730 return NO_RESPONSE;
AxedaCorp 0:65004368569c 731 }
AxedaCorp 0:65004368569c 732 wait(.2);
AxedaCorp 0:65004368569c 733 string response2 = sendCommand(message, 4000, CTRL_Z);
AxedaCorp 0:65004368569c 734 printf("SMS Response: %s\r\n", response2.c_str());
AxedaCorp 0:65004368569c 735 if (response2.find("+CMGS:") == string::npos) {
AxedaCorp 0:65004368569c 736 return FAILURE;
AxedaCorp 0:65004368569c 737 }
AxedaCorp 0:65004368569c 738 return SUCCESS;
AxedaCorp 0:65004368569c 739 }
AxedaCorp 0:65004368569c 740
AxedaCorp 0:65004368569c 741 std::vector<Cellular::Sms> Cellular::getReceivedSms()
AxedaCorp 0:65004368569c 742 {
AxedaCorp 0:65004368569c 743 int smsNumber = 0;
AxedaCorp 0:65004368569c 744 std::vector<Sms> vSms;
AxedaCorp 0:65004368569c 745 std::string received = sendCommand("AT+CMGL=\"ALL\"", 4000);
AxedaCorp 0:65004368569c 746 size_t pos = received.find("+CMGL: ");
AxedaCorp 0:65004368569c 747
AxedaCorp 0:65004368569c 748 while (pos != std::string::npos) {
AxedaCorp 0:65004368569c 749 Cellular::Sms sms;
AxedaCorp 0:65004368569c 750 std::string line(Text::getLine(received, pos, pos));
AxedaCorp 0:65004368569c 751 //printf("[DEBUG] Top of SMS Parse Loop. LINE[%s]\r\n", line.c_str());
AxedaCorp 0:65004368569c 752 if(line.find("+CMGL: ") == std::string::npos) {
AxedaCorp 0:65004368569c 753 continue;
AxedaCorp 0:65004368569c 754 }
AxedaCorp 0:65004368569c 755
AxedaCorp 0:65004368569c 756 //Start of SMS message
AxedaCorp 0:65004368569c 757 std::vector<std::string> vSmsParts = Text::split(line, ',');
AxedaCorp 0:65004368569c 758 if(vSmsParts.size() != 6) {
AxedaCorp 0:65004368569c 759 printf("[WARNING] Expected 6 commas. SMS[%d] DATA[%s]. Continuing ...\r\n", smsNumber, line.c_str());
AxedaCorp 0:65004368569c 760 continue;
AxedaCorp 0:65004368569c 761 }
AxedaCorp 0:65004368569c 762
AxedaCorp 0:65004368569c 763 sms.phoneNumber = vSmsParts[2];
AxedaCorp 0:65004368569c 764 sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5];
AxedaCorp 0:65004368569c 765
AxedaCorp 0:65004368569c 766 if(pos == std::string::npos) {
AxedaCorp 0:65004368569c 767 printf("[WARNING] Expected SMS body. SMS[%d]. Leaving ...\r\n", smsNumber);
AxedaCorp 0:65004368569c 768 break;
AxedaCorp 0:65004368569c 769 }
AxedaCorp 0:65004368569c 770 //Check for the start of the next SMS message
AxedaCorp 0:65004368569c 771 size_t bodyEnd = received.find("\r\n+CMGL: ", pos);
AxedaCorp 0:65004368569c 772 if(bodyEnd == std::string::npos) {
AxedaCorp 0:65004368569c 773 //printf("[DEBUG] Parsing Last SMS. SMS[%d]\r\n", smsNumber);
AxedaCorp 0:65004368569c 774 //This must be the last SMS message
AxedaCorp 0:65004368569c 775 bodyEnd = received.find("\r\n\r\nOK", pos);
AxedaCorp 0:65004368569c 776 }
AxedaCorp 0:65004368569c 777
AxedaCorp 0:65004368569c 778 //Safety check that we found the boundary of this current SMS message
AxedaCorp 0:65004368569c 779 if(bodyEnd != std::string::npos) {
AxedaCorp 0:65004368569c 780 sms.message = received.substr(pos, bodyEnd - pos);
AxedaCorp 0:65004368569c 781 } else {
AxedaCorp 0:65004368569c 782 sms.message = received.substr(pos);
AxedaCorp 0:65004368569c 783 printf("[WARNING] Expected to find end of SMS list. SMS[%d] DATA[%s].\r\n", smsNumber, sms.message.c_str());
AxedaCorp 0:65004368569c 784 }
AxedaCorp 0:65004368569c 785 vSms.push_back(sms);
AxedaCorp 0:65004368569c 786 pos = bodyEnd;
AxedaCorp 0:65004368569c 787 //printf("[DEBUG] Parsed SMS[%d]. Starting Next at position [%d]\r\n", smsNumber, pos);
AxedaCorp 0:65004368569c 788 smsNumber++;
AxedaCorp 0:65004368569c 789 }
AxedaCorp 0:65004368569c 790 printf("Received %d SMS\r\n", smsNumber);
AxedaCorp 0:65004368569c 791 return vSms;
AxedaCorp 0:65004368569c 792 }
AxedaCorp 0:65004368569c 793
AxedaCorp 0:65004368569c 794 Code Cellular::deleteOnlyReceivedReadSms()
AxedaCorp 0:65004368569c 795 {
AxedaCorp 0:65004368569c 796 return sendBasicCommand("AT+CMGD=1,1", 1000);
AxedaCorp 0:65004368569c 797 }
AxedaCorp 0:65004368569c 798
AxedaCorp 0:65004368569c 799 Code Cellular::deleteAllReceivedSms()
AxedaCorp 0:65004368569c 800 {
AxedaCorp 0:65004368569c 801 return sendBasicCommand("AT+CMGD=1,4", 1000);
AxedaCorp 0:65004368569c 802 }
AxedaCorp 0:65004368569c 803
AxedaCorp 0:65004368569c 804 Code Cellular::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc)
AxedaCorp 0:65004368569c 805 {
AxedaCorp 0:65004368569c 806 if(socketOpened) {
AxedaCorp 0:65004368569c 807 printf("[ERROR] socket is open. Can not send AT commands\r\n");
AxedaCorp 0:65004368569c 808 return ERROR;
AxedaCorp 0:65004368569c 809 }
AxedaCorp 0:65004368569c 810
AxedaCorp 0:65004368569c 811 string response = sendCommand(command, timeoutMillis, esc);
AxedaCorp 0:65004368569c 812 if (response.size() == 0) {
AxedaCorp 0:65004368569c 813 return NO_RESPONSE;
AxedaCorp 0:65004368569c 814 } else if (response.find("OK") != string::npos) {
AxedaCorp 0:65004368569c 815 return SUCCESS;
AxedaCorp 0:65004368569c 816 } else if (response.find("ERROR") != string::npos) {
AxedaCorp 0:65004368569c 817 return ERROR;
AxedaCorp 0:65004368569c 818 } else {
AxedaCorp 0:65004368569c 819 return FAILURE;
AxedaCorp 0:65004368569c 820 }
AxedaCorp 0:65004368569c 821 }
AxedaCorp 0:65004368569c 822
AxedaCorp 0:65004368569c 823 string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
AxedaCorp 0:65004368569c 824 {
AxedaCorp 0:65004368569c 825 if(io == NULL) {
AxedaCorp 0:65004368569c 826 printf("[ERROR] MTSBufferedIO not set\r\n");
AxedaCorp 0:65004368569c 827 return "";
AxedaCorp 0:65004368569c 828 }
AxedaCorp 0:65004368569c 829 if(socketOpened) {
AxedaCorp 0:65004368569c 830 printf("[ERROR] socket is open. Can not send AT commands\r\n");
AxedaCorp 0:65004368569c 831 return "";
AxedaCorp 0:65004368569c 832 }
AxedaCorp 0:65004368569c 833
AxedaCorp 0:65004368569c 834 io->rxClear();
AxedaCorp 0:65004368569c 835 io->txClear();
AxedaCorp 0:65004368569c 836 std::string result;
AxedaCorp 0:65004368569c 837
AxedaCorp 0:65004368569c 838 //Attempt to write command
AxedaCorp 0:65004368569c 839 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
AxedaCorp 0:65004368569c 840 //Failed to write command
AxedaCorp 0:65004368569c 841 if (command != "AT" && command != "at") {
AxedaCorp 0:65004368569c 842 printf("[ERROR] failed to send command to radio within %d milliseconds\r\n", timeoutMillis);
AxedaCorp 0:65004368569c 843 }
AxedaCorp 0:65004368569c 844 return "";
AxedaCorp 0:65004368569c 845 }
AxedaCorp 0:65004368569c 846
AxedaCorp 0:65004368569c 847 //Send Escape Character
AxedaCorp 0:65004368569c 848 if (esc != 0x00) {
AxedaCorp 0:65004368569c 849 if(io->write(esc, timeoutMillis) != 1) {
AxedaCorp 0:65004368569c 850 if (command != "AT" && command != "at") {
AxedaCorp 0:65004368569c 851 printf("[ERROR] failed to send character '%c' (0x%02X) to radio within %d milliseconds\r\n", esc, esc, timeoutMillis);
AxedaCorp 0:65004368569c 852 }
AxedaCorp 0:65004368569c 853 return "";
AxedaCorp 0:65004368569c 854 }
AxedaCorp 0:65004368569c 855 }
AxedaCorp 0:65004368569c 856
AxedaCorp 0:65004368569c 857 int timer = 0;
AxedaCorp 0:65004368569c 858 size_t previous = 0;
AxedaCorp 0:65004368569c 859 char tmp[256];
AxedaCorp 0:65004368569c 860 tmp[255] = 0;
AxedaCorp 0:65004368569c 861 bool started = !echoMode;
AxedaCorp 0:65004368569c 862 bool done = false;
AxedaCorp 0:65004368569c 863 do {
AxedaCorp 0:65004368569c 864 wait(0.1);
AxedaCorp 0:65004368569c 865 timer += 100;
AxedaCorp 0:65004368569c 866
AxedaCorp 0:65004368569c 867 previous = result.size();
AxedaCorp 0:65004368569c 868 //Make a non-blocking read call by passing timeout of zero
AxedaCorp 0:65004368569c 869 int size = io->read(tmp,255,0); //1 less than allocated (timeout is instant)
AxedaCorp 0:65004368569c 870 if(size > 0) {
AxedaCorp 0:65004368569c 871 result.append(tmp, size);
AxedaCorp 0:65004368569c 872 }
AxedaCorp 0:65004368569c 873 if(!started) {
AxedaCorp 0:65004368569c 874 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
AxedaCorp 0:65004368569c 875 if(result.size() > command.size() + 2) {
AxedaCorp 0:65004368569c 876 started = true;
AxedaCorp 0:65004368569c 877 }
AxedaCorp 0:65004368569c 878 } else {
AxedaCorp 0:65004368569c 879 done = (result.size() == previous);
AxedaCorp 0:65004368569c 880 }
AxedaCorp 0:65004368569c 881 if(timer >= timeoutMillis) {
AxedaCorp 0:65004368569c 882 if (command != "AT" && command != "at") {
AxedaCorp 0:65004368569c 883 printf("[WARNING] sendCommand [%s] timed out after %d milliseconds\r\n", command.c_str(), timeoutMillis);
AxedaCorp 0:65004368569c 884 }
AxedaCorp 0:65004368569c 885 done = true;
AxedaCorp 0:65004368569c 886 }
AxedaCorp 0:65004368569c 887 } while (!done);
AxedaCorp 0:65004368569c 888
AxedaCorp 0:65004368569c 889 return result;
AxedaCorp 0:65004368569c 890 }
AxedaCorp 0:65004368569c 891
AxedaCorp 0:65004368569c 892 std::string Cellular::getRegistrationNames(Registration registration)
AxedaCorp 0:65004368569c 893 {
AxedaCorp 0:65004368569c 894 switch(registration) {
AxedaCorp 0:65004368569c 895 case NOT_REGISTERED:
AxedaCorp 0:65004368569c 896 return "NOT_REGISTERED";
AxedaCorp 0:65004368569c 897 case REGISTERED:
AxedaCorp 0:65004368569c 898 return "REGISTERED";
AxedaCorp 0:65004368569c 899 case SEARCHING:
AxedaCorp 0:65004368569c 900 return "SEARCHING";
AxedaCorp 0:65004368569c 901 case DENIED:
AxedaCorp 0:65004368569c 902 return "DENIED";
AxedaCorp 0:65004368569c 903 case UNKNOWN:
AxedaCorp 0:65004368569c 904 return "UNKNOWN";
AxedaCorp 0:65004368569c 905 case ROAMING:
AxedaCorp 0:65004368569c 906 return "ROAMING";
AxedaCorp 0:65004368569c 907 default:
AxedaCorp 0:65004368569c 908 return "UNKNOWN ENUM";
AxedaCorp 0:65004368569c 909 }
AxedaCorp 0:65004368569c 910 }