wifly/socket interface for wifly modules
Dependents: WiFi neurGAI_WIFI thingspeak thingspeak2
Revision 11:b912f91e3212, committed 2012-08-24
- Comitter:
- samux
- Date:
- Fri Aug 24 13:07:01 2012 +0000
- Parent:
- 10:81445de1fe27
- Child:
- 12:5ffaed1456c8
- Commit message:
- add state data structure
Changed in this revision
--- a/Socket/Endpoint.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Socket/Endpoint.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -24,7 +24,7 @@ Endpoint::Endpoint() { wifly = Wifly::getInstance(); if (wifly == NULL) - printf("Endpoint constructor error: no wifly instance available!\r\n"); + error("Endpoint constructor error: no wifly instance available!\r\n"); reset_address(); } Endpoint::~Endpoint() {} @@ -36,7 +36,7 @@ int Endpoint::set_address(const char* host, const int port) { //Resolve DNS address or populate hard-coded IP address - wifly->dnsLookup(host, _ipAddress); + wifly->gethostbyname(host, _ipAddress); _port = port; return 0; }
--- a/Socket/Socket.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Socket/Socket.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -22,7 +22,7 @@ Socket::Socket() : _blocking(true), _timeout(1500) { wifi = Wifly::getInstance(); if (wifi == NULL) - printf("Socket constructor error: no wifly instance available!\r\n"); + error("Socket constructor error: no wifly instance available!\r\n"); } void Socket::set_blocking(bool blocking, unsigned int timeout) {
--- a/Socket/TCPSocketConnection.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Socket/TCPSocketConnection.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -22,38 +22,9 @@ TCPSocketConnection::TCPSocketConnection() {} int TCPSocketConnection::connect(const char* host, const int port) -{ - //open the connection - char cmd[30]; - char rcv[40]; - - if (wifi->dnsLookup(host, rcv)) { - sprintf(cmd, "set ip host %s\r", rcv); - if (!wifi->sendCommand(cmd, "AOK")) - return -1; - } else { - return -1; - } - - sprintf(cmd, "set ip remote %d\r", port); - if (!wifi->sendCommand(cmd, "AOK")) +{ + if (!wifi->connect(host, port)) return -1; - - if (wifi->sendCommand("open\r", NULL, rcv)) { - if (strstr(rcv, "OPEN") == NULL) { - if (strstr(rcv, "Connected") != NULL) { - if (!wifi->sendCommand("close\r", "CLOS")) - return -1; - if (!wifi->sendCommand(cmd, "OPEN")) - return -1; - } else { - return -1; - } - } - } else { - return -1; - } - wifi->flush(); return 0; }
--- a/Socket/TCPSocketServer.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Socket/TCPSocketServer.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -25,15 +25,14 @@ int TCPSocketServer::bind(int port) { // use udp auto pairing char cmd[20]; - if (!wifi->sendCommand("set ip proto 2\r", "AOK")) + /*if (!wifi->sendCommand("set ip proto 2\r", "AOK")) return -1; if (!wifi->sendCommand("set ip flags 0x07\r", "AOK")) - return -1; + return -1;*/ + wifi->setProtocol(TCP); sprintf(cmd, "set ip local %d\r", port); if (!wifi->sendCommand(cmd, "AOK")) return -1; - if (!wifi->sendCommand("save\r", "Stor")) - return -1; wifi->exit(); return 0; }
--- a/Socket/UDPSocket.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Socket/UDPSocket.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -29,8 +29,7 @@ int UDPSocket::init(void) { - if (!wifi->sendCommand("set ip proto 1\r", "AOK")) - return -1; + wifi->setProtocol(UDP); wifi->exit(); return 0; } @@ -38,21 +37,15 @@ // Server initialization int UDPSocket::bind(int port) { - // use udp auto pairing - char cmd[20]; - if (!wifi->sendCommand("set ip proto 1\r", "AOK")) - return -1; - if (!wifi->sendCommand("set ip flags 0x40\r", "AOK")) - return -1; - if (!wifi->sendCommand("set ip host 0.0.0.0\r", "AOK")) - return -1; - if (!wifi->sendCommand("set ip remote 0\r", "AOK")) - return -1; - sprintf(cmd, "set ip local %d\r", port); + char cmd[17]; + + // set udp protocol + wifi->setProtocol(UDP); + + // set local port + sprintf(cmd, "set i l %d\r", port); if (!wifi->sendCommand(cmd, "AOK")) return -1; - if (!wifi->sendCommand("save\r", "Stor")) - return -1; wifi->exit(); return 0; } @@ -124,14 +117,16 @@ if (!endpoint_configured) { host = ep.get_address(); if (host[0] != '\0') { - sprintf(cmd, "set ip host %s\r", host); + // set host + sprintf(cmd, "set i h %s\r", host); if (!wifi->sendCommand(cmd, "AOK")) return false; - sprintf(cmd, "set ip remote %d\r", ep.get_port()); + + // set remote port + sprintf(cmd, "set i r %d\r", ep.get_port()); if (!wifi->sendCommand(cmd, "AOK")) return false; - if (!wifi->sendCommand("save\r", "Stor")) - return false; + wifi->exit(); endpoint_configured = true; return true;
--- a/Wifly/Wifly.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/Wifly/Wifly.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -1,455 +1,533 @@ -/* 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 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__); - -#define MAX_TRY_JOIN 3 - -Wifly * Wifly::inst; - -Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): - wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(512) -{ - this->wpa = wpa; - security = sec; - - // change all ' ' in '$' in the ssid and the passphrase - strcpy(this->ssid, ssid); - for (int i = 0; i < strlen(ssid); i++) { - if (this->ssid[i] == ' ') - this->ssid[i] = '$'; - } - strcpy(this->phrase, phrase); - for (int i = 0; i < strlen(phrase); i++) { - if (this->phrase[i] == ' ') - this->phrase[i] = '$'; - } - - inst = this; - attach_rx(false); - cmd_mode = false; -} - -bool Wifly::join() -{ - char cmd[100]; - - for (int i= 0; i < MAX_TRY_JOIN; i++) { - if (!sendCommand("set comm time 20\r", "AOK")) - continue; - - if (!sendCommand("set comm size 128\r", "AOK")) - continue; - - if (!sendCommand("set sys iofunc 0x40\r", "AOK")) - continue; - - // no string sent to the tcp client - if (!sendCommand("set comm remote 0\r", "AOK")) - continue; - - // tcp protocol - if (!sendCommand("set ip proto 2\r", "AOK")) - continue; - - // tcp retry - if (!sendCommand("set ip flags 0x7\r", "AOK")) - continue; - - //no echo - if (!sendCommand("set u m 1\r", "AOK")) - continue; - - // no auto join - if (!sendCommand("set w j 0\r", "AOK")) - continue; - - //dhcp - sprintf(cmd, "set i d %d\r", (dhcp) ? 1 : 0); - if (!sendCommand(cmd, "AOK")) - continue; - - // ssid - sprintf(cmd, "set w s %s\r", ssid); - if (!sendCommand(cmd, "AOK")) - continue; - - //auth - sprintf(cmd, "set w a %d\r", security); - if (!sendCommand(cmd, "AOK")) - continue; - - // 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")) - continue; - - sprintf(cmd, "set i n %s\r", netmask); - if (!sendCommand(cmd, "AOK")) - continue; - - sprintf(cmd, "set i g %s\r", gateway); - if (!sendCommand(cmd, "AOK")) - continue; - } - - //key step - if (security != NONE) { - if (security == WPA) - sprintf(cmd, "set w p %s\r", phrase); - else if (security == WEP_128) - sprintf(cmd, "set w k %s\r", phrase); - - if (!sendCommand(cmd, "AOK")) - continue; - } - - // save - if (!sendCommand("save\r", "Stor")) - return false; - - //join the network - sprintf(cmd, "join\r"); - if (!sendCommand(cmd, "Associated", NULL, 3000)) - continue; - - if (dhcp) { - if (!sendCommand("", "DHCP=ON", NULL, 3000)) - continue; - } - - exit(); - - INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); - return true; - } - return false; -} - -char * Wifly::getStringSecurity() { - switch(security) { - case NONE: - return "NONE"; - case WEP_128: - return "WEP_128"; - case WPA: - return "WPA"; - } - return "UNKNOWN"; -} - - -bool Wifly::dnsLookup(const char * host, char * ip) -{ - string h = host; - char cmd[30], rcv[100]; - int l = 0; - char * point; - int nb_digits = 0; - - // no dns needed - int pos = h.find("."); - if (pos != string::npos) { - string sub = h.substr(0, h.find(".")); - nb_digits = atoi(sub.c_str()); - } - //printf("substrL %s\r\n", sub.c_str()); - if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { - strcpy(ip, host); - } - // dns needed - else { - nb_digits = 0; - sprintf(cmd, "lookup %s\r", host); - if (!sendCommand(cmd, NULL, rcv)) - return false; - - // 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; -} - - -void Wifly::flush() -{ - buf_wifly.flush(); -} - -bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) -{ - if (!cmd_mode) { - cmdMode(); - } - if (send(cmd, strlen(cmd), ack, res, timeout) == -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 (!cmd_mode) - return true; - if (send("exit\r", 5, "EXIT") == -1) - return false; - cmd_mode = false; - flush(); - 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, int timeout) -{ - 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_ms() > timeout) { - //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() > 2) { - 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; +/* 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 (0 && defined(TARGET_LPC1768)) +#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 + +#if TARGET_LPC1768 +#define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); +#else +#define INFO(x, ...) +#endif + +#define MAX_TRY_JOIN 3 + +Wifly * Wifly::inst; + +Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): + wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(512) +{ + memset(&state, 0, sizeof(state)); + state.sec = sec; + + // change all ' ' in '$' in the ssid and the passphrase + strcpy(this->ssid, ssid); + for (int i = 0; i < strlen(ssid); i++) { + if (this->ssid[i] == ' ') + this->ssid[i] = '$'; + } + strcpy(this->phrase, phrase); + for (int i = 0; i < strlen(phrase); i++) { + if (this->phrase[i] == ' ') + this->phrase[i] = '$'; + } + + inst = this; + attach_rx(false); + state.cmd_mode = false; +} + +bool Wifly::join() +{ + char cmd[100]; + + for (int i= 0; i < MAX_TRY_JOIN; i++) { + // set time + if (!sendCommand("set c t 20\r", "AOK")) + continue; + + // set size + if (!sendCommand("set c s 128\r", "AOK")) + continue; + + // red led on when tcp connection active + if (!sendCommand("set s i 0x40\r", "AOK")) + continue; + + // no string sent to the tcp client + if (!sendCommand("set c r 0\r", "AOK")) + continue; + + // tcp protocol + if (!sendCommand("set i p 2\r", "AOK")) + continue; + + // tcp retry + if (!sendCommand("set i f 0x7\r", "AOK")) + continue; + + //no echo + if (!sendCommand("set u m 1\r", "AOK")) + continue; + + // no auto join + if (!sendCommand("set w j 0\r", "AOK")) + continue; + + //dhcp + sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0); + if (!sendCommand(cmd, "AOK")) + continue; + + // ssid + sprintf(cmd, "set w s %s\r", ssid); + if (!sendCommand(cmd, "AOK")) + continue; + + //auth + sprintf(cmd, "set w a %d\r", state.sec); + if (!sendCommand(cmd, "AOK")) + continue; + + // if no dhcp, set ip, netmask and gateway + if (!state.dhcp) { + DBG("not dhcp\r"); + + sprintf(cmd, "set i a %s\r\n", ip); + if (!sendCommand(cmd, "AOK")) + continue; + + sprintf(cmd, "set i n %s\r", netmask); + if (!sendCommand(cmd, "AOK")) + continue; + + sprintf(cmd, "set i g %s\r", gateway); + if (!sendCommand(cmd, "AOK")) + continue; + } + + //key step + if (state.sec != NONE) { + if (state.sec == WPA) + sprintf(cmd, "set w p %s\r", phrase); + else if (state.sec == WEP_128) + sprintf(cmd, "set w k %s\r", phrase); + + if (!sendCommand(cmd, "AOK")) + continue; + } + + // save + if (!sendCommand("save\r", "Stor")) + return false; + + //join the network + sprintf(cmd, "join\r"); + if (!sendCommand(cmd, "Associated", NULL, 3000)) + continue; + + if (state.dhcp) { + if (!sendCommand("", "DHCP=ON", NULL, 3000)) + continue; + } + + exit(); + + INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); + return true; + } + return false; +} + + +bool Wifly::setProtocol(Protocol p) +{ + // use udp auto pairing + char cmd[20]; + sprintf(cmd, "set i p %d\r", p); + if (!sendCommand(cmd, "AOK")) + return false; + + switch(p) { + case TCP: + // set ip flags: tcp retry enabled + if (!sendCommand("set i f 0x07\r", "AOK")) + return false; + break; + case UDP: + // set ip flags: udp auto pairing enabled + if (!sendCommand("set i f 0x40\r", "AOK")) + return false; + if (!sendCommand("set i h 0.0.0.0\r", "AOK")) + return false; + if (!sendCommand("set i r 0\r", "AOK")) + return false; + break; + } + state.proto = p; + return true; +} + +char * Wifly::getStringSecurity() +{ + switch(state.sec) { + case NONE: + return "NONE"; + case WEP_128: + return "WEP_128"; + case WPA: + return "WPA"; + } + return "UNKNOWN"; +} + +bool Wifly::connect(const char * host, int port) +{ + char rcv[20]; + char cmd[20]; + + // get ip from host and set host + if (gethostbyname(host, rcv)) { + sprintf(cmd, "set i h %s\r", rcv); + if (!sendCommand(cmd, "AOK")) + return false; + } else { + return false; + } + + // set port + sprintf(cmd, "set i r %d\r", port); + if (!sendCommand(cmd, "AOK")) + return false; + + // open + if (sendCommand("open\r", NULL, rcv)) { + if (strstr(rcv, "OPEN") == NULL) { + if (strstr(rcv, "Connected") != NULL) { + if (!sendCommand("close\r", "CLOS")) + return false; + if (!sendCommand("open\r", "OPEN")) + return false; + } else { + return false; + } + } + } else { + return false; + } + + state.tcp = true; + state.cmd_mode = false; + + return true; +} + + +bool Wifly::gethostbyname(const char * host, char * ip) +{ + string h = host; + char cmd[30], rcv[100]; + int l = 0; + char * point; + int nb_digits = 0; + + // no dns needed + int pos = h.find("."); + if (pos != string::npos) { + string sub = h.substr(0, h.find(".")); + nb_digits = atoi(sub.c_str()); + } + //printf("substrL %s\r\n", sub.c_str()); + if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { + strcpy(ip, host); + } + // dns needed + else { + nb_digits = 0; + sprintf(cmd, "lookup %s\r", host); + if (!sendCommand(cmd, NULL, rcv)) + return false; + + // 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; +} + + +void Wifly::flush() +{ + buf_wifly.flush(); +} + +bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) +{ + if (!state.cmd_mode) { + cmdMode(); + } + if (send(cmd, strlen(cmd), ack, res, timeout) == -1) { + ERR("sendCommand: cannot %s\r\n", cmd); + exit(); + return false; + } + return true; +} + +bool Wifly::cmdMode() +{ + // if already in cmd mode, return + if (state.cmd_mode) + return true; + + if (send("$$$", 3, "CMD") == -1) { + ERR("cannot enter in cmd mode\r\n"); + return false; + } + state.cmd_mode = true; + return true; +} + +bool Wifly::disconnect() +{ + // if already disconnected, return + if (!state.associated) + return true; + + 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() +{ + // if not connected, return + if (!state.tcp) + return true; + + wait(0.25); + if (!sendCommand("close\r", "CLOS")) + return false; + exit(); + + state.tcp = false; + return true; +} + + +int Wifly::putc(char c) +{ + while (!wifi.writeable()); + return wifi.putc(c); +} + + +bool Wifly::exit() +{ + flush(); + if (!state.cmd_mode) + return true; + if (!sendCommand("exit\r", "EXIT")) + return false; + state.cmd_mode = false; + flush(); + 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, int timeout) +{ + 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_ms() > timeout) { + //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() > 2) { + 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
--- a/Wifly/Wifly.h Thu Aug 23 16:03:52 2012 +0000 +++ b/Wifly/Wifly.h Fri Aug 24 13:07:01 2012 +0000 @@ -38,7 +38,13 @@ WPA = 3 }; -class Wifly { +enum Protocol { + UDP = (1 << 0), + TCP = (1 << 1) +}; + +class Wifly +{ public: /* @@ -55,39 +61,36 @@ Wifly( PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec); /* - * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module. - * Useful to send a command to the module and wait a response. - * - * - * @param str string to be sent - * @param len string length - * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") - * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) - * - * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s. - */ - int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); - - /* * Connect the wifi module to the ssid contained in the constructor. * * @return true if connected, false otherwise */ bool join(); - + /* - * Close a connection with the access point + * Disconnect the wifly module from the access point * * @ returns true if successful */ - bool leave(); + bool disconnect(); /* - * Read a string if available + * Open a tcp connection with the specified host on the specified port * - *@param str pointer where will be stored the string read + * @param host host (can be either an ip address or a name. If a name is provided, a dns request will be established) + * @param port port + * @ returns true if successful */ - bool read(char * str); + bool connect(const char * host, int port); + + + /* + * Set the protocol (UDP or TCP) + * + * @param p protocol + * @ returns true if successful + */ + bool setProtocol(Protocol p); /* * Reset the wifi module @@ -100,14 +103,14 @@ * @return number of available characters */ int readable(); - + /* * Check if characters are available * * @return number of available characters */ int writeable(); - + /* * Check if a tcp link is active * @@ -148,14 +151,28 @@ * @return true if successful, false otherwise */ bool exit(); - + /* * Close a tcp connection * * @ returns true if successful */ bool close(); - + + /* + * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module. + * Useful to send a command to the module and wait a response. + * + * + * @param str string to be sent + * @param len string length + * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO") + * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL) + * + * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s. + */ + int send(const char * str, int len, const char * ACK = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); + /* * Send a command to the wify module. Check if the module is in command mode. If not enter in command mode * @@ -166,17 +183,17 @@ * @returns true if successful */ bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT); - - bool dnsLookup(const char * host, char * ip); - - static Wifly * getInstance() {return inst;}; + + bool gethostbyname(const char * host, char * ip); + + static Wifly * getInstance() { + return inst; + }; protected: Serial wifi; DigitalOut reset_pin; DigitalIn tcp_status; - bool wpa; - bool dhcp; char phrase[30]; char ssid[30]; const char * ip; @@ -184,15 +201,24 @@ const char * gateway; int channel; CircBuffer<char> buf_wifly; - Security security; - char * getStringSecurity(); - - bool cmd_mode; - + static Wifly * inst; void attach_rx(bool null); void handler_rx(void); + + + typedef struct STATE { + bool associated; + bool tcp; + bool dhcp; + Security sec; + Protocol proto; + bool cmd_mode; + } State; + + State state; + char * getStringSecurity(); }; #endif \ No newline at end of file
--- a/WiflyInterface.cpp Thu Aug 23 16:03:52 2012 +0000 +++ b/WiflyInterface.cpp Fri Aug 24 13:07:01 2012 +0000 @@ -1,40 +1,50 @@ #include "WiflyInterface.h" -WiflyInterface::WiflyInterface(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec) : - Wifly(tx, rx, reset, tcp_status, ssid, phrase, sec) {ip_set = false;} - -int WiflyInterface::init() { - dhcp = true; +WiflyInterface::WiflyInterface( PinName tx, PinName rx, PinName reset, PinName tcp_status, + const char * ssid, const char * phrase, Security sec) : + Wifly(tx, rx, reset, tcp_status, ssid, phrase, sec) +{ + ip_set = false; +} + +int WiflyInterface::init() +{ + state.dhcp = true; reset(); return 0; } -int WiflyInterface::init(const char* ip, const char* mask, const char* gateway) { - dhcp = false; +int WiflyInterface::init(const char* ip, const char* mask, const char* gateway) +{ + state.dhcp = false; this->ip = ip; strcpy(ip_string, ip); ip_set = true; this->netmask = mask; this->gateway = gateway; - reset(); + return 0; } -int WiflyInterface::connect() { +int WiflyInterface::connect() +{ return join(); } -int WiflyInterface::disconnect() { - return leave(); +int WiflyInterface::disconnect() +{ + return disconnect(); } -char * WiflyInterface::getIPAddress() { +char * WiflyInterface::getIPAddress() +{ char * match = 0; if (!ip_set) { if (!sendCommand("get ip a\r", NULL, ip_string)) return NULL; exit(); + flush(); match = strstr(ip_string, "<"); if (match != NULL) { *match = '\0';