ESP8266 Socket Library. AT Thinker firmware.

Dependents:   ESP8266_MQTT_HelloWorld ESP8266_IFTTT_Test ECE_4180_Lab_4 websocketmbed ... more

Fork of ESP8266Interface by ESP8266

This repository has been superceded

This project has moved to https://developer.mbed.org/teams/ESP8266/code/esp8266-driver/

This library works with the AT Thinker firmware.

Note

This library is currently in Beta. It is not feature complete and has some bugs, proceed with caution! Fixes and patches are welcome and appreciated!

Currently the ESP8266Interface Library has the following Abilities:

Working

  • TCP Client
  • UDP Client
  • Transparent mode (single connection of 1 type at a time)
  • Station Mode (connects to AP)

To be implemented

  • TCP Server
  • UDP Server
  • Multi Connection Mode (able to have up to 5 sockets at a time)
  • AP Mode (Make ESP Chip act like access point)
  • DNS Support (currently websites must be looked up by IP)
  • Error Recovery

Nice but not necessary

  • colorized text for ESP AT Commands in Command line (easier to differentiate from other text)
Committer:
mbedAustin
Date:
Wed Apr 29 22:43:03 2015 +0000
Revision:
30:c035696b9397
Parent:
29:939372104145
Child:
32:cf071dc33972
Safety Save

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 1:fb4494783863 1 /* Copyright (C) 2012 mbed.org, MIT License
samux 1:fb4494783863 2 *
samux 1:fb4494783863 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
samux 1:fb4494783863 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
samux 1:fb4494783863 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
samux 1:fb4494783863 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
samux 1:fb4494783863 7 * furnished to do so, subject to the following conditions:
samux 1:fb4494783863 8 *
samux 1:fb4494783863 9 * The above copyright notice and this permission notice shall be included in all copies or
samux 1:fb4494783863 10 * substantial portions of the Software.
samux 1:fb4494783863 11 *
samux 1:fb4494783863 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
samux 1:fb4494783863 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
samux 1:fb4494783863 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
samux 1:fb4494783863 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
samux 1:fb4494783863 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
samux 1:fb4494783863 17 */
samux 1:fb4494783863 18
samux 1:fb4494783863 19 #include "mbed.h"
michaeljkoster 13:41098c907200 20 #include "ESP8266.h"
michaeljkoster 16:3f0efaa57a12 21 #include "Endpoint.h"
samux 1:fb4494783863 22 #include <string>
samux 1:fb4494783863 23 #include <algorithm>
samux 1:fb4494783863 24
samux 1:fb4494783863 25 //Debug is disabled by default
mbedAustin 28:91e65e22e63a 26 #ifdef DEBUG
mbedAustin 28:91e65e22e63a 27 #define DBG(x, ...) printf("[ESP8266 : DBG]"x"\r\n", ##__VA_ARGS__);
mbedAustin 28:91e65e22e63a 28 #define WARN(x, ...) printf("[ESP8266 : WARN]"x"\r\n", ##__VA_ARGS__);
mbedAustin 28:91e65e22e63a 29 #define ERR(x, ...) printf("[ESP8266 : ERR]"x"\r\n", ##__VA_ARGS__);
samux 1:fb4494783863 30 #else
samux 1:fb4494783863 31 #define DBG(x, ...)
samux 1:fb4494783863 32 #define WARN(x, ...)
samux 1:fb4494783863 33 #define ERR(x, ...)
samux 1:fb4494783863 34 #endif
samux 1:fb4494783863 35
mbedAustin 28:91e65e22e63a 36 #ifdef DEBUG
michaeljkoster 13:41098c907200 37 #define INFO(x, ...) printf("[ESP8266 : INFO]"x"\r\n", ##__VA_ARGS__);
samux 1:fb4494783863 38 #else
samux 1:fb4494783863 39 #define INFO(x, ...)
samux 1:fb4494783863 40 #endif
samux 1:fb4494783863 41
mbedAustin 30:c035696b9397 42 #define ESP_MAX_TRY_JOIN 3
mbedAustin 30:c035696b9397 43 #define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible)
samux 1:fb4494783863 44
michaeljkoster 12:c5f0eac67a8a 45 extern Serial pc;
michaeljkoster 12:c5f0eac67a8a 46
michaeljkoster 13:41098c907200 47 ESP8266 * ESP8266::inst;
mbedAustin 29:939372104145 48 char* ip = NULL;
samux 1:fb4494783863 49
mbedAustin 28:91e65e22e63a 50 ESP8266::ESP8266( PinName tx, PinName rx, PinName _reset, const char * ssid, const char * phrase, uint32_t baud):
michaeljkoster 13:41098c907200 51 wifi(tx, rx), reset_pin(_reset), buf_ESP8266(256)
samux 1:fb4494783863 52 {
samux 1:fb4494783863 53 memset(&state, 0, sizeof(state));
samux 1:fb4494783863 54
michaeljkoster 26:0d5bcb3903e2 55 // change all ' ' in '$' in the ssid and the passphrase
samux 1:fb4494783863 56 strcpy(this->ssid, ssid);
samux 1:fb4494783863 57 for (int i = 0; i < strlen(ssid); i++) {
samux 1:fb4494783863 58 if (this->ssid[i] == ' ')
samux 1:fb4494783863 59 this->ssid[i] = '$';
samux 1:fb4494783863 60 }
samux 1:fb4494783863 61 strcpy(this->phrase, phrase);
samux 1:fb4494783863 62 for (int i = 0; i < strlen(phrase); i++) {
samux 1:fb4494783863 63 if (this->phrase[i] == ' ')
samux 1:fb4494783863 64 this->phrase[i] = '$';
samux 1:fb4494783863 65 }
michaeljkoster 26:0d5bcb3903e2 66
samux 1:fb4494783863 67
samux 1:fb4494783863 68 inst = this;
samux 1:fb4494783863 69 attach_rx(false);
mbedAustin 28:91e65e22e63a 70
mbedAustin 28:91e65e22e63a 71 wifi.baud(baud); // initial baud rate of the ESP8266
mbedAustin 28:91e65e22e63a 72
michaeljkoster 22:c4360e61486a 73 state.associated = false;
michaeljkoster 22:c4360e61486a 74 state.cmdMode = false;
samux 1:fb4494783863 75 }
samux 1:fb4494783863 76
michaeljkoster 13:41098c907200 77 bool ESP8266::join()
samux 1:fb4494783863 78 {
michaeljkoster 23:de9221771e96 79 sendCommand( "AT+CWMODE=1", "change", NULL, 1000);
michaeljkoster 16:3f0efaa57a12 80 string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\"";
mbedAustin 28:91e65e22e63a 81 if( sendCommand( cmd.c_str(), "OK", NULL, 10000) ) {
michaeljkoster 16:3f0efaa57a12 82 // successfully joined the network
samux 1:fb4494783863 83 state.associated = true;
michaeljkoster 13:41098c907200 84 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase);
samux 1:fb4494783863 85 return true;
samux 1:fb4494783863 86 }
samux 1:fb4494783863 87 return false;
samux 1:fb4494783863 88 }
samux 1:fb4494783863 89
michaeljkoster 13:41098c907200 90 bool ESP8266::connect()
samux 1:fb4494783863 91 {
mbedAustin 28:91e65e22e63a 92 sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode
mbedAustin 28:91e65e22e63a 93 return ESP8266::join();
samux 1:fb4494783863 94 }
samux 1:fb4494783863 95
michaeljkoster 15:37a7a56a424f 96 bool ESP8266::is_connected()
michaeljkoster 15:37a7a56a424f 97 {
michaeljkoster 15:37a7a56a424f 98 return true;
michaeljkoster 15:37a7a56a424f 99 }
michaeljkoster 15:37a7a56a424f 100
mbedAustin 30:c035696b9397 101 bool ESP8266::start(bool type,char* ip, int port, int id)
mbedAustin 30:c035696b9397 102 {
mbedAustin 30:c035696b9397 103 // Error Check
mbedAustin 30:c035696b9397 104 if(id > ESP_MAXID) {
mbedAustin 30:c035696b9397 105 ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id);
mbedAustin 30:c035696b9397 106 return false;
mbedAustin 30:c035696b9397 107 }
mbedAustin 30:c035696b9397 108 // Single Connection Mode
mbedAustin 30:c035696b9397 109 if(id < 0) {
mbedAustin 30:c035696b9397 110 DBG("Start Single Connection Mode");
mbedAustin 30:c035696b9397 111 char portstr[5];
mbedAustin 30:c035696b9397 112 char idstr[2];
mbedAustin 30:c035696b9397 113 bool check [3] = {0};
mbedAustin 30:c035696b9397 114 sprintf(idstr,"%d",id);
mbedAustin 30:c035696b9397 115 sprintf(portstr, "%d", port);
mbedAustin 30:c035696b9397 116 switch(type) {
mbedAustin 30:c035696b9397 117 case ESP_UDP_TYPE : //UDP
mbedAustin 30:c035696b9397 118 check[0] = sendCommand(( "AT+CIPSTART=" + (string) idstr + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 30:c035696b9397 119 break;
mbedAustin 30:c035696b9397 120 case ESP_TCP_TYPE : //TCP
mbedAustin 30:c035696b9397 121 check[0] = sendCommand(( "AT+CIPSTART=" + (string) idstr + ",\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 30:c035696b9397 122 break;
mbedAustin 30:c035696b9397 123 default:
mbedAustin 30:c035696b9397 124 ERR("Default hit for starting connection, this shouldnt be possible!!");
mbedAustin 30:c035696b9397 125 break;
mbedAustin 30:c035696b9397 126 }
mbedAustin 30:c035696b9397 127 check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode
mbedAustin 30:c035696b9397 128 check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode
mbedAustin 30:c035696b9397 129 // check that all commands were sucessful
mbedAustin 30:c035696b9397 130 if(check[0] && check[1] && check[2]) {
mbedAustin 30:c035696b9397 131 pc.printf("Data Mode\r\n");
mbedAustin 30:c035696b9397 132 state.cmdMode = false;
mbedAustin 30:c035696b9397 133 return true;
mbedAustin 30:c035696b9397 134 } else {
mbedAustin 30:c035696b9397 135 DBG("\r\nstartUDPTransparent Failed for ip:%s, port:%d\r\n",ip,port);
mbedAustin 30:c035696b9397 136 return false;
mbedAustin 30:c035696b9397 137 }
mbedAustin 30:c035696b9397 138 }
mbedAustin 30:c035696b9397 139 // Multi Connection Mode
mbedAustin 30:c035696b9397 140 else {
mbedAustin 30:c035696b9397 141 //TODO: impliment Multi Connection Mode
mbedAustin 30:c035696b9397 142 ERR("Not currently Supported!");
mbedAustin 30:c035696b9397 143 return false;
mbedAustin 30:c035696b9397 144 }
mbedAustin 30:c035696b9397 145 }
mbedAustin 30:c035696b9397 146
mbedAustin 28:91e65e22e63a 147 bool ESP8266::startUDP(char* ip, int port)
mbedAustin 28:91e65e22e63a 148 {
michaeljkoster 17:d11fa4c3ac65 149 char portstr[5];
michaeljkoster 16:3f0efaa57a12 150 sprintf(portstr, "%d", port);
michaeljkoster 18:60422852e99c 151 sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 28:91e65e22e63a 152
mbedAustin 28:91e65e22e63a 153 sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode
mbedAustin 28:91e65e22e63a 154 sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode
mbedAustin 30:c035696b9397 155 pc.printf("Data Mode\r\n");
michaeljkoster 22:c4360e61486a 156 state.cmdMode = false;
mbedAustin 28:91e65e22e63a 157
michaeljkoster 16:3f0efaa57a12 158 return true;
michaeljkoster 16:3f0efaa57a12 159 }
michaeljkoster 16:3f0efaa57a12 160
michaeljkoster 15:37a7a56a424f 161 bool ESP8266::close()
michaeljkoster 15:37a7a56a424f 162 {
michaeljkoster 17:d11fa4c3ac65 163 send("+++",3);
michaeljkoster 17:d11fa4c3ac65 164 wait(1);
michaeljkoster 22:c4360e61486a 165 state.cmdMode = true;
michaeljkoster 16:3f0efaa57a12 166 sendCommand("AT+CIPCLOSE","OK", NULL, 10000);
michaeljkoster 15:37a7a56a424f 167 return true;
michaeljkoster 15:37a7a56a424f 168 }
michaeljkoster 15:37a7a56a424f 169
michaeljkoster 15:37a7a56a424f 170 bool ESP8266::disconnect()
michaeljkoster 15:37a7a56a424f 171 {
michaeljkoster 15:37a7a56a424f 172 // if already disconnected, return
michaeljkoster 15:37a7a56a424f 173 if (!state.associated)
michaeljkoster 15:37a7a56a424f 174 return true;
michaeljkoster 15:37a7a56a424f 175 // send command to quit AP
mbedAustin 28:91e65e22e63a 176 sendCommand("AT+CWQAP", "OK", NULL, 10000);
michaeljkoster 15:37a7a56a424f 177 state.associated = false;
michaeljkoster 15:37a7a56a424f 178 return true;
michaeljkoster 15:37a7a56a424f 179 }
michaeljkoster 15:37a7a56a424f 180
mbedAustin 28:91e65e22e63a 181 /*
mbedAustin 28:91e65e22e63a 182 Assuming Returned data looks like this:
mbedAustin 28:91e65e22e63a 183 +CIFSR:STAIP,"192.168.11.2"
mbedAustin 28:91e65e22e63a 184 +CIFSR:STAMAC,"18:fe:34:9f:3a:f5"
mbedAustin 28:91e65e22e63a 185 grabbing IP from first set of quotation marks
mbedAustin 28:91e65e22e63a 186 */
michaeljkoster 15:37a7a56a424f 187 char* ESP8266::getIPAddress()
michaeljkoster 15:37a7a56a424f 188 {
mbedAustin 28:91e65e22e63a 189 char result[30] = {0};
mbedAustin 28:91e65e22e63a 190 int check = 0;
mbedAustin 28:91e65e22e63a 191 check = sendCommand("AT+CIFSR", NULL, result, 1000);
mbedAustin 29:939372104145 192 //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result);
mbedAustin 29:939372104145 193 ip = ipString;
mbedAustin 29:939372104145 194 if(check) {
mbedAustin 28:91e65e22e63a 195 // Success
mbedAustin 28:91e65e22e63a 196 string resultString(result);
mbedAustin 28:91e65e22e63a 197 uint8_t pos1 = 0, pos2 = 0;
mbedAustin 28:91e65e22e63a 198 //uint8_t pos3 = 0, pos4 = 0;
mbedAustin 28:91e65e22e63a 199 pos1 = resultString.find("+CIFSR:STAIP");
mbedAustin 28:91e65e22e63a 200 pos1 = resultString.find('"',pos1);
mbedAustin 28:91e65e22e63a 201 pos2 = resultString.find('"',pos1+1);
mbedAustin 28:91e65e22e63a 202 //pos3 = resultString.find('"',pos2+1); //would find mac address
mbedAustin 28:91e65e22e63a 203 //pos4 = resultString.find('"',pos3+1);
mbedAustin 28:91e65e22e63a 204 strncpy(ipString,resultString.substr(pos1,pos2).c_str(),sizeof(ipString));
mbedAustin 28:91e65e22e63a 205 ipString[pos2 - pos1 +1] = 0; // null terminate string correctly.
mbedAustin 28:91e65e22e63a 206 DBG("IP: %s\r\n",ipString);
mbedAustin 29:939372104145 207 ip = ipString;
mbedAustin 29:939372104145 208
mbedAustin 29:939372104145 209 } else {
mbedAustin 28:91e65e22e63a 210 // Failure
mbedAustin 28:91e65e22e63a 211 DBG("getIPAddress() failed\r\n");
mbedAustin 29:939372104145 212 ip = NULL;
mbedAustin 28:91e65e22e63a 213 }
mbedAustin 29:939372104145 214 return ip;
michaeljkoster 15:37a7a56a424f 215 }
michaeljkoster 15:37a7a56a424f 216
michaeljkoster 13:41098c907200 217 bool ESP8266::gethostbyname(const char * host, char * ip)
samux 1:fb4494783863 218 {
samux 1:fb4494783863 219 string h = host;
samux 1:fb4494783863 220 int nb_digits = 0;
samux 1:fb4494783863 221
samux 1:fb4494783863 222 // no dns needed
samux 1:fb4494783863 223 int pos = h.find(".");
samux 1:fb4494783863 224 if (pos != string::npos) {
samux 1:fb4494783863 225 string sub = h.substr(0, h.find("."));
samux 1:fb4494783863 226 nb_digits = atoi(sub.c_str());
samux 1:fb4494783863 227 }
samux 1:fb4494783863 228 //printf("substrL %s\r\n", sub.c_str());
samux 1:fb4494783863 229 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
samux 1:fb4494783863 230 strcpy(ip, host);
michaeljkoster 13:41098c907200 231 return true;
mbedAustin 28:91e65e22e63a 232 } else {
michaeljkoster 13:41098c907200 233 // dns needed, not currently available
mbedAustin 30:c035696b9397 234 ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!");
michaeljkoster 13:41098c907200 235 return false;
michaeljkoster 13:41098c907200 236 }
michaeljkoster 13:41098c907200 237 }
samux 1:fb4494783863 238
michaeljkoster 13:41098c907200 239 void ESP8266::reset()
samux 1:fb4494783863 240 {
samux 1:fb4494783863 241 reset_pin = 0;
samux 1:fb4494783863 242 wait(0.2);
samux 1:fb4494783863 243 reset_pin = 1;
michaeljkoster 24:03585a13ff3b 244 wait(1);
mbedAustin 28:91e65e22e63a 245
michaeljkoster 24:03585a13ff3b 246 //send("+++",3);
michaeljkoster 24:03585a13ff3b 247 //wait(1);
michaeljkoster 24:03585a13ff3b 248 state.cmdMode = true;
michaeljkoster 24:03585a13ff3b 249 sendCommand("AT", "OK", NULL, 1000);
mbedAustin 28:91e65e22e63a 250 sendCommand("AT+RST", "ready", NULL, 10000);
michaeljkoster 24:03585a13ff3b 251 state.associated = false;
michaeljkoster 24:03585a13ff3b 252
samux 1:fb4494783863 253 }
samux 1:fb4494783863 254
michaeljkoster 13:41098c907200 255 bool ESP8266::reboot()
samux 3:9aa05e19c62e 256 {
michaeljkoster 16:3f0efaa57a12 257 reset();
samux 3:9aa05e19c62e 258 return true;
samux 3:9aa05e19c62e 259 }
samux 3:9aa05e19c62e 260
michaeljkoster 15:37a7a56a424f 261 void ESP8266::handler_rx(void)
samux 1:fb4494783863 262 {
michaeljkoster 15:37a7a56a424f 263 //read characters
michaeljkoster 16:3f0efaa57a12 264 char c;
mbedAustin 28:91e65e22e63a 265 while (wifi.readable()) {
michaeljkoster 16:3f0efaa57a12 266 c=wifi.getc();
michaeljkoster 16:3f0efaa57a12 267 buf_ESP8266.queue(c);
michaeljkoster 26:0d5bcb3903e2 268 //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns
michaeljkoster 16:3f0efaa57a12 269 }
michaeljkoster 15:37a7a56a424f 270 }
michaeljkoster 15:37a7a56a424f 271
michaeljkoster 15:37a7a56a424f 272 void ESP8266::attach_rx(bool callback)
michaeljkoster 15:37a7a56a424f 273 {
michaeljkoster 15:37a7a56a424f 274 if (!callback)
michaeljkoster 15:37a7a56a424f 275 wifi.attach(NULL);
michaeljkoster 15:37a7a56a424f 276 else
michaeljkoster 15:37a7a56a424f 277 wifi.attach(this, &ESP8266::handler_rx);
samux 1:fb4494783863 278 }
samux 1:fb4494783863 279
michaeljkoster 13:41098c907200 280 int ESP8266::readable()
samux 1:fb4494783863 281 {
michaeljkoster 13:41098c907200 282 return buf_ESP8266.available();
samux 1:fb4494783863 283 }
samux 1:fb4494783863 284
michaeljkoster 13:41098c907200 285 int ESP8266::writeable()
samux 1:fb4494783863 286 {
samux 1:fb4494783863 287 return wifi.writeable();
samux 1:fb4494783863 288 }
samux 1:fb4494783863 289
michaeljkoster 13:41098c907200 290 char ESP8266::getc()
samux 1:fb4494783863 291 {
michaeljkoster 14:4d1128f72e00 292 char c=0;
michaeljkoster 13:41098c907200 293 while (!buf_ESP8266.available());
michaeljkoster 13:41098c907200 294 buf_ESP8266.dequeue(&c);
samux 1:fb4494783863 295 return c;
samux 1:fb4494783863 296 }
samux 1:fb4494783863 297
michaeljkoster 15:37a7a56a424f 298 int ESP8266::putc(char c)
samux 1:fb4494783863 299 {
michaeljkoster 20:d764237405c2 300 while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first
michaeljkoster 15:37a7a56a424f 301 return wifi.putc(c);
samux 1:fb4494783863 302 }
samux 1:fb4494783863 303
michaeljkoster 15:37a7a56a424f 304 void ESP8266::flush()
samux 1:fb4494783863 305 {
michaeljkoster 15:37a7a56a424f 306 buf_ESP8266.flush();
samux 1:fb4494783863 307 }
samux 1:fb4494783863 308
michaeljkoster 16:3f0efaa57a12 309 int ESP8266::send(const char * buf, int len)
michaeljkoster 15:37a7a56a424f 310 {
michaeljkoster 18:60422852e99c 311
michaeljkoster 16:3f0efaa57a12 312 const char* bufptr=buf;
mbedAustin 28:91e65e22e63a 313 for(int i=0; i<len; i++) {
michaeljkoster 17:d11fa4c3ac65 314 putc((int)*bufptr++);
michaeljkoster 18:60422852e99c 315 }
michaeljkoster 19:fb8d5bff2076 316 return len;
michaeljkoster 15:37a7a56a424f 317 }
samux 1:fb4494783863 318
michaeljkoster 16:3f0efaa57a12 319 bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout)
samux 1:fb4494783863 320 {
samux 1:fb4494783863 321 char read;
samux 1:fb4494783863 322 size_t found = string::npos;
samux 1:fb4494783863 323 string checking;
samux 1:fb4494783863 324 Timer tmr;
samux 1:fb4494783863 325 int result = 0;
samux 1:fb4494783863 326
mbedAustin 28:91e65e22e63a 327 DBG("will send: %s\r\n",cmd);
samux 1:fb4494783863 328
michaeljkoster 17:d11fa4c3ac65 329 attach_rx(true);
samux 1:fb4494783863 330
samux 1:fb4494783863 331 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 332 while (readable())
michaeljkoster 17:d11fa4c3ac65 333 getc();
mbedAustin 28:91e65e22e63a 334
samux 1:fb4494783863 335 if (!ACK || !strcmp(ACK, "NO")) {
mbedAustin 28:91e65e22e63a 336 for (int i = 0; i < strlen(cmd); i++) {
michaeljkoster 16:3f0efaa57a12 337 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
michaeljkoster 20:d764237405c2 338 wait(.005); // prevents stuck recieve ready (?) need to let echoed character get read first
michaeljkoster 16:3f0efaa57a12 339 }
michaeljkoster 16:3f0efaa57a12 340 putc(13); //CR
michaeljkoster 20:d764237405c2 341 wait(.005); // wait for echo
michaeljkoster 16:3f0efaa57a12 342 putc(10); //LF
michaeljkoster 16:3f0efaa57a12 343
samux 1:fb4494783863 344 } else {
samux 1:fb4494783863 345 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 346 while (readable())
michaeljkoster 17:d11fa4c3ac65 347 getc();
samux 1:fb4494783863 348
samux 1:fb4494783863 349 tmr.start();
mbedAustin 28:91e65e22e63a 350 for (int i = 0; i < strlen(cmd); i++) {
michaeljkoster 16:3f0efaa57a12 351 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
michaeljkoster 20:d764237405c2 352 wait(.005); // wait for echo
michaeljkoster 16:3f0efaa57a12 353 }
michaeljkoster 16:3f0efaa57a12 354 putc(13); //CR
michaeljkoster 20:d764237405c2 355 wait(.005); // wait for echo
michaeljkoster 16:3f0efaa57a12 356 putc(10); //LF
samux 1:fb4494783863 357
samux 1:fb4494783863 358 while (1) {
samux 1:fb4494783863 359 if (tmr.read_ms() > timeout) {
samux 1:fb4494783863 360 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 361 while (readable())
michaeljkoster 17:d11fa4c3ac65 362 getc();
samux 1:fb4494783863 363
samux 1:fb4494783863 364 DBG("check: %s\r\n", checking.c_str());
samux 1:fb4494783863 365
samux 1:fb4494783863 366 attach_rx(true);
samux 1:fb4494783863 367 return -1;
michaeljkoster 17:d11fa4c3ac65 368 } else if (readable()) {
michaeljkoster 17:d11fa4c3ac65 369 read = getc();
mbedAustin 28:91e65e22e63a 370 printf("%c",read); //debug echo
samux 1:fb4494783863 371 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 372 checking += read;
samux 1:fb4494783863 373 found = checking.find(ACK);
samux 1:fb4494783863 374 if (found != string::npos) {
samux 1:fb4494783863 375 wait(0.01);
samux 1:fb4494783863 376
samux 1:fb4494783863 377 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 378 while (readable())
michaeljkoster 26:0d5bcb3903e2 379 read = getc();
mbedAustin 28:91e65e22e63a 380 printf("%c",read); //debug echo
samux 1:fb4494783863 381 break;
samux 1:fb4494783863 382 }
samux 1:fb4494783863 383 }
samux 1:fb4494783863 384 }
samux 1:fb4494783863 385 }
samux 1:fb4494783863 386 DBG("check: %s\r\n", checking.c_str());
samux 1:fb4494783863 387
samux 1:fb4494783863 388 attach_rx(true);
samux 1:fb4494783863 389 return result;
samux 1:fb4494783863 390 }
samux 1:fb4494783863 391
samux 1:fb4494783863 392 //the user wants the result from the command (ACK == NULL, res != NULL)
samux 1:fb4494783863 393 if ( res != NULL) {
samux 1:fb4494783863 394 int i = 0;
samux 1:fb4494783863 395 Timer timeout;
samux 1:fb4494783863 396 timeout.start();
samux 1:fb4494783863 397 tmr.reset();
samux 1:fb4494783863 398 while (1) {
samux 1:fb4494783863 399 if (timeout.read() > 2) {
samux 1:fb4494783863 400 if (i == 0) {
samux 1:fb4494783863 401 res = NULL;
samux 1:fb4494783863 402 break;
samux 1:fb4494783863 403 }
samux 1:fb4494783863 404 res[i] = '\0';
samux 1:fb4494783863 405 DBG("user str 1: %s\r\n", res);
samux 1:fb4494783863 406
samux 1:fb4494783863 407 break;
samux 1:fb4494783863 408 } else {
samux 1:fb4494783863 409 if (tmr.read_ms() > 300) {
samux 1:fb4494783863 410 res[i] = '\0';
samux 1:fb4494783863 411 DBG("user str: %s\r\n", res);
samux 1:fb4494783863 412
samux 1:fb4494783863 413 break;
samux 1:fb4494783863 414 }
michaeljkoster 17:d11fa4c3ac65 415 if (readable()) {
samux 1:fb4494783863 416 tmr.start();
michaeljkoster 17:d11fa4c3ac65 417 read = getc();
samux 1:fb4494783863 418
samux 1:fb4494783863 419 // we drop \r and \n
samux 1:fb4494783863 420 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 421 res[i++] = read;
samux 1:fb4494783863 422 }
samux 1:fb4494783863 423 }
samux 1:fb4494783863 424 }
samux 1:fb4494783863 425 }
samux 1:fb4494783863 426 DBG("user str: %s\r\n", res);
samux 1:fb4494783863 427 }
samux 1:fb4494783863 428
samux 1:fb4494783863 429 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 430 while (readable())
michaeljkoster 17:d11fa4c3ac65 431 getc();
samux 1:fb4494783863 432
samux 1:fb4494783863 433 attach_rx(true);
samux 1:fb4494783863 434 DBG("result: %d\r\n", result)
samux 1:fb4494783863 435 return result;
michaeljkoster 15:37a7a56a424f 436 }