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:
Tue Dec 31 21:35:49 2013 +0000
Revision:
114:cd34b1d64360
Parent:
113:7238f9b8db17
Child:
117:e59a616ffe16
In Wifi made isOpen and close methods way more robust to handle issues seen with closing an HTTP connection.

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