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 19:26:35 2015 +0000
Revision:
45:3cfb7406d993
Parent:
44:16da10e7b3f7
Child:
47:04632d22a723
Sanitized both transmitted and recieved strings

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 44:16da10e7b3f7 191 bool ESP8266::send(const char *buffer, int len) {
geky 45:3cfb7406d993 192 if (!command("cs('"))
geky 45:3cfb7406d993 193 return false;
geky 45:3cfb7406d993 194
geky 45:3cfb7406d993 195 for (int i = 0; i < len; i++) {
geky 45:3cfb7406d993 196 int a = buffer[i] / 100;
geky 45:3cfb7406d993 197 int b = (buffer[i] - a*100) / 10;
geky 45:3cfb7406d993 198 int c = (buffer[i] - a*100 - b*10);
geky 45:3cfb7406d993 199
geky 45:3cfb7406d993 200 if (serialputc('\\') < 0 ||
geky 45:3cfb7406d993 201 serialputc(a + '0') < 0 ||
geky 45:3cfb7406d993 202 serialputc(b + '0') < 0 ||
geky 45:3cfb7406d993 203 serialputc(c + '0') < 0)
geky 45:3cfb7406d993 204 return false;
geky 45:3cfb7406d993 205 }
geky 45:3cfb7406d993 206
geky 45:3cfb7406d993 207 if (!(command("')") && execute()))
geky 44:16da10e7b3f7 208 return false;
geky 44:16da10e7b3f7 209
geky 44:16da10e7b3f7 210 return true;
geky 44:16da10e7b3f7 211 }
geky 44:16da10e7b3f7 212
geky 44:16da10e7b3f7 213 bool ESP8266::recv(char *buffer, int *len) {
geky 44:16da10e7b3f7 214 char len_buf[16];
geky 44:16da10e7b3f7 215 sprintf(len_buf, "%d", *len);
geky 44:16da10e7b3f7 216
geky 44:16da10e7b3f7 217 if (!(command("cr(") &&
geky 44:16da10e7b3f7 218 command(len_buf) &&
geky 45:3cfb7406d993 219 command(")")))
geky 45:3cfb7406d993 220 return false;
geky 45:3cfb7406d993 221
geky 45:3cfb7406d993 222 if (!(command("\r\n") && discardEcho()))
geky 44:16da10e7b3f7 223 return false;
geky 45:3cfb7406d993 224
geky 45:3cfb7406d993 225 // Read in response
geky 45:3cfb7406d993 226 for (int i = 0; i < *len; i++) {
geky 45:3cfb7406d993 227 int e = serialgetc();
geky 45:3cfb7406d993 228
geky 45:3cfb7406d993 229 if (e == '\r') {
geky 45:3cfb7406d993 230 *len = i;
geky 45:3cfb7406d993 231 break;
geky 45:3cfb7406d993 232 } else if (e != '\\') {
geky 45:3cfb7406d993 233 return false;
geky 45:3cfb7406d993 234 }
geky 45:3cfb7406d993 235
geky 45:3cfb7406d993 236 int a = serialgetc();
geky 45:3cfb7406d993 237 int b = serialgetc();
geky 45:3cfb7406d993 238 int c = serialgetc();
geky 45:3cfb7406d993 239
geky 45:3cfb7406d993 240 if (a < 0 || b < 0 || c < 0)
geky 45:3cfb7406d993 241 return false;
geky 45:3cfb7406d993 242
geky 45:3cfb7406d993 243 buffer[i] = (a-'0')*100 + (b-'0')*10 + (c-'0');
geky 45:3cfb7406d993 244 }
geky 44:16da10e7b3f7 245
geky 45:3cfb7406d993 246 // Flush to next prompt
geky 45:3cfb7406d993 247 return flush();
geky 44:16da10e7b3f7 248 }
geky 44:16da10e7b3f7 249
geky 44:16da10e7b3f7 250 int ESP8266::putc(char c) {
geky 44:16da10e7b3f7 251 char buffer[1] = { c };
geky 44:16da10e7b3f7 252
geky 44:16da10e7b3f7 253 return send(buffer, 1) ? 0 : -1;
geky 44:16da10e7b3f7 254 }
geky 44:16da10e7b3f7 255
geky 44:16da10e7b3f7 256 int ESP8266::getc() {
geky 44:16da10e7b3f7 257 char buffer[1];
geky 44:16da10e7b3f7 258
geky 44:16da10e7b3f7 259 while (true) {
geky 44:16da10e7b3f7 260 int len = 1;
geky 44:16da10e7b3f7 261
geky 44:16da10e7b3f7 262 if (!recv(buffer, &len))
geky 44:16da10e7b3f7 263 return -1;
geky 44:16da10e7b3f7 264
geky 44:16da10e7b3f7 265 if (len > 0)
geky 44:16da10e7b3f7 266 break;
geky 44:16da10e7b3f7 267 }
geky 44:16da10e7b3f7 268
geky 44:16da10e7b3f7 269 return buffer[0];
geky 44:16da10e7b3f7 270 }
geky 44:16da10e7b3f7 271
geky 44:16da10e7b3f7 272 int ESP8266::writeable() {
geky 44:16da10e7b3f7 273 // Always succeeds since message can be temporarily stored on the esp
geky 44:16da10e7b3f7 274 return 1;
geky 44:16da10e7b3f7 275 }
geky 44:16da10e7b3f7 276
geky 44:16da10e7b3f7 277 int ESP8266::readable() {
geky 44:16da10e7b3f7 278 char count_buf[16];
geky 44:16da10e7b3f7 279 int count_len = 15;
geky 44:16da10e7b3f7 280
geky 44:16da10e7b3f7 281 if (!(command("ca()") && execute(count_buf, &count_len)))
geky 44:16da10e7b3f7 282 return false;
geky 44:16da10e7b3f7 283
geky 44:16da10e7b3f7 284 count_buf[count_len] = 0;
geky 44:16da10e7b3f7 285 return atoi(count_buf);
geky 44:16da10e7b3f7 286 }
geky 44:16da10e7b3f7 287
geky 44:16da10e7b3f7 288 const char *ESP8266::getIPAddress() {
geky 44:16da10e7b3f7 289 if (strcmp(_ip, "nil") != 0)
geky 44:16da10e7b3f7 290 return _ip;
geky 44:16da10e7b3f7 291 else
geky 44:16da10e7b3f7 292 return 0;
geky 44:16da10e7b3f7 293 }
geky 44:16da10e7b3f7 294
geky 44:16da10e7b3f7 295 bool ESP8266::getHostByName(const char *host, char *ip) {
geky 44:16da10e7b3f7 296 if (!(command("dh='") &&
geky 44:16da10e7b3f7 297 command(host) &&
geky 44:16da10e7b3f7 298 command("';") &&
geky 44:16da10e7b3f7 299 command("dn=nil;") &&
geky 44:16da10e7b3f7 300 command("if dh:match('%d+.%d+.%d+.%d+') then ") &&
geky 44:16da10e7b3f7 301 command("dn=dh ") &&
geky 44:16da10e7b3f7 302 command("else ") &&
geky 44:16da10e7b3f7 303 command("dc=net.createConnection(net.TCP);") &&
geky 44:16da10e7b3f7 304 command("dc:dns(dh,function(dc,ip) dn=ip end);") &&
geky 44:16da10e7b3f7 305 command("dc=nil ") &&
geky 44:16da10e7b3f7 306 command("end") &&
geky 44:16da10e7b3f7 307 execute()))
geky 44:16da10e7b3f7 308 return false;
geky 44:16da10e7b3f7 309
geky 44:16da10e7b3f7 310 // Wait for a response
geky 44:16da10e7b3f7 311 Timer timer;
geky 44:16da10e7b3f7 312 timer.start();
geky 44:16da10e7b3f7 313
geky 44:16da10e7b3f7 314 while (true) {
geky 44:16da10e7b3f7 315 int ip_len = 15;
geky 44:16da10e7b3f7 316
geky 44:16da10e7b3f7 317 if (!(command("print(dn)") && execute(ip, &ip_len)))
geky 44:16da10e7b3f7 318 return false;
geky 44:16da10e7b3f7 319
geky 44:16da10e7b3f7 320 ip[ip_len] = 0;
geky 44:16da10e7b3f7 321
geky 44:16da10e7b3f7 322 if (strcmp(ip, "nil") != 0)
geky 44:16da10e7b3f7 323 return true;
geky 44:16da10e7b3f7 324
geky 44:16da10e7b3f7 325 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 326 return false;
geky 44:16da10e7b3f7 327 }
geky 44:16da10e7b3f7 328 }
geky 44:16da10e7b3f7 329
geky 44:16da10e7b3f7 330 int ESP8266::serialgetc() {
geky 44:16da10e7b3f7 331 Timer timer;
geky 44:16da10e7b3f7 332 timer.start();
geky 44:16da10e7b3f7 333
geky 44:16da10e7b3f7 334 while (true) {
geky 44:16da10e7b3f7 335 if (_serial.readable()) {
geky 44:16da10e7b3f7 336 char c = _serial.getc();
geky 44:16da10e7b3f7 337 #ifdef ESP8266_ECHO
geky 44:16da10e7b3f7 338 printf("%c", c);
geky 44:16da10e7b3f7 339 #endif
geky 44:16da10e7b3f7 340 return c;
geky 44:16da10e7b3f7 341 }
geky 44:16da10e7b3f7 342
geky 44:16da10e7b3f7 343 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 344 return -1;
geky 44:16da10e7b3f7 345 }
geky 44:16da10e7b3f7 346 }
geky 44:16da10e7b3f7 347
geky 44:16da10e7b3f7 348 int ESP8266::serialputc(char c) {
geky 44:16da10e7b3f7 349 Timer timer;
geky 44:16da10e7b3f7 350 timer.start();
geky 44:16da10e7b3f7 351
geky 44:16da10e7b3f7 352 while (true) {
geky 44:16da10e7b3f7 353 if (_serial.writeable())
geky 44:16da10e7b3f7 354 return _serial.putc(c);
geky 44:16da10e7b3f7 355
geky 44:16da10e7b3f7 356 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 357 return -1;
geky 44:16da10e7b3f7 358 }
geky 44:16da10e7b3f7 359 }
geky 44:16da10e7b3f7 360
geky 44:16da10e7b3f7 361 bool ESP8266::discardEcho() {
geky 44:16da10e7b3f7 362 while (true) {
geky 44:16da10e7b3f7 363 int c = serialgetc();
geky 44:16da10e7b3f7 364
geky 44:16da10e7b3f7 365 if (c < 0)
geky 44:16da10e7b3f7 366 return false;
geky 45:3cfb7406d993 367 else if (c == '\n')
geky 45:3cfb7406d993 368 return true;
geky 45:3cfb7406d993 369 }
geky 45:3cfb7406d993 370 }
geky 45:3cfb7406d993 371
geky 45:3cfb7406d993 372 bool ESP8266::flush() {
geky 45:3cfb7406d993 373 while (true) {
geky 45:3cfb7406d993 374 int c = serialgetc();
geky 45:3cfb7406d993 375
geky 45:3cfb7406d993 376 if (c < 0)
geky 45:3cfb7406d993 377 return false;
geky 44:16da10e7b3f7 378 else if (c == '>')
geky 44:16da10e7b3f7 379 return true;
geky 44:16da10e7b3f7 380 }
geky 44:16da10e7b3f7 381 }
geky 44:16da10e7b3f7 382
geky 44:16da10e7b3f7 383 bool ESP8266::command(const char *cmd) {
geky 44:16da10e7b3f7 384 DBG("command sent:\t %s", cmd);
geky 44:16da10e7b3f7 385
geky 44:16da10e7b3f7 386 for (int i = 0; cmd[i]; i++) {
geky 44:16da10e7b3f7 387 if (serialputc(cmd[i]) < 0)
geky 44:16da10e7b3f7 388 return false;
geky 44:16da10e7b3f7 389 }
geky 44:16da10e7b3f7 390
geky 44:16da10e7b3f7 391 return true;
geky 45:3cfb7406d993 392 }
geky 44:16da10e7b3f7 393
geky 44:16da10e7b3f7 394 bool ESP8266::execute(char *resp_buf, int *resp_len) {
geky 44:16da10e7b3f7 395 // Finish command with a newline
geky 45:3cfb7406d993 396 if (!(command("\r\n") && discardEcho()))
geky 44:16da10e7b3f7 397 return false;
geky 44:16da10e7b3f7 398
geky 44:16da10e7b3f7 399 // Read in response if any
geky 44:16da10e7b3f7 400 if (resp_buf && resp_len) {
geky 44:16da10e7b3f7 401 int i;
geky 44:16da10e7b3f7 402
geky 44:16da10e7b3f7 403 for (i = 0; i < *resp_len; i++) {
geky 44:16da10e7b3f7 404 int c = serialgetc();
geky 44:16da10e7b3f7 405
geky 44:16da10e7b3f7 406 if (c < 0)
geky 44:16da10e7b3f7 407 return false;
geky 44:16da10e7b3f7 408
geky 44:16da10e7b3f7 409 if (c == '\r') {
geky 44:16da10e7b3f7 410 *resp_len = i;
geky 44:16da10e7b3f7 411 break;
geky 44:16da10e7b3f7 412 }
geky 44:16da10e7b3f7 413
geky 44:16da10e7b3f7 414 resp_buf[i] = c;
geky 44:16da10e7b3f7 415 }
geky 44:16da10e7b3f7 416
geky 44:16da10e7b3f7 417 DBG("command response:\t %.*s", *resp_len, resp_buf);
geky 44:16da10e7b3f7 418 }
geky 44:16da10e7b3f7 419
geky 45:3cfb7406d993 420 return flush();
geky 44:16da10e7b3f7 421 }