Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Mike Fiore
Date:
Wed May 21 15:39:35 2014 -0500
Revision:
9:1a03e3f3e7fe
Parent:
8:2d7259d244d1
Child:
10:c188cc05aed5
more restructuring
move configureSignals and pins to Cellular class
add Radio field to Cellular class to hold radio type

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike Fiore 3:04046eebaef5 1 #include "mbed.h"
Mike Fiore 3:04046eebaef5 2 #include "UIP.h"
Mike Fiore 1:f155d94d6f3a 3 #include "MTSText.h"
Mike Fiore 4:1f63354b8d1b 4 #include "MTSLog.h"
Mike Fiore 2:10e72dce251d 5 #include "CellUtils.h"
Mike Fiore 1:f155d94d6f3a 6
Mike Fiore 1:f155d94d6f3a 7 using namespace mts;
Mike Fiore 1:f155d94d6f3a 8
Mike Fiore 3:04046eebaef5 9 UIP::UIP()
Mike Fiore 1:f155d94d6f3a 10 {
Mike Fiore 3:04046eebaef5 11 io = NULL;
Mike Fiore 9:1a03e3f3e7fe 12 dcd = NULL;
Mike Fiore 9:1a03e3f3e7fe 13 dtr = NULL;
Mike Fiore 9:1a03e3f3e7fe 14 resetLine = NULL;
Mike Fiore 3:04046eebaef5 15 echoMode = true;
Mike Fiore 3:04046eebaef5 16 pppConnected = false;
Mike Fiore 3:04046eebaef5 17 mode = TCP;
Mike Fiore 3:04046eebaef5 18 socketOpened = false;
Mike Fiore 3:04046eebaef5 19 socketCloseable = true;
Mike Fiore 3:04046eebaef5 20 local_port = 0;
Mike Fiore 3:04046eebaef5 21 local_address = "";
Mike Fiore 3:04046eebaef5 22 host_port = 0;
Mike Fiore 1:f155d94d6f3a 23 }
Mike Fiore 1:f155d94d6f3a 24
Mike Fiore 3:04046eebaef5 25 UIP::~UIP()
Mike Fiore 1:f155d94d6f3a 26 {
Mike Fiore 1:f155d94d6f3a 27 if (dtr != NULL) {
Mike Fiore 1:f155d94d6f3a 28 dtr->write(1);
Mike Fiore 1:f155d94d6f3a 29 }
Mike Fiore 1:f155d94d6f3a 30
Mike Fiore 1:f155d94d6f3a 31 delete dcd;
Mike Fiore 1:f155d94d6f3a 32 delete dtr;
Mike Fiore 1:f155d94d6f3a 33 delete resetLine;
Mike Fiore 1:f155d94d6f3a 34 }
Mike Fiore 1:f155d94d6f3a 35
Mike Fiore 3:04046eebaef5 36 bool UIP::init(MTSBufferedIO* io)
Mike Fiore 1:f155d94d6f3a 37 {
Mike Fiore 8:2d7259d244d1 38 if (! Cellular::init(io)) {
Mike Fiore 1:f155d94d6f3a 39 return false;
Mike Fiore 1:f155d94d6f3a 40 }
Mike Fiore 1:f155d94d6f3a 41
Mike Fiore 1:f155d94d6f3a 42 // Reset radio to make sure it's in a good state and wait for it to come back
Mike Fiore 1:f155d94d6f3a 43 reset();
Mike Fiore 1:f155d94d6f3a 44 test();
Mike Fiore 1:f155d94d6f3a 45
Mike Fiore 8:2d7259d244d1 46 return true;
Mike Fiore 1:f155d94d6f3a 47 }
Mike Fiore 1:f155d94d6f3a 48
Mike Fiore 3:04046eebaef5 49 bool UIP::connect()
Mike Fiore 1:f155d94d6f3a 50 {
Mike Fiore 1:f155d94d6f3a 51 //Check if socket is open
Mike Fiore 1:f155d94d6f3a 52 if(socketOpened) {
Mike Fiore 1:f155d94d6f3a 53 return true;
Mike Fiore 1:f155d94d6f3a 54 }
Mike Fiore 1:f155d94d6f3a 55
Mike Fiore 1:f155d94d6f3a 56 //Check if already connected
Mike Fiore 1:f155d94d6f3a 57 if(isConnected()) {
Mike Fiore 1:f155d94d6f3a 58 return true;
Mike Fiore 1:f155d94d6f3a 59 }
Mike Fiore 1:f155d94d6f3a 60
Mike Fiore 1:f155d94d6f3a 61 Timer tmr;
Mike Fiore 1:f155d94d6f3a 62
Mike Fiore 1:f155d94d6f3a 63 //Check Registration: AT+CREG? == 0,1
Mike Fiore 1:f155d94d6f3a 64 tmr.start();
Mike Fiore 1:f155d94d6f3a 65 do {
Mike Fiore 1:f155d94d6f3a 66 Registration registration = getRegistration();
Mike Fiore 1:f155d94d6f3a 67 if(registration != REGISTERED) {
Mike Fiore 4:1f63354b8d1b 68 logWarning("Not Registered [%d] ... waiting", (int)registration);
Mike Fiore 1:f155d94d6f3a 69 wait(1);
Mike Fiore 1:f155d94d6f3a 70 } else {
Mike Fiore 1:f155d94d6f3a 71 break;
Mike Fiore 1:f155d94d6f3a 72 }
Mike Fiore 1:f155d94d6f3a 73 } while(tmr.read() < 30);
Mike Fiore 1:f155d94d6f3a 74
Mike Fiore 1:f155d94d6f3a 75 //Check RSSI: AT+CSQ
Mike Fiore 1:f155d94d6f3a 76 tmr.reset();
Mike Fiore 1:f155d94d6f3a 77 do {
Mike Fiore 1:f155d94d6f3a 78 int rssi = getSignalStrength();
Mike Fiore 4:1f63354b8d1b 79 logDebug("Signal strength: %d", rssi);
Mike Fiore 1:f155d94d6f3a 80 if(rssi == 99) {
Mike Fiore 4:1f63354b8d1b 81 logWarning("No Signal ... waiting");
Mike Fiore 1:f155d94d6f3a 82 wait(1);
Mike Fiore 1:f155d94d6f3a 83 } else {
Mike Fiore 1:f155d94d6f3a 84 break;
Mike Fiore 1:f155d94d6f3a 85 }
Mike Fiore 1:f155d94d6f3a 86 } while(tmr.read() < 30);
Mike Fiore 1:f155d94d6f3a 87
Mike Fiore 1:f155d94d6f3a 88 //AT#CONNECTIONSTART: Make a PPP connection
Mike Fiore 4:1f63354b8d1b 89 logDebug("Making PPP Connection Attempt. APN[%s]", apn.c_str());
Mike Fiore 1:f155d94d6f3a 90 std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
Mike Fiore 1:f155d94d6f3a 91 std::vector<std::string> parts = Text::split(pppResult, "\r\n");
Mike Fiore 1:f155d94d6f3a 92
Mike Fiore 1:f155d94d6f3a 93 if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
Mike Fiore 1:f155d94d6f3a 94 if(parts.size() >= 2) {
Mike Fiore 1:f155d94d6f3a 95 local_address = parts[1];
Mike Fiore 1:f155d94d6f3a 96 }
Mike Fiore 4:1f63354b8d1b 97 logInfo("PPP Connection Established: IP[%s]", local_address.c_str());
Mike Fiore 1:f155d94d6f3a 98 pppConnected = true;
Mike Fiore 1:f155d94d6f3a 99
Mike Fiore 1:f155d94d6f3a 100 } else {
Mike Fiore 1:f155d94d6f3a 101 pppConnected = false;
Mike Fiore 1:f155d94d6f3a 102 }
Mike Fiore 1:f155d94d6f3a 103
Mike Fiore 1:f155d94d6f3a 104 return pppConnected;
Mike Fiore 1:f155d94d6f3a 105 }
Mike Fiore 1:f155d94d6f3a 106
Mike Fiore 3:04046eebaef5 107 void UIP::disconnect()
Mike Fiore 1:f155d94d6f3a 108 {
Mike Fiore 1:f155d94d6f3a 109 //AT#CONNECTIONSTOP: Close a PPP connection
Mike Fiore 4:1f63354b8d1b 110 logDebug("Closing PPP Connection");
Mike Fiore 1:f155d94d6f3a 111
Mike Fiore 1:f155d94d6f3a 112 if(socketOpened) {
Mike Fiore 1:f155d94d6f3a 113 close();
Mike Fiore 1:f155d94d6f3a 114 }
Mike Fiore 1:f155d94d6f3a 115
Mike Fiore 1:f155d94d6f3a 116 Code code = sendBasicCommand("AT#CONNECTIONSTOP", 10000);
Mike Fiore 1:f155d94d6f3a 117 if(code == SUCCESS) {
Mike Fiore 4:1f63354b8d1b 118 logDebug("Successfully closed PPP Connection");
Mike Fiore 1:f155d94d6f3a 119 } else {
Mike Fiore 4:1f63354b8d1b 120 logError("Closing PPP Connection [%d]. Continuing ...", (int)code);
Mike Fiore 1:f155d94d6f3a 121 }
Mike Fiore 1:f155d94d6f3a 122
Mike Fiore 1:f155d94d6f3a 123 pppConnected = false;
Mike Fiore 1:f155d94d6f3a 124 }
Mike Fiore 1:f155d94d6f3a 125
Mike Fiore 3:04046eebaef5 126 bool UIP::isConnected()
Mike Fiore 1:f155d94d6f3a 127 {
Mike Fiore 1:f155d94d6f3a 128 //1) Check if APN was set
Mike Fiore 1:f155d94d6f3a 129 if(apn.size() == 0) {
Mike Fiore 4:1f63354b8d1b 130 logDebug("APN is not set");
Mike Fiore 1:f155d94d6f3a 131 return false;
Mike Fiore 1:f155d94d6f3a 132 }
Mike Fiore 1:f155d94d6f3a 133
Mike Fiore 1:f155d94d6f3a 134 //1) Check that we do not have a live connection up
Mike Fiore 1:f155d94d6f3a 135 if(socketOpened) {
Mike Fiore 4:1f63354b8d1b 136 logDebug("Socket is opened");
Mike Fiore 1:f155d94d6f3a 137 return true;
Mike Fiore 1:f155d94d6f3a 138 }
Mike Fiore 1:f155d94d6f3a 139 //2) Query the radio
Mike Fiore 1:f155d94d6f3a 140 std::string result = sendCommand("AT#VSTATE", 3000);
Mike Fiore 1:f155d94d6f3a 141 if(result.find("CONNECTED") != std::string::npos) {
Mike Fiore 1:f155d94d6f3a 142 if(pppConnected == false) {
Mike Fiore 4:1f63354b8d1b 143 logWarning("Internal PPP state tracking differs from radio (DISCONNECTED:CONNECTED)");
Mike Fiore 1:f155d94d6f3a 144 }
Mike Fiore 1:f155d94d6f3a 145 pppConnected = true;
Mike Fiore 1:f155d94d6f3a 146 } else {
Mike Fiore 1:f155d94d6f3a 147 if(pppConnected == true) {
Mike Fiore 1:f155d94d6f3a 148 //Find out what state is
Mike Fiore 1:f155d94d6f3a 149 size_t pos = result.find("STATE:");
Mike Fiore 1:f155d94d6f3a 150 if(pos != std::string::npos) {
Mike Fiore 1:f155d94d6f3a 151 result = Text::getLine(result, pos + sizeof("STATE:"), pos);
Mike Fiore 4:1f63354b8d1b 152 logWarning("Internal PPP state tracking differs from radio (CONNECTED:%s)", result.c_str());
Mike Fiore 1:f155d94d6f3a 153 } else {
Mike Fiore 4:1f63354b8d1b 154 logError("Unable to parse radio state: [%s]", result.c_str());
Mike Fiore 1:f155d94d6f3a 155 }
Mike Fiore 1:f155d94d6f3a 156
Mike Fiore 1:f155d94d6f3a 157 }
Mike Fiore 1:f155d94d6f3a 158 pppConnected = false;
Mike Fiore 1:f155d94d6f3a 159 }
Mike Fiore 1:f155d94d6f3a 160
Mike Fiore 1:f155d94d6f3a 161 return pppConnected;
Mike Fiore 1:f155d94d6f3a 162 }
Mike Fiore 1:f155d94d6f3a 163
Mike Fiore 3:04046eebaef5 164 bool UIP::bind(unsigned int port)
Mike Fiore 1:f155d94d6f3a 165 {
Mike Fiore 1:f155d94d6f3a 166 if(socketOpened) {
Mike Fiore 4:1f63354b8d1b 167 logError("socket is open. Can not set local port");
Mike Fiore 1:f155d94d6f3a 168 return false;
Mike Fiore 1:f155d94d6f3a 169 }
Mike Fiore 1:f155d94d6f3a 170 if(port > 65535) {
Mike Fiore 4:1f63354b8d1b 171 logError("port out of range (0-65535)");
Mike Fiore 1:f155d94d6f3a 172 return false;
Mike Fiore 1:f155d94d6f3a 173 }
Mike Fiore 1:f155d94d6f3a 174 local_port = port;
Mike Fiore 1:f155d94d6f3a 175 return true;
Mike Fiore 1:f155d94d6f3a 176 }
Mike Fiore 1:f155d94d6f3a 177
Mike Fiore 3:04046eebaef5 178 bool UIP::open(const std::string& address, unsigned int port, Mode mode)
Mike Fiore 1:f155d94d6f3a 179 {
Mike Fiore 1:f155d94d6f3a 180 char buffer[256] = {0};
Mike Fiore 1:f155d94d6f3a 181 Code portCode, addressCode;
Mike Fiore 1:f155d94d6f3a 182
Mike Fiore 1:f155d94d6f3a 183 //1) Check that we do not have a live connection up
Mike Fiore 1:f155d94d6f3a 184 if(socketOpened) {
Mike Fiore 1:f155d94d6f3a 185 //Check that the address, port, and mode match
Mike Fiore 1:f155d94d6f3a 186 if(host_address != address || host_port != port || this->mode != mode) {
Mike Fiore 1:f155d94d6f3a 187 if(this->mode == TCP) {
Mike Fiore 4:1f63354b8d1b 188 logError("TCP socket already opened [%s:%d]", host_address.c_str(), host_port);
Mike Fiore 1:f155d94d6f3a 189 } else {
Mike Fiore 4:1f63354b8d1b 190 logError("UDP socket already opened [%s:%d]", host_address.c_str(), host_port);
Mike Fiore 1:f155d94d6f3a 191 }
Mike Fiore 1:f155d94d6f3a 192 return false;
Mike Fiore 1:f155d94d6f3a 193 }
Mike Fiore 1:f155d94d6f3a 194
Mike Fiore 4:1f63354b8d1b 195 logDebug("Socket already opened");
Mike Fiore 1:f155d94d6f3a 196 return true;
Mike Fiore 1:f155d94d6f3a 197 }
Mike Fiore 1:f155d94d6f3a 198
Mike Fiore 1:f155d94d6f3a 199 //2) Check Parameters
Mike Fiore 1:f155d94d6f3a 200 if(port > 65535) {
Mike Fiore 4:1f63354b8d1b 201 logError("port out of range (0-65535)");
Mike Fiore 1:f155d94d6f3a 202 return false;
Mike Fiore 1:f155d94d6f3a 203 }
Mike Fiore 1:f155d94d6f3a 204
Mike Fiore 1:f155d94d6f3a 205 //3) Check PPP connection
Mike Fiore 1:f155d94d6f3a 206 if(!isConnected()) {
Mike Fiore 4:1f63354b8d1b 207 logError("PPP not established. Attempting to connect");
Mike Fiore 1:f155d94d6f3a 208 if(!connect()) {
Mike Fiore 4:1f63354b8d1b 209 logError("PPP connection failed");
Mike Fiore 1:f155d94d6f3a 210 return false;
Mike Fiore 1:f155d94d6f3a 211 } else {
Mike Fiore 4:1f63354b8d1b 212 logDebug("PPP connection established");
Mike Fiore 1:f155d94d6f3a 213 }
Mike Fiore 1:f155d94d6f3a 214 }
Mike Fiore 1:f155d94d6f3a 215
Mike Fiore 1:f155d94d6f3a 216 //Set Local Port
Mike Fiore 1:f155d94d6f3a 217 if(local_port != 0) {
Mike Fiore 1:f155d94d6f3a 218 //Attempt to set local port
Mike Fiore 1:f155d94d6f3a 219 sprintf(buffer, "AT#OUTPORT=%d", local_port);
Mike Fiore 1:f155d94d6f3a 220 Code code = sendBasicCommand(buffer, 1000);
Mike Fiore 1:f155d94d6f3a 221 if(code != SUCCESS) {
Mike Fiore 4:1f63354b8d1b 222 logWarning("Unable to set local port (%d) [%d]", local_port, (int) code);
Mike Fiore 1:f155d94d6f3a 223 }
Mike Fiore 1:f155d94d6f3a 224 }
Mike Fiore 1:f155d94d6f3a 225
Mike Fiore 1:f155d94d6f3a 226 //Set TCP/UDP parameters
Mike Fiore 1:f155d94d6f3a 227 if(mode == TCP) {
Mike Fiore 1:f155d94d6f3a 228 if(socketCloseable) {
Mike Fiore 1:f155d94d6f3a 229 Code code = sendBasicCommand("AT#DLEMODE=1,1", 1000);
Mike Fiore 1:f155d94d6f3a 230 if(code != SUCCESS) {
Mike Fiore 4:1f63354b8d1b 231 logWarning("Unable to set socket closeable [%d]", (int) code);
Mike Fiore 1:f155d94d6f3a 232 }
Mike Fiore 1:f155d94d6f3a 233 }
Mike Fiore 1:f155d94d6f3a 234 sprintf(buffer, "AT#TCPPORT=1,%d", port);
Mike Fiore 1:f155d94d6f3a 235 portCode = sendBasicCommand(buffer, 1000);
Mike Fiore 1:f155d94d6f3a 236 addressCode = sendBasicCommand("AT#TCPSERV=1,\"" + address + "\"", 1000);
Mike Fiore 1:f155d94d6f3a 237 } else {
Mike Fiore 1:f155d94d6f3a 238 if(socketCloseable) {
Mike Fiore 1:f155d94d6f3a 239 Code code = sendBasicCommand("AT#UDPDLEMODE=1", 1000);
Mike Fiore 1:f155d94d6f3a 240 if(code != SUCCESS) {
Mike Fiore 4:1f63354b8d1b 241 logWarning("Unable to set socket closeable [%d]", (int) code);
Mike Fiore 1:f155d94d6f3a 242 }
Mike Fiore 1:f155d94d6f3a 243 }
Mike Fiore 1:f155d94d6f3a 244 sprintf(buffer, "AT#UDPPORT=%d", port);
Mike Fiore 1:f155d94d6f3a 245 portCode = sendBasicCommand(buffer, 1000);
Mike Fiore 1:f155d94d6f3a 246 addressCode = sendBasicCommand("AT#UDPSERV=\"" + address + "\"", 1000);
Mike Fiore 1:f155d94d6f3a 247 }
Mike Fiore 1:f155d94d6f3a 248
Mike Fiore 1:f155d94d6f3a 249 if(portCode == SUCCESS) {
Mike Fiore 1:f155d94d6f3a 250 host_port = port;
Mike Fiore 1:f155d94d6f3a 251 } else {
Mike Fiore 4:1f63354b8d1b 252 logError("Host port could not be set");
Mike Fiore 1:f155d94d6f3a 253 }
Mike Fiore 1:f155d94d6f3a 254
Mike Fiore 1:f155d94d6f3a 255 if(addressCode == SUCCESS) {
Mike Fiore 1:f155d94d6f3a 256 host_address = address;
Mike Fiore 1:f155d94d6f3a 257 } else {
Mike Fiore 4:1f63354b8d1b 258 logError("Host address could not be set");
Mike Fiore 1:f155d94d6f3a 259 }
Mike Fiore 1:f155d94d6f3a 260
Mike Fiore 1:f155d94d6f3a 261 // Try and Connect
Mike Fiore 1:f155d94d6f3a 262 std::string sMode;
Mike Fiore 1:f155d94d6f3a 263 std::string sOpenSocketCmd;
Mike Fiore 1:f155d94d6f3a 264 if(mode == TCP) {
Mike Fiore 1:f155d94d6f3a 265 sOpenSocketCmd = "AT#OTCP=1";
Mike Fiore 1:f155d94d6f3a 266 sMode = "TCP";
Mike Fiore 1:f155d94d6f3a 267 } else {
Mike Fiore 1:f155d94d6f3a 268 sOpenSocketCmd = "AT#OUDP";
Mike Fiore 1:f155d94d6f3a 269 sMode = "UDP";
Mike Fiore 1:f155d94d6f3a 270 }
Mike Fiore 1:f155d94d6f3a 271
Mike Fiore 1:f155d94d6f3a 272 string response = sendCommand(sOpenSocketCmd, 30000);
Mike Fiore 1:f155d94d6f3a 273 if (response.find("Ok_Info_WaitingForData") != string::npos) {
Mike Fiore 4:1f63354b8d1b 274 logInfo("Opened %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port);
Mike Fiore 1:f155d94d6f3a 275 socketOpened = true;
Mike Fiore 1:f155d94d6f3a 276 } else {
Mike Fiore 4:1f63354b8d1b 277 logWarning("Unable to open %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port);
Mike Fiore 1:f155d94d6f3a 278 socketOpened = false;
Mike Fiore 1:f155d94d6f3a 279 }
Mike Fiore 1:f155d94d6f3a 280
Mike Fiore 1:f155d94d6f3a 281 return socketOpened;
Mike Fiore 1:f155d94d6f3a 282 }
Mike Fiore 1:f155d94d6f3a 283
Mike Fiore 3:04046eebaef5 284 bool UIP::isOpen()
Mike Fiore 1:f155d94d6f3a 285 {
Mike Fiore 1:f155d94d6f3a 286 if(io->readable()) {
Mike Fiore 4:1f63354b8d1b 287 logDebug("Assuming open, data available to read.\n\r");
Mike Fiore 1:f155d94d6f3a 288 return true;
Mike Fiore 1:f155d94d6f3a 289 }
Mike Fiore 1:f155d94d6f3a 290 return socketOpened;
Mike Fiore 1:f155d94d6f3a 291 }
Mike Fiore 1:f155d94d6f3a 292
Mike Fiore 3:04046eebaef5 293 bool UIP::close()
Mike Fiore 1:f155d94d6f3a 294 {
Mike Fiore 1:f155d94d6f3a 295 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 296 logError("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 297 return false;
Mike Fiore 1:f155d94d6f3a 298 }
Mike Fiore 1:f155d94d6f3a 299
Mike Fiore 1:f155d94d6f3a 300 if(!socketOpened) {
Mike Fiore 4:1f63354b8d1b 301 logWarning("Socket close() called, but socket was not open");
Mike Fiore 1:f155d94d6f3a 302 return true;
Mike Fiore 1:f155d94d6f3a 303 }
Mike Fiore 1:f155d94d6f3a 304
Mike Fiore 1:f155d94d6f3a 305 if(!socketCloseable) {
Mike Fiore 4:1f63354b8d1b 306 logError("Socket is not closeable");
Mike Fiore 1:f155d94d6f3a 307 return false;
Mike Fiore 1:f155d94d6f3a 308 }
Mike Fiore 1:f155d94d6f3a 309
Mike Fiore 1:f155d94d6f3a 310
Mike Fiore 1:f155d94d6f3a 311
Mike Fiore 1:f155d94d6f3a 312 if(io->write(ETX, 1000) != 1) {
Mike Fiore 4:1f63354b8d1b 313 logError("Timed out attempting to close socket");
Mike Fiore 1:f155d94d6f3a 314 return false;
Mike Fiore 1:f155d94d6f3a 315 }
Mike Fiore 1:f155d94d6f3a 316
Mike Fiore 1:f155d94d6f3a 317 Timer tmr;
Mike Fiore 1:f155d94d6f3a 318 int counter = 0;
Mike Fiore 1:f155d94d6f3a 319 char tmp[256];
Mike Fiore 1:f155d94d6f3a 320 tmr.start();
Mike Fiore 1:f155d94d6f3a 321 do {
Mike Fiore 1:f155d94d6f3a 322 if(socketOpened == false) {
Mike Fiore 1:f155d94d6f3a 323 break;
Mike Fiore 1:f155d94d6f3a 324 }
Mike Fiore 1:f155d94d6f3a 325 read(tmp, 256, 1000);
Mike Fiore 1:f155d94d6f3a 326 } while(counter++ < 10);
Mike Fiore 1:f155d94d6f3a 327
Mike Fiore 1:f155d94d6f3a 328 io->rxClear();
Mike Fiore 1:f155d94d6f3a 329 io->txClear();
Mike Fiore 1:f155d94d6f3a 330
Mike Fiore 1:f155d94d6f3a 331 socketOpened = false;
Mike Fiore 1:f155d94d6f3a 332 return true;
Mike Fiore 1:f155d94d6f3a 333 }
Mike Fiore 1:f155d94d6f3a 334
Mike Fiore 3:04046eebaef5 335 int UIP::read(char* data, int max, int timeout)
Mike Fiore 1:f155d94d6f3a 336 {
Mike Fiore 1:f155d94d6f3a 337 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 338 logError("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 339 return -1;
Mike Fiore 1:f155d94d6f3a 340 }
Mike Fiore 1:f155d94d6f3a 341
Mike Fiore 1:f155d94d6f3a 342 //Check that nothing is in the rx buffer
Mike Fiore 1:f155d94d6f3a 343 if(!socketOpened && !io->readable()) {
Mike Fiore 4:1f63354b8d1b 344 logError("Socket is not open");
Mike Fiore 1:f155d94d6f3a 345 return -1;
Mike Fiore 1:f155d94d6f3a 346 }
Mike Fiore 1:f155d94d6f3a 347
Mike Fiore 1:f155d94d6f3a 348 int bytesRead = 0;
Mike Fiore 1:f155d94d6f3a 349
Mike Fiore 1:f155d94d6f3a 350 if(timeout >= 0) {
Mike Fiore 1:f155d94d6f3a 351 bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
Mike Fiore 1:f155d94d6f3a 352 } else {
Mike Fiore 1:f155d94d6f3a 353 bytesRead = io->read(data, max);
Mike Fiore 1:f155d94d6f3a 354 }
Mike Fiore 1:f155d94d6f3a 355
Mike Fiore 1:f155d94d6f3a 356 if(bytesRead > 0 && socketCloseable) {
Mike Fiore 1:f155d94d6f3a 357 //Remove escape characters
Mike Fiore 1:f155d94d6f3a 358 int index = 0;
Mike Fiore 1:f155d94d6f3a 359 bool escapeFlag = false;
Mike Fiore 1:f155d94d6f3a 360 for(int i = 0; i < bytesRead; i++) {
Mike Fiore 1:f155d94d6f3a 361 if(data[i] == DLE || data[i] == ETX) {
Mike Fiore 1:f155d94d6f3a 362 if(escapeFlag == true) {
Mike Fiore 1:f155d94d6f3a 363 //This character has been escaped
Mike Fiore 1:f155d94d6f3a 364 escapeFlag = false;
Mike Fiore 1:f155d94d6f3a 365 } else if(data[bytesRead] == DLE) {
Mike Fiore 1:f155d94d6f3a 366 //Found escape character
Mike Fiore 1:f155d94d6f3a 367 escapeFlag = true;
Mike Fiore 1:f155d94d6f3a 368 continue;
Mike Fiore 1:f155d94d6f3a 369 } else {
Mike Fiore 1:f155d94d6f3a 370 //ETX sent without escape -> Socket closed
Mike Fiore 4:1f63354b8d1b 371 logInfo("Read ETX character without DLE escape. Socket closed");
Mike Fiore 1:f155d94d6f3a 372 socketOpened = false;
Mike Fiore 1:f155d94d6f3a 373 continue;
Mike Fiore 1:f155d94d6f3a 374 }
Mike Fiore 1:f155d94d6f3a 375 }
Mike Fiore 1:f155d94d6f3a 376
Mike Fiore 1:f155d94d6f3a 377 if(index != i) {
Mike Fiore 1:f155d94d6f3a 378 data[index] = data[i];
Mike Fiore 1:f155d94d6f3a 379 }
Mike Fiore 1:f155d94d6f3a 380 index++;
Mike Fiore 1:f155d94d6f3a 381 }
Mike Fiore 1:f155d94d6f3a 382 bytesRead = index;
Mike Fiore 1:f155d94d6f3a 383 }
Mike Fiore 1:f155d94d6f3a 384
Mike Fiore 1:f155d94d6f3a 385 //Scan for socket closed message
Mike Fiore 1:f155d94d6f3a 386 for(size_t i = 0; i < bytesRead; i++) {
Mike Fiore 1:f155d94d6f3a 387 if(data[i] == 'O') {
Mike Fiore 1:f155d94d6f3a 388 if(strstr(&data[i], "Ok_Info_SocketClosed")) {
Mike Fiore 4:1f63354b8d1b 389 logInfo("Found socket closed message. Socket closed");
Mike Fiore 1:f155d94d6f3a 390 //Close socket and Cut Off End of Message
Mike Fiore 1:f155d94d6f3a 391 socketOpened = false;
Mike Fiore 1:f155d94d6f3a 392 data[i] = '\0';
Mike Fiore 1:f155d94d6f3a 393 bytesRead = i;
Mike Fiore 1:f155d94d6f3a 394 break;
Mike Fiore 1:f155d94d6f3a 395 }
Mike Fiore 1:f155d94d6f3a 396 }
Mike Fiore 1:f155d94d6f3a 397 }
Mike Fiore 1:f155d94d6f3a 398 return bytesRead;
Mike Fiore 1:f155d94d6f3a 399 }
Mike Fiore 1:f155d94d6f3a 400
Mike Fiore 3:04046eebaef5 401 int UIP::write(const char* data, int length, int timeout)
Mike Fiore 1:f155d94d6f3a 402 {
Mike Fiore 1:f155d94d6f3a 403 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 404 logError("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 405 return -1;
Mike Fiore 1:f155d94d6f3a 406 }
Mike Fiore 1:f155d94d6f3a 407
Mike Fiore 1:f155d94d6f3a 408 if(!socketOpened) {
Mike Fiore 4:1f63354b8d1b 409 logError("Socket is not open");
Mike Fiore 1:f155d94d6f3a 410 return -1;
Mike Fiore 1:f155d94d6f3a 411 }
Mike Fiore 1:f155d94d6f3a 412
Mike Fiore 1:f155d94d6f3a 413 //In order to avoid allocating another buffer, capture indices of
Mike Fiore 1:f155d94d6f3a 414 //characters to escape during write
Mike Fiore 1:f155d94d6f3a 415 int specialWritten = 0;
Mike Fiore 1:f155d94d6f3a 416 std::vector<int> vSpecial;
Mike Fiore 1:f155d94d6f3a 417 if(socketCloseable) {
Mike Fiore 1:f155d94d6f3a 418 for(int i = 0; i < length; i++) {
Mike Fiore 1:f155d94d6f3a 419 if(data[i] == ETX || data[i] == DLE) {
Mike Fiore 1:f155d94d6f3a 420 //Push back index of special characters
Mike Fiore 1:f155d94d6f3a 421 vSpecial.push_back(i);
Mike Fiore 1:f155d94d6f3a 422 }
Mike Fiore 1:f155d94d6f3a 423 }
Mike Fiore 1:f155d94d6f3a 424 }
Mike Fiore 1:f155d94d6f3a 425
Mike Fiore 1:f155d94d6f3a 426 int bytesWritten = 0;
Mike Fiore 1:f155d94d6f3a 427 if(timeout >= 0) {
Mike Fiore 1:f155d94d6f3a 428 Timer tmr;
Mike Fiore 1:f155d94d6f3a 429 tmr.start();
Mike Fiore 1:f155d94d6f3a 430 do {
Mike Fiore 1:f155d94d6f3a 431 int available = io->writeable();
Mike Fiore 1:f155d94d6f3a 432 if (available > 0) {
Mike Fiore 1:f155d94d6f3a 433 if(specialWritten < vSpecial.size()) {
Mike Fiore 1:f155d94d6f3a 434 //Check if current index is at a special character
Mike Fiore 1:f155d94d6f3a 435 if(bytesWritten == vSpecial[specialWritten]) {
Mike Fiore 1:f155d94d6f3a 436 if(available < 2) {
Mike Fiore 1:f155d94d6f3a 437 //Requires at least two bytes of space
Mike Fiore 1:f155d94d6f3a 438 wait(0.05);
Mike Fiore 1:f155d94d6f3a 439 continue;
Mike Fiore 1:f155d94d6f3a 440 }
Mike Fiore 1:f155d94d6f3a 441 //Ready to write special character
Mike Fiore 1:f155d94d6f3a 442 if(io->write(DLE)) {
Mike Fiore 1:f155d94d6f3a 443 specialWritten++;
Mike Fiore 1:f155d94d6f3a 444 if(io->write(data[bytesWritten])) {
Mike Fiore 1:f155d94d6f3a 445 bytesWritten++;
Mike Fiore 1:f155d94d6f3a 446 }
Mike Fiore 1:f155d94d6f3a 447 } else {
Mike Fiore 1:f155d94d6f3a 448 //Unable to write escape character, try again next round
Mike Fiore 1:f155d94d6f3a 449 wait(0.05);
Mike Fiore 1:f155d94d6f3a 450 }
Mike Fiore 1:f155d94d6f3a 451 } else {
Mike Fiore 1:f155d94d6f3a 452 //We want to write all the way up to the next special character
Mike Fiore 1:f155d94d6f3a 453 int relativeIndex = vSpecial[specialWritten] - bytesWritten;
Mike Fiore 1:f155d94d6f3a 454 int size = MIN(available, relativeIndex);
Mike Fiore 1:f155d94d6f3a 455 bytesWritten += io->write(&data[bytesWritten], size);
Mike Fiore 1:f155d94d6f3a 456 }
Mike Fiore 1:f155d94d6f3a 457 } else {
Mike Fiore 1:f155d94d6f3a 458 int size = MIN(available, length - bytesWritten);
Mike Fiore 1:f155d94d6f3a 459 bytesWritten += io->write(&data[bytesWritten], size);
Mike Fiore 1:f155d94d6f3a 460 }
Mike Fiore 1:f155d94d6f3a 461 } else {
Mike Fiore 1:f155d94d6f3a 462 wait(0.05);
Mike Fiore 1:f155d94d6f3a 463 }
Mike Fiore 1:f155d94d6f3a 464 } while (tmr.read_ms() <= timeout && bytesWritten < length);
Mike Fiore 1:f155d94d6f3a 465 } else {
Mike Fiore 1:f155d94d6f3a 466 for(int i = 0; i < vSpecial.size(); i++) {
Mike Fiore 1:f155d94d6f3a 467 //Write up to the special character, then write the special character
Mike Fiore 1:f155d94d6f3a 468 int size = vSpecial[i] - bytesWritten;
Mike Fiore 1:f155d94d6f3a 469 int currentWritten = io->write(&data[bytesWritten], size);
Mike Fiore 1:f155d94d6f3a 470 bytesWritten += currentWritten;
Mike Fiore 1:f155d94d6f3a 471 if(currentWritten != size) {
Mike Fiore 1:f155d94d6f3a 472 //Failed to write up to the special character.
Mike Fiore 1:f155d94d6f3a 473 return bytesWritten;
Mike Fiore 1:f155d94d6f3a 474 }
Mike Fiore 1:f155d94d6f3a 475 if(io->write(DLE) && io->write(data[bytesWritten])) {
Mike Fiore 1:f155d94d6f3a 476 bytesWritten++;
Mike Fiore 1:f155d94d6f3a 477 } else {
Mike Fiore 1:f155d94d6f3a 478 //Failed to write the special character.
Mike Fiore 1:f155d94d6f3a 479 return bytesWritten;
Mike Fiore 1:f155d94d6f3a 480 }
Mike Fiore 1:f155d94d6f3a 481 }
Mike Fiore 1:f155d94d6f3a 482
Mike Fiore 1:f155d94d6f3a 483 bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
Mike Fiore 1:f155d94d6f3a 484 }
Mike Fiore 1:f155d94d6f3a 485
Mike Fiore 1:f155d94d6f3a 486 return bytesWritten;
Mike Fiore 1:f155d94d6f3a 487 }
Mike Fiore 1:f155d94d6f3a 488
Mike Fiore 3:04046eebaef5 489 unsigned int UIP::readable()
Mike Fiore 1:f155d94d6f3a 490 {
Mike Fiore 1:f155d94d6f3a 491 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 492 logWarning("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 493 return 0;
Mike Fiore 1:f155d94d6f3a 494 }
Mike Fiore 1:f155d94d6f3a 495 if(!socketOpened && !io->readable()) {
Mike Fiore 4:1f63354b8d1b 496 logWarning("Socket is not open");
Mike Fiore 1:f155d94d6f3a 497 return 0;
Mike Fiore 1:f155d94d6f3a 498 }
Mike Fiore 1:f155d94d6f3a 499 return io->readable();
Mike Fiore 1:f155d94d6f3a 500 }
Mike Fiore 1:f155d94d6f3a 501
Mike Fiore 3:04046eebaef5 502 unsigned int UIP::writeable()
Mike Fiore 1:f155d94d6f3a 503 {
Mike Fiore 1:f155d94d6f3a 504 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 505 logWarning("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 506 return 0;
Mike Fiore 1:f155d94d6f3a 507 }
Mike Fiore 1:f155d94d6f3a 508 if(!socketOpened) {
Mike Fiore 4:1f63354b8d1b 509 logWarning("Socket is not open");
Mike Fiore 1:f155d94d6f3a 510 return 0;
Mike Fiore 1:f155d94d6f3a 511 }
Mike Fiore 1:f155d94d6f3a 512
Mike Fiore 1:f155d94d6f3a 513 return io->writeable();
Mike Fiore 1:f155d94d6f3a 514 }
Mike Fiore 1:f155d94d6f3a 515
Mike Fiore 3:04046eebaef5 516 bool UIP::setDeviceIP(std::string address)
Mike Fiore 1:f155d94d6f3a 517 {
Mike Fiore 1:f155d94d6f3a 518 if (address.compare("DHCP") == 0) {
Mike Fiore 1:f155d94d6f3a 519 return true;
Mike Fiore 1:f155d94d6f3a 520 } else {
Mike Fiore 4:1f63354b8d1b 521 logWarning("Radio does not support static IPs, using DHCP.\n\r");
Mike Fiore 1:f155d94d6f3a 522 return false;
Mike Fiore 1:f155d94d6f3a 523 }
Mike Fiore 1:f155d94d6f3a 524 }
Mike Fiore 1:f155d94d6f3a 525
Mike Fiore 3:04046eebaef5 526 void UIP::reset()
Mike Fiore 1:f155d94d6f3a 527 {
Mike Fiore 1:f155d94d6f3a 528 disconnect();
Mike Fiore 1:f155d94d6f3a 529 Code code = sendBasicCommand("AT#RESET=0", 10000);
Mike Fiore 1:f155d94d6f3a 530 if(code != SUCCESS) {
Mike Fiore 4:1f63354b8d1b 531 logError("Socket Modem did not accept RESET command\n\r");
Mike Fiore 1:f155d94d6f3a 532 } else {
Mike Fiore 4:1f63354b8d1b 533 logWarning("Socket Modem is resetting, allow 30 seconds for it to come back\n\r");
Mike Fiore 1:f155d94d6f3a 534 }
Mike Fiore 1:f155d94d6f3a 535 }
Mike Fiore 1:f155d94d6f3a 536
Mike Fiore 3:04046eebaef5 537 std::string UIP::getDeviceIP()
Mike Fiore 1:f155d94d6f3a 538 {
Mike Fiore 1:f155d94d6f3a 539 return local_address;
Mike Fiore 1:f155d94d6f3a 540 }
Mike Fiore 1:f155d94d6f3a 541
Mike Fiore 3:04046eebaef5 542 Code UIP::echo(bool state)
Mike Fiore 1:f155d94d6f3a 543 {
Mike Fiore 1:f155d94d6f3a 544 Code code;
Mike Fiore 1:f155d94d6f3a 545 if (state) {
Mike Fiore 1:f155d94d6f3a 546 code = sendBasicCommand("ATE0", 1000);
Mike Fiore 1:f155d94d6f3a 547 echoMode = (code == SUCCESS) ? false : echoMode;
Mike Fiore 1:f155d94d6f3a 548 } else {
Mike Fiore 1:f155d94d6f3a 549 code = sendBasicCommand("ATE1", 1000);
Mike Fiore 1:f155d94d6f3a 550 echoMode = (code == SUCCESS) ? true : echoMode;
Mike Fiore 1:f155d94d6f3a 551 }
Mike Fiore 1:f155d94d6f3a 552 return code;
Mike Fiore 1:f155d94d6f3a 553 }
Mike Fiore 1:f155d94d6f3a 554
Mike Fiore 3:04046eebaef5 555 bool UIP::ping(const std::string& address)
Mike Fiore 1:f155d94d6f3a 556 {
Mike Fiore 1:f155d94d6f3a 557 char buffer[256] = {0};
Mike Fiore 1:f155d94d6f3a 558 Code code;
Mike Fiore 1:f155d94d6f3a 559
Mike Fiore 1:f155d94d6f3a 560 code = sendBasicCommand("AT#PINGREMOTE=\"" + address + "\"", 1000);
Mike Fiore 1:f155d94d6f3a 561 if (code != SUCCESS) {
Mike Fiore 1:f155d94d6f3a 562 return false;
Mike Fiore 1:f155d94d6f3a 563 }
Mike Fiore 1:f155d94d6f3a 564
Mike Fiore 1:f155d94d6f3a 565 sprintf(buffer, "AT#PINGNUM=%d", 1);
Mike Fiore 1:f155d94d6f3a 566 code = sendBasicCommand(buffer , 1000);
Mike Fiore 1:f155d94d6f3a 567 if (code != SUCCESS) {
Mike Fiore 1:f155d94d6f3a 568 return false;
Mike Fiore 1:f155d94d6f3a 569 }
Mike Fiore 1:f155d94d6f3a 570
Mike Fiore 1:f155d94d6f3a 571 sprintf(buffer, "AT#PINGDELAY=%d", PINGDELAY);
Mike Fiore 1:f155d94d6f3a 572 code = sendBasicCommand(buffer , 1000);
Mike Fiore 1:f155d94d6f3a 573 if (code != SUCCESS) {
Mike Fiore 1:f155d94d6f3a 574 return false;
Mike Fiore 1:f155d94d6f3a 575 }
Mike Fiore 1:f155d94d6f3a 576
Mike Fiore 1:f155d94d6f3a 577 std::string response;
Mike Fiore 1:f155d94d6f3a 578 for (int i = 0; i < PINGNUM; i++) {
Mike Fiore 1:f155d94d6f3a 579 response = sendCommand("AT#PING", PINGDELAY * 1000);
Mike Fiore 1:f155d94d6f3a 580 if (response.find("alive") != std::string::npos) {
Mike Fiore 1:f155d94d6f3a 581 return true;
Mike Fiore 1:f155d94d6f3a 582 }
Mike Fiore 1:f155d94d6f3a 583 }
Mike Fiore 1:f155d94d6f3a 584 return false;
Mike Fiore 1:f155d94d6f3a 585 }
Mike Fiore 1:f155d94d6f3a 586
Mike Fiore 3:04046eebaef5 587 Code UIP::setSocketCloseable(bool enabled)
Mike Fiore 1:f155d94d6f3a 588 {
Mike Fiore 1:f155d94d6f3a 589 if(socketCloseable == enabled) {
Mike Fiore 1:f155d94d6f3a 590 return SUCCESS;
Mike Fiore 1:f155d94d6f3a 591 }
Mike Fiore 1:f155d94d6f3a 592
Mike Fiore 1:f155d94d6f3a 593 if(socketOpened) {
Mike Fiore 4:1f63354b8d1b 594 logError("socket is already opened. Can not set closeable");
Mike Fiore 1:f155d94d6f3a 595 return ERROR;
Mike Fiore 1:f155d94d6f3a 596 }
Mike Fiore 1:f155d94d6f3a 597
Mike Fiore 1:f155d94d6f3a 598 socketCloseable = enabled;
Mike Fiore 1:f155d94d6f3a 599
Mike Fiore 1:f155d94d6f3a 600 return SUCCESS;
Mike Fiore 1:f155d94d6f3a 601 }
Mike Fiore 1:f155d94d6f3a 602
Mike Fiore 3:04046eebaef5 603 Code UIP::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc)
Mike Fiore 1:f155d94d6f3a 604 {
Mike Fiore 1:f155d94d6f3a 605 if(socketOpened) {
Mike Fiore 4:1f63354b8d1b 606 logError("socket is open. Can not send AT commands");
Mike Fiore 1:f155d94d6f3a 607 return ERROR;
Mike Fiore 1:f155d94d6f3a 608 }
Mike Fiore 1:f155d94d6f3a 609
Mike Fiore 1:f155d94d6f3a 610 string response = sendCommand(command, timeoutMillis, esc);
Mike Fiore 1:f155d94d6f3a 611 if (response.size() == 0) {
Mike Fiore 1:f155d94d6f3a 612 return NO_RESPONSE;
Mike Fiore 1:f155d94d6f3a 613 } else if (response.find("OK") != string::npos) {
Mike Fiore 1:f155d94d6f3a 614 return SUCCESS;
Mike Fiore 1:f155d94d6f3a 615 } else if (response.find("ERROR") != string::npos) {
Mike Fiore 1:f155d94d6f3a 616 return ERROR;
Mike Fiore 1:f155d94d6f3a 617 } else {
Mike Fiore 1:f155d94d6f3a 618 return FAILURE;
Mike Fiore 1:f155d94d6f3a 619 }
Mike Fiore 1:f155d94d6f3a 620 }
Mike Fiore 1:f155d94d6f3a 621
Mike Fiore 3:04046eebaef5 622 string UIP::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
Mike Fiore 1:f155d94d6f3a 623 {
Mike Fiore 1:f155d94d6f3a 624 if(io == NULL) {
Mike Fiore 4:1f63354b8d1b 625 logError("MTSBufferedIO not set");
Mike Fiore 1:f155d94d6f3a 626 return "";
Mike Fiore 1:f155d94d6f3a 627 }
Mike Fiore 1:f155d94d6f3a 628 if(socketOpened) {
Mike Fiore 4:1f63354b8d1b 629 logError("socket is open. Can not send AT commands");
Mike Fiore 1:f155d94d6f3a 630 return "";
Mike Fiore 1:f155d94d6f3a 631 }
Mike Fiore 1:f155d94d6f3a 632
Mike Fiore 1:f155d94d6f3a 633 io->rxClear();
Mike Fiore 1:f155d94d6f3a 634 io->txClear();
Mike Fiore 1:f155d94d6f3a 635 std::string result;
Mike Fiore 1:f155d94d6f3a 636
Mike Fiore 1:f155d94d6f3a 637 //Attempt to write command
Mike Fiore 1:f155d94d6f3a 638 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
Mike Fiore 1:f155d94d6f3a 639 //Failed to write command
Mike Fiore 1:f155d94d6f3a 640 if (command != "AT" && command != "at") {
Mike Fiore 4:1f63354b8d1b 641 logError("failed to send command to radio within %d milliseconds", timeoutMillis);
Mike Fiore 1:f155d94d6f3a 642 }
Mike Fiore 1:f155d94d6f3a 643 return "";
Mike Fiore 1:f155d94d6f3a 644 }
Mike Fiore 1:f155d94d6f3a 645
Mike Fiore 1:f155d94d6f3a 646 //Send Escape Character
Mike Fiore 1:f155d94d6f3a 647 if (esc != 0x00) {
Mike Fiore 1:f155d94d6f3a 648 if(io->write(esc, timeoutMillis) != 1) {
Mike Fiore 1:f155d94d6f3a 649 if (command != "AT" && command != "at") {
Mike Fiore 4:1f63354b8d1b 650 logError("failed to send character '%c' (0x%02X) to radio within %d milliseconds", esc, esc, timeoutMillis);
Mike Fiore 1:f155d94d6f3a 651 }
Mike Fiore 1:f155d94d6f3a 652 return "";
Mike Fiore 1:f155d94d6f3a 653 }
Mike Fiore 1:f155d94d6f3a 654 }
Mike Fiore 1:f155d94d6f3a 655
Mike Fiore 1:f155d94d6f3a 656 int timer = 0;
Mike Fiore 1:f155d94d6f3a 657 size_t previous = 0;
Mike Fiore 1:f155d94d6f3a 658 char tmp[256];
Mike Fiore 1:f155d94d6f3a 659 tmp[255] = 0;
Mike Fiore 1:f155d94d6f3a 660 bool started = !echoMode;
Mike Fiore 1:f155d94d6f3a 661 bool done = false;
Mike Fiore 1:f155d94d6f3a 662 do {
Mike Fiore 1:f155d94d6f3a 663 wait(0.1);
Mike Fiore 1:f155d94d6f3a 664 timer += 100;
Mike Fiore 1:f155d94d6f3a 665
Mike Fiore 1:f155d94d6f3a 666 previous = result.size();
Mike Fiore 1:f155d94d6f3a 667 //Make a non-blocking read call by passing timeout of zero
Mike Fiore 1:f155d94d6f3a 668 int size = io->read(tmp,255,0); //1 less than allocated (timeout is instant)
Mike Fiore 1:f155d94d6f3a 669 if(size > 0) {
Mike Fiore 1:f155d94d6f3a 670 result.append(tmp, size);
Mike Fiore 1:f155d94d6f3a 671 }
Mike Fiore 1:f155d94d6f3a 672 if(!started) {
Mike Fiore 1:f155d94d6f3a 673 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
Mike Fiore 1:f155d94d6f3a 674 if(result.size() > command.size() + 2) {
Mike Fiore 1:f155d94d6f3a 675 started = true;
Mike Fiore 1:f155d94d6f3a 676 }
Mike Fiore 1:f155d94d6f3a 677 } else {
Mike Fiore 1:f155d94d6f3a 678 done = (result.size() == previous);
Mike Fiore 1:f155d94d6f3a 679 }
Mike Fiore 1:f155d94d6f3a 680 if(timer >= timeoutMillis) {
Mike Fiore 1:f155d94d6f3a 681 if (command != "AT" && command != "at") {
Mike Fiore 4:1f63354b8d1b 682 logWarning("sendCommand [%s] timed out after %d milliseconds", command.c_str(), timeoutMillis);
Mike Fiore 1:f155d94d6f3a 683 }
Mike Fiore 1:f155d94d6f3a 684 done = true;
Mike Fiore 1:f155d94d6f3a 685 }
Mike Fiore 1:f155d94d6f3a 686 } while (!done);
Mike Fiore 1:f155d94d6f3a 687
Mike Fiore 1:f155d94d6f3a 688 return result;
Mike Fiore 8:2d7259d244d1 689 }