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 09 10:26:03 2018 +0000
Revision:
2:cb5c0d3fa776
Parent:
1:5d78eedef723
Synchronized with git revision 78a139f3bce17e23f2b4bd9342dd7adca023d248

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 2:cb5c0d3fa776 41 , _serial(tx, rx, ESP32_DEFAULT_BAUD_RATE), _parser(&_serial, "\r\n")
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 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 218 if (connect) {
dkato 0:92d12d355ba9 219 _id_bits |= (1 << id);
dkato 0:92d12d355ba9 220 if (_server_act) {
dkato 0:92d12d355ba9 221 _accept_id.push_back(id);
dkato 0:92d12d355ba9 222 }
dkato 0:92d12d355ba9 223 } else {
dkato 0:92d12d355ba9 224 _id_bits &= ~(1 << id);
dkato 0:92d12d355ba9 225 _id_bits_close |= (1 << id);
dkato 0:92d12d355ba9 226 if (_server_act) {
dkato 0:92d12d355ba9 227 for (size_t i = 0; i < _accept_id.size(); i++) {
dkato 0:92d12d355ba9 228 if (id == _accept_id[i]) {
dkato 0:92d12d355ba9 229 _accept_id.erase(_accept_id.begin() + i);
dkato 0:92d12d355ba9 230 }
dkato 0:92d12d355ba9 231 }
dkato 0:92d12d355ba9 232 }
dkato 0:92d12d355ba9 233 }
dkato 0:92d12d355ba9 234 }
dkato 0:92d12d355ba9 235
dkato 0:92d12d355ba9 236 bool ESP32::accept(int * p_id)
dkato 0:92d12d355ba9 237 {
dkato 0:92d12d355ba9 238 bool ret = false;
dkato 0:92d12d355ba9 239
dkato 0:92d12d355ba9 240 while (!ret) {
dkato 0:92d12d355ba9 241 if (!_server_act) {
dkato 0:92d12d355ba9 242 break;
dkato 0:92d12d355ba9 243 }
dkato 0:92d12d355ba9 244
dkato 0:92d12d355ba9 245 _smutex.lock();
dkato 0:92d12d355ba9 246 startup();
dkato 0:92d12d355ba9 247 if (!_accept_id.empty()) {
dkato 0:92d12d355ba9 248 ret = true;
dkato 0:92d12d355ba9 249 } else {
dkato 0:92d12d355ba9 250 _parser.process_oob(); // Poll for inbound packets
dkato 0:92d12d355ba9 251 if (!_accept_id.empty()) {
dkato 0:92d12d355ba9 252 ret = true;
dkato 0:92d12d355ba9 253 }
dkato 0:92d12d355ba9 254 }
dkato 0:92d12d355ba9 255 if (ret) {
dkato 0:92d12d355ba9 256 *p_id = _accept_id[0];
dkato 0:92d12d355ba9 257 _accept_id.erase(_accept_id.begin());
dkato 0:92d12d355ba9 258 }
dkato 0:92d12d355ba9 259 _smutex.unlock();
dkato 0:92d12d355ba9 260 if (!ret) {
dkato 0:92d12d355ba9 261 Thread::wait(5);
dkato 0:92d12d355ba9 262 }
dkato 0:92d12d355ba9 263 }
dkato 0:92d12d355ba9 264
dkato 0:92d12d355ba9 265 if (ret) {
dkato 0:92d12d355ba9 266 for (int i = 0; i < 50; i++) {
dkato 0:92d12d355ba9 267 if ((_id_bits_close & (1 << *p_id)) == 0) {
dkato 0:92d12d355ba9 268 break;
dkato 0:92d12d355ba9 269 }
dkato 0:92d12d355ba9 270 Thread::wait(10);
dkato 0:92d12d355ba9 271 }
dkato 0:92d12d355ba9 272 }
dkato 0:92d12d355ba9 273
dkato 0:92d12d355ba9 274 return ret;
dkato 0:92d12d355ba9 275 }
dkato 0:92d12d355ba9 276
dkato 0:92d12d355ba9 277 bool ESP32::reset(void)
dkato 0:92d12d355ba9 278 {
dkato 0:92d12d355ba9 279 for (int i = 0; i < 2; i++) {
dkato 0:92d12d355ba9 280 if (_parser.send("AT+RST")
dkato 0:92d12d355ba9 281 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 282 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE);
dkato 1:5d78eedef723 283 #if DEVICE_SERIAL_FC
dkato 1:5d78eedef723 284 _serial.set_flow_control(SerialBase::Disabled);
dkato 1:5d78eedef723 285 #endif
dkato 0:92d12d355ba9 286 _parser.recv("ready");
dkato 1:5d78eedef723 287 _clear_socket_packets(ESP32_ALL_SOCKET_IDS);
dkato 0:92d12d355ba9 288
dkato 2:cb5c0d3fa776 289 if (_parser.send("AT+UART_CUR=%d,8,1,0,%d", _baudrate, _flow_control)
dkato 0:92d12d355ba9 290 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 291 _serial.set_baud(_baudrate);
dkato 1:5d78eedef723 292 #if DEVICE_SERIAL_FC
dkato 1:5d78eedef723 293 switch (_flow_control) {
dkato 1:5d78eedef723 294 case 1:
dkato 1:5d78eedef723 295 _serial.set_flow_control(SerialBase::RTS, _rts);
dkato 1:5d78eedef723 296 break;
dkato 1:5d78eedef723 297 case 2:
dkato 1:5d78eedef723 298 _serial.set_flow_control(SerialBase::CTS, _cts);
dkato 1:5d78eedef723 299 break;
dkato 1:5d78eedef723 300 case 3:
dkato 1:5d78eedef723 301 _serial.set_flow_control(SerialBase::RTSCTS, _rts, _cts);
dkato 1:5d78eedef723 302 break;
dkato 1:5d78eedef723 303 case 0:
dkato 1:5d78eedef723 304 default:
dkato 1:5d78eedef723 305 // do nothing
dkato 1:5d78eedef723 306 break;
dkato 1:5d78eedef723 307 }
dkato 1:5d78eedef723 308 #endif
dkato 0:92d12d355ba9 309 }
dkato 0:92d12d355ba9 310
dkato 0:92d12d355ba9 311 return true;
dkato 0:92d12d355ba9 312 }
dkato 0:92d12d355ba9 313 }
dkato 0:92d12d355ba9 314
dkato 0:92d12d355ba9 315 return false;
dkato 0:92d12d355ba9 316 }
dkato 0:92d12d355ba9 317
dkato 0:92d12d355ba9 318 bool ESP32::dhcp(bool enabled, int mode)
dkato 0:92d12d355ba9 319 {
dkato 0:92d12d355ba9 320 //only 3 valid modes
dkato 0:92d12d355ba9 321 if (mode < 0 || mode > 2) {
dkato 0:92d12d355ba9 322 return false;
dkato 0:92d12d355ba9 323 }
dkato 0:92d12d355ba9 324
dkato 0:92d12d355ba9 325 _smutex.lock();
dkato 0:92d12d355ba9 326 startup();
dkato 0:92d12d355ba9 327 bool done = _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
dkato 0:92d12d355ba9 328 && _parser.recv("OK");
dkato 0:92d12d355ba9 329 _smutex.unlock();
dkato 0:92d12d355ba9 330
dkato 0:92d12d355ba9 331 return done;
dkato 0:92d12d355ba9 332 }
dkato 0:92d12d355ba9 333
dkato 0:92d12d355ba9 334 bool ESP32::connect(const char *ap, const char *passPhrase)
dkato 0:92d12d355ba9 335 {
dkato 0:92d12d355ba9 336 bool ret;
dkato 0:92d12d355ba9 337
dkato 0:92d12d355ba9 338 _wifi_status = STATUS_DISCONNECTED;
dkato 0:92d12d355ba9 339
dkato 0:92d12d355ba9 340 _smutex.lock();
dkato 0:92d12d355ba9 341 startup();
dkato 0:92d12d355ba9 342
dkato 0:92d12d355ba9 343 setTimeout(ESP32_CONNECT_TIMEOUT);
dkato 0:92d12d355ba9 344 ret = _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
dkato 0:92d12d355ba9 345 && _parser.recv("OK");
dkato 0:92d12d355ba9 346 setTimeout();
dkato 0:92d12d355ba9 347 _smutex.unlock();
dkato 0:92d12d355ba9 348 return ret;
dkato 0:92d12d355ba9 349 }
dkato 0:92d12d355ba9 350
dkato 0:92d12d355ba9 351 bool ESP32::config_soft_ap(const char *ap, const char *passPhrase, uint8_t chl, uint8_t ecn)
dkato 0:92d12d355ba9 352 {
dkato 0:92d12d355ba9 353 bool ret;
dkato 0:92d12d355ba9 354
dkato 0:92d12d355ba9 355 _smutex.lock();
dkato 0:92d12d355ba9 356 startup();
dkato 0:92d12d355ba9 357 ret = _parser.send("AT+CWSAP=\"%s\",\"%s\",%hhu,%hhu", ap, passPhrase, chl, ecn)
dkato 0:92d12d355ba9 358 && _parser.recv("OK");
dkato 0:92d12d355ba9 359 _smutex.unlock();
dkato 0:92d12d355ba9 360 return ret;
dkato 0:92d12d355ba9 361 }
dkato 0:92d12d355ba9 362
dkato 0:92d12d355ba9 363 bool ESP32::get_ssid(char *ap)
dkato 0:92d12d355ba9 364 {
dkato 0:92d12d355ba9 365 bool ret;
dkato 0:92d12d355ba9 366
dkato 0:92d12d355ba9 367 _smutex.lock();
dkato 0:92d12d355ba9 368 startup();
dkato 0:92d12d355ba9 369 ret = _parser.send("AT+CWJAP?")
dkato 0:92d12d355ba9 370 && _parser.recv("+CWJAP:\"%33[^\"]\",", ap)
dkato 0:92d12d355ba9 371 && _parser.recv("OK");
dkato 0:92d12d355ba9 372 _smutex.unlock();
dkato 0:92d12d355ba9 373 return ret;
dkato 0:92d12d355ba9 374 }
dkato 0:92d12d355ba9 375
dkato 0:92d12d355ba9 376 bool ESP32::disconnect(void)
dkato 0:92d12d355ba9 377 {
dkato 0:92d12d355ba9 378 bool ret;
dkato 0:92d12d355ba9 379
dkato 0:92d12d355ba9 380 _smutex.lock();
dkato 0:92d12d355ba9 381 startup();
dkato 0:92d12d355ba9 382 ret = _parser.send("AT+CWQAP") && _parser.recv("OK");
dkato 0:92d12d355ba9 383 _smutex.unlock();
dkato 0:92d12d355ba9 384 return ret;
dkato 0:92d12d355ba9 385 }
dkato 0:92d12d355ba9 386
dkato 0:92d12d355ba9 387 const char *ESP32::getIPAddress(void)
dkato 0:92d12d355ba9 388 {
dkato 0:92d12d355ba9 389 bool ret;
dkato 0:92d12d355ba9 390
dkato 0:92d12d355ba9 391 _smutex.lock();
dkato 0:92d12d355ba9 392 startup();
dkato 0:92d12d355ba9 393 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 394 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
dkato 0:92d12d355ba9 395 && _parser.recv("OK");
dkato 0:92d12d355ba9 396 _smutex.unlock();
dkato 0:92d12d355ba9 397 if (!ret) {
dkato 0:92d12d355ba9 398 return 0;
dkato 0:92d12d355ba9 399 }
dkato 0:92d12d355ba9 400 return _ip_buffer;
dkato 0:92d12d355ba9 401 }
dkato 0:92d12d355ba9 402
dkato 0:92d12d355ba9 403 const char *ESP32::getIPAddress_ap(void)
dkato 0:92d12d355ba9 404 {
dkato 0:92d12d355ba9 405 bool ret;
dkato 0:92d12d355ba9 406
dkato 0:92d12d355ba9 407 _smutex.lock();
dkato 0:92d12d355ba9 408 startup();
dkato 0:92d12d355ba9 409 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 410 && _parser.recv("+CIFSR:APIP,\"%15[^\"]\"", _ip_buffer_ap)
dkato 0:92d12d355ba9 411 && _parser.recv("OK");
dkato 0:92d12d355ba9 412 _smutex.unlock();
dkato 0:92d12d355ba9 413 if (!ret) {
dkato 0:92d12d355ba9 414 return 0;
dkato 0:92d12d355ba9 415 }
dkato 0:92d12d355ba9 416 return _ip_buffer_ap;
dkato 0:92d12d355ba9 417 }
dkato 0:92d12d355ba9 418
dkato 0:92d12d355ba9 419 const char *ESP32::getMACAddress(void)
dkato 0:92d12d355ba9 420 {
dkato 0:92d12d355ba9 421 bool ret;
dkato 0:92d12d355ba9 422
dkato 0:92d12d355ba9 423 _smutex.lock();
dkato 0:92d12d355ba9 424 startup();
dkato 0:92d12d355ba9 425 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 426 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
dkato 0:92d12d355ba9 427 && _parser.recv("OK");
dkato 0:92d12d355ba9 428 _smutex.unlock();
dkato 0:92d12d355ba9 429
dkato 0:92d12d355ba9 430 if (!ret) {
dkato 0:92d12d355ba9 431 return 0;
dkato 0:92d12d355ba9 432 }
dkato 0:92d12d355ba9 433 return _mac_buffer;
dkato 0:92d12d355ba9 434 }
dkato 0:92d12d355ba9 435
dkato 0:92d12d355ba9 436 const char *ESP32::getMACAddress_ap(void)
dkato 0:92d12d355ba9 437 {
dkato 0:92d12d355ba9 438 bool ret;
dkato 0:92d12d355ba9 439
dkato 0:92d12d355ba9 440 _smutex.lock();
dkato 0:92d12d355ba9 441 startup();
dkato 0:92d12d355ba9 442 ret = _parser.send("AT+CIFSR")
dkato 0:92d12d355ba9 443 && _parser.recv("+CIFSR:APMAC,\"%17[^\"]\"", _mac_buffer_ap)
dkato 0:92d12d355ba9 444 && _parser.recv("OK");
dkato 0:92d12d355ba9 445 _smutex.unlock();
dkato 0:92d12d355ba9 446
dkato 0:92d12d355ba9 447 if (!ret) {
dkato 0:92d12d355ba9 448 return 0;
dkato 0:92d12d355ba9 449 }
dkato 0:92d12d355ba9 450 return _mac_buffer_ap;
dkato 0:92d12d355ba9 451 }
dkato 0:92d12d355ba9 452
dkato 0:92d12d355ba9 453 const char *ESP32::getGateway()
dkato 0:92d12d355ba9 454 {
dkato 0:92d12d355ba9 455 bool ret;
dkato 0:92d12d355ba9 456
dkato 0:92d12d355ba9 457 _smutex.lock();
dkato 0:92d12d355ba9 458 startup();
dkato 0:92d12d355ba9 459 ret = _parser.send("AT+CIPSTA?")
dkato 0:92d12d355ba9 460 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer)
dkato 0:92d12d355ba9 461 && _parser.recv("OK");
dkato 0:92d12d355ba9 462 _smutex.unlock();
dkato 0:92d12d355ba9 463
dkato 0:92d12d355ba9 464 if (!ret) {
dkato 0:92d12d355ba9 465 return 0;
dkato 0:92d12d355ba9 466 }
dkato 0:92d12d355ba9 467 return _gateway_buffer;
dkato 0:92d12d355ba9 468 }
dkato 0:92d12d355ba9 469
dkato 0:92d12d355ba9 470 const char *ESP32::getGateway_ap()
dkato 0:92d12d355ba9 471 {
dkato 0:92d12d355ba9 472 bool ret;
dkato 0:92d12d355ba9 473
dkato 0:92d12d355ba9 474 _smutex.lock();
dkato 0:92d12d355ba9 475 startup();
dkato 0:92d12d355ba9 476 ret = _parser.send("AT+CIPAP?")
dkato 0:92d12d355ba9 477 && _parser.recv("+CIPAP:gateway:\"%15[^\"]\"", _gateway_buffer_ap)
dkato 0:92d12d355ba9 478 && _parser.recv("OK");
dkato 0:92d12d355ba9 479 _smutex.unlock();
dkato 0:92d12d355ba9 480
dkato 0:92d12d355ba9 481 if (!ret) {
dkato 0:92d12d355ba9 482 return 0;
dkato 0:92d12d355ba9 483 }
dkato 0:92d12d355ba9 484 return _gateway_buffer_ap;
dkato 0:92d12d355ba9 485 }
dkato 0:92d12d355ba9 486
dkato 0:92d12d355ba9 487 const char *ESP32::getNetmask()
dkato 0:92d12d355ba9 488 {
dkato 0:92d12d355ba9 489 bool ret;
dkato 0:92d12d355ba9 490
dkato 0:92d12d355ba9 491 _smutex.lock();
dkato 0:92d12d355ba9 492 startup();
dkato 0:92d12d355ba9 493 ret = _parser.send("AT+CIPSTA?")
dkato 0:92d12d355ba9 494 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer)
dkato 0:92d12d355ba9 495 && _parser.recv("OK");
dkato 0:92d12d355ba9 496 _smutex.unlock();
dkato 0:92d12d355ba9 497
dkato 0:92d12d355ba9 498 if (!ret) {
dkato 0:92d12d355ba9 499 return 0;
dkato 0:92d12d355ba9 500 }
dkato 0:92d12d355ba9 501 return _netmask_buffer;
dkato 0:92d12d355ba9 502 }
dkato 0:92d12d355ba9 503
dkato 0:92d12d355ba9 504 const char *ESP32::getNetmask_ap()
dkato 0:92d12d355ba9 505 {
dkato 0:92d12d355ba9 506 bool ret;
dkato 0:92d12d355ba9 507
dkato 0:92d12d355ba9 508 _smutex.lock();
dkato 0:92d12d355ba9 509 startup();
dkato 0:92d12d355ba9 510 ret = _parser.send("AT+CIPAP?")
dkato 0:92d12d355ba9 511 && _parser.recv("+CIPAP:netmask:\"%15[^\"]\"", _netmask_buffer_ap)
dkato 0:92d12d355ba9 512 && _parser.recv("OK");
dkato 0:92d12d355ba9 513 _smutex.unlock();
dkato 0:92d12d355ba9 514
dkato 0:92d12d355ba9 515 if (!ret) {
dkato 0:92d12d355ba9 516 return 0;
dkato 0:92d12d355ba9 517 }
dkato 0:92d12d355ba9 518 return _netmask_buffer_ap;
dkato 0:92d12d355ba9 519 }
dkato 0:92d12d355ba9 520
dkato 0:92d12d355ba9 521 int8_t ESP32::getRSSI()
dkato 0:92d12d355ba9 522 {
dkato 0:92d12d355ba9 523 bool ret;
dkato 0:92d12d355ba9 524 int8_t rssi;
dkato 0:92d12d355ba9 525 char ssid[33];
dkato 0:92d12d355ba9 526 char bssid[18];
dkato 0:92d12d355ba9 527
dkato 0:92d12d355ba9 528 _smutex.lock();
dkato 0:92d12d355ba9 529 startup();
dkato 0:92d12d355ba9 530 ret = _parser.send("AT+CWJAP?")
dkato 0:92d12d355ba9 531 && _parser.recv("+CWJAP:\"%32[^\"]\",\"%17[^\"]\"", ssid, bssid)
dkato 0:92d12d355ba9 532 && _parser.recv("OK");
dkato 0:92d12d355ba9 533 if (!ret) {
dkato 0:92d12d355ba9 534 _smutex.unlock();
dkato 0:92d12d355ba9 535 return 0;
dkato 0:92d12d355ba9 536 }
dkato 0:92d12d355ba9 537
dkato 0:92d12d355ba9 538 ret = _parser.send("AT+CWLAP=\"%s\",\"%s\"", ssid, bssid)
dkato 0:92d12d355ba9 539 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
dkato 0:92d12d355ba9 540 && _parser.recv("OK");
dkato 0:92d12d355ba9 541 _smutex.unlock();
dkato 0:92d12d355ba9 542
dkato 0:92d12d355ba9 543 if (!ret) {
dkato 0:92d12d355ba9 544 return 0;
dkato 0:92d12d355ba9 545 }
dkato 0:92d12d355ba9 546
dkato 0:92d12d355ba9 547 return rssi;
dkato 0:92d12d355ba9 548 }
dkato 0:92d12d355ba9 549
dkato 0:92d12d355ba9 550 int ESP32::scan(WiFiAccessPoint *res, unsigned limit)
dkato 0:92d12d355ba9 551 {
dkato 0:92d12d355ba9 552 unsigned cnt = 0;
dkato 0:92d12d355ba9 553 nsapi_wifi_ap_t ap;
dkato 0:92d12d355ba9 554
dkato 0:92d12d355ba9 555 if (!init_end) {
dkato 0:92d12d355ba9 556 _smutex.lock();
dkato 0:92d12d355ba9 557 startup();
dkato 0:92d12d355ba9 558 _smutex.unlock();
dkato 0:92d12d355ba9 559 Thread::wait(1500);
dkato 0:92d12d355ba9 560 }
dkato 0:92d12d355ba9 561
dkato 0:92d12d355ba9 562 _smutex.lock();
dkato 0:92d12d355ba9 563 setTimeout(5000);
dkato 0:92d12d355ba9 564 if (!_parser.send("AT+CWLAP")) {
dkato 0:92d12d355ba9 565 _smutex.unlock();
dkato 0:92d12d355ba9 566 return NSAPI_ERROR_DEVICE_ERROR;
dkato 0:92d12d355ba9 567 }
dkato 0:92d12d355ba9 568
dkato 0:92d12d355ba9 569 while (recv_ap(&ap)) {
dkato 0:92d12d355ba9 570 if (cnt < limit) {
dkato 0:92d12d355ba9 571 res[cnt] = WiFiAccessPoint(ap);
dkato 0:92d12d355ba9 572 }
dkato 0:92d12d355ba9 573
dkato 0:92d12d355ba9 574 cnt++;
dkato 0:92d12d355ba9 575 if ((limit != 0) && (cnt >= limit)) {
dkato 0:92d12d355ba9 576 break;
dkato 0:92d12d355ba9 577 }
dkato 0:92d12d355ba9 578 setTimeout(500);
dkato 0:92d12d355ba9 579 }
dkato 0:92d12d355ba9 580 setTimeout(10);
dkato 0:92d12d355ba9 581 _parser.recv("OK");
dkato 0:92d12d355ba9 582 setTimeout();
dkato 0:92d12d355ba9 583 _smutex.unlock();
dkato 0:92d12d355ba9 584
dkato 0:92d12d355ba9 585 return cnt;
dkato 0:92d12d355ba9 586 }
dkato 0:92d12d355ba9 587
dkato 0:92d12d355ba9 588 bool ESP32::isConnected(void)
dkato 0:92d12d355ba9 589 {
dkato 0:92d12d355ba9 590 return getIPAddress() != 0;
dkato 0:92d12d355ba9 591 }
dkato 0:92d12d355ba9 592
dkato 0:92d12d355ba9 593 bool ESP32::open(const char *type, int id, const char* addr, int port, int opt)
dkato 0:92d12d355ba9 594 {
dkato 0:92d12d355ba9 595 bool ret;
dkato 0:92d12d355ba9 596
dkato 0:92d12d355ba9 597 if (id >= SOCKET_COUNT) {
dkato 0:92d12d355ba9 598 return false;
dkato 0:92d12d355ba9 599 }
dkato 0:92d12d355ba9 600 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 601
dkato 0:92d12d355ba9 602 _smutex.lock();
dkato 0:92d12d355ba9 603 startup();
dkato 0:92d12d355ba9 604 setTimeout(500);
dkato 0:92d12d355ba9 605 if (opt != 0) {
dkato 0:92d12d355ba9 606 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d, %d", id, type, addr, port, opt)
dkato 0:92d12d355ba9 607 && _parser.recv("OK");
dkato 0:92d12d355ba9 608 } else {
dkato 0:92d12d355ba9 609 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
dkato 0:92d12d355ba9 610 && _parser.recv("OK");
dkato 0:92d12d355ba9 611 }
dkato 0:92d12d355ba9 612 setTimeout();
dkato 1:5d78eedef723 613 _clear_socket_packets(id);
dkato 0:92d12d355ba9 614 _smutex.unlock();
dkato 0:92d12d355ba9 615
dkato 0:92d12d355ba9 616 return ret;
dkato 0:92d12d355ba9 617 }
dkato 0:92d12d355ba9 618
dkato 0:92d12d355ba9 619 bool ESP32::send(int id, const void *data, uint32_t amount)
dkato 0:92d12d355ba9 620 {
dkato 0:92d12d355ba9 621 int send_size;
dkato 0:92d12d355ba9 622 bool ret;
dkato 0:92d12d355ba9 623 int error_cnt = 0;
dkato 0:92d12d355ba9 624 int index = 0;
dkato 0:92d12d355ba9 625
dkato 0:92d12d355ba9 626 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 627 if (amount == 0) {
dkato 0:92d12d355ba9 628 return true;
dkato 0:92d12d355ba9 629 }
dkato 0:92d12d355ba9 630
dkato 0:92d12d355ba9 631 //May take a second try if device is busy
dkato 2:cb5c0d3fa776 632 _smutex.lock();
dkato 0:92d12d355ba9 633 while (error_cnt < 2) {
dkato 0:92d12d355ba9 634 if (((_id_bits & (1 << id)) == 0)
dkato 0:92d12d355ba9 635 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 2:cb5c0d3fa776 636 _smutex.unlock();
dkato 0:92d12d355ba9 637 return false;
dkato 0:92d12d355ba9 638 }
dkato 0:92d12d355ba9 639 send_size = amount;
dkato 0:92d12d355ba9 640 if (send_size > 2048) {
dkato 0:92d12d355ba9 641 send_size = 2048;
dkato 0:92d12d355ba9 642 }
dkato 0:92d12d355ba9 643 startup();
dkato 0:92d12d355ba9 644 ret = _parser.send("AT+CIPSEND=%d,%d", id, send_size)
dkato 0:92d12d355ba9 645 && _parser.recv(">")
dkato 0:92d12d355ba9 646 && (_parser.write((char*)data + index, (int)send_size) >= 0)
dkato 0:92d12d355ba9 647 && _parser.recv("SEND OK");
dkato 0:92d12d355ba9 648 if (ret) {
dkato 0:92d12d355ba9 649 amount -= send_size;
dkato 0:92d12d355ba9 650 index += send_size;
dkato 0:92d12d355ba9 651 error_cnt = 0;
dkato 0:92d12d355ba9 652 if (amount == 0) {
dkato 2:cb5c0d3fa776 653 _smutex.unlock();
dkato 0:92d12d355ba9 654 return true;
dkato 0:92d12d355ba9 655 }
dkato 0:92d12d355ba9 656 } else {
dkato 0:92d12d355ba9 657 error_cnt++;
dkato 0:92d12d355ba9 658 }
dkato 0:92d12d355ba9 659 }
dkato 2:cb5c0d3fa776 660 _smutex.unlock();
dkato 0:92d12d355ba9 661
dkato 0:92d12d355ba9 662 return false;
dkato 0:92d12d355ba9 663 }
dkato 0:92d12d355ba9 664
dkato 0:92d12d355ba9 665 void ESP32::_packet_handler()
dkato 0:92d12d355ba9 666 {
dkato 0:92d12d355ba9 667 int id;
dkato 0:92d12d355ba9 668 int amount;
dkato 1:5d78eedef723 669 uint32_t tmp_timeout;
dkato 0:92d12d355ba9 670
dkato 0:92d12d355ba9 671 // parse out the packet
dkato 0:92d12d355ba9 672 if (!_parser.recv(",%d,%d:", &id, &amount)) {
dkato 0:92d12d355ba9 673 return;
dkato 0:92d12d355ba9 674 }
dkato 0:92d12d355ba9 675
dkato 0:92d12d355ba9 676 struct packet *packet = (struct packet*)malloc(
dkato 0:92d12d355ba9 677 sizeof(struct packet) + amount);
dkato 0:92d12d355ba9 678 if (!packet) {
dkato 0:92d12d355ba9 679 return;
dkato 0:92d12d355ba9 680 }
dkato 0:92d12d355ba9 681
dkato 0:92d12d355ba9 682 packet->id = id;
dkato 0:92d12d355ba9 683 packet->len = amount;
dkato 0:92d12d355ba9 684 packet->next = 0;
dkato 0:92d12d355ba9 685 packet->index = 0;
dkato 0:92d12d355ba9 686
dkato 1:5d78eedef723 687 tmp_timeout = last_timeout_ms;
dkato 1:5d78eedef723 688 setTimeout(500);
dkato 0:92d12d355ba9 689 if (!(_parser.read((char*)(packet + 1), amount))) {
dkato 0:92d12d355ba9 690 free(packet);
dkato 1:5d78eedef723 691 setTimeout(tmp_timeout);
dkato 0:92d12d355ba9 692 return;
dkato 0:92d12d355ba9 693 }
dkato 0:92d12d355ba9 694
dkato 0:92d12d355ba9 695 // append to packet list
dkato 0:92d12d355ba9 696 *_packets_end = packet;
dkato 0:92d12d355ba9 697 _packets_end = &packet->next;
dkato 0:92d12d355ba9 698 }
dkato 0:92d12d355ba9 699
dkato 0:92d12d355ba9 700 int32_t ESP32::recv(int id, void *data, uint32_t amount, uint32_t timeout)
dkato 0:92d12d355ba9 701 {
dkato 2:cb5c0d3fa776 702 struct packet **p;
dkato 2:cb5c0d3fa776 703 uint32_t retry_cnt = 0;
dkato 2:cb5c0d3fa776 704 uint32_t idx = 0;
dkato 2:cb5c0d3fa776 705
dkato 0:92d12d355ba9 706 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 707
dkato 2:cb5c0d3fa776 708 while (1) {
dkato 2:cb5c0d3fa776 709 _smutex.lock();
dkato 2:cb5c0d3fa776 710 if (_rts == NC) {
dkato 2:cb5c0d3fa776 711 setTimeout(1);
dkato 2:cb5c0d3fa776 712 while (_parser.process_oob()); // Poll for inbound packets
dkato 2:cb5c0d3fa776 713 setTimeout();
dkato 2:cb5c0d3fa776 714 } else if ((retry_cnt != 0) ||(_packets == NULL)) {
dkato 2:cb5c0d3fa776 715 setTimeout(1);
dkato 2:cb5c0d3fa776 716 _parser.process_oob(); // Poll for inbound packets
dkato 2:cb5c0d3fa776 717 setTimeout();
dkato 2:cb5c0d3fa776 718 } else {
dkato 2:cb5c0d3fa776 719 // do nothing
dkato 2:cb5c0d3fa776 720 }
dkato 0:92d12d355ba9 721
dkato 2:cb5c0d3fa776 722 // check if any packets are ready for us
dkato 2:cb5c0d3fa776 723 p = &_packets;
dkato 2:cb5c0d3fa776 724 while (*p) {
dkato 2:cb5c0d3fa776 725 if ((*p)->id == id) {
dkato 2:cb5c0d3fa776 726 struct packet *q = *p;
dkato 0:92d12d355ba9 727
dkato 2:cb5c0d3fa776 728 if (q->len <= amount) { // Return and remove full packet
dkato 2:cb5c0d3fa776 729 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, q->len);
dkato 2:cb5c0d3fa776 730 if (_packets_end == &(*p)->next) {
dkato 2:cb5c0d3fa776 731 _packets_end = p;
dkato 2:cb5c0d3fa776 732 }
dkato 2:cb5c0d3fa776 733 *p = (*p)->next;
dkato 2:cb5c0d3fa776 734 idx += q->len;
dkato 2:cb5c0d3fa776 735 amount -= q->len;
dkato 2:cb5c0d3fa776 736 free(q);
dkato 2:cb5c0d3fa776 737 } else { // return only partial packet
dkato 2:cb5c0d3fa776 738 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, amount);
dkato 2:cb5c0d3fa776 739 q->len -= amount;
dkato 2:cb5c0d3fa776 740 q->index += amount;
dkato 2:cb5c0d3fa776 741 idx += amount;
dkato 2:cb5c0d3fa776 742 break;
dkato 2:cb5c0d3fa776 743 }
dkato 2:cb5c0d3fa776 744 } else {
dkato 2:cb5c0d3fa776 745 p = &(*p)->next;
dkato 0:92d12d355ba9 746 }
dkato 0:92d12d355ba9 747 }
dkato 2:cb5c0d3fa776 748 if (idx > 0) {
dkato 2:cb5c0d3fa776 749 _smutex.unlock();
dkato 2:cb5c0d3fa776 750 return idx;
dkato 2:cb5c0d3fa776 751 }
dkato 2:cb5c0d3fa776 752 if (retry_cnt >= timeout) {
dkato 2:cb5c0d3fa776 753 if (((_id_bits & (1 << id)) == 0)
dkato 2:cb5c0d3fa776 754 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 2:cb5c0d3fa776 755 _smutex.unlock();
dkato 2:cb5c0d3fa776 756 return -2;
dkato 2:cb5c0d3fa776 757 } else {
dkato 2:cb5c0d3fa776 758 _smutex.unlock();
dkato 2:cb5c0d3fa776 759 return -1;
dkato 2:cb5c0d3fa776 760 }
dkato 2:cb5c0d3fa776 761 }
dkato 2:cb5c0d3fa776 762 retry_cnt++;
dkato 2:cb5c0d3fa776 763 _smutex.unlock();
dkato 2:cb5c0d3fa776 764 Thread::wait(1);
dkato 0:92d12d355ba9 765 }
dkato 0:92d12d355ba9 766 }
dkato 0:92d12d355ba9 767
dkato 1:5d78eedef723 768 void ESP32::_clear_socket_packets(int id)
dkato 1:5d78eedef723 769 {
dkato 1:5d78eedef723 770 struct packet **p = &_packets;
dkato 1:5d78eedef723 771
dkato 1:5d78eedef723 772 while (*p) {
dkato 1:5d78eedef723 773 if ((*p)->id == id || id == ESP32_ALL_SOCKET_IDS) {
dkato 1:5d78eedef723 774 struct packet *q = *p;
dkato 1:5d78eedef723 775
dkato 1:5d78eedef723 776 if (_packets_end == &(*p)->next) {
dkato 1:5d78eedef723 777 _packets_end = p; // Set last packet next field/_packets
dkato 1:5d78eedef723 778 }
dkato 1:5d78eedef723 779 *p = (*p)->next;
dkato 1:5d78eedef723 780
dkato 1:5d78eedef723 781 free(q);
dkato 1:5d78eedef723 782 } else {
dkato 1:5d78eedef723 783 // Point to last packet next field
dkato 1:5d78eedef723 784 p = &(*p)->next;
dkato 1:5d78eedef723 785 }
dkato 1:5d78eedef723 786 }
dkato 1:5d78eedef723 787 }
dkato 1:5d78eedef723 788
dkato 0:92d12d355ba9 789 bool ESP32::close(int id, bool wait_close)
dkato 0:92d12d355ba9 790 {
dkato 0:92d12d355ba9 791 if (wait_close) {
dkato 1:5d78eedef723 792 _smutex.lock();
dkato 0:92d12d355ba9 793 for (int j = 0; j < 2; j++) {
dkato 0:92d12d355ba9 794 if (((_id_bits & (1 << id)) == 0)
dkato 0:92d12d355ba9 795 || ((_id_bits_close & (1 << id)) != 0)) {
dkato 0:92d12d355ba9 796 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 797 _ids[id] = false;
dkato 1:5d78eedef723 798 _clear_socket_packets(id);
dkato 1:5d78eedef723 799 _smutex.unlock();
dkato 0:92d12d355ba9 800 return true;
dkato 0:92d12d355ba9 801 }
dkato 0:92d12d355ba9 802 startup();
dkato 0:92d12d355ba9 803 setTimeout(500);
dkato 0:92d12d355ba9 804 _parser.process_oob(); // Poll for inbound packets
dkato 0:92d12d355ba9 805 setTimeout();
dkato 0:92d12d355ba9 806 }
dkato 1:5d78eedef723 807 _smutex.unlock();
dkato 0:92d12d355ba9 808 }
dkato 0:92d12d355ba9 809
dkato 0:92d12d355ba9 810 //May take a second try if device is busy
dkato 0:92d12d355ba9 811 for (unsigned i = 0; i < 2; i++) {
dkato 1:5d78eedef723 812 _smutex.lock();
dkato 0:92d12d355ba9 813 if ((_id_bits & (1 << id)) == 0) {
dkato 0:92d12d355ba9 814 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 815 _ids[id] = false;
dkato 1:5d78eedef723 816 _clear_socket_packets(id);
dkato 1:5d78eedef723 817 _smutex.unlock();
dkato 0:92d12d355ba9 818 return true;
dkato 0:92d12d355ba9 819 }
dkato 0:92d12d355ba9 820 startup();
dkato 0:92d12d355ba9 821 setTimeout(500);
dkato 0:92d12d355ba9 822 if (_parser.send("AT+CIPCLOSE=%d", id)
dkato 0:92d12d355ba9 823 && _parser.recv("OK")) {
dkato 0:92d12d355ba9 824 setTimeout();
dkato 1:5d78eedef723 825 _clear_socket_packets(id);
dkato 0:92d12d355ba9 826 _id_bits_close &= ~(1 << id);
dkato 0:92d12d355ba9 827 _ids[id] = false;
dkato 1:5d78eedef723 828 _smutex.unlock();
dkato 0:92d12d355ba9 829 return true;
dkato 0:92d12d355ba9 830 }
dkato 0:92d12d355ba9 831 setTimeout();
dkato 0:92d12d355ba9 832 _smutex.unlock();
dkato 0:92d12d355ba9 833 }
dkato 0:92d12d355ba9 834
dkato 0:92d12d355ba9 835 _ids[id] = false;
dkato 0:92d12d355ba9 836 return false;
dkato 0:92d12d355ba9 837 }
dkato 0:92d12d355ba9 838
dkato 0:92d12d355ba9 839 void ESP32::setTimeout(uint32_t timeout_ms)
dkato 0:92d12d355ba9 840 {
dkato 1:5d78eedef723 841 last_timeout_ms = timeout_ms;
dkato 0:92d12d355ba9 842 _parser.set_timeout(timeout_ms);
dkato 0:92d12d355ba9 843 }
dkato 0:92d12d355ba9 844
dkato 0:92d12d355ba9 845 bool ESP32::readable()
dkato 0:92d12d355ba9 846 {
dkato 0:92d12d355ba9 847 return _serial.FileHandle::readable();
dkato 0:92d12d355ba9 848 }
dkato 0:92d12d355ba9 849
dkato 0:92d12d355ba9 850 bool ESP32::writeable()
dkato 0:92d12d355ba9 851 {
dkato 0:92d12d355ba9 852 return _serial.FileHandle::writable();
dkato 0:92d12d355ba9 853 }
dkato 0:92d12d355ba9 854
dkato 0:92d12d355ba9 855 void ESP32::socket_attach(int id, void (*callback)(void *), void *data)
dkato 0:92d12d355ba9 856 {
dkato 0:92d12d355ba9 857 _cbs[id].callback = callback;
dkato 0:92d12d355ba9 858 _cbs[id].data = data;
dkato 0:92d12d355ba9 859 _cbs[id].Notified = 0;
dkato 0:92d12d355ba9 860 }
dkato 0:92d12d355ba9 861
dkato 0:92d12d355ba9 862 bool ESP32::recv_ap(nsapi_wifi_ap_t *ap)
dkato 0:92d12d355ba9 863 {
dkato 0:92d12d355ba9 864 int sec;
dkato 0:92d12d355ba9 865 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%hhu)", &sec, ap->ssid,
dkato 0:92d12d355ba9 866 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
dkato 0:92d12d355ba9 867 &ap->bssid[5], &ap->channel);
dkato 0:92d12d355ba9 868
dkato 0:92d12d355ba9 869 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
dkato 0:92d12d355ba9 870
dkato 0:92d12d355ba9 871 return ret;
dkato 0:92d12d355ba9 872 }
dkato 0:92d12d355ba9 873
dkato 0:92d12d355ba9 874 void ESP32::_connect_handler_0() { socket_handler(true, 0); }
dkato 0:92d12d355ba9 875 void ESP32::_connect_handler_1() { socket_handler(true, 1); }
dkato 0:92d12d355ba9 876 void ESP32::_connect_handler_2() { socket_handler(true, 2); }
dkato 0:92d12d355ba9 877 void ESP32::_connect_handler_3() { socket_handler(true, 3); }
dkato 0:92d12d355ba9 878 void ESP32::_connect_handler_4() { socket_handler(true, 4); }
dkato 0:92d12d355ba9 879 void ESP32::_closed_handler_0() { socket_handler(false, 0); }
dkato 0:92d12d355ba9 880 void ESP32::_closed_handler_1() { socket_handler(false, 1); }
dkato 0:92d12d355ba9 881 void ESP32::_closed_handler_2() { socket_handler(false, 2); }
dkato 0:92d12d355ba9 882 void ESP32::_closed_handler_3() { socket_handler(false, 3); }
dkato 0:92d12d355ba9 883 void ESP32::_closed_handler_4() { socket_handler(false, 4); }
dkato 0:92d12d355ba9 884
dkato 0:92d12d355ba9 885 void ESP32::_connection_status_handler()
dkato 0:92d12d355ba9 886 {
dkato 0:92d12d355ba9 887 char status[13];
dkato 0:92d12d355ba9 888 if (_parser.recv("%12[^\"]\n", status)) {
dkato 0:92d12d355ba9 889 if (strcmp(status, "CONNECTED\n") == 0) {
dkato 0:92d12d355ba9 890 _wifi_status = STATUS_CONNECTED;
dkato 0:92d12d355ba9 891 } else if (strcmp(status, "GOT IP\n") == 0) {
dkato 0:92d12d355ba9 892 _wifi_status = STATUS_GOT_IP;
dkato 0:92d12d355ba9 893 } else if (strcmp(status, "DISCONNECT\n") == 0) {
dkato 0:92d12d355ba9 894 _wifi_status = STATUS_DISCONNECTED;
dkato 0:92d12d355ba9 895 } else {
dkato 0:92d12d355ba9 896 return;
dkato 0:92d12d355ba9 897 }
dkato 0:92d12d355ba9 898
dkato 0:92d12d355ba9 899 if(_wifi_status_cb) {
dkato 0:92d12d355ba9 900 _wifi_status_cb(_wifi_status);
dkato 0:92d12d355ba9 901 }
dkato 0:92d12d355ba9 902 }
dkato 0:92d12d355ba9 903 }
dkato 0:92d12d355ba9 904
dkato 0:92d12d355ba9 905 int ESP32::get_free_id()
dkato 0:92d12d355ba9 906 {
dkato 0:92d12d355ba9 907 // Look for an unused socket
dkato 0:92d12d355ba9 908 int id = -1;
dkato 0:92d12d355ba9 909
dkato 0:92d12d355ba9 910 for (int i = 0; i < SOCKET_COUNT; i++) {
dkato 0:92d12d355ba9 911 if ((!_ids[i]) && ((_id_bits & (1 << i)) == 0)) {
dkato 0:92d12d355ba9 912 id = i;
dkato 0:92d12d355ba9 913 _ids[i] = true;
dkato 0:92d12d355ba9 914 break;
dkato 0:92d12d355ba9 915 }
dkato 0:92d12d355ba9 916 }
dkato 0:92d12d355ba9 917
dkato 0:92d12d355ba9 918 return id;
dkato 0:92d12d355ba9 919 }
dkato 0:92d12d355ba9 920
dkato 0:92d12d355ba9 921 void ESP32::event() {
dkato 0:92d12d355ba9 922 for (int i = 0; i < SOCKET_COUNT; i++) {
dkato 0:92d12d355ba9 923 if ((_cbs[i].callback) && (_cbs[i].Notified == 0)) {
dkato 0:92d12d355ba9 924 _cbs[i].callback(_cbs[i].data);
dkato 0:92d12d355ba9 925 _cbs[i].Notified = 1;
dkato 0:92d12d355ba9 926 }
dkato 0:92d12d355ba9 927 }
dkato 0:92d12d355ba9 928 }
dkato 0:92d12d355ba9 929
dkato 0:92d12d355ba9 930 bool ESP32::set_network(const char *ip_address, const char *netmask, const char *gateway)
dkato 0:92d12d355ba9 931 {
dkato 0:92d12d355ba9 932 bool ret;
dkato 0:92d12d355ba9 933
dkato 0:92d12d355ba9 934 if (ip_address == NULL) {
dkato 0:92d12d355ba9 935 return false;
dkato 0:92d12d355ba9 936 }
dkato 0:92d12d355ba9 937
dkato 0:92d12d355ba9 938 _smutex.lock();
dkato 0:92d12d355ba9 939 if ((netmask != NULL) && (gateway != NULL)) {
dkato 0:92d12d355ba9 940 ret = _parser.send("AT+CIPSTA=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask)
dkato 0:92d12d355ba9 941 && _parser.recv("OK");
dkato 0:92d12d355ba9 942 } else {
dkato 0:92d12d355ba9 943 ret = _parser.send("AT+CIPSTA=\"%s\"", ip_address)
dkato 0:92d12d355ba9 944 && _parser.recv("OK");
dkato 0:92d12d355ba9 945 }
dkato 0:92d12d355ba9 946 _smutex.unlock();
dkato 0:92d12d355ba9 947
dkato 0:92d12d355ba9 948 return ret;
dkato 0:92d12d355ba9 949 }
dkato 0:92d12d355ba9 950
dkato 0:92d12d355ba9 951 bool ESP32::set_network_ap(const char *ip_address, const char *netmask, const char *gateway)
dkato 0:92d12d355ba9 952 {
dkato 0:92d12d355ba9 953 bool ret;
dkato 0:92d12d355ba9 954
dkato 0:92d12d355ba9 955 if (ip_address == NULL) {
dkato 0:92d12d355ba9 956 return false;
dkato 0:92d12d355ba9 957 }
dkato 0:92d12d355ba9 958
dkato 0:92d12d355ba9 959 _smutex.lock();
dkato 0:92d12d355ba9 960 if ((netmask != NULL) && (gateway != NULL)) {
dkato 0:92d12d355ba9 961 ret = _parser.send("AT+CIPAP=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask)
dkato 0:92d12d355ba9 962 && _parser.recv("OK");
dkato 0:92d12d355ba9 963 } else {
dkato 0:92d12d355ba9 964 ret = _parser.send("AT+CIPAP=\"%s\"", ip_address)
dkato 0:92d12d355ba9 965 && _parser.recv("OK");
dkato 0:92d12d355ba9 966 }
dkato 0:92d12d355ba9 967 _smutex.unlock();
dkato 0:92d12d355ba9 968
dkato 0:92d12d355ba9 969 return ret;
dkato 0:92d12d355ba9 970 }
dkato 0:92d12d355ba9 971
dkato 0:92d12d355ba9 972 void ESP32::attach_wifi_status(mbed::Callback<void(int8_t)> status_cb)
dkato 0:92d12d355ba9 973 {
dkato 0:92d12d355ba9 974 _wifi_status_cb = status_cb;
dkato 0:92d12d355ba9 975 }
dkato 0:92d12d355ba9 976
dkato 0:92d12d355ba9 977 int8_t ESP32::get_wifi_status() const
dkato 0:92d12d355ba9 978 {
dkato 0:92d12d355ba9 979 return _wifi_status;
dkato 0:92d12d355ba9 980 }
dkato 0:92d12d355ba9 981