Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Mike Fiore
Date:
Wed May 21 15:21:25 2014 -0500
Revision:
7:0ee8e69a3e9c
Parent:
4:1f63354b8d1b
Child:
8:2d7259d244d1
more restructuring
updated radio types in Cellular.h
moved SMS code to Cellular class

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