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 22:09:21 2013 +0000
Revision:
119:544578fd290c
Parent:
117:e59a616ffe16
Child:
121:5a7fba896c98
Added small delay after Wifi close so that subsequent isOpen calls would return correctly.

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 117:e59a616ffe16 159 if(isOpen()) {
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(!setCmdMode(true)) {
jengbrecht 114:cd34b1d64360 293 printf("[ERROR] Failed to properly check if TCP connection is open.\r\n");
jengbrecht 114:cd34b1d64360 294 return socketOpened;
jengbrecht 114:cd34b1d64360 295 }
jengbrecht 114:cd34b1d64360 296 std::string response = sendCommand("show connection", 2000, "\n");
jengbrecht 114:cd34b1d64360 297 int start = response.find("f");
jengbrecht 114:cd34b1d64360 298 if(start != string::npos && response.size() >= (start + 3)) {
jengbrecht 114:cd34b1d64360 299 if(response[start + 3] == '1') {
jengbrecht 114:cd34b1d64360 300 socketOpened = true;
jengbrecht 114:cd34b1d64360 301 } else {
jengbrecht 114:cd34b1d64360 302 socketOpened = false;
jengbrecht 114:cd34b1d64360 303 }
jengbrecht 114:cd34b1d64360 304 } else {
jengbrecht 114:cd34b1d64360 305 printf("[WARNING] Trouble checking TCP Connection status.\n\r");
jengbrecht 114:cd34b1d64360 306 }
jengbrecht 95:4fdf968b5b37 307 return socketOpened;
jengbrecht 69:f3e696bbb0d5 308 }
jengbrecht 69:f3e696bbb0d5 309
jengbrecht 69:f3e696bbb0d5 310 bool Wifi::close()
jengbrecht 69:f3e696bbb0d5 311 {
jengbrecht 114:cd34b1d64360 312 wait(1);
jengbrecht 95:4fdf968b5b37 313 if(io == NULL) {
jengbrecht 95:4fdf968b5b37 314 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 95:4fdf968b5b37 315 return false;
jengbrecht 95:4fdf968b5b37 316 }
jengbrecht 95:4fdf968b5b37 317
jengbrecht 95:4fdf968b5b37 318 if(!socketOpened) {
jengbrecht 95:4fdf968b5b37 319 printf("[WARNING] Socket close() called, but socket was not open\r\n");
jengbrecht 95:4fdf968b5b37 320 return true;
jengbrecht 95:4fdf968b5b37 321 }
jengbrecht 95:4fdf968b5b37 322
jengbrecht 98:dbeac735109d 323 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 324 printf("[ERROR] Failed to close socket\r\n");
jengbrecht 98:dbeac735109d 325 return false;
jengbrecht 95:4fdf968b5b37 326 }
jengbrecht 95:4fdf968b5b37 327
jengbrecht 114:cd34b1d64360 328 if(isOpen()) {
jengbrecht 114:cd34b1d64360 329 std::string response = sendCommand("close", 3000, "CLOS");
jengbrecht 114:cd34b1d64360 330 if(response.find("CLOS") == string::npos) {
jengbrecht 114:cd34b1d64360 331 printf("[WARNING] Failed to successfully close socket...\r\n");
jengbrecht 114:cd34b1d64360 332 return false;
jengbrecht 114:cd34b1d64360 333 }
jengbrecht 95:4fdf968b5b37 334 }
jengbrecht 119:544578fd290c 335
jengbrecht 119:544578fd290c 336 wait(1); //Wait so the subsequent isOpen calls return correctly.
jengbrecht 113:7238f9b8db17 337 io->rxClear();
jengbrecht 113:7238f9b8db17 338 io->txClear();
jengbrecht 114:cd34b1d64360 339
jengbrecht 69:f3e696bbb0d5 340 return true;
jengbrecht 69:f3e696bbb0d5 341 }
jengbrecht 69:f3e696bbb0d5 342
jengbrecht 69:f3e696bbb0d5 343 int Wifi::read(char* data, int max, int timeout)
jengbrecht 69:f3e696bbb0d5 344 {
jengbrecht 98:dbeac735109d 345 if(io == NULL) {
jengbrecht 98:dbeac735109d 346 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 98:dbeac735109d 347 return -1;
jengbrecht 98:dbeac735109d 348 }
jengbrecht 98:dbeac735109d 349
jengbrecht 98:dbeac735109d 350 //Check that nothing is in the rx buffer
jengbrecht 98:dbeac735109d 351 if(!socketOpened && !io->readable()) {
jengbrecht 98:dbeac735109d 352 printf("[ERROR] Socket is not open\r\n");
jengbrecht 98:dbeac735109d 353 return -1;
jengbrecht 98:dbeac735109d 354 }
jengbrecht 98:dbeac735109d 355
jengbrecht 98:dbeac735109d 356 //Check for data mode
jengbrecht 98:dbeac735109d 357 if(!setCmdMode(false)) {
jengbrecht 98:dbeac735109d 358 printf("[ERROR] Failed to read data due to mode\r\n");
jengbrecht 98:dbeac735109d 359 return -1;
jengbrecht 98:dbeac735109d 360 }
jengbrecht 98:dbeac735109d 361
jengbrecht 98:dbeac735109d 362 int bytesRead = 0;
jengbrecht 98:dbeac735109d 363
jengbrecht 98:dbeac735109d 364 if(timeout >= 0) {
jengbrecht 98:dbeac735109d 365 bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
jengbrecht 98:dbeac735109d 366 } else {
jengbrecht 98:dbeac735109d 367 bytesRead = io->read(data, max);
jengbrecht 98:dbeac735109d 368 }
jengbrecht 98:dbeac735109d 369
jengbrecht 98:dbeac735109d 370 return bytesRead;
jengbrecht 69:f3e696bbb0d5 371 }
jengbrecht 69:f3e696bbb0d5 372
jengbrecht 69:f3e696bbb0d5 373 int Wifi::write(const char* data, int length, int timeout)
jengbrecht 69:f3e696bbb0d5 374 {
jengbrecht 98:dbeac735109d 375 if(io == NULL) {
jengbrecht 98:dbeac735109d 376 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 98:dbeac735109d 377 return -1;
jengbrecht 98:dbeac735109d 378 }
jengbrecht 98:dbeac735109d 379
jengbrecht 98:dbeac735109d 380 if(!socketOpened) {
jengbrecht 98:dbeac735109d 381 printf("[ERROR] Socket is not open\r\n");
jengbrecht 98:dbeac735109d 382 return -1;
jengbrecht 98:dbeac735109d 383 }
jengbrecht 98:dbeac735109d 384
jengbrecht 98:dbeac735109d 385 //Check for data mode
jengbrecht 98:dbeac735109d 386 if(!setCmdMode(false)) {
jengbrecht 98:dbeac735109d 387 printf("[ERROR] Failed to write data due to mode\r\n");
jengbrecht 98:dbeac735109d 388 return -1;
jengbrecht 98:dbeac735109d 389 }
jengbrecht 98:dbeac735109d 390
jengbrecht 98:dbeac735109d 391 int bytesWritten = 0;
jengbrecht 103:da58d27c15d7 392
jengbrecht 98:dbeac735109d 393 if(timeout >= 0) {
jengbrecht 100:9d96b4391151 394 bytesWritten = io->write(data, length, static_cast<unsigned int>(timeout));
jengbrecht 98:dbeac735109d 395 } else {
jengbrecht 100:9d96b4391151 396 bytesWritten = io->write(data, length);
jengbrecht 98:dbeac735109d 397 }
jengbrecht 103:da58d27c15d7 398
jengbrecht 98:dbeac735109d 399 return bytesWritten;
jengbrecht 69:f3e696bbb0d5 400 }
jengbrecht 69:f3e696bbb0d5 401
jengbrecht 69:f3e696bbb0d5 402 unsigned int Wifi::readable()
jengbrecht 69:f3e696bbb0d5 403 {
jengbrecht 69:f3e696bbb0d5 404 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 405 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 406 return 0;
jengbrecht 69:f3e696bbb0d5 407 }
jengbrecht 69:f3e696bbb0d5 408 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 409 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 410 return 0;
jengbrecht 69:f3e696bbb0d5 411 }
jengbrecht 69:f3e696bbb0d5 412 return io->readable();
jengbrecht 69:f3e696bbb0d5 413 }
jengbrecht 69:f3e696bbb0d5 414
jengbrecht 69:f3e696bbb0d5 415 unsigned int Wifi::writeable()
jengbrecht 69:f3e696bbb0d5 416 {
jengbrecht 69:f3e696bbb0d5 417 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 418 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 419 return 0;
jengbrecht 69:f3e696bbb0d5 420 }
jengbrecht 69:f3e696bbb0d5 421 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 422 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 423 return 0;
jengbrecht 69:f3e696bbb0d5 424 }
jengbrecht 69:f3e696bbb0d5 425
jengbrecht 69:f3e696bbb0d5 426 return io->writeable();
jengbrecht 69:f3e696bbb0d5 427 }
jengbrecht 69:f3e696bbb0d5 428
jengbrecht 69:f3e696bbb0d5 429 void Wifi::reset()
jengbrecht 69:f3e696bbb0d5 430 {
jengbrecht 69:f3e696bbb0d5 431 }
jengbrecht 69:f3e696bbb0d5 432
jengbrecht 106:358972176b89 433 Code Wifi::setDeviceIP(std::string address)
jengbrecht 106:358972176b89 434 {
jengbrecht 108:554585370b4a 435 //Check for command mode
jengbrecht 108:554585370b4a 436 if(!setCmdMode(true)) {
jengbrecht 108:554585370b4a 437 printf("[ERROR] Failed to set IP due to mode issue\r\n");
jengbrecht 108:554585370b4a 438 return FAILURE;
jengbrecht 108:554585370b4a 439 }
jengbrecht 113:7238f9b8db17 440
jengbrecht 106:358972176b89 441 //Set to DHCP mode
jengbrecht 106:358972176b89 442 if(address.compare("DHCP") == 0) {
jengbrecht 106:358972176b89 443 return sendBasicCommand("set ip dhcp 1", 1000);
jengbrecht 106:358972176b89 444 }
jengbrecht 106:358972176b89 445
jengbrecht 106:358972176b89 446 //Set to static mode and set address
jengbrecht 106:358972176b89 447 Code code = sendBasicCommand("set ip address " + address, 1000);
jengbrecht 106:358972176b89 448 if(code != SUCCESS) {
jengbrecht 106:358972176b89 449 return code;
jengbrecht 106:358972176b89 450 }
jengbrecht 106:358972176b89 451 code = sendBasicCommand("set ip dhcp 0", 1000);
jengbrecht 106:358972176b89 452 if(code != SUCCESS) {
jengbrecht 106:358972176b89 453 return code;
jengbrecht 106:358972176b89 454 }
jengbrecht 106:358972176b89 455 local_address = address;
jengbrecht 106:358972176b89 456 return SUCCESS;
jengbrecht 106:358972176b89 457 }
jengbrecht 106:358972176b89 458
jengbrecht 106:358972176b89 459 std::string Wifi::getDeviceIP()
jengbrecht 106:358972176b89 460 {
jengbrecht 106:358972176b89 461 return local_address;
jengbrecht 106:358972176b89 462 }
jengbrecht 106:358972176b89 463
jengbrecht 103:da58d27c15d7 464 Code Wifi::setNetwork(const std::string& ssid, SecurityType type, const std::string& key)
jengbrecht 69:f3e696bbb0d5 465 {
jengbrecht 98:dbeac735109d 466 //Check the command mode
jengbrecht 98:dbeac735109d 467 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 468 return FAILURE;
jengbrecht 98:dbeac735109d 469 }
jengbrecht 98:dbeac735109d 470
sgodinez 73:bb5bbca971ae 471 Code code;
jengbrecht 69:f3e696bbb0d5 472
jengbrecht 69:f3e696bbb0d5 473 //Set the appropraite SSID
jengbrecht 69:f3e696bbb0d5 474 code = sendBasicCommand("set wlan ssid " + ssid, 1000);
sgodinez 73:bb5bbca971ae 475 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 476 return code;
jengbrecht 69:f3e696bbb0d5 477 }
jengbrecht 69:f3e696bbb0d5 478
jengbrecht 69:f3e696bbb0d5 479 //Set the security key
jengbrecht 69:f3e696bbb0d5 480 if (type == WEP64 || type == WEP128) {
jengbrecht 69:f3e696bbb0d5 481 //Set the WEP key if using WEP encryption
jengbrecht 69:f3e696bbb0d5 482 code = sendBasicCommand("set wlan key " + key, 1000);
sgodinez 73:bb5bbca971ae 483 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 484 return code;
jengbrecht 69:f3e696bbb0d5 485 }
jengbrecht 69:f3e696bbb0d5 486 } else if (type == WPA || type == WPA2) {
jengbrecht 69:f3e696bbb0d5 487 //Set the WPA key if using WPA encryption
jengbrecht 69:f3e696bbb0d5 488 code = sendBasicCommand("set wlan phrase " + key, 1000);
sgodinez 73:bb5bbca971ae 489 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 490 return code;
jengbrecht 69:f3e696bbb0d5 491 }
jengbrecht 69:f3e696bbb0d5 492 }
jengbrecht 69:f3e696bbb0d5 493
jengbrecht 69:f3e696bbb0d5 494 _ssid = ssid;
sgodinez 73:bb5bbca971ae 495 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 496 }
jengbrecht 69:f3e696bbb0d5 497
jengbrecht 94:1baa587e89ae 498 Code Wifi::setDNS(const std::string& dnsName)
jengbrecht 94:1baa587e89ae 499 {
jengbrecht 98:dbeac735109d 500 //Check the command mode
jengbrecht 98:dbeac735109d 501 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 502 return FAILURE;
jengbrecht 98:dbeac735109d 503 }
jengbrecht 98:dbeac735109d 504
jengbrecht 94:1baa587e89ae 505 return sendBasicCommand("set dns name " + dnsName, 1000);
jengbrecht 94:1baa587e89ae 506 }
jengbrecht 94:1baa587e89ae 507
jengbrecht 69:f3e696bbb0d5 508 int Wifi::getSignalStrength()
jengbrecht 69:f3e696bbb0d5 509 {
jengbrecht 103:da58d27c15d7 510 //Signal strength does not report correctly if not connected
jengbrecht 103:da58d27c15d7 511 if(!wifiConnected) {
jengbrecht 103:da58d27c15d7 512 printf("[ERROR] Could not get RSSI, Wifi network not connected.\n\r");
jengbrecht 103:da58d27c15d7 513 return 99;
jengbrecht 103:da58d27c15d7 514 }
jengbrecht 103:da58d27c15d7 515
jengbrecht 98:dbeac735109d 516 //Check the command mode
jengbrecht 98:dbeac735109d 517 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 518 printf("[ERROR] Could not get RSSI\n\r");
jengbrecht 103:da58d27c15d7 519 return 99;
jengbrecht 98:dbeac735109d 520 }
jengbrecht 98:dbeac735109d 521
jengbrecht 93:aa7a48e65974 522 string response = sendCommand("show rssi", 2000, "dBm");
jengbrecht 74:9f87bd22c222 523 if (response.find("RSSI") == string::npos) {
jengbrecht 98:dbeac735109d 524 printf("[ERROR] Could not get RSSI\n\r");
jengbrecht 103:da58d27c15d7 525 return 99;
jengbrecht 74:9f87bd22c222 526 }
jengbrecht 74:9f87bd22c222 527 int start = response.find('(');
jengbrecht 74:9f87bd22c222 528 int stop = response.find(')', start);
jengbrecht 74:9f87bd22c222 529 string signal = response.substr(start + 1, stop - start - 1);
jengbrecht 74:9f87bd22c222 530 int value;
jengbrecht 74:9f87bd22c222 531 sscanf(signal.c_str(), "%d", &value);
jengbrecht 74:9f87bd22c222 532 return value;
jengbrecht 69:f3e696bbb0d5 533 }
jengbrecht 69:f3e696bbb0d5 534
jengbrecht 95:4fdf968b5b37 535 bool Wifi::ping(const std::string& address)
jengbrecht 95:4fdf968b5b37 536 {
jengbrecht 98:dbeac735109d 537 //Check the command mode
jengbrecht 98:dbeac735109d 538 if(!setCmdMode(true)) {
jengbrecht 98:dbeac735109d 539 printf("[ERROR] Could not send ping command\n\r");
jengbrecht 98:dbeac735109d 540 return false;
jengbrecht 98:dbeac735109d 541 }
jengbrecht 98:dbeac735109d 542
jengbrecht 95:4fdf968b5b37 543 std::string response;
jengbrecht 95:4fdf968b5b37 544 for (int i = 0; i < PINGNUM; i++) {
jengbrecht 95:4fdf968b5b37 545 response = sendCommand("ping " + address, PINGDELAY * 1000, "reply");
jengbrecht 95:4fdf968b5b37 546 if (response.find("reply") != std::string::npos) {
jengbrecht 95:4fdf968b5b37 547 return true;
jengbrecht 95:4fdf968b5b37 548 }
jengbrecht 95:4fdf968b5b37 549 }
jengbrecht 95:4fdf968b5b37 550 return false;
jengbrecht 95:4fdf968b5b37 551 }
jengbrecht 95:4fdf968b5b37 552
jengbrecht 79:f356009dbc12 553 bool Wifi::setCmdMode(bool on)
jengbrecht 74:9f87bd22c222 554 {
jengbrecht 79:f356009dbc12 555 if (on) {
jengbrecht 79:f356009dbc12 556 if (cmdOn) {
jengbrecht 79:f356009dbc12 557 return true;
jengbrecht 79:f356009dbc12 558 }
jengbrecht 79:f356009dbc12 559 wait(.5);
jengbrecht 93:aa7a48e65974 560 std::string response = sendCommand("$$", 2000, "CMD", '$');
jengbrecht 79:f356009dbc12 561 if (response.find("CMD") != string::npos) {
jengbrecht 79:f356009dbc12 562 cmdOn = true;
jengbrecht 113:7238f9b8db17 563 wait(.5);
jengbrecht 79:f356009dbc12 564 return true;
jengbrecht 79:f356009dbc12 565 }
jengbrecht 98:dbeac735109d 566 printf("[ERROR] Failed to enter command mode\n\r");
jengbrecht 79:f356009dbc12 567 return false;
jengbrecht 79:f356009dbc12 568 } else {
jengbrecht 79:f356009dbc12 569 if (!cmdOn) {
jengbrecht 79:f356009dbc12 570 return true;
jengbrecht 79:f356009dbc12 571 }
jengbrecht 93:aa7a48e65974 572 std::string response = sendCommand("exit", 2000, "EXIT");
jengbrecht 79:f356009dbc12 573 if (response.find("EXIT") != string::npos) {
jengbrecht 79:f356009dbc12 574 cmdOn = false;
jengbrecht 79:f356009dbc12 575 return true;
jengbrecht 79:f356009dbc12 576 }
jengbrecht 98:dbeac735109d 577 printf("[ERROR] Failed to exit command mode\n\r");
jengbrecht 79:f356009dbc12 578 return false;
jengbrecht 74:9f87bd22c222 579 }
jengbrecht 74:9f87bd22c222 580 }
jengbrecht 69:f3e696bbb0d5 581
sgodinez 73:bb5bbca971ae 582 Code Wifi::sendBasicCommand(string command, int timeoutMillis, char esc)
jengbrecht 69:f3e696bbb0d5 583 {
jengbrecht 69:f3e696bbb0d5 584 if(socketOpened) {
jengbrecht 69:f3e696bbb0d5 585 printf("[ERROR] socket is open. Can not send AT commands\r\n");
sgodinez 73:bb5bbca971ae 586 return ERROR;
jengbrecht 69:f3e696bbb0d5 587 }
jengbrecht 69:f3e696bbb0d5 588
jengbrecht 93:aa7a48e65974 589 string response = sendCommand(command, timeoutMillis, "AOK", esc);
jengbrecht 69:f3e696bbb0d5 590 //printf("Response: %s\n\r", response.c_str());
jengbrecht 69:f3e696bbb0d5 591 if (response.size() == 0) {
sgodinez 73:bb5bbca971ae 592 return NO_RESPONSE;
jengbrecht 69:f3e696bbb0d5 593 } else if (response.find("AOK") != string::npos) {
sgodinez 73:bb5bbca971ae 594 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 595 } else if (response.find("ERR") != string::npos) {
sgodinez 73:bb5bbca971ae 596 return ERROR;
jengbrecht 69:f3e696bbb0d5 597 } else {
sgodinez 73:bb5bbca971ae 598 return FAILURE;
jengbrecht 69:f3e696bbb0d5 599 }
jengbrecht 69:f3e696bbb0d5 600 }
jengbrecht 69:f3e696bbb0d5 601
jengbrecht 93:aa7a48e65974 602 string Wifi::sendCommand(string command, int timeoutMillis, std::string response, char esc)
jengbrecht 69:f3e696bbb0d5 603 {
jengbrecht 69:f3e696bbb0d5 604 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 605 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 606 return "";
jengbrecht 69:f3e696bbb0d5 607 }
jengbrecht 106:358972176b89 608 //if(socketOpened && command.compare("$$") != 0 && command.compare("exit") != 0 && command.compare("close") != 0) {
jengbrecht 106:358972176b89 609 // printf("[ERROR] socket is open. Can not send AT commands\r\n");
jengbrecht 106:358972176b89 610 // return "";
jengbrecht 106:358972176b89 611 //}
jengbrecht 69:f3e696bbb0d5 612
jengbrecht 69:f3e696bbb0d5 613 io->rxClear();
jengbrecht 69:f3e696bbb0d5 614 io->txClear();
jengbrecht 69:f3e696bbb0d5 615 std::string result;
jengbrecht 79:f356009dbc12 616
sgodinez 73:bb5bbca971ae 617 //Attempt to write command
sgodinez 73:bb5bbca971ae 618 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
sgodinez 73:bb5bbca971ae 619 //Failed to write command
sgodinez 73:bb5bbca971ae 620 printf("[ERROR] failed to send command to radio within %d milliseconds\r\n", timeoutMillis);
sgodinez 73:bb5bbca971ae 621 return "";
sgodinez 73:bb5bbca971ae 622 }
jengbrecht 79:f356009dbc12 623
sgodinez 73:bb5bbca971ae 624 //Send Escape Character
sgodinez 73:bb5bbca971ae 625 if (esc != 0x00) {
sgodinez 73:bb5bbca971ae 626 if(io->write(esc, timeoutMillis) != 1) {
sgodinez 73:bb5bbca971ae 627 printf("[ERROR] failed to send '%c' to radio within %d milliseconds\r\n", esc, timeoutMillis);
sgodinez 73:bb5bbca971ae 628 return "";
sgodinez 73:bb5bbca971ae 629 }
sgodinez 73:bb5bbca971ae 630 }
sgodinez 73:bb5bbca971ae 631
jengbrecht 69:f3e696bbb0d5 632 int timer = 0;
sgodinez 73:bb5bbca971ae 633 size_t previous = 0;
jengbrecht 69:f3e696bbb0d5 634 char tmp[256];
jengbrecht 69:f3e696bbb0d5 635 tmp[255] = 0;
jengbrecht 69:f3e696bbb0d5 636 bool done = false;
jengbrecht 69:f3e696bbb0d5 637 do {
jengbrecht 93:aa7a48e65974 638 wait(.2);
jengbrecht 93:aa7a48e65974 639 timer = timer + 200;
sgodinez 73:bb5bbca971ae 640 previous = result.size();
jengbrecht 93:aa7a48e65974 641 int size = io->read(tmp, 255, 0); //1 less than allocated
jengbrecht 69:f3e696bbb0d5 642 if(size > 0) {
jengbrecht 69:f3e696bbb0d5 643 result.append(tmp, size);
jengbrecht 93:aa7a48e65974 644 if (response.size() != 0) {
jengbrecht 93:aa7a48e65974 645 if (result.find(response) != string::npos) {
jengbrecht 93:aa7a48e65974 646 return result;
jengbrecht 93:aa7a48e65974 647 }
jengbrecht 93:aa7a48e65974 648 } else {
jengbrecht 93:aa7a48e65974 649 done = (result.size() == previous);
jengbrecht 69:f3e696bbb0d5 650 }
jengbrecht 69:f3e696bbb0d5 651 }
jengbrecht 69:f3e696bbb0d5 652 if(timer >= timeoutMillis) {
jengbrecht 93:aa7a48e65974 653 printf("[WARNING] sendCommand [%s] timed out after %d milliseconds\r\n", command.c_str(), timeoutMillis);
jengbrecht 69:f3e696bbb0d5 654 done = true;
jengbrecht 69:f3e696bbb0d5 655 }
jengbrecht 69:f3e696bbb0d5 656 } while (!done);
jengbrecht 79:f356009dbc12 657
jengbrecht 93:aa7a48e65974 658 //printf("Result: %s\n\r", result.c_str());
jengbrecht 69:f3e696bbb0d5 659 return result;
jengbrecht 69:f3e696bbb0d5 660 }