Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Mike Fiore
Date:
Wed May 21 15:45:05 2014 -0500
Revision:
10:c188cc05aed5
Parent:
9:1a03e3f3e7fe
Child:
11:4e428f689069
more restructuring
move sendCommand and sendBasicCommand 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 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 }