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