Test version

Committer:
a2824256
Date:
Tue Mar 20 02:09:21 2018 +0000
Revision:
0:4be500de690c
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
a2824256 0:4be500de690c 1 /* ESP8266 Example
a2824256 0:4be500de690c 2 * Copyright (c) 2015 ARM Limited
a2824256 0:4be500de690c 3 *
a2824256 0:4be500de690c 4 * Licensed under the Apache License, Version 2.0 (the "License");
a2824256 0:4be500de690c 5 * you may not use this file except in compliance with the License.
a2824256 0:4be500de690c 6 * You may obtain a copy of the License at
a2824256 0:4be500de690c 7 *
a2824256 0:4be500de690c 8 * http://www.apache.org/licenses/LICENSE-2.0
a2824256 0:4be500de690c 9 *
a2824256 0:4be500de690c 10 * Unless required by applicable law or agreed to in writing, software
a2824256 0:4be500de690c 11 * distributed under the License is distributed on an "AS IS" BASIS,
a2824256 0:4be500de690c 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
a2824256 0:4be500de690c 13 * See the License for the specific language governing permissions and
a2824256 0:4be500de690c 14 * limitations under the License.
a2824256 0:4be500de690c 15 */
a2824256 0:4be500de690c 16
a2824256 0:4be500de690c 17 #include "ESP8266.h"
a2824256 0:4be500de690c 18 #include "mbed_debug.h"
a2824256 0:4be500de690c 19 #include "nsapi_types.h"
a2824256 0:4be500de690c 20
a2824256 0:4be500de690c 21 #include <cstring>
a2824256 0:4be500de690c 22
a2824256 0:4be500de690c 23
a2824256 0:4be500de690c 24 #define TRACE_GROUP "Wifi"
a2824256 0:4be500de690c 25 #define ESP8266_DEFAULT_BAUD_RATE 115200
a2824256 0:4be500de690c 26
a2824256 0:4be500de690c 27
a2824256 0:4be500de690c 28 ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
a2824256 0:4be500de690c 29 : _serial(tx, rx, ESP8266_DEFAULT_BAUD_RATE),
a2824256 0:4be500de690c 30 _parser(&_serial),
a2824256 0:4be500de690c 31 _packets(0),
a2824256 0:4be500de690c 32 _packets_end(&_packets),
a2824256 0:4be500de690c 33 _connect_error(0),
a2824256 0:4be500de690c 34 _fail(false),
a2824256 0:4be500de690c 35 _socket_open()
a2824256 0:4be500de690c 36 {
a2824256 0:4be500de690c 37 _serial.set_baud( ESP8266_DEFAULT_BAUD_RATE );
a2824256 0:4be500de690c 38 _parser.debug_on(debug);
a2824256 0:4be500de690c 39 _parser.set_delimiter("\r\n");
a2824256 0:4be500de690c 40 _parser.oob("+IPD", callback(this, &ESP8266::_packet_handler));
a2824256 0:4be500de690c 41 //Note: espressif at command document says that this should be +CWJAP_CUR:<error code>
a2824256 0:4be500de690c 42 //but seems that at least current version is not sending it
a2824256 0:4be500de690c 43 //https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
a2824256 0:4be500de690c 44 //Also seems that ERROR is not sent, but FAIL instead
a2824256 0:4be500de690c 45 _parser.oob("+CWJAP:", callback(this, &ESP8266::_connect_error_handler));
a2824256 0:4be500de690c 46 _parser.oob("0,CLOSED", callback(this, &ESP8266::_oob_socket0_closed_handler));
a2824256 0:4be500de690c 47 _parser.oob("1,CLOSED", callback(this, &ESP8266::_oob_socket1_closed_handler));
a2824256 0:4be500de690c 48 _parser.oob("2,CLOSED", callback(this, &ESP8266::_oob_socket2_closed_handler));
a2824256 0:4be500de690c 49 _parser.oob("3,CLOSED", callback(this, &ESP8266::_oob_socket3_closed_handler));
a2824256 0:4be500de690c 50 _parser.oob("4,CLOSED", callback(this, &ESP8266::_oob_socket4_closed_handler));
a2824256 0:4be500de690c 51 }
a2824256 0:4be500de690c 52
a2824256 0:4be500de690c 53 int ESP8266::get_firmware_version()
a2824256 0:4be500de690c 54 {
a2824256 0:4be500de690c 55 int version;
a2824256 0:4be500de690c 56
a2824256 0:4be500de690c 57 _smutex.lock();
a2824256 0:4be500de690c 58 bool done = _parser.send("AT+GMR")
a2824256 0:4be500de690c 59 && _parser.recv("SDK version:%d", &version)
a2824256 0:4be500de690c 60 && _parser.recv("OK\n");
a2824256 0:4be500de690c 61 _smutex.unlock();
a2824256 0:4be500de690c 62
a2824256 0:4be500de690c 63 if(done) {
a2824256 0:4be500de690c 64 return version;
a2824256 0:4be500de690c 65 } else {
a2824256 0:4be500de690c 66 // Older firmware versions do not prefix the version with "SDK version: "
a2824256 0:4be500de690c 67 return -1;
a2824256 0:4be500de690c 68 }
a2824256 0:4be500de690c 69 }
a2824256 0:4be500de690c 70
a2824256 0:4be500de690c 71 bool ESP8266::startup(int mode)
a2824256 0:4be500de690c 72 {
a2824256 0:4be500de690c 73 if (!(mode == WIFIMODE_STATION || mode == WIFIMODE_SOFTAP
a2824256 0:4be500de690c 74 || mode == WIFIMODE_STATION_SOFTAP)) {
a2824256 0:4be500de690c 75 return false;
a2824256 0:4be500de690c 76 }
a2824256 0:4be500de690c 77
a2824256 0:4be500de690c 78 _smutex.lock();
a2824256 0:4be500de690c 79 bool done = _parser.send("AT+CWMODE_CUR=%d", mode)
a2824256 0:4be500de690c 80 && _parser.recv("OK\n")
a2824256 0:4be500de690c 81 &&_parser.send("AT+CIPMUX=1")
a2824256 0:4be500de690c 82 && _parser.recv("OK\n");
a2824256 0:4be500de690c 83 _smutex.unlock();
a2824256 0:4be500de690c 84
a2824256 0:4be500de690c 85 return done;
a2824256 0:4be500de690c 86 }
a2824256 0:4be500de690c 87
a2824256 0:4be500de690c 88 bool ESP8266::reset(void)
a2824256 0:4be500de690c 89 {
a2824256 0:4be500de690c 90 _smutex.lock();
a2824256 0:4be500de690c 91 for (int i = 0; i < 2; i++) {
a2824256 0:4be500de690c 92 if (_parser.send("AT+RST")
a2824256 0:4be500de690c 93 && _parser.recv("OK\n")
a2824256 0:4be500de690c 94 && _parser.recv("ready")) {
a2824256 0:4be500de690c 95 _smutex.unlock();
a2824256 0:4be500de690c 96 return true;
a2824256 0:4be500de690c 97 }
a2824256 0:4be500de690c 98 }
a2824256 0:4be500de690c 99 _smutex.unlock();
a2824256 0:4be500de690c 100
a2824256 0:4be500de690c 101 return false;
a2824256 0:4be500de690c 102 }
a2824256 0:4be500de690c 103
a2824256 0:4be500de690c 104 bool ESP8266::dhcp(bool enabled, int mode)
a2824256 0:4be500de690c 105 {
a2824256 0:4be500de690c 106 //only 3 valid modes
a2824256 0:4be500de690c 107 if (mode < 0 || mode > 2) {
a2824256 0:4be500de690c 108 return false;
a2824256 0:4be500de690c 109 }
a2824256 0:4be500de690c 110
a2824256 0:4be500de690c 111 _smutex.lock();
a2824256 0:4be500de690c 112 bool done = _parser.send("AT+CWDHCP_CUR=%d,%d", mode, enabled?1:0)
a2824256 0:4be500de690c 113 && _parser.recv("OK\n");
a2824256 0:4be500de690c 114 _smutex.unlock();
a2824256 0:4be500de690c 115
a2824256 0:4be500de690c 116 return done;
a2824256 0:4be500de690c 117 }
a2824256 0:4be500de690c 118
a2824256 0:4be500de690c 119 nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)
a2824256 0:4be500de690c 120 {
a2824256 0:4be500de690c 121 _smutex.lock();
a2824256 0:4be500de690c 122 _parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"", ap, passPhrase);
a2824256 0:4be500de690c 123 if (!_parser.recv("OK\n")) {
a2824256 0:4be500de690c 124 if (_fail) {
a2824256 0:4be500de690c 125 _smutex.unlock();
a2824256 0:4be500de690c 126 nsapi_error_t ret;
a2824256 0:4be500de690c 127 if (_connect_error == 1)
a2824256 0:4be500de690c 128 ret = NSAPI_ERROR_CONNECTION_TIMEOUT;
a2824256 0:4be500de690c 129 else if (_connect_error == 2)
a2824256 0:4be500de690c 130 ret = NSAPI_ERROR_AUTH_FAILURE;
a2824256 0:4be500de690c 131 else if (_connect_error == 3)
a2824256 0:4be500de690c 132 ret = NSAPI_ERROR_NO_SSID;
a2824256 0:4be500de690c 133 else
a2824256 0:4be500de690c 134 ret = NSAPI_ERROR_NO_CONNECTION;
a2824256 0:4be500de690c 135
a2824256 0:4be500de690c 136 _fail = false;
a2824256 0:4be500de690c 137 _connect_error = 0;
a2824256 0:4be500de690c 138 return ret;
a2824256 0:4be500de690c 139 }
a2824256 0:4be500de690c 140 }
a2824256 0:4be500de690c 141 _smutex.unlock();
a2824256 0:4be500de690c 142
a2824256 0:4be500de690c 143 return NSAPI_ERROR_OK;
a2824256 0:4be500de690c 144 }
a2824256 0:4be500de690c 145
a2824256 0:4be500de690c 146 bool ESP8266::disconnect(void)
a2824256 0:4be500de690c 147 {
a2824256 0:4be500de690c 148 _smutex.lock();
a2824256 0:4be500de690c 149 bool done = _parser.send("AT+CWQAP") && _parser.recv("OK\n");
a2824256 0:4be500de690c 150 _smutex.unlock();
a2824256 0:4be500de690c 151
a2824256 0:4be500de690c 152 return done;
a2824256 0:4be500de690c 153 }
a2824256 0:4be500de690c 154
a2824256 0:4be500de690c 155 const char *ESP8266::getIPAddress(void)
a2824256 0:4be500de690c 156 {
a2824256 0:4be500de690c 157 _smutex.lock();
a2824256 0:4be500de690c 158 if (!(_parser.send("AT+CIFSR")
a2824256 0:4be500de690c 159 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
a2824256 0:4be500de690c 160 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 161 _smutex.unlock();
a2824256 0:4be500de690c 162 return 0;
a2824256 0:4be500de690c 163 }
a2824256 0:4be500de690c 164 _smutex.unlock();
a2824256 0:4be500de690c 165
a2824256 0:4be500de690c 166 return _ip_buffer;
a2824256 0:4be500de690c 167 }
a2824256 0:4be500de690c 168
a2824256 0:4be500de690c 169 const char *ESP8266::getMACAddress(void)
a2824256 0:4be500de690c 170 {
a2824256 0:4be500de690c 171 _smutex.lock();
a2824256 0:4be500de690c 172 if (!(_parser.send("AT+CIFSR")
a2824256 0:4be500de690c 173 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
a2824256 0:4be500de690c 174 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 175 _smutex.unlock();
a2824256 0:4be500de690c 176 return 0;
a2824256 0:4be500de690c 177 }
a2824256 0:4be500de690c 178 _smutex.unlock();
a2824256 0:4be500de690c 179
a2824256 0:4be500de690c 180 return _mac_buffer;
a2824256 0:4be500de690c 181 }
a2824256 0:4be500de690c 182
a2824256 0:4be500de690c 183 const char *ESP8266::getGateway()
a2824256 0:4be500de690c 184 {
a2824256 0:4be500de690c 185 _smutex.lock();
a2824256 0:4be500de690c 186 if (!(_parser.send("AT+CIPSTA_CUR?")
a2824256 0:4be500de690c 187 && _parser.recv("+CIPSTA_CUR:gateway:\"%15[^\"]\"", _gateway_buffer)
a2824256 0:4be500de690c 188 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 189 _smutex.unlock();
a2824256 0:4be500de690c 190 return 0;
a2824256 0:4be500de690c 191 }
a2824256 0:4be500de690c 192 _smutex.unlock();
a2824256 0:4be500de690c 193
a2824256 0:4be500de690c 194 return _gateway_buffer;
a2824256 0:4be500de690c 195 }
a2824256 0:4be500de690c 196
a2824256 0:4be500de690c 197 const char *ESP8266::getNetmask()
a2824256 0:4be500de690c 198 {
a2824256 0:4be500de690c 199 _smutex.lock();
a2824256 0:4be500de690c 200 if (!(_parser.send("AT+CIPSTA_CUR?")
a2824256 0:4be500de690c 201 && _parser.recv("+CIPSTA_CUR:netmask:\"%15[^\"]\"", _netmask_buffer)
a2824256 0:4be500de690c 202 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 203 _smutex.unlock();
a2824256 0:4be500de690c 204 return 0;
a2824256 0:4be500de690c 205 }
a2824256 0:4be500de690c 206 _smutex.unlock();
a2824256 0:4be500de690c 207
a2824256 0:4be500de690c 208 return _netmask_buffer;
a2824256 0:4be500de690c 209 }
a2824256 0:4be500de690c 210
a2824256 0:4be500de690c 211 int8_t ESP8266::getRSSI()
a2824256 0:4be500de690c 212 {
a2824256 0:4be500de690c 213 int8_t rssi;
a2824256 0:4be500de690c 214 char bssid[18];
a2824256 0:4be500de690c 215
a2824256 0:4be500de690c 216 _smutex.lock();
a2824256 0:4be500de690c 217 if (!(_parser.send("AT+CWJAP_CUR?")
a2824256 0:4be500de690c 218 && _parser.recv("+CWJAP_CUR:\"%*[^\"]\",\"%17[^\"]\"", bssid)
a2824256 0:4be500de690c 219 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 220 _smutex.unlock();
a2824256 0:4be500de690c 221 return 0;
a2824256 0:4be500de690c 222 }
a2824256 0:4be500de690c 223 _smutex.unlock();
a2824256 0:4be500de690c 224
a2824256 0:4be500de690c 225 _smutex.lock();
a2824256 0:4be500de690c 226 if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid)
a2824256 0:4be500de690c 227 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
a2824256 0:4be500de690c 228 && _parser.recv("OK\n"))) {
a2824256 0:4be500de690c 229 _smutex.unlock();
a2824256 0:4be500de690c 230 return 0;
a2824256 0:4be500de690c 231 }
a2824256 0:4be500de690c 232 _smutex.unlock();
a2824256 0:4be500de690c 233
a2824256 0:4be500de690c 234 return rssi;
a2824256 0:4be500de690c 235 }
a2824256 0:4be500de690c 236
a2824256 0:4be500de690c 237 int ESP8266::scan(WiFiAccessPoint *res, unsigned limit)
a2824256 0:4be500de690c 238 {
a2824256 0:4be500de690c 239 unsigned cnt = 0;
a2824256 0:4be500de690c 240 nsapi_wifi_ap_t ap;
a2824256 0:4be500de690c 241
a2824256 0:4be500de690c 242 _smutex.lock();
a2824256 0:4be500de690c 243 if (!_parser.send("AT+CWLAP")) {
a2824256 0:4be500de690c 244 _smutex.unlock();
a2824256 0:4be500de690c 245 return NSAPI_ERROR_DEVICE_ERROR;
a2824256 0:4be500de690c 246 }
a2824256 0:4be500de690c 247
a2824256 0:4be500de690c 248 while (recv_ap(&ap)) {
a2824256 0:4be500de690c 249 if (cnt < limit) {
a2824256 0:4be500de690c 250 res[cnt] = WiFiAccessPoint(ap);
a2824256 0:4be500de690c 251 }
a2824256 0:4be500de690c 252
a2824256 0:4be500de690c 253 cnt++;
a2824256 0:4be500de690c 254 if (limit != 0 && cnt >= limit) {
a2824256 0:4be500de690c 255 break;
a2824256 0:4be500de690c 256 }
a2824256 0:4be500de690c 257 }
a2824256 0:4be500de690c 258 _smutex.unlock();
a2824256 0:4be500de690c 259
a2824256 0:4be500de690c 260 return cnt;
a2824256 0:4be500de690c 261 }
a2824256 0:4be500de690c 262
a2824256 0:4be500de690c 263 bool ESP8266::open_udp(int id, const char* addr, int port, int local_port)
a2824256 0:4be500de690c 264 {
a2824256 0:4be500de690c 265 static const char *type = "UDP";
a2824256 0:4be500de690c 266 bool done = false;
a2824256 0:4be500de690c 267
a2824256 0:4be500de690c 268 if (id >= SOCKET_COUNT || _socket_open[id]) {
a2824256 0:4be500de690c 269 return false;
a2824256 0:4be500de690c 270 }
a2824256 0:4be500de690c 271
a2824256 0:4be500de690c 272 _smutex.lock();
a2824256 0:4be500de690c 273 if(local_port) {
a2824256 0:4be500de690c 274 done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, local_port)
a2824256 0:4be500de690c 275 && _parser.recv("OK\n");
a2824256 0:4be500de690c 276 } else {
a2824256 0:4be500de690c 277 done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
a2824256 0:4be500de690c 278 && _parser.recv("OK\n");
a2824256 0:4be500de690c 279 }
a2824256 0:4be500de690c 280
a2824256 0:4be500de690c 281 if (done) {
a2824256 0:4be500de690c 282 _socket_open[id] = 1;
a2824256 0:4be500de690c 283 }
a2824256 0:4be500de690c 284
a2824256 0:4be500de690c 285 _smutex.unlock();
a2824256 0:4be500de690c 286
a2824256 0:4be500de690c 287 return done;
a2824256 0:4be500de690c 288 }
a2824256 0:4be500de690c 289
a2824256 0:4be500de690c 290 bool ESP8266::open_tcp(int id, const char* addr, int port, int keepalive)
a2824256 0:4be500de690c 291 {
a2824256 0:4be500de690c 292 static const char *type = "TCP";
a2824256 0:4be500de690c 293 bool done = false;
a2824256 0:4be500de690c 294
a2824256 0:4be500de690c 295 if (id >= SOCKET_COUNT || _socket_open[id]) {
a2824256 0:4be500de690c 296 return false;
a2824256 0:4be500de690c 297 }
a2824256 0:4be500de690c 298
a2824256 0:4be500de690c 299 _smutex.lock();
a2824256 0:4be500de690c 300
a2824256 0:4be500de690c 301 if(keepalive) {
a2824256 0:4be500de690c 302 done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, keepalive)
a2824256 0:4be500de690c 303 && _parser.recv("OK\n");
a2824256 0:4be500de690c 304 } else {
a2824256 0:4be500de690c 305 done = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
a2824256 0:4be500de690c 306 && _parser.recv("OK\n");
a2824256 0:4be500de690c 307 }
a2824256 0:4be500de690c 308
a2824256 0:4be500de690c 309 if (done) {
a2824256 0:4be500de690c 310 _socket_open[id] = 1;
a2824256 0:4be500de690c 311 }
a2824256 0:4be500de690c 312
a2824256 0:4be500de690c 313 _smutex.unlock();
a2824256 0:4be500de690c 314
a2824256 0:4be500de690c 315 return done;
a2824256 0:4be500de690c 316 }
a2824256 0:4be500de690c 317
a2824256 0:4be500de690c 318 bool ESP8266::dns_lookup(const char* name, char* ip)
a2824256 0:4be500de690c 319 {
a2824256 0:4be500de690c 320 _smutex.lock();
a2824256 0:4be500de690c 321 bool done = _parser.send("AT+CIPDOMAIN=\"%s\"", name) && _parser.recv("+CIPDOMAIN:%s%*[\r]%*[\n]", ip);
a2824256 0:4be500de690c 322 _smutex.unlock();
a2824256 0:4be500de690c 323
a2824256 0:4be500de690c 324 return done;
a2824256 0:4be500de690c 325 }
a2824256 0:4be500de690c 326
a2824256 0:4be500de690c 327 nsapi_error_t ESP8266::send(int id, const void *data, uint32_t amount)
a2824256 0:4be500de690c 328 {
a2824256 0:4be500de690c 329 //May take a second try if device is busy
a2824256 0:4be500de690c 330 for (unsigned i = 0; i < 2; i++) {
a2824256 0:4be500de690c 331 _smutex.lock();
a2824256 0:4be500de690c 332 if (_parser.send("AT+CIPSEND=%d,%lu", id, amount)
a2824256 0:4be500de690c 333 && _parser.recv(">")
a2824256 0:4be500de690c 334 && _parser.write((char*)data, (int)amount) >= 0) {
a2824256 0:4be500de690c 335 while (_parser.process_oob()); // multiple sends in a row require this
a2824256 0:4be500de690c 336 _smutex.unlock();
a2824256 0:4be500de690c 337 return NSAPI_ERROR_OK;
a2824256 0:4be500de690c 338 }
a2824256 0:4be500de690c 339 _smutex.unlock();
a2824256 0:4be500de690c 340 }
a2824256 0:4be500de690c 341
a2824256 0:4be500de690c 342 return NSAPI_ERROR_DEVICE_ERROR;
a2824256 0:4be500de690c 343 }
a2824256 0:4be500de690c 344
a2824256 0:4be500de690c 345 void ESP8266::_packet_handler()
a2824256 0:4be500de690c 346 {
a2824256 0:4be500de690c 347 int id;
a2824256 0:4be500de690c 348 uint32_t amount;
a2824256 0:4be500de690c 349
a2824256 0:4be500de690c 350 // parse out the packet
a2824256 0:4be500de690c 351 if (!_parser.recv(",%d,%lu:", &id, &amount)) {
a2824256 0:4be500de690c 352 return;
a2824256 0:4be500de690c 353 }
a2824256 0:4be500de690c 354
a2824256 0:4be500de690c 355 struct packet *packet = (struct packet*)malloc(
a2824256 0:4be500de690c 356 sizeof(struct packet) + amount);
a2824256 0:4be500de690c 357 if (!packet) {
a2824256 0:4be500de690c 358 debug("Could not allocate memory for RX data");
a2824256 0:4be500de690c 359 return;
a2824256 0:4be500de690c 360 }
a2824256 0:4be500de690c 361
a2824256 0:4be500de690c 362 packet->id = id;
a2824256 0:4be500de690c 363 packet->len = amount;
a2824256 0:4be500de690c 364 packet->next = 0;
a2824256 0:4be500de690c 365
a2824256 0:4be500de690c 366 if (!(_parser.read((char*)(packet + 1), amount))) {
a2824256 0:4be500de690c 367 free(packet);
a2824256 0:4be500de690c 368 return;
a2824256 0:4be500de690c 369 }
a2824256 0:4be500de690c 370
a2824256 0:4be500de690c 371 // append to packet list
a2824256 0:4be500de690c 372 *_packets_end = packet;
a2824256 0:4be500de690c 373 _packets_end = &packet->next;
a2824256 0:4be500de690c 374 }
a2824256 0:4be500de690c 375
a2824256 0:4be500de690c 376 int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount)
a2824256 0:4be500de690c 377 {
a2824256 0:4be500de690c 378 _smutex.lock();
a2824256 0:4be500de690c 379 // Poll for inbound packets
a2824256 0:4be500de690c 380 while (_parser.process_oob()) {
a2824256 0:4be500de690c 381 }
a2824256 0:4be500de690c 382
a2824256 0:4be500de690c 383 // check if any packets are ready for us
a2824256 0:4be500de690c 384 for (struct packet **p = &_packets; *p; p = &(*p)->next) {
a2824256 0:4be500de690c 385 if ((*p)->id == id) {
a2824256 0:4be500de690c 386 struct packet *q = *p;
a2824256 0:4be500de690c 387
a2824256 0:4be500de690c 388 if (q->len <= amount) { // Return and remove full packet
a2824256 0:4be500de690c 389 memcpy(data, q+1, q->len);
a2824256 0:4be500de690c 390
a2824256 0:4be500de690c 391 if (_packets_end == &(*p)->next) {
a2824256 0:4be500de690c 392 _packets_end = p;
a2824256 0:4be500de690c 393 }
a2824256 0:4be500de690c 394 *p = (*p)->next;
a2824256 0:4be500de690c 395 _smutex.unlock();
a2824256 0:4be500de690c 396
a2824256 0:4be500de690c 397 uint32_t len = q->len;
a2824256 0:4be500de690c 398 free(q);
a2824256 0:4be500de690c 399 return len;
a2824256 0:4be500de690c 400 } else { // return only partial packet
a2824256 0:4be500de690c 401 memcpy(data, q+1, amount);
a2824256 0:4be500de690c 402
a2824256 0:4be500de690c 403 q->len -= amount;
a2824256 0:4be500de690c 404 memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
a2824256 0:4be500de690c 405
a2824256 0:4be500de690c 406 _smutex.unlock();
a2824256 0:4be500de690c 407 return amount;
a2824256 0:4be500de690c 408 }
a2824256 0:4be500de690c 409 }
a2824256 0:4be500de690c 410 }
a2824256 0:4be500de690c 411 if(!_socket_open[id]) {
a2824256 0:4be500de690c 412 _smutex.unlock();
a2824256 0:4be500de690c 413 return 0;
a2824256 0:4be500de690c 414 }
a2824256 0:4be500de690c 415
a2824256 0:4be500de690c 416 _smutex.unlock();
a2824256 0:4be500de690c 417
a2824256 0:4be500de690c 418 return NSAPI_ERROR_WOULD_BLOCK;
a2824256 0:4be500de690c 419 }
a2824256 0:4be500de690c 420
a2824256 0:4be500de690c 421 int32_t ESP8266::recv_udp(int id, void *data, uint32_t amount)
a2824256 0:4be500de690c 422 {
a2824256 0:4be500de690c 423 _smutex.lock();
a2824256 0:4be500de690c 424 // Poll for inbound packets
a2824256 0:4be500de690c 425 while (_parser.process_oob()) {
a2824256 0:4be500de690c 426 }
a2824256 0:4be500de690c 427
a2824256 0:4be500de690c 428 // check if any packets are ready for us
a2824256 0:4be500de690c 429 for (struct packet **p = &_packets; *p; p = &(*p)->next) {
a2824256 0:4be500de690c 430 if ((*p)->id == id) {
a2824256 0:4be500de690c 431 struct packet *q = *p;
a2824256 0:4be500de690c 432
a2824256 0:4be500de690c 433 // Return and remove packet (truncated if necessary)
a2824256 0:4be500de690c 434 uint32_t len = q->len < amount ? q->len : amount;
a2824256 0:4be500de690c 435 memcpy(data, q+1, len);
a2824256 0:4be500de690c 436
a2824256 0:4be500de690c 437 if (_packets_end == &(*p)->next) {
a2824256 0:4be500de690c 438 _packets_end = p;
a2824256 0:4be500de690c 439 }
a2824256 0:4be500de690c 440 *p = (*p)->next;
a2824256 0:4be500de690c 441 _smutex.unlock();
a2824256 0:4be500de690c 442
a2824256 0:4be500de690c 443 free(q);
a2824256 0:4be500de690c 444 return len;
a2824256 0:4be500de690c 445 }
a2824256 0:4be500de690c 446 }
a2824256 0:4be500de690c 447
a2824256 0:4be500de690c 448 _smutex.unlock();
a2824256 0:4be500de690c 449
a2824256 0:4be500de690c 450 return NSAPI_ERROR_WOULD_BLOCK;
a2824256 0:4be500de690c 451 }
a2824256 0:4be500de690c 452
a2824256 0:4be500de690c 453 bool ESP8266::close(int id)
a2824256 0:4be500de690c 454 {
a2824256 0:4be500de690c 455 //May take a second try if device is busy
a2824256 0:4be500de690c 456 for (unsigned i = 0; i < 2; i++) {
a2824256 0:4be500de690c 457 _smutex.lock();
a2824256 0:4be500de690c 458 if (_parser.send("AT+CIPCLOSE=%d", id) && _parser.recv("OK\n")) {
a2824256 0:4be500de690c 459 if (!_socket_open[id]) { // recv(processing OOBs) needs to be done first
a2824256 0:4be500de690c 460 _smutex.unlock();
a2824256 0:4be500de690c 461 return true;
a2824256 0:4be500de690c 462 }
a2824256 0:4be500de690c 463 }
a2824256 0:4be500de690c 464 _smutex.unlock();
a2824256 0:4be500de690c 465 }
a2824256 0:4be500de690c 466
a2824256 0:4be500de690c 467 return false;
a2824256 0:4be500de690c 468 }
a2824256 0:4be500de690c 469
a2824256 0:4be500de690c 470 void ESP8266::setTimeout(uint32_t timeout_ms)
a2824256 0:4be500de690c 471 {
a2824256 0:4be500de690c 472 _parser.set_timeout(timeout_ms);
a2824256 0:4be500de690c 473 }
a2824256 0:4be500de690c 474
a2824256 0:4be500de690c 475 bool ESP8266::readable()
a2824256 0:4be500de690c 476 {
a2824256 0:4be500de690c 477 return _serial.FileHandle::readable();
a2824256 0:4be500de690c 478 }
a2824256 0:4be500de690c 479
a2824256 0:4be500de690c 480 bool ESP8266::writeable()
a2824256 0:4be500de690c 481 {
a2824256 0:4be500de690c 482 return _serial.FileHandle::writable();
a2824256 0:4be500de690c 483 }
a2824256 0:4be500de690c 484
a2824256 0:4be500de690c 485 void ESP8266::attach(Callback<void()> func)
a2824256 0:4be500de690c 486 {
a2824256 0:4be500de690c 487 _serial.sigio(func);
a2824256 0:4be500de690c 488 }
a2824256 0:4be500de690c 489
a2824256 0:4be500de690c 490 bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap)
a2824256 0:4be500de690c 491 {
a2824256 0:4be500de690c 492 int sec;
a2824256 0:4be500de690c 493 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%hhu", &sec, ap->ssid,
a2824256 0:4be500de690c 494 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
a2824256 0:4be500de690c 495 &ap->bssid[5], &ap->channel);
a2824256 0:4be500de690c 496
a2824256 0:4be500de690c 497 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
a2824256 0:4be500de690c 498
a2824256 0:4be500de690c 499 return ret;
a2824256 0:4be500de690c 500 }
a2824256 0:4be500de690c 501
a2824256 0:4be500de690c 502 void ESP8266::_connect_error_handler()
a2824256 0:4be500de690c 503 {
a2824256 0:4be500de690c 504 _fail = false;
a2824256 0:4be500de690c 505 _connect_error = 0;
a2824256 0:4be500de690c 506
a2824256 0:4be500de690c 507 if (_parser.recv("%d", &_connect_error) && _parser.recv("FAIL")) {
a2824256 0:4be500de690c 508 _fail = true;
a2824256 0:4be500de690c 509 _parser.abort();
a2824256 0:4be500de690c 510 }
a2824256 0:4be500de690c 511 }
a2824256 0:4be500de690c 512
a2824256 0:4be500de690c 513 void ESP8266::_oob_socket0_closed_handler()
a2824256 0:4be500de690c 514 {
a2824256 0:4be500de690c 515 _socket_open[0] = 0;
a2824256 0:4be500de690c 516 }
a2824256 0:4be500de690c 517
a2824256 0:4be500de690c 518 void ESP8266::_oob_socket1_closed_handler()
a2824256 0:4be500de690c 519 {
a2824256 0:4be500de690c 520 _socket_open[1] = 0;
a2824256 0:4be500de690c 521 }
a2824256 0:4be500de690c 522
a2824256 0:4be500de690c 523 void ESP8266::_oob_socket2_closed_handler()
a2824256 0:4be500de690c 524 {
a2824256 0:4be500de690c 525 _socket_open[2] = 0;
a2824256 0:4be500de690c 526 }
a2824256 0:4be500de690c 527
a2824256 0:4be500de690c 528 void ESP8266::_oob_socket3_closed_handler()
a2824256 0:4be500de690c 529 {
a2824256 0:4be500de690c 530 _socket_open[3] = 0;
a2824256 0:4be500de690c 531 }
a2824256 0:4be500de690c 532
a2824256 0:4be500de690c 533 void ESP8266::_oob_socket4_closed_handler()
a2824256 0:4be500de690c 534 {
a2824256 0:4be500de690c 535 _socket_open[4] = 0;
a2824256 0:4be500de690c 536 }
a2824256 0:4be500de690c 537
a2824256 0:4be500de690c 538 int8_t ESP8266::get_default_wifi_mode()
a2824256 0:4be500de690c 539 {
a2824256 0:4be500de690c 540 int8_t mode;
a2824256 0:4be500de690c 541
a2824256 0:4be500de690c 542 _smutex.lock();
a2824256 0:4be500de690c 543 if (_parser.send("AT+CWMODE_DEF?")
a2824256 0:4be500de690c 544 && _parser.recv("+CWMODE_DEF:%hhd", &mode)
a2824256 0:4be500de690c 545 && _parser.recv("OK\n")) {
a2824256 0:4be500de690c 546 _smutex.unlock();
a2824256 0:4be500de690c 547 return mode;
a2824256 0:4be500de690c 548 }
a2824256 0:4be500de690c 549 _smutex.unlock();
a2824256 0:4be500de690c 550
a2824256 0:4be500de690c 551 return 0;
a2824256 0:4be500de690c 552 }
a2824256 0:4be500de690c 553
a2824256 0:4be500de690c 554 bool ESP8266::set_default_wifi_mode(const int8_t mode)
a2824256 0:4be500de690c 555 {
a2824256 0:4be500de690c 556 _smutex.lock();
a2824256 0:4be500de690c 557 bool done = _parser.send("AT+CWMODE_DEF=%hhd", mode)
a2824256 0:4be500de690c 558 && _parser.recv("OK\n");
a2824256 0:4be500de690c 559 _smutex.unlock();
a2824256 0:4be500de690c 560
a2824256 0:4be500de690c 561 return done;
a2824256 0:4be500de690c 562 }