wifly/socket interface for wifly modules
Dependents: PROJET_MATTHIEU_2019 PROJET_MATTHIEU_2019
Diff: Wifly/Wifly.cpp
- Revision:
- 1:8f04181f9ad8
- Parent:
- 0:6ffb0aeb3972
- Child:
- 2:d78b1f66e345
diff -r 6ffb0aeb3972 -r 8f04181f9ad8 Wifly/Wifly.cpp --- a/Wifly/Wifly.cpp Fri Aug 17 08:28:04 2012 +0000 +++ b/Wifly/Wifly.cpp Wed Aug 22 15:52:29 2012 +0000 @@ -1,394 +1,453 @@ -/* Copyright (C) 2012 mbed.org, MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "mbed.h" -#include "Wifly.h" -#include <string> - -//Debug is disabled by default -#if 0 -#define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__); -#define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__); -#define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__); -#else -#define DBG(x, ...) -#define WARN(x, ...) -#define ERR(x, ...) -#endif - -#define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); - -Wifly * Wifly::inst; - -Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, bool wpa): - wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256) { - this->wpa = wpa; - this->phrase = phrase; - this->ssid = ssid; - inst = this; - attach_rx(false); - cmd_mode = false; -} - -bool Wifly::join() { - char cmd[100]; - - if (!sendCommand("set comm time 20\r", "AOK")) - return false; - - if (!sendCommand("set comm size 128\r", "AOK")) - return false; - - if (!sendCommand("set sys iofunc 0x40\r", "AOK")) - return false; - - // no string sent to the tcp client - if (!sendCommand("set comm remote 0\r", "AOK")) - return false; - - // tcp protocol - if (!sendCommand("set ip proto 2\r", "AOK")) - return false; - - // tcp retry - if (!sendCommand("set ip flags 0x7\r", "AOK")) - return false; - - //no echo - if (!sendCommand("set u m 1\r", "AOK")) - return false; - - //dhcp - sprintf(cmd, "set i d %d\r", (dhcp) ? 1 : 0); - if (!sendCommand(cmd, "AOK")) - return false; - - if (dhcp) { - if (!sendCommand("get w\r", NULL, cmd)) - return false; - - // if the wlan parameters are already known, we just connect without resending all commands - if ((string(cmd).find(ssid) != string::npos) && (string(cmd).find(phrase) != string::npos) ) { - DBG("ssid found && phrase found\r\n"); - Timer tmr; - tmr.start(); - while (tmr.read() < 2) { - send("show c\r", 7, NULL, cmd); - DBG("join: state of conn: %s\r\n", cmd); - if ((cmd[2] - '0') & 0x01) { - INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, (wpa) ? "WPA" : "WEP"); - // save - if (!sendCommand("save\r", "Stor")) - return false; - reboot(); - return true; - } - wait(0.2); - } - } - - DBG("getw: %s\r\n", cmd); - } - - // ssid - sprintf(cmd, "set w s %s\r", ssid); - if (!sendCommand(cmd, "AOK")) - return false; - - //auth - sprintf(cmd, "set w a %d\r", (wpa) ? 3 : 1); - if (!sendCommand(cmd, "AOK")) - return false; - - // if no dhcp, set ip, netmask and gateway - if (!dhcp) { - DBG("not dhcp\r"); - - sprintf(cmd, "set i a %s\r\n", ip); - if (!sendCommand(cmd, "AOK")) - return false; - - sprintf(cmd, "set i n %s\r", netmask); - if (!sendCommand(cmd, "AOK")) - return false; - - sprintf(cmd, "set i g %s\r", gateway); - if (!sendCommand(cmd, "AOK")) - return false; - } - - //key step - if (wpa) - sprintf(cmd, "set w p %s\r", phrase); - else - sprintf(cmd, "set w k %s\r", phrase); - - if (!sendCommand(cmd, "AOK")) - return false; - - // auto join - if (!sendCommand("set w j 1\r", "AOK")) - return false; - - // save - if (!sendCommand("save\r", "Stor")) - return false; - - //join the network - sprintf(cmd, "join %s\r", ssid); - if (!sendCommand(cmd, "Associated")) - return false; - - reboot(); - - INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, (wpa) ? "WPA" : "WEP"); - return true; -} - -bool Wifly::reboot() { - if (!sendCommand("reboot\r", "boot")) - return false; - wait(0.2); - // wait that the module fetches an IP - if (dhcp) { - while(send("", 0, "DHCP=ON") == -1); - } else { - while(send("", 0, "Static") == -1); - } - flush(); - cmd_mode = false; - return true; -} - - -void Wifly::flush() { - buf_wifly.flush(); -} - -bool Wifly::sendCommand(const char * cmd, const char * ack, char * res) { - if (!cmd_mode) { - cmdMode(); - } - if (send(cmd, strlen(cmd), ack, res) == -1) { - ERR("sendCommand: cannot %s\r\n", cmd); - exit(); - return false; - } - return true; -} - -bool Wifly::cmdMode() { - if (send("$$$", 3, "CMD") == -1) { - ERR("cannot enter in cmd mode\r\n"); - return false; - } - cmd_mode = true; - return true; -} - -bool Wifly::leave() { - if (!sendCommand("leave\r", "DeAuth")) - return false; - exit(); - return true; - -} - -bool Wifly::is_connected() { - return (tcp_status.read() == 1) ? true : false; -} - - -void Wifly::reset() { - reset_pin = 0; - wait(0.2); - reset_pin = 1; - wait(0.2); -} - -bool Wifly::close() { - wait(0.25); - if (!cmdMode()) - return false; - if (send("close\r", 6, "CLOS") == -1) - return false; - exit(); - return true; -} - - -int Wifly::putc(char c) { - while (!wifi.writeable()); - return wifi.putc(c); -} - - -bool Wifly::read(char * str) { - int length = buf_wifly.available(); - if (length == 0) - return false; - for (int i = 0; i < length; i++) - buf_wifly.dequeue(&str[i]); - str[length] = 0; - return true; -} - - -bool Wifly::exit() { - flush(); - if (send("exit\r", 5, "EXIT") == -1) - return false; - cmd_mode = false; - return true; -} - - -int Wifly::readable() { - return buf_wifly.available(); -} - -int Wifly::writeable() { - return wifi.writeable(); -} - -char Wifly::getc() { - char c; - while (!buf_wifly.available()); - buf_wifly.dequeue(&c); - return c; -} - -void Wifly::handler_rx(void) { - //read characters - while (wifi.readable()) - buf_wifly.queue(wifi.getc()); -} - -void Wifly::attach_rx(bool callback) { - if (!callback) - wifi.attach(NULL); - else - wifi.attach(this, &Wifly::handler_rx); -} - - -int Wifly::send(const char * str, int len, const char * ACK, char * res) { - char read; - size_t found = string::npos; - string checking; - Timer tmr; - int result = 0; - - DBG("will send: %s\r\n",str); - - attach_rx(false); - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - if (!ACK || !strcmp(ACK, "NO")) { - for (int i = 0; i < len; i++) - result = (putc(str[i]) == str[i]) ? result + 1 : result; - } else { - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - tmr.start(); - for (int i = 0; i < len; i++) - result = (putc(str[i]) == str[i]) ? result + 1 : result; - - while (1) { - if (tmr.read() > 3) { - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - DBG("check: %s\r\n", checking.c_str()); - - attach_rx(true); - return -1; - } else if (wifi.readable()) { - read = wifi.getc(); - if ( read != '\r' && read != '\n') { - checking += read; - found = checking.find(ACK); - if (found != string::npos) { - wait(0.01); - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - break; - } - } - } - } - DBG("check: %s\r\n", checking.c_str()); - - attach_rx(true); - return result; - } - - //the user wants the result from the command (ACK == NULL, res != NULL) - if ( res != NULL) { - int i = 0; - Timer timeout; - timeout.start(); - tmr.reset(); - while (1) { - if (timeout.read() > 3) { - if (i == 0) { - res = NULL; - break; - } - res[i] = '\0'; - DBG("user str 1: %s\r\n", res); - - break; - } else { - if (tmr.read_ms() > 1000) { - res[i] = '\0'; - DBG("user str: %s\r\n", res); - - break; - } - if (wifi.readable()) { - tmr.start(); - read = wifi.getc(); - - // we drop \r and \n - if ( read != '\r' && read != '\n') { - res[i++] = read; - } - } - } - } - DBG("user str: %s\r\n", res); - } - - //We flush the buffer - while (wifi.readable()) - wifi.getc(); - - attach_rx(true); - DBG("result: %d\r\n", result) - return result; +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "mbed.h" +#include "Wifly.h" +#include <string> +#include <algorithm> + +//Debug is disabled by default +#if 1 +#define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__); +#else +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#endif + +#define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); + +Wifly * Wifly::inst; + +Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, bool wpa): + wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256) +{ + this->wpa = wpa; + this->phrase = phrase; + this->ssid = ssid; + inst = this; + attach_rx(false); + cmd_mode = false; +} + +bool Wifly::join() +{ + char cmd[100]; + + if (!sendCommand("set comm time 20\r", "AOK")) + return false; + + if (!sendCommand("set comm size 128\r", "AOK")) + return false; + + if (!sendCommand("set sys iofunc 0x40\r", "AOK")) + return false; + + // no string sent to the tcp client + if (!sendCommand("set comm remote 0\r", "AOK")) + return false; + + // tcp protocol + if (!sendCommand("set ip proto 2\r", "AOK")) + return false; + + // tcp retry + if (!sendCommand("set ip flags 0x7\r", "AOK")) + return false; + + //no echo + if (!sendCommand("set u m 1\r", "AOK")) + return false; + + //dhcp + sprintf(cmd, "set i d %d\r", (dhcp) ? 1 : 0); + if (!sendCommand(cmd, "AOK")) + return false; + + if (dhcp) { + if (!sendCommand("get w\r", NULL, cmd)) + return false; + + // if the wlan parameters are already known, we just connect without resending all commands + if ((string(cmd).find(ssid) != string::npos) && (string(cmd).find(phrase) != string::npos) ) { + DBG("ssid found && phrase found\r\n"); + Timer tmr; + tmr.start(); + while (tmr.read() < 2) { + send("show c\r", 7, NULL, cmd); + DBG("join: state of conn: %s\r\n", cmd); + if ((cmd[2] - '0') & 0x01) { + INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, (wpa) ? "WPA" : "WEP"); + // save + if (!sendCommand("save\r", "Stor")) + return false; + reboot(); + return true; + } + wait(0.2); + } + } + + DBG("getw: %s\r\n", cmd); + } + + // ssid + sprintf(cmd, "set w s %s\r", ssid); + if (!sendCommand(cmd, "AOK")) + return false; + + //auth + sprintf(cmd, "set w a %d\r", (wpa) ? 3 : 1); + if (!sendCommand(cmd, "AOK")) + return false; + + // if no dhcp, set ip, netmask and gateway + if (!dhcp) { + DBG("not dhcp\r"); + + sprintf(cmd, "set i a %s\r\n", ip); + if (!sendCommand(cmd, "AOK")) + return false; + + sprintf(cmd, "set i n %s\r", netmask); + if (!sendCommand(cmd, "AOK")) + return false; + + sprintf(cmd, "set i g %s\r", gateway); + if (!sendCommand(cmd, "AOK")) + return false; + } + + //key step + if (wpa) + sprintf(cmd, "set w p %s\r", phrase); + else + sprintf(cmd, "set w k %s\r", phrase); + + if (!sendCommand(cmd, "AOK")) + return false; + + // auto join + if (!sendCommand("set w j 1\r", "AOK")) + return false; + + // save + if (!sendCommand("save\r", "Stor")) + return false; + + //join the network + sprintf(cmd, "join %s\r", ssid); + if (!sendCommand(cmd, "Associated")) + return false; + + reboot(); + + INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, (wpa) ? "WPA" : "WEP"); + return true; +} + + +bool Wifly::dnsLookup(const char * host, char * ip) +{ + string h = host; + char cmd[30], rcv[30]; + int l = 0; + char * point; + int nb_digits = 0; + + // no dns needed + if (atoi(host) > 0 && count(h.begin(), h.end(), '.') == 4) { + strcpy(ip, host); + } + // dns needed + else { + sprintf(cmd, "lookup %s\r", host); + if (!sendCommand(cmd, NULL, rcv)) + return false; + DBG("lookup: %s\r\n", rcv); + + // look for the ip address + char * begin = strstr(rcv, "=") + 1; + for (int i = 0; i < 3; i++) { + point = strstr(begin + l, "."); + DBG("str: %s", begin + l); + l += point - (begin + l) + 1; + } + DBG("str: %s", begin + l); + while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { + DBG("digit: %c", *(begin + l + nb_digits)); + nb_digits++; + } + memcpy(ip, begin, l + nb_digits); + ip[l+nb_digits] = 0; + DBG("ip from dns: %s", ip); + } + return true; +} + +bool Wifly::reboot() +{ + if (!sendCommand("reboot\r", "boot")) + return false; + wait(0.2); + // wait that the module fetches an IP + if (dhcp) { + while(send("", 0, "DHCP=ON") == -1); + } else { + while(send("", 0, "Static") == -1); + } + flush(); + cmd_mode = false; + return true; +} + + +void Wifly::flush() +{ + buf_wifly.flush(); +} + +bool Wifly::sendCommand(const char * cmd, const char * ack, char * res) +{ + if (!cmd_mode) { + cmdMode(); + } + if (send(cmd, strlen(cmd), ack, res) == -1) { + ERR("sendCommand: cannot %s\r\n", cmd); + exit(); + return false; + } + return true; +} + +bool Wifly::cmdMode() +{ + if (send("$$$", 3, "CMD") == -1) { + ERR("cannot enter in cmd mode\r\n"); + return false; + } + cmd_mode = true; + return true; +} + +bool Wifly::leave() +{ + if (!sendCommand("leave\r", "DeAuth")) + return false; + exit(); + return true; + +} + +bool Wifly::is_connected() +{ + return (tcp_status.read() == 1) ? true : false; +} + + +void Wifly::reset() +{ + reset_pin = 0; + wait(0.2); + reset_pin = 1; + wait(0.2); +} + +bool Wifly::close() +{ + wait(0.25); + if (!cmdMode()) + return false; + if (send("close\r", 6, "CLOS") == -1) + return false; + exit(); + return true; +} + + +int Wifly::putc(char c) +{ + while (!wifi.writeable()); + return wifi.putc(c); +} + + +bool Wifly::read(char * str) +{ + int length = buf_wifly.available(); + if (length == 0) + return false; + for (int i = 0; i < length; i++) + buf_wifly.dequeue(&str[i]); + str[length] = 0; + return true; +} + + +bool Wifly::exit() +{ + flush(); + if (send("exit\r", 5, "EXIT") == -1) + return false; + cmd_mode = false; + return true; +} + + +int Wifly::readable() +{ + return buf_wifly.available(); +} + +int Wifly::writeable() +{ + return wifi.writeable(); +} + +char Wifly::getc() +{ + char c; + while (!buf_wifly.available()); + buf_wifly.dequeue(&c); + return c; +} + +void Wifly::handler_rx(void) +{ + //read characters + while (wifi.readable()) + buf_wifly.queue(wifi.getc()); +} + +void Wifly::attach_rx(bool callback) +{ + if (!callback) + wifi.attach(NULL); + else + wifi.attach(this, &Wifly::handler_rx); +} + + +int Wifly::send(const char * str, int len, const char * ACK, char * res) +{ + char read; + size_t found = string::npos; + string checking; + Timer tmr; + int result = 0; + + DBG("will send: %s\r\n",str); + + attach_rx(false); + + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + if (!ACK || !strcmp(ACK, "NO")) { + for (int i = 0; i < len; i++) + result = (putc(str[i]) == str[i]) ? result + 1 : result; + } else { + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + tmr.start(); + for (int i = 0; i < len; i++) + result = (putc(str[i]) == str[i]) ? result + 1 : result; + + while (1) { + if (tmr.read() > 1.5) { + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + DBG("check: %s\r\n", checking.c_str()); + + attach_rx(true); + return -1; + } else if (wifi.readable()) { + read = wifi.getc(); + if ( read != '\r' && read != '\n') { + checking += read; + found = checking.find(ACK); + if (found != string::npos) { + wait(0.01); + + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + break; + } + } + } + } + DBG("check: %s\r\n", checking.c_str()); + + attach_rx(true); + return result; + } + + //the user wants the result from the command (ACK == NULL, res != NULL) + if ( res != NULL) { + int i = 0; + Timer timeout; + timeout.start(); + tmr.reset(); + while (1) { + if (timeout.read() > 3) { + if (i == 0) { + res = NULL; + break; + } + res[i] = '\0'; + DBG("user str 1: %s\r\n", res); + + break; + } else { + if (tmr.read_ms() > 300) { + res[i] = '\0'; + DBG("user str: %s\r\n", res); + + break; + } + if (wifi.readable()) { + tmr.start(); + read = wifi.getc(); + + // we drop \r and \n + if ( read != '\r' && read != '\n') { + res[i++] = read; + } + } + } + } + DBG("user str: %s\r\n", res); + } + + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + attach_rx(true); + DBG("result: %d\r\n", result) + return result; } \ No newline at end of file