Simple detection for LE910-NA1 modules

Fork of MTS-Cellular by MultiTech

Committer:
Mike Fiore
Date:
Tue May 20 15:21:06 2014 -0500
Revision:
3:04046eebaef5
Parent:
Cellular/SMCIP.cpp@2:10e72dce251d
Child:
4:1f63354b8d1b
rename SMC and SMCIP files to EasyIP and UIP, remove RadioInterface code

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