now this shit works

Dependencies:   BufferedSerial

Dependents:   IoTWeatherStation

Fork of ESP8266NodeMCUInterface by ESP8266

Committer:
krbng4180
Date:
Mon Mar 14 02:40:12 2016 +0000
Revision:
50:7c4a5bdcb624
Parent:
49:a7741fe989ca
publishing;

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