test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP32.cpp Source File

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