Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Vanger
Date:
Mon Aug 11 16:03:19 2014 +0000
Revision:
52:2cb58398a4f9
Parent:
51:ffc556ba33f7
Child:
54:a6c738bfc391
Removed parse response '>' from sendCommand() under Cellular.cpp, changed sendSMS() to verify sending SMS message under Cellular.cpp, changed disconnect() to have better flow under EasyIP.cpp, changed isConnected() to be simpler under EasyIP.cpp

Who changed what in which revision?

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