The driver for the ESP32 WiFi module

The ESP32 WiFi driver for Mbed OS

The Mbed OS driver for the ESP32 WiFi module.

Firmware version

How to write mbed-os compatible firmware : https://github.com/d-kato/GR-Boards_ESP32_Serial_Bridge

Restrictions

  • Setting up an UDP server is not possible
  • The serial port does not have hardware flow control enabled. The AT command set does not either have a way to limit the download rate. Therefore, downloading anything larger than the serial port input buffer is unreliable. An application should be able to read fast enough to stay ahead of the network. This affects mostly the TCP protocol where data would be lost with no notification. On UDP, this would lead to only packet losses which the higher layer protocol should recover from.

Committer:
dkato
Date:
Mon Jul 02 02:21:21 2018 +0000
Revision:
1:5d78eedef723
Parent:
0:92d12d355ba9
Child:
2:cb5c0d3fa776
Synchronized with git revision 5407cadab12f6c2a07348950b2fcde42b9d7a050

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:92d12d355ba9 1 /* ESP32 Example
dkato 0:92d12d355ba9 2 * Copyright (c) 2015 ARM Limited
dkato 0:92d12d355ba9 3 * Copyright (c) 2017 Renesas Electronics Corporation
dkato 0:92d12d355ba9 4 *
dkato 0:92d12d355ba9 5 * Licensed under the Apache License, Version 2.0 (the "License");
dkato 0:92d12d355ba9 6 * you may not use this file except in compliance with the License.
dkato 0:92d12d355ba9 7 * You may obtain a copy of the License at
dkato 0:92d12d355ba9 8 *
dkato 0:92d12d355ba9 9 * http://www.apache.org/licenses/LICENSE-2.0
dkato 0:92d12d355ba9 10 *
dkato 0:92d12d355ba9 11 * Unless required by applicable law or agreed to in writing, software
dkato 0:92d12d355ba9 12 * distributed under the License is distributed on an "AS IS" BASIS,
dkato 0:92d12d355ba9 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dkato 0:92d12d355ba9 14 * See the License for the specific language governing permissions and
dkato 0:92d12d355ba9 15 * limitations under the License.
dkato 0:92d12d355ba9 16 */
dkato 0:92d12d355ba9 17
dkato 0:92d12d355ba9 18 #include "ESP32.h"
dkato 0:92d12d355ba9 19
dkato 0:92d12d355ba9 20 #define ESP32_DEFAULT_BAUD_RATE 115200
dkato 1:5d78eedef723 21 #define ESP32_ALL_SOCKET_IDS -1
dkato 0:92d12d355ba9 22
dkato 0:92d12d355ba9 23 ESP32 * ESP32::instESP32 = NULL;
dkato 0:92d12d355ba9 24
dkato 1:5d78eedef723 25 ESP32 * ESP32::getESP32Inst(PinName en, PinName io0, PinName tx, PinName rx, bool debug,
dkato 1:5d78eedef723 26 PinName rts, PinName cts, int baudrate)
dkato 0:92d12d355ba9 27 {
dkato 0:92d12d355ba9 28 if (instESP32 == NULL) {
dkato 1:5d78eedef723 29 instESP32 = new ESP32(en, io0, tx, rx, debug, rts, cts, baudrate);
dkato 0:92d12d355ba9 30 } else {
dkato 0:92d12d355ba9 31 if (debug) {
dkato 0:92d12d355ba9 32 instESP32->debugOn(debug);
dkato 0:92d12d355ba9 33 }
dkato 0:92d12d355ba9 34 }
dkato 0:92d12d355ba9 35 return instESP32;
dkato 0:92d12d355ba9 36 }
dkato 0:92d12d355ba9 37
dkato 1:5d78eedef723 38 ESP32::ESP32(PinName en, PinName io0, PinName tx, PinName rx, bool debug,
dkato 1:5d78eedef723 39 PinName rts, PinName cts, int baudrate)
dkato 0:92d12d355ba9 40 : _p_wifi_en(NULL), _p_wifi_io0(NULL), init_end(false)
dkato 0:92d12d355ba9 41 , _serial(tx, rx, ESP32_DEFAULT_BAUD_RATE), _parser(&_serial, "\r\n", 512)
dkato 0:92d12d355ba9 42 , _packets(0), _packets_end(&_packets)
dkato 0:92d12d355ba9 43 , _id_bits(0), _id_bits_close(0), _server_act(false)
dkato 0:92d12d355ba9 44 , _wifi_status(STATUS_DISCONNECTED)
dkato 0:92d12d355ba9 45 , _wifi_status_cb(NULL)
dkato 0:92d12d355ba9 46 {
dkato 0:92d12d355ba9 47 if ((int)en != NC) {
dkato 0:92d12d355ba9 48 _p_wifi_en = new DigitalOut(en);
dkato 0:92d12d355ba9 49 }
dkato 0:92d12d355ba9 50 if ((int)io0 != NC) {
dkato 0:92d12d355ba9 51 _p_wifi_io0 = new DigitalOut(io0);
dkato 0:92d12d355ba9 52 }
dkato 0:92d12d355ba9 53
dkato 0:92d12d355ba9 54 _wifi_mode = WIFIMODE_STATION;
dkato 0:92d12d355ba9 55 _baudrate = baudrate;
dkato 0:92d12d355ba9 56 memset(_ids, 0, sizeof(_ids));
dkato 0:92d12d355ba9 57 memset(_cbs, 0, sizeof(_cbs));
dkato 0:92d12d355ba9 58
dkato 1:5d78eedef723 59 _rts = rts;
dkato 1:5d78eedef723 60 _cts = cts;
dkato 1:5d78eedef723 61
dkato 1:5d78eedef723 62 if ((_rts != NC) && (_cts != NC)) {
dkato 1:5d78eedef723 63 _flow_control = 3;
dkato 1:5d78eedef723 64 } else if (_rts != NC) {
dkato 1:5d78eedef723 65 _flow_control = 1;
dkato 1:5d78eedef723 66 } else if (_cts != NC) {
dkato 1:5d78eedef723 67 _flow_control = 2;
dkato 1:5d78eedef723 68 } else {
dkato 1:5d78eedef723 69 _flow_control = 0;
dkato 1:5d78eedef723 70 }
dkato 1:5d78eedef723 71
dkato 0:92d12d355ba9 72 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE);
dkato 0:92d12d355ba9 73 debugOn(debug);
dkato 0:92d12d355ba9 74
dkato 0:92d12d355ba9 75 _parser.oob("+IPD", callback(this, &ESP32::_packet_handler));
dkato 0:92d12d355ba9 76 _parser.oob("0,CONNECT", callback(this, &ESP32::_connect_handler_0));
dkato 0:92d12d355ba9 77 _parser.oob("1,CONNECT", callback(this, &ESP32::_connect_handler_1));
dkato 0:92d12d355ba9 78 _parser.oob("2,CONNECT", callback(this, &ESP32::_connect_handler_2));
dkato 0:92d12d355ba9 79 _parser.oob("3,CONNECT", callback(this, &ESP32::_connect_handler_3));
dkato 0:92d12d355ba9 80 _parser.oob("4,CONNECT", callback(this, &ESP32::_connect_handler_4));
dkato 0:92d12d355ba9 81 _parser.oob("0,CLOSED", callback(this, &ESP32::_closed_handler_0));
dkato 0:92d12d355ba9 82 _parser.oob("1,CLOSED", callback(this, &ESP32::_closed_handler_1));
dkato 0:92d12d355ba9 83 _parser.oob("2,CLOSED", callback(this, &ESP32::_closed_handler_2));
dkato 0:92d12d355ba9 84 _parser.oob("3,CLOSED", callback(this, &ESP32::_closed_handler_3));
dkato 0:92d12d355ba9 85 _parser.oob("4,CLOSED", callback(this, &ESP32::_closed_handler_4));
dkato 0:92d12d355ba9 86 _parser.oob("WIFI ", callback(this, &ESP32::_connection_status_handler));
dkato 0:92d12d355ba9 87
dkato 0:92d12d355ba9 88 _serial.sigio(Callback<void()>(this, &ESP32::event));
dkato 1:5d78eedef723 89
dkato 1:5d78eedef723 90 setTimeout();
dkato 0:92d12d355ba9 91 }
dkato 0:92d12d355ba9 92
dkato 0:92d12d355ba9 93 void ESP32::debugOn(bool debug)
dkato 0:92d12d355ba9 94 {
dkato 0:92d12d355ba9 95 _parser.debug_on((debug) ? 1 : 0);
dkato 0:92d12d355ba9 96 }
dkato 0:92d12d355ba9 97
dkato 0:92d12d355ba9 98 int ESP32::get_firmware_version()
dkato 0:92d12d355ba9 99 {
dkato 0:92d12d355ba9 100 int version;
dkato 0:92d12d355ba9 101
dkato 0:92d12d355ba9 102 _smutex.lock();
dkato 1:5d78eedef723 103 startup();
dkato 0:92d12d355ba9 104 bool done = _parser.send("AT+GMR")
dkato 0:92d12d355ba9 105 && _parser.recv("SDK version:%d", &version)
dkato 0:92d12d355ba9 106 && _parser.recv("OK");
dkato 0:92d12d355ba9 107 _smutex.unlock();
dkato 0:92d12d355ba9 108
dkato 0:92d12d355ba9 109 if(done) {
dkato 0:92d12d355ba9 110 return version;
dkato 0:92d12d355ba9 111 } else {
dkato 0:92d12d355ba9 112 // Older firmware versions do not prefix the version with "SDK version: "
dkato 0:92d12d355ba9 113 return -1;
dkato 0:92d12d355ba9 114 }
dkato 0:92d12d355ba9 115 }
dkato 0:92d12d355ba9 116
dkato 0:92d12d355ba9 117 bool ESP32::startup()
dkato 0:92d12d355ba9 118 {
dkato 0:92d12d355ba9 119 if (init_end) {
dkato 0:92d12d355ba9 120 return true;
dkato 0:92d12d355ba9 121 }
dkato 0:92d12d355ba9 122
dkato 0:92d12d355ba9 123 if (_p_wifi_io0 != NULL) {
dkato 0:92d12d355ba9 124 _p_wifi_io0->write(1);
dkato 0:92d12d355ba9 125 }
dkato 0:92d12d355ba9 126 if (_p_wifi_en != NULL) {
dkato 0:92d12d355ba9 127 _p_wifi_en->write(0);
dkato 0:92d12d355ba9 128 Thread::wait(10);
dkato 0:92d12d355ba9 129 _p_wifi_en->write(1);
dkato 0:92d12d355ba9 130 _parser.recv("ready");
dkato 0:92d12d355ba9 131 } else {
dkato 0:92d12d355ba9 132 setTimeout(100);
dkato 0:92d12d355ba9 133 _parser.recv("ready");
dkato 0:92d12d355ba9 134 }
dkato 0:92d12d355ba9 135
dkato 0:92d12d355ba9 136 reset();
dkato 0:92d12d355ba9 137 bool success = _parser.send("AT+CWMODE=%d", _wifi_mode)
dkato 0:92d12d355ba9 138 && _parser.recv("OK")
dkato 0:92d12d355ba9 139 && _parser.send("AT+CIPMUX=1")
dkato 0:92d12d355ba9 140 && _parser.recv("OK")
dkato 0:92d12d355ba9 141 && _parser.send("AT+CWAUTOCONN=0")
dkato 0:92d12d355ba9 142 && _parser.recv("OK")
dkato 0:92d12d355ba9 143 && _parser.send("AT+CWQAP")
dkato 0:92d12d355ba9 144 && _parser.recv("OK");
dkato 0:92d12d355ba9 145 if (success) {
dkato 0:92d12d355ba9 146 init_end = true;
dkato 0:92d12d355ba9 147 }
dkato 0:92d12d355ba9 148
dkato 0:92d12d355ba9 149 return success;
dkato 0:92d12d355ba9 150 }
dkato 0:92d12d355ba9 151
dkato 0:92d12d355ba9 152 bool ESP32::restart()
dkato 0:92d12d355ba9 153 {
dkato 0:92d12d355ba9 154 bool success;
dkato 0:92d12d355ba9 155
dkato 0:92d12d355ba9 156 _smutex.lock();
dkato 0:92d12d355ba9 157 if (!init_end) {
dkato 0:92d12d355ba9 158 success = startup();
dkato 0:92d12d355ba9 159 } else {
dkato 0:92d12d355ba9 160 reset();
dkato 0:92d12d355ba9 161 success = _parser.send("AT+CWMODE=%d", _wifi_mode)
dkato 0:92d12d355ba9 162 && _parser.recv("OK")
dkato 0:92d12d355ba9 163 && _parser.send("AT+CIPMUX=1")
dkato 0:92d12d355ba9 164 && _parser.recv("OK");
dkato 0:92d12d355ba9 165 }
dkato 0:92d12d355ba9 166 _smutex.unlock();
dkato 0:92d12d355ba9 167
dkato 0:92d12d355ba9 168 return success;
dkato 0:92d12d355ba9 169 }
dkato 0:92d12d355ba9 170
dkato 0:92d12d355ba9 171 bool ESP32::set_mode(int mode)
dkato 0:92d12d355ba9 172 {
dkato 0:92d12d355ba9 173 //only 3 valid modes
dkato 0:92d12d355ba9 174 if (mode < 1 || mode > 3) {
dkato 0:92d12d355ba9 175 return false;
dkato 0:92d12d355ba9 176 }
dkato 0:92d12d355ba9 177 if (_wifi_mode != mode) {
dkato 0:92d12d355ba9 178 _wifi_mode = mode;
dkato 0:92d12d355ba9 179 return restart();
dkato 0:92d12d355ba9 180 }
dkato 0:92d12d355ba9 181 return true;
dkato 0:92d12d355ba9 182 }
dkato 0:92d12d355ba9 183
dkato 0:92d12d355ba9 184 bool ESP32::cre_server(int port)
dkato 0:92d12d355ba9 185 {
dkato 0:92d12d355ba9 186 if (_server_act) {
dkato 0:92d12d355ba9 187 return false;
dkato 0:92d12d355ba9 188 }
dkato 0:92d12d355ba9 189 _smutex.lock();
dkato 0:92d12d355ba9 190 startup();
dkato 0:92d12d355ba9 191 if (!(_parser.send("AT+CIPSERVER=1,%d", port)
dkato 0:92d12d355ba9 192 && _parser.recv("OK"))) {
dkato 0:92d12d355ba9 193 _smutex.unlock();
dkato 0:92d12d355ba9 194 return false;
dkato 0:92d12d355ba9 195 }
dkato 0:92d12d355ba9 196 _server_act = true;
dkato 0:92d12d355ba9 197 _smutex.unlock();
dkato 0:92d12d355ba9 198 return true;
dkato 0:92d12d355ba9 199 }
dkato 0:92d12d355ba9 200
dkato 0:92d12d355ba9 201 bool ESP32::del_server()
dkato 0:92d12d355ba9 202 {
dkato 0:92d12d355ba9 203 _smutex.lock();
dkato 0:92d12d355ba9 204 startup();
dkato 0:92d12d355ba9 205 if (!(_parser.send("AT+CIPSERVER=0")
dkato 0:92d12d355ba9 206 && _parser.recv("OK"))) {
dkato 0:92d12d355ba9 207 _smutex.unlock();
dkato 0:92d12d355ba9 208 return false;
dkato 0:92d12d355ba9 209 }
dkato 0:92d12d355ba9 210 _server_act = false;
dkato 0:92d12d355ba9 211 _smutex.unlock();
dkato 0:92d12d355ba9 212 return true;
dkato 0:92d12d355ba9 213 }
dkato 0:92d12d355ba9 214
dkato 0:92d12d355ba9 215 void ESP32::socket_handler(bool connect, int id)
dkato 0:92d12d355ba9 216 {
dkato 0:92d12d355ba9 217 _smutex.lock();
dkato 0:92d12d355ba9 218 startup();
dkato 0:92d12d355ba9 219 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 220 if (connect) {
dkato 0:92d12d355ba9 221 _id_bits |= (1 << id);
dkato 0:92d12d355ba9 222 if (_server_act) {
dkato 0:92d12d355ba9 223 _accept_id.push_back(id);
dkato 0:92d12d355ba9 224 }
dkato 0:92d12d355ba9 225 } else {
dkato 0:92d12d355ba9 226 _id_bits &= ~(1 << id);
dkato 0:92d12d355ba9 227 _id_bits_close |= (1 << id);
dkato 0:92d12d355ba9 228 if (_server_act) {
dkato 0:92d12d355ba9 229 for (size_t i = 0; i < _accept_id.size(); i++) {
dkato 0:92d12d355ba9 230 if (id == _accept_id[i]) {
dkato 0:92d12d355ba9 231 _accept_id.erase(_accept_id.begin() + i);
dkato 0:92d12d355ba9 232 }
dkato 0:92d12d355ba9 233 }
dkato 0:92d12d355ba9 234 }
dkato 0:92d12d355ba9 235 }
dkato 0:92d12d355ba9 236 _smutex.unlock();
dkato 0:92d12d355ba9 237 }
dkato 0:92d12d355ba9 238
dkato 0:92d12d355ba9 239 bool ESP32::accept(int * p_id)
dkato 0:92d12d355ba9 240 {
dkato 0:92d12d355ba9 241 bool ret = false;
dkato 0:92d12d355ba9 242
dkato 0:92d12d355ba9 243 while (!ret) {
dkato 0:92d12d355ba9 244 if (!_server_act) {
dkato 0:92d12d355ba9 245 break;
dkato 0:92d12d355ba9 246 }
dkato 0:92d12d355ba9 247
dkato 0:92d12d355ba9 248 _smutex.lock();
dkato 0:92d12d355ba9 249 startup();
dkato 0:92d12d355ba9 250 if (!_accept_id.empty()) {
dkato 0:92d12d355ba9 251 ret = true;
dkato 0:92d12d355ba9 252 } else {
dkato 0:92d12d355ba9 253 _parser.process_oob(); // Poll for inbound packets
dkato 0:92d12d355ba9 254 if (!_accept_id.empty()) {
dkato 0:92d12d355ba9 255 ret = true;
dkato 0:92d12d355ba9 256 }
dkato 0:92d12d355ba9 257 }
dkato 0:92d12d355ba9 258 if (ret) {
dkato 0:92d12d355ba9 259 *p_id = _accept_id[0];
dkato 0:92d12d355ba9 260 _accept_id.erase(_accept_id.begin());
dkato 0:92d12d355ba9 261 }
dkato 0:92d12d355ba9 262 _smutex.unlock();
dkato 0:92d12d355ba9 263 if (!ret) {
dkato 0:92d12d355ba9 264 Thread::wait(5);
dkato 0:92d12d355ba9 265 }
dkato 0:92d12d355ba9 266 }
dkato 0:92d12d355ba9 267
dkato 0:92d12d355ba9 268 if (ret) {
dkato 0:92d12d355ba9 269 for (int i = 0; i < 50; i++) {
dkato 0:92d12d355ba9 270 if ((_id_bits_close & (1 << *p_id)) == 0) {
dkato 0:92d12d355ba9 271 break;
dkato 0:92d12d355ba9 272 }
dkato 0:92d12d355ba9 273 Thread::wait(10);
dkato 0:92d12d355ba9 274 }
dkato 0:92d12d355ba9 275 }
dkato 0:92d12d355ba9 276
dkato 0:92d12d355ba9 277 return ret;
dkato 0:92d12d355ba9 278 }
dkato 0:92d12d355ba9 279
dkato 0:92d12d355ba9 280 bool ESP32::reset(void)
dkato 0:92d12d355ba9 281 {
dkato 0:92d12d355ba9 282 for (int i = 0; i < 2; i++) {
dkato 0:92d12d355ba9 283 if (_parser.send("AT+RST")
dkato 0:92d12d355ba9 284 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 285 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE);
dkato 1:5d78eedef723 286 #if DEVICE_SERIAL_FC
dkato 1:5d78eedef723 287 _serial.set_flow_control(SerialBase::Disabled);
dkato 1:5d78eedef723 288 #endif
dkato 0:92d12d355ba9 289 _parser.recv("ready");
dkato 1:5d78eedef723 290 _clear_socket_packets(ESP32_ALL_SOCKET_IDS);
dkato 0:92d12d355ba9 291
dkato 0:92d12d355ba9 292 if (_parser.send("AT+UART_CUR=%d,8,1,0,%d", _baudrate, 0)
dkato 0:92d12d355ba9 293 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 294 _serial.set_baud(_baudrate);
dkato 1:5d78eedef723 295 #if DEVICE_SERIAL_FC
dkato 1:5d78eedef723 296 switch (_flow_control) {
dkato 1:5d78eedef723 297 case 1:
dkato 1:5d78eedef723 298 _serial.set_flow_control(SerialBase::RTS, _rts);
dkato 1:5d78eedef723 299 break;
dkato 1:5d78eedef723 300 case 2:
dkato 1:5d78eedef723 301 _serial.set_flow_control(SerialBase::CTS, _cts);
dkato 1:5d78eedef723 302 break;
dkato 1:5d78eedef723 303 case 3:
dkato 1:5d78eedef723 304 _serial.set_flow_control(SerialBase::RTSCTS, _rts, _cts);
dkato 1:5d78eedef723 305 break;
dkato 1:5d78eedef723 306 case 0:
dkato 1:5d78eedef723 307 default:
dkato 1:5d78eedef723 308 // do nothing
dkato 1:5d78eedef723 309 break;
dkato 1:5d78eedef723 310 }
dkato 1:5d78eedef723 311 #endif
dkato 0:92d12d355ba9 312 }
dkato 0:92d12d355ba9 313
dkato 0:92d12d355ba9 314 return true;
dkato 0:92d12d355ba9 315 }
dkato 0:92d12d355ba9 316 }
dkato 0:92d12d355ba9 317
dkato 0:92d12d355ba9 318 return false;
dkato 0:92d12d355ba9 319 }
dkato 0:92d12d355ba9 320
dkato 0:92d12d355ba9 321 bool ESP32::dhcp(bool enabled, int mode)
dkato 0:92d12d355ba9 322 {
dkato 0:92d12d355ba9 323 //only 3 valid modes
dkato 0:92d12d355ba9 324 if (mode < 0 || mode > 2) {
dkato 0:92d12d355ba9 325 return false;
dkato 0:92d12d355ba9 326 }
dkato 0:92d12d355ba9 327
dkato 0:92d12d355ba9 328 _smutex.lock();
dkato 0:92d12d355ba9 329 startup();
dkato 0:92d12d355ba9 330 bool done = _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
dkato 0:92d12d355ba9 331 && _parser.recv("OK");
dkato 0:92d12d355ba9 332 _smutex.unlock();
dkato 0:92d12d355ba9 333
dkato 0:92d12d355ba9 334 return done;
dkato 0:92d12d355ba9 335 }
dkato 0:92d12d355ba9 336
dkato 0:92d12d355ba9 337 bool ESP32::connect(const char *ap, const char *passPhrase)
dkato 0:92d12d355ba9 338 {
dkato 0:92d12d355ba9 339 bool ret;
dkato 0:92d12d355ba9 340
dkato 0:92d12d355ba9 341 _wifi_status = STATUS_DISCONNECTED;
dkato 0:92d12d355ba9 342
dkato 0:92d12d355ba9 343 _smutex.lock();
dkato 0:92d12d355ba9 344 startup();
dkato 0:92d12d355ba9 345
dkato 0:92d12d355ba9 346 setTimeout(ESP32_CONNECT_TIMEOUT);
dkato 0:92d12d355ba9 347 ret = _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
dkato 0:92d12d355ba9 348 && _parser.recv("OK");
dkato 0:92d12d355ba9 349 setTimeout();
dkato 0:92d12d355ba9 350 _smutex.unlock();
dkato 0:92d12d355ba9 351 return ret;
dkato 0:92d12d355ba9 352 }
dkato 0:92d12d355ba9 353
dkato 0:92d12d355ba9 354 bool ESP32::config_soft_ap(const char *ap, const char *passPhrase, uint8_t chl, uint8_t ecn)
dkato 0:92d12d355ba9 355 {
dkato 0:92d12d355ba9 356 bool ret;
dkato 0:92d12d355ba9 357
dkato 0:92d12d355ba9 358 _smutex.lock();
dkato 0:92d12d355ba9 359 startup();
dkato 0:92d12d355ba9 360 ret = _parser.send("AT+CWSAP=\"%s\",\"%s\",%hhu,%hhu", ap, passPhrase, chl, ecn)
dkato 0:92d12d355ba9 361 && _parser.recv("OK");
dkato 0:92d12d355ba9 362 _smutex.unlock();
dkato 0:92d12d355ba9 363 return ret;
dkato 0:92d12d355ba9 364 }
dkato 0:92d12d355ba9 365
dkato 0:92d12d355ba9 366 bool ESP32::get_ssid(char *ap)
dkato 0:92d12d355ba9 367 {
dkato 0:92d12d355ba9 368 bool ret;
dkato 0:92d12d355ba9 369
dkato 0:92d12d355ba9 370 _smutex.lock();
dkato 0:92d12d355ba9 371 startup();
dkato 0:92d12d355ba9 372 ret = _parser.send("AT+CWJAP?")
dkato 0:92d12d355ba9 373 && _parser.recv("+CWJAP:\"%33[^\"]\",", ap)
dkato 0:92d12d355ba9 374 && _parser.recv("OK");
dkato 0:92d12d355ba9 375 _smutex.unlock();
dkato 0:92d12d355ba9 376 return ret;
dkato 0:92d12d355ba9 377 }
dkato 0:92d12d355ba9 378
dkato 0:92d12d355ba9 379 bool ESP32::disconnect(void)
dkato 0:92d12d355ba9 380 {
dkato 0:92d12d355ba9 381 bool ret;
dkato 0:92d12d355ba9 382
dkato 0:92d12d355ba9 383 _smutex.lock();
dkato 0:92d12d355ba9 384 startup();
dkato 0:92d12d355ba9 385 ret = _parser.send("AT+CWQAP") && _parser.recv("OK");
dkato 0:92d12d355ba9 386 _smutex.unlock();
dkato 0:92d12d355ba9 387 return ret;
dkato 0:92d12d355ba9 388 }
dkato 0:92d12d355ba9 389
dkato 0:92d12d355ba9 390 const char *ESP32::getIPAddress(void)
dkato 0:92d12d355ba9 391 {
dkato 0:92d12d355ba9 392 bool ret;
dkato 0:92d12d355ba9 393
dkato 0:92d12d355ba9 394 _smutex.lock();
dkato 0:92d12d355ba9 395 startup();
dkato 0:92d12d355ba9 396 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 397 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
dkato 0:92d12d355ba9 398 && _parser.recv("OK");
dkato 0:92d12d355ba9 399 _smutex.unlock();
dkato 0:92d12d355ba9 400 if (!ret) {
dkato 0:92d12d355ba9 401 return 0;
dkato 0:92d12d355ba9 402 }
dkato 0:92d12d355ba9 403 return _ip_buffer;
dkato 0:92d12d355ba9 404 }
dkato 0:92d12d355ba9 405
dkato 0:92d12d355ba9 406 const char *ESP32::getIPAddress_ap(void)
dkato 0:92d12d355ba9 407 {
dkato 0:92d12d355ba9 408 bool ret;
dkato 0:92d12d355ba9 409
dkato 0:92d12d355ba9 410 _smutex.lock();
dkato 0:92d12d355ba9 411 startup();
dkato 0:92d12d355ba9 412 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 413 && _parser.recv("+CIFSR:APIP,\"%15[^\"]\"", _ip_buffer_ap)
dkato 0:92d12d355ba9 414 && _parser.recv("OK");
dkato 0:92d12d355ba9 415 _smutex.unlock();
dkato 0:92d12d355ba9 416 if (!ret) {
dkato 0:92d12d355ba9 417 return 0;
dkato 0:92d12d355ba9 418 }
dkato 0:92d12d355ba9 419 return _ip_buffer_ap;
dkato 0:92d12d355ba9 420 }
dkato 0:92d12d355ba9 421
dkato 0:92d12d355ba9 422 const char *ESP32::getMACAddress(void)
dkato 0:92d12d355ba9 423 {
dkato 0:92d12d355ba9 424 bool ret;
dkato 0:92d12d355ba9 425
dkato 0:92d12d355ba9 426 _smutex.lock();
dkato 0:92d12d355ba9 427 startup();
dkato 0:92d12d355ba9 428 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 429 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
dkato 0:92d12d355ba9 430 && _parser.recv("OK");
dkato 0:92d12d355ba9 431 _smutex.unlock();
dkato 0:92d12d355ba9 432
dkato 0:92d12d355ba9 433 if (!ret) {
dkato 0:92d12d355ba9 434 return 0;
dkato 0:92d12d355ba9 435 }
dkato 0:92d12d355ba9 436 return _mac_buffer;
dkato 0:92d12d355ba9 437 }
dkato 0:92d12d355ba9 438
dkato 0:92d12d355ba9 439 const char *ESP32::getMACAddress_ap(void)
dkato 0:92d12d355ba9 440 {
dkato 0:92d12d355ba9 441 bool ret;
dkato 0:92d12d355ba9 442
dkato 0:92d12d355ba9 443 _smutex.lock();
dkato 0:92d12d355ba9 444 startup();
dkato 0:92d12d355ba9 445 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 446 && _parser.recv("+CIFSR:APMAC,\"%17[^\"]\"", _mac_buffer_ap)
dkato 0:92d12d355ba9 447 && _parser.recv("OK");
dkato 0:92d12d355ba9 448 _smutex.unlock();
dkato 0:92d12d355ba9 449
dkato 0:92d12d355ba9 450 if (!ret) {
dkato 0:92d12d355ba9 451 return 0;
dkato 0:92d12d355ba9 452 }
dkato 0:92d12d355ba9 453 return _mac_buffer_ap;
dkato 0:92d12d355ba9 454 }
dkato 0:92d12d355ba9 455
dkato 0:92d12d355ba9 456 const char *ESP32::getGateway()
dkato 0:92d12d355ba9 457 {
dkato 0:92d12d355ba9 458 bool ret;
dkato 0:92d12d355ba9 459
dkato 0:92d12d355ba9 460 _smutex.lock();
dkato 0:92d12d355ba9 461 startup();
dkato 0:92d12d355ba9 462 ret = _parser.send("AT+CIPSTA?")
dkato 0:92d12d355ba9 463 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer)
dkato 0:92d12d355ba9 464 && _parser.recv("OK");
dkato 0:92d12d355ba9 465 _smutex.unlock();
dkato 0:92d12d355ba9 466
dkato 0:92d12d355ba9 467 if (!ret) {
dkato 0:92d12d355ba9 468 return 0;
dkato 0:92d12d355ba9 469 }
dkato 0:92d12d355ba9 470 return _gateway_buffer;
dkato 0:92d12d355ba9 471 }
dkato 0:92d12d355ba9 472
dkato 0:92d12d355ba9 473 const char *ESP32::getGateway_ap()
dkato 0:92d12d355ba9 474 {
dkato 0:92d12d355ba9 475 bool ret;
dkato 0:92d12d355ba9 476
dkato 0:92d12d355ba9 477 _smutex.lock();
dkato 0:92d12d355ba9 478 startup();
dkato 0:92d12d355ba9 479 ret = _parser.send("AT+CIPAP?")
dkato 0:92d12d355ba9 480 && _parser.recv("+CIPAP:gateway:\"%15[^\"]\"", _gateway_buffer_ap)
dkato 0:92d12d355ba9 481 && _parser.recv("OK");
dkato 0:92d12d355ba9 482 _smutex.unlock();
dkato 0:92d12d355ba9 483
dkato 0:92d12d355ba9 484 if (!ret) {
dkato 0:92d12d355ba9 485 return 0;
dkato 0:92d12d355ba9 486 }
dkato 0:92d12d355ba9 487 return _gateway_buffer_ap;
dkato 0:92d12d355ba9 488 }
dkato 0:92d12d355ba9 489
dkato 0:92d12d355ba9 490 const char *ESP32::getNetmask()
dkato 0:92d12d355ba9 491 {
dkato 0:92d12d355ba9 492 bool ret;
dkato 0:92d12d355ba9 493
dkato 0:92d12d355ba9 494 _smutex.lock();
dkato 0:92d12d355ba9 495 startup();
dkato 0:92d12d355ba9 496 ret = _parser.send("AT+CIPSTA?")
dkato 0:92d12d355ba9 497 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer)
dkato 0:92d12d355ba9 498 && _parser.recv("OK");
dkato 0:92d12d355ba9 499 _smutex.unlock();
dkato 0:92d12d355ba9 500
dkato 0:92d12d355ba9 501 if (!ret) {
dkato 0:92d12d355ba9 502 return 0;
dkato 0:92d12d355ba9 503 }
dkato 0:92d12d355ba9 504 return _netmask_buffer;
dkato 0:92d12d355ba9 505 }
dkato 0:92d12d355ba9 506
dkato 0:92d12d355ba9 507 const char *ESP32::getNetmask_ap()
dkato 0:92d12d355ba9 508 {
dkato 0:92d12d355ba9 509 bool ret;
dkato 0:92d12d355ba9 510
dkato 0:92d12d355ba9 511 _smutex.lock();
dkato 0:92d12d355ba9 512 startup();
dkato 0:92d12d355ba9 513 ret = _parser.send("AT+CIPAP?")
dkato 0:92d12d355ba9 514 && _parser.recv("+CIPAP:netmask:\"%15[^\"]\"", _netmask_buffer_ap)
dkato 0:92d12d355ba9 515 && _parser.recv("OK");
dkato 0:92d12d355ba9 516 _smutex.unlock();
dkato 0:92d12d355ba9 517
dkato 0:92d12d355ba9 518 if (!ret) {
dkato 0:92d12d355ba9 519 return 0;
dkato 0:92d12d355ba9 520 }
dkato 0:92d12d355ba9 521 return _netmask_buffer_ap;
dkato 0:92d12d355ba9 522 }
dkato 0:92d12d355ba9 523
dkato 0:92d12d355ba9 524 int8_t ESP32::getRSSI()
dkato 0:92d12d355ba9 525 {
dkato 0:92d12d355ba9 526 bool ret;
dkato 0:92d12d355ba9 527 int8_t rssi;
dkato 0:92d12d355ba9 528 char ssid[33];
dkato 0:92d12d355ba9 529 char bssid[18];
dkato 0:92d12d355ba9 530
dkato 0:92d12d355ba9 531 _smutex.lock();
dkato 0:92d12d355ba9 532 startup();
dkato 0:92d12d355ba9 533 ret = _parser.send("AT+CWJAP?")
dkato 0:92d12d355ba9 534 && _parser.recv("+CWJAP:\"%32[^\"]\",\"%17[^\"]\"", ssid, bssid)
dkato 0:92d12d355ba9 535 && _parser.recv("OK");
dkato 0:92d12d355ba9 536 if (!ret) {
dkato 0:92d12d355ba9 537 _smutex.unlock();
dkato 0:92d12d355ba9 538 return 0;
dkato 0:92d12d355ba9 539 }
dkato 0:92d12d355ba9 540
dkato 0:92d12d355ba9 541 ret = _parser.send("AT+CWLAP=\"%s\",\"%s\"", ssid, bssid)
dkato 0:92d12d355ba9 542 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
dkato 0:92d12d355ba9 543 && _parser.recv("OK");
dkato 0:92d12d355ba9 544 _smutex.unlock();
dkato 0:92d12d355ba9 545
dkato 0:92d12d355ba9 546 if (!ret) {
dkato 0:92d12d355ba9 547 return 0;
dkato 0:92d12d355ba9 548 }
dkato 0:92d12d355ba9 549
dkato 0:92d12d355ba9 550 return rssi;
dkato 0:92d12d355ba9 551 }
dkato 0:92d12d355ba9 552
dkato 0:92d12d355ba9 553 int ESP32::scan(WiFiAccessPoint *res, unsigned limit)
dkato 0:92d12d355ba9 554 {
dkato 0:92d12d355ba9 555 unsigned cnt = 0;
dkato 0:92d12d355ba9 556 nsapi_wifi_ap_t ap;
dkato 0:92d12d355ba9 557
dkato 0:92d12d355ba9 558 if (!init_end) {
dkato 0:92d12d355ba9 559 _smutex.lock();
dkato 0:92d12d355ba9 560 startup();
dkato 0:92d12d355ba9 561 _smutex.unlock();
dkato 0:92d12d355ba9 562 Thread::wait(1500);
dkato 0:92d12d355ba9 563 }
dkato 0:92d12d355ba9 564
dkato 0:92d12d355ba9 565 _smutex.lock();
dkato 0:92d12d355ba9 566 setTimeout(5000);
dkato 0:92d12d355ba9 567 if (!_parser.send("AT+CWLAP")) {
dkato 0:92d12d355ba9 568 _smutex.unlock();
dkato 0:92d12d355ba9 569 return NSAPI_ERROR_DEVICE_ERROR;
dkato 0:92d12d355ba9 570 }
dkato 0:92d12d355ba9 571
dkato 0:92d12d355ba9 572 while (recv_ap(&ap)) {
dkato 0:92d12d355ba9 573 if (cnt < limit) {
dkato 0:92d12d355ba9 574 res[cnt] = WiFiAccessPoint(ap);
dkato 0:92d12d355ba9 575 }
dkato 0:92d12d355ba9 576
dkato 0:92d12d355ba9 577 cnt++;
dkato 0:92d12d355ba9 578 if ((limit != 0) && (cnt >= limit)) {
dkato 0:92d12d355ba9 579 break;
dkato 0:92d12d355ba9 580 }
dkato 0:92d12d355ba9 581 setTimeout(500);
dkato 0:92d12d355ba9 582 }
dkato 0:92d12d355ba9 583 setTimeout(10);
dkato 0:92d12d355ba9 584 _parser.recv("OK");
dkato 0:92d12d355ba9 585 setTimeout();
dkato 0:92d12d355ba9 586 _smutex.unlock();
dkato 0:92d12d355ba9 587
dkato 0:92d12d355ba9 588 return cnt;
dkato 0:92d12d355ba9 589 }
dkato 0:92d12d355ba9 590
dkato 0:92d12d355ba9 591 bool ESP32::isConnected(void)
dkato 0:92d12d355ba9 592 {
dkato 0:92d12d355ba9 593 return getIPAddress() != 0;
dkato 0:92d12d355ba9 594 }
dkato 0:92d12d355ba9 595
dkato 0:92d12d355ba9 596 bool ESP32::open(const char *type, int id, const char* addr, int port, int opt)
dkato 0:92d12d355ba9 597 {
dkato 0:92d12d355ba9 598 bool ret;
dkato 0:92d12d355ba9 599
dkato 0:92d12d355ba9 600 if (id >= SOCKET_COUNT) {
dkato 0:92d12d355ba9 601 return false;
dkato 0:92d12d355ba9 602 }
dkato 0:92d12d355ba9 603 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 604
dkato 0:92d12d355ba9 605 _smutex.lock();
dkato 0:92d12d355ba9 606 startup();
dkato 0:92d12d355ba9 607 setTimeout(500);
dkato 0:92d12d355ba9 608 if (opt != 0) {
dkato 0:92d12d355ba9 609 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d, %d", id, type, addr, port, opt)
dkato 0:92d12d355ba9 610 && _parser.recv("OK");
dkato 0:92d12d355ba9 611 } else {
dkato 0:92d12d355ba9 612 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
dkato 0:92d12d355ba9 613 && _parser.recv("OK");
dkato 0:92d12d355ba9 614 }
dkato 0:92d12d355ba9 615 setTimeout();
dkato 1:5d78eedef723 616 _clear_socket_packets(id);
dkato 0:92d12d355ba9 617 _smutex.unlock();
dkato 0:92d12d355ba9 618
dkato 0:92d12d355ba9 619 return ret;
dkato 0:92d12d355ba9 620 }
dkato 0:92d12d355ba9 621
dkato 0:92d12d355ba9 622 bool ESP32::send(int id, const void *data, uint32_t amount)
dkato 0:92d12d355ba9 623 {
dkato 0:92d12d355ba9 624 int send_size;
dkato 0:92d12d355ba9 625 bool ret;
dkato 0:92d12d355ba9 626 int error_cnt = 0;
dkato 0:92d12d355ba9 627 int index = 0;
dkato 0:92d12d355ba9 628
dkato 0:92d12d355ba9 629 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 630 if (amount == 0) {
dkato 0:92d12d355ba9 631 return true;
dkato 0:92d12d355ba9 632 }
dkato 0:92d12d355ba9 633
dkato 0:92d12d355ba9 634 //May take a second try if device is busy
dkato 0:92d12d355ba9 635 while (error_cnt < 2) {
dkato 0:92d12d355ba9 636 if (((_id_bits & (1 << id)) == 0)
dkato 0:92d12d355ba9 637 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 0:92d12d355ba9 638 return false;
dkato 0:92d12d355ba9 639 }
dkato 0:92d12d355ba9 640 send_size = amount;
dkato 0:92d12d355ba9 641 if (send_size > 2048) {
dkato 0:92d12d355ba9 642 send_size = 2048;
dkato 0:92d12d355ba9 643 }
dkato 0:92d12d355ba9 644 _smutex.lock();
dkato 0:92d12d355ba9 645 startup();
dkato 0:92d12d355ba9 646 ret = _parser.send("AT+CIPSEND=%d,%d", id, send_size)
dkato 0:92d12d355ba9 647 && _parser.recv(">")
dkato 0:92d12d355ba9 648 && (_parser.write((char*)data + index, (int)send_size) >= 0)
dkato 0:92d12d355ba9 649 && _parser.recv("SEND OK");
dkato 0:92d12d355ba9 650 _smutex.unlock();
dkato 0:92d12d355ba9 651 if (ret) {
dkato 0:92d12d355ba9 652 amount -= send_size;
dkato 0:92d12d355ba9 653 index += send_size;
dkato 0:92d12d355ba9 654 error_cnt = 0;
dkato 0:92d12d355ba9 655 if (amount == 0) {
dkato 0:92d12d355ba9 656 return true;
dkato 0:92d12d355ba9 657 }
dkato 0:92d12d355ba9 658 } else {
dkato 0:92d12d355ba9 659 error_cnt++;
dkato 0:92d12d355ba9 660 }
dkato 0:92d12d355ba9 661 }
dkato 0:92d12d355ba9 662
dkato 0:92d12d355ba9 663 return false;
dkato 0:92d12d355ba9 664 }
dkato 0:92d12d355ba9 665
dkato 0:92d12d355ba9 666 void ESP32::_packet_handler()
dkato 0:92d12d355ba9 667 {
dkato 0:92d12d355ba9 668 int id;
dkato 0:92d12d355ba9 669 int amount;
dkato 1:5d78eedef723 670 uint32_t tmp_timeout;
dkato 0:92d12d355ba9 671
dkato 0:92d12d355ba9 672 // parse out the packet
dkato 0:92d12d355ba9 673 if (!_parser.recv(",%d,%d:", &id, &amount)) {
dkato 0:92d12d355ba9 674 return;
dkato 0:92d12d355ba9 675 }
dkato 0:92d12d355ba9 676
dkato 0:92d12d355ba9 677 struct packet *packet = (struct packet*)malloc(
dkato 0:92d12d355ba9 678 sizeof(struct packet) + amount);
dkato 0:92d12d355ba9 679 if (!packet) {
dkato 0:92d12d355ba9 680 return;
dkato 0:92d12d355ba9 681 }
dkato 0:92d12d355ba9 682
dkato 0:92d12d355ba9 683 packet->id = id;
dkato 0:92d12d355ba9 684 packet->len = amount;
dkato 0:92d12d355ba9 685 packet->next = 0;
dkato 0:92d12d355ba9 686 packet->index = 0;
dkato 0:92d12d355ba9 687
dkato 1:5d78eedef723 688 tmp_timeout = last_timeout_ms;
dkato 1:5d78eedef723 689 setTimeout(500);
dkato 0:92d12d355ba9 690 if (!(_parser.read((char*)(packet + 1), amount))) {
dkato 0:92d12d355ba9 691 free(packet);
dkato 1:5d78eedef723 692 setTimeout(tmp_timeout);
dkato 0:92d12d355ba9 693 return;
dkato 0:92d12d355ba9 694 }
dkato 0:92d12d355ba9 695
dkato 0:92d12d355ba9 696 // append to packet list
dkato 0:92d12d355ba9 697 *_packets_end = packet;
dkato 0:92d12d355ba9 698 _packets_end = &packet->next;
dkato 0:92d12d355ba9 699 }
dkato 0:92d12d355ba9 700
dkato 0:92d12d355ba9 701 int32_t ESP32::recv(int id, void *data, uint32_t amount, uint32_t timeout)
dkato 0:92d12d355ba9 702 {
dkato 0:92d12d355ba9 703 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 704
dkato 0:92d12d355ba9 705 _smutex.lock();
dkato 0:92d12d355ba9 706 setTimeout(timeout);
dkato 0:92d12d355ba9 707 _parser.process_oob(); // Poll for inbound packets
dkato 0:92d12d355ba9 708 setTimeout();
dkato 0:92d12d355ba9 709
dkato 0:92d12d355ba9 710 // check if any packets are ready for us
dkato 0:92d12d355ba9 711 for (struct packet **p = &_packets; *p; p = &(*p)->next) {
dkato 0:92d12d355ba9 712 if ((*p)->id == id) {
dkato 0:92d12d355ba9 713 struct packet *q = *p;
dkato 0:92d12d355ba9 714
dkato 0:92d12d355ba9 715 if (q->len <= amount) { // Return and remove full packet
dkato 0:92d12d355ba9 716 memcpy(data, (uint8_t*)(q+1) + q->index, q->len);
dkato 0:92d12d355ba9 717
dkato 0:92d12d355ba9 718 if (_packets_end == &(*p)->next) {
dkato 0:92d12d355ba9 719 _packets_end = p;
dkato 0:92d12d355ba9 720 }
dkato 0:92d12d355ba9 721 *p = (*p)->next;
dkato 0:92d12d355ba9 722 _smutex.unlock();
dkato 0:92d12d355ba9 723
dkato 0:92d12d355ba9 724 uint32_t len = q->len;
dkato 0:92d12d355ba9 725 free(q);
dkato 0:92d12d355ba9 726 return len;
dkato 0:92d12d355ba9 727 } else { // return only partial packet
dkato 0:92d12d355ba9 728 memcpy(data, (uint8_t*)(q+1) + q->index, amount);
dkato 0:92d12d355ba9 729
dkato 0:92d12d355ba9 730 q->len -= amount;
dkato 0:92d12d355ba9 731 q->index += amount;
dkato 0:92d12d355ba9 732
dkato 0:92d12d355ba9 733 _smutex.unlock();
dkato 0:92d12d355ba9 734 return amount;
dkato 0:92d12d355ba9 735 }
dkato 0:92d12d355ba9 736 }
dkato 0:92d12d355ba9 737 }
dkato 0:92d12d355ba9 738 _smutex.unlock();
dkato 0:92d12d355ba9 739
dkato 0:92d12d355ba9 740 if (((_id_bits & (1 << id)) == 0)
dkato 0:92d12d355ba9 741 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 0:92d12d355ba9 742 return -2;
dkato 0:92d12d355ba9 743 } else {
dkato 0:92d12d355ba9 744 return -1;
dkato 0:92d12d355ba9 745 }
dkato 0:92d12d355ba9 746 }
dkato 0:92d12d355ba9 747
dkato 1:5d78eedef723 748 void ESP32::_clear_socket_packets(int id)
dkato 1:5d78eedef723 749 {
dkato 1:5d78eedef723 750 struct packet **p = &_packets;
dkato 1:5d78eedef723 751
dkato 1:5d78eedef723 752 while (*p) {
dkato 1:5d78eedef723 753 if ((*p)->id == id || id == ESP32_ALL_SOCKET_IDS) {
dkato 1:5d78eedef723 754 struct packet *q = *p;
dkato 1:5d78eedef723 755
dkato 1:5d78eedef723 756 if (_packets_end == &(*p)->next) {
dkato 1:5d78eedef723 757 _packets_end = p; // Set last packet next field/_packets
dkato 1:5d78eedef723 758 }
dkato 1:5d78eedef723 759 *p = (*p)->next;
dkato 1:5d78eedef723 760
dkato 1:5d78eedef723 761 free(q);
dkato 1:5d78eedef723 762 } else {
dkato 1:5d78eedef723 763 // Point to last packet next field
dkato 1:5d78eedef723 764 p = &(*p)->next;
dkato 1:5d78eedef723 765 }
dkato 1:5d78eedef723 766 }
dkato 1:5d78eedef723 767 }
dkato 1:5d78eedef723 768
dkato 0:92d12d355ba9 769 bool ESP32::close(int id, bool wait_close)
dkato 0:92d12d355ba9 770 {
dkato 0:92d12d355ba9 771 if (wait_close) {
dkato 1:5d78eedef723 772 _smutex.lock();
dkato 0:92d12d355ba9 773 for (int j = 0; j < 2; j++) {
dkato 0:92d12d355ba9 774 if (((_id_bits & (1 << id)) == 0)
dkato 0:92d12d355ba9 775 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 0:92d12d355ba9 776 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 777 _ids[id] = false;
dkato 1:5d78eedef723 778 _clear_socket_packets(id);
dkato 1:5d78eedef723 779 _smutex.unlock();
dkato 0:92d12d355ba9 780 return true;
dkato 0:92d12d355ba9 781 }
dkato 0:92d12d355ba9 782 startup();
dkato 0:92d12d355ba9 783 setTimeout(500);
dkato 0:92d12d355ba9 784 _parser.process_oob(); // Poll for inbound packets
dkato 0:92d12d355ba9 785 setTimeout();
dkato 0:92d12d355ba9 786 }
dkato 1:5d78eedef723 787 _smutex.unlock();
dkato 0:92d12d355ba9 788 }
dkato 0:92d12d355ba9 789
dkato 0:92d12d355ba9 790 //May take a second try if device is busy
dkato 0:92d12d355ba9 791 for (unsigned i = 0; i < 2; i++) {
dkato 1:5d78eedef723 792 _smutex.lock();
dkato 0:92d12d355ba9 793 if ((_id_bits & (1 << id)) == 0) {
dkato 0:92d12d355ba9 794 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 795 _ids[id] = false;
dkato 1:5d78eedef723 796 _clear_socket_packets(id);
dkato 1:5d78eedef723 797 _smutex.unlock();
dkato 0:92d12d355ba9 798 return true;
dkato 0:92d12d355ba9 799 }
dkato 0:92d12d355ba9 800 startup();
dkato 0:92d12d355ba9 801 setTimeout(500);
dkato 0:92d12d355ba9 802 if (_parser.send("AT+CIPCLOSE=%d", id)
dkato 0:92d12d355ba9 803 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 804 setTimeout();
dkato 1:5d78eedef723 805 _clear_socket_packets(id);
dkato 0:92d12d355ba9 806 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 807 _ids[id] = false;
dkato 1:5d78eedef723 808 _smutex.unlock();
dkato 0:92d12d355ba9 809 return true;
dkato 0:92d12d355ba9 810 }
dkato 0:92d12d355ba9 811 setTimeout();
dkato 0:92d12d355ba9 812 _smutex.unlock();
dkato 0:92d12d355ba9 813 }
dkato 0:92d12d355ba9 814
dkato 0:92d12d355ba9 815 _ids[id] = false;
dkato 0:92d12d355ba9 816 return false;
dkato 0:92d12d355ba9 817 }
dkato 0:92d12d355ba9 818
dkato 0:92d12d355ba9 819 void ESP32::setTimeout(uint32_t timeout_ms)
dkato 0:92d12d355ba9 820 {
dkato 1:5d78eedef723 821 last_timeout_ms = timeout_ms;
dkato 0:92d12d355ba9 822 _parser.set_timeout(timeout_ms);
dkato 0:92d12d355ba9 823 }
dkato 0:92d12d355ba9 824
dkato 0:92d12d355ba9 825 bool ESP32::readable()
dkato 0:92d12d355ba9 826 {
dkato 0:92d12d355ba9 827 return _serial.FileHandle::readable();
dkato 0:92d12d355ba9 828 }
dkato 0:92d12d355ba9 829
dkato 0:92d12d355ba9 830 bool ESP32::writeable()
dkato 0:92d12d355ba9 831 {
dkato 0:92d12d355ba9 832 return _serial.FileHandle::writable();
dkato 0:92d12d355ba9 833 }
dkato 0:92d12d355ba9 834
dkato 0:92d12d355ba9 835 void ESP32::socket_attach(int id, void (*callback)(void *), void *data)
dkato 0:92d12d355ba9 836 {
dkato 0:92d12d355ba9 837 _cbs[id].callback = callback;
dkato 0:92d12d355ba9 838 _cbs[id].data = data;
dkato 0:92d12d355ba9 839 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 840 }
dkato 0:92d12d355ba9 841
dkato 0:92d12d355ba9 842 bool ESP32::recv_ap(nsapi_wifi_ap_t *ap)
dkato 0:92d12d355ba9 843 {
dkato 0:92d12d355ba9 844 int sec;
dkato 0:92d12d355ba9 845 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%hhu)", &sec, ap->ssid,
dkato 0:92d12d355ba9 846 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
dkato 0:92d12d355ba9 847 &ap->bssid[5], &ap->channel);
dkato 0:92d12d355ba9 848
dkato 0:92d12d355ba9 849 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
dkato 0:92d12d355ba9 850
dkato 0:92d12d355ba9 851 return ret;
dkato 0:92d12d355ba9 852 }
dkato 0:92d12d355ba9 853
dkato 0:92d12d355ba9 854 void ESP32::_connect_handler_0() { socket_handler(true, 0); }
dkato 0:92d12d355ba9 855 void ESP32::_connect_handler_1() { socket_handler(true, 1); }
dkato 0:92d12d355ba9 856 void ESP32::_connect_handler_2() { socket_handler(true, 2); }
dkato 0:92d12d355ba9 857 void ESP32::_connect_handler_3() { socket_handler(true, 3); }
dkato 0:92d12d355ba9 858 void ESP32::_connect_handler_4() { socket_handler(true, 4); }
dkato 0:92d12d355ba9 859 void ESP32::_closed_handler_0() { socket_handler(false, 0); }
dkato 0:92d12d355ba9 860 void ESP32::_closed_handler_1() { socket_handler(false, 1); }
dkato 0:92d12d355ba9 861 void ESP32::_closed_handler_2() { socket_handler(false, 2); }
dkato 0:92d12d355ba9 862 void ESP32::_closed_handler_3() { socket_handler(false, 3); }
dkato 0:92d12d355ba9 863 void ESP32::_closed_handler_4() { socket_handler(false, 4); }
dkato 0:92d12d355ba9 864
dkato 0:92d12d355ba9 865 void ESP32::_connection_status_handler()
dkato 0:92d12d355ba9 866 {
dkato 0:92d12d355ba9 867 char status[13];
dkato 0:92d12d355ba9 868 if (_parser.recv("%12[^\"]\n", status)) {
dkato 0:92d12d355ba9 869 if (strcmp(status, "CONNECTED\n") == 0) {
dkato 0:92d12d355ba9 870 _wifi_status = STATUS_CONNECTED;
dkato 0:92d12d355ba9 871 } else if (strcmp(status, "GOT IP\n") == 0) {
dkato 0:92d12d355ba9 872 _wifi_status = STATUS_GOT_IP;
dkato 0:92d12d355ba9 873 } else if (strcmp(status, "DISCONNECT\n") == 0) {
dkato 0:92d12d355ba9 874 _wifi_status = STATUS_DISCONNECTED;
dkato 0:92d12d355ba9 875 } else {
dkato 0:92d12d355ba9 876 return;
dkato 0:92d12d355ba9 877 }
dkato 0:92d12d355ba9 878
dkato 0:92d12d355ba9 879 if(_wifi_status_cb) {
dkato 0:92d12d355ba9 880 _wifi_status_cb(_wifi_status);
dkato 0:92d12d355ba9 881 }
dkato 0:92d12d355ba9 882 }
dkato 0:92d12d355ba9 883 }
dkato 0:92d12d355ba9 884
dkato 0:92d12d355ba9 885 int ESP32::get_free_id()
dkato 0:92d12d355ba9 886 {
dkato 0:92d12d355ba9 887 // Look for an unused socket
dkato 0:92d12d355ba9 888 int id = -1;
dkato 0:92d12d355ba9 889
dkato 0:92d12d355ba9 890 for (int i = 0; i < SOCKET_COUNT; i++) {
dkato 0:92d12d355ba9 891 if ((!_ids[i]) && ((_id_bits & (1 << i)) == 0)) {
dkato 0:92d12d355ba9 892 id = i;
dkato 0:92d12d355ba9 893 _ids[i] = true;
dkato 0:92d12d355ba9 894 break;
dkato 0:92d12d355ba9 895 }
dkato 0:92d12d355ba9 896 }
dkato 0:92d12d355ba9 897
dkato 0:92d12d355ba9 898 return id;
dkato 0:92d12d355ba9 899 }
dkato 0:92d12d355ba9 900
dkato 0:92d12d355ba9 901 void ESP32::event() {
dkato 0:92d12d355ba9 902 for (int i = 0; i < SOCKET_COUNT; i++) {
dkato 0:92d12d355ba9 903 if ((_cbs[i].callback) && (_cbs[i].Notified == 0)) {
dkato 0:92d12d355ba9 904 _cbs[i].callback(_cbs[i].data);
dkato 0:92d12d355ba9 905 _cbs[i].Notified = 1;
dkato 0:92d12d355ba9 906 }
dkato 0:92d12d355ba9 907 }
dkato 0:92d12d355ba9 908 }
dkato 0:92d12d355ba9 909
dkato 0:92d12d355ba9 910 bool ESP32::set_network(const char *ip_address, const char *netmask, const char *gateway)
dkato 0:92d12d355ba9 911 {
dkato 0:92d12d355ba9 912 bool ret;
dkato 0:92d12d355ba9 913
dkato 0:92d12d355ba9 914 if (ip_address == NULL) {
dkato 0:92d12d355ba9 915 return false;
dkato 0:92d12d355ba9 916 }
dkato 0:92d12d355ba9 917
dkato 0:92d12d355ba9 918 _smutex.lock();
dkato 0:92d12d355ba9 919 if ((netmask != NULL) && (gateway != NULL)) {
dkato 0:92d12d355ba9 920 ret = _parser.send("AT+CIPSTA=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask)
dkato 0:92d12d355ba9 921 && _parser.recv("OK");
dkato 0:92d12d355ba9 922 } else {
dkato 0:92d12d355ba9 923 ret = _parser.send("AT+CIPSTA=\"%s\"", ip_address)
dkato 0:92d12d355ba9 924 && _parser.recv("OK");
dkato 0:92d12d355ba9 925 }
dkato 0:92d12d355ba9 926 _smutex.unlock();
dkato 0:92d12d355ba9 927
dkato 0:92d12d355ba9 928 return ret;
dkato 0:92d12d355ba9 929 }
dkato 0:92d12d355ba9 930
dkato 0:92d12d355ba9 931 bool ESP32::set_network_ap(const char *ip_address, const char *netmask, const char *gateway)
dkato 0:92d12d355ba9 932 {
dkato 0:92d12d355ba9 933 bool ret;
dkato 0:92d12d355ba9 934
dkato 0:92d12d355ba9 935 if (ip_address == NULL) {
dkato 0:92d12d355ba9 936 return false;
dkato 0:92d12d355ba9 937 }
dkato 0:92d12d355ba9 938
dkato 0:92d12d355ba9 939 _smutex.lock();
dkato 0:92d12d355ba9 940 if ((netmask != NULL) && (gateway != NULL)) {
dkato 0:92d12d355ba9 941 ret = _parser.send("AT+CIPAP=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask)
dkato 0:92d12d355ba9 942 && _parser.recv("OK");
dkato 0:92d12d355ba9 943 } else {
dkato 0:92d12d355ba9 944 ret = _parser.send("AT+CIPAP=\"%s\"", ip_address)
dkato 0:92d12d355ba9 945 && _parser.recv("OK");
dkato 0:92d12d355ba9 946 }
dkato 0:92d12d355ba9 947 _smutex.unlock();
dkato 0:92d12d355ba9 948
dkato 0:92d12d355ba9 949 return ret;
dkato 0:92d12d355ba9 950 }
dkato 0:92d12d355ba9 951
dkato 0:92d12d355ba9 952 void ESP32::attach_wifi_status(mbed::Callback<void(int8_t)> status_cb)
dkato 0:92d12d355ba9 953 {
dkato 0:92d12d355ba9 954 _wifi_status_cb = status_cb;
dkato 0:92d12d355ba9 955 }
dkato 0:92d12d355ba9 956
dkato 0:92d12d355ba9 957 int8_t ESP32::get_wifi_status() const
dkato 0:92d12d355ba9 958 {
dkato 0:92d12d355ba9 959 return _wifi_status;
dkato 0:92d12d355ba9 960 }
dkato 0:92d12d355ba9 961