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:23:41 2013 +0000
Revision:
75:7ad32827b39e
Parent:
74:9f87bd22c222
Child:
76:371aab9902a4
Removed Echo mode method

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
jengbrecht 69:f3e696bbb0d5 64 if (sendBasicCommand("set wlan join 0", 1000) != Cellular::CELL_OK) {
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
jengbrecht 69:f3e696bbb0d5 70 if (sendBasicCommand("set wlan channel 0", 1000) != Cellular::CELL_OK) {
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
jengbrecht 69:f3e696bbb0d5 75 if (sendBasicCommand("set comm remote 0", 1000) != Cellular::CELL_OK) {
jengbrecht 69:f3e696bbb0d5 76 return false;
jengbrecht 69:f3e696bbb0d5 77 }
jengbrecht 69:f3e696bbb0d5 78
jengbrecht 69:f3e696bbb0d5 79 //Set device into DHCP mode
jengbrecht 69:f3e696bbb0d5 80 if (sendBasicCommand("set ip dhcp 1", 1000) != Cellular::CELL_OK) {
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
jengbrecht 69:f3e696bbb0d5 182 Cellular::Code Wifi::setNetwork(const std::string& ssid, const std::string& key, SecurityType type)
jengbrecht 69:f3e696bbb0d5 183 {
jengbrecht 69:f3e696bbb0d5 184 Cellular::Code code;
jengbrecht 69:f3e696bbb0d5 185
jengbrecht 69:f3e696bbb0d5 186 //Set the appropraite SSID
jengbrecht 74:9f87bd22c222 187 code = sendBasicCommand("set wlan ssid " + ssid, 2000);
jengbrecht 69:f3e696bbb0d5 188 if (code != Cellular::CELL_OK) {
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 74:9f87bd22c222 195 code = sendBasicCommand("set wlan key " + key, 2000);
jengbrecht 69:f3e696bbb0d5 196 if (code != Cellular::CELL_OK) {
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 74:9f87bd22c222 201 code = sendBasicCommand("set wlan phrase " + key, 2000);
jengbrecht 69:f3e696bbb0d5 202 if (code != Cellular::CELL_OK) {
jengbrecht 69:f3e696bbb0d5 203 return code;
jengbrecht 69:f3e696bbb0d5 204 }
jengbrecht 69:f3e696bbb0d5 205 }
jengbrecht 69:f3e696bbb0d5 206
jengbrecht 69:f3e696bbb0d5 207 _ssid = ssid;
jengbrecht 69:f3e696bbb0d5 208 return Cellular::CELL_OK;
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 74:9f87bd22c222 228 std::string response = sendCommand("$$$", 2000, Cellular::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
jengbrecht 69:f3e696bbb0d5 235 Cellular::Code Wifi::sendBasicCommand(string command, int timeoutMillis, Cellular::ESC_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");
jengbrecht 69:f3e696bbb0d5 239 return Cellular::CELL_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) {
jengbrecht 69:f3e696bbb0d5 245 return Cellular::CELL_NO_RESPONSE;
jengbrecht 69:f3e696bbb0d5 246 } else if (response.find("AOK") != string::npos) {
jengbrecht 69:f3e696bbb0d5 247 return Cellular::CELL_OK;
jengbrecht 69:f3e696bbb0d5 248 } else if (response.find("ERR") != string::npos) {
jengbrecht 69:f3e696bbb0d5 249 return Cellular::CELL_ERROR;
jengbrecht 69:f3e696bbb0d5 250 } else {
jengbrecht 69:f3e696bbb0d5 251 return Cellular::CELL_FAILURE;
jengbrecht 69:f3e696bbb0d5 252 }
jengbrecht 69:f3e696bbb0d5 253 }
jengbrecht 69:f3e696bbb0d5 254
jengbrecht 69:f3e696bbb0d5 255 string Wifi::sendCommand(string command, int timeoutMillis, Cellular::ESC_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) {
jengbrecht 69:f3e696bbb0d5 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 int size = command.size() + 1;
jengbrecht 69:f3e696bbb0d5 267 char cmd[size];
jengbrecht 69:f3e696bbb0d5 268 strcpy(cmd, command.c_str());
jengbrecht 69:f3e696bbb0d5 269 if (esc == Cellular::CR) {
jengbrecht 69:f3e696bbb0d5 270 cmd[size -1] = '\r';
jengbrecht 69:f3e696bbb0d5 271 } else if (esc == Cellular::CTRL_Z) {
jengbrecht 69:f3e696bbb0d5 272 cmd[size -1] = 0x1A;
jengbrecht 69:f3e696bbb0d5 273 } else if(esc == NONE) {
jengbrecht 74:9f87bd22c222 274 size = size - 1;
jengbrecht 69:f3e696bbb0d5 275 }
jengbrecht 69:f3e696bbb0d5 276
jengbrecht 69:f3e696bbb0d5 277 io->rxClear();
jengbrecht 69:f3e696bbb0d5 278 io->txClear();
jengbrecht 69:f3e696bbb0d5 279 std::string result;
jengbrecht 69:f3e696bbb0d5 280 int status = io->write(cmd, size);
jengbrecht 69:f3e696bbb0d5 281 int available = io->readable();
jengbrecht 69:f3e696bbb0d5 282 int previous = -1;
jengbrecht 69:f3e696bbb0d5 283 int timer = 0;
jengbrecht 69:f3e696bbb0d5 284 char tmp[256];
jengbrecht 69:f3e696bbb0d5 285 tmp[255] = 0;
jengbrecht 69:f3e696bbb0d5 286 bool started = !echoMode;
jengbrecht 69:f3e696bbb0d5 287 bool done = false;
jengbrecht 69:f3e696bbb0d5 288 do {
jengbrecht 74:9f87bd22c222 289 wait(.2);
jengbrecht 74:9f87bd22c222 290 timer = timer + 200;
jengbrecht 69:f3e696bbb0d5 291 previous = available;
jengbrecht 69:f3e696bbb0d5 292 available = io->readable();
jengbrecht 69:f3e696bbb0d5 293
jengbrecht 69:f3e696bbb0d5 294 int size = io->read(tmp,255); //1 less than allocated
jengbrecht 69:f3e696bbb0d5 295 if(size > 0) {
jengbrecht 69:f3e696bbb0d5 296 result.append(tmp, size);
jengbrecht 69:f3e696bbb0d5 297 }
jengbrecht 69:f3e696bbb0d5 298
jengbrecht 69:f3e696bbb0d5 299 if(!started) {
jengbrecht 69:f3e696bbb0d5 300 //In Echo Mode (Command will have echo'd + 2 characters for \r\n)
jengbrecht 69:f3e696bbb0d5 301 if(result.size() > command.size() + 2) {
jengbrecht 69:f3e696bbb0d5 302 started = true;
jengbrecht 69:f3e696bbb0d5 303 }
jengbrecht 69:f3e696bbb0d5 304 } else {
jengbrecht 69:f3e696bbb0d5 305 done = (available == previous);
jengbrecht 69:f3e696bbb0d5 306 }
jengbrecht 69:f3e696bbb0d5 307 if(timer >= timeoutMillis) {
jengbrecht 69:f3e696bbb0d5 308 printf("[WARNING] sendCommand timed out after %d milliseconds\r\n", timeoutMillis);
jengbrecht 69:f3e696bbb0d5 309 done = true;
jengbrecht 69:f3e696bbb0d5 310 }
jengbrecht 69:f3e696bbb0d5 311 } while (!done);
jengbrecht 69:f3e696bbb0d5 312
jengbrecht 69:f3e696bbb0d5 313 return result;
jengbrecht 69:f3e696bbb0d5 314 }