Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems

Dependents:   mtsas mtsas mtsas mtsas

Committer:
Mike Fiore
Date:
Mon May 19 12:34:32 2014 -0500
Revision:
1:f155d94d6f3a
Child:
2:10e72dce251d
add all cellular code, remove MBEDCellularRadioInterface

Who changed what in which revision?

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