diff --git a/examples/Advanced/NimBLE_Client/main/main.cpp b/examples/Advanced/NimBLE_Client/main/main.cpp index 47f8419..a057b7d 100644 --- a/examples/Advanced/NimBLE_Client/main/main.cpp +++ b/examples/Advanced/NimBLE_Client/main/main.cpp @@ -50,7 +50,7 @@ class ClientCallbacks : public NimBLEClientCallbacks { void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){ printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); }; /** Pairing process complete, we can check the results in connInfo */ @@ -58,7 +58,7 @@ class ClientCallbacks : public NimBLEClientCallbacks { if(!connInfo.isEncrypted()) { printf("Encrypt connection failed - disconnecting\n"); /** Find the client with the connection handle provided in desc */ - NimBLEDevice::getClientByID(connInfo.getConnHandle())->disconnect(); + NimBLEDevice::getClientByHandle(connInfo.getConnHandle())->disconnect(); return; } } diff --git a/examples/Advanced/NimBLE_Server/main/main.cpp b/examples/Advanced/NimBLE_Server/main/main.cpp index 472faa7..e31f5ed 100644 --- a/examples/Advanced/NimBLE_Server/main/main.cpp +++ b/examples/Advanced/NimBLE_Server/main/main.cpp @@ -55,7 +55,7 @@ class ServerCallbacks: public NimBLEServerCallbacks { void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){ printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); }; void onAuthenticationComplete(NimBLEConnInfo& connInfo){ diff --git a/examples/basic/BLE_client/main/main.cpp b/examples/basic/BLE_client/main/main.cpp index 670c4ca..742b9c3 100644 --- a/examples/basic/BLE_client/main/main.cpp +++ b/examples/basic/BLE_client/main/main.cpp @@ -62,7 +62,7 @@ class MyClientCallback : public BLEClientCallbacks { void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){ printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); }; /** Pairing process complete, we can check the results in connInfo */ @@ -70,7 +70,7 @@ class MyClientCallback : public BLEClientCallbacks { if(!connInfo.isEncrypted()) { printf("Encrypt connection failed - disconnecting\n"); /** Find the client with the connection handle provided in desc */ - NimBLEDevice::getClientByID(connInfo.getConnHandle())->disconnect(); + NimBLEDevice::getClientByHandle(connInfo.getConnHandle())->disconnect(); return; } } diff --git a/examples/basic/BLE_notify/main/main.cpp b/examples/basic/BLE_notify/main/main.cpp index 807545a..bdc9318 100644 --- a/examples/basic/BLE_notify/main/main.cpp +++ b/examples/basic/BLE_notify/main/main.cpp @@ -68,7 +68,7 @@ class MyServerCallbacks: public BLEServerCallbacks { void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){ printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); }; void onAuthenticationComplete(NimBLEConnInfo& connInfo){ diff --git a/examples/basic/BLE_uart/main/main.cpp b/examples/basic/BLE_uart/main/main.cpp index 3d0fd5c..005e3af 100644 --- a/examples/basic/BLE_uart/main/main.cpp +++ b/examples/basic/BLE_uart/main/main.cpp @@ -70,7 +70,7 @@ class MyServerCallbacks: public BLEServerCallbacks { void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){ printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); }; void onAuthenticationComplete(NimBLEConnInfo& connInfo){ diff --git a/src/NimBLEAdvertising.cpp b/src/NimBLEAdvertising.cpp index 0ac09d7..150fb6d 100644 --- a/src/NimBLEAdvertising.cpp +++ b/src/NimBLEAdvertising.cpp @@ -44,7 +44,7 @@ NimBLEAdvertising::NimBLEAdvertising() { * @brief Stops the current advertising and resets the advertising data to the default values. */ void NimBLEAdvertising::reset() { - if(NimBLEDevice::getInitialized() && isAdvertising()) { + if(NimBLEDevice::isInitialized() && isAdvertising()) { stop(); } memset(&m_advData, 0, sizeof m_advData); @@ -58,6 +58,8 @@ void NimBLEAdvertising::reset() { m_advData.name_is_complete = 1; #ifndef CONFIG_IDF_TARGET_ESP32P4 m_advData.tx_pwr_lvl = NimBLEDevice::getPower(); +#else + m_advData.tx_pwr_lvl = 0; #endif m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP); @@ -641,7 +643,7 @@ bool NimBLEAdvertising::start(uint32_t duration, advCompleteCB_t advCompleteCB, } #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - rc = ble_gap_adv_start(NimBLEDevice::m_own_addr_type, + rc = ble_gap_adv_start(NimBLEDevice::m_ownAddrType, (dirAddr != nullptr) ? dirAddr->getBase() : NULL, duration, &m_advParams, @@ -649,7 +651,7 @@ bool NimBLEAdvertising::start(uint32_t duration, advCompleteCB_t advCompleteCB, NimBLEAdvertising::handleGapEvent, (void*)this); #else - rc = ble_gap_adv_start(NimBLEDevice::m_own_addr_type, + rc = ble_gap_adv_start(NimBLEDevice::m_ownAddrType, (dirAddr != nullptr) ? &peerAddr : NULL, duration, &m_advParams, @@ -1022,6 +1024,8 @@ void NimBLEAdvertisementData::addTxPower() { cdata[1] = BLE_HS_ADV_TYPE_TX_PWR_LVL; #ifndef CONFIG_IDF_TARGET_ESP32P4 cdata[2] = NimBLEDevice::getPower(); +#else + cdata[2] = 0; #endif addData(cdata, 3); } // addTxPower diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index 9d96fbd..e874040 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -226,7 +226,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes) */ do { #if CONFIG_BT_NIMBLE_EXT_ADV - rc = ble_gap_ext_connect(NimBLEDevice::m_own_addr_type, + rc = ble_gap_ext_connect(NimBLEDevice::m_ownAddrType, peerAddr, m_connectTimeout, m_phyMask, @@ -237,7 +237,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes) this); #else - rc = ble_gap_connect(NimBLEDevice::m_own_addr_type, peerAddr, + rc = ble_gap_connect(NimBLEDevice::m_ownAddrType, peerAddr, m_connectTimeout, &m_pConnParams, NimBLEClient::handleGapEvent, this); #endif @@ -1342,7 +1342,7 @@ void NimBLEClientCallbacks::onIdentity(NimBLEConnInfo& connInfo){ void NimBLEClientCallbacks::onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pin){ NIMBLE_LOGD("NimBLEClientCallbacks", "onConfirmPIN: default: true"); - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); } #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */ diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index f6d7019..1fe6fd2 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -15,34 +15,34 @@ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) -#include "NimBLEDevice.h" -#include "NimBLEUtils.h" +# include "NimBLEDevice.h" +# include "NimBLEUtils.h" -#ifdef ESP_PLATFORM +# ifdef ESP_PLATFORM # include "esp_err.h" -#ifndef CONFIG_IDF_TARGET_ESP32P4 -# include "esp_bt.h" -#endif +# ifndef CONFIG_IDF_TARGET_ESP32P4 +# include "esp_bt.h" +# endif # include "nvs_flash.h" # if defined(CONFIG_NIMBLE_CPP_IDF) -# if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) || CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE) -# include "esp_nimble_hci.h" -# endif -# include "nimble/nimble_port.h" -# include "nimble/nimble_port_freertos.h" -# include "host/ble_hs.h" -# include "host/ble_hs_pvcy.h" -# include "host/util/util.h" -# include "services/gap/ble_svc_gap.h" -# include "services/gatt/ble_svc_gatt.h" +# if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) || CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE) +# include "esp_nimble_hci.h" +# endif +# include "nimble/nimble_port.h" +# include "nimble/nimble_port_freertos.h" +# include "host/ble_hs.h" +# include "host/ble_hs_pvcy.h" +# include "host/util/util.h" +# include "services/gap/ble_svc_gap.h" +# include "services/gatt/ble_svc_gatt.h" # else -# include "nimble/esp_port/esp-hci/include/esp_nimble_hci.h" +# include "nimble/esp_port/esp-hci/include/esp_nimble_hci.h" # endif -#else +# else # include "nimble/nimble/controller/include/controller/ble_phy.h" -#endif +# endif -#ifndef CONFIG_NIMBLE_CPP_IDF +# ifndef CONFIG_NIMBLE_CPP_IDF # include "nimble/porting/nimble/include/nimble/nimble_port.h" # include "nimble/porting/npl/freertos/include/nimble/nimble_port_freertos.h" # include "nimble/nimble/host/include/host/ble_hs.h" @@ -50,64 +50,75 @@ # include "nimble/nimble/host/util/include/host/util/util.h" # include "nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h" # include "nimble/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h" -#endif +# endif -#if defined(ESP_PLATFORM) && defined(CONFIG_ENABLE_ARDUINO_DEPENDS) +# if defined(ESP_PLATFORM) && defined(CONFIG_ENABLE_ARDUINO_DEPENDS) # include "esp32-hal-bt.h" -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) -#include "NimBLEClient.h" -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# include "NimBLEClient.h" +# endif -#include "NimBLELog.h" -#include +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +# include "NimBLEServer.h" +# endif + +# include "NimBLELog.h" static const char* LOG_TAG = "NimBLEDevice"; +extern "C" void ble_store_config_init(void); + /** * Singletons for the NimBLEDevice. */ -static bool initialized = false; -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) -NimBLEScan* NimBLEDevice::m_pScan = nullptr; -#endif -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -NimBLEServer* NimBLEDevice::m_pServer = nullptr; -#endif -uint32_t NimBLEDevice::m_passkey = 123456; -bool NimBLEDevice::m_synced = false; -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +NimBLEScan* NimBLEDevice::m_pScan = nullptr; +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +NimBLEServer* NimBLEDevice::m_pServer = nullptr; +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) # if CONFIG_BT_NIMBLE_EXT_ADV NimBLEExtAdvertising* NimBLEDevice::m_bleAdvertising = nullptr; # else NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr; # endif -#endif +# endif -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) std::array NimBLEDevice::m_pClients{nullptr}; -#endif +# endif -gap_event_handler NimBLEDevice::m_customGapHandler = nullptr; -ble_gap_event_listener NimBLEDevice::m_listener; -std::vector NimBLEDevice::m_ignoreList; -std::vector NimBLEDevice::m_whiteList; -uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC; -#ifdef ESP_PLATFORM +bool NimBLEDevice::m_initialized{false}; +uint32_t NimBLEDevice::m_passkey{123456}; +bool NimBLEDevice::m_synced{false}; +ble_gap_event_listener NimBLEDevice::m_listener{}; +std::vector NimBLEDevice::m_ignoreList{}; +std::vector NimBLEDevice::m_whiteList{}; +uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC}; + +# ifdef ESP_PLATFORM # ifdef CONFIG_BTDM_BLE_SCAN_DUPL -uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE; -uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DUPL_TYPE; +uint16_t NimBLEDevice::m_scanDuplicateSize{CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE}; +uint8_t NimBLEDevice::m_scanFilterMode{CONFIG_BTDM_SCAN_DUPL_TYPE}; # endif -#endif +# endif +/* -------------------------------------------------------------------------- */ +/* SERVER FUNCTIONS */ +/* -------------------------------------------------------------------------- */ + +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) /** - * @brief Create a new instance of a server. - * @return A new instance of the server. + * @brief Create an instance of a server. + * @return A pointer to the instance of the server. */ -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -/* STATIC */ NimBLEServer* NimBLEDevice::createServer() { - if(NimBLEDevice::m_pServer == nullptr) { +NimBLEServer* NimBLEDevice::createServer() { + if (NimBLEDevice::m_pServer == nullptr) { NimBLEDevice::m_pServer = new NimBLEServer(); ble_gatts_reset(); ble_svc_gap_init(); @@ -117,54 +128,52 @@ uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DU return m_pServer; } // createServer - /** * @brief Get the instance of the server. - * @return A pointer to the server instance. + * @return A pointer to the server instance or nullptr if none have been created. */ -/* STATIC */ NimBLEServer* NimBLEDevice::getServer() { +NimBLEServer* NimBLEDevice::getServer() { return m_pServer; } // getServer -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +# endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +/* -------------------------------------------------------------------------- */ +/* ADVERTISING FUNCTIONS */ +/* -------------------------------------------------------------------------- */ -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) # if CONFIG_BT_NIMBLE_EXT_ADV /** - * @brief Get the instance of the advertising object. - * @return A pointer to the advertising object. + * @brief Get the instance of the extended advertising object. + * @return A pointer to the extended advertising object. */ NimBLEExtAdvertising* NimBLEDevice::getAdvertising() { - if(m_bleAdvertising == nullptr) { + if (m_bleAdvertising == nullptr) { m_bleAdvertising = new NimBLEExtAdvertising(); } + return m_bleAdvertising; } - /** * @brief Convenience function to begin advertising. - * @param [in] inst_id The extended advertisement instance ID to start. + * @param [in] instId The extended advertisement instance ID to start. * @param [in] duration How long to advertise for in milliseconds, 0 = forever (default). - * @param [in] max_events Maximum number of advertisement events to send, 0 = no limit (default). + * @param [in] maxEvents Maximum number of advertisement events to send, 0 = no limit (default). * @return True if advertising started successfully. */ -bool NimBLEDevice::startAdvertising(uint8_t inst_id, - int duration, - int max_events) { - return getAdvertising()->start(inst_id, duration, max_events); +bool NimBLEDevice::startAdvertising(uint8_t instId, int duration, int maxEvents) { + return getAdvertising()->start(instId, duration, maxEvents); } // startAdvertising - /** * @brief Convenience function to stop advertising a data set. - * @param [in] inst_id The extended advertisement instance ID to stop advertising. + * @param [in] instId The extended advertisement instance ID to stop advertising. * @return True if advertising stopped successfully. */ -bool NimBLEDevice::stopAdvertising(uint8_t inst_id) { - return getAdvertising()->stop(inst_id); +bool NimBLEDevice::stopAdvertising(uint8_t instId) { + return getAdvertising()->stop(instId); } // stopAdvertising - # endif # if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) @@ -173,13 +182,12 @@ bool NimBLEDevice::stopAdvertising(uint8_t inst_id) { * @return A pointer to the advertising object. */ NimBLEAdvertising* NimBLEDevice::getAdvertising() { - if(m_bleAdvertising == nullptr) { + if (m_bleAdvertising == nullptr) { m_bleAdvertising = new NimBLEAdvertising(); } return m_bleAdvertising; } - /** * @brief Convenience function to begin advertising. * @param [in] duration The duration in milliseconds to advertise for, default = forever. @@ -197,88 +205,144 @@ bool NimBLEDevice::startAdvertising(uint32_t duration) { bool NimBLEDevice::stopAdvertising() { return getAdvertising()->stop(); } // stopAdvertising -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +/* -------------------------------------------------------------------------- */ +/* SCAN FUNCTIONS */ +/* -------------------------------------------------------------------------- */ /** * @brief Retrieve the Scan object that we use for scanning. * @return The scanning object reference. This is a singleton object. The caller should not * try and release/delete it. */ -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) -/* STATIC */ +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) NimBLEScan* NimBLEDevice::getScan() { if (m_pScan == nullptr) { m_pScan = new NimBLEScan(); } + return m_pScan; } // getScan -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - +# ifdef ESP_PLATFORM +# ifdef CONFIG_BTDM_BLE_SCAN_DUPL /** - * @brief Creates a new client object and maintains a list of all client objects - * each client can connect to 1 peripheral device. - * @param [in] peerAddress An optional peer address that is copied to the new client - * object, allows for calling NimBLEClient::connect(bool) without a device or address parameter. - * @return A reference to the new client object, or nullptr on error. + * @brief Set the duplicate filter cache size for filtering scanned devices. + * @param [in] size The number of advertisements filtered before the cache is reset.\n + * Range is 10-1000, a larger value will reduce how often the same devices are reported. + * @details Must only be called before calling NimBLEDevice::init. */ -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) -/* STATIC */ -NimBLEClient* NimBLEDevice::createClient(NimBLEAddress peerAddress) { - if (getCreatedClientCount() == NIMBLE_MAX_CONNECTIONS) { - NIMBLE_LOGE(LOG_TAG,"Unable to create client; already at max: %d",NIMBLE_MAX_CONNECTIONS); - return nullptr; - } - - NimBLEClient* pClient = new NimBLEClient(peerAddress); - for (auto& clt : m_pClients) { - if (clt == nullptr) { - clt = pClient; - break; +void NimBLEDevice::setScanDuplicateCacheSize(uint16_t size) { + if (m_initialized) { + NIMBLE_LOGE(LOG_TAG, "Cannot change scan cache size while initialized"); + return; + } else { + if (size > 1000) { + size = 1000; + } else if (size < 10) { + size = 10; } } - return pClient; + NIMBLE_LOGD(LOG_TAG, "Set duplicate cache size to: %u", size); + m_scanDuplicateSize = size; +} + +/** + * @brief Set the duplicate filter mode for filtering scanned devices. + * @param [in] mode One of three possible options: + * * CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE (0) (default)\n + Filter by device address only, advertisements from the same address will be reported only once. + * * CONFIG_BTDM_SCAN_DUPL_TYPE_DATA (1)\n + Filter by data only, advertisements with the same data will only be reported once,\n + even from different addresses. + * * CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE (2)\n + Filter by address and data, advertisements from the same address will be reported only once,\n + except if the data in the advertisement has changed, then it will be reported again. + * @details Must only be called before calling NimBLEDevice::init. + */ +void NimBLEDevice::setScanFilterMode(uint8_t mode) { + if (m_initialized) { + NIMBLE_LOGE(LOG_TAG, "Cannot change scan duplicate type while initialized"); + return; + } else if (mode > 2) { + NIMBLE_LOGE(LOG_TAG, "Invalid scan duplicate type"); + return; + } + + m_scanFilterMode = mode; +} +# endif // CONFIG_BTDM_BLE_SCAN_DUPL +# endif // ESP_PLATFORM +# endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +/* -------------------------------------------------------------------------- */ +/* CLIENT FUNCTIONS */ +/* -------------------------------------------------------------------------- */ + +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +/** + * @brief Creates a new client object, each client can connect to 1 peripheral device. + * @return A pointer to the new client object, or nullptr on error. + */ +NimBLEClient* NimBLEDevice::createClient() { + return createClient(NimBLEAddress{}); } // createClient +/** + * @brief Creates a new client object, each client can connect to 1 peripheral device. + * @param [in] peerAddress A peer address reference that is copied to the new client + * object, allows for calling NimBLEClient::connect(bool) without a device or address parameter. + * @return A pointer to the new client object, or nullptr on error. + */ +NimBLEClient* NimBLEDevice::createClient(const NimBLEAddress& peerAddress) { + for (auto& clt : m_pClients) { + if (clt == nullptr) { + clt = new NimBLEClient(peerAddress); + return clt; + } + } + + NIMBLE_LOGE(LOG_TAG, "Unable to create client; already at max: %d", NIMBLE_MAX_CONNECTIONS); + return nullptr; +} // createClient /** * @brief Delete the client object and remove it from the list.\n * Checks if it is connected or trying to connect and disconnects/stops it first. * @param [in] pClient A pointer to the client object. */ -/* STATIC */ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) { - if(pClient == nullptr) { + if (pClient == nullptr) { return false; } // Set the connection established flag to false to stop notifications // from accessing the attribute vectors while they are being deleted. pClient->m_connEstablished = false; - int rc =0; + int rc = 0; - if(pClient->isConnected()) { + if (pClient->isConnected()) { rc = pClient->disconnect(); if (rc != 0 && rc != BLE_HS_EALREADY && rc != BLE_HS_ENOTCONN) { return false; } - while(pClient->isConnected()) { - taskYIELD(); + while (pClient->isConnected()) { + ble_npl_time_delay(1); } // Since we set the flag to false the app will not get a callback // in the disconnect event so we call it here for good measure. pClient->m_pClientCallbacks->onDisconnect(pClient, BLE_ERR_CONN_TERM_LOCAL); - - } else if(pClient->m_pTaskData != nullptr) { + } else if (pClient->m_pTaskData != nullptr) { rc = ble_gap_conn_cancel(); if (rc != 0 && rc != BLE_HS_EALREADY) { return false; } - while(pClient->m_pTaskData != nullptr) { - taskYIELD(); + + while (pClient->m_pTaskData != nullptr) { + ble_npl_time_delay(1); } } @@ -292,15 +356,13 @@ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) { return true; } // deleteClient - /** * @brief Get the number of created client objects. * @return Number of client objects created. */ -/* STATIC */ size_t NimBLEDevice::getCreatedClientCount() { - auto count = 0; - for (auto clt : m_pClients) { + size_t count = 0; + for (const auto clt : m_pClients) { if (clt != nullptr) { count++; } @@ -309,33 +371,29 @@ size_t NimBLEDevice::getCreatedClientCount() { return count; } // getCreatedClientCount - /** - * @brief Get a reference to a client by connection ID. - * @param [in] conn_id The client connection ID to search for. - * @return A pointer to the client object with the specified connection ID or nullptr. + * @brief Get a reference to a client by connection handle. + * @param [in] connHandle The client connection handle to search for. + * @return A pointer to the client object with the specified connection handle or nullptr. */ -/* STATIC */ -NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) { - for(auto clt : m_pClients) { - if(clt != nullptr && clt->getConnId() == conn_id) { +NimBLEClient* NimBLEDevice::getClientByHandle(uint16_t connHandle) { + for (const auto clt : m_pClients) { + if (clt != nullptr && clt->getConnId() == connHandle) { return clt; } } return nullptr; -} // getClientByID - +} // getClientByHandle /** * @brief Get a reference to a client by peer address. - * @param [in] peer_addr The address of the peer to search for. + * @param [in] addr The address of the peer to search for. * @return A pointer to the client object with the peer address or nullptr. */ -/* STATIC */ -NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) { - for(auto clt : m_pClients) { - if(clt != nullptr && clt->getPeerAddress() == peer_addr) { +NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress& addr) { + for (const auto clt : m_pClients) { + if (clt != nullptr && clt->getPeerAddress() == addr) { return clt; } } @@ -343,15 +401,13 @@ NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_add return nullptr; } // getClientPeerAddress - /** * @brief Finds the first disconnected client in the list. * @return A pointer to the first client object that is not connected to a peer or nullptr. */ -/* STATIC */ NimBLEClient* NimBLEDevice::getDisconnectedClient() { - for(auto clt : m_pClients) { - if(clt != nullptr && !clt->isConnected()) { + for (const auto clt : m_pClients) { + if (clt != nullptr && !clt->isConnected()) { return clt; } } @@ -359,68 +415,74 @@ NimBLEClient* NimBLEDevice::getDisconnectedClient() { return nullptr; } // getDisconnectedClient -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +/* -------------------------------------------------------------------------- */ +/* TRANSMIT POWER */ +/* -------------------------------------------------------------------------- */ -#ifdef ESP_PLATFORM -#ifndef CONFIG_IDF_TARGET_ESP32P4 /** * @brief Set the transmission power. - * @param [in] powerLevel The power level to set, can be one of: - * * ESP_PWR_LVL_N12 = 0, Corresponding to -12dbm - * * ESP_PWR_LVL_N9 = 1, Corresponding to -9dbm - * * ESP_PWR_LVL_N6 = 2, Corresponding to -6dbm - * * ESP_PWR_LVL_N3 = 3, Corresponding to -3dbm - * * ESP_PWR_LVL_N0 = 4, Corresponding to 0dbm - * * ESP_PWR_LVL_P3 = 5, Corresponding to +3dbm - * * ESP_PWR_LVL_P6 = 6, Corresponding to +6dbm - * * ESP_PWR_LVL_P9 = 7, Corresponding to +9dbm - * @param [in] powerType The BLE function to set the power level for, can be one of: - * * ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, For connection handle 0 - * * ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, For connection handle 1 - * * ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, For connection handle 2 - * * ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, For connection handle 3 - * * ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, For connection handle 4 - * * ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, For connection handle 5 - * * ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, For connection handle 6 - * * ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, For connection handle 7 - * * ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, For connection handle 8 - * * ESP_BLE_PWR_TYPE_ADV = 9, For advertising - * * ESP_BLE_PWR_TYPE_SCAN = 10, For scan - * * ESP_BLE_PWR_TYPE_DEFAULT = 11, For default, if not set other, it will use default value + * @param [in] dbm The power level to set in dBm. + * @return True if the power level was set successfully. */ -/* STATIC */ -void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) { - NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType); +bool NimBLEDevice::setPower(int8_t dbm) { + NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", dbm); +# ifdef ESP_PLATFORM +# ifndef CONFIG_IDF_TARGET_ESP32P4 + if (dbm >= 9) { + dbm = ESP_PWR_LVL_P9; + } else if (dbm >= 6) { + dbm = ESP_PWR_LVL_P6; + } else if (dbm >= 3) { + dbm = ESP_PWR_LVL_P3; + } else if (dbm >= 0) { + dbm = ESP_PWR_LVL_N0; + } else if (dbm >= -3) { + dbm = ESP_PWR_LVL_N3; + } else if (dbm >= -6) { + dbm = ESP_PWR_LVL_N6; + } else if (dbm >= -9) { + dbm = ESP_PWR_LVL_N9; + } else if (dbm >= -12) { + dbm = ESP_PWR_LVL_N12; + } else { + NIMBLE_LOGE(LOG_TAG, "Unsupported power level"); + return false; + } - esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel); + esp_err_t errRc = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, (esp_power_level_t)dbm); if (errRc != ESP_OK) { NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc); } - NIMBLE_LOGD(LOG_TAG, "<< setPower"); -} // setPower + return errRc == ESP_OK; +# else + return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 +# endif +# else + ble_hci_vs_set_tx_pwr_cp cmd{dbm}; + ble_hci_vs_set_tx_pwr_rp rsp{0}; + int rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + if (rc) { + NIMBLE_LOGE(LOG_TAG, "failed to set TX power, rc: %04x\n", rc); + return false; + } + + NIMBLE_LOGD(LOG_TAG, "TX power set to %d dBm\n", rsp.tx_power); + return true; +# endif +} // setPower /** * @brief Get the transmission power. - * @param [in] powerType The power level to set, can be one of: - * * ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, For connection handle 0 - * * ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, For connection handle 1 - * * ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, For connection handle 2 - * * ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, For connection handle 3 - * * ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, For connection handle 4 - * * ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, For connection handle 5 - * * ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, For connection handle 6 - * * ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, For connection handle 7 - * * ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, For connection handle 8 - * * ESP_BLE_PWR_TYPE_ADV = 9, For advertising - * * ESP_BLE_PWR_TYPE_SCAN = 10, For scan - * * ESP_BLE_PWR_TYPE_DEFAULT = 11, For default, if not set other, it will use default value - * @return the power level currently used by the type specified. + * @return The power level currently used in dbm. */ -/* STATIC */ -int NimBLEDevice::getPower(esp_ble_power_type_t powerType) { - switch(esp_ble_tx_power_get(powerType)) { +int NimBLEDevice::getPower() { +# ifdef ESP_PLATFORM +# ifndef CONFIG_IDF_TARGET_ESP32P4 + switch (esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT)) { case ESP_PWR_LVL_N12: return -12; case ESP_PWR_LVL_N9: @@ -438,155 +500,67 @@ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) { case ESP_PWR_LVL_P9: return 9; default: - return BLE_HS_ADV_TX_PWR_LVL_AUTO; + return 0xFF; } -} // getPower -#endif -#else +# else + return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get +# endif -void NimBLEDevice::setPower(int dbm) { - ble_phy_txpwr_set(dbm); -} - - -int NimBLEDevice::getPower() { +# else return ble_phy_txpwr_get(); -} -#endif - -/** - * @brief Get our device address. - * @return A NimBLEAddress object of our public address if we have one, - * if not then our current random address. - */ -/* STATIC*/ -NimBLEAddress NimBLEDevice::getAddress() { - ble_addr_t addr{}; - - if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) { - NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); - addr.type = BLE_ADDR_RANDOM; - ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); - } - - return NimBLEAddress(addr); -} // getAddress - - -/** - * @brief Return a string representation of the address of this device. - * @return A string representation of this device address. - */ -/* STATIC */ -std::string NimBLEDevice::toString() { - return getAddress().toString(); -} // toString +# endif +} // getPower +/* -------------------------------------------------------------------------- */ +/* MTU FUNCTIONS */ +/* -------------------------------------------------------------------------- */ /** * @brief Setup local mtu that will be used to negotiate mtu during request from client peer. * @param [in] mtu Value to set local mtu: * * This should be larger than 23 and lower or equal to BLE_ATT_MTU_MAX = 527. + * @return True if the mtu was set successfully. */ -/* STATIC */ -int NimBLEDevice::setMTU(uint16_t mtu) { - NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu); - - int rc = ble_att_set_preferred_mtu(mtu); - +bool NimBLEDevice::setMTU(uint16_t mtu) { + int rc = ble_att_set_preferred_mtu(mtu); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d", mtu); + NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d, rc: %d", mtu, rc); } - NIMBLE_LOGD(LOG_TAG, "<< setLocalMTU"); - return rc; + return rc == 0; } // setMTU - /** * @brief Get local MTU value set. * @return The current preferred MTU setting. */ -/* STATIC */ uint16_t NimBLEDevice::getMTU() { return ble_att_preferred_mtu(); } +/* -------------------------------------------------------------------------- */ +/* BOND MANAGEMENT */ +/* -------------------------------------------------------------------------- */ -#ifdef ESP_PLATFORM -# ifdef CONFIG_BTDM_BLE_SCAN_DUPL -/** - * @brief Set the duplicate filter cache size for filtering scanned devices. - * @param [in] cacheSize The number of advertisements filtered before the cache is reset.\n - * Range is 10-1000, a larger value will reduce how often the same devices are reported. - * @details Must only be called before calling NimBLEDevice::init. - */ -/*STATIC*/ -void NimBLEDevice::setScanDuplicateCacheSize(uint16_t cacheSize) { - if(initialized) { - NIMBLE_LOGE(LOG_TAG, "Cannot change scan cache size while initialized"); - return; - } else if(cacheSize > 1000 || cacheSize <10) { - NIMBLE_LOGE(LOG_TAG, "Invalid scan cache size; min=10 max=1000"); - return; - } - - m_scanDuplicateSize = cacheSize; -} - - - -/** - * @brief Set the duplicate filter mode for filtering scanned devices. - * @param [in] mode One of three possible options: - * * CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE (0) (default)\n - Filter by device address only, advertisements from the same address will be reported only once. - * * CONFIG_BTDM_SCAN_DUPL_TYPE_DATA (1)\n - Filter by data only, advertisements with the same data will only be reported once,\n - even from different addresses. - * * CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE (2)\n - Filter by address and data, advertisements from the same address will be reported only once,\n - except if the data in the advertisement has changed, then it will be reported again. - * @details Must only be called before calling NimBLEDevice::init. - */ -/*STATIC*/ -void NimBLEDevice::setScanFilterMode(uint8_t mode) { - if(initialized) { - NIMBLE_LOGE(LOG_TAG, "Cannot change scan duplicate type while initialized"); - return; - } else if(mode > 2) { - NIMBLE_LOGE(LOG_TAG, "Invalid scan duplicate type"); - return; - } - - m_scanFilterMode = mode; -} -# endif // CONFIG_BTDM_BLE_SCAN_DUPL -#endif // ESP_PLATFORM - -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) /** * @brief Gets the number of bonded peers stored */ -/*STATIC*/ int NimBLEDevice::getNumBonds() { ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_peers, rc; - + int num_peers, rc; rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); - if (rc !=0) { + if (rc != 0) { return 0; } return num_peers; } - /** * @brief Deletes all bonding information. - * @returns true on success, false on failure. + * @returns True on success. */ -/*STATIC*/ bool NimBLEDevice::deleteAllBonds() { int rc = ble_store_clear(); if (rc != 0) { @@ -596,27 +570,23 @@ bool NimBLEDevice::deleteAllBonds() { return true; } - /** * @brief Deletes a peer bond. * @param [in] address The address of the peer with which to delete bond info. - * @returns true on success. + * @returns True on success. */ -/*STATIC*/ -bool NimBLEDevice::deleteBond(const NimBLEAddress &address) { +bool NimBLEDevice::deleteBond(const NimBLEAddress& address) { return ble_gap_unpair(address.getBase()) == 0; } - /** * @brief Checks if a peer device is bonded. * @param [in] address The address to check for bonding. - * @returns true if bonded. + * @returns True if bonded. */ -/*STATIC*/ -bool NimBLEDevice::isBonded(const NimBLEAddress &address) { +bool NimBLEDevice::isBonded(const NimBLEAddress& address) { ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_peers, rc; + int num_peers, rc; rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); if (rc != 0) { @@ -625,7 +595,7 @@ bool NimBLEDevice::isBonded(const NimBLEAddress &address) { for (int i = 0; i < num_peers; i++) { NimBLEAddress storedAddr(peer_id_addrs[i]); - if(storedAddr == address) { + if (storedAddr == address) { return true; } } @@ -633,17 +603,14 @@ bool NimBLEDevice::isBonded(const NimBLEAddress &address) { return false; } - /** * @brief Get the address of a bonded peer device by index. * @param [in] index The index to retrieve the peer address of. * @returns NimBLEAddress of the found bonded peer or nullptr if not found. */ -/*STATIC*/ NimBLEAddress NimBLEDevice::getBondedAddress(int index) { ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_peers, rc; - + int num_peers, rc; rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); if (rc != 0) { return nullptr; @@ -655,17 +622,20 @@ NimBLEAddress NimBLEDevice::getBondedAddress(int index) { return NimBLEAddress(peer_id_addrs[index]); } -#endif +# endif + +/* -------------------------------------------------------------------------- */ +/* WHITELIST */ +/* -------------------------------------------------------------------------- */ /** * @brief Checks if a peer device is whitelisted. * @param [in] address The address to check for in the whitelist. - * @returns true if the address is in the whitelist. + * @returns True if the address is in the whitelist. */ -/*STATIC*/ -bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) { - for (auto &it : m_whiteList) { - if (it == address) { +bool NimBLEDevice::onWhiteList(const NimBLEAddress& address) { + for (const auto& addr : m_whiteList) { + if (addr == address) { return true; } } @@ -673,14 +643,12 @@ bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) { return false; } - /** * @brief Add a peer address to the whitelist. * @param [in] address The address to add to the whitelist. - * @returns true if successful. + * @returns True if successful. */ -/*STATIC*/ -bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) { +bool NimBLEDevice::whiteListAdd(const NimBLEAddress& address) { if (!NimBLEDevice::onWhiteList(address)) { m_whiteList.push_back(address); int rc = ble_gap_wl_set(reinterpret_cast(&m_whiteList[0]), m_whiteList.size()); @@ -694,300 +662,351 @@ bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) { return true; } - /** * @brief Remove a peer address from the whitelist. * @param [in] address The address to remove from the whitelist. - * @returns true if successful. + * @returns True if successful. */ -/*STATIC*/ -bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) { - auto it = std::find(m_whiteList.begin(), m_whiteList.end(), address); - if (it != m_whiteList.end()) { - m_whiteList.erase(it); - int rc = ble_gap_wl_set(reinterpret_cast(&m_whiteList[0]), m_whiteList.size()); - if (rc != 0) { - m_whiteList.push_back(address); - NIMBLE_LOGE(LOG_TAG, "Failed removing from whitelist rc=%d", rc); - return false; +bool NimBLEDevice::whiteListRemove(const NimBLEAddress& address) { + for (auto it = m_whiteList.begin(); it < m_whiteList.end(); ++it) { + if (*it == address) { + m_whiteList.erase(it); + int rc = ble_gap_wl_set(reinterpret_cast(&m_whiteList[0]), m_whiteList.size()); + if (rc != 0) { + m_whiteList.push_back(address); + NIMBLE_LOGE(LOG_TAG, "Failed removing from whitelist rc=%d", rc); + return false; + } + + std::vector(m_whiteList).swap(m_whiteList); } } return true; } - /** * @brief Gets the count of addresses in the whitelist. * @returns The number of addresses in the whitelist. */ -/*STATIC*/ size_t NimBLEDevice::getWhiteListCount() { return m_whiteList.size(); } - /** * @brief Gets the address at the vector index. * @param [in] index The vector index to retrieve the address from. - * @returns the NimBLEAddress at the whitelist index or nullptr if not found. + * @returns The NimBLEAddress at the whitelist index or nullptr if not found. */ -/*STATIC*/ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) { if (index > m_whiteList.size()) { NIMBLE_LOGE(LOG_TAG, "Invalid index; %u", index); return nullptr; } + return m_whiteList[index]; } +/* -------------------------------------------------------------------------- */ +/* STACK FUNCTIONS */ +/* -------------------------------------------------------------------------- */ /** - * @brief Host reset, we pass the message so we don't make calls until resynced. + * @brief Host reset, we pass the message so we don't make calls until re-synced. * @param [in] reason The reason code for the reset. */ -/* STATIC */ -void NimBLEDevice::onReset(int reason) -{ - if(!m_synced) { +void NimBLEDevice::onReset(int reason) { + if (!m_synced) { return; } m_synced = false; - NIMBLE_LOGE(LOG_TAG, "Resetting state; reason=%d, %s", reason, - NimBLEUtils::returnCodeToString(reason)); + NIMBLE_LOGE(LOG_TAG, "Resetting state; reason=%d, %s", reason, NimBLEUtils::returnCodeToString(reason)); -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - if(initialized) { - if(m_pScan != nullptr) { +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if (m_initialized) { + if (m_pScan != nullptr) { m_pScan->onHostReset(); } } -#endif +# endif } // onReset - /** - * @brief Host resynced with controller, all clear to make calls to the stack. + * @brief Host synced with controller, all clear to make calls to the stack. */ -/* STATIC */ -void NimBLEDevice::onSync(void) -{ +void NimBLEDevice::onSync(void) { NIMBLE_LOGI(LOG_TAG, "NimBle host synced."); // This check is needed due to potentially being called multiple times in succession // If this happens, the call to scan start may get stuck or cause an advertising fault. - if(m_synced) { + if (m_synced) { return; } - /* Make sure we have proper identity address set (public preferred) */ + // Get the public and random address for the device. int rc = ble_hs_util_ensure_addr(0); + if (rc == 0) { + rc = ble_hs_util_ensure_addr(1); + } + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "error ensuring address; rc=%d", rc); return; } -#ifndef ESP_PLATFORM - rc = ble_hs_id_infer_auto(m_own_addr_type, &m_own_addr_type); + // start with using the public address if available, if not then use random. + rc = ble_hs_id_copy_addr(BLE_OWN_ADDR_PUBLIC, NULL, NULL); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "error determining address type; rc=%d", rc); - return; + m_ownAddrType = BLE_OWN_ADDR_RANDOM; } -#endif - // Yield for housekeeping before returning to operations. + // Yield for housekeeping tasks before returning to operations. // Occasionally triggers exception without. - taskYIELD(); + ble_npl_time_delay(1); m_synced = true; - if(initialized) { -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - if(m_pScan != nullptr) { + if (m_initialized) { +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if (m_pScan != nullptr) { m_pScan->onHostSync(); } -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) - if(m_bleAdvertising != nullptr) { +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if (m_bleAdvertising != nullptr) { m_bleAdvertising->onHostSync(); } -#endif +# endif } } // onSync - /** * @brief The main host task. */ -/* STATIC */ -void NimBLEDevice::host_task(void *param) -{ +void NimBLEDevice::host_task(void* param) { NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started"); - - /* This function will return only when nimble_port_stop() is executed */ - nimble_port_run(); - + nimble_port_run(); // This function will return only when nimble_port_stop() is executed nimble_port_freertos_deinit(); } // host_task - /** - * @brief Initialize the %BLE environment. + * @brief Initialize the BLE environment. * @param [in] deviceName The device name of the device. */ -/* STATIC */ -void NimBLEDevice::init(const std::string &deviceName) { - if(!initialized){ - int rc=0; -#ifdef ESP_PLATFORM - esp_err_t errRc = ESP_OK; +bool NimBLEDevice::init(const std::string& deviceName) { + if (!m_initialized) { +# ifdef ESP_PLATFORM -#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS +# ifdef CONFIG_ENABLE_ARDUINO_DEPENDS // make sure the linker includes esp32-hal-bt.c so Arduino init doesn't release BLE memory. btStarted(); -#endif +# endif - errRc = nvs_flash_init(); - - if (errRc == ESP_ERR_NVS_NO_FREE_PAGES || errRc == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - errRc = nvs_flash_init(); + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + err = nvs_flash_erase(); + if (err == ESP_OK) { + err = nvs_flash_init(); + } } - ESP_ERROR_CHECK(errRc); + if (err != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "nvs_flash_init() failed; err=%d", err); + return false; + } -#if CONFIG_IDF_TARGET_ESP32 +# if CONFIG_IDF_TARGET_ESP32 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); -#endif +# endif -#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) | !defined(CONFIG_NIMBLE_CPP_IDF) +# if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) | !defined(CONFIG_NIMBLE_CPP_IDF) esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); -# if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +# if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE; -# else - bt_cfg.mode = ESP_BT_MODE_BLE; +# else + bt_cfg.mode = ESP_BT_MODE_BLE; bt_cfg.ble_max_conn = CONFIG_BT_NIMBLE_MAX_CONNECTIONS; -# endif +# endif -# ifdef CONFIG_BTDM_BLE_SCAN_DUPL - bt_cfg.normal_adv_size = m_scanDuplicateSize; +# ifdef CONFIG_BTDM_BLE_SCAN_DUPL + bt_cfg.normal_adv_size = m_scanDuplicateSize; bt_cfg.scan_duplicate_type = m_scanFilterMode; +# endif + err = esp_bt_controller_init(&bt_cfg); + if (err != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_bt_controller_init() failed; err=%d", err); + return false; + } + + err = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (err != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_bt_controller_enable() failed; err=%d", err); + return false; + } + + err = esp_nimble_hci_init(); + if (err != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_init() failed; err=%d", err); + return false; + } # endif - ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg)); - ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE)); - ESP_ERROR_CHECK(esp_nimble_hci_init()); -# endif -#endif +# endif nimble_port_init(); // Setup callbacks for host events ble_hs_cfg.reset_cb = NimBLEDevice::onReset; - ble_hs_cfg.sync_cb = NimBLEDevice::onSync; + ble_hs_cfg.sync_cb = NimBLEDevice::onSync; // Set initial security capabilities - ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT; - ble_hs_cfg.sm_bonding = 0; - ble_hs_cfg.sm_mitm = 0; - ble_hs_cfg.sm_sc = 1; - ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT; + ble_hs_cfg.sm_bonding = 0; + ble_hs_cfg.sm_mitm = 0; + ble_hs_cfg.sm_sc = 1; + ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/ - ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/ - - // Set the device name. - rc = ble_svc_gap_device_name_set(deviceName.c_str()); - if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_svc_gap_device_name_set() failed; rc=%d", rc); - } - + setDeviceName(deviceName); ble_store_config_init(); - nimble_port_freertos_init(NimBLEDevice::host_task); } // Wait for host and controller to sync before returning and accepting new tasks - while(!m_synced){ - taskYIELD(); + while (!m_synced) { + ble_npl_time_delay(1); } - initialized = true; // Set the initialization flag to ensure we are only initialized once. + m_initialized = true; // Set the initialization flag to ensure we are only initialized once. + return true; } // init - /** * @brief Shutdown the NimBLE stack/controller. - * @param [in] clearAll If true, deletes all server/advertising/scan/client objects after deinitializing. - * @note If clearAll is true when called, any references to the created objects become invalid. + * @param [in] clearAll If true, deletes all server/advertising/scan/client objects after de-initializing. + * @note If clearAll is true when called all objects created will be deleted and any references to the created objects become invalid. + * If clearAll is false, the objects will remain and can be used again after re-initializing the stack. + * If the stack was not already initialized, the objects created can be deleted when clearAll is true with no effect on the stack. */ -/* STATIC */ -void NimBLEDevice::deinit(bool clearAll) { - if(clearAll) { -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - if(NimBLEDevice::m_pServer != nullptr) { +bool NimBLEDevice::deinit(bool clearAll) { + int rc = 0; + if (m_initialized) { + rc = nimble_port_stop(); + if (rc == 0) { + nimble_port_deinit(); +# ifdef CONFIG_NIMBLE_CPP_IDF +# if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + rc = esp_nimble_hci_and_controller_deinit(); + if (rc != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", rc); + } +# endif +# endif + m_initialized = false; + m_synced = false; + } + } + + if (clearAll) { +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + if (NimBLEDevice::m_pServer != nullptr) { delete NimBLEDevice::m_pServer; NimBLEDevice::m_pServer = nullptr; } -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) - if(NimBLEDevice::m_bleAdvertising != nullptr) { +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if (NimBLEDevice::m_bleAdvertising != nullptr) { delete NimBLEDevice::m_bleAdvertising; NimBLEDevice::m_bleAdvertising = nullptr; } -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - if(NimBLEDevice::m_pScan != nullptr) { +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if (NimBLEDevice::m_pScan != nullptr) { delete NimBLEDevice::m_pScan; - NimBLEDevice::m_pScan= nullptr; + NimBLEDevice::m_pScan = nullptr; } -#endif +# endif -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) - for(auto clt : m_pClients) { +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + for (auto clt : m_pClients) { deleteClient(clt); } -#endif +# endif m_ignoreList.clear(); } - int ret = nimble_port_stop(); - if (ret == 0) { - nimble_port_deinit(); -#ifdef CONFIG_NIMBLE_CPP_IDF -# if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) - ret = esp_nimble_hci_and_controller_deinit(); - if (ret != ESP_OK) { - NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret); - } -# endif -#endif - initialized = false; - m_synced = false; - } + return rc == 0; } // deinit -/** - * @brief Set the BLEDevice's name - * @param [in] deviceName The device name of the device. - */ -/* STATIC */ -void NimBLEDevice::setDeviceName(const std::string &deviceName) { - ble_svc_gap_device_name_set(deviceName.c_str()); -} // setDeviceName - - /** * @brief Check if the initialization is complete. * @return true if initialized. */ -/*STATIC*/ -bool NimBLEDevice::getInitialized() { - return initialized; +bool NimBLEDevice::isInitialized() { + return m_initialized; } // getInitialized +/* -------------------------------------------------------------------------- */ +/* ADDRESS MANAGEMENT */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Get our device address. + * @return A NimBLEAddress object with the currently used address, or a NULL address if not set. + */ +NimBLEAddress NimBLEDevice::getAddress() { + ble_addr_t addr{}; + uint8_t type = m_ownAddrType & 1; // input must be random or public, odd values are random + int rc = ble_hs_id_copy_addr(type, addr.val, NULL); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "No address, rc: %d", rc); + } else { + addr.type = type; + } + + return NimBLEAddress{addr}; +} // getAddress + +/** + * @brief Sets the address type to use. + * @param [in] type Bluetooth Device address type. + * The available types are defined as: + * * 0x00: BLE_OWN_ADDR_PUBLIC - Public address; Uses the hardware static address. + * * 0x01: BLE_OWN_ADDR_RANDOM - Random static address; Uses the hardware or generated random static address. + * * 0x02: BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT - Resolvable private address, defaults to public if no RPA available. + * * 0x03: BLE_OWN_ADDR_RPA_RANDOM_DEFAULT - Resolvable private address, defaults to random static if no RPA available. + */ +bool NimBLEDevice::setOwnAddrType(uint8_t type) { + int rc = ble_hs_id_copy_addr(type & 1, NULL, NULL); // Odd values are random + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Unable to set address type %d, rc=%d", type, rc); + return false; + } + + m_ownAddrType = type; + + if (type == BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT || type == BLE_OWN_ADDR_RPA_RANDOM_DEFAULT) { +# ifdef CONFIG_IDF_TARGET_ESP32 + // esp32 controller does not support RPA so we must use the random static for calls to the stack + // the host will take care of the random private address generation/setting. + m_ownAddrType = BLE_OWN_ADDR_RANDOM; + rc = ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA); +# endif + } else { +# ifdef CONFIG_IDF_TARGET_ESP32 + rc = ble_hs_pvcy_rpa_config(NIMBLE_HOST_DISABLE_PRIVACY); +# endif + } + + return rc == 0; +} // setOwnAddrType + +/* -------------------------------------------------------------------------- */ +/* SECURITY */ +/* -------------------------------------------------------------------------- */ /** * @brief Set the authorization mode for this device. @@ -995,15 +1014,13 @@ bool NimBLEDevice::getInitialized() { * @param mitm If true we are capable of man in the middle protection, false if not. * @param sc If true we will perform secure connection pairing, false we will use legacy pairing. */ -/*STATIC*/ void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) { - NIMBLE_LOGD(LOG_TAG, "Setting bonding: %d, mitm: %d, sc: %d",bonding,mitm,sc); + NIMBLE_LOGD(LOG_TAG, "Setting bonding: %d, mitm: %d, sc: %d", bonding, mitm, sc); ble_hs_cfg.sm_bonding = bonding; - ble_hs_cfg.sm_mitm = mitm; - ble_hs_cfg.sm_sc = sc; + ble_hs_cfg.sm_mitm = mitm; + ble_hs_cfg.sm_sc = sc; } // setSecurityAuth - /** * @brief Set the authorization mode for this device. * @param auth_req A bitmap indicating what modes are supported.\n @@ -1013,14 +1030,12 @@ void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) { * * 0x08 BLE_SM_PAIR_AUTHREQ_SC * * 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. */ -/*STATIC*/ void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { - NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, - (auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0, - (auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0); + NimBLEDevice::setSecurityAuth(auth_req & BLE_SM_PAIR_AUTHREQ_BOND, + auth_req & BLE_SM_PAIR_AUTHREQ_MITM, + auth_req & BLE_SM_PAIR_AUTHREQ_SC); } // setSecurityAuth - /** * @brief Set the Input/Output capabilities of this device. * @param iocap One of the following values: @@ -1030,161 +1045,103 @@ void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { * * 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability * * 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability */ -/*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) { ble_hs_cfg.sm_io_cap = iocap; } // setSecurityIOCap - /** * @brief If we are the initiator of the security procedure this sets the keys we will distribute. - * @param init_key A bitmap indicating which keys to distribute during pairing.\n + * @param initKey A bitmap indicating which keys to distribute during pairing.\n * The available bits are defined as: * * 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key. * * 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK). * * 0x04: BLE_SM_PAIR_KEY_DIST_SIGN * * 0x08: BLE_SM_PAIR_KEY_DIST_LINK */ -/*STATIC*/ -void NimBLEDevice::setSecurityInitKey(uint8_t init_key) { - ble_hs_cfg.sm_our_key_dist = init_key; +void NimBLEDevice::setSecurityInitKey(uint8_t initKey) { + ble_hs_cfg.sm_our_key_dist = initKey; } // setsSecurityInitKey - /** * @brief Set the keys we are willing to accept during pairing. - * @param resp_key A bitmap indicating which keys to accept during pairing. + * @param respKey A bitmap indicating which keys to accept during pairing. * The available bits are defined as: * * 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key. * * 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK). * * 0x04: BLE_SM_PAIR_KEY_DIST_SIGN * * 0x08: BLE_SM_PAIR_KEY_DIST_LINK */ -/*STATIC*/ -void NimBLEDevice::setSecurityRespKey(uint8_t resp_key) { - ble_hs_cfg.sm_their_key_dist = resp_key; +void NimBLEDevice::setSecurityRespKey(uint8_t respKey) { + ble_hs_cfg.sm_their_key_dist = respKey; } // setsSecurityRespKey - /** * @brief Set the passkey the server will ask for when pairing. - * @param [in] pin The passkey to use. + * @param [in] passkey The passkey to use. */ -/*STATIC*/ -void NimBLEDevice::setSecurityPasskey(uint32_t pin) { - m_passkey = pin; +void NimBLEDevice::setSecurityPasskey(uint32_t passkey) { + m_passkey = passkey; } // setSecurityPasskey - /** * @brief Get the current passkey used for pairing. * @return The current passkey. */ -/*STATIC*/ uint32_t NimBLEDevice::getSecurityPasskey() { return m_passkey; } // getSecurityPasskey - -#ifdef ESP_PLATFORM -/** - * @brief Set the own address type. - * @param [in] own_addr_type Own Bluetooth Device address type.\n - * The available bits are defined as: - * * 0x00: BLE_OWN_ADDR_PUBLIC - * * 0x01: BLE_OWN_ADDR_RANDOM - * * 0x02: BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT - * * 0x03: BLE_OWN_ADDR_RPA_RANDOM_DEFAULT - * @param [in] useNRPA If true, and address type is random, uses a non-resolvable random address. - */ -/*STATIC*/ -void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) { - m_own_addr_type = own_addr_type; - switch (own_addr_type) { -#ifdef CONFIG_IDF_TARGET_ESP32 - case BLE_OWN_ADDR_PUBLIC: - ble_hs_pvcy_rpa_config(NIMBLE_HOST_DISABLE_PRIVACY); - break; -#endif - case BLE_OWN_ADDR_RANDOM: - setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); -#ifdef CONFIG_IDF_TARGET_ESP32 - ble_hs_pvcy_rpa_config(useNRPA ? NIMBLE_HOST_ENABLE_NRPA : NIMBLE_HOST_ENABLE_RPA); -#endif - break; - case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT: - case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT: - setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID); -#ifdef CONFIG_IDF_TARGET_ESP32 - ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA); -#endif - break; - } -} // setOwnAddrType -#endif - /** * @brief Start the connection securing and authorization for this connection. - * @param conn_id The connection id of the peer device. + * @param connHandle The connection handle of the peer device. * @returns NimBLE stack return code, 0 = success. */ -/* STATIC */ -int NimBLEDevice::startSecurity(uint16_t conn_id) { - int rc = ble_gap_security_initiate(conn_id); - if(rc != 0){ +bool NimBLEDevice::startSecurity(uint16_t connHandle) { + int rc = ble_gap_security_initiate(connHandle); + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } - return rc; + return rc == 0; } // startSecurity - /** - * @brief Inject the provided passkey into the Security Manager - * @param [in] peerInfo Connection information for the peer - * @param [in] pin The 6-digit pin to inject + * @brief Inject the provided passkey into the Security Manager. + * @param [in] peerInfo Connection information for the peer. + * @param [in] passkey The 6-digit passkey to inject. * @return true if the passkey was injected successfully. */ -bool NimBLEDevice::injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin) { - int rc = 0; - struct ble_sm_io pkey = {0,0}; - - pkey.action = BLE_SM_IOACT_INPUT; - pkey.passkey = pin; - - rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); +bool NimBLEDevice::injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t passkey) { + ble_sm_io pkey{.action = BLE_SM_IOACT_INPUT, .passkey = passkey}; + int rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc); return rc == 0; } - /** - * @brief Inject the provided numeric comparison response into the Security Manager - * @param [in] peerInfo Connection information for the peer - * @param [in] accept Whether the user confirmed or declined the comparison + * @brief Inject the provided numeric comparison response into the Security Manager. + * @param [in] peerInfo Connection information for the peer. + * @param [in] accept Whether the user confirmed or declined the comparison. */ -bool NimBLEDevice::injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept) { - int rc = 0; - struct ble_sm_io pkey = {0,0}; - - pkey.action = BLE_SM_IOACT_NUMCMP; - pkey.numcmp_accept = accept; - - rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); +bool NimBLEDevice::injectConfirmPasskey(const NimBLEConnInfo& peerInfo, bool accept) { + ble_sm_io pkey{.action = BLE_SM_IOACT_NUMCMP, .numcmp_accept = accept}; + int rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc); return rc == 0; } +/* -------------------------------------------------------------------------- */ +/* IGNORE LIST */ +/* -------------------------------------------------------------------------- */ /** * @brief Check if the device address is on our ignore list. * @param [in] address The address to look for. * @return True if ignoring. */ -/*STATIC*/ -bool NimBLEDevice::isIgnored(const NimBLEAddress &address) { - for(auto &it : m_ignoreList) { - if(it.equals(address)){ +bool NimBLEDevice::isIgnored(const NimBLEAddress& address) { + for (const auto& addr : m_ignoreList) { + if (addr == address) { return true; } } @@ -1192,58 +1149,82 @@ bool NimBLEDevice::isIgnored(const NimBLEAddress &address) { return false; } - /** * @brief Add a device to the ignore list. * @param [in] address The address of the device we want to ignore. */ -/*STATIC*/ -void NimBLEDevice::addIgnored(const NimBLEAddress &address) { - m_ignoreList.push_back(address); +void NimBLEDevice::addIgnored(const NimBLEAddress& address) { + if (!isIgnored(address)) { + m_ignoreList.push_back(address); + } } - /** * @brief Remove a device from the ignore list. * @param [in] address The address of the device we want to remove from the list. */ -/*STATIC*/ -void NimBLEDevice::removeIgnored(const NimBLEAddress &address) { - for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) { - if((*it).equals(address)){ +void NimBLEDevice::removeIgnored(const NimBLEAddress& address) { + for (auto it = m_ignoreList.begin(); it < m_ignoreList.end(); ++it) { + if (*it == address) { m_ignoreList.erase(it); - return; + std::vector(m_ignoreList).swap(m_ignoreList); } } } +/* -------------------------------------------------------------------------- */ +/* UTILITIES */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Set the BLEDevice name. + * @param [in] deviceName The name to set. + */ +bool NimBLEDevice::setDeviceName(const std::string& deviceName) { + int rc = ble_svc_gap_device_name_set(deviceName.c_str()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Device name not set - too long"); + return false; + } + + return true; +} // setDeviceName /** * @brief Set a custom callback for gap events. * @param [in] handler The function to call when gap events occur. + * @returns */ -/*STATIC*/ -void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { - m_customGapHandler = handler; - int rc = ble_gap_event_listener_register(&m_listener, m_customGapHandler, NULL); - if(rc == BLE_HS_EALREADY){ +bool NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { + int rc = ble_gap_event_listener_register(&m_listener, handler, NULL); + if (rc == BLE_HS_EALREADY) { NIMBLE_LOGI(LOG_TAG, "Already listening to GAP events."); + return true; } else if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gap_event_listener_register: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } + return rc == 0; } // setCustomGapHandler -#if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED || __DOXYGEN__ +/** + * @brief Return a string representation of the address of this device. + * @return A string representation of this device address. + */ +std::string NimBLEDevice::toString() { + return getAddress().toString(); +} // toString + +# if CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED || __DOXYGEN__ /** * @brief Debug assert - weak function. * @param [in] file The file where the assert occurred. * @param [in] line The line number where the assert occurred. */ -void nimble_cpp_assert(const char *file, unsigned line) { +void nimble_cpp_assert(const char* file, unsigned line) { NIMBLE_LOGC("", "Assertion failed at %s:%u\n", file, line); abort(); } -#endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED +# endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED #endif // CONFIG_BT_ENABLED diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index b9dce8d..27d13f1 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -12,241 +12,260 @@ * Author: kolban */ -#ifndef MAIN_NIMBLEDEVICE_H_ -#define MAIN_NIMBLEDEVICE_H_ +#ifndef NIMBLE_CPP_DEVICE_H_ +#define NIMBLE_CPP_DEVICE_H_ #include "nimconfig.h" #if defined(CONFIG_BT_ENABLED) +# ifdef ESP_PLATFORM +# include +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) -#include "NimBLEScan.h" -#endif +# if defined(CONFIG_NIMBLE_CPP_IDF) +# include +# else +# include +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -# if CONFIG_BT_NIMBLE_EXT_ADV -# include "NimBLEExtAdvertising.h" -# else -# include "NimBLEAdvertising.h" -# endif -#endif +/**** FIX COMPILATION ****/ +# undef min +# undef max +/**************************/ -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# include +# include + +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# include class NimBLEClient; -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#include "NimBLEServer.h" -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +class NimBLEScan; +# endif -#include "NimBLEUtils.h" -#include "NimBLEAddress.h" +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if CONFIG_BT_NIMBLE_EXT_ADV +class NimBLEExtAdvertising; +# else +class NimBLEAdvertising; +# endif +# endif -#ifdef ESP_PLATFORM -#ifndef CONFIG_IDF_TARGET_ESP32P4 -# include "esp_bt.h" -#endif -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +class NimBLEServer; +# endif -#include -#include +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) || defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +class NimBLEConnInfo; +# endif -#define BLEDevice NimBLEDevice -#define BLEClient NimBLEClient -#define BLERemoteService NimBLERemoteService -#define BLERemoteCharacteristic NimBLERemoteCharacteristic -#define BLERemoteDescriptor NimBLERemoteDescriptor -#define BLEAdvertisedDevice NimBLEAdvertisedDevice -#define BLEScan NimBLEScan -#define BLEUUID NimBLEUUID -#define BLESecurity NimBLESecurity -#define BLESecurityCallbacks NimBLESecurityCallbacks -#define BLEAddress NimBLEAddress -#define BLEUtils NimBLEUtils -#define BLEClientCallbacks NimBLEClientCallbacks -#define BLEAdvertisedDeviceCallbacks NimBLEScanCallbacks -#define BLEScanResults NimBLEScanResults -#define BLEServer NimBLEServer -#define BLEService NimBLEService -#define BLECharacteristic NimBLECharacteristic -#define BLEAdvertising NimBLEAdvertising -#define BLEServerCallbacks NimBLEServerCallbacks -#define BLECharacteristicCallbacks NimBLECharacteristicCallbacks -#define BLEAdvertisementData NimBLEAdvertisementData -#define BLEDescriptor NimBLEDescriptor -#define BLE2902 NimBLE2902 -#define BLE2904 NimBLE2904 -#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks -#define BLEBeacon NimBLEBeacon -#define BLEEddystoneTLM NimBLEEddystoneTLM -#define BLEEddystoneURL NimBLEEddystoneURL -#define BLEConnInfo NimBLEConnInfo +class NimBLEAddress; -#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#else -#define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS -#endif +# define BLEDevice NimBLEDevice +# define BLEClient NimBLEClient +# define BLERemoteService NimBLERemoteService +# define BLERemoteCharacteristic NimBLERemoteCharacteristic +# define BLERemoteDescriptor NimBLERemoteDescriptor +# define BLEAdvertisedDevice NimBLEAdvertisedDevice +# define BLEScan NimBLEScan +# define BLEUUID NimBLEUUID +# define BLEAddress NimBLEAddress +# define BLEUtils NimBLEUtils +# define BLEClientCallbacks NimBLEClientCallbacks +# define BLEAdvertisedDeviceCallbacks NimBLEScanCallbacks +# define BLEScanResults NimBLEScanResults +# define BLEServer NimBLEServer +# define BLEService NimBLEService +# define BLECharacteristic NimBLECharacteristic +# define BLEAdvertising NimBLEAdvertising +# define BLEServerCallbacks NimBLEServerCallbacks +# define BLECharacteristicCallbacks NimBLECharacteristicCallbacks +# define BLEAdvertisementData NimBLEAdvertisementData +# define BLEDescriptor NimBLEDescriptor +# define BLE2904 NimBLE2904 +# define BLEDescriptorCallbacks NimBLEDescriptorCallbacks +# define BLEBeacon NimBLEBeacon +# define BLEEddystoneTLM NimBLEEddystoneTLM +# define BLEEddystoneURL NimBLEEddystoneURL +# define BLEConnInfo NimBLEConnInfo -typedef int (*gap_event_handler)(ble_gap_event *event, void *arg); +# ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS +# define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS +# else +# define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS +# endif -extern "C" void ble_store_config_init(void); +typedef int (*gap_event_handler)(ble_gap_event* event, void* arg); /** - * @brief A model of a %BLE Device from which all the BLE roles are created. + * @brief A model of a BLE Device from which all the BLE roles are created. */ class NimBLEDevice { -public: - static void init(const std::string &deviceName); - static void deinit(bool clearAll = false); - static void setDeviceName(const std::string &deviceName); - static bool getInitialized(); - static NimBLEAddress getAddress(); - static std::string toString(); - static bool whiteListAdd(const NimBLEAddress & address); - static bool whiteListRemove(const NimBLEAddress & address); - static bool onWhiteList(const NimBLEAddress & address); - static size_t getWhiteListCount(); - static NimBLEAddress getWhiteListAddress(size_t index); + public: + static bool init(const std::string& deviceName); + static bool deinit(bool clearAll = false); + static bool setDeviceName(const std::string& deviceName); + static bool isInitialized(); + static NimBLEAddress getAddress(); + static std::string toString(); + static bool whiteListAdd(const NimBLEAddress& address); + static bool whiteListRemove(const NimBLEAddress& address); + static bool onWhiteList(const NimBLEAddress& address); + static size_t getWhiteListCount(); + static NimBLEAddress getWhiteListAddress(size_t index); + static bool setPower(int8_t dbm); + static int getPower(); + static bool setOwnAddrType(uint8_t type); + static void setScanDuplicateCacheSize(uint16_t cacheSize); + static void setScanFilterMode(uint8_t type); + static bool setCustomGapHandler(gap_event_handler handler); + static void setSecurityAuth(bool bonding, bool mitm, bool sc); + static void setSecurityAuth(uint8_t auth); + static void setSecurityIOCap(uint8_t iocap); + static void setSecurityInitKey(uint8_t initKey); + static void setSecurityRespKey(uint8_t respKey); + static void setSecurityPasskey(uint32_t passKey); + static uint32_t getSecurityPasskey(); + static bool startSecurity(uint16_t connHandle); + static bool setMTU(uint16_t mtu); + static uint16_t getMTU(); + static bool isIgnored(const NimBLEAddress& address); + static void addIgnored(const NimBLEAddress& address); + static void removeIgnored(const NimBLEAddress& address); + static void onReset(int reason); + static void onSync(void); + static void host_task(void* param); -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - static NimBLEScan* getScan(); -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + static NimBLEScan* getScan(); +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - static NimBLEServer* createServer(); - static NimBLEServer* getServer(); -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static NimBLEServer* createServer(); + static NimBLEServer* getServer(); +# endif -#ifdef ESP_PLATFORM -#ifndef CONFIG_IDF_TARGET_ESP32P4 - static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); - static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); -#endif - static void setOwnAddrType(uint8_t own_addr_type, bool useNRPA=false); - static void setScanDuplicateCacheSize(uint16_t cacheSize); - static void setScanFilterMode(uint8_t type); -#else - static void setPower(int dbm); - static int getPower(); -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) || defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static bool injectConfirmPasskey(const NimBLEConnInfo& peerInfo, bool accept); + static bool injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin); +# endif - static void setCustomGapHandler(gap_event_handler handler); - static void setSecurityAuth(bool bonding, bool mitm, bool sc); - static void setSecurityAuth(uint8_t auth_req); - static void setSecurityIOCap(uint8_t iocap); - static void setSecurityInitKey(uint8_t init_key); - static void setSecurityRespKey(uint8_t init_key); - static void setSecurityPasskey(uint32_t pin); - static uint32_t getSecurityPasskey(); - static int startSecurity(uint16_t conn_id); - static bool injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept); - static bool injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin); - static int setMTU(uint16_t mtu); - static uint16_t getMTU(); - static bool isIgnored(const NimBLEAddress &address); - static void addIgnored(const NimBLEAddress &address); - static void removeIgnored(const NimBLEAddress &address); - -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) # if CONFIG_BT_NIMBLE_EXT_ADV static NimBLEExtAdvertising* getAdvertising(); - static bool startAdvertising(uint8_t inst_id, - int duration = 0, - int max_events = 0); - static bool stopAdvertising(uint8_t inst_id); + static bool startAdvertising(uint8_t instId, int duration = 0, int maxEvents = 0); + static bool stopAdvertising(uint8_t instId); static bool stopAdvertising(); # endif # if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) - static NimBLEAdvertising* getAdvertising(); - static bool startAdvertising(uint32_t duration = 0); - static bool stopAdvertising(); + static NimBLEAdvertising* getAdvertising(); + static bool startAdvertising(uint32_t duration = 0); + static bool stopAdvertising(); # endif -#endif +# endif -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) - static NimBLEClient* createClient(NimBLEAddress peerAddress = NimBLEAddress{}); - static bool deleteClient(NimBLEClient* pClient); - static NimBLEClient* getClientByID(uint16_t conn_id); - static NimBLEClient* getClientByPeerAddress(const NimBLEAddress &peer_addr); - static NimBLEClient* getDisconnectedClient(); - static size_t getCreatedClientCount(); -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static NimBLEClient* createClient(); + static NimBLEClient* createClient(const NimBLEAddress& peerAddress); + static bool deleteClient(NimBLEClient* pClient); + static NimBLEClient* getClientByHandle(uint16_t connHandle); + static NimBLEClient* getClientByPeerAddress(const NimBLEAddress& peerAddress); + static NimBLEClient* getDisconnectedClient(); + static size_t getCreatedClientCount(); +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - static bool deleteBond(const NimBLEAddress &address); - static int getNumBonds(); - static bool isBonded(const NimBLEAddress &address); - static bool deleteAllBonds(); - static NimBLEAddress getBondedAddress(int index); -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static bool deleteBond(const NimBLEAddress& address); + static int getNumBonds(); + static bool isBonded(const NimBLEAddress& address); + static bool deleteAllBonds(); + static NimBLEAddress getBondedAddress(int index); +# endif -private: -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + private: + static bool m_synced; + static bool m_initialized; + static std::vector m_ignoreList; + static uint32_t m_passkey; + static ble_gap_event_listener m_listener; + static uint8_t m_ownAddrType; + static std::vector m_whiteList; + +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + static NimBLEScan* m_pScan; +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static NimBLEServer* m_pServer; +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if CONFIG_BT_NIMBLE_EXT_ADV + static NimBLEExtAdvertising* m_bleAdvertising; +# else + static NimBLEAdvertising* m_bleAdvertising; +# endif +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static std::array m_pClients; +# endif + +# ifdef ESP_PLATFORM +# ifdef CONFIG_BTDM_BLE_SCAN_DUPL + static uint16_t m_scanDuplicateSize; + static uint8_t m_scanFilterMode; +# endif +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) friend class NimBLEClient; -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) friend class NimBLEScan; -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) friend class NimBLEServer; friend class NimBLECharacteristic; -#endif +# endif -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) friend class NimBLEAdvertising; # if CONFIG_BT_NIMBLE_EXT_ADV friend class NimBLEExtAdvertising; friend class NimBLEExtAdvertisement; # endif -#endif - - static void onReset(int reason); - static void onSync(void); - static void host_task(void *param); - static bool m_synced; - -#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) - static NimBLEScan* m_pScan; -#endif - -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - static NimBLEServer* m_pServer; -#endif - -#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -# if CONFIG_BT_NIMBLE_EXT_ADV - static NimBLEExtAdvertising* m_bleAdvertising; -# else - static NimBLEAdvertising* m_bleAdvertising; -# endif -#endif - - static std::vector m_ignoreList; - static uint32_t m_passkey; - static ble_gap_event_listener m_listener; - static gap_event_handler m_customGapHandler; - static uint8_t m_own_addr_type; - static std::vector m_whiteList; -#ifdef ESP_PLATFORM -# ifdef CONFIG_BTDM_BLE_SCAN_DUPL - static uint16_t m_scanDuplicateSize; - static uint8_t m_scanFilterMode; -# endif -#endif - -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) - static std::array m_pClients; -#endif +# endif }; -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) -#include "NimBLEClient.h" -#include "NimBLERemoteService.h" -#include "NimBLERemoteCharacteristic.h" -#include "NimBLERemoteDescriptor.h" -#endif +# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +# include "NimBLEClient.h" +# include "NimBLERemoteService.h" +# include "NimBLERemoteCharacteristic.h" +# include "NimBLERemoteDescriptor.h" +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +# include "NimBLEScan.h" +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +# include "NimBLEServer.h" +# include "NimBLEService.h" +# include "NimBLECharacteristic.h" +# include "NimBLEDescriptor.h" +# endif + +# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +# if CONFIG_BT_NIMBLE_EXT_ADV +# include "NimBLEExtAdvertising.h" +# else +# include "NimBLEAdvertising.h" +# endif +# endif #endif // CONFIG_BT_ENABLED -#endif // MAIN_NIMBLEDEVICE_H_ +#endif // NIMBLE_CPP_DEVICE_H_ diff --git a/src/NimBLEExtAdvertising.cpp b/src/NimBLEExtAdvertising.cpp index 7686b13..592abe7 100644 --- a/src/NimBLEExtAdvertising.cpp +++ b/src/NimBLEExtAdvertising.cpp @@ -387,7 +387,7 @@ NimBLEExtAdvertisement::NimBLEExtAdvertisement(uint8_t priPhy, uint8_t secPhy) : m_advAddress{} { memset (&m_params, 0, sizeof(m_params)); - m_params.own_addr_type = NimBLEDevice::m_own_addr_type; + m_params.own_addr_type = NimBLEDevice::m_ownAddrType; m_params.primary_phy = priPhy; m_params.secondary_phy = secPhy; m_params.tx_power = 127; diff --git a/src/NimBLEScan.cpp b/src/NimBLEScan.cpp index 2e449c6..d21b6a4 100644 --- a/src/NimBLEScan.cpp +++ b/src/NimBLEScan.cpp @@ -310,7 +310,7 @@ bool NimBLEScan::start(uint32_t duration, bool is_continue) { scan_params.passive = m_scan_params.passive; scan_params.itvl = m_scan_params.itvl; scan_params.window = m_scan_params.window; - int rc = ble_gap_ext_disc(NimBLEDevice::m_own_addr_type, + int rc = ble_gap_ext_disc(NimBLEDevice::m_ownAddrType, duration/10, 0, m_scan_params.filter_duplicates, @@ -321,7 +321,7 @@ bool NimBLEScan::start(uint32_t duration, bool is_continue) { NimBLEScan::handleGapEvent, NULL); #else - int rc = ble_gap_disc(NimBLEDevice::m_own_addr_type, + int rc = ble_gap_disc(NimBLEDevice::m_ownAddrType, duration, &m_scan_params, NimBLEScan::handleGapEvent, diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index a453556..9bf2f7f 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -702,7 +702,7 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onConfirmPIN(peerInfo, event->passkey.params.numcmp); + pServer->m_pServerCallbacks->onConfirmPassKey(peerInfo, event->passkey.params.numcmp); //TODO: Handle out of band pairing } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { static uint8_t tem_oob[16] = {0}; @@ -1076,9 +1076,9 @@ uint32_t NimBLEServerCallbacks::onPassKeyDisplay(){ return 123456; } //onPassKeyDisplay -void NimBLEServerCallbacks::onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pin){ +void NimBLEServerCallbacks::onConfirmPassKey(NimBLEConnInfo& connInfo, uint32_t pin){ NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true"); - NimBLEDevice::injectConfirmPIN(connInfo, true); + NimBLEDevice::injectConfirmPasskey(connInfo, true); } // onConfirmPIN void NimBLEServerCallbacks::onIdentity(NimBLEConnInfo& connInfo){ diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h index a840ded..936daa8 100644 --- a/src/NimBLEServer.h +++ b/src/NimBLEServer.h @@ -180,10 +180,10 @@ public: /** * @brief Called when using numeric comparision for pairing. * @param [in] connInfo A reference to a NimBLEConnInfo instance with information - * Should be passed back to NimBLEDevice::injectConfirmPIN + * Should be passed back to NimBLEDevice::injectConfirmPasskey * @param [in] pin The pin to compare with the client. */ - virtual void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pin); + virtual void onConfirmPassKey(NimBLEConnInfo& connInfo, uint32_t pin); /** * @brief Called when the pairing procedure is complete.