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:
Wed Jun 03 21:44:20 2015 +0000
Revision:
44:16da10e7b3f7
Parent:
35:22d30e936e4c
Child:
45:3cfb7406d993
Child:
46:4abb80f0a920
Reimplemented ESP8266 driver using the Nodemcu firmware

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 cr(n) print(cm:sub(1,n)); cm=cm:sub(n+1,-1) end;") &&
geky 44:16da10e7b3f7 141 command("function ca() print(#cm) end;") &&
geky 44:16da10e7b3f7 142 command("c:on('receive',function(c,n) cm=cm..n end)") &&
geky 44:16da10e7b3f7 143 execute()))
geky 44:16da10e7b3f7 144 return false;
geky 44:16da10e7b3f7 145
geky 44:16da10e7b3f7 146 // Convert port to a string
geky 44:16da10e7b3f7 147 char port_buf[16];
geky 44:16da10e7b3f7 148 sprintf(port_buf, "%d", port);
geky 44:16da10e7b3f7 149
geky 44:16da10e7b3f7 150 // Connect to the ip address
geky 44:16da10e7b3f7 151 if (!(command("c:connect(") &&
geky 44:16da10e7b3f7 152 command(port_buf) &&
geky 44:16da10e7b3f7 153 command(",'") &&
geky 44:16da10e7b3f7 154 command(ip) &&
geky 44:16da10e7b3f7 155 command("')") &&
geky 44:16da10e7b3f7 156 execute()))
geky 44:16da10e7b3f7 157 return false;
geky 44:16da10e7b3f7 158
geky 44:16da10e7b3f7 159 // Wait for it to connect
geky 44:16da10e7b3f7 160 // TODO WISHLIST make this a seperate check so it can run asynch?
geky 44:16da10e7b3f7 161 Timer timer;
geky 44:16da10e7b3f7 162 timer.start();
geky 44:16da10e7b3f7 163
geky 44:16da10e7b3f7 164 while (true) {
geky 44:16da10e7b3f7 165 char con_buf[5];
geky 44:16da10e7b3f7 166 int con_len = 5;
geky 44:16da10e7b3f7 167
geky 44:16da10e7b3f7 168 if (!(command("print(cc)") && execute(con_buf, &con_len)))
geky 44:16da10e7b3f7 169 return false;
geky 44:16da10e7b3f7 170
geky 44:16da10e7b3f7 171 if (memcmp(con_buf, "true", con_len) == 0)
geky 44:16da10e7b3f7 172 return true;
geky 44:16da10e7b3f7 173 else if (memcmp(con_buf, "false", con_len) == 0)
geky 44:16da10e7b3f7 174 return false;
geky 44:16da10e7b3f7 175
geky 44:16da10e7b3f7 176 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 177 return false;
geky 44:16da10e7b3f7 178 }
geky 44:16da10e7b3f7 179 }
geky 44:16da10e7b3f7 180
geky 44:16da10e7b3f7 181 bool ESP8266::close() {
geky 44:16da10e7b3f7 182 return command("c:close();" "c=nil") && execute();
geky 44:16da10e7b3f7 183 }
geky 44:16da10e7b3f7 184
geky 44:16da10e7b3f7 185 bool ESP8266::send(const char *buffer, int len) {
geky 44:16da10e7b3f7 186 if (!(command("cs('") &&
geky 44:16da10e7b3f7 187 payload(buffer, len) &&
geky 44:16da10e7b3f7 188 command("')") &&
geky 44:16da10e7b3f7 189 execute()))
geky 44:16da10e7b3f7 190 return false;
geky 44:16da10e7b3f7 191
geky 44:16da10e7b3f7 192 return true;
geky 44:16da10e7b3f7 193 }
geky 44:16da10e7b3f7 194
geky 44:16da10e7b3f7 195 bool ESP8266::recv(char *buffer, int *len) {
geky 44:16da10e7b3f7 196 char len_buf[16];
geky 44:16da10e7b3f7 197 sprintf(len_buf, "%d", *len);
geky 44:16da10e7b3f7 198
geky 44:16da10e7b3f7 199 if (!(command("cr(") &&
geky 44:16da10e7b3f7 200 command(len_buf) &&
geky 44:16da10e7b3f7 201 command(")") &&
geky 44:16da10e7b3f7 202 execute(buffer, len)))
geky 44:16da10e7b3f7 203 return false;
geky 44:16da10e7b3f7 204
geky 44:16da10e7b3f7 205 return true;
geky 44:16da10e7b3f7 206 }
geky 44:16da10e7b3f7 207
geky 44:16da10e7b3f7 208 int ESP8266::putc(char c) {
geky 44:16da10e7b3f7 209 char buffer[1] = { c };
geky 44:16da10e7b3f7 210
geky 44:16da10e7b3f7 211 return send(buffer, 1) ? 0 : -1;
geky 44:16da10e7b3f7 212 }
geky 44:16da10e7b3f7 213
geky 44:16da10e7b3f7 214 int ESP8266::getc() {
geky 44:16da10e7b3f7 215 char buffer[1];
geky 44:16da10e7b3f7 216
geky 44:16da10e7b3f7 217 while (true) {
geky 44:16da10e7b3f7 218 int len = 1;
geky 44:16da10e7b3f7 219
geky 44:16da10e7b3f7 220 if (!recv(buffer, &len))
geky 44:16da10e7b3f7 221 return -1;
geky 44:16da10e7b3f7 222
geky 44:16da10e7b3f7 223 if (len > 0)
geky 44:16da10e7b3f7 224 break;
geky 44:16da10e7b3f7 225 }
geky 44:16da10e7b3f7 226
geky 44:16da10e7b3f7 227 return buffer[0];
geky 44:16da10e7b3f7 228 }
geky 44:16da10e7b3f7 229
geky 44:16da10e7b3f7 230 int ESP8266::writeable() {
geky 44:16da10e7b3f7 231 // Always succeeds since message can be temporarily stored on the esp
geky 44:16da10e7b3f7 232 return 1;
geky 44:16da10e7b3f7 233 }
geky 44:16da10e7b3f7 234
geky 44:16da10e7b3f7 235 int ESP8266::readable() {
geky 44:16da10e7b3f7 236 char count_buf[16];
geky 44:16da10e7b3f7 237 int count_len = 15;
geky 44:16da10e7b3f7 238
geky 44:16da10e7b3f7 239 if (!(command("ca()") && execute(count_buf, &count_len)))
geky 44:16da10e7b3f7 240 return false;
geky 44:16da10e7b3f7 241
geky 44:16da10e7b3f7 242 count_buf[count_len] = 0;
geky 44:16da10e7b3f7 243 return atoi(count_buf);
geky 44:16da10e7b3f7 244 }
geky 44:16da10e7b3f7 245
geky 44:16da10e7b3f7 246 const char *ESP8266::getIPAddress() {
geky 44:16da10e7b3f7 247 if (strcmp(_ip, "nil") != 0)
geky 44:16da10e7b3f7 248 return _ip;
geky 44:16da10e7b3f7 249 else
geky 44:16da10e7b3f7 250 return 0;
geky 44:16da10e7b3f7 251 }
geky 44:16da10e7b3f7 252
geky 44:16da10e7b3f7 253 bool ESP8266::getHostByName(const char *host, char *ip) {
geky 44:16da10e7b3f7 254 if (!(command("dh='") &&
geky 44:16da10e7b3f7 255 command(host) &&
geky 44:16da10e7b3f7 256 command("';") &&
geky 44:16da10e7b3f7 257 command("dn=nil;") &&
geky 44:16da10e7b3f7 258 command("if dh:match('%d+.%d+.%d+.%d+') then ") &&
geky 44:16da10e7b3f7 259 command("dn=dh ") &&
geky 44:16da10e7b3f7 260 command("else ") &&
geky 44:16da10e7b3f7 261 command("dc=net.createConnection(net.TCP);") &&
geky 44:16da10e7b3f7 262 command("dc:dns(dh,function(dc,ip) dn=ip end);") &&
geky 44:16da10e7b3f7 263 command("dc=nil ") &&
geky 44:16da10e7b3f7 264 command("end") &&
geky 44:16da10e7b3f7 265 execute()))
geky 44:16da10e7b3f7 266 return false;
geky 44:16da10e7b3f7 267
geky 44:16da10e7b3f7 268 // Wait for a response
geky 44:16da10e7b3f7 269 Timer timer;
geky 44:16da10e7b3f7 270 timer.start();
geky 44:16da10e7b3f7 271
geky 44:16da10e7b3f7 272 while (true) {
geky 44:16da10e7b3f7 273 int ip_len = 15;
geky 44:16da10e7b3f7 274
geky 44:16da10e7b3f7 275 if (!(command("print(dn)") && execute(ip, &ip_len)))
geky 44:16da10e7b3f7 276 return false;
geky 44:16da10e7b3f7 277
geky 44:16da10e7b3f7 278 ip[ip_len] = 0;
geky 44:16da10e7b3f7 279
geky 44:16da10e7b3f7 280 if (strcmp(ip, "nil") != 0)
geky 44:16da10e7b3f7 281 return true;
geky 44:16da10e7b3f7 282
geky 44:16da10e7b3f7 283 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 284 return false;
geky 44:16da10e7b3f7 285 }
geky 44:16da10e7b3f7 286 }
geky 44:16da10e7b3f7 287
geky 44:16da10e7b3f7 288 int ESP8266::serialgetc() {
geky 44:16da10e7b3f7 289 Timer timer;
geky 44:16da10e7b3f7 290 timer.start();
geky 44:16da10e7b3f7 291
geky 44:16da10e7b3f7 292 while (true) {
geky 44:16da10e7b3f7 293 if (_serial.readable()) {
geky 44:16da10e7b3f7 294 char c = _serial.getc();
geky 44:16da10e7b3f7 295 #ifdef ESP8266_ECHO
geky 44:16da10e7b3f7 296 printf("%c", c);
geky 44:16da10e7b3f7 297 #endif
geky 44:16da10e7b3f7 298 return c;
geky 44:16da10e7b3f7 299 }
geky 44:16da10e7b3f7 300
geky 44:16da10e7b3f7 301 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 302 return -1;
geky 44:16da10e7b3f7 303 }
geky 44:16da10e7b3f7 304 }
geky 44:16da10e7b3f7 305
geky 44:16da10e7b3f7 306 int ESP8266::serialputc(char c) {
geky 44:16da10e7b3f7 307 Timer timer;
geky 44:16da10e7b3f7 308 timer.start();
geky 44:16da10e7b3f7 309
geky 44:16da10e7b3f7 310 while (true) {
geky 44:16da10e7b3f7 311 if (_serial.writeable())
geky 44:16da10e7b3f7 312 return _serial.putc(c);
geky 44:16da10e7b3f7 313
geky 44:16da10e7b3f7 314 if (timer.read_ms() > _timeout)
geky 44:16da10e7b3f7 315 return -1;
geky 44:16da10e7b3f7 316 }
geky 44:16da10e7b3f7 317 }
geky 44:16da10e7b3f7 318
geky 44:16da10e7b3f7 319 bool ESP8266::discardEcho() {
geky 44:16da10e7b3f7 320 while (true) {
geky 44:16da10e7b3f7 321 int c = serialgetc();
geky 44:16da10e7b3f7 322
geky 44:16da10e7b3f7 323 if (c < 0)
geky 44:16da10e7b3f7 324 return false;
geky 44:16da10e7b3f7 325 else if (c == '>')
geky 44:16da10e7b3f7 326 return true;
geky 44:16da10e7b3f7 327 }
geky 44:16da10e7b3f7 328 }
geky 44:16da10e7b3f7 329
geky 44:16da10e7b3f7 330 bool ESP8266::command(const char *cmd) {
geky 44:16da10e7b3f7 331 DBG("command sent:\t %s", cmd);
geky 44:16da10e7b3f7 332
geky 44:16da10e7b3f7 333 for (int i = 0; cmd[i]; i++) {
geky 44:16da10e7b3f7 334 if (serialputc(cmd[i]) < 0)
geky 44:16da10e7b3f7 335 return false;
geky 44:16da10e7b3f7 336 }
geky 44:16da10e7b3f7 337
geky 44:16da10e7b3f7 338 return true;
geky 44:16da10e7b3f7 339 }
geky 44:16da10e7b3f7 340
geky 44:16da10e7b3f7 341 bool ESP8266::payload(const char *data, int len) {
geky 44:16da10e7b3f7 342 for (int i = 0; i < len; i++) {
geky 44:16da10e7b3f7 343 int a = data[i] / 100;
geky 44:16da10e7b3f7 344 int b = (data[i] - a*100) / 10;
geky 44:16da10e7b3f7 345 int c = (data[i] - a*100 - b*10);
geky 44:16da10e7b3f7 346
geky 44:16da10e7b3f7 347 if (serialputc('\\') < 0 ||
geky 44:16da10e7b3f7 348 serialputc(a + '0') < 0 ||
geky 44:16da10e7b3f7 349 serialputc(b + '0') < 0 ||
geky 44:16da10e7b3f7 350 serialputc(c + '0') < 0)
geky 44:16da10e7b3f7 351 return false;
geky 44:16da10e7b3f7 352 }
geky 44:16da10e7b3f7 353
geky 44:16da10e7b3f7 354 return true;
geky 44:16da10e7b3f7 355 }
geky 44:16da10e7b3f7 356
geky 44:16da10e7b3f7 357 bool ESP8266::execute(char *resp_buf, int *resp_len) {
geky 44:16da10e7b3f7 358 // Finish command with a newline
geky 44:16da10e7b3f7 359 if (serialputc('\r') < 0 || serialputc('\n') < 0)
geky 44:16da10e7b3f7 360 return false;
geky 44:16da10e7b3f7 361
geky 44:16da10e7b3f7 362 // Drop echoed string
geky 44:16da10e7b3f7 363 while (true) {
geky 44:16da10e7b3f7 364 int c = serialgetc();
geky 44:16da10e7b3f7 365
geky 44:16da10e7b3f7 366 if (c < 0)
geky 44:16da10e7b3f7 367 return false;
geky 44:16da10e7b3f7 368 else if (c == '\n')
geky 44:16da10e7b3f7 369 break;
geky 44:16da10e7b3f7 370 }
geky 44:16da10e7b3f7 371
geky 44:16da10e7b3f7 372 // Read in response if any
geky 44:16da10e7b3f7 373 if (resp_buf && resp_len) {
geky 44:16da10e7b3f7 374 int i;
geky 44:16da10e7b3f7 375
geky 44:16da10e7b3f7 376 for (i = 0; i < *resp_len; i++) {
geky 44:16da10e7b3f7 377 int c = serialgetc();
geky 44:16da10e7b3f7 378
geky 44:16da10e7b3f7 379 if (c < 0)
geky 44:16da10e7b3f7 380 return false;
geky 44:16da10e7b3f7 381
geky 44:16da10e7b3f7 382 if (c == '\r') {
geky 44:16da10e7b3f7 383 *resp_len = i;
geky 44:16da10e7b3f7 384 break;
geky 44:16da10e7b3f7 385 }
geky 44:16da10e7b3f7 386
geky 44:16da10e7b3f7 387 resp_buf[i] = c;
geky 44:16da10e7b3f7 388 }
geky 44:16da10e7b3f7 389
geky 44:16da10e7b3f7 390 DBG("command response:\t %.*s", *resp_len, resp_buf);
geky 44:16da10e7b3f7 391 }
geky 44:16da10e7b3f7 392
geky 44:16da10e7b3f7 393 // Flush to next prompt
geky 44:16da10e7b3f7 394 return discardEcho();
geky 44:16da10e7b3f7 395 }