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