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
wifi/Wifi.cpp
- Committer:
- jengbrecht
- Date:
- 2013-12-27
- Revision:
- 93:aa7a48e65974
- Parent:
- 79:f356009dbc12
- Child:
- 94:1baa587e89ae
File content as of revision 93:aa7a48e65974:
#include "Wifi.h" #include <string> Wifi* Wifi::instance = NULL; Wifi* Wifi::getInstance() { if(instance == NULL) { instance = new Wifi(NULL); } return instance; } bool Wifi::init(MTSBufferedIO* io) { if (io == NULL) { return false; } instance->io = io; if (setCmdMode(true)) { return true; } return false; } Wifi::Wifi(MTSBufferedIO* io) : io(io) , wifiConnected(false) , _ssid("") , mode(TCP) , socketOpened(false) , socketCloseable(true) , local_port(0) , host_port(0) , cmdOn(false) { } Wifi::~Wifi() { } bool Wifi::connect() { //Check if socket is open if(socketOpened) { return true; } //Run Test first to validate a good state if(isConnected()) { return true; } if (_ssid.size() == 0) { printf("[ERROR] No SSID has been set\n\r"); return false; } if (!cmdOn) { if(!setCmdMode(true)) { printf("[ERROR] Failed to enter command mode\n\r"); return false; } } //Check RSSI: AT+CSQ int rssi = getSignalStrength(); printf("[DEBUG] Signal strength: %d\r\n", rssi); //Possibly add a scan command here and look for the network.... printf("[DEBUG] Starting Network Configuration\n\r"); //Set device to manual infrastructure mode if (sendBasicCommand("set wlan join 0", 1000) != SUCCESS) { return false; } //Set device to channel auto-scanning mode if (sendBasicCommand("set wlan channel 0", 1000) != SUCCESS) { return false; } //Set device so no data is transmitted immediately following a socket connection if (sendBasicCommand("set comm remote 0", 1000) != SUCCESS) { return false; } //Set device into DHCP mode if (sendBasicCommand("set ip dhcp 1", 1000) != SUCCESS) { return false; } //join my_network printf("[DEBUG] Making SSID Connection Attempt. SSID[%s]\r\n", _ssid.c_str()); std::string result = sendCommand("join " + _ssid, 15000, "Listen"); //printf("Connect Status: %s\n\r", result.c_str()); //Check whether connection was successful if(result.find("Associated!") != string::npos) { int start = result.find("IP="); int stop = result.find(":", start); local_address = result.substr(start + 3, stop - start - 3); printf("[INFO] WiFi Connection Established: IP[%s]\r\n", local_address.c_str()); wifiConnected = true; } else { wifiConnected = false; } return wifiConnected; } void Wifi::disconnect() { printf("[DEBUG] Disconnecting from network\r\n"); if(socketOpened) { close(); } bool success = false; if (setCmdMode(true)) { std::string response = sendCommand("leave", 10000); if (response.find("DeAuth") != string::npos) { success = true; } } if(success) { printf("[DEBUG] Successfully disconnected from network\r\n"); } else { printf("[ERROR] Failed in disconnecting from network. Continuing ...\r\n"); } wifiConnected = false; } bool Wifi::isConnected() { //1) Check if SSID was set if(_ssid.size() == 0) { printf("[DEBUG] SSID is not set\r\n"); return false; } //1) Check that we do not have a live connection up if(socketOpened) { printf("[DEBUG] Socket is opened\r\n"); return true; } //2) Query the wifi module wifiConnected = false; std::string result = sendCommand("show net", 5000, "Links"); //printf("netResult: %s\n\r", result); if(result.find("Assoc=OK") != std::string::npos) { wifiConnected = true; } return wifiConnected; } bool Wifi::bind(unsigned int port) { return true; } bool Wifi::open(const std::string& address, unsigned int port, Mode mode) { //set comm size??? are advanced Socket settings //set comm time??? are advanced Socket settings return true; } bool Wifi::isOpen() { return true; } bool Wifi::close() { return true; } int Wifi::read(char* data, int max, int timeout) { return 0; } int Wifi::write(const char* data, int length, int timeout) { return 0; } unsigned int Wifi::readable() { if(io == NULL) { printf("[ERROR] MTSBufferedIO not set\r\n"); return 0; } if(!socketOpened) { printf("[ERROR] Socket is not open\r\n"); return 0; } return io->readable(); } unsigned int Wifi::writeable() { if(io == NULL) { printf("[ERROR] MTSBufferedIO not set\r\n"); return 0; } if(!socketOpened) { printf("[ERROR] Socket is not open\r\n"); return 0; } return io->writeable(); } void Wifi::reset() { } Code Wifi::setNetwork(const std::string& ssid, const std::string& key, SecurityType type) { Code code; //Set the appropraite SSID code = sendBasicCommand("set wlan ssid " + ssid, 1000); if (code != SUCCESS) { return code; } //Set the security key if (type == WEP64 || type == WEP128) { //Set the WEP key if using WEP encryption code = sendBasicCommand("set wlan key " + key, 1000); if (code != SUCCESS) { return code; } } else if (type == WPA || type == WPA2) { //Set the WPA key if using WPA encryption code = sendBasicCommand("set wlan phrase " + key, 1000); if (code != SUCCESS) { return code; } } _ssid = ssid; return SUCCESS; } int Wifi::getSignalStrength() { string response = sendCommand("show rssi", 2000, "dBm"); if (response.find("RSSI") == string::npos) { return -1; } int start = response.find('('); int stop = response.find(')', start); string signal = response.substr(start + 1, stop - start - 1); int value; sscanf(signal.c_str(), "%d", &value); return value; } bool Wifi::setCmdMode(bool on) { if (on) { if (cmdOn) { return true; } wait(.5); std::string response = sendCommand("$$", 2000, "CMD", '$'); if (response.find("CMD") != string::npos) { cmdOn = true; return true; } printf("Failed Response: %s\n\r", response.c_str()); return false; } else { if (!cmdOn) { return true; } std::string response = sendCommand("exit", 2000, "EXIT"); if (response.find("EXIT") != string::npos) { cmdOn = false; return true; } return false; } } Code Wifi::sendBasicCommand(string command, int timeoutMillis, char esc) { if(socketOpened) { printf("[ERROR] socket is open. Can not send AT commands\r\n"); return ERROR; } string response = sendCommand(command, timeoutMillis, "AOK", esc); //printf("Response: %s\n\r", response.c_str()); if (response.size() == 0) { return NO_RESPONSE; } else if (response.find("AOK") != string::npos) { return SUCCESS; } else if (response.find("ERR") != string::npos) { return ERROR; } else { return FAILURE; } } string Wifi::sendCommand(string command, int timeoutMillis, std::string response, char esc) { if(io == NULL) { printf("[ERROR] MTSBufferedIO not set\r\n"); return ""; } if(socketOpened && command.compare("$$") != 0) { printf("[ERROR] socket is open. Can not send AT commands\r\n"); return ""; } io->rxClear(); io->txClear(); std::string result; //Attempt to write command if(io->write(command.data(), command.size(), timeoutMillis) != command.size()) { //Failed to write command printf("[ERROR] failed to send command to radio within %d milliseconds\r\n", timeoutMillis); return ""; } //Send Escape Character if (esc != 0x00) { if(io->write(esc, timeoutMillis) != 1) { printf("[ERROR] failed to send '%c' to radio within %d milliseconds\r\n", esc, timeoutMillis); return ""; } } int timer = 0; size_t previous = 0; char tmp[256]; tmp[255] = 0; bool done = false; do { wait(.2); timer = timer + 200; previous = result.size(); int size = io->read(tmp, 255, 0); //1 less than allocated if(size > 0) { result.append(tmp, size); if (response.size() != 0) { if (result.find(response) != string::npos) { return result; } } else { done = (result.size() == previous); } } if(timer >= timeoutMillis) { printf("[WARNING] sendCommand [%s] timed out after %d milliseconds\r\n", command.c_str(), timeoutMillis); done = true; } } while (!done); //printf("Result: %s\n\r", result.c_str()); return result; }