The driver for the ESP32 WiFi module
Embed:
(wiki syntax)
Show/hide line numbers
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