A library for talking to Multi-Tech's Cellular SocketModem Devices.

Dependents:   M2X_dev axeda_wrapper_dev MTS_M2x_Example1 MTS_Cellular_Connect_Example ... more

Committer:
jengbrecht
Date:
Mon Dec 30 20:04:50 2013 +0000
Revision:
99:eba6b99bc80c
Parent:
98:dbeac735109d
Parent:
97:5e65d8f334d5
Child:
100:9d96b4391151
Merged

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jengbrecht 69:f3e696bbb0d5 1 #include "Wifi.h"
jengbrecht 93:aa7a48e65974 2 #include <string>
jengbrecht 69:f3e696bbb0d5 3
jengbrecht 69:f3e696bbb0d5 4 Wifi* Wifi::instance = NULL;
jengbrecht 69:f3e696bbb0d5 5
jengbrecht 69:f3e696bbb0d5 6 Wifi* Wifi::getInstance()
jengbrecht 69:f3e696bbb0d5 7 {
jengbrecht 69:f3e696bbb0d5 8 if(instance == NULL) {
jengbrecht 69:f3e696bbb0d5 9 instance = new Wifi(NULL);
jengbrecht 69:f3e696bbb0d5 10 }
jengbrecht 69:f3e696bbb0d5 11 return instance;
jengbrecht 69:f3e696bbb0d5 12 }
jengbrecht 69:f3e696bbb0d5 13
jengbrecht 69:f3e696bbb0d5 14 bool Wifi::init(MTSBufferedIO* io)
jengbrecht 69:f3e696bbb0d5 15 {
jengbrecht 69:f3e696bbb0d5 16 if (io == NULL) {
jengbrecht 69:f3e696bbb0d5 17 return false;
jengbrecht 69:f3e696bbb0d5 18 }
jengbrecht 69:f3e696bbb0d5 19 instance->io = io;
jengbrecht 94:1baa587e89ae 20 //Set device into command mode
jengbrecht 94:1baa587e89ae 21 if (!setCmdMode(true)) {
jengbrecht 94:1baa587e89ae 22 return false;
jengbrecht 94:1baa587e89ae 23 }
jengbrecht 94:1baa587e89ae 24
jengbrecht 94:1baa587e89ae 25 //Set device to non-echo mode
jengbrecht 94:1baa587e89ae 26 if (sendBasicCommand("set uart mode 1", 1000) != SUCCESS) {
jengbrecht 94:1baa587e89ae 27 printf("[ERROR] Failed to set to non-echo mode\n\r");
jengbrecht 94:1baa587e89ae 28 return false;
jengbrecht 74:9f87bd22c222 29 }
jengbrecht 94:1baa587e89ae 30
jengbrecht 94:1baa587e89ae 31 //Set device to manual infrastructure mode
jengbrecht 94:1baa587e89ae 32 if (sendBasicCommand("set wlan join 0", 1000) != SUCCESS) {
jengbrecht 94:1baa587e89ae 33 printf("[ERROR] Failed to set join mode\n\r");
jengbrecht 94:1baa587e89ae 34 return false;
jengbrecht 94:1baa587e89ae 35 }
jengbrecht 94:1baa587e89ae 36
jengbrecht 94:1baa587e89ae 37 //Set device to channel auto-scanning mode
jengbrecht 94:1baa587e89ae 38 if (sendBasicCommand("set wlan channel 0", 1000) != SUCCESS) {
jengbrecht 94:1baa587e89ae 39 printf("[ERROR] Failed to set auto-scanning mode\n\r");
jengbrecht 94:1baa587e89ae 40 return false;
jengbrecht 94:1baa587e89ae 41 }
jengbrecht 94:1baa587e89ae 42
jengbrecht 94:1baa587e89ae 43 //Set device so no data is transmitted immediately following a socket connection
jengbrecht 94:1baa587e89ae 44 if (sendBasicCommand("set comm remote 0", 1000) != SUCCESS) {
jengbrecht 94:1baa587e89ae 45 printf("[ERROR] Failed to set remote transmit mode\n\r");
jengbrecht 94:1baa587e89ae 46 return false;
jengbrecht 94:1baa587e89ae 47 }
jengbrecht 94:1baa587e89ae 48 return true;
jengbrecht 69:f3e696bbb0d5 49 }
jengbrecht 69:f3e696bbb0d5 50
jengbrecht 69:f3e696bbb0d5 51 Wifi::Wifi(MTSBufferedIO* io)
jengbrecht 69:f3e696bbb0d5 52 : io(io)
jengbrecht 69:f3e696bbb0d5 53 , wifiConnected(false)
jengbrecht 79:f356009dbc12 54 , _ssid("")
jengbrecht 69:f3e696bbb0d5 55 , mode(TCP)
jengbrecht 69:f3e696bbb0d5 56 , socketOpened(false)
jengbrecht 69:f3e696bbb0d5 57 , socketCloseable(true)
jengbrecht 69:f3e696bbb0d5 58 , local_port(0)
jengbrecht 69:f3e696bbb0d5 59 , host_port(0)
jengbrecht 79:f356009dbc12 60 , cmdOn(false)
jengbrecht 69:f3e696bbb0d5 61 {
jengbrecht 69:f3e696bbb0d5 62
jengbrecht 69:f3e696bbb0d5 63 }
jengbrecht 69:f3e696bbb0d5 64
jengbrecht 69:f3e696bbb0d5 65 Wifi::~Wifi()
jengbrecht 69:f3e696bbb0d5 66 {
jengbrecht 69:f3e696bbb0d5 67 }
jengbrecht 69:f3e696bbb0d5 68
jengbrecht 69:f3e696bbb0d5 69 bool Wifi::connect()
jengbrecht 69:f3e696bbb0d5 70 {
jengbrecht 69:f3e696bbb0d5 71 //Check if socket is open
jengbrecht 69:f3e696bbb0d5 72 if(socketOpened) {
jengbrecht 69:f3e696bbb0d5 73 return true;
jengbrecht 69:f3e696bbb0d5 74 }
jengbrecht 69:f3e696bbb0d5 75
jengbrecht 69:f3e696bbb0d5 76 //Run Test first to validate a good state
jengbrecht 69:f3e696bbb0d5 77 if(isConnected()) {
jengbrecht 69:f3e696bbb0d5 78 return true;
jengbrecht 69:f3e696bbb0d5 79 }
jengbrecht 69:f3e696bbb0d5 80
jengbrecht 93:aa7a48e65974 81 if (_ssid.size() == 0) {
jengbrecht 93:aa7a48e65974 82 printf("[ERROR] No SSID has been set\n\r");
jengbrecht 93:aa7a48e65974 83 return false;
jengbrecht 93:aa7a48e65974 84 }
jengbrecht 93:aa7a48e65974 85
jengbrecht 98:dbeac735109d 86 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 87 return false;
jengbrecht 93:aa7a48e65974 88 }
jengbrecht 93:aa7a48e65974 89
jengbrecht 69:f3e696bbb0d5 90 //Check RSSI: AT+CSQ
jengbrecht 93:aa7a48e65974 91 int rssi = getSignalStrength();
jengbrecht 94:1baa587e89ae 92 printf("[DEBUG] Signal strength (dBm): %d\r\n", rssi);
jengbrecht 69:f3e696bbb0d5 93
jengbrecht 69:f3e696bbb0d5 94 //Possibly add a scan command here and look for the network....
jengbrecht 69:f3e696bbb0d5 95
jengbrecht 69:f3e696bbb0d5 96 //Set device into DHCP mode
sgodinez 73:bb5bbca971ae 97 if (sendBasicCommand("set ip dhcp 1", 1000) != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 98 return false;
jengbrecht 69:f3e696bbb0d5 99 }
jengbrecht 69:f3e696bbb0d5 100
jengbrecht 69:f3e696bbb0d5 101 //join my_network
jengbrecht 69:f3e696bbb0d5 102 printf("[DEBUG] Making SSID Connection Attempt. SSID[%s]\r\n", _ssid.c_str());
jengbrecht 93:aa7a48e65974 103 std::string result = sendCommand("join " + _ssid, 15000, "Listen");
jengbrecht 93:aa7a48e65974 104 //printf("Connect Status: %s\n\r", result.c_str());
jengbrecht 69:f3e696bbb0d5 105
jengbrecht 93:aa7a48e65974 106 //Check whether connection was successful
jengbrecht 93:aa7a48e65974 107 if(result.find("Associated!") != string::npos) {
jengbrecht 93:aa7a48e65974 108 int start = result.find("IP=");
jengbrecht 93:aa7a48e65974 109 int stop = result.find(":", start);
jengbrecht 93:aa7a48e65974 110 local_address = result.substr(start + 3, stop - start - 3);
jengbrecht 93:aa7a48e65974 111 printf("[INFO] WiFi Connection Established: IP[%s]\r\n", local_address.c_str());
jengbrecht 93:aa7a48e65974 112 wifiConnected = true;
jengbrecht 93:aa7a48e65974 113 } else {
jengbrecht 93:aa7a48e65974 114 wifiConnected = false;
jengbrecht 93:aa7a48e65974 115 }
jengbrecht 69:f3e696bbb0d5 116
jengbrecht 69:f3e696bbb0d5 117 return wifiConnected;
jengbrecht 69:f3e696bbb0d5 118 }
jengbrecht 69:f3e696bbb0d5 119
jengbrecht 69:f3e696bbb0d5 120 void Wifi::disconnect()
jengbrecht 69:f3e696bbb0d5 121 {
jengbrecht 79:f356009dbc12 122 printf("[DEBUG] Disconnecting from network\r\n");
jengbrecht 79:f356009dbc12 123
jengbrecht 79:f356009dbc12 124 if(socketOpened) {
jengbrecht 79:f356009dbc12 125 close();
jengbrecht 79:f356009dbc12 126 }
jengbrecht 79:f356009dbc12 127
jengbrecht 98:dbeac735109d 128 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 129 printf("[ERROR] Failed in disconnecting from network. Continuing ...\r\n");
jengbrecht 79:f356009dbc12 130 }
jengbrecht 79:f356009dbc12 131
jengbrecht 94:1baa587e89ae 132 std::string response = sendCommand("leave", 20000);
jengbrecht 94:1baa587e89ae 133 printf("Response: %s\n\r", response.c_str());
jengbrecht 94:1baa587e89ae 134 if (response.find("DeAuth") != string::npos) {
jengbrecht 79:f356009dbc12 135 printf("[DEBUG] Successfully disconnected from network\r\n");
jengbrecht 79:f356009dbc12 136 } else {
jengbrecht 79:f356009dbc12 137 printf("[ERROR] Failed in disconnecting from network. Continuing ...\r\n");
jengbrecht 79:f356009dbc12 138 }
jengbrecht 79:f356009dbc12 139
jengbrecht 79:f356009dbc12 140 wifiConnected = false;
jengbrecht 69:f3e696bbb0d5 141 }
jengbrecht 69:f3e696bbb0d5 142
jengbrecht 69:f3e696bbb0d5 143 bool Wifi::isConnected()
jengbrecht 69:f3e696bbb0d5 144 {
jengbrecht 79:f356009dbc12 145 //1) Check if SSID was set
jengbrecht 79:f356009dbc12 146 if(_ssid.size() == 0) {
jengbrecht 79:f356009dbc12 147 printf("[DEBUG] SSID is not set\r\n");
jengbrecht 79:f356009dbc12 148 return false;
jengbrecht 79:f356009dbc12 149 }
jengbrecht 79:f356009dbc12 150
jengbrecht 79:f356009dbc12 151 //1) Check that we do not have a live connection up
jengbrecht 79:f356009dbc12 152 if(socketOpened) {
jengbrecht 79:f356009dbc12 153 printf("[DEBUG] Socket is opened\r\n");
jengbrecht 79:f356009dbc12 154 return true;
jengbrecht 79:f356009dbc12 155 }
jengbrecht 79:f356009dbc12 156
jengbrecht 98:dbeac735109d 157 //Check command mode.
jengbrecht 98:dbeac735109d 158 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 159 return false;
jengbrecht 98:dbeac735109d 160 }
jengbrecht 98:dbeac735109d 161
jengbrecht 79:f356009dbc12 162 //2) Query the wifi module
jengbrecht 79:f356009dbc12 163 wifiConnected = false;
jengbrecht 93:aa7a48e65974 164 std::string result = sendCommand("show net", 5000, "Links");
jengbrecht 93:aa7a48e65974 165 //printf("netResult: %s\n\r", result);
jengbrecht 93:aa7a48e65974 166 if(result.find("Assoc=OK") != std::string::npos) {
jengbrecht 79:f356009dbc12 167 wifiConnected = true;
jengbrecht 79:f356009dbc12 168 }
jengbrecht 79:f356009dbc12 169
jengbrecht 79:f356009dbc12 170 return wifiConnected;
jengbrecht 69:f3e696bbb0d5 171 }
jengbrecht 69:f3e696bbb0d5 172
jengbrecht 69:f3e696bbb0d5 173 bool Wifi::bind(unsigned int port)
jengbrecht 69:f3e696bbb0d5 174 {
jengbrecht 94:1baa587e89ae 175 if(socketOpened) {
jengbrecht 94:1baa587e89ae 176 printf("[ERROR] socket is open. Can not set local port\r\n");
jengbrecht 94:1baa587e89ae 177 return false;
jengbrecht 94:1baa587e89ae 178 }
jengbrecht 94:1baa587e89ae 179 if(port > 65535) {
jengbrecht 94:1baa587e89ae 180 printf("[ERROR] port out of range (0-65535)\r\n");
jengbrecht 94:1baa587e89ae 181 return false;
jengbrecht 94:1baa587e89ae 182 }
jengbrecht 94:1baa587e89ae 183 local_port = port;
jengbrecht 69:f3e696bbb0d5 184 return true;
jengbrecht 69:f3e696bbb0d5 185 }
jengbrecht 69:f3e696bbb0d5 186
jengbrecht 69:f3e696bbb0d5 187 bool Wifi::open(const std::string& address, unsigned int port, Mode mode)
jengbrecht 69:f3e696bbb0d5 188 {
jengbrecht 69:f3e696bbb0d5 189 //set comm size??? are advanced Socket settings
jengbrecht 69:f3e696bbb0d5 190 //set comm time??? are advanced Socket settings
jengbrecht 95:4fdf968b5b37 191 char buffer[256] = {0};
jengbrecht 95:4fdf968b5b37 192 printf("[DEBUG] Attempting to Open Socket\r\n");
jengbrecht 95:4fdf968b5b37 193
jengbrecht 95:4fdf968b5b37 194 //1) Check that we do not have a live connection up
jengbrecht 95:4fdf968b5b37 195 if(socketOpened) {
jengbrecht 95:4fdf968b5b37 196 //Check that the address, port, and mode match
jengbrecht 95:4fdf968b5b37 197 if(host_address != address || host_port != port || this->mode != mode) {
jengbrecht 95:4fdf968b5b37 198 if(this->mode == TCP) {
jengbrecht 95:4fdf968b5b37 199 printf("[ERROR] TCP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
jengbrecht 95:4fdf968b5b37 200 } else {
jengbrecht 95:4fdf968b5b37 201 printf("[ERROR] UDP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
jengbrecht 95:4fdf968b5b37 202 }
jengbrecht 95:4fdf968b5b37 203 return false;
jengbrecht 95:4fdf968b5b37 204 }
jengbrecht 95:4fdf968b5b37 205
jengbrecht 95:4fdf968b5b37 206 printf("[DEBUG] Socket already opened\r\n");
jengbrecht 95:4fdf968b5b37 207 return true;
jengbrecht 95:4fdf968b5b37 208 }
jengbrecht 95:4fdf968b5b37 209
jengbrecht 95:4fdf968b5b37 210 //2) Check Parameters
jengbrecht 95:4fdf968b5b37 211 if(port > 65535) {
jengbrecht 95:4fdf968b5b37 212 printf("[ERROR] port out of range (0-65535)\r\n");
jengbrecht 95:4fdf968b5b37 213 return false;
jengbrecht 95:4fdf968b5b37 214 }
jengbrecht 95:4fdf968b5b37 215
jengbrecht 95:4fdf968b5b37 216
jengbrecht 95:4fdf968b5b37 217 //3) Check Wifi network connection
jengbrecht 95:4fdf968b5b37 218 if(!isConnected()) {
jengbrecht 95:4fdf968b5b37 219 printf("[ERROR] Wifi network not connected. Attempting to connect\r\n");
jengbrecht 95:4fdf968b5b37 220 if(!connect()) {
jengbrecht 95:4fdf968b5b37 221 printf("[ERROR] Wifi network connection failed\r\n");
jengbrecht 95:4fdf968b5b37 222 return false;
jengbrecht 95:4fdf968b5b37 223 } else {
jengbrecht 95:4fdf968b5b37 224 printf("[DEBUG] Wifi connection established\r\n");
jengbrecht 95:4fdf968b5b37 225 }
jengbrecht 95:4fdf968b5b37 226 }
jengbrecht 95:4fdf968b5b37 227
jengbrecht 95:4fdf968b5b37 228 //Check command mode
jengbrecht 98:dbeac735109d 229 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 230 return false;
jengbrecht 95:4fdf968b5b37 231 }
jengbrecht 95:4fdf968b5b37 232
jengbrecht 95:4fdf968b5b37 233 //Set Local Port
jengbrecht 95:4fdf968b5b37 234 if(local_port != 0) {
jengbrecht 95:4fdf968b5b37 235 //Attempt to set local port
jengbrecht 95:4fdf968b5b37 236 sprintf(buffer, "set ip localport %d", local_port);
jengbrecht 95:4fdf968b5b37 237 Code code = sendBasicCommand(buffer, 1000);
jengbrecht 95:4fdf968b5b37 238 if(code != SUCCESS) {
jengbrecht 95:4fdf968b5b37 239 printf("[WARNING] Unable to set local port (%d) [%d]. Continuing...\r\n", local_port, (int) code);
jengbrecht 95:4fdf968b5b37 240 }
jengbrecht 95:4fdf968b5b37 241 }
jengbrecht 95:4fdf968b5b37 242
jengbrecht 95:4fdf968b5b37 243 //Set TCP/UDP parameters
jengbrecht 95:4fdf968b5b37 244 sprintf(buffer, "set ip remote %d", port);
jengbrecht 95:4fdf968b5b37 245 if(sendBasicCommand(buffer, 1000) == SUCCESS) {
jengbrecht 95:4fdf968b5b37 246 host_port = port;
jengbrecht 95:4fdf968b5b37 247 } else {
jengbrecht 95:4fdf968b5b37 248 printf("[ERROR] Host port could not be set\r\n");
jengbrecht 95:4fdf968b5b37 249 }
jengbrecht 95:4fdf968b5b37 250
jengbrecht 95:4fdf968b5b37 251 if(sendBasicCommand("set ip host " + address, 1000) == SUCCESS) {
jengbrecht 95:4fdf968b5b37 252 host_address = address;
jengbrecht 95:4fdf968b5b37 253 } else {
jengbrecht 95:4fdf968b5b37 254 printf("[ERROR] Host address could not be set\r\n");
jengbrecht 95:4fdf968b5b37 255 }
jengbrecht 95:4fdf968b5b37 256
jengbrecht 95:4fdf968b5b37 257 if(sendBasicCommand("set ip host " + address, 1000) == SUCCESS) {
jengbrecht 95:4fdf968b5b37 258 host_address = address;
jengbrecht 95:4fdf968b5b37 259 } else {
jengbrecht 95:4fdf968b5b37 260 printf("[ERROR] Host address could not be set\r\n");
jengbrecht 95:4fdf968b5b37 261 }
jengbrecht 95:4fdf968b5b37 262
jengbrecht 95:4fdf968b5b37 263 // Try and Connect
jengbrecht 95:4fdf968b5b37 264 std::string sMode;
jengbrecht 95:4fdf968b5b37 265 std::string sOpenSocketCmd;
jengbrecht 95:4fdf968b5b37 266 if(mode == TCP) {
jengbrecht 95:4fdf968b5b37 267 sOpenSocketCmd = "open";
jengbrecht 95:4fdf968b5b37 268 sMode = "TCP";
jengbrecht 95:4fdf968b5b37 269 } else {
jengbrecht 95:4fdf968b5b37 270 sOpenSocketCmd = "AT#OUDP";
jengbrecht 95:4fdf968b5b37 271 sMode = "UDP";
jengbrecht 95:4fdf968b5b37 272 }
jengbrecht 95:4fdf968b5b37 273 string response = sendCommand(sOpenSocketCmd, 20000, "OPEN");
jengbrecht 95:4fdf968b5b37 274 printf("Open Response: %s\n\r", response.c_str());
jengbrecht 95:4fdf968b5b37 275 if (response.find("OPEN") != string::npos) {
jengbrecht 95:4fdf968b5b37 276 printf("[INFO] Opened %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
jengbrecht 95:4fdf968b5b37 277 socketOpened = true;
jengbrecht 98:dbeac735109d 278 cmdOn = false; //Need to make sure that this is true...
jengbrecht 95:4fdf968b5b37 279 } else {
jengbrecht 95:4fdf968b5b37 280 printf("[WARNING] Unable to open %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
jengbrecht 95:4fdf968b5b37 281 socketOpened = false;
jengbrecht 95:4fdf968b5b37 282 }
jengbrecht 95:4fdf968b5b37 283
jengbrecht 95:4fdf968b5b37 284 return socketOpened;
jengbrecht 69:f3e696bbb0d5 285 }
jengbrecht 69:f3e696bbb0d5 286
jengbrecht 69:f3e696bbb0d5 287 bool Wifi::isOpen()
jengbrecht 69:f3e696bbb0d5 288 {
jengbrecht 95:4fdf968b5b37 289 return socketOpened;
jengbrecht 69:f3e696bbb0d5 290 }
jengbrecht 69:f3e696bbb0d5 291
jengbrecht 69:f3e696bbb0d5 292 bool Wifi::close()
jengbrecht 69:f3e696bbb0d5 293 {
jengbrecht 95:4fdf968b5b37 294 if(io == NULL) {
jengbrecht 95:4fdf968b5b37 295 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 95:4fdf968b5b37 296 return false;
jengbrecht 95:4fdf968b5b37 297 }
jengbrecht 95:4fdf968b5b37 298
jengbrecht 95:4fdf968b5b37 299 if(!socketOpened) {
jengbrecht 95:4fdf968b5b37 300 printf("[WARNING] Socket close() called, but socket was not open\r\n");
jengbrecht 95:4fdf968b5b37 301 return true;
jengbrecht 95:4fdf968b5b37 302 }
jengbrecht 95:4fdf968b5b37 303
jengbrecht 98:dbeac735109d 304 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 305 printf("[ERROR] Failed to close socket\r\n");
jengbrecht 98:dbeac735109d 306 return false;
jengbrecht 95:4fdf968b5b37 307 }
jengbrecht 95:4fdf968b5b37 308
jengbrecht 95:4fdf968b5b37 309 std::string response = sendCommand("close", 10000, "CLOS");
sgodinez 97:5e65d8f334d5 310 if(response.find("CLOS") == string::npos) {
jengbrecht 98:dbeac735109d 311 printf("[ERROR] Failed to successfully close socket\r\n");
jengbrecht 95:4fdf968b5b37 312 return false;
jengbrecht 95:4fdf968b5b37 313 }
jengbrecht 95:4fdf968b5b37 314
jengbrecht 95:4fdf968b5b37 315 socketOpened = false;
jengbrecht 69:f3e696bbb0d5 316 return true;
jengbrecht 69:f3e696bbb0d5 317 }
jengbrecht 69:f3e696bbb0d5 318
jengbrecht 69:f3e696bbb0d5 319 int Wifi::read(char* data, int max, int timeout)
jengbrecht 69:f3e696bbb0d5 320 {
jengbrecht 98:dbeac735109d 321 if(io == NULL) {
jengbrecht 98:dbeac735109d 322 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 98:dbeac735109d 323 return -1;
jengbrecht 98:dbeac735109d 324 }
jengbrecht 98:dbeac735109d 325
jengbrecht 98:dbeac735109d 326 //Check that nothing is in the rx buffer
jengbrecht 98:dbeac735109d 327 if(!socketOpened && !io->readable()) {
jengbrecht 98:dbeac735109d 328 printf("[ERROR] Socket is not open\r\n");
jengbrecht 98:dbeac735109d 329 return -1;
jengbrecht 98:dbeac735109d 330 }
jengbrecht 98:dbeac735109d 331
jengbrecht 98:dbeac735109d 332 //Check for data mode
jengbrecht 98:dbeac735109d 333 if(!setCmdMode(false)) {
jengbrecht 98:dbeac735109d 334 printf("[ERROR] Failed to read data due to mode\r\n");
jengbrecht 98:dbeac735109d 335 return -1;
jengbrecht 98:dbeac735109d 336 }
jengbrecht 98:dbeac735109d 337
jengbrecht 98:dbeac735109d 338 int bytesRead = 0;
jengbrecht 98:dbeac735109d 339
jengbrecht 98:dbeac735109d 340 if(timeout >= 0) {
jengbrecht 98:dbeac735109d 341 bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
jengbrecht 98:dbeac735109d 342 } else {
jengbrecht 98:dbeac735109d 343 bytesRead = io->read(data, max);
jengbrecht 98:dbeac735109d 344 }
jengbrecht 98:dbeac735109d 345
jengbrecht 98:dbeac735109d 346 if(bytesRead > 0 && socketCloseable) {
jengbrecht 98:dbeac735109d 347 //Remove escape characters
jengbrecht 98:dbeac735109d 348 int index = 0;
jengbrecht 98:dbeac735109d 349 bool escapeFlag = false;
jengbrecht 98:dbeac735109d 350 for(int i = 0; i < bytesRead; i++) {
jengbrecht 98:dbeac735109d 351 if(data[i] == DLE || data[i] == ETX) {
jengbrecht 98:dbeac735109d 352 if(escapeFlag == true) {
jengbrecht 98:dbeac735109d 353 //This character has been escaped
jengbrecht 98:dbeac735109d 354 escapeFlag = false;
jengbrecht 98:dbeac735109d 355 } else if(data[bytesRead] == DLE) {
jengbrecht 98:dbeac735109d 356 //Found escape character
jengbrecht 98:dbeac735109d 357 escapeFlag = true;
jengbrecht 98:dbeac735109d 358 continue;
jengbrecht 98:dbeac735109d 359 } else {
jengbrecht 98:dbeac735109d 360 //ETX sent without escape -> Socket closed
jengbrecht 98:dbeac735109d 361 printf("[INFO] Read ETX character without DLE escape. Socket closed\r\n");
jengbrecht 98:dbeac735109d 362 socketOpened = false;
jengbrecht 98:dbeac735109d 363 continue;
jengbrecht 98:dbeac735109d 364 }
jengbrecht 98:dbeac735109d 365 }
jengbrecht 98:dbeac735109d 366
jengbrecht 98:dbeac735109d 367 if(index != i) {
jengbrecht 98:dbeac735109d 368 data[index] = data[i];
jengbrecht 98:dbeac735109d 369 }
jengbrecht 98:dbeac735109d 370 index++;
jengbrecht 98:dbeac735109d 371 }
jengbrecht 98:dbeac735109d 372 bytesRead = index;
jengbrecht 98:dbeac735109d 373 }
jengbrecht 98:dbeac735109d 374
jengbrecht 98:dbeac735109d 375 //Scan for socket closed message
jengbrecht 98:dbeac735109d 376 for(size_t i = 0; i < bytesRead; i++) {
jengbrecht 98:dbeac735109d 377 if(data[i] == 'O') {
jengbrecht 98:dbeac735109d 378 if(strstr(&data[i], "Ok_Info_SocketClosed")) {
jengbrecht 98:dbeac735109d 379 printf("[INFO] Found socket closed message. Socket closed\r\n");
jengbrecht 98:dbeac735109d 380 //Close socket and Cut Off End of Message
jengbrecht 98:dbeac735109d 381 socketOpened = false;
jengbrecht 98:dbeac735109d 382 data[i] = '\0';
jengbrecht 98:dbeac735109d 383 bytesRead = i;
jengbrecht 98:dbeac735109d 384 break;
jengbrecht 98:dbeac735109d 385 }
jengbrecht 98:dbeac735109d 386 }
jengbrecht 98:dbeac735109d 387 }
jengbrecht 98:dbeac735109d 388 return bytesRead;
jengbrecht 69:f3e696bbb0d5 389 }
jengbrecht 69:f3e696bbb0d5 390
jengbrecht 69:f3e696bbb0d5 391 int Wifi::write(const char* data, int length, int timeout)
jengbrecht 69:f3e696bbb0d5 392 {
jengbrecht 98:dbeac735109d 393 if(io == NULL) {
jengbrecht 98:dbeac735109d 394 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 98:dbeac735109d 395 return -1;
jengbrecht 98:dbeac735109d 396 }
jengbrecht 98:dbeac735109d 397
jengbrecht 98:dbeac735109d 398 if(!socketOpened) {
jengbrecht 98:dbeac735109d 399 printf("[ERROR] Socket is not open\r\n");
jengbrecht 98:dbeac735109d 400 return -1;
jengbrecht 98:dbeac735109d 401 }
jengbrecht 98:dbeac735109d 402
jengbrecht 98:dbeac735109d 403 //Check for data mode
jengbrecht 98:dbeac735109d 404 if(!setCmdMode(false)) {
jengbrecht 98:dbeac735109d 405 printf("[ERROR] Failed to write data due to mode\r\n");
jengbrecht 98:dbeac735109d 406 return -1;
jengbrecht 98:dbeac735109d 407 }
jengbrecht 98:dbeac735109d 408
jengbrecht 98:dbeac735109d 409 int bytesWritten = 0;
jengbrecht 98:dbeac735109d 410 if(timeout >= 0) {
jengbrecht 98:dbeac735109d 411 Timer tmr;
jengbrecht 98:dbeac735109d 412 tmr.start();
jengbrecht 98:dbeac735109d 413 do {
jengbrecht 98:dbeac735109d 414 int available = io->writeable();
jengbrecht 98:dbeac735109d 415 if (available > 0) {
jengbrecht 98:dbeac735109d 416 int size = MIN(available, length - bytesWritten);
jengbrecht 98:dbeac735109d 417 bytesWritten += io->write(&data[bytesWritten], size);
jengbrecht 98:dbeac735109d 418 } else {
jengbrecht 98:dbeac735109d 419 wait(0.05);
jengbrecht 98:dbeac735109d 420 }
jengbrecht 98:dbeac735109d 421 } while (tmr.read_ms() <= timeout && bytesWritten < length);
jengbrecht 98:dbeac735109d 422 } else {
jengbrecht 98:dbeac735109d 423 bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
jengbrecht 98:dbeac735109d 424 }
jengbrecht 98:dbeac735109d 425
jengbrecht 98:dbeac735109d 426 return bytesWritten;
jengbrecht 69:f3e696bbb0d5 427 }
jengbrecht 69:f3e696bbb0d5 428
jengbrecht 69:f3e696bbb0d5 429 unsigned int Wifi::readable()
jengbrecht 69:f3e696bbb0d5 430 {
jengbrecht 69:f3e696bbb0d5 431 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 432 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 433 return 0;
jengbrecht 69:f3e696bbb0d5 434 }
jengbrecht 69:f3e696bbb0d5 435 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 436 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 437 return 0;
jengbrecht 69:f3e696bbb0d5 438 }
jengbrecht 69:f3e696bbb0d5 439 return io->readable();
jengbrecht 69:f3e696bbb0d5 440 }
jengbrecht 69:f3e696bbb0d5 441
jengbrecht 69:f3e696bbb0d5 442 unsigned int Wifi::writeable()
jengbrecht 69:f3e696bbb0d5 443 {
jengbrecht 69:f3e696bbb0d5 444 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 445 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 446 return 0;
jengbrecht 69:f3e696bbb0d5 447 }
jengbrecht 69:f3e696bbb0d5 448 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 449 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 450 return 0;
jengbrecht 69:f3e696bbb0d5 451 }
jengbrecht 69:f3e696bbb0d5 452
jengbrecht 69:f3e696bbb0d5 453 return io->writeable();
jengbrecht 69:f3e696bbb0d5 454 }
jengbrecht 69:f3e696bbb0d5 455
jengbrecht 69:f3e696bbb0d5 456 void Wifi::reset()
jengbrecht 69:f3e696bbb0d5 457 {
jengbrecht 69:f3e696bbb0d5 458 }
jengbrecht 69:f3e696bbb0d5 459
sgodinez 73:bb5bbca971ae 460 Code Wifi::setNetwork(const std::string& ssid, const std::string& key, SecurityType type)
jengbrecht 69:f3e696bbb0d5 461 {
jengbrecht 98:dbeac735109d 462 //Check the command mode
jengbrecht 98:dbeac735109d 463 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 464 return FAILURE;
jengbrecht 98:dbeac735109d 465 }
jengbrecht 98:dbeac735109d 466
sgodinez 73:bb5bbca971ae 467 Code code;
jengbrecht 69:f3e696bbb0d5 468
jengbrecht 69:f3e696bbb0d5 469 //Set the appropraite SSID
jengbrecht 69:f3e696bbb0d5 470 code = sendBasicCommand("set wlan ssid " + ssid, 1000);
sgodinez 73:bb5bbca971ae 471 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 472 return code;
jengbrecht 69:f3e696bbb0d5 473 }
jengbrecht 69:f3e696bbb0d5 474
jengbrecht 69:f3e696bbb0d5 475 //Set the security key
jengbrecht 69:f3e696bbb0d5 476 if (type == WEP64 || type == WEP128) {
jengbrecht 69:f3e696bbb0d5 477 //Set the WEP key if using WEP encryption
jengbrecht 69:f3e696bbb0d5 478 code = sendBasicCommand("set wlan key " + key, 1000);
sgodinez 73:bb5bbca971ae 479 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 480 return code;
jengbrecht 69:f3e696bbb0d5 481 }
jengbrecht 69:f3e696bbb0d5 482 } else if (type == WPA || type == WPA2) {
jengbrecht 69:f3e696bbb0d5 483 //Set the WPA key if using WPA encryption
jengbrecht 69:f3e696bbb0d5 484 code = sendBasicCommand("set wlan phrase " + key, 1000);
sgodinez 73:bb5bbca971ae 485 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 486 return code;
jengbrecht 69:f3e696bbb0d5 487 }
jengbrecht 69:f3e696bbb0d5 488 }
jengbrecht 69:f3e696bbb0d5 489
jengbrecht 69:f3e696bbb0d5 490 _ssid = ssid;
sgodinez 73:bb5bbca971ae 491 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 492 }
jengbrecht 69:f3e696bbb0d5 493
jengbrecht 94:1baa587e89ae 494 Code Wifi::setDNS(const std::string& dnsName)
jengbrecht 94:1baa587e89ae 495 {
jengbrecht 98:dbeac735109d 496 //Check the command mode
jengbrecht 98:dbeac735109d 497 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 498 return FAILURE;
jengbrecht 98:dbeac735109d 499 }
jengbrecht 98:dbeac735109d 500
jengbrecht 94:1baa587e89ae 501 return sendBasicCommand("set dns name " + dnsName, 1000);
jengbrecht 94:1baa587e89ae 502 }
jengbrecht 94:1baa587e89ae 503
jengbrecht 69:f3e696bbb0d5 504 int Wifi::getSignalStrength()
jengbrecht 69:f3e696bbb0d5 505 {
jengbrecht 98:dbeac735109d 506 //Check the command mode
jengbrecht 98:dbeac735109d 507 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 508 printf("[ERROR] Could not get RSSI\n\r");
jengbrecht 98:dbeac735109d 509 return -1;
jengbrecht 98:dbeac735109d 510 }
jengbrecht 98:dbeac735109d 511
jengbrecht 93:aa7a48e65974 512 string response = sendCommand("show rssi", 2000, "dBm");
jengbrecht 74:9f87bd22c222 513 if (response.find("RSSI") == string::npos) {
jengbrecht 98:dbeac735109d 514 printf("[ERROR] Could not get RSSI\n\r");
jengbrecht 74:9f87bd22c222 515 return -1;
jengbrecht 74:9f87bd22c222 516 }
jengbrecht 74:9f87bd22c222 517 int start = response.find('(');
jengbrecht 74:9f87bd22c222 518 int stop = response.find(')', start);
jengbrecht 74:9f87bd22c222 519 string signal = response.substr(start + 1, stop - start - 1);
jengbrecht 74:9f87bd22c222 520 int value;
jengbrecht 74:9f87bd22c222 521 sscanf(signal.c_str(), "%d", &value);
jengbrecht 74:9f87bd22c222 522 return value;
jengbrecht 69:f3e696bbb0d5 523 }
jengbrecht 69:f3e696bbb0d5 524
jengbrecht 95:4fdf968b5b37 525 bool Wifi::ping(const std::string& address)
jengbrecht 95:4fdf968b5b37 526 {
jengbrecht 98:dbeac735109d 527 //Check the command mode
jengbrecht 98:dbeac735109d 528 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 529 printf("[ERROR] Could not send ping command\n\r");
jengbrecht 98:dbeac735109d 530 return false;
jengbrecht 98:dbeac735109d 531 }
jengbrecht 98:dbeac735109d 532
jengbrecht 95:4fdf968b5b37 533 std::string response;
jengbrecht 95:4fdf968b5b37 534 for (int i = 0; i < PINGNUM; i++) {
jengbrecht 95:4fdf968b5b37 535 response = sendCommand("ping " + address, PINGDELAY * 1000, "reply");
jengbrecht 95:4fdf968b5b37 536 if (response.find("reply") != std::string::npos) {
jengbrecht 95:4fdf968b5b37 537 return true;
jengbrecht 95:4fdf968b5b37 538 }
jengbrecht 95:4fdf968b5b37 539 }
jengbrecht 95:4fdf968b5b37 540 return false;
jengbrecht 95:4fdf968b5b37 541 }
jengbrecht 95:4fdf968b5b37 542
jengbrecht 79:f356009dbc12 543 bool Wifi::setCmdMode(bool on)
jengbrecht 74:9f87bd22c222 544 {
jengbrecht 79:f356009dbc12 545 if (on) {
jengbrecht 79:f356009dbc12 546 if (cmdOn) {
jengbrecht 79:f356009dbc12 547 return true;
jengbrecht 79:f356009dbc12 548 }
jengbrecht 79:f356009dbc12 549 wait(.5);
jengbrecht 93:aa7a48e65974 550 std::string response = sendCommand("$$", 2000, "CMD", '$');
jengbrecht 79:f356009dbc12 551 if (response.find("CMD") != string::npos) {
jengbrecht 79:f356009dbc12 552 cmdOn = true;
jengbrecht 79:f356009dbc12 553 return true;
jengbrecht 79:f356009dbc12 554 }
jengbrecht 98:dbeac735109d 555 printf("[ERROR] Failed to enter command mode\n\r");
jengbrecht 79:f356009dbc12 556 return false;
jengbrecht 79:f356009dbc12 557 } else {
jengbrecht 79:f356009dbc12 558 if (!cmdOn) {
jengbrecht 79:f356009dbc12 559 return true;
jengbrecht 79:f356009dbc12 560 }
jengbrecht 93:aa7a48e65974 561 std::string response = sendCommand("exit", 2000, "EXIT");
jengbrecht 79:f356009dbc12 562 if (response.find("EXIT") != string::npos) {
jengbrecht 79:f356009dbc12 563 cmdOn = false;
jengbrecht 79:f356009dbc12 564 return true;
jengbrecht 79:f356009dbc12 565 }
jengbrecht 98:dbeac735109d 566 printf("[ERROR] Failed to exit command mode\n\r");
jengbrecht 79:f356009dbc12 567 return false;
jengbrecht 74:9f87bd22c222 568 }
jengbrecht 74:9f87bd22c222 569 }
jengbrecht 69:f3e696bbb0d5 570
sgodinez 73:bb5bbca971ae 571 Code Wifi::sendBasicCommand(string command, int timeoutMillis, char esc)
jengbrecht 69:f3e696bbb0d5 572 {
jengbrecht 69:f3e696bbb0d5 573 if(socketOpened) {
jengbrecht 69:f3e696bbb0d5 574 printf("[ERROR] socket is open. Can not send AT commands\r\n");
sgodinez 73:bb5bbca971ae 575 return ERROR;
jengbrecht 69:f3e696bbb0d5 576 }
jengbrecht 69:f3e696bbb0d5 577
jengbrecht 93:aa7a48e65974 578 string response = sendCommand(command, timeoutMillis, "AOK", esc);
jengbrecht 69:f3e696bbb0d5 579 //printf("Response: %s\n\r", response.c_str());
jengbrecht 69:f3e696bbb0d5 580 if (response.size() == 0) {
sgodinez 73:bb5bbca971ae 581 return NO_RESPONSE;
jengbrecht 69:f3e696bbb0d5 582 } else if (response.find("AOK") != string::npos) {
sgodinez 73:bb5bbca971ae 583 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 584 } else if (response.find("ERR") != string::npos) {
sgodinez 73:bb5bbca971ae 585 return ERROR;
jengbrecht 69:f3e696bbb0d5 586 } else {
sgodinez 73:bb5bbca971ae 587 return FAILURE;
jengbrecht 69:f3e696bbb0d5 588 }
jengbrecht 69:f3e696bbb0d5 589 }
jengbrecht 69:f3e696bbb0d5 590
jengbrecht 93:aa7a48e65974 591 string Wifi::sendCommand(string command, int timeoutMillis, std::string response, char esc)
jengbrecht 69:f3e696bbb0d5 592 {
jengbrecht 69:f3e696bbb0d5 593 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 594 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 595 return "";
jengbrecht 69:f3e696bbb0d5 596 }
jengbrecht 98:dbeac735109d 597 if(socketOpened && command.compare("$$") != 0 && command.compare("exit") != 0) {
jengbrecht 79:f356009dbc12 598 printf("[ERROR] socket is open. Can not send AT commands\r\n");
jengbrecht 69:f3e696bbb0d5 599 return "";
jengbrecht 69:f3e696bbb0d5 600 }
jengbrecht 69:f3e696bbb0d5 601
jengbrecht 69:f3e696bbb0d5 602 io->rxClear();
jengbrecht 69:f3e696bbb0d5 603 io->txClear();
jengbrecht 69:f3e696bbb0d5 604 std::string result;
jengbrecht 79:f356009dbc12 605
sgodinez 73:bb5bbca971ae 606 //Attempt to write command
sgodinez 73:bb5bbca971ae 607 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
sgodinez 73:bb5bbca971ae 608 //Failed to write command
sgodinez 73:bb5bbca971ae 609 printf("[ERROR] failed to send command to radio within %d milliseconds\r\n", timeoutMillis);
sgodinez 73:bb5bbca971ae 610 return "";
sgodinez 73:bb5bbca971ae 611 }
jengbrecht 79:f356009dbc12 612
sgodinez 73:bb5bbca971ae 613 //Send Escape Character
sgodinez 73:bb5bbca971ae 614 if (esc != 0x00) {
sgodinez 73:bb5bbca971ae 615 if(io->write(esc, timeoutMillis) != 1) {
sgodinez 73:bb5bbca971ae 616 printf("[ERROR] failed to send '%c' to radio within %d milliseconds\r\n", esc, timeoutMillis);
sgodinez 73:bb5bbca971ae 617 return "";
sgodinez 73:bb5bbca971ae 618 }
sgodinez 73:bb5bbca971ae 619 }
sgodinez 73:bb5bbca971ae 620
jengbrecht 69:f3e696bbb0d5 621 int timer = 0;
sgodinez 73:bb5bbca971ae 622 size_t previous = 0;
jengbrecht 69:f3e696bbb0d5 623 char tmp[256];
jengbrecht 69:f3e696bbb0d5 624 tmp[255] = 0;
jengbrecht 69:f3e696bbb0d5 625 bool done = false;
jengbrecht 69:f3e696bbb0d5 626 do {
jengbrecht 93:aa7a48e65974 627 wait(.2);
jengbrecht 93:aa7a48e65974 628 timer = timer + 200;
sgodinez 73:bb5bbca971ae 629 previous = result.size();
jengbrecht 93:aa7a48e65974 630 int size = io->read(tmp, 255, 0); //1 less than allocated
jengbrecht 69:f3e696bbb0d5 631 if(size > 0) {
jengbrecht 69:f3e696bbb0d5 632 result.append(tmp, size);
jengbrecht 93:aa7a48e65974 633 if (response.size() != 0) {
jengbrecht 93:aa7a48e65974 634 if (result.find(response) != string::npos) {
jengbrecht 93:aa7a48e65974 635 return result;
jengbrecht 93:aa7a48e65974 636 }
jengbrecht 93:aa7a48e65974 637 } else {
jengbrecht 93:aa7a48e65974 638 done = (result.size() == previous);
jengbrecht 69:f3e696bbb0d5 639 }
jengbrecht 69:f3e696bbb0d5 640 }
jengbrecht 69:f3e696bbb0d5 641 if(timer >= timeoutMillis) {
jengbrecht 93:aa7a48e65974 642 printf("[WARNING] sendCommand [%s] timed out after %d milliseconds\r\n", command.c_str(), timeoutMillis);
jengbrecht 69:f3e696bbb0d5 643 done = true;
jengbrecht 69:f3e696bbb0d5 644 }
jengbrecht 69:f3e696bbb0d5 645 } while (!done);
jengbrecht 79:f356009dbc12 646
jengbrecht 93:aa7a48e65974 647 //printf("Result: %s\n\r", result.c_str());
jengbrecht 69:f3e696bbb0d5 648 return result;
jengbrecht 69:f3e696bbb0d5 649 }