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:
Thu Dec 26 16:35:29 2013 +0000
Revision:
76:371aab9902a4
Parent:
73:bb5bbca971ae
Parent:
75:7ad32827b39e
Child:
79:f356009dbc12
Merged

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jengbrecht 69:f3e696bbb0d5 1 #include "Wifi.h"
jengbrecht 69:f3e696bbb0d5 2
jengbrecht 69:f3e696bbb0d5 3 Wifi* Wifi::instance = NULL;
jengbrecht 69:f3e696bbb0d5 4
jengbrecht 69:f3e696bbb0d5 5 Wifi* Wifi::getInstance()
jengbrecht 69:f3e696bbb0d5 6 {
jengbrecht 69:f3e696bbb0d5 7 if(instance == NULL) {
jengbrecht 69:f3e696bbb0d5 8 instance = new Wifi(NULL);
jengbrecht 69:f3e696bbb0d5 9 }
jengbrecht 69:f3e696bbb0d5 10 return instance;
jengbrecht 69:f3e696bbb0d5 11 }
jengbrecht 69:f3e696bbb0d5 12
jengbrecht 69:f3e696bbb0d5 13 bool Wifi::init(MTSBufferedIO* io)
jengbrecht 69:f3e696bbb0d5 14 {
jengbrecht 69:f3e696bbb0d5 15 if (io == NULL) {
jengbrecht 69:f3e696bbb0d5 16 return false;
jengbrecht 69:f3e696bbb0d5 17 }
jengbrecht 69:f3e696bbb0d5 18 instance->io = io;
jengbrecht 74:9f87bd22c222 19 if(cmdMode()) {
jengbrecht 74:9f87bd22c222 20 return true;
jengbrecht 74:9f87bd22c222 21 }
jengbrecht 74:9f87bd22c222 22 printf("[ERROR] Failed to enter command mode\r\n");
jengbrecht 74:9f87bd22c222 23 return false;
jengbrecht 69:f3e696bbb0d5 24 }
jengbrecht 69:f3e696bbb0d5 25
jengbrecht 69:f3e696bbb0d5 26 Wifi::Wifi(MTSBufferedIO* io)
jengbrecht 69:f3e696bbb0d5 27 : io(io)
jengbrecht 69:f3e696bbb0d5 28 , echoMode(true)
jengbrecht 69:f3e696bbb0d5 29 , wifiConnected(false)
jengbrecht 69:f3e696bbb0d5 30 , mode(TCP)
jengbrecht 69:f3e696bbb0d5 31 , socketOpened(false)
jengbrecht 69:f3e696bbb0d5 32 , socketCloseable(true)
jengbrecht 69:f3e696bbb0d5 33 , local_port(0)
jengbrecht 69:f3e696bbb0d5 34 , host_port(0)
jengbrecht 69:f3e696bbb0d5 35 , _ssid("")
jengbrecht 69:f3e696bbb0d5 36 {
jengbrecht 69:f3e696bbb0d5 37
jengbrecht 69:f3e696bbb0d5 38 }
jengbrecht 69:f3e696bbb0d5 39
jengbrecht 69:f3e696bbb0d5 40 Wifi::~Wifi()
jengbrecht 69:f3e696bbb0d5 41 {
jengbrecht 69:f3e696bbb0d5 42 }
jengbrecht 69:f3e696bbb0d5 43
jengbrecht 69:f3e696bbb0d5 44 bool Wifi::connect()
jengbrecht 69:f3e696bbb0d5 45 {
jengbrecht 69:f3e696bbb0d5 46 //Check if socket is open
jengbrecht 69:f3e696bbb0d5 47 if(socketOpened) {
jengbrecht 69:f3e696bbb0d5 48 return true;
jengbrecht 69:f3e696bbb0d5 49 }
jengbrecht 69:f3e696bbb0d5 50
jengbrecht 69:f3e696bbb0d5 51 //Run Test first to validate a good state
jengbrecht 69:f3e696bbb0d5 52 if(isConnected()) {
jengbrecht 69:f3e696bbb0d5 53 return true;
jengbrecht 69:f3e696bbb0d5 54 }
jengbrecht 69:f3e696bbb0d5 55
jengbrecht 69:f3e696bbb0d5 56 //Check RSSI: AT+CSQ
jengbrecht 69:f3e696bbb0d5 57 //int rssi = getSignalStrength();
jengbrecht 69:f3e696bbb0d5 58 //printf("[DEBUG] Signal strength: %d\r\n", rssi);
jengbrecht 69:f3e696bbb0d5 59
jengbrecht 69:f3e696bbb0d5 60 //Possibly add a scan command here and look for the network....
jengbrecht 69:f3e696bbb0d5 61
jengbrecht 69:f3e696bbb0d5 62 printf("Starting Setup\n\r");
jengbrecht 69:f3e696bbb0d5 63 //Set device to manual infrastructure mode
sgodinez 73:bb5bbca971ae 64 if (sendBasicCommand("set wlan join 0", 1000) != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 65 return false;
jengbrecht 69:f3e696bbb0d5 66 }
jengbrecht 69:f3e696bbb0d5 67
jengbrecht 69:f3e696bbb0d5 68 printf("Set Manual Mode\n\r");
jengbrecht 69:f3e696bbb0d5 69 //Set device to channel auto-scanning mode
sgodinez 73:bb5bbca971ae 70 if (sendBasicCommand("set wlan channel 0", 1000) != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 71 return false;
jengbrecht 69:f3e696bbb0d5 72 }
jengbrecht 69:f3e696bbb0d5 73
jengbrecht 69:f3e696bbb0d5 74 //Set device so no data is transmitted immediately following a socket connection
sgodinez 73:bb5bbca971ae 75 if (sendBasicCommand("set comm remote 0", 1000) != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 76 return false;
jengbrecht 69:f3e696bbb0d5 77 }
jengbrecht 69:f3e696bbb0d5 78
jengbrecht 69:f3e696bbb0d5 79 //Set device into DHCP mode
sgodinez 73:bb5bbca971ae 80 if (sendBasicCommand("set ip dhcp 1", 1000) != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 81 return false;
jengbrecht 69:f3e696bbb0d5 82 }
jengbrecht 69:f3e696bbb0d5 83
jengbrecht 69:f3e696bbb0d5 84 //join my_network
jengbrecht 69:f3e696bbb0d5 85
jengbrecht 69:f3e696bbb0d5 86 //AT#CONNECTIONSTART: Make a PPP connection
jengbrecht 69:f3e696bbb0d5 87 printf("[DEBUG] Making SSID Connection Attempt. SSID[%s]\r\n", _ssid.c_str());
jengbrecht 69:f3e696bbb0d5 88 std::string result = sendCommand("join " + _ssid, 10000);
jengbrecht 69:f3e696bbb0d5 89 printf("Connect Status: %s\n\r", result.c_str());
jengbrecht 69:f3e696bbb0d5 90 //std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
jengbrecht 69:f3e696bbb0d5 91 // std::vector<std::string> parts = Text::split(pppResult, "\r\n");
jengbrecht 69:f3e696bbb0d5 92
jengbrecht 69:f3e696bbb0d5 93 /*
jengbrecht 69:f3e696bbb0d5 94 if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
jengbrecht 69:f3e696bbb0d5 95 if(parts.size() >= 2) {
jengbrecht 69:f3e696bbb0d5 96 local_address = parts[1];
jengbrecht 69:f3e696bbb0d5 97 }
jengbrecht 69:f3e696bbb0d5 98 printf("[INFO] PPP Connection Established: IP[%s]\r\n", local_address.c_str());
jengbrecht 69:f3e696bbb0d5 99 pppConnected = true;
jengbrecht 69:f3e696bbb0d5 100
jengbrecht 69:f3e696bbb0d5 101 } else {
jengbrecht 69:f3e696bbb0d5 102 pppConnected = false;
jengbrecht 69:f3e696bbb0d5 103 }
jengbrecht 69:f3e696bbb0d5 104 */
jengbrecht 69:f3e696bbb0d5 105
jengbrecht 69:f3e696bbb0d5 106 wifiConnected = true;
jengbrecht 69:f3e696bbb0d5 107 return wifiConnected;
jengbrecht 69:f3e696bbb0d5 108 }
jengbrecht 69:f3e696bbb0d5 109
jengbrecht 69:f3e696bbb0d5 110 void Wifi::disconnect()
jengbrecht 69:f3e696bbb0d5 111 {
jengbrecht 69:f3e696bbb0d5 112 }
jengbrecht 69:f3e696bbb0d5 113
jengbrecht 69:f3e696bbb0d5 114 bool Wifi::isConnected()
jengbrecht 69:f3e696bbb0d5 115 {
jengbrecht 69:f3e696bbb0d5 116 return false;
jengbrecht 69:f3e696bbb0d5 117 }
jengbrecht 69:f3e696bbb0d5 118
jengbrecht 69:f3e696bbb0d5 119 bool Wifi::bind(unsigned int port)
jengbrecht 69:f3e696bbb0d5 120 {
jengbrecht 69:f3e696bbb0d5 121 return true;
jengbrecht 69:f3e696bbb0d5 122 }
jengbrecht 69:f3e696bbb0d5 123
jengbrecht 69:f3e696bbb0d5 124 bool Wifi::open(const std::string& address, unsigned int port, Mode mode)
jengbrecht 69:f3e696bbb0d5 125 {
jengbrecht 69:f3e696bbb0d5 126 //set comm size??? are advanced Socket settings
jengbrecht 69:f3e696bbb0d5 127 //set comm time??? are advanced Socket settings
jengbrecht 69:f3e696bbb0d5 128 return true;
jengbrecht 69:f3e696bbb0d5 129 }
jengbrecht 69:f3e696bbb0d5 130
jengbrecht 69:f3e696bbb0d5 131 bool Wifi::isOpen()
jengbrecht 69:f3e696bbb0d5 132 {
jengbrecht 69:f3e696bbb0d5 133 return true;
jengbrecht 69:f3e696bbb0d5 134 }
jengbrecht 69:f3e696bbb0d5 135
jengbrecht 69:f3e696bbb0d5 136 bool Wifi::close()
jengbrecht 69:f3e696bbb0d5 137 {
jengbrecht 69:f3e696bbb0d5 138 return true;
jengbrecht 69:f3e696bbb0d5 139 }
jengbrecht 69:f3e696bbb0d5 140
jengbrecht 69:f3e696bbb0d5 141 int Wifi::read(char* data, int max, int timeout)
jengbrecht 69:f3e696bbb0d5 142 {
jengbrecht 69:f3e696bbb0d5 143 return 0;
jengbrecht 69:f3e696bbb0d5 144 }
jengbrecht 69:f3e696bbb0d5 145
jengbrecht 69:f3e696bbb0d5 146 int Wifi::write(const char* data, int length, int timeout)
jengbrecht 69:f3e696bbb0d5 147 {
jengbrecht 69:f3e696bbb0d5 148 return 0;
jengbrecht 69:f3e696bbb0d5 149 }
jengbrecht 69:f3e696bbb0d5 150
jengbrecht 69:f3e696bbb0d5 151 unsigned int Wifi::readable()
jengbrecht 69:f3e696bbb0d5 152 {
jengbrecht 69:f3e696bbb0d5 153 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 154 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 155 return 0;
jengbrecht 69:f3e696bbb0d5 156 }
jengbrecht 69:f3e696bbb0d5 157 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 158 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 159 return 0;
jengbrecht 69:f3e696bbb0d5 160 }
jengbrecht 69:f3e696bbb0d5 161 return io->readable();
jengbrecht 69:f3e696bbb0d5 162 }
jengbrecht 69:f3e696bbb0d5 163
jengbrecht 69:f3e696bbb0d5 164 unsigned int Wifi::writeable()
jengbrecht 69:f3e696bbb0d5 165 {
jengbrecht 69:f3e696bbb0d5 166 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 167 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 168 return 0;
jengbrecht 69:f3e696bbb0d5 169 }
jengbrecht 69:f3e696bbb0d5 170 if(!socketOpened) {
jengbrecht 69:f3e696bbb0d5 171 printf("[ERROR] Socket is not open\r\n");
jengbrecht 69:f3e696bbb0d5 172 return 0;
jengbrecht 69:f3e696bbb0d5 173 }
jengbrecht 69:f3e696bbb0d5 174
jengbrecht 69:f3e696bbb0d5 175 return io->writeable();
jengbrecht 69:f3e696bbb0d5 176 }
jengbrecht 69:f3e696bbb0d5 177
jengbrecht 69:f3e696bbb0d5 178 void Wifi::reset()
jengbrecht 69:f3e696bbb0d5 179 {
jengbrecht 69:f3e696bbb0d5 180 }
jengbrecht 69:f3e696bbb0d5 181
sgodinez 73:bb5bbca971ae 182 Code Wifi::setNetwork(const std::string& ssid, const std::string& key, SecurityType type)
jengbrecht 69:f3e696bbb0d5 183 {
sgodinez 73:bb5bbca971ae 184 Code code;
jengbrecht 69:f3e696bbb0d5 185
jengbrecht 69:f3e696bbb0d5 186 //Set the appropraite SSID
jengbrecht 69:f3e696bbb0d5 187 code = sendBasicCommand("set wlan ssid " + ssid, 1000);
sgodinez 73:bb5bbca971ae 188 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 189 return code;
jengbrecht 69:f3e696bbb0d5 190 }
jengbrecht 69:f3e696bbb0d5 191
jengbrecht 69:f3e696bbb0d5 192 //Set the security key
jengbrecht 69:f3e696bbb0d5 193 if (type == WEP64 || type == WEP128) {
jengbrecht 69:f3e696bbb0d5 194 //Set the WEP key if using WEP encryption
jengbrecht 69:f3e696bbb0d5 195 code = sendBasicCommand("set wlan key " + key, 1000);
sgodinez 73:bb5bbca971ae 196 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 197 return code;
jengbrecht 69:f3e696bbb0d5 198 }
jengbrecht 69:f3e696bbb0d5 199 } else if (type == WPA || type == WPA2) {
jengbrecht 69:f3e696bbb0d5 200 //Set the WPA key if using WPA encryption
jengbrecht 69:f3e696bbb0d5 201 code = sendBasicCommand("set wlan phrase " + key, 1000);
sgodinez 73:bb5bbca971ae 202 if (code != SUCCESS) {
jengbrecht 69:f3e696bbb0d5 203 return code;
jengbrecht 69:f3e696bbb0d5 204 }
jengbrecht 69:f3e696bbb0d5 205 }
jengbrecht 69:f3e696bbb0d5 206
jengbrecht 69:f3e696bbb0d5 207 _ssid = ssid;
sgodinez 73:bb5bbca971ae 208 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 209 }
jengbrecht 69:f3e696bbb0d5 210
jengbrecht 69:f3e696bbb0d5 211 int Wifi::getSignalStrength()
jengbrecht 69:f3e696bbb0d5 212 {
jengbrecht 74:9f87bd22c222 213 string response = sendCommand("show rssi", 2000);
jengbrecht 74:9f87bd22c222 214 if (response.find("RSSI") == string::npos) {
jengbrecht 74:9f87bd22c222 215 return -1;
jengbrecht 74:9f87bd22c222 216 }
jengbrecht 74:9f87bd22c222 217 int start = response.find('(');
jengbrecht 74:9f87bd22c222 218 int stop = response.find(')', start);
jengbrecht 74:9f87bd22c222 219 string signal = response.substr(start + 1, stop - start - 1);
jengbrecht 74:9f87bd22c222 220 int value;
jengbrecht 74:9f87bd22c222 221 sscanf(signal.c_str(), "%d", &value);
jengbrecht 74:9f87bd22c222 222 return value;
jengbrecht 69:f3e696bbb0d5 223 }
jengbrecht 69:f3e696bbb0d5 224
jengbrecht 74:9f87bd22c222 225 bool Wifi::cmdMode()
jengbrecht 74:9f87bd22c222 226 {
jengbrecht 74:9f87bd22c222 227 wait(.5);
jengbrecht 76:371aab9902a4 228 std::string response = sendCommand("$$$", 2000, NONE);
jengbrecht 74:9f87bd22c222 229 if (response.find("CMD") != string::npos) {
jengbrecht 74:9f87bd22c222 230 return true;
jengbrecht 74:9f87bd22c222 231 }
jengbrecht 74:9f87bd22c222 232 return false;
jengbrecht 74:9f87bd22c222 233 }
jengbrecht 69:f3e696bbb0d5 234
sgodinez 73:bb5bbca971ae 235 Code Wifi::sendBasicCommand(string command, int timeoutMillis, char esc)
jengbrecht 69:f3e696bbb0d5 236 {
jengbrecht 69:f3e696bbb0d5 237 if(socketOpened) {
jengbrecht 69:f3e696bbb0d5 238 printf("[ERROR] socket is open. Can not send AT commands\r\n");
sgodinez 73:bb5bbca971ae 239 return ERROR;
jengbrecht 69:f3e696bbb0d5 240 }
jengbrecht 69:f3e696bbb0d5 241
jengbrecht 69:f3e696bbb0d5 242 string response = sendCommand(command, timeoutMillis, esc);
jengbrecht 69:f3e696bbb0d5 243 //printf("Response: %s\n\r", response.c_str());
jengbrecht 69:f3e696bbb0d5 244 if (response.size() == 0) {
sgodinez 73:bb5bbca971ae 245 return NO_RESPONSE;
jengbrecht 69:f3e696bbb0d5 246 } else if (response.find("AOK") != string::npos) {
sgodinez 73:bb5bbca971ae 247 return SUCCESS;
jengbrecht 69:f3e696bbb0d5 248 } else if (response.find("ERR") != string::npos) {
sgodinez 73:bb5bbca971ae 249 return ERROR;
jengbrecht 69:f3e696bbb0d5 250 } else {
sgodinez 73:bb5bbca971ae 251 return FAILURE;
jengbrecht 69:f3e696bbb0d5 252 }
jengbrecht 69:f3e696bbb0d5 253 }
jengbrecht 69:f3e696bbb0d5 254
sgodinez 73:bb5bbca971ae 255 string Wifi::sendCommand(string command, int timeoutMillis, char esc)
jengbrecht 69:f3e696bbb0d5 256 {
jengbrecht 69:f3e696bbb0d5 257 if(io == NULL) {
jengbrecht 69:f3e696bbb0d5 258 printf("[ERROR] MTSBufferedIO not set\r\n");
jengbrecht 69:f3e696bbb0d5 259 return "";
jengbrecht 69:f3e696bbb0d5 260 }
jengbrecht 69:f3e696bbb0d5 261 if(socketOpened) {
sgodinez 73:bb5bbca971ae 262 printf("[ERROR] socket is open. Can not send AT commands\r\n");
jengbrecht 69:f3e696bbb0d5 263 return "";
jengbrecht 69:f3e696bbb0d5 264 }
jengbrecht 69:f3e696bbb0d5 265
jengbrecht 69:f3e696bbb0d5 266 io->rxClear();
jengbrecht 69:f3e696bbb0d5 267 io->txClear();
jengbrecht 69:f3e696bbb0d5 268 std::string result;
sgodinez 73:bb5bbca971ae 269
sgodinez 73:bb5bbca971ae 270 //Attempt to write command
sgodinez 73:bb5bbca971ae 271 if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) {
sgodinez 73:bb5bbca971ae 272 //Failed to write command
sgodinez 73:bb5bbca971ae 273 printf("[ERROR] failed to send command to radio within %d milliseconds\r\n", timeoutMillis);
sgodinez 73:bb5bbca971ae 274 return "";
sgodinez 73:bb5bbca971ae 275 }
sgodinez 73:bb5bbca971ae 276
sgodinez 73:bb5bbca971ae 277 //Send Escape Character
sgodinez 73:bb5bbca971ae 278 if (esc != 0x00) {
sgodinez 73:bb5bbca971ae 279 if(io->write(esc, timeoutMillis) != 1) {
sgodinez 73:bb5bbca971ae 280 printf("[ERROR] failed to send '%c' to radio within %d milliseconds\r\n", esc, timeoutMillis);
sgodinez 73:bb5bbca971ae 281 return "";
sgodinez 73:bb5bbca971ae 282 }
sgodinez 73:bb5bbca971ae 283 }
sgodinez 73:bb5bbca971ae 284
jengbrecht 69:f3e696bbb0d5 285 int timer = 0;
sgodinez 73:bb5bbca971ae 286 size_t previous = 0;
jengbrecht 69:f3e696bbb0d5 287 char tmp[256];
jengbrecht 69:f3e696bbb0d5 288 tmp[255] = 0;
jengbrecht 69:f3e696bbb0d5 289 bool started = !echoMode;
jengbrecht 69:f3e696bbb0d5 290 bool done = false;
jengbrecht 69:f3e696bbb0d5 291 do {
jengbrecht 69:f3e696bbb0d5 292 wait(.1);
jengbrecht 69:f3e696bbb0d5 293 timer = timer + 100;
sgodinez 73:bb5bbca971ae 294 previous = result.size();
jengbrecht 69:f3e696bbb0d5 295 int size = io->read(tmp,255); //1 less than allocated
jengbrecht 69:f3e696bbb0d5 296 if(size > 0) {
jengbrecht 69:f3e696bbb0d5 297 result.append(tmp, size);
jengbrecht 69:f3e696bbb0d5 298 }
sgodinez 73:bb5bbca971ae 299
jengbrecht 69:f3e696bbb0d5 300 if(!started) {
jengbrecht 69:f3e696bbb0d5 301 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
jengbrecht 69:f3e696bbb0d5 302 if(result.size() > command.size() + 2) {
jengbrecht 69:f3e696bbb0d5 303 started = true;
jengbrecht 69:f3e696bbb0d5 304 }
jengbrecht 69:f3e696bbb0d5 305 } else {
sgodinez 73:bb5bbca971ae 306 done = (result.size() == previous);
jengbrecht 69:f3e696bbb0d5 307 }
jengbrecht 69:f3e696bbb0d5 308 if(timer >= timeoutMillis) {
jengbrecht 69:f3e696bbb0d5 309 printf("[WARNING] sendCommand timed out after %d milliseconds\r\n", timeoutMillis);
jengbrecht 69:f3e696bbb0d5 310 done = true;
jengbrecht 69:f3e696bbb0d5 311 }
jengbrecht 69:f3e696bbb0d5 312 } while (!done);
sgodinez 73:bb5bbca971ae 313
jengbrecht 69:f3e696bbb0d5 314 return result;
jengbrecht 69:f3e696bbb0d5 315 }