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