diff --git a/docs/Migration_guide.md b/docs/Migration_guide.md
index accf1bc9e..ee06ca7c7 100644
--- a/docs/Migration_guide.md
+++ b/docs/Migration_guide.md
@@ -386,7 +386,7 @@ The callback methods are:
> `bool onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pin)`
Receives the pin when using numeric comparison authentication.
-Call `NimBLEDevice::injectConfirmPIN(connInfo, true);` to accept or `NimBLEDevice::injectConfirmPIN(connInfo, false);` to reject.
+Call `NimBLEDevice::injectConfirmPasskey(connInfo, true);` to accept or `NimBLEDevice::injectConfirmPasskey(connInfo, false);` to reject.
> `void onPassKeyEntry(NimBLEConnInfo& connInfo)`
diff --git a/examples/NimBLE_Client/NimBLE_Client.ino b/examples/NimBLE_Client/NimBLE_Client.ino
index 2ad6eb93f..384eb9530 100644
--- a/examples/NimBLE_Client/NimBLE_Client.ino
+++ b/examples/NimBLE_Client/NimBLE_Client.ino
@@ -67,7 +67,7 @@ class ClientCallbacks : public NimBLEClientCallbacks {
void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key){
Serial.print("The passkey YES/NO number: ");Serial.println(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 */
@@ -75,7 +75,7 @@ class ClientCallbacks : public NimBLEClientCallbacks {
if(!connInfo.isEncrypted()) {
Serial.println("Encrypt connection failed - disconnecting");
/** 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/NimBLE_Server/NimBLE_Server.ino b/examples/NimBLE_Server/NimBLE_Server.ino
index 3b00e3a80..0ee943013 100644
--- a/examples/NimBLE_Server/NimBLE_Server.ino
+++ b/examples/NimBLE_Server/NimBLE_Server.ino
@@ -48,7 +48,7 @@ class ServerCallbacks: public NimBLEServerCallbacks {
void onConfirmPIN(NimBLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(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/Refactored_original_examples/BLE_client/BLE_client.ino b/examples/Refactored_original_examples/BLE_client/BLE_client.ino
index 4cd796207..e71114d64 100644
--- a/examples/Refactored_original_examples/BLE_client/BLE_client.ino
+++ b/examples/Refactored_original_examples/BLE_client/BLE_client.ino
@@ -58,7 +58,7 @@ class MyClientCallback : public BLEClientCallbacks {
void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- NimBLEDevice::injectConfirmPIN(connInfo, true);
+ NimBLEDevice::injectConfirmPasskey(connInfo, true);
}
void onAuthenticationComplete(const BLEConnInfo& connInfo){
diff --git a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino b/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
index 5ff203b64..6250c2754 100644
--- a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
+++ b/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
@@ -65,7 +65,7 @@ class MyServerCallbacks: public BLEServerCallbacks {
void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
/** Inject false if passkeys don't match. */
- NimBLEDevice::injectConfirmPIN(connInfo, true);
+ NimBLEDevice::injectConfirmPasskey(connInfo, true);
}
void onAuthenticationComplete(const BLEConnInfo& connInfo) {
diff --git a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino b/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
index 5a6ad01e4..310558c16 100644
--- a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
+++ b/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
@@ -67,7 +67,7 @@ class MyServerCallbacks: public BLEServerCallbacks {
void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
/** Inject false if passkeys don't match. */
- NimBLEDevice::injectConfirmPIN(connInfo, true);
+ NimBLEDevice::injectConfirmPasskey(connInfo, true);
}
void onAuthenticationComplete(const BLEConnInfo& connInfo) {
diff --git a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino b/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
index a609952e6..43c31899a 100644
--- a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
+++ b/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
@@ -67,7 +67,7 @@ class MyServerCallbacks: public BLEServerCallbacks {
void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
/** Inject false if passkeys don't match. */
- NimBLEDevice::injectConfirmPIN(connInfo, true);
+ NimBLEDevice::injectConfirmPasskey(connInfo, true);
}
void onAuthenticationComplete(const BLEConnInfo& connInfo) {
diff --git a/src/NimBLEAdvertising.cpp b/src/NimBLEAdvertising.cpp
index 9c216340b..150fb6d5e 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);
@@ -56,7 +56,11 @@ void NimBLEAdvertising::reset() {
m_advData.name = (uint8_t *)name;
m_advData.name_len = strlen(name);
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);
#if !defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
@@ -639,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,
@@ -647,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,
@@ -1018,7 +1022,11 @@ void NimBLEAdvertisementData::addTxPower() {
char cdata[3];
cdata[0] = BLE_HS_ADV_TX_PWR_LVL_LEN + 1;
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 9d96fbdbd..e87404009 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 605d55ab1..e60c9f873 100644
--- a/src/NimBLEDevice.cpp
+++ b/src/NimBLEDevice.cpp
@@ -15,32 +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"
-# include "esp_bt.h"
+# 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"
@@ -48,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
-
-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
+# endif
+
+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();
@@ -115,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_)
@@ -171,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.
@@ -195,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 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.
+ */
+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;
+ }
+ }
+
+ NIMBLE_LOGD(LOG_TAG, "Set duplicate cache size to: %u", size);
+ m_scanDuplicateSize = size;
+}
/**
- * @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 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.
*/
-#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;
+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;
}
- NimBLEClient* pClient = new NimBLEClient(peerAddress);
+ 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 = pClient;
- break;
+ clt = new NimBLEClient(peerAddress);
+ return clt;
}
}
- return pClient;
+ 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);
}
}
@@ -290,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++;
}
@@ -307,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;
}
}
@@ -341,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;
}
}
@@ -357,67 +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
/**
* @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:
@@ -435,167 +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;
- }
-} // getPower
-
-#else
-
-void NimBLEDevice::setPower(int dbm) {
- struct ble_hci_vs_set_tx_pwr_cp cmd;
- struct ble_hci_vs_set_tx_pwr_rp rsp;
- int rc;
-
- cmd.tx_power = dbm;
- 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;
+ return 0xFF;
}
+# else
+ return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get
+# endif
- NIMBLE_LOGD(LOG_TAG, "TX power set to %d dBm\n", rsp.tx_power);
- return;
-}
-
-
-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) {
@@ -605,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) {
@@ -634,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;
}
}
@@ -642,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;
@@ -664,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;
}
}
@@ -682,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());
@@ -703,299 +662,377 @@ 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;
-
-#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
+bool NimBLEDevice::init(const std::string& deviceName) {
+ if (!m_initialized) {
+# ifdef ESP_PLATFORM
+
+# ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
// make sure the linker includes esp32-hal-bt.c so Arduino init doesn't release BLE memory.
btStarted();
-#endif
-
- errRc = nvs_flash_init();
+# endif
- 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.
+ * @brief Check if the initialization is complete.
+ * @return true if initialized.
*/
-/* STATIC */
-void NimBLEDevice::setDeviceName(const std::string &deviceName) {
- ble_svc_gap_device_name_set(deviceName.c_str());
-} // setDeviceName
+bool NimBLEDevice::isInitialized() {
+ return m_initialized;
+} // getInitialized
+/* -------------------------------------------------------------------------- */
+/* ADDRESS MANAGEMENT */
+/* -------------------------------------------------------------------------- */
/**
- * @brief Check if the initialization is complete.
- * @return true if initialized.
+ * @brief Get our device address.
+ * @return A NimBLEAddress object with the currently used address, or a NULL address if not set.
*/
-/*STATIC*/
-bool NimBLEDevice::getInitialized() {
- return initialized;
-} // getInitialized
+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
+
+/**
+ * @brief Set the device address to use.
+ * @param [in] addr The address to set.
+ * @return True if the address was set successfully.
+ * @details To use the address generated the address type must be set to random with `setOwnAddrType`.
+ */
+bool NimBLEDevice::setOwnAddr(const NimBLEAddress& addr) {
+ return setOwnAddr(addr.getBase()->val);
+} // setOwnAddr
+
+/**
+ * @brief Set the device address to use.
+ * @param [in] addr The address to set.
+ * @return True if the address was set successfully.
+ * @details To use the address generated the address type must be set to random with `setOwnAddrType`.
+ */
+bool NimBLEDevice::setOwnAddr(const uint8_t* addr) {
+ int rc = ble_hs_id_set_rnd(addr);
+ if (rc != 0) {
+ NIMBLE_LOGE(LOG_TAG, "Failed to set address, rc=%d", rc);
+ return false;
+ }
+
+ return true;
+} // setOwnAddr
+/* -------------------------------------------------------------------------- */
+/* SECURITY */
+/* -------------------------------------------------------------------------- */
/**
* @brief Set the authorization mode for this device.
@@ -1003,15 +1040,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
@@ -1021,14 +1056,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:
@@ -1038,161 +1071,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;
}
}
@@ -1200,58 +1175,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 121df587a..507b5ad79 100644
--- a/src/NimBLEDevice.h
+++ b/src/NimBLEDevice.h
@@ -12,237 +12,262 @@
* 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_NIMBLE_CPP_IDF)
+# include
+# else
+# include
+# endif
+
+/**** FIX COMPILATION ****/
+# undef min
+# undef max
+/**************************/
+
+# include
+# include
+
+# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
+# include
+class NimBLEClient;
+# endif
-#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
-#include "NimBLEScan.h"
-#endif
+# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
+class NimBLEScan;
+# endif
-#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
+# if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
# if CONFIG_BT_NIMBLE_EXT_ADV
-# include "NimBLEExtAdvertising.h"
+class NimBLEExtAdvertising;
# else
-# include "NimBLEAdvertising.h"
+class NimBLEAdvertising;
# endif
-#endif
-
-#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
-class NimBLEClient;
-#endif
-
-#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
-#include "NimBLEServer.h"
-#endif
-
-#include "NimBLEUtils.h"
-#include "NimBLEAddress.h"
-
-#ifdef ESP_PLATFORM
-# include "esp_bt.h"
-#endif
-
-#include
-#include
-
-#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
-
-#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
-
-typedef int (*gap_event_handler)(ble_gap_event *event, void *arg);
-
-extern "C" void ble_store_config_init(void);
+# endif
+
+# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
+class NimBLEServer;
+# endif
+
+# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) || defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
+class NimBLEConnInfo;
+# endif
+
+class NimBLEAddress;
+
+# 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
+
+# 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
+
+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);
-
-#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
-
-#ifdef ESP_PLATFORM
- 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);
- 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
-
- 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)
+ 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 bool setOwnAddr(const NimBLEAddress& addr);
+ static bool setOwnAddr(const uint8_t* addr);
+ 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_PERIPHERAL)
+ static NimBLEServer* createServer();
+ static NimBLEServer* getServer();
+# 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
+
+# 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
-
-#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) || 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)
+# 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
+
+ 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
+# endif
+};
-#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
+# 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
- static NimBLEExtAdvertising* m_bleAdvertising;
+# include "NimBLEExtAdvertising.h"
# 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;
+# include "NimBLEAdvertising.h"
# endif
-#endif
-
-#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
- static std::array m_pClients;
-#endif
-};
-
-#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
-#include "NimBLEClient.h"
-#include "NimBLERemoteService.h"
-#include "NimBLERemoteCharacteristic.h"
-#include "NimBLERemoteDescriptor.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 7686b1388..592abe7ce 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 1590b7c68..d2e93bf35 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 a453556b9..9bf2f7f51 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 a840dedbd..936daa8bf 100644
--- a/src/NimBLEServer.h
+++ b/src/NimBLEServer.h
@@ -180,10 +180,10 @@ class NimBLEServerCallbacks {
/**
* @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.
diff --git a/src/NimBLEUtils.cpp b/src/NimBLEUtils.cpp
index 06e649c09..cc50e138b 100644
--- a/src/NimBLEUtils.cpp
+++ b/src/NimBLEUtils.cpp
@@ -10,6 +10,7 @@
#if defined(CONFIG_BT_ENABLED)
#include "NimBLEUtils.h"
+#include "NimBLEAddress.h"
#include "NimBLELog.h"
#include
@@ -476,4 +477,20 @@ const char* NimBLEUtils::gapEventToString(uint8_t eventType) {
#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT)
} // gapEventToString
+/**
+ * @brief Generate a random BLE address.
+ * @param [in] nrpa True to generate a non-resolvable private address,
+ * false to generate a random static address
+ * @return The generated address or a NULL address if there was an error.
+ */
+NimBLEAddress NimBLEUtils::generateAddr(bool nrpa) {
+ ble_addr_t addr{};
+ int rc = ble_hs_id_gen_rnd(nrpa, &addr);
+ if (rc != 0) {
+ NIMBLE_LOGE(LOG_TAG, "Generate address failed, rc=%d", rc);
+ }
+
+ return NimBLEAddress{addr};
+} // generateAddr
+
#endif //CONFIG_BT_ENABLED
diff --git a/src/NimBLEUtils.h b/src/NimBLEUtils.h
index 57d22a0aa..a581011b1 100644
--- a/src/NimBLEUtils.h
+++ b/src/NimBLEUtils.h
@@ -25,6 +25,8 @@
#include
+class NimBLEAddress;
+
typedef struct {
void *pATT;
TaskHandle_t task;
@@ -43,6 +45,7 @@ class NimBLEUtils {
static char* buildHexData(uint8_t* target, const uint8_t* source, uint8_t length);
static const char* advTypeToString(uint8_t advType);
static const char* returnCodeToString(int rc);
+ static NimBLEAddress generateAddr(bool nrpa);
};