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:
geky
Date:
Thu Jun 04 20:18:39 2015 +0000
Revision:
47:04632d22a723
Parent:
46:4abb80f0a920
Parent:
45:3cfb7406d993
Child:
49:cac09a34102c
Merged rev 46/45

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