A fork of the original interface for OS/2. Features a correctly-implemented recv (but retains the old behavior via recv2).

Dependencies:   BufferedSerial

Dependents:   weather_clock weather_clock

Committer:
alexhrao
Date:
Fri May 24 23:19:03 2019 +0000
Revision:
52:a5c7a72aa707
Parent:
51:c8c727b413d9
Child:
53:4224de23da9e
Add basic new node support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geky 44:16da10e7b3f7 1 /* Copyright (C) 2012 mbed.org, MIT License
geky 44:16da10e7b3f7 2 *
geky 44:16da10e7b3f7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
geky 44:16da10e7b3f7 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
geky 44:16da10e7b3f7 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
geky 44:16da10e7b3f7 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
geky 44:16da10e7b3f7 7 * furnished to do so, subject to the following conditions:
geky 44:16da10e7b3f7 8 *
geky 44:16da10e7b3f7 9 * The above copyright notice and this permission notice shall be included in all copies or
geky 44:16da10e7b3f7 10 * substantial portions of the Software.
geky 44:16da10e7b3f7 11 *
geky 44:16da10e7b3f7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
geky 44:16da10e7b3f7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
geky 44:16da10e7b3f7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
geky 44:16da10e7b3f7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
geky 44:16da10e7b3f7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
geky 44:16da10e7b3f7 17 */
geky 44:16da10e7b3f7 18
geky 44:16da10e7b3f7 19 #include "mbed.h"
geky 44:16da10e7b3f7 20 #include "ESP8266.h"
geky 44:16da10e7b3f7 21 #include "Endpoint.h"
geky 44:16da10e7b3f7 22 #include <string>
geky 44:16da10e7b3f7 23 #include <algorithm>
geky 44:16da10e7b3f7 24
geky 44:16da10e7b3f7 25 //Debug is disabled by default
alexhrao 51:c8c727b413d9 26 #if 0
geky 44:16da10e7b3f7 27 #define DBG(x, ...) printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
geky 44:16da10e7b3f7 28 #define WARN(x, ...) printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
geky 44:16da10e7b3f7 29 #define ERR(x, ...) printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
geky 44:16da10e7b3f7 30 #define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
geky 44:16da10e7b3f7 31 #ifndef ESP8266_ECHO
geky 44:16da10e7b3f7 32 #define ESP8266_ECHO 1
geky 44:16da10e7b3f7 33 #endif
geky 44:16da10e7b3f7 34 #else
geky 44:16da10e7b3f7 35 #define DBG(x, ...)
geky 44:16da10e7b3f7 36 #define WARN(x, ...)
geky 44:16da10e7b3f7 37 #define ERR(x, ...)
geky 44:16da10e7b3f7 38 #define INFO(x, ...)
geky 44:16da10e7b3f7 39 #endif
geky 44:16da10e7b3f7 40
alexhrao 52:a5c7a72aa707 41 #ifndef ESP8226_NEW_NODE
alexhrao 52:a5c7a72aa707 42 #define ESP8226_NEW_NODE 0
alexhrao 52:a5c7a72aa707 43 #endif
alexhrao 52:a5c7a72aa707 44
geky 44:16da10e7b3f7 45 ESP8266 *ESP8266::_inst;
geky 44:16da10e7b3f7 46
geky 44:16da10e7b3f7 47 ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, int baud, int timeout) :
geky 44:16da10e7b3f7 48 _serial(tx, rx), _reset_pin(reset) {
geky 44:16da10e7b3f7 49 INFO("Initializing ESP8266 object");
geky 44:16da10e7b3f7 50
alexhrao 51:c8c727b413d9 51 _baud = baud;
alexhrao 51:c8c727b413d9 52 _timeout = timeout;
geky 44:16da10e7b3f7 53
alexhrao 51:c8c727b413d9 54 _serial.baud(_baud);
geky 44:16da10e7b3f7 55
geky 44:16da10e7b3f7 56 _inst = this;
geky 44:16da10e7b3f7 57 }
geky 44:16da10e7b3f7 58
geky 44:16da10e7b3f7 59 bool ESP8266::reset() {
geky 44:16da10e7b3f7 60 _reset_pin = 0;
geky 44:16da10e7b3f7 61 wait_us(20);
geky 44:16da10e7b3f7 62 _reset_pin = 1;
geky 44:16da10e7b3f7 63
geky 44:16da10e7b3f7 64 // Send reboot command in case reset is not connected
geky 44:16da10e7b3f7 65 return command("\x03\r\n" "node.restart()") && execute();
geky 44:16da10e7b3f7 66 }
geky 44:16da10e7b3f7 67
geky 44:16da10e7b3f7 68 bool ESP8266::init() {
geky 44:16da10e7b3f7 69 // Reset device to clear state
geky 44:16da10e7b3f7 70 return reset();
geky 44:16da10e7b3f7 71 }
geky 44:16da10e7b3f7 72
geky 44:16da10e7b3f7 73 bool ESP8266::connect(const char *ssid, const char *phrase) {
geky 44:16da10e7b3f7 74 // Configure as station with passed ssid and passphrase
alexhrao 52:a5c7a72aa707 75 // If we're in the new lua interpreter, then this is wrong - how do we know?
alexhrao 52:a5c7a72aa707 76 // TODO: ESCAPE!!!
alexhrao 52:a5c7a72aa707 77 // Actually, we can try both...
alexhrao 52:a5c7a72aa707 78 #if ESP8226_NEW_NODE == 1
alexhrao 52:a5c7a72aa707 79 if (!(command("wifi.setmode(wifi.STATION);") &&
alexhrao 52:a5c7a72aa707 80 command("cfg={};cfg.ssid=\"") &&
alexhrao 52:a5c7a72aa707 81 command(ssid) &&
alexhrao 52:a5c7a72aa707 82 command("\";cfg.pwd=\"") &&
alexhrao 52:a5c7a72aa707 83 command(phrase) &&
alexhrao 52:a5c7a72aa707 84 command("\";wifi.sta.config(cfg)") &&
alexhrao 52:a5c7a72aa707 85 execute()))
alexhrao 52:a5c7a72aa707 86 return false;
alexhrao 52:a5c7a72aa707 87 #else
geky 44:16da10e7b3f7 88 if (!(command("wifi.setmode(wifi.STATION);") &&
alexhrao 49:cac09a34102c 89 command("wifi.sta.config(\"") &&
geky 44:16da10e7b3f7 90 command(ssid) &&
alexhrao 49:cac09a34102c 91 command("\",\"") &&
geky 44:16da10e7b3f7 92 command(phrase) &&
alexhrao 49:cac09a34102c 93 command("\")") &&
geky 44:16da10e7b3f7 94 execute()))
geky 44:16da10e7b3f7 95 return false;
alexhrao 52:a5c7a72aa707 96 #endif
geky 44:16da10e7b3f7 97 // Wait for an IP address
geky 44:16da10e7b3f7 98 // TODO WISHLIST make this a seperate check so it can run asynch?
geky 44:16da10e7b3f7 99 Timer timer;
geky 44:16da10e7b3f7 100 timer.start();
alexhrao 49:cac09a34102c 101
geky 44:16da10e7b3f7 102 while (true) {
geky 44:16da10e7b3f7 103 int ip_len = 15;
geky 44:16da10e7b3f7 104
geky 44:16da10e7b3f7 105 if (!(command("ip=wifi.sta.getip();") &&
geky 44:16da10e7b3f7 106 command("print(ip)") &&
geky 44:16da10e7b3f7 107 execute(_ip, &ip_len)))
geky 44:16da10e7b3f7 108 return false;
geky 44:16da10e7b3f7 109
geky 44:16da10e7b3f7 110 _ip[ip_len] = 0;
geky 44:16da10e7b3f7 111
geky 44:16da10e7b3f7 112 if (strcmp(_ip, "nil") != 0)
geky 44:16da10e7b3f7 113 return true;
geky 44:16da10e7b3f7 114
geky 44:16da10e7b3f7 115 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 116 return false;
geky 44:16da10e7b3f7 117 }
geky 44:16da10e7b3f7 118 }
geky 44:16da10e7b3f7 119
geky 44:16da10e7b3f7 120 bool ESP8266::disconnect() {
geky 44:16da10e7b3f7 121 int ip_len = 15;
geky 44:16da10e7b3f7 122
geky 44:16da10e7b3f7 123 if (!(command("wifi.sta.disconnect();") &&
geky 44:16da10e7b3f7 124 command("ip=wifi.sta.getip();") &&
geky 44:16da10e7b3f7 125 command("print(ip)") &&
geky 44:16da10e7b3f7 126 execute(_ip, &ip_len)))
geky 44:16da10e7b3f7 127 return false;
geky 44:16da10e7b3f7 128
geky 44:16da10e7b3f7 129 _ip[ip_len] = 0;
geky 44:16da10e7b3f7 130
geky 44:16da10e7b3f7 131 return (strcmp(_ip, "nil") == 0);
geky 44:16da10e7b3f7 132 }
geky 44:16da10e7b3f7 133
geky 44:16da10e7b3f7 134 bool ESP8266::is_connected() {
geky 44:16da10e7b3f7 135 return (strcmp(_ip, "nil") != 0);
geky 44:16da10e7b3f7 136 }
geky 44:16da10e7b3f7 137
geky 44:16da10e7b3f7 138 bool ESP8266::open(bool type, char* ip, int port, int id) {
geky 44:16da10e7b3f7 139 // Create the actual connection
geky 44:16da10e7b3f7 140 if (!(command("c=net.createConnection(") &&
geky 44:16da10e7b3f7 141 command(type ? "net.TCP" : "net.UDP") &&
geky 44:16da10e7b3f7 142 command(")") &&
geky 44:16da10e7b3f7 143 execute()))
geky 44:16da10e7b3f7 144 return false;
geky 44:16da10e7b3f7 145
geky 44:16da10e7b3f7 146 // Setup handlers for connecting and disconnecting
geky 44:16da10e7b3f7 147 if (!(command("cc=nil;") &&
geky 44:16da10e7b3f7 148 command("c:on('connection',function() cc=true end);") &&
geky 44:16da10e7b3f7 149 command("c:on('disconnection',function() cc=false end)") &&
geky 44:16da10e7b3f7 150 execute()))
geky 44:16da10e7b3f7 151 return false;
geky 44:16da10e7b3f7 152
geky 44:16da10e7b3f7 153 // Setup functions for sending and recieving characters on the esp side
geky 44:16da10e7b3f7 154 if (!(command("cm='';") &&
alexhrao 49:cac09a34102c 155 command("function cs(n) c:send(n); end;") &&
geky 44:16da10e7b3f7 156 command("function ca() print(#cm) end;") &&
geky 45:3cfb7406d993 157 command("function cr(n) "
geky 45:3cfb7406d993 158 "d=cm:sub(1,n):gsub('.', function(s) "
geky 45:3cfb7406d993 159 "return s.format('\\\\%03d', s:byte(1)) "
geky 45:3cfb7406d993 160 "end);"
alexhrao 49:cac09a34102c 161 "cm=cm:sub(n+1,-1); "
geky 45:3cfb7406d993 162 "print(d) "
geky 45:3cfb7406d993 163 "end;") &&
alexhrao 49:cac09a34102c 164 command("c:on('receive',function(c,n) "
alexhrao 49:cac09a34102c 165 "cm=cm..n "
alexhrao 49:cac09a34102c 166 "end)") &&
geky 44:16da10e7b3f7 167 execute()))
geky 44:16da10e7b3f7 168 return false;
geky 44:16da10e7b3f7 169
geky 44:16da10e7b3f7 170 // Convert port to a string
geky 44:16da10e7b3f7 171 char port_buf[16];
geky 44:16da10e7b3f7 172 sprintf(port_buf, "%d", port);
geky 44:16da10e7b3f7 173
geky 44:16da10e7b3f7 174 // Connect to the ip address
geky 44:16da10e7b3f7 175 if (!(command("c:connect(") &&
geky 44:16da10e7b3f7 176 command(port_buf) &&
geky 44:16da10e7b3f7 177 command(",'") &&
geky 44:16da10e7b3f7 178 command(ip) &&
geky 44:16da10e7b3f7 179 command("')") &&
geky 44:16da10e7b3f7 180 execute()))
geky 44:16da10e7b3f7 181 return false;
geky 44:16da10e7b3f7 182
geky 44:16da10e7b3f7 183 // Wait for it to connect
geky 44:16da10e7b3f7 184 // TODO WISHLIST make this a seperate check so it can run asynch?
geky 44:16da10e7b3f7 185 Timer timer;
geky 44:16da10e7b3f7 186 timer.start();
geky 44:16da10e7b3f7 187
geky 44:16da10e7b3f7 188 while (true) {
geky 44:16da10e7b3f7 189 char con_buf[5];
geky 44:16da10e7b3f7 190 int con_len = 5;
geky 44:16da10e7b3f7 191
geky 44:16da10e7b3f7 192 if (!(command("print(cc)") && execute(con_buf, &con_len)))
geky 44:16da10e7b3f7 193 return false;
geky 44:16da10e7b3f7 194
alexhrao 49:cac09a34102c 195 if (memcmp(con_buf, "true", con_len) == 0) {
geky 44:16da10e7b3f7 196 return true;
alexhrao 49:cac09a34102c 197 }
geky 44:16da10e7b3f7 198 else if (memcmp(con_buf, "false", con_len) == 0)
geky 44:16da10e7b3f7 199 return false;
geky 44:16da10e7b3f7 200
geky 44:16da10e7b3f7 201 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 202 return false;
geky 44:16da10e7b3f7 203 }
geky 44:16da10e7b3f7 204 }
geky 44:16da10e7b3f7 205
geky 44:16da10e7b3f7 206 bool ESP8266::close() {
geky 44:16da10e7b3f7 207 return command("c:close();" "c=nil") && execute();
geky 44:16da10e7b3f7 208 }
geky 44:16da10e7b3f7 209
geky 46:4abb80f0a920 210 bool ESP8266::send(const char *buffer, int len) {
geky 46:4abb80f0a920 211 for (int line = 0; line < len; line += ESP_MAX_LINE) {
geky 46:4abb80f0a920 212 if (!command("cs('"))
geky 46:4abb80f0a920 213 return false;
geky 47:04632d22a723 214
geky 46:4abb80f0a920 215 for (int i = 0; i < ESP_MAX_LINE && line+i < len; i++) {
geky 46:4abb80f0a920 216 int a = buffer[line+i] / 100;
geky 46:4abb80f0a920 217 int b = (buffer[line+i] - a*100) / 10;
geky 46:4abb80f0a920 218 int c = (buffer[line+i] - a*100 - b*10);
geky 46:4abb80f0a920 219
geky 46:4abb80f0a920 220 if (serialputc('\\') < 0 ||
geky 46:4abb80f0a920 221 serialputc(a + '0') < 0 ||
geky 46:4abb80f0a920 222 serialputc(b + '0') < 0 ||
geky 46:4abb80f0a920 223 serialputc(c + '0') < 0)
geky 46:4abb80f0a920 224 return false;
geky 46:4abb80f0a920 225 }
geky 46:4abb80f0a920 226 if (!(command("')") && execute()))
geky 45:3cfb7406d993 227 return false;
alexhrao 49:cac09a34102c 228
geky 45:3cfb7406d993 229 }
geky 44:16da10e7b3f7 230 return true;
geky 44:16da10e7b3f7 231 }
geky 44:16da10e7b3f7 232
alexhrao 50:f484783b8a34 233 int ESP8266::recv(char* buffer, int len, int offset=0) {
alexhrao 49:cac09a34102c 234 // start at offset, read at most LEN bytes
alexhrao 49:cac09a34102c 235 // first make sure we have that many bytes to read!
alexhrao 49:cac09a34102c 236
alexhrao 49:cac09a34102c 237 // Get total number of bytes
alexhrao 49:cac09a34102c 238 char num_buf[16];
alexhrao 49:cac09a34102c 239 int num_i = 0;
alexhrao 49:cac09a34102c 240 char cmd[128];
alexhrao 49:cac09a34102c 241
alexhrao 49:cac09a34102c 242 sprintf(cmd, "print(#cm)\r\n");
alexhrao 49:cac09a34102c 243 command(cmd);
alexhrao 49:cac09a34102c 244
alexhrao 49:cac09a34102c 245 // cleanup
alexhrao 49:cac09a34102c 246 while ((serialgetc() != '\n'));
alexhrao 49:cac09a34102c 247
alexhrao 49:cac09a34102c 248 // Get number
alexhrao 49:cac09a34102c 249 while (char tmp = serialgetc()) {
alexhrao 49:cac09a34102c 250 if (tmp == '\r') {
alexhrao 49:cac09a34102c 251 serialgetc();
alexhrao 49:cac09a34102c 252 break;
alexhrao 49:cac09a34102c 253 }
alexhrao 49:cac09a34102c 254 num_buf[num_i++] = tmp;
alexhrao 49:cac09a34102c 255 }
alexhrao 49:cac09a34102c 256 num_buf[num_i] = '\0';
alexhrao 49:cac09a34102c 257
alexhrao 49:cac09a34102c 258 // now we can get number
alexhrao 49:cac09a34102c 259 int resp_len = atoi(num_buf);
alexhrao 49:cac09a34102c 260 if (offset >= resp_len) {
alexhrao 49:cac09a34102c 261 // Can't read anything!
alexhrao 49:cac09a34102c 262 return -1;
alexhrao 49:cac09a34102c 263 }
alexhrao 49:cac09a34102c 264 if ((offset + len) > resp_len) {
alexhrao 49:cac09a34102c 265 len = resp_len - offset;
alexhrao 49:cac09a34102c 266 }
alexhrao 49:cac09a34102c 267 // we're good
alexhrao 49:cac09a34102c 268 sprintf(cmd, "print(cm:sub(%d, %d))\r\n", offset + 1, offset + len);
alexhrao 49:cac09a34102c 269 command(cmd);
alexhrao 49:cac09a34102c 270
alexhrao 49:cac09a34102c 271 // cleanup
alexhrao 49:cac09a34102c 272 while ((serialgetc() != '\n'));
alexhrao 49:cac09a34102c 273
alexhrao 49:cac09a34102c 274 // Read Data
alexhrao 49:cac09a34102c 275 for (int i = 0; i < len; i++) {
alexhrao 49:cac09a34102c 276 buffer[i] = serialgetc();
alexhrao 49:cac09a34102c 277 }
alexhrao 49:cac09a34102c 278 // Will be two more characters to clean up, but NOT PART OF DATA
alexhrao 49:cac09a34102c 279 serialgetc();
alexhrao 49:cac09a34102c 280 serialgetc();
alexhrao 49:cac09a34102c 281
alexhrao 49:cac09a34102c 282 return len;
alexhrao 49:cac09a34102c 283 }
alexhrao 49:cac09a34102c 284 bool ESP8266::recv2(char *buffer, int *len) {
geky 44:16da10e7b3f7 285 char len_buf[16];
geky 44:16da10e7b3f7 286 sprintf(len_buf, "%d", *len);
geky 44:16da10e7b3f7 287
alexhrao 50:f484783b8a34 288 if (!(command("cr(") &&
alexhrao 50:f484783b8a34 289 command(len_buf) &&
alexhrao 50:f484783b8a34 290 command(")")))
alexhrao 50:f484783b8a34 291 return false;
geky 45:3cfb7406d993 292
geky 45:3cfb7406d993 293 if (!(command("\r\n") && discardEcho()))
geky 44:16da10e7b3f7 294 return false;
geky 45:3cfb7406d993 295
geky 45:3cfb7406d993 296 // Read in response
geky 45:3cfb7406d993 297 for (int i = 0; i < *len; i++) {
geky 45:3cfb7406d993 298 int e = serialgetc();
geky 45:3cfb7406d993 299
geky 45:3cfb7406d993 300 if (e == '\r') {
geky 45:3cfb7406d993 301 *len = i;
geky 45:3cfb7406d993 302 break;
geky 45:3cfb7406d993 303 } else if (e != '\\') {
geky 45:3cfb7406d993 304 return false;
geky 45:3cfb7406d993 305 }
geky 45:3cfb7406d993 306
geky 45:3cfb7406d993 307 int a = serialgetc();
geky 45:3cfb7406d993 308 int b = serialgetc();
geky 45:3cfb7406d993 309 int c = serialgetc();
geky 45:3cfb7406d993 310
geky 45:3cfb7406d993 311 if (a < 0 || b < 0 || c < 0)
geky 45:3cfb7406d993 312 return false;
geky 45:3cfb7406d993 313
geky 45:3cfb7406d993 314 buffer[i] = (a-'0')*100 + (b-'0')*10 + (c-'0');
geky 45:3cfb7406d993 315 }
alexhrao 50:f484783b8a34 316
geky 45:3cfb7406d993 317 // Flush to next prompt
geky 45:3cfb7406d993 318 return flush();
geky 44:16da10e7b3f7 319 }
geky 44:16da10e7b3f7 320
geky 44:16da10e7b3f7 321 int ESP8266::putc(char c) {
geky 44:16da10e7b3f7 322 char buffer[1] = { c };
geky 44:16da10e7b3f7 323
geky 44:16da10e7b3f7 324 return send(buffer, 1) ? 0 : -1;
geky 44:16da10e7b3f7 325 }
geky 44:16da10e7b3f7 326
geky 44:16da10e7b3f7 327 int ESP8266::getc() {
geky 44:16da10e7b3f7 328 char buffer[1];
geky 44:16da10e7b3f7 329
geky 44:16da10e7b3f7 330 while (true) {
geky 44:16da10e7b3f7 331 int len = 1;
geky 44:16da10e7b3f7 332
alexhrao 50:f484783b8a34 333 if (!recv2(buffer, &len))
geky 44:16da10e7b3f7 334 return -1;
geky 44:16da10e7b3f7 335
geky 44:16da10e7b3f7 336 if (len > 0)
geky 44:16da10e7b3f7 337 break;
geky 44:16da10e7b3f7 338 }
geky 44:16da10e7b3f7 339
geky 44:16da10e7b3f7 340 return buffer[0];
geky 44:16da10e7b3f7 341 }
geky 44:16da10e7b3f7 342
geky 44:16da10e7b3f7 343 int ESP8266::writeable() {
geky 44:16da10e7b3f7 344 // Always succeeds since message can be temporarily stored on the esp
geky 44:16da10e7b3f7 345 return 1;
geky 44:16da10e7b3f7 346 }
geky 44:16da10e7b3f7 347
geky 44:16da10e7b3f7 348 int ESP8266::readable() {
geky 44:16da10e7b3f7 349 char count_buf[16];
geky 44:16da10e7b3f7 350 int count_len = 15;
geky 44:16da10e7b3f7 351
geky 44:16da10e7b3f7 352 if (!(command("ca()") && execute(count_buf, &count_len)))
geky 44:16da10e7b3f7 353 return false;
geky 44:16da10e7b3f7 354
geky 44:16da10e7b3f7 355 count_buf[count_len] = 0;
geky 44:16da10e7b3f7 356 return atoi(count_buf);
geky 44:16da10e7b3f7 357 }
geky 44:16da10e7b3f7 358
geky 44:16da10e7b3f7 359 const char *ESP8266::getIPAddress() {
geky 44:16da10e7b3f7 360 if (strcmp(_ip, "nil") != 0)
geky 44:16da10e7b3f7 361 return _ip;
geky 44:16da10e7b3f7 362 else
geky 44:16da10e7b3f7 363 return 0;
geky 44:16da10e7b3f7 364 }
geky 44:16da10e7b3f7 365
geky 44:16da10e7b3f7 366 bool ESP8266::getHostByName(const char *host, char *ip) {
geky 44:16da10e7b3f7 367 if (!(command("dh='") &&
geky 44:16da10e7b3f7 368 command(host) &&
geky 44:16da10e7b3f7 369 command("';") &&
geky 44:16da10e7b3f7 370 command("dn=nil;") &&
geky 44:16da10e7b3f7 371 command("if dh:match('%d+.%d+.%d+.%d+') then ") &&
geky 44:16da10e7b3f7 372 command("dn=dh ") &&
geky 44:16da10e7b3f7 373 command("else ") &&
geky 44:16da10e7b3f7 374 command("dc=net.createConnection(net.TCP);") &&
geky 44:16da10e7b3f7 375 command("dc:dns(dh,function(dc,ip) dn=ip end);") &&
geky 44:16da10e7b3f7 376 command("dc=nil ") &&
geky 44:16da10e7b3f7 377 command("end") &&
geky 44:16da10e7b3f7 378 execute()))
geky 44:16da10e7b3f7 379 return false;
geky 44:16da10e7b3f7 380
geky 44:16da10e7b3f7 381 // Wait for a response
geky 44:16da10e7b3f7 382 Timer timer;
geky 44:16da10e7b3f7 383 timer.start();
geky 44:16da10e7b3f7 384
geky 44:16da10e7b3f7 385 while (true) {
geky 44:16da10e7b3f7 386 int ip_len = 15;
geky 44:16da10e7b3f7 387
geky 44:16da10e7b3f7 388 if (!(command("print(dn)") && execute(ip, &ip_len)))
geky 44:16da10e7b3f7 389 return false;
geky 44:16da10e7b3f7 390
geky 44:16da10e7b3f7 391 ip[ip_len] = 0;
geky 44:16da10e7b3f7 392
geky 44:16da10e7b3f7 393 if (strcmp(ip, "nil") != 0)
geky 44:16da10e7b3f7 394 return true;
geky 44:16da10e7b3f7 395
geky 44:16da10e7b3f7 396 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 397 return false;
geky 44:16da10e7b3f7 398 }
geky 44:16da10e7b3f7 399 }
geky 44:16da10e7b3f7 400
geky 44:16da10e7b3f7 401 int ESP8266::serialgetc() {
geky 44:16da10e7b3f7 402 Timer timer;
alexhrao 49:cac09a34102c 403
geky 44:16da10e7b3f7 404 timer.start();
geky 44:16da10e7b3f7 405
geky 44:16da10e7b3f7 406 while (true) {
geky 44:16da10e7b3f7 407 if (_serial.readable()) {
geky 44:16da10e7b3f7 408 char c = _serial.getc();
geky 44:16da10e7b3f7 409 #ifdef ESP8266_ECHO
alexhrao 49:cac09a34102c 410 // tmp_buf[tmp_buf_ind++ % 8192] = c;
geky 44:16da10e7b3f7 411 printf("%c", c);
geky 44:16da10e7b3f7 412 #endif
geky 44:16da10e7b3f7 413 return c;
geky 44:16da10e7b3f7 414 }
geky 44:16da10e7b3f7 415
geky 44:16da10e7b3f7 416 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 417 return -1;
geky 44:16da10e7b3f7 418 }
geky 44:16da10e7b3f7 419 }
geky 44:16da10e7b3f7 420
geky 44:16da10e7b3f7 421 int ESP8266::serialputc(char c) {
geky 44:16da10e7b3f7 422 Timer timer;
geky 44:16da10e7b3f7 423 timer.start();
geky 44:16da10e7b3f7 424
geky 44:16da10e7b3f7 425 while (true) {
geky 44:16da10e7b3f7 426 if (_serial.writeable())
geky 44:16da10e7b3f7 427 return _serial.putc(c);
geky 44:16da10e7b3f7 428
geky 44:16da10e7b3f7 429 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 430 return -1;
geky 44:16da10e7b3f7 431 }
geky 44:16da10e7b3f7 432 }
geky 44:16da10e7b3f7 433
geky 44:16da10e7b3f7 434 bool ESP8266::discardEcho() {
geky 44:16da10e7b3f7 435 while (true) {
geky 44:16da10e7b3f7 436 int c = serialgetc();
geky 44:16da10e7b3f7 437
geky 44:16da10e7b3f7 438 if (c < 0)
geky 44:16da10e7b3f7 439 return false;
geky 45:3cfb7406d993 440 else if (c == '\n')
geky 45:3cfb7406d993 441 return true;
geky 45:3cfb7406d993 442 }
geky 45:3cfb7406d993 443 }
geky 45:3cfb7406d993 444
geky 45:3cfb7406d993 445 bool ESP8266::flush() {
geky 45:3cfb7406d993 446 while (true) {
geky 45:3cfb7406d993 447 int c = serialgetc();
geky 45:3cfb7406d993 448
geky 45:3cfb7406d993 449 if (c < 0)
geky 45:3cfb7406d993 450 return false;
geky 44:16da10e7b3f7 451 else if (c == '>')
geky 44:16da10e7b3f7 452 return true;
geky 44:16da10e7b3f7 453 }
geky 44:16da10e7b3f7 454 }
geky 44:16da10e7b3f7 455
geky 44:16da10e7b3f7 456 bool ESP8266::command(const char *cmd) {
alexhrao 49:cac09a34102c 457 //DBG("command sent:\t %s", cmd);
geky 44:16da10e7b3f7 458
geky 44:16da10e7b3f7 459 for (int i = 0; cmd[i]; i++) {
geky 44:16da10e7b3f7 460 if (serialputc(cmd[i]) < 0)
geky 44:16da10e7b3f7 461 return false;
geky 44:16da10e7b3f7 462 }
geky 44:16da10e7b3f7 463
geky 44:16da10e7b3f7 464 return true;
geky 45:3cfb7406d993 465 }
geky 44:16da10e7b3f7 466
geky 44:16da10e7b3f7 467 bool ESP8266::execute(char *resp_buf, int *resp_len) {
geky 44:16da10e7b3f7 468 // Finish command with a newline
geky 45:3cfb7406d993 469 if (!(command("\r\n") && discardEcho()))
geky 44:16da10e7b3f7 470 return false;
geky 44:16da10e7b3f7 471
geky 44:16da10e7b3f7 472 // Read in response if any
geky 44:16da10e7b3f7 473 if (resp_buf && resp_len) {
geky 44:16da10e7b3f7 474 int i;
geky 44:16da10e7b3f7 475
geky 44:16da10e7b3f7 476 for (i = 0; i < *resp_len; i++) {
geky 44:16da10e7b3f7 477 int c = serialgetc();
geky 44:16da10e7b3f7 478
geky 44:16da10e7b3f7 479 if (c < 0)
geky 44:16da10e7b3f7 480 return false;
geky 44:16da10e7b3f7 481
geky 44:16da10e7b3f7 482 if (c == '\r') {
geky 44:16da10e7b3f7 483 *resp_len = i;
geky 44:16da10e7b3f7 484 break;
geky 44:16da10e7b3f7 485 }
geky 44:16da10e7b3f7 486
geky 44:16da10e7b3f7 487 resp_buf[i] = c;
geky 44:16da10e7b3f7 488 }
geky 44:16da10e7b3f7 489
alexhrao 49:cac09a34102c 490 //DBG("command response:\t %.*s", *resp_len, resp_buf);
geky 44:16da10e7b3f7 491 }
geky 44:16da10e7b3f7 492
geky 45:3cfb7406d993 493 return flush();
geky 44:16da10e7b3f7 494 }