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