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:
Sun Mar 31 03:08:45 2019 +0000
Revision:
50:f484783b8a34
Parent:
49:cac09a34102c
Child:
51:c8c727b413d9
Minor changes

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