test public
Dependencies: HttpServer_snapshot_mbed-os
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 #include "platform/mbed_interface.h" 00021 00022 #define ESP32_DEFAULT_BAUD_RATE 115200 00023 #define ESP32_ALL_SOCKET_IDS -1 00024 00025 using namespace mbed; 00026 using namespace rtos; 00027 00028 ESP32 * ESP32::instESP32 = NULL; 00029 00030 ESP32 * ESP32::getESP32Inst(PinName en, PinName io0, PinName tx, PinName rx, bool debug, 00031 PinName rts, PinName cts, int baudrate) 00032 { 00033 if (instESP32 == NULL) { 00034 instESP32 = new ESP32(en, io0, tx, rx, debug, rts, cts, baudrate); 00035 } else { 00036 if (debug) { 00037 instESP32->debugOn(debug); 00038 } 00039 } 00040 return instESP32; 00041 } 00042 00043 ESP32 * ESP32::getESP32Inst(bool debug) 00044 { 00045 return getESP32Inst(MBED_CONF_ESP32_WIFI_EN, MBED_CONF_ESP32_WIFI_IO0, 00046 MBED_CONF_ESP32_WIFI_TX, MBED_CONF_ESP32_WIFI_RX, debug, 00047 MBED_CONF_ESP32_WIFI_RTS, MBED_CONF_ESP32_WIFI_CTS, 00048 MBED_CONF_ESP32_WIFI_BAUDRATE); 00049 } 00050 00051 ESP32::ESP32(PinName en, PinName io0, PinName tx, PinName rx, bool debug, 00052 PinName rts, PinName cts, int baudrate) 00053 : _p_wifi_en(NULL), _p_wifi_io0(NULL), _init_end_common(false), _init_end_wifi(false) 00054 , _serial(tx, rx, ESP32_DEFAULT_BAUD_RATE), _parser(&_serial, "\r\n") 00055 , _packets(0), _packets_end(&_packets) 00056 , _id_bits(0), _server_act(false) 00057 , _wifi_status(STATUS_DISCONNECTED) 00058 , _wifi_status_cb(NULL), _at_version(0) 00059 #if defined(TARGET_ESP32AT_BLE) 00060 , _ble_conn_cb(NULL), _ble_disconn_cb(NULL), _ble_write_cb(NULL), _ble_scan_cb(NULL) 00061 , _ble_role(INIT_SERVER_ROLE), _init_end_ble(false) 00062 , _primary_service_idx(0), _discovers_char_idx(0), _discovers_desc_idx(0) 00063 #endif /* TARGET_ESP32AT_BLE */ 00064 { 00065 if ((int)en != NC) { 00066 _p_wifi_en = new DigitalOut(en); 00067 } 00068 if ((int)io0 != NC) { 00069 _p_wifi_io0 = new DigitalOut(io0); 00070 } 00071 00072 _wifi_mode = WIFIMODE_STATION; 00073 _baudrate = baudrate; 00074 memset(_ids, 0, sizeof(_ids)); 00075 memset(_cbs, 0, sizeof(_cbs)); 00076 #if defined(TARGET_ESP32AT_BLE) 00077 memset(&_cbs_ble, 0, sizeof(_cbs_ble)); 00078 #endif /* TARGET_ESP32AT_BLE */ 00079 00080 _rts = rts; 00081 _cts = cts; 00082 00083 if ((_rts != NC) && (_cts != NC)) { 00084 _flow_control = 3; 00085 } else if (_rts != NC) { 00086 _flow_control = 1; 00087 } else if (_cts != NC) { 00088 _flow_control = 2; 00089 } else { 00090 _flow_control = 0; 00091 } 00092 00093 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE); 00094 debugOn(debug); 00095 00096 _parser.oob("+IPD", callback(this, &ESP32::_packet_handler)); 00097 _parser.oob("0,CONNECT", callback(this, &ESP32::_connect_handler_0)); 00098 _parser.oob("1,CONNECT", callback(this, &ESP32::_connect_handler_1)); 00099 _parser.oob("2,CONNECT", callback(this, &ESP32::_connect_handler_2)); 00100 _parser.oob("3,CONNECT", callback(this, &ESP32::_connect_handler_3)); 00101 _parser.oob("4,CONNECT", callback(this, &ESP32::_connect_handler_4)); 00102 _parser.oob("0,CLOSED", callback(this, &ESP32::_closed_handler_0)); 00103 _parser.oob("1,CLOSED", callback(this, &ESP32::_closed_handler_1)); 00104 _parser.oob("2,CLOSED", callback(this, &ESP32::_closed_handler_2)); 00105 _parser.oob("3,CLOSED", callback(this, &ESP32::_closed_handler_3)); 00106 _parser.oob("4,CLOSED", callback(this, &ESP32::_closed_handler_4)); 00107 _parser.oob("WIFI ", callback(this, &ESP32::_connection_status_handler)); 00108 #if defined(TARGET_ESP32AT_BLE) 00109 _parser.oob("+BLECONN:", callback(this, &ESP32::_ble_conn)); 00110 _parser.oob("+BLEDISCONN:", callback(this, &ESP32::_ble_disconn)); 00111 _parser.oob("+WRITE:", callback(this, &ESP32::_ble_write)); 00112 _parser.oob("+BLESCAN:", callback(this, &ESP32::_ble_scan)); 00113 _parser.oob("+BLEGATTCPRIMSRV:", callback(this, &ESP32::_ble_primsrv)); 00114 _parser.oob("+BLEGATTCCHAR:", callback(this, &ESP32::_ble_discovers_char)); 00115 #endif /* TARGET_ESP32AT_BLE */ 00116 00117 _serial.sigio(Callback<void()>(this, &ESP32::event)); 00118 00119 setTimeout(); 00120 } 00121 00122 void ESP32::debugOn(bool debug) 00123 { 00124 _parser.debug_on((debug) ? 1 : 0); 00125 } 00126 00127 bool ESP32::get_version_info(char * ver_info, int buf_size) 00128 { 00129 bool ret; 00130 int idx = 0; 00131 const char key_word[6] = "\nOK\r\n"; 00132 char wk_buf[5]; 00133 int wk_idx; 00134 char c; 00135 00136 if (ver_info == NULL) { 00137 return false; 00138 } 00139 _smutex.lock(); 00140 _startup_common(); 00141 setTimeout(500); 00142 ret = _parser.send("AT+GMR"); 00143 if (!ret) { 00144 setTimeout(); 00145 _smutex.unlock(); 00146 return false; 00147 } 00148 for (int i = 0; i < 10; i++) { 00149 _parser.getc(); // dummy read 00150 } 00151 while (idx < buf_size) { 00152 wk_idx = 0; 00153 for (int i = 0; i < 5; i++) { 00154 c = _parser.getc(); 00155 wk_buf[wk_idx++] = c; 00156 if (c != key_word[i]) { 00157 break; 00158 } 00159 } 00160 if (wk_idx >= 5) { 00161 break; 00162 } 00163 for (int i = 0; (i < wk_idx) && (idx < buf_size); i++) { 00164 ver_info[idx++] = wk_buf[i]; 00165 } 00166 } 00167 setTimeout(); 00168 _smutex.unlock(); 00169 00170 ver_info[idx] = '\0'; 00171 while (idx > 0) { 00172 idx--; 00173 if (ver_info[idx] != '\r' && ver_info[idx] != '\n') { 00174 break; 00175 } 00176 ver_info[idx] = '\0'; 00177 } 00178 00179 return true; 00180 } 00181 00182 void ESP32::_startup_common() 00183 { 00184 if (_init_end_common) { 00185 return; 00186 } 00187 00188 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE); 00189 if (_p_wifi_io0 != NULL) { 00190 _p_wifi_io0->write(1); 00191 } 00192 if (_p_wifi_en != NULL) { 00193 _p_wifi_en->write(0); 00194 ThisThread::sleep_for(10); 00195 _p_wifi_en->write(1); 00196 _parser.recv("ready"); 00197 } else { 00198 setTimeout(100); 00199 _parser.recv("ready"); 00200 } 00201 00202 reset(); 00203 00204 _init_end_common = true; 00205 00206 return; 00207 } 00208 00209 bool ESP32::_startup_wifi() 00210 { 00211 _startup_common(); 00212 00213 if (_init_end_wifi) { 00214 return true; 00215 } 00216 00217 bool success = _parser.send("AT+CWMODE=%d", _wifi_mode) 00218 && _parser.recv("OK") 00219 && _parser.send("AT+CIPMUX=1") 00220 && _parser.recv("OK") 00221 && _parser.send("AT+CWAUTOCONN=0") 00222 && _parser.recv("OK") 00223 && _parser.send("AT+CWQAP") 00224 && _parser.recv("OK"); 00225 if (success) { 00226 _init_end_wifi = true; 00227 } 00228 00229 return success; 00230 } 00231 00232 bool ESP32::restart() 00233 { 00234 bool success = true;; 00235 bool ret; 00236 00237 _smutex.lock(); 00238 setTimeout(); 00239 reset(); 00240 if (_init_end_wifi) { 00241 ret = _parser.send("AT+CWMODE=%d", _wifi_mode) 00242 && _parser.recv("OK") 00243 && _parser.send("AT+CIPMUX=1") 00244 && _parser.recv("OK"); 00245 if (!ret) { 00246 success = false; 00247 } 00248 } 00249 #if defined(TARGET_ESP32AT_BLE) 00250 if (_init_end_ble) { 00251 ret = _parser.send("AT+BLEINIT=%d", _ble_role) 00252 && _parser.recv("OK"); 00253 if (!ret) { 00254 success = false; 00255 } 00256 } 00257 #endif 00258 _smutex.unlock(); 00259 00260 return success; 00261 } 00262 00263 bool ESP32::set_mode(int mode) 00264 { 00265 //only 3 valid modes 00266 if (mode < 1 || mode > 3) { 00267 return false; 00268 } 00269 if (_wifi_mode != mode) { 00270 _wifi_mode = mode; 00271 if (_init_end_wifi) { 00272 return restart(); 00273 } 00274 } 00275 return true; 00276 } 00277 00278 bool ESP32::cre_server(int port) 00279 { 00280 if (_server_act) { 00281 return false; 00282 } 00283 _smutex.lock(); 00284 _startup_wifi(); 00285 if (!(_parser.send("AT+CIPSERVER=1,%d", port) 00286 && _parser.recv("OK"))) { 00287 _smutex.unlock(); 00288 return false; 00289 } 00290 _server_act = true; 00291 _smutex.unlock(); 00292 return true; 00293 } 00294 00295 bool ESP32::del_server() 00296 { 00297 _smutex.lock(); 00298 _startup_wifi(); 00299 if (!(_parser.send("AT+CIPSERVER=0") 00300 && _parser.recv("OK"))) { 00301 _smutex.unlock(); 00302 return false; 00303 } 00304 _server_act = false; 00305 _smutex.unlock(); 00306 return true; 00307 } 00308 00309 void ESP32::socket_handler(bool connect, int id) 00310 { 00311 _cbs[id].Notified = 0; 00312 if (connect) { 00313 _id_bits |= (1 << id); 00314 if (_server_act) { 00315 _accept_id.push_back(id); 00316 } 00317 } else { 00318 _id_bits &= ~(1 << id); 00319 if (_server_act) { 00320 for (size_t i = 0; i < _accept_id.size(); i++) { 00321 if (id == _accept_id[i]) { 00322 _accept_id.erase(_accept_id.begin() + i); 00323 } 00324 } 00325 } 00326 } 00327 } 00328 00329 bool ESP32::accept(int * p_id) 00330 { 00331 bool ret = false; 00332 00333 while (!ret) { 00334 if (!_server_act) { 00335 break; 00336 } 00337 00338 _smutex.lock(); 00339 _startup_wifi(); 00340 if (!_accept_id.empty()) { 00341 ret = true; 00342 } else { 00343 _parser.process_oob(); // Poll for inbound packets 00344 if (!_accept_id.empty()) { 00345 ret = true; 00346 } 00347 } 00348 if (ret) { 00349 *p_id = _accept_id[0]; 00350 _accept_id.erase(_accept_id.begin()); 00351 } 00352 _smutex.unlock(); 00353 if (!ret) { 00354 ThisThread::sleep_for(5); 00355 } 00356 } 00357 00358 return ret; 00359 } 00360 00361 bool ESP32::reset(void) 00362 { 00363 for (int i = 0; i < 2; i++) { 00364 if (_parser.send("AT+RST") 00365 && _parser.recv("OK")) { 00366 _serial.set_baud(ESP32_DEFAULT_BAUD_RATE); 00367 #if DEVICE_SERIAL_FC 00368 _serial.set_flow_control(SerialBase::Disabled); 00369 #endif 00370 _parser.recv("ready"); 00371 _clear_socket_packets(ESP32_ALL_SOCKET_IDS); 00372 00373 if (_parser.send("AT+UART_CUR=%d,8,1,0,%d", _baudrate, _flow_control) 00374 && _parser.recv("OK")) { 00375 _serial.set_baud(_baudrate); 00376 #if DEVICE_SERIAL_FC 00377 switch (_flow_control) { 00378 case 1: 00379 _serial.set_flow_control(SerialBase::RTS, _rts); 00380 break; 00381 case 2: 00382 _serial.set_flow_control(SerialBase::CTS, _cts); 00383 break; 00384 case 3: 00385 _serial.set_flow_control(SerialBase::RTSCTS, _rts, _cts); 00386 break; 00387 case 0: 00388 default: 00389 // do nothing 00390 break; 00391 } 00392 #endif 00393 } 00394 00395 ThisThread::sleep_for(5); 00396 00397 uint8_t wk_ver[4+1]; /* It needs 1 byte extra. */ 00398 00399 if (_parser.send("AT+GMR") 00400 && _parser.recv("AT version:%hhx.%hhx.%hhx.%hhx", &wk_ver[0], &wk_ver[1], &wk_ver[2], &wk_ver[3]) 00401 && _parser.recv("OK") 00402 ) { 00403 _at_version = (wk_ver[0] << 24) 00404 | (wk_ver[1] << 16) 00405 | (wk_ver[2] << 8) 00406 | (wk_ver[3] << 0); 00407 } 00408 00409 return true; 00410 } 00411 } 00412 00413 return false; 00414 } 00415 00416 bool ESP32::dhcp(bool enabled, int mode) 00417 { 00418 //only 3 valid modes 00419 if (mode < 0 || mode > 2) { 00420 return false; 00421 } 00422 00423 _smutex.lock(); 00424 _startup_wifi(); 00425 bool done = _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode) 00426 && _parser.recv("OK"); 00427 _smutex.unlock(); 00428 00429 return done; 00430 } 00431 00432 bool ESP32::connect(const char *ap, const char *passPhrase) 00433 { 00434 bool ret; 00435 00436 _wifi_status = STATUS_DISCONNECTED; 00437 00438 _smutex.lock(); 00439 _startup_wifi(); 00440 00441 setTimeout(ESP32_CONNECT_TIMEOUT); 00442 ret = _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase) 00443 && _parser.recv("OK"); 00444 setTimeout(); 00445 _smutex.unlock(); 00446 return ret; 00447 } 00448 00449 bool ESP32::config_soft_ap(const char *ap, const char *passPhrase, uint8_t chl, uint8_t ecn) 00450 { 00451 bool ret; 00452 00453 _smutex.lock(); 00454 _startup_wifi(); 00455 ret = _parser.send("AT+CWSAP=\"%s\",\"%s\",%hhu,%hhu", ap, passPhrase, chl, ecn) 00456 && _parser.recv("OK"); 00457 _smutex.unlock(); 00458 return ret; 00459 } 00460 00461 bool ESP32::get_ssid(char *ap) 00462 { 00463 bool ret; 00464 00465 _smutex.lock(); 00466 _startup_wifi(); 00467 ret = _parser.send("AT+CWJAP?") 00468 && _parser.recv("+CWJAP:\"%33[^\"]\",", ap) 00469 && _parser.recv("OK"); 00470 _smutex.unlock(); 00471 return ret; 00472 } 00473 00474 bool ESP32::disconnect(void) 00475 { 00476 bool ret; 00477 00478 _smutex.lock(); 00479 _startup_wifi(); 00480 ret = _parser.send("AT+CWQAP") && _parser.recv("OK"); 00481 _smutex.unlock(); 00482 return ret; 00483 } 00484 00485 const char *ESP32::getIPAddress(void) 00486 { 00487 bool ret; 00488 00489 _smutex.lock(); 00490 _startup_wifi(); 00491 ret = _parser.send("AT+CIFSR") 00492 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer) 00493 && _parser.recv("OK"); 00494 _smutex.unlock(); 00495 if (!ret) { 00496 return 0; 00497 } 00498 return _ip_buffer; 00499 } 00500 00501 const char *ESP32::getIPAddress_ap(void) 00502 { 00503 bool ret; 00504 00505 _smutex.lock(); 00506 _startup_wifi(); 00507 ret = _parser.send("AT+CIFSR") 00508 && _parser.recv("+CIFSR:APIP,\"%15[^\"]\"", _ip_buffer_ap) 00509 && _parser.recv("OK"); 00510 _smutex.unlock(); 00511 if (!ret) { 00512 return 0; 00513 } 00514 return _ip_buffer_ap; 00515 } 00516 00517 const char *ESP32::getMACAddress(void) 00518 { 00519 bool ret; 00520 00521 _smutex.lock(); 00522 _startup_wifi(); 00523 ret = _parser.send("AT+CIFSR") 00524 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer) 00525 && _parser.recv("OK"); 00526 _smutex.unlock(); 00527 00528 if (!ret) { 00529 return 0; 00530 } 00531 return _mac_buffer; 00532 } 00533 00534 const char *ESP32::getMACAddress_ap(void) 00535 { 00536 bool ret; 00537 00538 _smutex.lock(); 00539 _startup_wifi(); 00540 ret = _parser.send("AT+CIFSR") 00541 && _parser.recv("+CIFSR:APMAC,\"%17[^\"]\"", _mac_buffer_ap) 00542 && _parser.recv("OK"); 00543 _smutex.unlock(); 00544 00545 if (!ret) { 00546 return 0; 00547 } 00548 return _mac_buffer_ap; 00549 } 00550 00551 const char *ESP32::getGateway() 00552 { 00553 bool ret; 00554 00555 _smutex.lock(); 00556 _startup_wifi(); 00557 ret = _parser.send("AT+CIPSTA?") 00558 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer) 00559 && _parser.recv("OK"); 00560 _smutex.unlock(); 00561 00562 if (!ret) { 00563 return 0; 00564 } 00565 return _gateway_buffer; 00566 } 00567 00568 const char *ESP32::getGateway_ap() 00569 { 00570 bool ret; 00571 00572 _smutex.lock(); 00573 _startup_wifi(); 00574 ret = _parser.send("AT+CIPAP?") 00575 && _parser.recv("+CIPAP:gateway:\"%15[^\"]\"", _gateway_buffer_ap) 00576 && _parser.recv("OK"); 00577 _smutex.unlock(); 00578 00579 if (!ret) { 00580 return 0; 00581 } 00582 return _gateway_buffer_ap; 00583 } 00584 00585 const char *ESP32::getNetmask() 00586 { 00587 bool ret; 00588 00589 _smutex.lock(); 00590 _startup_wifi(); 00591 ret = _parser.send("AT+CIPSTA?") 00592 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer) 00593 && _parser.recv("OK"); 00594 _smutex.unlock(); 00595 00596 if (!ret) { 00597 return 0; 00598 } 00599 return _netmask_buffer; 00600 } 00601 00602 const char *ESP32::getNetmask_ap() 00603 { 00604 bool ret; 00605 00606 _smutex.lock(); 00607 _startup_wifi(); 00608 ret = _parser.send("AT+CIPAP?") 00609 && _parser.recv("+CIPAP:netmask:\"%15[^\"]\"", _netmask_buffer_ap) 00610 && _parser.recv("OK"); 00611 _smutex.unlock(); 00612 00613 if (!ret) { 00614 return 0; 00615 } 00616 return _netmask_buffer_ap; 00617 } 00618 00619 int8_t ESP32::getRSSI() 00620 { 00621 bool ret; 00622 int8_t rssi[2]; /* It needs 1 byte extra. */ 00623 char ssid[33]; 00624 char bssid[18]; 00625 00626 _smutex.lock(); 00627 _startup_wifi(); 00628 ret = _parser.send("AT+CWJAP?") 00629 && _parser.recv("+CWJAP:\"%32[^\"]\",\"%17[^\"]\"", ssid, bssid) 00630 && _parser.recv("OK"); 00631 if (!ret) { 00632 _smutex.unlock(); 00633 return 0; 00634 } 00635 00636 ret = _parser.send("AT+CWLAP=\"%s\",\"%s\"", ssid, bssid) 00637 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi[0]) 00638 && _parser.recv("OK"); 00639 _smutex.unlock(); 00640 00641 if (!ret) { 00642 return 0; 00643 } 00644 00645 return rssi[0]; 00646 } 00647 00648 int ESP32::scan(WiFiAccessPoint *res, unsigned limit) 00649 { 00650 unsigned cnt = 0; 00651 nsapi_wifi_ap_t ap; 00652 00653 if (!_init_end_wifi) { 00654 _smutex.lock(); 00655 _startup_wifi(); 00656 _smutex.unlock(); 00657 ThisThread::sleep_for(1500); 00658 } 00659 00660 _smutex.lock(); 00661 setTimeout(5000); 00662 if (!_parser.send("AT+CWLAP")) { 00663 _smutex.unlock(); 00664 return NSAPI_ERROR_DEVICE_ERROR; 00665 } 00666 00667 while (recv_ap(&ap)) { 00668 if (cnt < limit) { 00669 res[cnt] = WiFiAccessPoint(ap); 00670 } 00671 00672 cnt++; 00673 if ((limit != 0) && (cnt >= limit)) { 00674 setTimeout(10); 00675 _parser.recv("OK"); 00676 break; 00677 } 00678 setTimeout(500); 00679 } 00680 setTimeout(); 00681 _smutex.unlock(); 00682 00683 return cnt; 00684 } 00685 00686 bool ESP32::isConnected(void) 00687 { 00688 return getIPAddress() != 0; 00689 } 00690 00691 bool ESP32::open(const char *type, int id, const char* addr, int port, int opt) 00692 { 00693 bool ret; 00694 00695 if (id >= SOCKET_COUNT) { 00696 return false; 00697 } 00698 _cbs[id].Notified = 0; 00699 00700 _smutex.lock(); 00701 _startup_wifi(); 00702 setTimeout(ESP32_SEND_TIMEOUT); 00703 if (opt != 0) { 00704 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d,%d", id, type, addr, port, opt) 00705 && _parser.recv("OK"); 00706 } else { 00707 ret = _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port) 00708 && _parser.recv("OK"); 00709 } 00710 setTimeout(); 00711 _clear_socket_packets(id); 00712 _smutex.unlock(); 00713 00714 return ret; 00715 } 00716 00717 bool ESP32::send(int id, const void *data, uint32_t amount) 00718 { 00719 int send_size; 00720 int max_send_size = 2048; 00721 bool ret; 00722 int error_cnt = 0; 00723 int index = 0; 00724 00725 _cbs[id].Notified = 0; 00726 if (amount == 0) { 00727 return true; 00728 } 00729 00730 if (_cts == NC) { 00731 max_send_size = 512; 00732 } 00733 00734 //May take a second try if device is busy 00735 while (error_cnt < 2) { 00736 _smutex.lock(); 00737 if ((_id_bits & (1 << id)) == 0) { 00738 _smutex.unlock(); 00739 return false; 00740 } 00741 send_size = amount; 00742 if (send_size > max_send_size) { 00743 send_size = max_send_size; 00744 } 00745 _startup_wifi(); 00746 setTimeout(ESP32_SEND_TIMEOUT); 00747 ret = _parser.send("AT+CIPSEND=%d,%d", id, send_size) 00748 && _parser.recv(">") 00749 && (_parser.write((char*)data + index, (int)send_size) >= 0) 00750 && _parser.recv("SEND OK"); 00751 setTimeout(); 00752 _smutex.unlock(); 00753 if (ret) { 00754 amount -= send_size; 00755 index += send_size; 00756 error_cnt = 0; 00757 if (amount == 0) { 00758 return true; 00759 } 00760 } else { 00761 error_cnt++; 00762 } 00763 } 00764 00765 return false; 00766 } 00767 00768 void ESP32::_packet_handler() 00769 { 00770 int id; 00771 int amount; 00772 uint32_t tmp_timeout; 00773 00774 // parse out the packet 00775 if (!_parser.recv(",%d,%d:", &id, &amount)) { 00776 return; 00777 } 00778 00779 struct packet *packet = (struct packet*)malloc( 00780 sizeof(struct packet) + amount); 00781 if (!packet) { 00782 return; 00783 } 00784 00785 packet->id = id; 00786 packet->len = amount; 00787 packet->next = 0; 00788 packet->index = 0; 00789 00790 tmp_timeout = last_timeout_ms; 00791 setTimeout(500); 00792 if (!(_parser.read((char*)(packet + 1), amount))) { 00793 free(packet); 00794 setTimeout(tmp_timeout); 00795 return; 00796 } 00797 00798 // append to packet list 00799 *_packets_end = packet; 00800 _packets_end = &packet->next; 00801 } 00802 00803 int32_t ESP32::recv(int id, void *data, uint32_t amount, uint32_t timeout) 00804 { 00805 struct packet **p; 00806 uint32_t idx = 0; 00807 00808 _cbs[id].Notified = 0; 00809 00810 _smutex.lock(); 00811 setTimeout(timeout); 00812 if (_rts == NC) { 00813 while (_parser.process_oob()); // Poll for inbound packets 00814 } else { 00815 _parser.process_oob(); // Poll for inbound packets 00816 } 00817 setTimeout(); 00818 00819 // check if any packets are ready for us 00820 p = &_packets; 00821 while (*p) { 00822 if ((*p)->id == id) { 00823 struct packet *q = *p; 00824 00825 if (q->len <= amount) { // Return and remove full packet 00826 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, q->len); 00827 if (_packets_end == &(*p)->next) { 00828 _packets_end = p; 00829 } 00830 *p = (*p)->next; 00831 idx += q->len; 00832 amount -= q->len; 00833 free(q); 00834 } else { // return only partial packet 00835 memcpy(&(((uint8_t *)data)[idx]), (uint8_t*)(q+1) + q->index, amount); 00836 q->len -= amount; 00837 q->index += amount; 00838 idx += amount; 00839 } 00840 break; 00841 } else { 00842 p = &(*p)->next; 00843 } 00844 } 00845 _smutex.unlock(); 00846 00847 if (idx > 0) { 00848 return idx; 00849 } else if ((_id_bits & (1 << id)) == 0) { 00850 return 0; 00851 } else { 00852 _cbs[id].Notified = 0; 00853 return -1; 00854 } 00855 } 00856 00857 void ESP32::_clear_socket_packets(int id) 00858 { 00859 struct packet **p = &_packets; 00860 00861 while (*p) { 00862 if ((*p)->id == id || id == ESP32_ALL_SOCKET_IDS) { 00863 struct packet *q = *p; 00864 00865 if (_packets_end == &(*p)->next) { 00866 _packets_end = p; // Set last packet next field/_packets 00867 } 00868 *p = (*p)->next; 00869 00870 free(q); 00871 } else { 00872 // Point to last packet next field 00873 p = &(*p)->next; 00874 } 00875 } 00876 } 00877 00878 bool ESP32::close(int id, bool wait_close) 00879 { 00880 if (wait_close) { 00881 _smutex.lock(); 00882 for (int j = 0; j < 2; j++) { 00883 if ((_id_bits & (1 << id)) == 0) { 00884 _ids[id] = false; 00885 _clear_socket_packets(id); 00886 _smutex.unlock(); 00887 return true; 00888 } 00889 _startup_wifi(); 00890 setTimeout(500); 00891 _parser.process_oob(); // Poll for inbound packets 00892 setTimeout(); 00893 } 00894 _smutex.unlock(); 00895 } 00896 00897 //May take a second try if device is busy 00898 for (unsigned i = 0; i < 2; i++) { 00899 _smutex.lock(); 00900 if ((_id_bits & (1 << id)) == 0) { 00901 _ids[id] = false; 00902 _clear_socket_packets(id); 00903 _smutex.unlock(); 00904 return true; 00905 } 00906 _startup_wifi(); 00907 setTimeout(500); 00908 if (_parser.send("AT+CIPCLOSE=%d", id) 00909 && _parser.recv("OK")) { 00910 setTimeout(); 00911 _clear_socket_packets(id); 00912 _ids[id] = false; 00913 _smutex.unlock(); 00914 return true; 00915 } 00916 setTimeout(); 00917 _smutex.unlock(); 00918 } 00919 00920 _ids[id] = false; 00921 return false; 00922 } 00923 00924 void ESP32::setTimeout(uint32_t timeout_ms) 00925 { 00926 last_timeout_ms = timeout_ms; 00927 _parser.set_timeout(timeout_ms); 00928 } 00929 00930 bool ESP32::readable() 00931 { 00932 return _serial.FileHandle::readable(); 00933 } 00934 00935 bool ESP32::writeable() 00936 { 00937 return _serial.FileHandle::writable(); 00938 } 00939 00940 void ESP32::socket_attach(int id, void (*callback)(void *), void *data) 00941 { 00942 _cbs[id].callback = callback; 00943 _cbs[id].data = data; 00944 _cbs[id].Notified = 0; 00945 } 00946 00947 bool ESP32::recv_ap(nsapi_wifi_ap_t *ap) 00948 { 00949 bool ret; 00950 int c; 00951 const char keyword_0[8] = "+CWLAP:"; 00952 const char keyword_1[6] = "\nOK\r\n"; 00953 int idx_0 = 0; 00954 int idx_1 = 0; 00955 00956 while (true) { 00957 c = _parser.getc(); 00958 if (c < 0) { 00959 ret = false; 00960 break; 00961 } 00962 if ((char)c == keyword_0[idx_0]) { 00963 idx_0++; 00964 } else { 00965 idx_0 = 0; 00966 } 00967 if ((char)c == keyword_1[idx_1]) { 00968 idx_1++; 00969 } else { 00970 idx_1 = 0; 00971 } 00972 00973 // "+CWLAP:" 00974 if (idx_0 >= (int)(sizeof(keyword_0) - 1)) { 00975 int sec; 00976 uint8_t work_buf[6+1]; /* It needs 1 byte extra. */ 00977 int8_t work_rssi[2]; /* It needs 1 byte extra. */ 00978 00979 ret = _parser.recv("(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%hhu)", &sec, ap->ssid, 00980 &work_rssi[0], &work_buf[0], &work_buf[1], &work_buf[2], &work_buf[3], &work_buf[4], 00981 &work_buf[5], &ap->channel); 00982 ap->rssi = work_rssi[0]; 00983 memcpy(ap->bssid, work_buf, 6); 00984 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN; 00985 break; 00986 } 00987 00988 // "\nOK\r\n" 00989 if (idx_1 >= (int)(sizeof(keyword_1) - 1)) { 00990 ret = false; 00991 break; 00992 } 00993 } 00994 00995 return ret; 00996 } 00997 00998 void ESP32::_connect_handler_0() { socket_handler(true, 0); } 00999 void ESP32::_connect_handler_1() { socket_handler(true, 1); } 01000 void ESP32::_connect_handler_2() { socket_handler(true, 2); } 01001 void ESP32::_connect_handler_3() { socket_handler(true, 3); } 01002 void ESP32::_connect_handler_4() { socket_handler(true, 4); } 01003 void ESP32::_closed_handler_0() { socket_handler(false, 0); } 01004 void ESP32::_closed_handler_1() { socket_handler(false, 1); } 01005 void ESP32::_closed_handler_2() { socket_handler(false, 2); } 01006 void ESP32::_closed_handler_3() { socket_handler(false, 3); } 01007 void ESP32::_closed_handler_4() { socket_handler(false, 4); } 01008 01009 void ESP32::_connection_status_handler() 01010 { 01011 char status[13]; 01012 if (_parser.recv("%12[^\"]\n", status)) { 01013 if (strcmp(status, "CONNECTED\n") == 0) { 01014 _wifi_status = STATUS_CONNECTED; 01015 } else if (strcmp(status, "GOT IP\n") == 0) { 01016 _wifi_status = STATUS_GOT_IP; 01017 } else if (strcmp(status, "DISCONNECT\n") == 0) { 01018 _wifi_status = STATUS_DISCONNECTED; 01019 } else { 01020 return; 01021 } 01022 01023 if(_wifi_status_cb) { 01024 _wifi_status_cb(_wifi_status); 01025 } 01026 } 01027 } 01028 01029 int ESP32::get_free_id() 01030 { 01031 // Look for an unused socket 01032 int id = -1; 01033 01034 for (int i = 0; i < SOCKET_COUNT; i++) { 01035 if ((!_ids[i]) && ((_id_bits & (1 << i)) == 0)) { 01036 id = i; 01037 _ids[i] = true; 01038 break; 01039 } 01040 } 01041 01042 return id; 01043 } 01044 01045 void ESP32::event() { 01046 #if defined(TARGET_ESP32AT_BLE) 01047 if ((_cbs_ble.callback) && (_cbs_ble.Notified == 0)) { 01048 _cbs_ble.Notified = 1; 01049 _cbs_ble.callback(); 01050 } 01051 #endif /* TARGET_ESP32AT_BLE */ 01052 for (int i = 0; i < SOCKET_COUNT; i++) { 01053 if ((_cbs[i].callback) && (_cbs[i].Notified == 0)) { 01054 _cbs[i].Notified = 1; 01055 _cbs[i].callback(_cbs[i].data); 01056 } 01057 } 01058 } 01059 01060 bool ESP32::set_network(const char *ip_address, const char *netmask, const char *gateway) 01061 { 01062 bool ret; 01063 01064 if (ip_address == NULL) { 01065 return false; 01066 } 01067 01068 _smutex.lock(); 01069 if ((netmask != NULL) && (gateway != NULL)) { 01070 ret = _parser.send("AT+CIPSTA=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask) 01071 && _parser.recv("OK"); 01072 } else { 01073 ret = _parser.send("AT+CIPSTA=\"%s\"", ip_address) 01074 && _parser.recv("OK"); 01075 } 01076 _smutex.unlock(); 01077 01078 return ret; 01079 } 01080 01081 bool ESP32::set_network_ap(const char *ip_address, const char *netmask, const char *gateway) 01082 { 01083 bool ret; 01084 01085 if (ip_address == NULL) { 01086 return false; 01087 } 01088 01089 _smutex.lock(); 01090 if ((netmask != NULL) && (gateway != NULL)) { 01091 ret = _parser.send("AT+CIPAP=\"%s\",\"%s\",\"%s\"", ip_address, gateway, netmask) 01092 && _parser.recv("OK"); 01093 } else { 01094 ret = _parser.send("AT+CIPAP=\"%s\"", ip_address) 01095 && _parser.recv("OK"); 01096 } 01097 _smutex.unlock(); 01098 01099 return ret; 01100 } 01101 01102 void ESP32::attach_wifi_status(mbed::Callback<void(int8_t)> status_cb) 01103 { 01104 _wifi_status_cb = status_cb; 01105 } 01106 01107 int8_t ESP32::get_wifi_status() const 01108 { 01109 return _wifi_status; 01110 } 01111 01112 #if defined(TARGET_ESP32AT_BLE) 01113 bool ESP32::ble_set_role(int role) 01114 { 01115 if ((role != INIT_CLIENT_ROLE) && (role != INIT_SERVER_ROLE)) { 01116 return false; 01117 } 01118 if (_ble_role != role) { 01119 _ble_role = role; 01120 if (_init_end_ble) { 01121 return restart(); 01122 } 01123 } 01124 return true; 01125 } 01126 01127 bool ESP32::ble_get_role(int * role) 01128 { 01129 *role = _ble_role; 01130 return true; 01131 } 01132 01133 bool ESP32::ble_set_device_name(const char * name) 01134 { 01135 bool ret; 01136 01137 _smutex.lock(); 01138 _startup_ble(); 01139 setTimeout(ESP32_MISC_TIMEOUT); 01140 ret = _parser.send("AT+BLENAME=\"%s\"", name) 01141 && _parser.recv("OK"); 01142 setTimeout(); 01143 _smutex.unlock(); 01144 if (!ret) { 01145 return false; 01146 } 01147 return true; 01148 } 01149 01150 bool ESP32::ble_get_device_name(char * name) 01151 { 01152 bool ret; 01153 01154 _smutex.lock(); 01155 _startup_ble(); 01156 setTimeout(ESP32_MISC_TIMEOUT); 01157 ret = _parser.send("AT+BLENAME?") 01158 && _parser.recv("+BLENAME:%s\n", name); 01159 setTimeout(); 01160 _smutex.unlock(); 01161 if (!ret) { 01162 return false; 01163 } 01164 return true; 01165 } 01166 01167 01168 bool ESP32::ble_start_services() 01169 { 01170 bool ret; 01171 01172 ble_set_role(INIT_SERVER_ROLE); 01173 _smutex.lock(); 01174 _startup_ble(); 01175 setTimeout(ESP32_MISC_TIMEOUT); 01176 ret = _parser.send("AT+BLEGATTSSRVCRE") 01177 && _parser.recv("OK") 01178 && _parser.send("AT+BLEGATTSSRVSTART") 01179 && _parser.recv("OK"); 01180 setTimeout(); 01181 _smutex.unlock(); 01182 if (!ret) { 01183 return false; 01184 } 01185 return true; 01186 } 01187 01188 bool ESP32::ble_set_scan_response(const uint8_t * data, int len) 01189 { 01190 bool ret; 01191 int size = 0; 01192 char * wk_buf = new char[1024]; 01193 01194 if (wk_buf == NULL) { 01195 return false; 01196 } 01197 01198 sprintf(&wk_buf[size], "AT+BLESCANRSPDATA=\""); 01199 size = strlen(wk_buf); 01200 _set_char(&wk_buf[size], data, len); 01201 strcat(wk_buf, "\""); 01202 01203 ble_set_role(INIT_SERVER_ROLE); 01204 _smutex.lock(); 01205 _startup_ble(); 01206 setTimeout(ESP32_MISC_TIMEOUT); 01207 ret = _parser.send("%s", wk_buf) 01208 && _parser.recv("OK"); 01209 setTimeout(); 01210 _smutex.unlock(); 01211 01212 delete [] wk_buf; 01213 01214 if (!ret) { 01215 return false; 01216 } 01217 return true; 01218 } 01219 01220 bool ESP32::ble_start_advertising() 01221 { 01222 bool ret; 01223 01224 ble_set_role(INIT_SERVER_ROLE); 01225 _smutex.lock(); 01226 _startup_ble(); 01227 setTimeout(ESP32_MISC_TIMEOUT); 01228 ret = _parser.send("AT+BLEADVSTART") 01229 && _parser.recv("OK"); 01230 setTimeout(); 01231 _smutex.unlock(); 01232 if (!ret) { 01233 return false; 01234 } 01235 return true; 01236 } 01237 01238 bool ESP32::ble_stop_advertising() 01239 { 01240 bool ret; 01241 01242 ble_set_role(INIT_SERVER_ROLE); 01243 _smutex.lock(); 01244 _startup_ble(); 01245 setTimeout(ESP32_MISC_TIMEOUT); 01246 ret = _parser.send("AT+BLEADVSTOP") 01247 && _parser.recv("OK"); 01248 setTimeout(); 01249 _smutex.unlock(); 01250 if (!ret) { 01251 return false; 01252 } 01253 return true; 01254 } 01255 01256 bool ESP32::ble_set_addr(int addr_type, const uint8_t * random_addr) 01257 { 01258 bool ret; 01259 01260 _smutex.lock(); 01261 _startup_ble(); 01262 setTimeout(ESP32_MISC_TIMEOUT); 01263 if ((addr_type == 1) && (random_addr != NULL)) { 01264 ret = _parser.send("AT+BLEADDR=1,\"%02x:%02x:%02x:%02x:%02x:%02x\"", 01265 random_addr[0], random_addr[1], random_addr[2], random_addr[3], random_addr[4], random_addr[5]) 01266 && _parser.recv("OK"); 01267 } else { 01268 ret = _parser.send("AT+BLEADDR=%d", addr_type) 01269 && _parser.recv("OK"); 01270 } 01271 setTimeout(); 01272 _smutex.unlock(); 01273 if (!ret) { 01274 return false; 01275 } 01276 return true; 01277 } 01278 01279 bool ESP32::ble_get_addr(uint8_t * public_addr) 01280 { 01281 bool ret; 01282 uint8_t work_buf[6+1]; /* It needs 1 byte extra. */ 01283 01284 _smutex.lock(); 01285 _startup_ble(); 01286 setTimeout(ESP32_MISC_TIMEOUT); 01287 ret = _parser.send("AT+BLEADDR?") 01288 && _parser.recv("+BLEADDR:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n", 01289 &work_buf[0], &work_buf[1], &work_buf[2], &work_buf[3], &work_buf[4], &work_buf[5]) 01290 && _parser.recv("OK"); 01291 setTimeout(); 01292 _smutex.unlock(); 01293 if (!ret) { 01294 return false; 01295 } 01296 memcpy(public_addr, work_buf, 6); 01297 01298 return true; 01299 } 01300 01301 bool ESP32::ble_set_advertising_param(const advertising_param_t * param) 01302 { 01303 bool ret; 01304 01305 ble_set_role(INIT_SERVER_ROLE); 01306 _smutex.lock(); 01307 _startup_ble(); 01308 setTimeout(ESP32_MISC_TIMEOUT); 01309 ret = _parser.send("AT+BLEADVPARAM=%d,%d,%d,%d,%d,%d,%d,\"%02x:%02x:%02x:%02x:%02x:%02x\"", 01310 param->adv_int_min, param->adv_int_max, param->adv_type, param->own_addr_type, 01311 param->channel_map, param->adv_filter_policy, param->peer_addr_type, 01312 param->peer_addr[0], param->peer_addr[1], param->peer_addr[2], 01313 param->peer_addr[3], param->peer_addr[4], param->peer_addr[5]) 01314 && _parser.recv("OK"); 01315 setTimeout(); 01316 _smutex.unlock(); 01317 if (!ret) { 01318 return false; 01319 } 01320 return true; 01321 } 01322 01323 bool ESP32::ble_set_advertising_data(const uint8_t * data, int len) 01324 { 01325 bool ret; 01326 int size = 0; 01327 char * wk_buf = new char[1024]; 01328 01329 if (wk_buf == NULL) { 01330 return false; 01331 } 01332 01333 sprintf(&wk_buf[size], "AT+BLEADVDATA=\""); 01334 size = strlen(wk_buf); 01335 _set_char(&wk_buf[size], data, len); 01336 strcat(wk_buf, "\""); 01337 01338 ble_set_role(INIT_SERVER_ROLE); 01339 _smutex.lock(); 01340 _startup_ble(); 01341 setTimeout(ESP32_MISC_TIMEOUT); 01342 ret = _parser.send("%s", wk_buf) 01343 && _parser.recv("OK"); 01344 setTimeout(); 01345 _smutex.unlock(); 01346 01347 delete [] wk_buf; 01348 01349 if (!ret) { 01350 return false; 01351 } 01352 return true; 01353 } 01354 01355 bool ESP32::ble_set_service(const gatt_service_t * service_list, int num) 01356 { 01357 uint8_t header[17] = {0x9D,0x10,0x27,0x95,0x7B,0x22,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x22,0x3A,0x20,0x5B}; 01358 bool ret; 01359 int idx = 0; 01360 int size = 0; 01361 uint8_t wk_data[4]; 01362 char * wk_buf = new char[1024]; 01363 01364 if (wk_buf == NULL) { 01365 return false; 01366 } 01367 01368 ble_set_role(INIT_SERVER_ROLE); 01369 _smutex.lock(); 01370 _startup_ble(); 01371 setTimeout(ESP32_MISC_TIMEOUT); 01372 01373 size = sizeof(header); 01374 ret = _parser.send("AT+SYSFLASH=0,\"ble_data\"") 01375 && _parser.recv("OK") 01376 && _parser.send("AT+SYSFLASH=1,\"ble_data\",0,%d", size) 01377 && _parser.recv(">") 01378 && (_parser.write((char*)header, size) >= 0) 01379 && _parser.recv("OK"); 01380 idx += size; 01381 if (!ret) { 01382 _smutex.unlock(); 01383 delete [] wk_buf; 01384 return false; 01385 } 01386 01387 for (int i = 0; i < num; i++) { 01388 size = 0; 01389 sprintf(&wk_buf[size], "{\"index\": %d, \"uuid\": \"", i); 01390 size = strlen(wk_buf); 01391 if ((service_list->uuid_type != 0) && (service_list->uuid_size <= 4)) { 01392 for (int j = 0; j < service_list->uuid_size; j++) { 01393 wk_data[j] = (service_list->uuid.data >> (8 * (service_list->uuid_size - 1 - j))) & 0x00FF; 01394 } 01395 _set_char(&wk_buf[size], wk_data, service_list->uuid_size); 01396 } else { 01397 _set_char(&wk_buf[size], service_list->uuid.addr, service_list->uuid_size); 01398 } 01399 size = strlen(wk_buf); 01400 01401 sprintf(&wk_buf[size], "\", \"uuid_len\": %d, \"val_max_len\": %d, \"value\": \"", 01402 service_list->uuid_size * 8, service_list->val_max_len); 01403 size = strlen(wk_buf); 01404 01405 if ((service_list->value_type != 0) && (service_list->value_size <= 4)) { 01406 for (int j = 0; j < service_list->value_size; j++) { 01407 wk_data[j] = (service_list->value.data >> (8 * (service_list->value_size - 1 - j))) & 0x00FF; 01408 } 01409 _set_char(&wk_buf[size], wk_data, service_list->value_size); 01410 } else { 01411 _set_char(&wk_buf[size], service_list->value.addr, service_list->value_size); 01412 } 01413 size = strlen(wk_buf); 01414 01415 sprintf(&wk_buf[size], "\", \"perm\": %d, \"val_cur_len\": %d}", 01416 service_list->permissions, service_list->value_size); 01417 if ((i + 1) == num) { 01418 strcat(wk_buf, "]}"); 01419 } else { 01420 strcat(wk_buf, ", "); 01421 } 01422 size = strlen(wk_buf); 01423 01424 ret = _parser.send("AT+SYSFLASH=1,\"ble_data\",%d,%d", idx, size) 01425 && _parser.recv(">") 01426 && (_parser.write((char*)wk_buf, size) >= 0) 01427 && _parser.recv("OK"); 01428 idx += size; 01429 if (!ret) { 01430 break; 01431 } 01432 service_list++; 01433 } 01434 delete [] wk_buf; 01435 01436 setTimeout(); 01437 _smutex.unlock(); 01438 if (!ret) { 01439 return false; 01440 } 01441 return true; 01442 } 01443 01444 bool ESP32::ble_set_characteristic(int srv_index, int char_index, const uint8_t * data, int len) 01445 { 01446 bool ret; 01447 01448 ble_set_role(INIT_SERVER_ROLE); 01449 _smutex.lock(); 01450 _startup_ble(); 01451 setTimeout(ESP32_MISC_TIMEOUT); 01452 ret = _parser.send("AT+BLEGATTSSETATTR=%d,%d,,%d", srv_index, char_index, len) 01453 && _parser.recv(">") 01454 && (_parser.write((char*)data, len) >= 0) 01455 && _parser.recv("OK"); 01456 setTimeout(); 01457 _smutex.unlock(); 01458 if (!ret) { 01459 return false; 01460 } 01461 return true; 01462 } 01463 01464 bool ESP32::ble_notifies_characteristic(int srv_index, int char_index, const uint8_t * data, int len) 01465 { 01466 bool ret; 01467 01468 ble_set_role(INIT_SERVER_ROLE); 01469 _smutex.lock(); 01470 _startup_ble(); 01471 setTimeout(ESP32_MISC_TIMEOUT); 01472 ret = _parser.send("AT+BLEGATTSNTFY=0,%d,%d,%d", srv_index, char_index, len) 01473 && _parser.recv(">") 01474 && (_parser.write((char*)data, len) >= 0) 01475 && _parser.recv("OK"); 01476 setTimeout(); 01477 _smutex.unlock(); 01478 if (!ret) { 01479 return false; 01480 } 01481 return true; 01482 } 01483 01484 bool ESP32::ble_set_scan_param(int scan_type, int own_addr_type, int filter_policy, int scan_interval, int scan_window) 01485 { 01486 bool ret; 01487 01488 ble_set_role(INIT_CLIENT_ROLE); 01489 _smutex.lock(); 01490 _startup_ble(); 01491 ret = _parser.send("AT+BLESCANPARAM=%d,%d,%d,%d,%d", 01492 scan_type, own_addr_type, filter_policy, scan_interval, scan_window) 01493 && _parser.recv("OK"); 01494 _smutex.unlock(); 01495 if (!ret) { 01496 return false; 01497 } 01498 return true; 01499 } 01500 01501 bool ESP32::ble_start_scan(int interval) 01502 { 01503 bool ret; 01504 01505 ble_set_role(INIT_CLIENT_ROLE); 01506 _smutex.lock(); 01507 _startup_ble(); 01508 ret = _parser.send("AT+BLESCAN=1,%d", interval); 01509 _smutex.unlock(); 01510 if (!ret) { 01511 return false; 01512 } 01513 return true; 01514 } 01515 01516 bool ESP32::ble_stop_scan() 01517 { 01518 bool ret; 01519 01520 ble_set_role(INIT_CLIENT_ROLE); 01521 _smutex.lock(); 01522 _startup_ble(); 01523 setTimeout(ESP32_MISC_TIMEOUT); 01524 ret = _parser.send("AT+BLESCAN=0") 01525 && _parser.recv("OK"); 01526 setTimeout(); 01527 _smutex.unlock(); 01528 if (!ret) { 01529 return false; 01530 } 01531 return true; 01532 } 01533 01534 bool ESP32::ble_connect(int conn_index, const uint8_t * remote_addr) 01535 { 01536 bool ret; 01537 01538 ble_set_role(INIT_CLIENT_ROLE); 01539 _smutex.lock(); 01540 _startup_ble(); 01541 setTimeout(ESP32_MISC_TIMEOUT); 01542 ret = _parser.send("AT+BLECONN=%d,\"%02x:%02x:%02x:%02x:%02x:%02x\"", conn_index, 01543 remote_addr[0], remote_addr[1], remote_addr[2], 01544 remote_addr[3], remote_addr[4], remote_addr[5]) 01545 && _parser.recv("OK"); 01546 setTimeout(); 01547 _smutex.unlock(); 01548 if (!ret) { 01549 return false; 01550 } 01551 return true; 01552 } 01553 01554 bool ESP32::ble_disconnect(int conn_index) 01555 { 01556 bool ret; 01557 01558 ble_set_role(INIT_CLIENT_ROLE); 01559 _smutex.lock(); 01560 _startup_ble(); 01561 setTimeout(ESP32_MISC_TIMEOUT); 01562 ret = _parser.send("AT+BLEDISCONN=%d", conn_index) 01563 && _parser.recv("OK"); 01564 setTimeout(); 01565 _smutex.unlock(); 01566 if (!ret) { 01567 return false; 01568 } 01569 return true; 01570 } 01571 01572 bool ESP32::ble_discovery_service(int conn_index, ble_primary_service_t * service, int * num) 01573 { 01574 bool ret; 01575 int cpy_num; 01576 01577 if ((service == NULL) || (num == NULL)) { 01578 return false; 01579 } 01580 01581 ble_set_role(INIT_CLIENT_ROLE); 01582 _smutex.lock(); 01583 _startup_ble(); 01584 setTimeout(ESP32_MISC_TIMEOUT); 01585 _primary_service_idx = 0; 01586 ret = _parser.send("AT+BLEGATTCPRIMSRV=%d", conn_index) 01587 && _parser.recv("OK"); 01588 setTimeout(); 01589 _smutex.unlock(); 01590 if (!ret) { 01591 *num = 0; 01592 return false; 01593 } 01594 01595 cpy_num = *num; 01596 if (cpy_num > _primary_service_idx) { 01597 cpy_num = _primary_service_idx; 01598 } 01599 for (int i = 0; i < cpy_num; i++) { 01600 service[i] = _primary_service[i]; 01601 } 01602 *num = cpy_num; 01603 01604 return true; 01605 } 01606 01607 bool ESP32::ble_discovery_characteristics( 01608 int conn_index, int srv_index, 01609 ble_discovers_char_t * discovers_char, int * char_num, 01610 ble_discovers_desc_t * discovers_desc, int * desc_num 01611 ) 01612 { 01613 bool ret; 01614 int cpy_num; 01615 01616 ble_set_role(INIT_CLIENT_ROLE); 01617 _smutex.lock(); 01618 _startup_ble(); 01619 setTimeout(ESP32_MISC_TIMEOUT); 01620 _discovers_char_idx = 0; 01621 _discovers_desc_idx = 0; 01622 ret = _parser.send("AT+BLEGATTCCHAR=%d,%d", conn_index, srv_index) 01623 && _parser.recv("OK"); 01624 setTimeout(); 01625 _smutex.unlock(); 01626 if (!ret) { 01627 if (char_num != NULL) { 01628 *char_num = 0; 01629 } 01630 if (desc_num != NULL) { 01631 *desc_num = 0; 01632 } 01633 return false; 01634 } 01635 01636 if ((discovers_char != NULL) && (char_num != NULL)) { 01637 cpy_num = *char_num; 01638 if (cpy_num > _discovers_char_idx) { 01639 cpy_num = _discovers_char_idx; 01640 } 01641 for (int i = 0; i < cpy_num; i++) { 01642 discovers_char[i] = _discovers_char[i]; 01643 } 01644 *char_num = cpy_num; 01645 } 01646 01647 if ((discovers_desc != NULL) && (desc_num != NULL)) { 01648 cpy_num = *desc_num; 01649 if (cpy_num > _discovers_desc_idx) { 01650 cpy_num = _discovers_desc_idx; 01651 } 01652 for (int i = 0; i < cpy_num; i++) { 01653 discovers_desc[i] = _discovers_desc[i]; 01654 } 01655 *desc_num = cpy_num; 01656 } 01657 01658 return true; 01659 } 01660 01661 int32_t ESP32::ble_read_characteristic(int conn_index, int srv_index, int char_index, uint8_t * data, int amount) 01662 { 01663 bool ret; 01664 int wk_conn_index; 01665 int data_len; 01666 int idx = 0;; 01667 char c; 01668 01669 ble_set_role(INIT_CLIENT_ROLE); 01670 _smutex.lock(); 01671 _startup_ble(); 01672 setTimeout(ESP32_MISC_TIMEOUT); 01673 ret = _parser.send("AT+BLEGATTCRD=%d,%d,%d", conn_index, srv_index, char_index) 01674 && _parser.recv("+BLEGATTCRD:%d,%d,", &wk_conn_index, &data_len); 01675 if (!ret) { 01676 setTimeout(); 01677 _smutex.unlock(); 01678 return -1; 01679 } 01680 for (int i = 0; i < data_len; i++) { 01681 c = _parser.getc(); 01682 if (idx < amount) { 01683 data[idx++] = (uint8_t)c; 01684 } 01685 } 01686 _parser.recv("OK"); 01687 01688 setTimeout(); 01689 _smutex.unlock(); 01690 01691 return idx; 01692 } 01693 01694 int32_t ESP32::ble_read_descriptor(int conn_index, int srv_index, int char_index, int desc_index, uint8_t * data, int amount) 01695 { 01696 bool ret; 01697 int wk_conn_index; 01698 int data_len; 01699 int idx = 0;; 01700 char c; 01701 01702 ble_set_role(INIT_CLIENT_ROLE); 01703 _smutex.lock(); 01704 _startup_ble(); 01705 setTimeout(ESP32_MISC_TIMEOUT); 01706 ret = _parser.send("AT+BLEGATTCRD=%d,%d,%d,%d", conn_index, srv_index, char_index, desc_index) 01707 && _parser.recv("+BLEGATTCRD:%d,%d,", &wk_conn_index, &data_len); 01708 if (!ret) { 01709 setTimeout(); 01710 _smutex.unlock(); 01711 return 0; 01712 } 01713 for (int i = 0; i < data_len; i++) { 01714 c = _parser.getc(); 01715 if (idx < amount) { 01716 data[idx++] = (uint8_t)c; 01717 } 01718 } 01719 _parser.recv("OK"); 01720 01721 setTimeout(); 01722 _smutex.unlock(); 01723 01724 return idx; 01725 } 01726 01727 bool ESP32::ble_write_characteristic(int conn_index, int srv_index, int char_index, const uint8_t * data, int amount) 01728 { 01729 bool ret; 01730 01731 ble_set_role(INIT_CLIENT_ROLE); 01732 _smutex.lock(); 01733 _startup_ble(); 01734 setTimeout(ESP32_MISC_TIMEOUT); 01735 ret = _parser.send("AT+BLEGATTCWR=%d,%d,%d,,%d", conn_index, srv_index, char_index, amount) 01736 && _parser.recv(">") 01737 && (_parser.write((char*)data, amount) >= 0) 01738 && _parser.recv("OK"); 01739 setTimeout(); 01740 _smutex.unlock(); 01741 if (!ret) { 01742 return false; 01743 } 01744 return true; 01745 } 01746 01747 bool ESP32::ble_write_descriptor(int conn_index, int srv_index, int char_index, int desc_index, const uint8_t * data, int amount) 01748 { 01749 bool ret; 01750 01751 ble_set_role(INIT_CLIENT_ROLE); 01752 _smutex.lock(); 01753 _startup_ble(); 01754 setTimeout(ESP32_MISC_TIMEOUT); 01755 ret = _parser.send("AT+BLEGATTCWR=%d,%d,%d,%d,%d", conn_index, srv_index, char_index, desc_index, amount) 01756 && _parser.recv(">") 01757 && (_parser.write((char*)data, amount) >= 0) 01758 && _parser.recv("OK"); 01759 setTimeout(); 01760 _smutex.unlock(); 01761 if (!ret) { 01762 return false; 01763 } 01764 return true; 01765 } 01766 01767 void ESP32::ble_process_oob(uint32_t timeout, bool all) 01768 { 01769 _smutex.lock(); 01770 _cbs_ble.Notified = 0; 01771 setTimeout(timeout); 01772 // Poll for inbound packets 01773 while (_parser.process_oob() && all) { 01774 } 01775 setTimeout(); 01776 _smutex.unlock(); 01777 } 01778 01779 void ESP32::ble_attach_sigio(mbed::Callback<void()> cb_func) 01780 { 01781 _smutex.lock(); 01782 _cbs_ble.Notified = 0; 01783 _cbs_ble.callback = cb_func; 01784 _smutex.unlock(); 01785 } 01786 01787 void ESP32::ble_attach_conn(mbed::Callback<void(int, uint8_t *)> cb_func) 01788 { 01789 _smutex.lock(); 01790 _ble_conn_cb = cb_func; 01791 _smutex.unlock(); 01792 } 01793 01794 void ESP32::ble_attach_disconn(mbed::Callback<void(int)> cb_func) 01795 { 01796 _smutex.lock(); 01797 _ble_disconn_cb = cb_func; 01798 _smutex.unlock(); 01799 } 01800 01801 void ESP32::ble_attach_write(mbed::Callback<void(ble_packet_t *)> cb_func) 01802 { 01803 _smutex.lock(); 01804 _ble_write_cb = cb_func; 01805 _smutex.unlock(); 01806 } 01807 01808 void ESP32::ble_attach_scan(mbed::Callback<void(ble_scan_t *)> cb_func) 01809 { 01810 _smutex.lock(); 01811 _ble_scan_cb = cb_func; 01812 _smutex.unlock(); 01813 } 01814 01815 bool ESP32::_startup_ble() 01816 { 01817 _startup_common(); 01818 01819 if (_init_end_ble) { 01820 return true; 01821 } 01822 01823 if (_at_version < 0x01010300) { 01824 printf("Please update ESP32 FW \"AT version:1.1.3.0\" or later.\r\n"); 01825 mbed_die(); 01826 } 01827 01828 setTimeout(ESP32_MISC_TIMEOUT); 01829 bool success = _parser.send("AT+BLEINIT=%d", _ble_role) 01830 && _parser.recv("OK"); 01831 setTimeout(); 01832 if (success) { 01833 _init_end_ble = true; 01834 } 01835 01836 return success; 01837 } 01838 01839 void ESP32::_ble_conn() 01840 { 01841 int conn_index; 01842 uint8_t remote_addr[6+1]; /* It needs 1 byte extra. */ 01843 01844 _parser.recv("%d,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\"", &conn_index, 01845 &remote_addr[0], &remote_addr[1], &remote_addr[2], &remote_addr[3], &remote_addr[4], &remote_addr[5]); 01846 if(_ble_conn_cb) { 01847 _ble_conn_cb(conn_index, remote_addr); 01848 } 01849 } 01850 01851 void ESP32::_ble_disconn() 01852 { 01853 int conn_index; 01854 01855 _parser.recv("%d", &conn_index); 01856 if(_ble_disconn_cb) { 01857 _ble_disconn_cb(conn_index); 01858 } 01859 } 01860 01861 void ESP32::_ble_write() 01862 { 01863 int conn_index; 01864 int srv_index; 01865 int char_index; 01866 int desc_index = -1; 01867 int amount; 01868 char c; 01869 uint32_t tmp_timeout; 01870 01871 if(!_ble_write_cb) { 01872 return; 01873 } 01874 01875 _parser.recv("%d,%d,%d,", &conn_index, &srv_index, &char_index); 01876 (void)conn_index; 01877 c = _parser.getc(); 01878 if (c != ',') { 01879 desc_index = c; 01880 _parser.getc(); // to read ',' after desc_index. 01881 } 01882 _parser.recv("%d,", &amount); 01883 01884 ble_packet_t *ble_packet = (ble_packet_t*)malloc( 01885 sizeof(ble_packet_t) + amount); 01886 if (!ble_packet) { 01887 return; 01888 } 01889 01890 ble_packet->srv_index = srv_index; 01891 ble_packet->char_index = char_index; 01892 ble_packet->desc_index = desc_index; 01893 ble_packet->len = amount; 01894 ble_packet->data = ble_packet + 1; 01895 01896 tmp_timeout = last_timeout_ms; 01897 setTimeout(500); 01898 if (!(_parser.read((char*)(ble_packet + 1), amount))) { 01899 free(ble_packet); 01900 setTimeout(tmp_timeout); 01901 return; 01902 } 01903 if(_ble_write_cb) { 01904 _ble_write_cb(ble_packet); 01905 } 01906 free(ble_packet); 01907 } 01908 01909 void ESP32::_ble_scan() 01910 { 01911 char c; 01912 int idx; 01913 uint8_t work_buf[7]; /* It needs 1 byte extra. */ 01914 int8_t work_rssi[2]; /* It needs 1 byte extra. */ 01915 01916 if(!_ble_scan_cb) { 01917 return; 01918 } 01919 01920 ble_scan_t *ble_scan = (ble_scan_t*)malloc(sizeof(ble_scan_t)); 01921 if (!ble_scan) { 01922 return; 01923 } 01924 01925 _parser.recv("%hhx:%hhx:%hhx:%hhx:%hhx:%hhx,%hhd,", 01926 &work_buf[0], &work_buf[1], &work_buf[2], 01927 &work_buf[3], &work_buf[4], &work_buf[5], 01928 &work_rssi[0]); 01929 01930 memcpy(ble_scan->addr, work_buf, 6); 01931 ble_scan->rssi = work_rssi[0]; 01932 01933 idx = 0; 01934 for (int i = 0; i < (31 * 2); i++) { 01935 c = _parser.getc(); 01936 if (c == ',') { 01937 break; 01938 } 01939 if ((i & 0x01) == 0) { 01940 ble_scan->adv_data[idx] = (_char2int(c) << 4); 01941 } else { 01942 ble_scan->adv_data[idx] += _char2int(c); 01943 idx++; 01944 } 01945 } 01946 ble_scan->adv_data_len = idx; 01947 01948 if (c != ',') { 01949 c = _parser.getc(); 01950 } 01951 01952 idx = 0; 01953 for (int i = 0; i < (31 * 2); i++) { 01954 c = _parser.getc(); 01955 if (c == ',') { 01956 break; 01957 } 01958 if ((i & 0x01) == 0) { 01959 ble_scan->scan_rsp_data[idx] = (_char2int(c) << 4); 01960 } else { 01961 ble_scan->scan_rsp_data[idx] += _char2int(c); 01962 idx++; 01963 } 01964 } 01965 ble_scan->scan_rsp_data_len = idx; 01966 01967 if (c != ',') { 01968 c = _parser.getc(); 01969 } 01970 01971 _parser.recv("%hhd\n", &work_buf[0]); 01972 ble_scan->addr_type = work_buf[0]; 01973 01974 if(_ble_scan_cb) { 01975 _ble_scan_cb(ble_scan); 01976 } 01977 free(ble_scan); 01978 } 01979 01980 void ESP32::_ble_primsrv() 01981 { 01982 // fix me (supports only short uuid) 01983 int conn_index; 01984 ble_primary_service_t * p_service = &_primary_service[_primary_service_idx]; 01985 01986 if (_primary_service_idx < PRIMARY_SERVICE_BUF_NUM) { 01987 if (_parser.recv("%d,%d,%hx,%d\n", &conn_index, &p_service->srv_index, 01988 &p_service->srv_uuid, &p_service->srv_type)) { 01989 _primary_service_idx++; 01990 } 01991 } 01992 } 01993 01994 void ESP32::_ble_discovers_char() 01995 { 01996 // fix me (supports only short uuid) 01997 int conn_index; 01998 int srv_index; 01999 char type[4]; 02000 uint8_t work_buf[2]; /* It needs 1 byte extra. */ 02001 02002 _parser.getc(); // skip '"' 02003 _parser.read(type, 4); 02004 _parser.getc(); // skip '"' 02005 02006 if (_parser.recv(",%d,%d,", &conn_index, &srv_index)) { 02007 if (memcmp(type, "char", 4) == 0) { 02008 if (_discovers_char_idx < DISCOVERS_CHAR_BUF_NUM) { 02009 ble_discovers_char_t * p_char = &_discovers_char[_discovers_char_idx]; 02010 if (_parser.recv("%d,%hx,%hhx\n", &p_char->char_index, &p_char->char_uuid, &work_buf[0])) { 02011 p_char->char_prop = work_buf[0]; 02012 _discovers_char_idx++; 02013 } 02014 } 02015 } else if (memcmp(type, "desc", 4) == 0) { 02016 if (_discovers_desc_idx < DISCOVERS_DESC_BUF_NUM) { 02017 ble_discovers_desc_t * p_desc = &_discovers_desc[_discovers_desc_idx]; 02018 if (_parser.recv("%d,%d,%hx\n", &p_desc->char_index, &p_desc->desc_index, &p_desc->desc_uuid)) { 02019 _discovers_desc_idx++; 02020 } 02021 } 02022 } else { 02023 // do nothing 02024 } 02025 } 02026 } 02027 02028 char ESP32::_int2char(int data) 02029 { 02030 if ((data >= 0) && (data <= 9)) { 02031 return data + '0'; 02032 } else if ((data >= 0xA) && (data <= 0xF)) { 02033 return data - 0xA + 'A'; 02034 } else { 02035 return 0; 02036 } 02037 } 02038 02039 int ESP32::_char2int(char c) 02040 { 02041 if ((c >= '0') && (c <= '9')) { 02042 return c - '0'; 02043 } else if ((c >= 'A') && (c <= 'F')) { 02044 return c - 'A' + 0xA; 02045 } else if ((c >= 'a') && (c <= 'f')) { 02046 return c - 'a' + 0xA; 02047 } else { 02048 return 0; 02049 } 02050 } 02051 02052 int ESP32::_set_char(char * buf1, const uint8_t * buf2, int size) 02053 { 02054 int idx = 0; 02055 02056 for (int i = 0; i < size; i++) { 02057 buf1[idx++] = _int2char((buf2[i]>> 4) & 0x0F); 02058 buf1[idx++] = _int2char(buf2[i] & 0x0F); 02059 } 02060 buf1[idx] = '\0'; 02061 02062 return idx; 02063 } 02064 #endif /* TARGET_ESP32AT_BLE */ 02065 02066 #endif 02067
Generated on Wed Jul 13 2022 05:33:36 by 1.7.2