A fork of the original interface for OS/2. Features a correctly-implemented recv (but retains the old behavior via recv2).
Dependents: weather_clock weather_clock
Diff: ESP8266/ESP8266.cpp
- Revision:
- 13:41098c907200
- Parent:
- 12:c5f0eac67a8a
- Child:
- 14:4d1128f72e00
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP8266/ESP8266.cpp Sun Nov 30 21:14:09 2014 +0000 @@ -0,0 +1,299 @@ +/* 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 "ESP8266.h" +#include <string> +#include <algorithm> + +//Debug is disabled by default +#if (defined(DEBUG)) +#define DBG(x, ...) std::printf("[ESP8266 : DBG]"x"\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[ESP8266 : WARN]"x"\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[ESP8266 : ERR]"x"\r\n", ##__VA_ARGS__); +#else +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#endif + +#if defined(DEBUG) +#define INFO(x, ...) printf("[ESP8266 : INFO]"x"\r\n", ##__VA_ARGS__); +#else +#define INFO(x, ...) +#endif + +#define MAX_TRY_JOIN 3 + +extern Serial pc; + +ESP8266 * ESP8266::inst; + +ESP8266::ESP8266( PinName tx, PinName rx, PinName _reset, const char * ssid, const char * phrase ): + wifi(tx, rx), reset_pin(_reset), buf_ESP8266(256) +{ + memset(&state, 0, sizeof(state)); + + // 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); +} + +bool ESP8266::join() +{ + + for (int i= 0; i < MAX_TRY_JOIN; i++) { + + //join the network + state.associated = true; + INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase); + return true; + } + return false; +} + +bool ESP8266::connect() +{ + return join(); +} + +bool ESP8266::gethostbyname(const char * host, char * ip) +{ + string h = host; + 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); + return true; + } + else { + // dns needed, not currently available + return false; + } +} + +void ESP8266::flush() +{ + buf_ESP8266.flush(); +} + +bool ESP8266::sendCommand(const char * cmd, const char * ack, char * res, int timeout) +{ + return true; +} + +bool ESP8266::close() +{ + return true; +} + +bool ESP8266::disconnect() +{ + // if already disconnected, return + if (!state.associated) + return true; + // send command to quit AP + // + state.associated = false; + return true; + +} + +bool ESP8266::is_connected() +{ + return true; +} + + +void ESP8266::reset() +{ + reset_pin = 0; + wait(0.2); + reset_pin = 1; + wait(0.2); +} + +bool ESP8266::reboot() +{ + return true; +} + +int ESP8266::putc(char c) +{ + while (!wifi.writeable()); + return wifi.putc(c); +} + +int ESP8266::readable() +{ + return buf_ESP8266.available(); +} + +int ESP8266::writeable() +{ + return wifi.writeable(); +} + +char ESP8266::getc() +{ + char c; + while (!buf_ESP8266.available()); + buf_ESP8266.dequeue(&c); + return c; +} + +void ESP8266::handler_rx(void) +{ + //read characters + while (wifi.readable()) + buf_ESP8266.queue(wifi.getc()); +} + +void ESP8266::attach_rx(bool callback) +{ + if (!callback) + wifi.attach(NULL); + else + wifi.attach(this, &ESP8266::handler_rx); +} + + +int ESP8266::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