Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ESP32.cpp
00001 /* ESP32 Example 00002 * Copyright (c) 2015 ARM Limited 00003 * Copyright (c) 2017 Renesas Electronics Corporation 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "ESP32.h" 00019 00020 #define ESP32_DEFAULT_BAUD_RATE 115200 00021 #define ESP32_ALL_SOCKET_IDS -1 00022 00023 ESP32 * ESP32::instESP32 = NULL; 00024 00025 ESP32 * ESP32::getESP32Inst(PinName en, PinName io0, PinName tx, PinName rx, bool debug, 00026 PinName rts, PinName cts, int baudrate) 00027 { 00028 if (instESP32 == NULL) { 00029 instESP32 = new ESP32(en, io0, tx, rx, debug, rts, cts, baudrate); 00030 } else { 00031 if (debug) { 00032 instESP32->debugOn(debug); 00033 } 00034 } 00035 return instESP32; 00036 } 00037 00038 ESP32::ESP32(PinName en, PinName io0, PinName tx, PinName rx, bool debug, 00039 PinName rts, PinName cts, int baudrate) 00040 : _p_wifi_en(NULL), _p_wifi_io0(NULL), init_end(false) 00041 , _serial(tx, rx, ESP32_DEFAULT_BAUD_RATE), _parser(&_serial, "\r\n") 00042 , _packets(0), _packets_end(&_packets) 00043 , _id_bits(0), _id_bits_close(0), _server_act(false) 00044 , _wifi_status(STATUS_DISCONNECTED) 00045 , _wifi_status_cb(NULL) 00046 { 00047 if ((int)en != NC) { 00048 _p_wifi_en = new DigitalOut(en); 00049 } 00050 if ((int)io0 != NC) { 00051 _p_wifi_io0 = new DigitalOut(io0); 00052 } 00053 00054 _wifi_mode = WIFIMODE_STATION; 00055 _baudrate = baudrate; 00056 memset(_ids, 0, sizeof(_ids)); 00057 memset(_cbs, 0, sizeof(_cbs)); 00058 00059 _rts = rts; 00060 _cts = cts; 00061 00062 if ((_rts != NC) && (_cts != NC)) { 00063 _flow_control = 3; 00064 } else if (_rts != NC) { 00065 _flow_control = 1; 00066 } else if (_cts != NC) { 00067 _flow_control = 2; 00068 } else { 00069 _flow_control = 0; 00070 } 00071 00072 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE); 00073 debugOn(debug); 00074 00075 _parser.oob("+IPD", callback(this, &ESP32::_packet_handler)); 00076 _parser.oob("0,CONNECT", callback(this, &ESP32::_connect_handler_0)); 00077 _parser.oob("1,CONNECT", callback(this, &ESP32::_connect_handler_1)); 00078 _parser.oob("2,CONNECT", callback(this, &ESP32::_connect_handler_2)); 00079 _parser.oob("3,CONNECT", callback(this, &ESP32::_connect_handler_3)); 00080 _parser.oob("4,CONNECT", callback(this, &ESP32::_connect_handler_4)); 00081 _parser.oob("0,CLOSED", callback(this, &ESP32::_closed_handler_0)); 00082 _parser.oob("1,CLOSED", callback(this, &ESP32::_closed_handler_1)); 00083 _parser.oob("2,CLOSED", callback(this, &ESP32::_closed_handler_2)); 00084 _parser.oob("3,CLOSED", callback(this, &ESP32::_closed_handler_3)); 00085 _parser.oob("4,CLOSED", callback(this, &ESP32::_closed_handler_4)); 00086 _parser.oob("WIFI ", callback(this, &ESP32::_connection_status_handler)); 00087 00088 _serial.sigio(Callback<void()>(this, &ESP32::event)); 00089 00090 setTimeout(); 00091 } 00092 00093 void ESP32::debugOn(bool debug) 00094 { 00095 _parser.debug_on((debug) ? 1 : 0); 00096 } 00097 00098 int ESP32::get_firmware_version() 00099 { 00100 int version; 00101 00102 _smutex.lock(); 00103 startup(); 00104 bool done = _parser.send("AT+GMR") 00105 && _parser.recv("SDK version:%d", &version) 00106 && _parser.recv("OK"); 00107 _smutex.unlock(); 00108 00109 if(done) { 00110 return version; 00111 } else { 00112 // Older firmware versions do not prefix the version with "SDK version: " 00113 return -1; 00114 } 00115 } 00116 00117 bool ESP32::startup() 00118 { 00119 if (init_end) { 00120 return true; 00121 } 00122 00123 if (_p_wifi_io0 != NULL) { 00124 _p_wifi_io0->write(1); 00125 } 00126 if (_p_wifi_en != NULL) { 00127 _p_wifi_en->write(0); 00128 Thread::wait(10); 00129 _p_wifi_en->write(1); 00130 _parser.recv("ready"); 00131 } else { 00132 setTimeout(100); 00133 _parser.recv("ready"); 00134 } 00135 00136 reset(); 00137 bool success = _parser.send("AT+CWMODE=%d", _wifi_mode) 00138 && _parser.recv("OK") 00139 && _parser.send("AT+CIPMUX=1") 00140 && _parser.recv("OK") 00141 && _parser.send("AT+CWAUTOCONN=0") 00142 && _parser.recv("OK") 00143 && _parser.send("AT+CWQAP") 00144 && _parser.recv("OK"); 00145 if (success) { 00146 init_end = true; 00147 } 00148 00149 return success; 00150 } 00151 00152 bool ESP32::restart() 00153 { 00154 bool success; 00155 00156 _smutex.lock(); 00157 if (!init_end) { 00158 success = startup(); 00159 } else { 00160 reset(); 00161 success = _parser.send("AT+CWMODE=%d", _wifi_mode) 00162 && _parser.recv("OK") 00163 && _parser.send("AT+CIPMUX=1") 00164 && _parser.recv("OK"); 00165 } 00166 _smutex.unlock(); 00167 00168 return success; 00169 } 00170 00171 bool ESP32::set_mode(int mode) 00172 { 00173 //only 3 valid modes 00174 if (mode < 1 || mode > 3) { 00175 return false; 00176 } 00177 if (_wifi_mode != mode) { 00178 _wifi_mode = mode; 00179 return restart(); 00180 } 00181 return true; 00182 } 00183 00184 bool ESP32::cre_server(int port) 00185 { 00186 if (_server_act) { 00187 return false; 00188 } 00189 _smutex.lock(); 00190 startup(); 00191 if (!(_parser.send("AT+CIPSERVER=1,%d", port) 00192 && _parser.recv("OK"))) { 00193 _smutex.unlock(); 00194 return false; 00195 } 00196 _server_act = true; 00197 _smutex.unlock(); 00198 return true; 00199 } 00200 00201 bool ESP32::del_server() 00202 { 00203 _smutex.lock(); 00204 startup(); 00205 if (!(_parser.send("AT+CIPSERVER=0") 00206 && _parser.recv("OK"))) { 00207 _smutex.unlock(); 00208 return false; 00209 } 00210 _server_act = false; 00211 _smutex.unlock(); 00212 return true; 00213 } 00214 00215 void ESP32::socket_handler(bool connect, int id) 00216 { 00217 _cbs[id].Notified = 0; 00218 if (connect) { 00219 _id_bits |= (1 << id); 00220 if (_server_act) { 00221 _accept_id.push_back(id); 00222 } 00223 } else { 00224 _id_bits &= ~(1 << id); 00225 _id_bits_close |= (1 << id); 00226 if (_server_act) { 00227 for (size_t i = 0; i < _accept_id.size(); i++) { 00228 if (id == _accept_id[i]) { 00229 _accept_id.erase(_accept_id.begin() + i); 00230 } 00231 } 00232 } 00233 } 00234 } 00235 00236 bool ESP32::accept(int * p_id) 00237 { 00238 bool ret = false; 00239 00240 while (!ret) { 00241 if (!_server_act) { 00242 break; 00243 } 00244 00245 _smutex.lock(); 00246 startup(); 00247 if (!_accept_id.empty()) { 00248 ret = true; 00249 } else { 00250 _parser.process_oob(); // Poll for inbound packets 00251 if (!_accept_id.empty()) { 00252 ret = true; 00253 } 00254 } 00255 if (ret) { 00256 *p_id = _accept_id[0]; 00257 _accept_id.erase(_accept_id.begin()); 00258 } 00259 _smutex.unlock(); 00260 if (!ret) { 00261 Thread::wait(5); 00262 } 00263 } 00264 00265 if (ret) { 00266 for (int i = 0; i < 50; i++) { 00267 if ((_id_bits_close & (1 << *p_id)) == 0) { 00268 break; 00269 } 00270 Thread::wait(10); 00271 } 00272 } 00273 00274 return ret; 00275 } 00276 00277 bool ESP32::reset(void) 00278 { 00279 for (int i = 0; i < 2; i++) { 00280 if (_parser.send("AT+RST") 00281 && _parser.recv("OK")) { 00282 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE); 00283 #if DEVICE_SERIAL_FC 00284 _serial.set_flow_control(SerialBase::Disabled); 00285 #endif 00286 _parser.recv("ready"); 00287 _clear_socket_packets(ESP32_ALL_SOCKET_IDS); 00288 00289 if (_parser.send("AT+UART_CUR=%d,8,1,0,%d", _baudrate, _flow_control) 00290 && _parser.recv("OK")) { 00291 _serial.set_baud(_baudrate); 00292 #if DEVICE_SERIAL_FC 00293 switch (_flow_control) { 00294 case 1: 00295 _serial.set_flow_control(SerialBase::RTS, _rts); 00296 break; 00297 case 2: 00298 _serial.set_flow_control(SerialBase::CTS, _cts); 00299 break; 00300 case 3: 00301 _serial.set_flow_control(SerialBase::RTSCTS, _rts, _cts); 00302 break; 00303 case 0: 00304 default: 00305 // do nothing 00306 break; 00307 } 00308 #endif 00309 } 00310 00311 return true; 00312 } 00313 } 00314 00315 return false; 00316 } 00317 00318 bool ESP32::dhcp(bool enabled, int mode) 00319 { 00320 //only 3 valid modes 00321 if (mode < 0 || mode > 2) { 00322 return false; 00323 } 00324 00325 _smutex.lock(); 00326 startup(); 00327 bool done = _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode) 00328 && _parser.recv("OK"); 00329 _smutex.unlock(); 00330 00331 return done; 00332 } 00333 00334 bool ESP32::connect(const char *ap, const char *passPhrase) 00335 { 00336 bool ret; 00337 00338 _wifi_status = STATUS_DISCONNECTED; 00339 00340 _smutex.lock(); 00341 startup(); 00342 00343 setTimeout(ESP32_CONNECT_TIMEOUT); 00344 ret = _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase) 00345 && _parser.recv("OK"); 00346 setTimeout(); 00347 _smutex.unlock(); 00348 return ret; 00349 } 00350 00351 bool ESP32::config_soft_ap(const char *ap, const char *passPhrase, uint8_t chl, uint8_t ecn) 00352 { 00353 bool ret; 00354 00355 _smutex.lock(); 00356 startup(); 00357 ret = _parser.send("AT+CWSAP=\"%s\",\"%s\",%hhu,%hhu", ap, passPhrase, chl, ecn) 00358 && _parser.recv("OK"); 00359 _smutex.unlock(); 00360 return ret; 00361 } 00362 00363 bool ESP32::get_ssid(char *ap) 00364 { 00365 bool ret; 00366 00367 _smutex.lock(); 00368 startup(); 00369 ret = _parser.send("AT+CWJAP?") 00370 && _parser.recv("+CWJAP:\"%33[^\"]\",", ap) 00371 && _parser.recv("OK"); 00372 _smutex.unlock(); 00373 return ret; 00374 } 00375 00376 bool ESP32::disconnect(void) 00377 { 00378 bool ret; 00379 00380 _smutex.lock(); 00381 startup(); 00382 ret = _parser.send("AT+CWQAP") && _parser.recv("OK"); 00383 _smutex.unlock(); 00384 return ret; 00385 } 00386 00387 const char *ESP32::getIPAddress(void) 00388 { 00389 bool ret; 00390 00391 _smutex.lock(); 00392 startup(); 00393 ret = _parser.send("AT+CIFSR") 00394 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer) 00395 && _parser.recv("OK"); 00396 _smutex.unlock(); 00397 if (!ret) { 00398 return 0; 00399 } 00400 return _ip_buffer; 00401 } 00402 00403 const char *ESP32::getIPAddress_ap(void) 00404 { 00405 bool ret; 00406 00407 _smutex.lock(); 00408 startup(); 00409 ret = _parser.send("AT+CIFSR") 00410 && _parser.recv("+CIFSR:APIP,\"%15[^\"]\"", _ip_buffer_ap) 00411 && _parser.recv("OK"); 00412 _smutex.unlock(); 00413 if (!ret) { 00414 return 0; 00415 } 00416 return _ip_buffer_ap; 00417 } 00418 00419 const char *ESP32::getMACAddress(void) 00420 { 00421 bool ret; 00422 00423 _smutex.lock(); 00424 startup(); 00425 ret = _parser.send("AT+CIFSR") 00426 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer) 00427 && _parser.recv("OK"); 00428 _smutex.unlock(); 00429 00430 if (!ret) { 00431 return 0; 00432 } 00433 return _mac_buffer; 00434 } 00435 00436 const char *ESP32::getMACAddress_ap(void) 00437 { 00438 bool ret; 00439 00440 _smutex.lock(); 00441 startup(); 00442 ret = _parser.send("AT+CIFSR") 00443 && _parser.recv("+CIFSR:APMAC,\"%17[^\"]\"", _mac_buffer_ap) 00444 && _parser.recv("OK"); 00445 _smutex.unlock(); 00446 00447 if (!ret) { 00448 return 0; 00449 } 00450 return _mac_buffer_ap; 00451 } 00452 00453 const char *ESP32::getGateway() 00454 { 00455 bool ret; 00456 00457 _smutex.lock(); 00458 startup(); 00459 ret = _parser.send("AT+CIPSTA?") 00460 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer) 00461 && _parser.recv("OK"); 00462 _smutex.unlock(); 00463 00464 if (!ret) { 00465 return 0; 00466 } 00467 return _gateway_buffer; 00468 } 00469 00470 const char *ESP32::getGateway_ap() 00471 { 00472 bool ret; 00473 00474 _smutex.lock(); 00475 startup(); 00476 ret = _parser.send("AT+CIPAP?") 00477 && _parser.recv("+CIPAP:gateway:\"%15[^\"]\"", _gateway_buffer_ap) 00478 && _parser.recv("OK"); 00479 _smutex.unlock(); 00480 00481 if (!ret) { 00482 return 0; 00483 } 00484 return _gateway_buffer_ap; 00485 } 00486 00487 const char *ESP32::getNetmask() 00488 { 00489 bool ret; 00490 00491 _smutex.lock(); 00492 startup(); 00493 ret = _parser.send("AT+CIPSTA?") 00494 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer) 00495 && _parser.recv("OK"); 00496 _smutex.unlock(); 00497 00498 if (!ret) { 00499 return 0; 00500 } 00501 return _netmask_buffer; 00502 } 00503 00504 const char *ESP32::getNetmask_ap() 00505 { 00506 bool ret; 00507 00508 _smutex.lock(); 00509 startup(); 00510 ret = _parser.send("AT+CIPAP?") 00511 && _parser.recv("+CIPAP:netmask:\"%15[^\"]\"", _netmask_buffer_ap) 00512 && _parser.recv("OK"); 00513 _smutex.unlock(); 00514 00515 if (!ret) { 00516 return 0; 00517 } 00518 return _netmask_buffer_ap; 00519 } 00520 00521 int8_t ESP32::getRSSI() 00522 { 00523 bool ret; 00524 int8_t rssi; 00525 char ssid[33]; 00526 char bssid[18]; 00527 00528 _smutex.lock(); 00529 startup(); 00530 ret = _parser.send("AT+CWJAP?") 00531 && _parser.recv("+CWJAP:\"%32[^\"]\",\"%17[^\"]\"", ssid, bssid) 00532 && _parser.recv("OK"); 00533 if (!ret) { 00534 _smutex.unlock(); 00535 return 0; 00536 } 00537 00538 ret = _parser.send("AT+CWLAP=\"%s\",\"%s\"", ssid, bssid) 00539 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi) 00540 && _parser.recv("OK"); 00541 _smutex.unlock(); 00542 00543 if (!ret) { 00544 return 0; 00545 } 00546 00547 return rssi; 00548 } 00549 00550 int ESP32::scan(WiFiAccessPoint *res, unsigned limit) 00551 { 00552 unsigned cnt = 0; 00553 nsapi_wifi_ap_t ap; 00554 00555 if (!init_end) { 00556 _smutex.lock(); 00557 startup(); 00558 _smutex.unlock(); 00559 Thread::wait(1500); 00560 } 00561 00562 _smutex.lock(); 00563 setTimeout(5000); 00564 if (!_parser.send("AT+CWLAP")) { 00565 _smutex.unlock(); 00566 return NSAPI_ERROR_DEVICE_ERROR; 00567 } 00568 00569 while (recv_ap(&ap)) { 00570 if (cnt < limit) { 00571 res[cnt] = WiFiAccessPoint(ap); 00572 } 00573 00574 cnt++; 00575 if ((limit != 0) && (cnt >= limit)) { 00576 break; 00577 } 00578 setTimeout(500); 00579 } 00580 setTimeout(10); 00581 _parser.recv("OK"); 00582 setTimeout(); 00583 _smutex.unlock(); 00584 00585 return cnt; 00586 } 00587 00588 bool ESP32::isConnected(void) 00589 { 00590 return getIPAddress() != 0; 00591 } 00592 00593 bool ESP32::open(const char *type, int id, const char* addr, int port, int opt) 00594 { 00595 bool ret; 00596 00597 if (id >= SOCKET_COUNT) { 00598 return false; 00599 } 00600 _cbs[id].Notified = 0; 00601 00602 _smutex.lock(); 00603 startup(); 00604 setTimeout(500); 00605 if (opt != 0) { 00606 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d, %d", id, type, addr, port, opt) 00607 && _parser.recv("OK"); 00608 } else { 00609 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port) 00610 && _parser.recv("OK"); 00611 } 00612 setTimeout(); 00613 _clear_socket_packets(id); 00614 _smutex.unlock(); 00615 00616 return ret; 00617 } 00618 00619 bool ESP32::send(int id, const void *data, uint32_t amount) 00620 { 00621 int send_size; 00622 bool ret; 00623 int error_cnt = 0; 00624 int index = 0; 00625 00626 _cbs[id].Notified = 0; 00627 if (amount == 0) { 00628 return true; 00629 } 00630 00631 //May take a second try if device is busy 00632 _smutex.lock(); 00633 while (error_cnt < 2) { 00634 if (((_id_bits & (1 << id)) == 0) 00635 || ((_id_bits_close & (1 << id)) != 0)) { 00636 _smutex.unlock(); 00637 return false; 00638 } 00639 send_size = amount; 00640 if (send_size > 2048) { 00641 send_size = 2048; 00642 } 00643 startup(); 00644 ret = _parser.send("AT+CIPSEND=%d,%d", id, send_size) 00645 && _parser.recv(">") 00646 && (_parser.write((char*)data + index, (int)send_size) >= 0) 00647 && _parser.recv("SEND OK"); 00648 if (ret) { 00649 amount -= send_size; 00650 index += send_size; 00651 error_cnt = 0; 00652 if (amount == 0) { 00653 _smutex.unlock(); 00654 return true; 00655 } 00656 } else { 00657 error_cnt++; 00658 } 00659 } 00660 _smutex.unlock(); 00661 00662 return false; 00663 } 00664 00665 void ESP32::_packet_handler() 00666 { 00667 int id; 00668 int amount; 00669 uint32_t tmp_timeout; 00670 00671 // parse out the packet 00672 if (!_parser.recv(",%d,%d:", &id, &amount)) { 00673 return; 00674 } 00675 00676 struct packet *packet = (struct packet*)malloc( 00677 sizeof(struct packet) + amount); 00678 if (!packet) { 00679 return; 00680 } 00681 00682 packet->id = id; 00683 packet->len = amount; 00684 packet->next = 0; 00685 packet->index = 0; 00686 00687 tmp_timeout = last_timeout_ms; 00688 setTimeout(500); 00689 if (!(_parser.read((char*)(packet + 1), amount))) { 00690 free(packet); 00691 setTimeout(tmp_timeout); 00692 return; 00693 } 00694 00695 // append to packet list 00696 *_packets_end = packet; 00697 _packets_end = &packet->next; 00698 } 00699 00700 int32_t ESP32::recv(int id, void *data, uint32_t amount, uint32_t timeout) 00701 { 00702 struct packet **p; 00703 uint32_t retry_cnt = 0; 00704 uint32_t idx = 0; 00705 00706 _cbs[id].Notified = 0; 00707 00708 while (1) { 00709 _smutex.lock(); 00710 if (_rts == NC) { 00711 setTimeout(1); 00712 while (_parser.process_oob()); // Poll for inbound packets 00713 setTimeout(); 00714 } else if ((retry_cnt != 0) ||(_packets == NULL)) { 00715 setTimeout(1); 00716 _parser.process_oob(); // Poll for inbound packets 00717 setTimeout(); 00718 } else { 00719 // do nothing 00720 } 00721 00722 // check if any packets are ready for us 00723 p = &_packets; 00724 while (*p) { 00725 if ((*p)->id == id) { 00726 struct packet *q = *p; 00727 00728 if (q->len <= amount) { // Return and remove full packet 00729 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, q->len); 00730 if (_packets_end == &(*p)->next) { 00731 _packets_end = p; 00732 } 00733 *p = (*p)->next; 00734 idx += q->len; 00735 amount -= q->len; 00736 free(q); 00737 } else { // return only partial packet 00738 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, amount); 00739 q->len -= amount; 00740 q->index += amount; 00741 idx += amount; 00742 break; 00743 } 00744 } else { 00745 p = &(*p)->next; 00746 } 00747 } 00748 if (idx > 0) { 00749 _smutex.unlock(); 00750 return idx; 00751 } 00752 if (retry_cnt >= timeout) { 00753 if (((_id_bits & (1 << id)) == 0) 00754 || ((_id_bits_close & (1 << id)) != 0)) { 00755 _smutex.unlock(); 00756 return -2; 00757 } else { 00758 _smutex.unlock(); 00759 return -1; 00760 } 00761 } 00762 retry_cnt++; 00763 _smutex.unlock(); 00764 Thread::wait(1); 00765 } 00766 } 00767 00768 void ESP32::_clear_socket_packets(int id) 00769 { 00770 struct packet **p = &_packets; 00771 00772 while (*p) { 00773 if ((*p)->id == id || id == ESP32_ALL_SOCKET_IDS) { 00774 struct packet *q = *p; 00775 00776 if (_packets_end == &(*p)->next) { 00777 _packets_end = p; // Set last packet next field/_packets 00778 } 00779 *p = (*p)->next; 00780 00781 free(q); 00782 } else { 00783 // Point to last packet next field 00784 p = &(*p)->next; 00785 } 00786 } 00787 } 00788 00789 bool ESP32::close(int id, bool wait_close) 00790 { 00791 if (wait_close) { 00792 _smutex.lock(); 00793 for (int j = 0; j < 2; j++) { 00794 if (((_id_bits & (1 << id)) == 0) 00795 || ((_id_bits_close & (1 << id)) != 0)) { 00796 _id_bits_close &= ~(1 << id); 00797 _ids[id] = false; 00798 _clear_socket_packets(id); 00799 _smutex.unlock(); 00800 return true; 00801 } 00802 startup(); 00803 setTimeout(500); 00804 _parser.process_oob(); // Poll for inbound packets 00805 setTimeout(); 00806 } 00807 _smutex.unlock(); 00808 } 00809 00810 //May take a second try if device is busy 00811 for (unsigned i = 0; i < 2; i++) { 00812 _smutex.lock(); 00813 if ((_id_bits & (1 << id)) == 0) { 00814 _id_bits_close &= ~(1 << id); 00815 _ids[id] = false; 00816 _clear_socket_packets(id); 00817 _smutex.unlock(); 00818 return true; 00819 } 00820 startup(); 00821 setTimeout(500); 00822 if (_parser.send("AT+CIPCLOSE=%d", id) 00823 && _parser.recv("OK")) { 00824 setTimeout(); 00825 _clear_socket_packets(id); 00826 _id_bits_close &= ~(1 << id); 00827 _ids[id] = false; 00828 _smutex.unlock(); 00829 return true; 00830 } 00831 setTimeout(); 00832 _smutex.unlock(); 00833 } 00834 00835 _ids[id] = false; 00836 return false; 00837 } 00838 00839 void ESP32::setTimeout(uint32_t timeout_ms) 00840 { 00841 last_timeout_ms = timeout_ms; 00842 _parser.set_timeout(timeout_ms); 00843 } 00844 00845 bool ESP32::readable() 00846 { 00847 return _serial.FileHandle::readable(); 00848 } 00849 00850 bool ESP32::writeable() 00851 { 00852 return _serial.FileHandle::writable(); 00853 } 00854 00855 void ESP32::socket_attach(int id, void (*callback)(void *), void *data) 00856 { 00857 _cbs[id].callback = callback; 00858 _cbs[id].data = data; 00859 _cbs[id].Notified = 0; 00860 } 00861 00862 bool ESP32::recv_ap(nsapi_wifi_ap_t *ap) 00863 { 00864 int sec; 00865 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%hhu)", &sec, ap->ssid, 00866 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], 00867 &ap->bssid[5], &ap->channel); 00868 00869 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN; 00870 00871 return ret; 00872 } 00873 00874 void ESP32::_connect_handler_0() { socket_handler(true, 0); } 00875 void ESP32::_connect_handler_1() { socket_handler(true, 1); } 00876 void ESP32::_connect_handler_2() { socket_handler(true, 2); } 00877 void ESP32::_connect_handler_3() { socket_handler(true, 3); } 00878 void ESP32::_connect_handler_4() { socket_handler(true, 4); } 00879 void ESP32::_closed_handler_0() { socket_handler(false, 0); } 00880 void ESP32::_closed_handler_1() { socket_handler(false, 1); } 00881 void ESP32::_closed_handler_2() { socket_handler(false, 2); } 00882 void ESP32::_closed_handler_3() { socket_handler(false, 3); } 00883 void ESP32::_closed_handler_4() { socket_handler(false, 4); } 00884 00885 void ESP32::_connection_status_handler() 00886 { 00887 char status[13]; 00888 if (_parser.recv("%12[^\"]\n", status)) { 00889 if (strcmp(status, "CONNECTED\n") == 0) { 00890 _wifi_status = STATUS_CONNECTED; 00891 } else if (strcmp(status, "GOT IP\n") == 0) { 00892 _wifi_status = STATUS_GOT_IP; 00893 } else if (strcmp(status, "DISCONNECT\n") == 0) { 00894 _wifi_status = STATUS_DISCONNECTED; 00895 } else { 00896 return; 00897 } 00898 00899 if(_wifi_status_cb) { 00900 _wifi_status_cb(_wifi_status); 00901 } 00902 } 00903 } 00904 00905 int ESP32::get_free_id() 00906 { 00907 // Look for an unused socket 00908 int id = -1; 00909 00910 for (int i = 0; i < SOCKET_COUNT; i++) { 00911 if ((!_ids[i]) && ((_id_bits & (1 << i)) == 0)) { 00912 id = i; 00913 _ids[i] = true; 00914 break; 00915 } 00916 } 00917 00918 return id; 00919 } 00920 00921 void ESP32::event() { 00922 for (int i = 0; i < SOCKET_COUNT; i++) { 00923 if ((_cbs[i].callback) && (_cbs[i].Notified == 0)) { 00924 _cbs[i].callback(_cbs[i].data); 00925 _cbs[i].Notified = 1; 00926 } 00927 } 00928 } 00929 00930 bool ESP32::set_network(const char *ip_address, const char *netmask, const char *gateway) 00931 { 00932 bool ret; 00933 00934 if (ip_address == NULL) { 00935 return false; 00936 } 00937 00938 _smutex.lock(); 00939 if ((netmask != NULL) && (gateway != NULL)) { 00940 ret = _parser.send("AT+CIPSTA=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask) 00941 && _parser.recv("OK"); 00942 } else { 00943 ret = _parser.send("AT+CIPSTA=\"%s\"", ip_address) 00944 && _parser.recv("OK"); 00945 } 00946 _smutex.unlock(); 00947 00948 return ret; 00949 } 00950 00951 bool ESP32::set_network_ap(const char *ip_address, const char *netmask, const char *gateway) 00952 { 00953 bool ret; 00954 00955 if (ip_address == NULL) { 00956 return false; 00957 } 00958 00959 _smutex.lock(); 00960 if ((netmask != NULL) && (gateway != NULL)) { 00961 ret = _parser.send("AT+CIPAP=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask) 00962 && _parser.recv("OK"); 00963 } else { 00964 ret = _parser.send("AT+CIPAP=\"%s\"", ip_address) 00965 && _parser.recv("OK"); 00966 } 00967 _smutex.unlock(); 00968 00969 return ret; 00970 } 00971 00972 void ESP32::attach_wifi_status(mbed::Callback<void(int8_t)> status_cb) 00973 { 00974 _wifi_status_cb = status_cb; 00975 } 00976 00977 int8_t ESP32::get_wifi_status() const 00978 { 00979 return _wifi_status; 00980 } 00981
Generated on Wed Jul 13 2022 08:56:28 by
1.7.2