Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Vanger
Date:
Mon Aug 11 16:03:19 2014 +0000
Revision:
52:2cb58398a4f9
Parent:
51:ffc556ba33f7
Child:
54:a6c738bfc391
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
Vanger 26:2b769ed8de4f 1 #include "mbed.h"
Vanger 26:2b769ed8de4f 2 #include "EasyIP.h"
Vanger 26:2b769ed8de4f 3 #include "MTSText.h"
Vanger 26:2b769ed8de4f 4 #include "MTSLog.h"
Vanger 26:2b769ed8de4f 5 #include "CellUtils.h"
Vanger 26:2b769ed8de4f 6
Vanger 26:2b769ed8de4f 7 using namespace mts;
Vanger 26:2b769ed8de4f 8
Vanger 26:2b769ed8de4f 9 EasyIP::EasyIP(Radio type)
Vanger 26:2b769ed8de4f 10 {
Vanger 26:2b769ed8de4f 11 this->type = type;
Vanger 26:2b769ed8de4f 12 io = NULL;
Vanger 26:2b769ed8de4f 13 dcd = NULL;
Vanger 26:2b769ed8de4f 14 dtr = NULL;
Vanger 26:2b769ed8de4f 15 resetLine = NULL;
Vanger 26:2b769ed8de4f 16 echoMode = true;
Vanger 26:2b769ed8de4f 17 pppConnected = false;
Vanger 26:2b769ed8de4f 18 socketMode = TCP;
Vanger 26:2b769ed8de4f 19 socketOpened = false;
Vanger 26:2b769ed8de4f 20 socketCloseable = true;
Vanger 26:2b769ed8de4f 21 local_port = 0;
Vanger 26:2b769ed8de4f 22 local_address = "";
Vanger 26:2b769ed8de4f 23 host_port = 0;
Vanger 26:2b769ed8de4f 24 }
Vanger 26:2b769ed8de4f 25
Vanger 26:2b769ed8de4f 26 EasyIP::~EasyIP()
Vanger 26:2b769ed8de4f 27 {
Vanger 26:2b769ed8de4f 28 if (dtr != NULL) {
Vanger 26:2b769ed8de4f 29 dtr->write(1);
Vanger 26:2b769ed8de4f 30 }
Vanger 26:2b769ed8de4f 31
Vanger 26:2b769ed8de4f 32 delete dcd;
Vanger 26:2b769ed8de4f 33 delete dtr;
Vanger 26:2b769ed8de4f 34 delete resetLine;
Vanger 26:2b769ed8de4f 35 }
Vanger 26:2b769ed8de4f 36
Vanger 26:2b769ed8de4f 37 //Initializes the MTS IO Buffer
Vanger 26:2b769ed8de4f 38 bool EasyIP::init(MTSBufferedIO* io)
Vanger 26:2b769ed8de4f 39 {
Vanger 26:2b769ed8de4f 40 if (! Cellular::init(io)) {
Vanger 26:2b769ed8de4f 41 return false;
Vanger 26:2b769ed8de4f 42 }
Vanger 26:2b769ed8de4f 43
Vanger 26:2b769ed8de4f 44 logDebug("radio type: %s", Cellular::getRadioNames(type).c_str());
Vanger 49:1fc51c53cebf 45 //Turns on the HW flow control
Vanger 41:8b9b5098696f 46 if(sendBasicCommand("AT&K3", 2000) != MTS_SUCCESS) {
Vanger 52:2cb58398a4f9 47 logWarning("Failed to enable serial flow control");
Vanger 35:257eb41405e1 48 }
Vanger 26:2b769ed8de4f 49 return true;
Vanger 26:2b769ed8de4f 50 }
Vanger 26:2b769ed8de4f 51
Vanger 26:2b769ed8de4f 52 bool EasyIP::connect()
Vanger 26:2b769ed8de4f 53 {
Vanger 33:3b6f3904dde0 54 //Check if APN is not set, if it is not, connect will not work.
Vanger 29:edc613ed3f2e 55 if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3) {
Vanger 29:edc613ed3f2e 56 if(apn.size() == 0) {
Vanger 29:edc613ed3f2e 57 logDebug("APN is not set");
Vanger 29:edc613ed3f2e 58 return false;
Vanger 29:edc613ed3f2e 59 }
Vanger 29:edc613ed3f2e 60 }
Vanger 29:edc613ed3f2e 61
Vanger 26:2b769ed8de4f 62 //Check if socket is open
Vanger 26:2b769ed8de4f 63 if(socketOpened) {
Vanger 26:2b769ed8de4f 64 return true;
Vanger 26:2b769ed8de4f 65 }
Vanger 26:2b769ed8de4f 66
Vanger 26:2b769ed8de4f 67 //Check if already connected
Vanger 26:2b769ed8de4f 68 if(isConnected()) {
Vanger 26:2b769ed8de4f 69 return true;
Vanger 26:2b769ed8de4f 70 }
Vanger 51:ffc556ba33f7 71
Vanger 26:2b769ed8de4f 72 Timer tmr;
Vanger 26:2b769ed8de4f 73 //Check Registration: AT+CREG? == 0,1
Vanger 26:2b769ed8de4f 74 tmr.start();
Vanger 26:2b769ed8de4f 75 do {
Vanger 26:2b769ed8de4f 76 Registration registration = getRegistration();
Vanger 26:2b769ed8de4f 77 if(registration != REGISTERED) {
Vanger 26:2b769ed8de4f 78 logTrace("Not Registered [%d] ... waiting", (int)registration);
Vanger 26:2b769ed8de4f 79 wait(1);
Vanger 26:2b769ed8de4f 80 } else {
Vanger 26:2b769ed8de4f 81 break;
Vanger 26:2b769ed8de4f 82 }
Vanger 30:1326b623919a 83 } while(tmr.read() < 30);
Vanger 51:ffc556ba33f7 84
Vanger 26:2b769ed8de4f 85 //Check RSSI: AT+CSQ
Vanger 26:2b769ed8de4f 86 tmr.reset();
Vanger 26:2b769ed8de4f 87 do {
Vanger 26:2b769ed8de4f 88 int rssi = getSignalStrength();
Vanger 26:2b769ed8de4f 89 logDebug("Signal strength: %d", rssi);
Vanger 51:ffc556ba33f7 90 if(rssi == 99 || rssi == -1) {
Vanger 26:2b769ed8de4f 91 logTrace("No Signal ... waiting");
Vanger 26:2b769ed8de4f 92 wait(1);
Vanger 26:2b769ed8de4f 93 } else {
Vanger 26:2b769ed8de4f 94 break;
Vanger 26:2b769ed8de4f 95 }
Vanger 26:2b769ed8de4f 96 } while(tmr.read() < 30);
Vanger 26:2b769ed8de4f 97
Vanger 52:2cb58398a4f9 98 //Make PPP connection
Vanger 26:2b769ed8de4f 99 if (type == MTSMC_H5 || type == MTSMC_G3) {
Vanger 26:2b769ed8de4f 100 logDebug("Making PPP Connection Attempt. APN[%s]", apn.c_str());
Vanger 26:2b769ed8de4f 101 } else {
Vanger 26:2b769ed8de4f 102 logDebug("Making PPP Connection Attempt");
Vanger 26:2b769ed8de4f 103 }
Vanger 35:257eb41405e1 104 std::string pppResult = sendCommand("AT#SGACT=1,1", 5000);
Vanger 30:1326b623919a 105 std::vector<std::string> parts;
Vanger 26:2b769ed8de4f 106 if(pppResult.find("OK") != std::string::npos) {
Vanger 30:1326b623919a 107 parts = Text::split(pppResult, "\r\n");
Vanger 26:2b769ed8de4f 108 if(parts.size() >= 2) {
Vanger 26:2b769ed8de4f 109 parts = Text::split(parts[1], " ");
Vanger 26:2b769ed8de4f 110 local_address = parts[1];
Vanger 26:2b769ed8de4f 111 }
Vanger 26:2b769ed8de4f 112 logInfo("PPP Connection Established: IP[%s]", local_address.c_str());
Vanger 26:2b769ed8de4f 113 pppConnected = true;
Vanger 26:2b769ed8de4f 114
Vanger 26:2b769ed8de4f 115 } else {
Vanger 30:1326b623919a 116 pppResult = sendCommand("AT#SGACT?", 2000);
Vanger 52:2cb58398a4f9 117 if(pppResult.find("1,1") != std::string::npos) {
Vanger 52:2cb58398a4f9 118 logDebug("Radio is already connected");
Vanger 52:2cb58398a4f9 119 pppConnected = true;
Vanger 30:1326b623919a 120 } else {
Vanger 52:2cb58398a4f9 121 logError("PPP connection attempt failed");
Vanger 52:2cb58398a4f9 122 pppConnected = false;
Vanger 30:1326b623919a 123 }
Vanger 26:2b769ed8de4f 124 }
Vanger 26:2b769ed8de4f 125
Vanger 26:2b769ed8de4f 126 return pppConnected;
Vanger 26:2b769ed8de4f 127 }
Vanger 26:2b769ed8de4f 128
Vanger 26:2b769ed8de4f 129 void EasyIP::disconnect()
Vanger 26:2b769ed8de4f 130 {
Vanger 52:2cb58398a4f9 131 //AT#SGACT=1,0: Close PPP connection
Vanger 52:2cb58398a4f9 132 logDebug("Closing PPP Connection");
Vanger 35:257eb41405e1 133 std::string result;
Vanger 35:257eb41405e1 134 Timer tmr;
Vanger 52:2cb58398a4f9 135
Vanger 52:2cb58398a4f9 136 if(socketOpened) {
Vanger 52:2cb58398a4f9 137 close();
Vanger 52:2cb58398a4f9 138 }
Vanger 52:2cb58398a4f9 139
Vanger 26:2b769ed8de4f 140 //Sends AT#SGACT=1,0 command
Vanger 35:257eb41405e1 141 if (sendBasicCommand("AT#SGACT=1,0", 1000) == MTS_SUCCESS) {
Vanger 30:1326b623919a 142 logDebug("Successfully closed PPP Connection");
Vanger 30:1326b623919a 143 }
Vanger 35:257eb41405e1 144
Vanger 52:2cb58398a4f9 145 /* Ensure PPP link is down, else ping commands will put radio in unknown state
Vanger 52:2cb58398a4f9 146 * (Link is not immediate in disconnection, even though OK is returned)
Vanger 51:ffc556ba33f7 147 */
Vanger 35:257eb41405e1 148 tmr.start();
Vanger 35:257eb41405e1 149 while(tmr.read() < 30) {
Vanger 35:257eb41405e1 150 result = sendCommand("AT#SGACT?", 1000);
Vanger 35:257eb41405e1 151 if(result.find("1,0") != std::string::npos) {
Vanger 35:257eb41405e1 152 break;
Vanger 35:257eb41405e1 153 } else if(result.find("ERROR") != std::string::npos) {
Vanger 35:257eb41405e1 154 break;
Vanger 35:257eb41405e1 155 } else {
Vanger 35:257eb41405e1 156 wait(1);
Vanger 35:257eb41405e1 157 }
Vanger 35:257eb41405e1 158 }
Vanger 35:257eb41405e1 159
Vanger 52:2cb58398a4f9 160 pppConnected = false;
Vanger 30:1326b623919a 161 return;
Vanger 26:2b769ed8de4f 162 }
Vanger 27:ec44d5a9544f 163
Vanger 26:2b769ed8de4f 164 bool EasyIP::isConnected()
Vanger 26:2b769ed8de4f 165 {
Vanger 52:2cb58398a4f9 166 enum RadioState {IDLE, CONNECTING, CONNECTED, DISCONNECTED};
Vanger 51:ffc556ba33f7 167 //state flags for various connection components
Vanger 30:1326b623919a 168 bool signal = false, regist = false, active = false;
Vanger 26:2b769ed8de4f 169
Vanger 29:edc613ed3f2e 170 //1) Check if APN was set if we're on an HSPA radio
Vanger 29:edc613ed3f2e 171 if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3) {
Vanger 29:edc613ed3f2e 172 if(apn.size() == 0) {
Vanger 29:edc613ed3f2e 173 logDebug("APN is not set");
Vanger 29:edc613ed3f2e 174 return false;
Vanger 29:edc613ed3f2e 175 }
Vanger 29:edc613ed3f2e 176 }
Vanger 29:edc613ed3f2e 177
Vanger 29:edc613ed3f2e 178 //2) Check that we do not have a live connection up
Vanger 52:2cb58398a4f9 179 if (socketOpened) {
Vanger 29:edc613ed3f2e 180 logDebug("Socket is opened");
Vanger 29:edc613ed3f2e 181 return true;
Vanger 29:edc613ed3f2e 182 }
Vanger 29:edc613ed3f2e 183
Vanger 29:edc613ed3f2e 184 //3) Query the radio
Vanger 52:2cb58398a4f9 185 int rssi = getSignalStrength();
Vanger 52:2cb58398a4f9 186 if (rssi == 99 || rssi == -1) {
Vanger 52:2cb58398a4f9 187 //Signal strength is nonexistent
Vanger 29:edc613ed3f2e 188 signal = false;
Vanger 29:edc613ed3f2e 189 } else {
Vanger 52:2cb58398a4f9 190 signal = true;
Vanger 29:edc613ed3f2e 191 }
Vanger 27:ec44d5a9544f 192
Vanger 52:2cb58398a4f9 193 Registration creg = getRegistration();
Vanger 52:2cb58398a4f9 194 if (creg == REGISTERED) {
Vanger 52:2cb58398a4f9 195 regist = true;
Vanger 29:edc613ed3f2e 196 } else {
Vanger 52:2cb58398a4f9 197 regist = false;
Vanger 29:edc613ed3f2e 198 }
Vanger 27:ec44d5a9544f 199
Vanger 52:2cb58398a4f9 200 string reply = sendCommand("AT#SGACT?", 500);
Vanger 52:2cb58398a4f9 201 if (reply.find("1,1") != std::string::npos) {
Vanger 52:2cb58398a4f9 202 active = true;
Vanger 29:edc613ed3f2e 203 } else {
Vanger 52:2cb58398a4f9 204 active = false;
Vanger 29:edc613ed3f2e 205 }
Vanger 52:2cb58398a4f9 206
Vanger 52:2cb58398a4f9 207 RadioState state;
Vanger 52:2cb58398a4f9 208 bool ppp = pppConnected;
Vanger 52:2cb58398a4f9 209 if (signal && regist && active) {
Vanger 52:2cb58398a4f9 210 //Radio connected
Vanger 52:2cb58398a4f9 211 state = CONNECTED;
Vanger 52:2cb58398a4f9 212 pppConnected = true;
Vanger 52:2cb58398a4f9 213 } else if (signal && !regist && !active) {
Vanger 52:2cb58398a4f9 214 //Radio idle
Vanger 52:2cb58398a4f9 215 state = IDLE;
Vanger 52:2cb58398a4f9 216 pppConnected = false;
Vanger 52:2cb58398a4f9 217 } else if (active) {
Vanger 52:2cb58398a4f9 218 //Radio Connecting
Vanger 52:2cb58398a4f9 219 state = CONNECTING;
Vanger 52:2cb58398a4f9 220 } else {
Vanger 52:2cb58398a4f9 221 //Radio Disconnected
Vanger 52:2cb58398a4f9 222 state = DISCONNECTED;
Vanger 30:1326b623919a 223 pppConnected = false;
Vanger 30:1326b623919a 224 }
Vanger 35:257eb41405e1 225
Vanger 52:2cb58398a4f9 226 if (!ppp && state == CONNECTED) {
Vanger 52:2cb58398a4f9 227 logWarning("Internal PPP state tracking differs from radio (DISCONNECTED:CONNECTED)");
Vanger 52:2cb58398a4f9 228 } else if (ppp && state != CONNECTED) {
Vanger 52:2cb58398a4f9 229 logWarning("Internal PPP state tracking differs from radio (CONNECTED:%s)", state);
Vanger 29:edc613ed3f2e 230 }
Vanger 52:2cb58398a4f9 231
Vanger 26:2b769ed8de4f 232 return pppConnected;
Vanger 26:2b769ed8de4f 233 }
Vanger 30:1326b623919a 234
Vanger 33:3b6f3904dde0 235 void EasyIP::reset()
Vanger 33:3b6f3904dde0 236 {
Vanger 33:3b6f3904dde0 237 disconnect();
Vanger 52:2cb58398a4f9 238
Vanger 33:3b6f3904dde0 239 if(sendBasicCommand("AT#REBOOT", 10000) != MTS_SUCCESS) {
Vanger 52:2cb58398a4f9 240 logError("Socket Modem did not accept RESET command");
Vanger 33:3b6f3904dde0 241 } else {
Vanger 52:2cb58398a4f9 242 logWarning("Socket Modem is resetting, allow 30 seconds for it to come back");
Vanger 33:3b6f3904dde0 243 return;
Vanger 33:3b6f3904dde0 244 }
Vanger 33:3b6f3904dde0 245 }
Vanger 33:3b6f3904dde0 246
Vanger 26:2b769ed8de4f 247 //Binds the socket to a specific port if able
Vanger 26:2b769ed8de4f 248 bool EasyIP::bind(unsigned int port)
Vanger 26:2b769ed8de4f 249 {
Vanger 30:1326b623919a 250 if(socketOpened) {
Vanger 30:1326b623919a 251 logError("socket is open. Can not set local port");
Vanger 30:1326b623919a 252 return false;
Vanger 30:1326b623919a 253 }
Vanger 30:1326b623919a 254 if(port > 65535) {
Vanger 30:1326b623919a 255 logError("port out of range (0-65535)");
Vanger 30:1326b623919a 256 return false;
Vanger 30:1326b623919a 257 }
Vanger 30:1326b623919a 258 local_port = port;
Vanger 26:2b769ed8de4f 259 return true;
Vanger 26:2b769ed8de4f 260 }
Vanger 27:ec44d5a9544f 261
Vanger 26:2b769ed8de4f 262 bool EasyIP::open(const std::string& address, unsigned int port, Mode mode)
Vanger 26:2b769ed8de4f 263 {
Vanger 30:1326b623919a 264 char sOpenSocketCmd[256] = {0}; //String for AT command
Vanger 30:1326b623919a 265 std::string sMode = "";
Vanger 31:529db15abda7 266 int typeSocket = 0;
Vanger 31:529db15abda7 267 int closeType = 0;
Vanger 30:1326b623919a 268
Vanger 30:1326b623919a 269 //1) Check that we do not have a live connection up
Vanger 30:1326b623919a 270 if(socketOpened) {
Vanger 30:1326b623919a 271 //Check that the address, port, and mode match
Vanger 30:1326b623919a 272 if(host_address != address || host_port != port || socketMode != mode) {
Vanger 30:1326b623919a 273 if(socketMode == TCP) {
Vanger 30:1326b623919a 274 logError("TCP socket already opened [%s:%d]", host_address.c_str(), host_port);
Vanger 30:1326b623919a 275 } else {
Vanger 30:1326b623919a 276 logError("UDP socket already opened [%s:%d]", host_address.c_str(), host_port);
Vanger 30:1326b623919a 277 }
Vanger 30:1326b623919a 278 return false;
Vanger 30:1326b623919a 279 }
Vanger 30:1326b623919a 280
Vanger 30:1326b623919a 281 logDebug("Socket already opened");
Vanger 30:1326b623919a 282 return true;
Vanger 30:1326b623919a 283 }
Vanger 30:1326b623919a 284
Vanger 30:1326b623919a 285 //2) Check Parameters
Vanger 30:1326b623919a 286 if(port > 65535) {
Vanger 30:1326b623919a 287 logError("port out of range (0-65535)");
Vanger 30:1326b623919a 288 return false;
Vanger 30:1326b623919a 289 }
Vanger 41:8b9b5098696f 290
Vanger 41:8b9b5098696f 291 if(type == MTSMC_EV3) {
Vanger 41:8b9b5098696f 292 if(!local_port) {
Vanger 41:8b9b5098696f 293 logDebug("Local port set to 1, port 0 not supported for MTSMC_EV3");
Vanger 41:8b9b5098696f 294 local_port = 1;
Vanger 41:8b9b5098696f 295 }
Vanger 41:8b9b5098696f 296 }
Vanger 30:1326b623919a 297
Vanger 30:1326b623919a 298 //3) Check PPP connection
Vanger 30:1326b623919a 299 if(!isConnected()) {
Vanger 30:1326b623919a 300 logError("PPP not established. Attempting to connect");
Vanger 30:1326b623919a 301 if(!connect()) {
Vanger 30:1326b623919a 302 logError("PPP connection failed");
Vanger 30:1326b623919a 303 return false;
Vanger 30:1326b623919a 304 } else {
Vanger 30:1326b623919a 305 logDebug("PPP connection established");
Vanger 30:1326b623919a 306 }
Vanger 30:1326b623919a 307 }
Vanger 30:1326b623919a 308
Vanger 30:1326b623919a 309 //4) Set escape sequence to not be transmitted
Vanger 30:1326b623919a 310 if(sendBasicCommand("AT#SKIPESC=1", 2000) != MTS_SUCCESS) {
Vanger 30:1326b623919a 311 logWarning("Failed to disable escape sequence transmission on data mode suspension");
Vanger 30:1326b623919a 312 }
Vanger 30:1326b623919a 313
Vanger 30:1326b623919a 314 if(mode == TCP) {
Vanger 30:1326b623919a 315 typeSocket = 0;
Vanger 30:1326b623919a 316 sMode = "TCP";
Vanger 30:1326b623919a 317 } else {
Vanger 30:1326b623919a 318 typeSocket = 1;
Vanger 30:1326b623919a 319 sMode = "UDP";
Vanger 30:1326b623919a 320 }
Vanger 31:529db15abda7 321
Vanger 31:529db15abda7 322 if(socketCloseable) {
Vanger 31:529db15abda7 323 closeType = 0;
Vanger 31:529db15abda7 324 } else {
Vanger 31:529db15abda7 325 closeType = 255;
Vanger 31:529db15abda7 326 }
Vanger 31:529db15abda7 327 //5) Open Socket
Vanger 31:529db15abda7 328 sprintf(sOpenSocketCmd, "AT#SD=1,%d,%d,%s,%d,%d,0", typeSocket, port, address.c_str(),closeType , local_port);
Vanger 38:b2088faa8bfd 329 std::string response = sendCommand(sOpenSocketCmd, 60000);
Vanger 30:1326b623919a 330
Vanger 30:1326b623919a 331 if(response.find("CONNECT") != std::string::npos) {
Vanger 30:1326b623919a 332 host_address = address;
Vanger 30:1326b623919a 333 host_port = port;
Vanger 30:1326b623919a 334
Vanger 30:1326b623919a 335 logInfo("Opened %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port);
Vanger 30:1326b623919a 336 socketOpened = true;
Vanger 30:1326b623919a 337 socketMode = mode;
Vanger 30:1326b623919a 338 } else {
Vanger 30:1326b623919a 339 logWarning("Unable to open %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port);
Vanger 30:1326b623919a 340 socketOpened = false;
Vanger 30:1326b623919a 341 }
Vanger 30:1326b623919a 342
Vanger 26:2b769ed8de4f 343 return socketOpened;
Vanger 26:2b769ed8de4f 344 }
Vanger 27:ec44d5a9544f 345
Vanger 26:2b769ed8de4f 346 bool EasyIP::isOpen()
Vanger 26:2b769ed8de4f 347 {
Vanger 30:1326b623919a 348 if(io->readable()) {
Vanger 52:2cb58398a4f9 349 logDebug("Assuming open, data available to read.");
Vanger 30:1326b623919a 350 return true;
Vanger 30:1326b623919a 351 }
Vanger 26:2b769ed8de4f 352 return socketOpened;
Vanger 26:2b769ed8de4f 353 }
Vanger 27:ec44d5a9544f 354
Vanger 26:2b769ed8de4f 355 bool EasyIP::close()
Vanger 26:2b769ed8de4f 356 {
Vanger 26:2b769ed8de4f 357
Vanger 30:1326b623919a 358 if(io == NULL) {
Vanger 30:1326b623919a 359 logError("MTSBufferedIO not set");
Vanger 30:1326b623919a 360 return false;
Vanger 30:1326b623919a 361 }
Vanger 30:1326b623919a 362
Vanger 30:1326b623919a 363 if(!socketOpened) {
Vanger 30:1326b623919a 364 logWarning("Socket close() called, but socket was not open");
Vanger 30:1326b623919a 365 return true;
Vanger 30:1326b623919a 366 }
Vanger 30:1326b623919a 367
Vanger 30:1326b623919a 368 if(!socketCloseable) {
Vanger 30:1326b623919a 369 logError("Socket is not closeable");
Vanger 30:1326b623919a 370 return false;
Vanger 30:1326b623919a 371 }
Vanger 30:1326b623919a 372
Vanger 30:1326b623919a 373 if(!sendEscapeCommand()) {
Vanger 30:1326b623919a 374 logError("Failed to exit online mode");
Vanger 30:1326b623919a 375 return false;
Vanger 30:1326b623919a 376 } else {
Vanger 30:1326b623919a 377 socketOpened = false;
Vanger 30:1326b623919a 378 }
Vanger 30:1326b623919a 379
Vanger 30:1326b623919a 380 if(sendBasicCommand("AT#SH=1", 2000) != MTS_SUCCESS) {
Vanger 30:1326b623919a 381 logDebug("Failed to close socket connection");
Vanger 30:1326b623919a 382 }
Vanger 30:1326b623919a 383
Vanger 30:1326b623919a 384 Timer tmr;
Vanger 30:1326b623919a 385 int counter = 0;
Vanger 30:1326b623919a 386 char tmp[256];
Vanger 30:1326b623919a 387 tmr.start();
Vanger 30:1326b623919a 388 do {
Vanger 30:1326b623919a 389 if(socketOpened == false) {
Vanger 30:1326b623919a 390 break;
Vanger 30:1326b623919a 391 }
Vanger 30:1326b623919a 392 read(tmp, 256, 1000);
Vanger 30:1326b623919a 393 } while(counter++ < 10);
Vanger 30:1326b623919a 394
Vanger 30:1326b623919a 395 io->rxClear();
Vanger 30:1326b623919a 396 io->txClear();
Vanger 30:1326b623919a 397
Vanger 30:1326b623919a 398 return !socketOpened;
Vanger 26:2b769ed8de4f 399 }
Vanger 26:2b769ed8de4f 400
Vanger 26:2b769ed8de4f 401 int EasyIP::read(char* data, int max, int timeout)
Vanger 26:2b769ed8de4f 402 {
Vanger 30:1326b623919a 403 if(io == NULL) {
Vanger 30:1326b623919a 404 logError("MTSBufferedIO not set");
Vanger 30:1326b623919a 405 return -1;
Vanger 30:1326b623919a 406 }
Vanger 30:1326b623919a 407
Vanger 30:1326b623919a 408 //Check that nothing is in the rx buffer
Vanger 30:1326b623919a 409 if(!socketOpened && !io->readable()) {
Vanger 30:1326b623919a 410 logError("Socket is not open");
Vanger 30:1326b623919a 411 return -1;
Vanger 30:1326b623919a 412 }
Vanger 30:1326b623919a 413
Vanger 30:1326b623919a 414 int bytesRead = 0;
Vanger 30:1326b623919a 415
Vanger 30:1326b623919a 416
Vanger 30:1326b623919a 417 if(timeout >= 0) {
Vanger 30:1326b623919a 418 bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
Vanger 30:1326b623919a 419 } else {
Vanger 30:1326b623919a 420 bytesRead = io->read(data, max);
Vanger 30:1326b623919a 421 }
Vanger 35:257eb41405e1 422
Vanger 35:257eb41405e1 423 //Scan for socket closed message
Vanger 31:529db15abda7 424 if(bytesRead > 0 && socketCloseable) {
Vanger 35:257eb41405e1 425 for(int i = 0; i < bytesRead; i++) {
Vanger 31:529db15abda7 426 if(data[i] == 'N') {
Vanger 31:529db15abda7 427 if(strstr(&data[i], "NO CARRIER")) {
Vanger 31:529db15abda7 428 logTrace("Found socket closed message. Checking validity");
Vanger 31:529db15abda7 429 //Close socket and Cut Off End of Message
Vanger 31:529db15abda7 430 socketOpened = socketCheck(); //Verifies legitimacy of socket disconnect
Vanger 31:529db15abda7 431 if(socketOpened) {
Vanger 31:529db15abda7 432 logDebug("Socket still open");
Vanger 31:529db15abda7 433 continue;
Vanger 31:529db15abda7 434 } else {
Vanger 31:529db15abda7 435 logDebug("Socket closed");
Vanger 31:529db15abda7 436 data[i] = '\0';
Vanger 31:529db15abda7 437 bytesRead = i;
Vanger 31:529db15abda7 438 break;
Vanger 31:529db15abda7 439 }
Vanger 30:1326b623919a 440 }
Vanger 30:1326b623919a 441 }
Vanger 30:1326b623919a 442 }
Vanger 30:1326b623919a 443 }
Vanger 30:1326b623919a 444 return bytesRead;
Vanger 26:2b769ed8de4f 445 }
Vanger 26:2b769ed8de4f 446
Vanger 26:2b769ed8de4f 447 int EasyIP::write(const char* data, int length, int timeout)
Vanger 26:2b769ed8de4f 448 {
Vanger 30:1326b623919a 449 if(io == NULL) {
Vanger 30:1326b623919a 450 logError("MTSBufferedIO not set");
Vanger 30:1326b623919a 451 return -1;
Vanger 30:1326b623919a 452 }
Vanger 30:1326b623919a 453
Vanger 30:1326b623919a 454 if(!socketOpened) {
Vanger 30:1326b623919a 455 logError("Socket is not open");
Vanger 30:1326b623919a 456 return -1;
Vanger 30:1326b623919a 457 }
Vanger 30:1326b623919a 458
Vanger 30:1326b623919a 459 int bytesWritten = 0;
Vanger 31:529db15abda7 460 int size = length;
Vanger 31:529db15abda7 461 int failedWrites = 0;
Vanger 30:1326b623919a 462 if(timeout >= 0) {
Vanger 30:1326b623919a 463 Timer tmr;
Vanger 30:1326b623919a 464 tmr.start();
Vanger 30:1326b623919a 465 do {
Vanger 30:1326b623919a 466 int available = io->writeable();
Vanger 30:1326b623919a 467 if (available > 0) {
Vanger 31:529db15abda7 468 size = MIN(available, length - bytesWritten);
Vanger 31:529db15abda7 469 bytesWritten += io->write(&data[bytesWritten], size);
Vanger 30:1326b623919a 470 } else {
Vanger 30:1326b623919a 471 wait(0.05);
Vanger 30:1326b623919a 472 }
Vanger 30:1326b623919a 473 } while (tmr.read_ms() <= timeout && bytesWritten < length);
Vanger 30:1326b623919a 474 } else {
Vanger 31:529db15abda7 475 //If timeout is -1:
Vanger 31:529db15abda7 476 do {
Vanger 31:529db15abda7 477 int available = io->writeable();
Vanger 31:529db15abda7 478 if(available > 0) {
Vanger 31:529db15abda7 479 size = MIN(available, length - bytesWritten);
Vanger 31:529db15abda7 480 int currentWritten = io->write(&data[bytesWritten], size);
Vanger 31:529db15abda7 481 bytesWritten += currentWritten;
Vanger 31:529db15abda7 482 if(!currentWritten) {
Vanger 31:529db15abda7 483 failedWrites++;
Vanger 31:529db15abda7 484 }
Vanger 31:529db15abda7 485 if(failedWrites > 10) {
Vanger 31:529db15abda7 486 logError("Couldn't write any characters");
Vanger 31:529db15abda7 487 return bytesWritten;
Vanger 31:529db15abda7 488 }
Vanger 31:529db15abda7 489 } else {
Vanger 31:529db15abda7 490 wait(0.05);
Vanger 30:1326b623919a 491 }
Vanger 31:529db15abda7 492 } while (bytesWritten < length);
Vanger 30:1326b623919a 493 }
Vanger 30:1326b623919a 494 return bytesWritten;
Vanger 26:2b769ed8de4f 495 }
Vanger 26:2b769ed8de4f 496
Vanger 26:2b769ed8de4f 497 unsigned int EasyIP::readable()
Vanger 26:2b769ed8de4f 498 {
Vanger 30:1326b623919a 499 if(io == NULL) {
Vanger 30:1326b623919a 500 logWarning("MTSBufferedIO not set");
Vanger 30:1326b623919a 501 return 0;
Vanger 30:1326b623919a 502 }
Vanger 30:1326b623919a 503 if(!socketOpened && !io->readable()) {
Vanger 30:1326b623919a 504 logWarning("Socket is not open");
Vanger 30:1326b623919a 505 return 0;
Vanger 30:1326b623919a 506 }
Vanger 26:2b769ed8de4f 507 return io->readable();
Vanger 26:2b769ed8de4f 508 }
Vanger 26:2b769ed8de4f 509
Vanger 26:2b769ed8de4f 510 unsigned int EasyIP::writeable()
Vanger 26:2b769ed8de4f 511 {
Vanger 30:1326b623919a 512 if(io == NULL) {
Vanger 30:1326b623919a 513 logWarning("MTSBufferedIO not set");
Vanger 30:1326b623919a 514 return 0;
Vanger 30:1326b623919a 515 }
Vanger 30:1326b623919a 516 if(!socketOpened) {
Vanger 30:1326b623919a 517 logWarning("Socket is not open");
Vanger 30:1326b623919a 518 return 0;
Vanger 30:1326b623919a 519 }
Vanger 26:2b769ed8de4f 520
Vanger 26:2b769ed8de4f 521 return io->writeable();
Vanger 26:2b769ed8de4f 522 }
Vanger 26:2b769ed8de4f 523
Vanger 26:2b769ed8de4f 524 bool EasyIP::setDeviceIP(std::string address)
Vanger 26:2b769ed8de4f 525 {
Vanger 26:2b769ed8de4f 526 if (address.compare("DHCP") == 0) {
Vanger 26:2b769ed8de4f 527 return true;
Vanger 26:2b769ed8de4f 528 } else {
Vanger 52:2cb58398a4f9 529 logWarning("Radio does not support static IPs, using DHCP.");
Vanger 26:2b769ed8de4f 530 return false;
Vanger 26:2b769ed8de4f 531 }
Vanger 26:2b769ed8de4f 532 }
Vanger 26:2b769ed8de4f 533
Vanger 26:2b769ed8de4f 534 Code EasyIP::setApn(const std::string& apn)
Vanger 26:2b769ed8de4f 535 {
Vanger 26:2b769ed8de4f 536 if (type == MTSMC_H5 || type == MTSMC_G3) {
Vanger 26:2b769ed8de4f 537 //Set IP,PPP,IPv6
Vanger 26:2b769ed8de4f 538 Code code = sendBasicCommand("AT+CGDCONT=1,PPP," + apn, 1000);
Vanger 26:2b769ed8de4f 539 if (code != MTS_SUCCESS) {
Vanger 33:3b6f3904dde0 540 return code; //This will return whatever is not MTS_SUCCESS
Vanger 26:2b769ed8de4f 541 }
Vanger 26:2b769ed8de4f 542 this->apn = apn;
Vanger 26:2b769ed8de4f 543 return code; //This will return MTS_SUCCESS
Vanger 26:2b769ed8de4f 544 } else {
Vanger 26:2b769ed8de4f 545 logInfo("CDMA radios don't need an APN");
Vanger 26:2b769ed8de4f 546 return MTS_SUCCESS;
Vanger 26:2b769ed8de4f 547 }
Vanger 26:2b769ed8de4f 548 }
Vanger 27:ec44d5a9544f 549
Vanger 26:2b769ed8de4f 550 std::string EasyIP::getDeviceIP()
Vanger 26:2b769ed8de4f 551 {
Vanger 26:2b769ed8de4f 552 return local_address;
Vanger 26:2b769ed8de4f 553 }
Vanger 26:2b769ed8de4f 554
Vanger 32:7d5581159bed 555 //Turns off echo when it receives a true, turns on when it receives false
Vanger 26:2b769ed8de4f 556 Code EasyIP::echo(bool state)
Vanger 26:2b769ed8de4f 557 {
Vanger 27:ec44d5a9544f 558 Code code;
Vanger 27:ec44d5a9544f 559 if (state) {
Vanger 27:ec44d5a9544f 560 code = sendBasicCommand("ATE0", 1000);
Vanger 27:ec44d5a9544f 561 echoMode = (code == MTS_SUCCESS) ? false : echoMode;
Vanger 27:ec44d5a9544f 562 } else {
Vanger 27:ec44d5a9544f 563 code = sendBasicCommand("ATE1", 1000);
Vanger 27:ec44d5a9544f 564 echoMode = (code == MTS_SUCCESS) ? true : echoMode;
Vanger 27:ec44d5a9544f 565 }
Vanger 27:ec44d5a9544f 566 return code;
Vanger 26:2b769ed8de4f 567 }
Vanger 26:2b769ed8de4f 568
Vanger 26:2b769ed8de4f 569 bool EasyIP::ping(const std::string& address)
Vanger 26:2b769ed8de4f 570 {
Vanger 26:2b769ed8de4f 571 char buffer[256] = {0};
Vanger 27:ec44d5a9544f 572 std::vector<std::string> parts;
Vanger 27:ec44d5a9544f 573 int TTL=0;
Vanger 27:ec44d5a9544f 574 int Timeout=0;
Vanger 27:ec44d5a9544f 575
Vanger 27:ec44d5a9544f 576 //Format parameters for sending to radio
Vanger 30:1326b623919a 577 sprintf(buffer, "AT#PING=%s,1,32,%d", address.c_str(), (PINGDELAY*10));
Vanger 26:2b769ed8de4f 578
Vanger 27:ec44d5a9544f 579 for(int pngs=0; pngs<PINGNUM; pngs++) {
Vanger 35:257eb41405e1 580 std::string response = sendCommand(buffer, (PINGDELAY*2000)); //Send 1 ping
Vanger 52:2cb58398a4f9 581 if(response.empty() || response.find("ERROR") != std::string::npos) {
Vanger 28:f93d7b3f7c2e 582 continue; //Skip current loop if send command fails
Vanger 28:f93d7b3f7c2e 583 }
Vanger 27:ec44d5a9544f 584 parts = Text::split(response, "\r\n");
Vanger 28:f93d7b3f7c2e 585 if(parts.size() < 2) {
Vanger 28:f93d7b3f7c2e 586 continue;
Vanger 28:f93d7b3f7c2e 587 }
Vanger 27:ec44d5a9544f 588 parts = Text::split(parts[1], ",");
Vanger 28:f93d7b3f7c2e 589 if(parts.size() < 4) {
Vanger 28:f93d7b3f7c2e 590 continue;
Vanger 28:f93d7b3f7c2e 591 }
Vanger 27:ec44d5a9544f 592 //Parse TTL and Timeout values
Vanger 27:ec44d5a9544f 593 Timeout = std::atoi(parts[2].c_str());
Vanger 27:ec44d5a9544f 594 TTL = std::atoi(parts[3].c_str());
Vanger 27:ec44d5a9544f 595
Vanger 27:ec44d5a9544f 596 if((Timeout < 600) && (TTL < 255)) {
Vanger 27:ec44d5a9544f 597 return true;
Vanger 27:ec44d5a9544f 598 }
Vanger 52:2cb58398a4f9 599 }
Vanger 26:2b769ed8de4f 600 return false;
Vanger 26:2b769ed8de4f 601 }
Vanger 26:2b769ed8de4f 602
Vanger 27:ec44d5a9544f 603 //Pass 1 to enable socket closeable
Vanger 27:ec44d5a9544f 604 //Pass 0 to disable socket closeable
Vanger 26:2b769ed8de4f 605 Code EasyIP::setSocketCloseable(bool enabled)
Vanger 26:2b769ed8de4f 606 {
Vanger 31:529db15abda7 607 if(socketCloseable == enabled) {
Vanger 31:529db15abda7 608 return MTS_SUCCESS;
Vanger 31:529db15abda7 609 }
Vanger 31:529db15abda7 610
Vanger 31:529db15abda7 611 if(socketOpened) {
Vanger 31:529db15abda7 612 logError("socket is already opened. Can not set closeable");
Vanger 31:529db15abda7 613 return MTS_ERROR;
Vanger 31:529db15abda7 614 }
Vanger 31:529db15abda7 615
Vanger 31:529db15abda7 616 socketCloseable = enabled;
Vanger 31:529db15abda7 617
Vanger 26:2b769ed8de4f 618 return MTS_SUCCESS;
Vanger 26:2b769ed8de4f 619 }
Vanger 33:3b6f3904dde0 620
Vanger 33:3b6f3904dde0 621 bool EasyIP::sendEscapeCommand()
Vanger 33:3b6f3904dde0 622 {
Vanger 33:3b6f3904dde0 623 //string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
Vanger 33:3b6f3904dde0 624 if(io == NULL) {
Vanger 33:3b6f3904dde0 625 logError("MTSBufferedIO not set");
Vanger 33:3b6f3904dde0 626 return false;
Vanger 33:3b6f3904dde0 627 }
Vanger 33:3b6f3904dde0 628 if(!socketOpened) {
Vanger 52:2cb58398a4f9 629 logError("Socket is not open.");
Vanger 52:2cb58398a4f9 630 return false;
Vanger 33:3b6f3904dde0 631 }
Vanger 33:3b6f3904dde0 632
Vanger 33:3b6f3904dde0 633 if(!socketCloseable) {
Vanger 33:3b6f3904dde0 634 logError("Socket is not closeable");
Vanger 33:3b6f3904dde0 635 return false;
Vanger 33:3b6f3904dde0 636 }
Vanger 33:3b6f3904dde0 637
Vanger 33:3b6f3904dde0 638 io->rxClear();
Vanger 33:3b6f3904dde0 639 io->txClear();
Vanger 33:3b6f3904dde0 640
Vanger 33:3b6f3904dde0 641 std::string result;
Vanger 52:2cb58398a4f9 642 unsigned int timeoutMillis = 10000;
Vanger 33:3b6f3904dde0 643 //Attempt to write command
Vanger 52:2cb58398a4f9 644 //Format for +++ command is 1 second wait, send +++, then another second wait
Vanger 52:2cb58398a4f9 645 wait(1.2);
Vanger 49:1fc51c53cebf 646 if(io->write("+++", 3, timeoutMillis) != 3) {
Vanger 33:3b6f3904dde0 647 //Failed to write command
Vanger 33:3b6f3904dde0 648 logError("failed to send command to radio within %d milliseconds", timeoutMillis);
Vanger 33:3b6f3904dde0 649 return false;
Vanger 33:3b6f3904dde0 650 }
Vanger 33:3b6f3904dde0 651
Vanger 52:2cb58398a4f9 652 Timer tmr;
Vanger 33:3b6f3904dde0 653 char tmp[256];
Vanger 33:3b6f3904dde0 654 tmp[255] = 0;
Vanger 33:3b6f3904dde0 655 bool done = false;
Vanger 33:3b6f3904dde0 656 bool exitmode = false;
Vanger 52:2cb58398a4f9 657 tmr.start();
Vanger 33:3b6f3904dde0 658 do {
Vanger 33:3b6f3904dde0 659 //Make a non-blocking read call by passing timeout of zero
Vanger 52:2cb58398a4f9 660 int size = io->read(tmp,255,0); //1 less than allocated (timeout is instant)
Vanger 52:2cb58398a4f9 661 if(size > 0) {
Vanger 52:2cb58398a4f9 662 result.append(tmp, size);
Vanger 52:2cb58398a4f9 663 }
Vanger 33:3b6f3904dde0 664 if(result.find("OK") != std::string::npos) {
Vanger 33:3b6f3904dde0 665 exitmode = true;
Vanger 33:3b6f3904dde0 666 done = true;
Vanger 33:3b6f3904dde0 667 } else if(result.find("NO CARRIER") != std::string::npos) {
Vanger 52:2cb58398a4f9 668 socketOpened = false;
Vanger 33:3b6f3904dde0 669 exitmode = true;
Vanger 33:3b6f3904dde0 670 done = true;
Vanger 33:3b6f3904dde0 671 } else if(result.find("ERROR") != std::string::npos) {
Vanger 33:3b6f3904dde0 672 exitmode = false;
Vanger 33:3b6f3904dde0 673 done = true;
Vanger 33:3b6f3904dde0 674 }
Vanger 52:2cb58398a4f9 675 if(tmr.read_ms() >= timeoutMillis) {
Vanger 33:3b6f3904dde0 676 logDebug("Escape sequence [+++] timed out after %d milliseconds", timeoutMillis);
Vanger 33:3b6f3904dde0 677 exitmode = true;
Vanger 33:3b6f3904dde0 678 done = true;
Vanger 33:3b6f3904dde0 679 }
Vanger 33:3b6f3904dde0 680 } while (!done);
Vanger 33:3b6f3904dde0 681
Vanger 33:3b6f3904dde0 682 return exitmode;
Vanger 33:3b6f3904dde0 683 }
Vanger 33:3b6f3904dde0 684
Vanger 33:3b6f3904dde0 685 bool EasyIP::socketCheck() {
Vanger 33:3b6f3904dde0 686 bool status = false;
Vanger 52:2cb58398a4f9 687 int socketInfo = 9; //error
Vanger 52:2cb58398a4f9 688 enum SocketStatus {SOCKETCLOSED, SOCKETACTIVEDATA, SOCKETSUSPEND, SOCKETSUSPENDDATA, SOCKETLISTEN, SOCKETINCOMING, ERROR = 9};
Vanger 33:3b6f3904dde0 689 std::vector<std::string> params;
Vanger 33:3b6f3904dde0 690
Vanger 33:3b6f3904dde0 691 //Goes from data mode to command mode
Vanger 33:3b6f3904dde0 692 if(sendEscapeCommand()) {
Vanger 52:2cb58398a4f9 693 std::string reply = sendCommand("AT#SS=1", 2000);
Vanger 52:2cb58398a4f9 694 if(reply.find("OK") != std::string::npos) {
Vanger 52:2cb58398a4f9 695 //Found valid response
Vanger 52:2cb58398a4f9 696 params = Text::split(reply, "\r\n");
Vanger 52:2cb58398a4f9 697 params = Text::split(params[1], ",");
Vanger 52:2cb58398a4f9 698 socketInfo = atoi(params[1].c_str());
Vanger 52:2cb58398a4f9 699 } else {
Vanger 52:2cb58398a4f9 700 logError("Could not determine socket status[%d]",socketInfo);
Vanger 52:2cb58398a4f9 701 socketInfo = 9; //9 is unrecognized
Vanger 33:3b6f3904dde0 702 }
Vanger 33:3b6f3904dde0 703 } else {
Vanger 33:3b6f3904dde0 704 status = false; //Return value of socketOpened when checking
Vanger 33:3b6f3904dde0 705 }
Vanger 33:3b6f3904dde0 706
Vanger 33:3b6f3904dde0 707 //Check socket status query
Vanger 52:2cb58398a4f9 708 if(socketInfo < 5 && socketInfo > 0) { //Socket opened responses
Vanger 52:2cb58398a4f9 709 status = true;
Vanger 52:2cb58398a4f9 710 } else if(socketInfo == SOCKETCLOSED || socketInfo == SOCKETINCOMING) {
Vanger 52:2cb58398a4f9 711 status = false;
Vanger 33:3b6f3904dde0 712 } else {
Vanger 33:3b6f3904dde0 713 logError("Could not determine socket status");
Vanger 52:2cb58398a4f9 714 status = false;
Vanger 33:3b6f3904dde0 715 }
Vanger 33:3b6f3904dde0 716
Vanger 52:2cb58398a4f9 717 //Reconnect to active socket if able
Vanger 33:3b6f3904dde0 718 if(status) {
Vanger 33:3b6f3904dde0 719 std::string reconnect = sendCommand("AT#SO=1", 2000);
Vanger 33:3b6f3904dde0 720 if(reconnect.find("CONNECT") != std::string::npos || reconnect.find("OK") != std::string::npos) {
Vanger 33:3b6f3904dde0 721 } else {
Vanger 33:3b6f3904dde0 722 logError("Failed to resume socket connection");
Vanger 33:3b6f3904dde0 723 }
Vanger 33:3b6f3904dde0 724 }
Vanger 33:3b6f3904dde0 725 return status;
Vanger 33:3b6f3904dde0 726 }