Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Vanger
Date:
Thu Jun 26 21:12:37 2014 +0000
Revision:
26:2b769ed8de4f
Parent:
22:c1004a807490
Child:
43:91c5e53f508f
Made setApn() a pure virtual in Cellular.; Implemented setApn in both UIP and EasyIP; Implemented connect(), disconnect(), and ping() in EasyIP; Uncommented cell instantiation for EasyIP type models in CellularFactory

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