2020-03-30 01:44:20 +02:00
|
|
|
/*
|
|
|
|
* NimBLEDevice.cpp
|
|
|
|
*
|
|
|
|
* Created: on Jan 24 2020
|
|
|
|
* Author H2zero
|
2020-05-14 06:03:56 +02:00
|
|
|
*
|
2020-03-30 01:44:20 +02:00
|
|
|
* Originally:
|
|
|
|
*
|
|
|
|
* BLEDevice.cpp
|
|
|
|
*
|
|
|
|
* Created on: Mar 16, 2017
|
|
|
|
* Author: kolban
|
|
|
|
*/
|
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#include "nimconfig.h"
|
2021-09-07 05:14:43 +02:00
|
|
|
#if defined(CONFIG_BT_ENABLED)
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
#include "NimBLEDevice.h"
|
|
|
|
#include "NimBLEUtils.h"
|
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
|
|
|
# include "esp_err.h"
|
|
|
|
# include "esp_bt.h"
|
|
|
|
# include "nvs_flash.h"
|
|
|
|
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
2023-08-13 18:08:11 +02:00
|
|
|
# if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) || CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE)
|
|
|
|
# include "esp_nimble_hci.h"
|
|
|
|
# endif
|
2021-12-29 16:08:25 +01:00
|
|
|
# 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"
|
|
|
|
# endif
|
2021-09-07 05:14:43 +02:00
|
|
|
#else
|
2021-12-29 16:08:25 +01:00
|
|
|
# include "nimble/nimble/controller/include/controller/ble_phy.h"
|
2021-09-07 05:14:43 +02:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#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"
|
|
|
|
# include "nimble/nimble/host/include/host/ble_hs_pvcy.h"
|
|
|
|
# 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
|
|
|
|
|
|
|
|
#if defined(ESP_PLATFORM) && defined(CONFIG_ENABLE_ARDUINO_DEPENDS)
|
|
|
|
# include "esp32-hal-bt.h"
|
2020-03-30 01:44:20 +02:00
|
|
|
#endif
|
|
|
|
|
2024-07-26 22:47:36 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
|
|
#include "NimBLEClient.h"
|
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2024-07-26 22:47:36 +02:00
|
|
|
#include "NimBLELog.h"
|
2024-07-05 03:17:13 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
static const char* LOG_TAG = "NimBLEDevice";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Singletons for the NimBLEDevice.
|
|
|
|
*/
|
2020-05-30 02:26:41 +02:00
|
|
|
static bool initialized = false;
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
2020-03-30 01:44:20 +02:00
|
|
|
NimBLEScan* NimBLEDevice::m_pScan = nullptr;
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
2020-03-30 01:44:20 +02:00
|
|
|
NimBLEServer* NimBLEDevice::m_pServer = nullptr;
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
uint32_t NimBLEDevice::m_passkey = 123456;
|
|
|
|
bool NimBLEDevice::m_synced = false;
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
2022-04-10 18:21:45 +02:00
|
|
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
|
|
|
NimBLEExtAdvertising* NimBLEDevice::m_bleAdvertising = nullptr;
|
|
|
|
# else
|
2020-03-30 01:44:20 +02:00
|
|
|
NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr;
|
2022-04-10 18:21:45 +02:00
|
|
|
# endif
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
2024-07-04 20:03:03 +02:00
|
|
|
std::array<NimBLEClient*, NIMBLE_MAX_CONNECTIONS> NimBLEDevice::m_pClients{nullptr};
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2024-07-04 20:03:03 +02:00
|
|
|
|
|
|
|
gap_event_handler NimBLEDevice::m_customGapHandler = nullptr;
|
|
|
|
ble_gap_event_listener NimBLEDevice::m_listener;
|
|
|
|
std::vector <NimBLEAddress> NimBLEDevice::m_ignoreList;
|
2021-05-23 21:12:44 +02:00
|
|
|
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList;
|
2021-01-14 02:00:48 +01:00
|
|
|
uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC;
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
2023-05-29 17:08:14 +02:00
|
|
|
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
|
2021-02-01 05:15:31 +01:00
|
|
|
uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE;
|
|
|
|
uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DUPL_TYPE;
|
2023-05-29 17:08:14 +02:00
|
|
|
# endif
|
2021-12-29 16:08:25 +01:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a new instance of a server.
|
|
|
|
* @return A new instance of the server.
|
|
|
|
*/
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
2020-03-30 01:44:20 +02:00
|
|
|
/* STATIC */ NimBLEServer* NimBLEDevice::createServer() {
|
|
|
|
if(NimBLEDevice::m_pServer == nullptr) {
|
|
|
|
NimBLEDevice::m_pServer = new NimBLEServer();
|
2020-05-14 06:03:56 +02:00
|
|
|
ble_gatts_reset();
|
2020-03-30 01:44:20 +02:00
|
|
|
ble_svc_gap_init();
|
|
|
|
ble_svc_gatt_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_pServer;
|
|
|
|
} // createServer
|
2020-05-14 20:59:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the instance of the server.
|
|
|
|
* @return A pointer to the server instance.
|
|
|
|
*/
|
|
|
|
/* STATIC */ NimBLEServer* NimBLEDevice::getServer() {
|
|
|
|
return m_pServer;
|
|
|
|
} // getServer
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
2022-04-10 18:21:45 +02:00
|
|
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
|
|
|
/**
|
|
|
|
* @brief Get the instance of the advertising object.
|
|
|
|
* @return A pointer to the advertising object.
|
|
|
|
*/
|
|
|
|
NimBLEExtAdvertising* NimBLEDevice::getAdvertising() {
|
|
|
|
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] 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).
|
|
|
|
* @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);
|
|
|
|
} // startAdvertising
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Convenience function to stop advertising a data set.
|
|
|
|
* @param [in] inst_id 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);
|
|
|
|
} // stopAdvertising
|
|
|
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
|
2020-07-09 03:27:26 +02:00
|
|
|
/**
|
|
|
|
* @brief Get the instance of the advertising object.
|
|
|
|
* @return A pointer to the advertising object.
|
|
|
|
*/
|
2020-03-30 01:44:20 +02:00
|
|
|
NimBLEAdvertising* NimBLEDevice::getAdvertising() {
|
2020-05-14 06:03:56 +02:00
|
|
|
if(m_bleAdvertising == nullptr) {
|
|
|
|
m_bleAdvertising = new NimBLEAdvertising();
|
|
|
|
}
|
|
|
|
return m_bleAdvertising;
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-07-09 03:27:26 +02:00
|
|
|
/**
|
|
|
|
* @brief Convenience function to begin advertising.
|
2022-08-27 03:32:01 +02:00
|
|
|
* @param [in] duration The duration in milliseconds to advertise for, default = forever.
|
2022-04-10 18:21:45 +02:00
|
|
|
* @return True if advertising started successfully.
|
2020-07-09 03:27:26 +02:00
|
|
|
*/
|
2022-08-27 03:32:01 +02:00
|
|
|
bool NimBLEDevice::startAdvertising(uint32_t duration) {
|
|
|
|
return getAdvertising()->start(duration);
|
2020-03-30 01:44:20 +02:00
|
|
|
} // startAdvertising
|
2022-04-10 18:21:45 +02:00
|
|
|
# endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2020-07-09 03:27:26 +02:00
|
|
|
/**
|
2022-04-10 18:21:45 +02:00
|
|
|
* @brief Convenience function to stop all advertising.
|
|
|
|
* @return True if advertising stopped successfully.
|
2020-07-09 03:27:26 +02:00
|
|
|
*/
|
2022-04-10 18:21:45 +02:00
|
|
|
bool NimBLEDevice::stopAdvertising() {
|
|
|
|
return getAdvertising()->stop();
|
2020-03-30 01:44:20 +02:00
|
|
|
} // stopAdvertising
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
NimBLEScan* NimBLEDevice::getScan() {
|
2020-03-30 01:44:20 +02:00
|
|
|
if (m_pScan == nullptr) {
|
|
|
|
m_pScan = new NimBLEScan();
|
|
|
|
}
|
|
|
|
return m_pScan;
|
|
|
|
} // getScan
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2020-07-09 03:27:26 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Creates a new client object and maintains a list of all client objects
|
2020-05-14 06:03:56 +02:00
|
|
|
* each client can connect to 1 peripheral device.
|
2020-07-30 18:07:52 +02:00
|
|
|
* @param [in] peerAddress An optional peer address that is copied to the new client
|
2020-07-30 18:09:27 +02:00
|
|
|
* object, allows for calling NimBLEClient::connect(bool) without a device or address parameter.
|
2024-07-04 20:03:03 +02:00
|
|
|
* @return A reference to the new client object, or nullptr on error.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
NimBLEClient* NimBLEDevice::createClient(NimBLEAddress peerAddress) {
|
2024-07-04 20:03:03 +02:00
|
|
|
if (getCreatedClientCount() == NIMBLE_MAX_CONNECTIONS) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG,"Unable to create client; already at max: %d",NIMBLE_MAX_CONNECTIONS);
|
|
|
|
return nullptr;
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-07-30 20:31:17 +02:00
|
|
|
NimBLEClient* pClient = new NimBLEClient(peerAddress);
|
2024-07-04 20:03:03 +02:00
|
|
|
for (auto& clt : m_pClients) {
|
|
|
|
if (clt == nullptr) {
|
|
|
|
clt = pClient;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
return pClient;
|
|
|
|
} // createClient
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @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.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
bool NimBLEDevice::deleteClient(NimBLEClient* pClient) {
|
2020-03-30 01:44:20 +02:00
|
|
|
if(pClient == nullptr) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2021-01-12 22:01:44 +01:00
|
|
|
// Set the connection established flag to false to stop notifications
|
|
|
|
// from accessing the attribute vectors while they are being deleted.
|
|
|
|
pClient->m_connEstablished = false;
|
2020-05-30 17:01:42 +02:00
|
|
|
int rc =0;
|
|
|
|
|
2021-01-12 21:50:08 +01:00
|
|
|
if(pClient->isConnected()) {
|
2020-05-30 17:01:42 +02:00
|
|
|
rc = pClient->disconnect();
|
|
|
|
if (rc != 0 && rc != BLE_HS_EALREADY && rc != BLE_HS_ENOTCONN) {
|
2020-03-30 01:44:20 +02:00
|
|
|
return false;
|
|
|
|
}
|
2020-05-30 17:01:42 +02:00
|
|
|
|
2021-01-12 21:50:08 +01:00
|
|
|
while(pClient->isConnected()) {
|
2021-01-12 21:54:53 +01:00
|
|
|
taskYIELD();
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
2021-01-12 22:01:44 +01:00
|
|
|
// 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.
|
2022-08-27 03:51:19 +02:00
|
|
|
pClient->m_pClientCallbacks->onDisconnect(pClient, BLE_ERR_CONN_TERM_LOCAL);
|
2021-01-12 22:01:44 +01:00
|
|
|
|
2021-01-12 21:50:08 +01:00
|
|
|
} else if(pClient->m_pTaskData != nullptr) {
|
2020-05-30 17:01:42 +02:00
|
|
|
rc = ble_gap_conn_cancel();
|
|
|
|
if (rc != 0 && rc != BLE_HS_EALREADY) {
|
2020-03-30 01:44:20 +02:00
|
|
|
return false;
|
|
|
|
}
|
2021-01-12 21:50:08 +01:00
|
|
|
while(pClient->m_pTaskData != nullptr) {
|
2021-01-12 21:54:53 +01:00
|
|
|
taskYIELD();
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2024-07-04 20:03:03 +02:00
|
|
|
for (auto& clt : m_pClients) {
|
|
|
|
if (clt == pClient) {
|
|
|
|
delete pClient;
|
|
|
|
clt = nullptr;
|
|
|
|
}
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return true;
|
|
|
|
} // deleteClient
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @brief Get the number of created client objects.
|
|
|
|
* @return Number of client objects created.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
2024-07-04 20:03:03 +02:00
|
|
|
size_t NimBLEDevice::getCreatedClientCount() {
|
|
|
|
auto count = 0;
|
|
|
|
for (auto clt : m_pClients) {
|
|
|
|
if (clt != nullptr) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
} // getCreatedClientCount
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get a reference to a client by connection ID.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] conn_id The client connection ID to search for.
|
2024-07-03 21:11:03 +02:00
|
|
|
* @return A pointer to the client object with the specified connection ID or nullptr.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) {
|
2024-07-04 20:03:03 +02:00
|
|
|
for(auto clt : m_pClients) {
|
|
|
|
if(clt != nullptr && clt->getConnId() == conn_id) {
|
|
|
|
return clt;
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-03 21:11:03 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return nullptr;
|
|
|
|
} // getClientByID
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get a reference to a client by peer address.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] peer_addr The address of the peer to search for.
|
2024-07-04 20:03:03 +02:00
|
|
|
* @return A pointer to the client object with the peer address or nullptr.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) {
|
2024-07-04 20:03:03 +02:00
|
|
|
for(auto clt : m_pClients) {
|
|
|
|
if(clt != nullptr && clt->getPeerAddress() == peer_addr) {
|
|
|
|
return clt;
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-04 20:03:03 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return nullptr;
|
|
|
|
} // getClientPeerAddress
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Finds the first disconnected client in the list.
|
2024-07-04 20:03:03 +02:00
|
|
|
* @return A pointer to the first client object that is not connected to a peer or nullptr.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
NimBLEClient* NimBLEDevice::getDisconnectedClient() {
|
2024-07-04 20:03:03 +02:00
|
|
|
for(auto clt : m_pClients) {
|
|
|
|
if(clt != nullptr && !clt->isConnected()) {
|
|
|
|
return clt;
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-04 20:03:03 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return nullptr;
|
|
|
|
} // getDisconnectedClient
|
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Set the transmission power.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @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
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
|
2020-04-14 03:13:51 +02:00
|
|
|
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType);
|
2021-12-29 16:08:25 +01:00
|
|
|
|
2020-04-14 03:13:51 +02:00
|
|
|
esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
|
2020-03-30 01:44:20 +02:00
|
|
|
if (errRc != ESP_OK) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc);
|
2020-04-14 03:13:51 +02:00
|
|
|
}
|
2021-12-29 16:08:25 +01:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
NIMBLE_LOGD(LOG_TAG, "<< setPower");
|
|
|
|
} // setPower
|
|
|
|
|
|
|
|
|
2020-07-09 03:27:26 +02:00
|
|
|
/**
|
2021-02-06 19:12:40 +01:00
|
|
|
* @brief Get the transmission power.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @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.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
|
2020-05-14 06:03:56 +02:00
|
|
|
switch(esp_ble_tx_power_get(powerType)) {
|
|
|
|
case ESP_PWR_LVL_N12:
|
|
|
|
return -12;
|
|
|
|
case ESP_PWR_LVL_N9:
|
|
|
|
return -9;
|
|
|
|
case ESP_PWR_LVL_N6:
|
|
|
|
return -6;
|
|
|
|
case ESP_PWR_LVL_N3:
|
2022-09-02 16:27:23 +02:00
|
|
|
return -3;
|
2020-05-14 06:03:56 +02:00
|
|
|
case ESP_PWR_LVL_N0:
|
|
|
|
return 0;
|
|
|
|
case ESP_PWR_LVL_P3:
|
|
|
|
return 3;
|
|
|
|
case ESP_PWR_LVL_P6:
|
|
|
|
return 6;
|
|
|
|
case ESP_PWR_LVL_P9:
|
|
|
|
return 9;
|
|
|
|
default:
|
|
|
|
return BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
|
|
|
}
|
2021-02-06 19:12:40 +01:00
|
|
|
} // getPower
|
2020-04-14 03:13:51 +02:00
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#else
|
|
|
|
|
|
|
|
void NimBLEDevice::setPower(int dbm) {
|
|
|
|
ble_phy_txpwr_set(dbm);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int NimBLEDevice::getPower() {
|
|
|
|
return ble_phy_txpwr_get();
|
|
|
|
}
|
|
|
|
#endif
|
2020-04-14 03:13:51 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Get our device address.
|
|
|
|
* @return A NimBLEAddress object of our public address if we have one,
|
|
|
|
* if not then our current random address.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC*/
|
|
|
|
NimBLEAddress NimBLEDevice::getAddress() {
|
2024-07-05 03:17:13 +02:00
|
|
|
ble_addr_t addr{};
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
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);
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return NimBLEAddress(addr);
|
|
|
|
} // getAddress
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return a string representation of the address of this device.
|
|
|
|
* @return A string representation of this device address.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
std::string NimBLEDevice::toString() {
|
2020-03-30 01:44:20 +02:00
|
|
|
return getAddress().toString();
|
|
|
|
} // toString
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @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.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
int NimBLEDevice::setMTU(uint16_t mtu) {
|
2020-03-30 01:44:20 +02:00
|
|
|
NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu);
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
int rc = ble_att_set_preferred_mtu(mtu);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d", mtu);
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
NIMBLE_LOGD(LOG_TAG, "<< setLocalMTU");
|
|
|
|
return rc;
|
|
|
|
} // setMTU
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get local MTU value set.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @return The current preferred MTU setting.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
uint16_t NimBLEDevice::getMTU() {
|
2020-03-30 01:44:20 +02:00
|
|
|
return ble_att_preferred_mtu();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
2023-05-29 17:08:14 +02:00
|
|
|
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
|
2021-02-01 05:15:31 +01:00
|
|
|
/**
|
2021-02-08 19:46:11 +01:00
|
|
|
* @brief Set the duplicate filter cache size for filtering scanned devices.
|
2021-02-06 19:12:40 +01:00
|
|
|
* @param [in] cacheSize The number of advertisements filtered before the cache is reset.\n
|
2021-02-01 05:15:31 +01:00
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-05-29 17:08:14 +02:00
|
|
|
|
2021-02-01 05:15:31 +01:00
|
|
|
/**
|
|
|
|
* @brief Set the duplicate filter mode for filtering scanned devices.
|
2021-02-06 19:12:40 +01:00
|
|
|
* @param [in] mode One of three possible options:
|
2021-02-01 05:15:31 +01:00
|
|
|
* * 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;
|
|
|
|
}
|
2023-05-29 17:08:14 +02:00
|
|
|
# endif // CONFIG_BTDM_BLE_SCAN_DUPL
|
|
|
|
#endif // ESP_PLATFORM
|
2021-02-01 05:15:31 +01:00
|
|
|
|
2021-04-25 16:06:38 +02:00
|
|
|
#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;
|
|
|
|
|
|
|
|
rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS));
|
|
|
|
if (rc !=0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return num_peers;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Deletes all bonding information.
|
2024-06-05 00:52:55 +02:00
|
|
|
* @returns true on success, false on failure.
|
2021-04-25 16:06:38 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2024-06-05 00:52:55 +02:00
|
|
|
bool NimBLEDevice::deleteAllBonds() {
|
|
|
|
int rc = ble_store_clear();
|
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Failed to delete all bonds; rc=%d", rc);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2021-04-25 16:06:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Deletes a peer bond.
|
|
|
|
* @param [in] address The address of the peer with which to delete bond info.
|
|
|
|
* @returns true on success.
|
|
|
|
*/
|
|
|
|
/*STATIC*/
|
|
|
|
bool NimBLEDevice::deleteBond(const NimBLEAddress &address) {
|
2024-07-05 03:17:13 +02:00
|
|
|
return ble_gap_unpair(address.getBase()) == 0;
|
2021-04-25 16:06:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Checks if a peer device is bonded.
|
|
|
|
* @param [in] address The address to check for bonding.
|
|
|
|
* @returns true if bonded.
|
|
|
|
*/
|
|
|
|
/*STATIC*/
|
|
|
|
bool NimBLEDevice::isBonded(const NimBLEAddress &address) {
|
|
|
|
ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
|
|
|
|
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 false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < num_peers; i++) {
|
|
|
|
NimBLEAddress storedAddr(peer_id_addrs[i]);
|
|
|
|
if(storedAddr == address) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS));
|
|
|
|
if (rc != 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index > num_peers || index < 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NimBLEAddress(peer_id_addrs[index]);
|
|
|
|
}
|
|
|
|
#endif
|
2021-02-01 05:15:31 +01:00
|
|
|
|
2021-05-23 21:12:44 +02:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-05-23 21:12:44 +02:00
|
|
|
bool NimBLEDevice::onWhiteList(const NimBLEAddress & address) {
|
|
|
|
for (auto &it : m_whiteList) {
|
|
|
|
if (it == address) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add a peer address to the whitelist.
|
|
|
|
* @param [in] address The address to add to the whitelist.
|
|
|
|
* @returns true if successful.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-05-23 21:12:44 +02:00
|
|
|
bool NimBLEDevice::whiteListAdd(const NimBLEAddress & address) {
|
2024-07-05 03:17:13 +02:00
|
|
|
if (!NimBLEDevice::onWhiteList(address)) {
|
|
|
|
m_whiteList.push_back(address);
|
|
|
|
int rc = ble_gap_wl_set(reinterpret_cast<ble_addr_t*>(&m_whiteList[0]), m_whiteList.size());
|
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Failed adding to whitelist rc=%d", rc);
|
|
|
|
m_whiteList.pop_back();
|
|
|
|
return false;
|
|
|
|
}
|
2021-05-23 21:12:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove a peer address from the whitelist.
|
|
|
|
* @param [in] address The address to remove from the whitelist.
|
|
|
|
* @returns true if successful.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-05-23 21:12:44 +02:00
|
|
|
bool NimBLEDevice::whiteListRemove(const NimBLEAddress & address) {
|
2024-07-05 03:17:13 +02:00
|
|
|
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<ble_addr_t*>(&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;
|
2021-05-23 21:12:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Gets the count of addresses in the whitelist.
|
|
|
|
* @returns The number of addresses in the whitelist.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-05-23 21:12:44 +02:00
|
|
|
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.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-05-23 21:12:44 +02:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Host reset, we pass the message so we don't make calls until resynced.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] reason The reason code for the reset.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::onReset(int reason)
|
2020-03-30 01:44:20 +02:00
|
|
|
{
|
|
|
|
if(!m_synced) {
|
|
|
|
return;
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
m_synced = false;
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2024-07-04 18:56:30 +02:00
|
|
|
NIMBLE_LOGE(LOG_TAG, "Resetting state; reason=%d, %s", reason,
|
2021-01-13 04:42:19 +01:00
|
|
|
NimBLEUtils::returnCodeToString(reason));
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2021-01-13 04:42:19 +01:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
|
|
|
if(initialized) {
|
|
|
|
if(m_pScan != nullptr) {
|
|
|
|
m_pScan->onHostReset();
|
|
|
|
}
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
} // onReset
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @brief Host resynced with controller, all clear to make calls to the stack.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::onSync(void)
|
2020-03-30 01:44:20 +02:00
|
|
|
{
|
|
|
|
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) {
|
|
|
|
return;
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/* Make sure we have proper identity address set (public preferred) */
|
|
|
|
int rc = ble_hs_util_ensure_addr(0);
|
2024-07-03 21:11:03 +02:00
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "error ensuring address; rc=%d", rc);
|
|
|
|
return;
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifndef ESP_PLATFORM
|
|
|
|
rc = ble_hs_id_infer_auto(m_own_addr_type, &m_own_addr_type);
|
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "error determining address type; rc=%d", rc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-07-31 19:00:12 +02:00
|
|
|
// Yield for housekeeping before returning to operations.
|
2021-01-12 21:59:49 +01:00
|
|
|
// Occasionally triggers exception without.
|
|
|
|
taskYIELD();
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
m_synced = true;
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-05-03 21:50:49 +02:00
|
|
|
if(initialized) {
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
2020-05-03 21:50:49 +02:00
|
|
|
if(m_pScan != nullptr) {
|
2021-01-13 04:42:19 +01:00
|
|
|
m_pScan->onHostSync();
|
2020-05-03 21:50:49 +02:00
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2020-05-03 21:50:49 +02:00
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
2020-05-03 21:50:49 +02:00
|
|
|
if(m_bleAdvertising != nullptr) {
|
2021-01-13 04:42:19 +01:00
|
|
|
m_bleAdvertising->onHostSync();
|
2020-05-03 21:50:49 +02:00
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
} // onSync
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The main host task.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::host_task(void *param)
|
2020-03-30 01:44:20 +02:00
|
|
|
{
|
|
|
|
NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started");
|
2021-12-29 16:08:25 +01:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/* This function will return only when nimble_port_stop() is executed */
|
|
|
|
nimble_port_run();
|
|
|
|
|
|
|
|
nimble_port_freertos_deinit();
|
|
|
|
} // host_task
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the %BLE environment.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] deviceName The device name of the device.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::init(const std::string &deviceName) {
|
2020-03-30 01:44:20 +02:00
|
|
|
if(!initialized){
|
|
|
|
int rc=0;
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
2020-03-30 01:44:20 +02:00
|
|
|
esp_err_t errRc = ESP_OK;
|
2021-08-03 20:43:34 +02:00
|
|
|
|
|
|
|
#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
|
2022-07-31 19:00:12 +02:00
|
|
|
// make sure the linker includes esp32-hal-bt.c so Arduino init doesn't release BLE memory.
|
2021-08-03 20:43:34 +02:00
|
|
|
btStarted();
|
|
|
|
#endif
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
errRc = nvs_flash_init();
|
2020-05-03 21:50:49 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
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_ERROR_CHECK(errRc);
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2024-06-13 22:44:14 +02:00
|
|
|
#if CONFIG_IDF_TARGET_ESP32
|
2021-02-01 05:15:31 +01:00
|
|
|
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
2024-06-13 22:44:14 +02:00
|
|
|
#endif
|
2021-02-01 05:15:31 +01:00
|
|
|
|
2024-06-13 22:44:14 +02:00
|
|
|
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) | !defined(CONFIG_NIMBLE_CPP_IDF)
|
2021-02-01 05:15:31 +01:00
|
|
|
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
2023-05-29 17:08:14 +02:00
|
|
|
# if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
2021-07-20 05:46:30 +02:00
|
|
|
bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE;
|
2023-05-29 17:08:14 +02:00
|
|
|
# else
|
2021-02-01 05:15:31 +01:00
|
|
|
bt_cfg.mode = ESP_BT_MODE_BLE;
|
|
|
|
bt_cfg.ble_max_conn = CONFIG_BT_NIMBLE_MAX_CONNECTIONS;
|
2023-05-29 17:08:14 +02:00
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
|
2021-02-01 05:15:31 +01:00
|
|
|
bt_cfg.normal_adv_size = m_scanDuplicateSize;
|
|
|
|
bt_cfg.scan_duplicate_type = m_scanFilterMode;
|
2023-05-29 17:08:14 +02:00
|
|
|
# endif
|
2021-02-01 05:15:31 +01:00
|
|
|
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());
|
2023-05-29 17:08:14 +02:00
|
|
|
# endif
|
2021-12-29 16:08:25 +01:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
nimble_port_init();
|
2020-05-14 06:03:56 +02:00
|
|
|
|
|
|
|
// Setup callbacks for host events
|
2020-03-30 01:44:20 +02:00
|
|
|
ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
|
|
|
|
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
// Set initial security capabilities
|
2020-05-14 06:03:56 +02:00
|
|
|
ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
|
2020-03-30 01:44:20 +02:00
|
|
|
ble_hs_cfg.sm_bonding = 0;
|
|
|
|
ble_hs_cfg.sm_mitm = 0;
|
|
|
|
ble_hs_cfg.sm_sc = 1;
|
2024-06-02 17:00:07 +02:00
|
|
|
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;
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
// Set the device name.
|
|
|
|
rc = ble_svc_gap_device_name_set(deviceName.c_str());
|
2024-07-03 21:11:03 +02:00
|
|
|
if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "ble_svc_gap_device_name_set() failed; rc=%d", rc);
|
|
|
|
}
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
ble_store_config_init();
|
2020-05-03 21:50:49 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
nimble_port_freertos_init(NimBLEDevice::host_task);
|
|
|
|
}
|
2021-12-29 16:08:25 +01:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
// Wait for host and controller to sync before returning and accepting new tasks
|
|
|
|
while(!m_synced){
|
2021-12-29 16:08:25 +01:00
|
|
|
taskYIELD();
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
2020-05-03 21:50:49 +02:00
|
|
|
|
|
|
|
initialized = true; // Set the initialization flag to ensure we are only initialized once.
|
2020-03-30 01:44:20 +02:00
|
|
|
} // init
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Shutdown the NimBLE stack/controller.
|
2020-07-29 04:57:33 +02:00
|
|
|
* @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.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
void NimBLEDevice::deinit(bool clearAll) {
|
2020-03-30 01:44:20 +02:00
|
|
|
int ret = nimble_port_stop();
|
|
|
|
if (ret == 0) {
|
|
|
|
nimble_port_deinit();
|
2024-06-13 22:44:14 +02:00
|
|
|
#ifdef CONFIG_NIMBLE_CPP_IDF
|
|
|
|
# if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
2020-03-30 01:44:20 +02:00
|
|
|
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);
|
|
|
|
}
|
2024-06-13 22:44:14 +02:00
|
|
|
# endif
|
2021-12-29 16:08:25 +01:00
|
|
|
#endif
|
2020-03-30 01:44:20 +02:00
|
|
|
initialized = false;
|
2020-05-03 21:50:49 +02:00
|
|
|
m_synced = false;
|
2020-07-29 04:57:33 +02:00
|
|
|
|
|
|
|
if(clearAll) {
|
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
|
|
|
if(NimBLEDevice::m_pServer != nullptr) {
|
|
|
|
delete NimBLEDevice::m_pServer;
|
|
|
|
NimBLEDevice::m_pServer = nullptr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
|
|
|
|
if(NimBLEDevice::m_bleAdvertising != nullptr) {
|
|
|
|
delete NimBLEDevice::m_bleAdvertising;
|
|
|
|
NimBLEDevice::m_bleAdvertising = nullptr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
|
|
|
if(NimBLEDevice::m_pScan != nullptr) {
|
|
|
|
delete NimBLEDevice::m_pScan;
|
|
|
|
NimBLEDevice::m_pScan= nullptr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
2024-07-04 20:03:03 +02:00
|
|
|
for(auto clt : m_pClients) {
|
|
|
|
deleteClient(clt);
|
2020-07-29 04:57:33 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
m_ignoreList.clear();
|
|
|
|
}
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
|
|
|
} // deinit
|
|
|
|
|
2022-07-22 01:33:21 +02:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Check if the initialization is complete.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @return true if initialized.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2020-03-30 01:44:20 +02:00
|
|
|
bool NimBLEDevice::getInitialized() {
|
|
|
|
return initialized;
|
|
|
|
} // getInitialized
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the authorization mode for this device.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param bonding If true we allow bonding, false no bonding will be performed.
|
|
|
|
* @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.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) {
|
2020-03-30 01:44:20 +02:00
|
|
|
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;
|
|
|
|
} // setSecurityAuth
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the authorization mode for this device.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param auth_req A bitmap indicating what modes are supported.\n
|
|
|
|
* The available bits are defined as:
|
|
|
|
* * 0x01 BLE_SM_PAIR_AUTHREQ_BOND
|
|
|
|
* * 0x04 BLE_SM_PAIR_AUTHREQ_MITM
|
|
|
|
* * 0x08 BLE_SM_PAIR_AUTHREQ_SC
|
|
|
|
* * 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported.
|
2020-05-14 06:03:56 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityAuth(uint8_t auth_req) {
|
2020-03-30 01:44:20 +02:00
|
|
|
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);
|
|
|
|
} // setSecurityAuth
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the Input/Output capabilities of this device.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param iocap One of the following values:
|
|
|
|
* * 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability
|
|
|
|
* * 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability
|
|
|
|
* * 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability
|
|
|
|
* * 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability
|
|
|
|
* * 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityIOCap(uint8_t iocap) {
|
2020-03-30 01:44:20 +02:00
|
|
|
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.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param init_key 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
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityInitKey(uint8_t init_key) {
|
2020-03-30 01:44:20 +02:00
|
|
|
ble_hs_cfg.sm_our_key_dist = init_key;
|
|
|
|
} // setsSecurityInitKey
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the keys we are willing to accept during pairing.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param resp_key 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
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityRespKey(uint8_t resp_key) {
|
2020-07-09 03:27:26 +02:00
|
|
|
ble_hs_cfg.sm_their_key_dist = resp_key;
|
2020-03-30 01:44:20 +02:00
|
|
|
} // setsSecurityRespKey
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @brief Set the passkey the server will ask for when pairing.
|
|
|
|
* @param [in] pin The passkey to use.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::setSecurityPasskey(uint32_t pin) {
|
2020-03-30 01:44:20 +02:00
|
|
|
m_passkey = pin;
|
|
|
|
} // setSecurityPasskey
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-09 03:27:26 +02:00
|
|
|
* @brief Get the current passkey used for pairing.
|
|
|
|
* @return The current passkey.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
uint32_t NimBLEDevice::getSecurityPasskey() {
|
2020-03-30 01:44:20 +02:00
|
|
|
return m_passkey;
|
|
|
|
} // getSecurityPasskey
|
|
|
|
|
|
|
|
|
2021-12-29 16:08:25 +01:00
|
|
|
#ifdef ESP_PLATFORM
|
2021-01-14 02:00:48 +01:00
|
|
|
/**
|
|
|
|
* @brief Set the own address type.
|
2021-01-16 05:51:49 +01:00
|
|
|
* @param [in] own_addr_type Own Bluetooth Device address type.\n
|
2021-01-14 02:00:48 +01:00
|
|
|
* 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
|
2021-01-16 05:51:49 +01:00
|
|
|
* @param [in] useNRPA If true, and address type is random, uses a non-resolvable random address.
|
2021-01-14 02:00:48 +01:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2021-01-14 02:00:48 +01:00
|
|
|
void NimBLEDevice::setOwnAddrType(uint8_t own_addr_type, bool useNRPA) {
|
|
|
|
m_own_addr_type = own_addr_type;
|
|
|
|
switch (own_addr_type) {
|
2021-07-20 05:46:30 +02:00
|
|
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
2021-01-14 02:00:48 +01:00
|
|
|
case BLE_OWN_ADDR_PUBLIC:
|
|
|
|
ble_hs_pvcy_rpa_config(NIMBLE_HOST_DISABLE_PRIVACY);
|
|
|
|
break;
|
2021-07-20 05:46:30 +02:00
|
|
|
#endif
|
2021-01-14 02:00:48 +01:00
|
|
|
case BLE_OWN_ADDR_RANDOM:
|
|
|
|
setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
|
2021-07-20 05:46:30 +02:00
|
|
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
2021-01-14 02:00:48 +01:00
|
|
|
ble_hs_pvcy_rpa_config(useNRPA ? NIMBLE_HOST_ENABLE_NRPA : NIMBLE_HOST_ENABLE_RPA);
|
2021-07-20 05:46:30 +02:00
|
|
|
#endif
|
2021-01-14 02:00:48 +01:00
|
|
|
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);
|
2021-07-20 05:46:30 +02:00
|
|
|
#ifdef CONFIG_IDF_TARGET_ESP32
|
2021-01-14 02:00:48 +01:00
|
|
|
ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA);
|
2021-07-20 05:46:30 +02:00
|
|
|
#endif
|
2021-01-14 02:00:48 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // setOwnAddrType
|
2021-12-29 16:08:25 +01:00
|
|
|
#endif
|
2021-01-14 02:00:48 +01:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Start the connection securing and authorization for this connection.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param conn_id The connection id of the peer device.
|
|
|
|
* @returns NimBLE stack return code, 0 = success.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/* STATIC */
|
|
|
|
int NimBLEDevice::startSecurity(uint16_t conn_id) {
|
2020-03-30 01:44:20 +02:00
|
|
|
int rc = ble_gap_security_initiate(conn_id);
|
|
|
|
if(rc != 0){
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
|
|
|
}
|
2020-05-14 06:03:56 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
return rc;
|
|
|
|
} // startSecurity
|
|
|
|
|
|
|
|
|
2024-06-07 03:36:14 +02:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
* @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);
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc);
|
|
|
|
return rc == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Check if the device address is on our ignore list.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] address The address to look for.
|
2020-03-30 01:44:20 +02:00
|
|
|
* @return True if ignoring.
|
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
bool NimBLEDevice::isIgnored(const NimBLEAddress &address) {
|
2020-03-30 01:44:20 +02:00
|
|
|
for(auto &it : m_ignoreList) {
|
|
|
|
if(it.equals(address)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add a device to the ignore list.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] address The address of the device we want to ignore.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::addIgnored(const NimBLEAddress &address) {
|
2020-03-30 01:44:20 +02:00
|
|
|
m_ignoreList.push_back(address);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove a device from the ignore list.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] address The address of the device we want to remove from the list.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
|
|
|
void NimBLEDevice::removeIgnored(const NimBLEAddress &address) {
|
2020-03-30 01:44:20 +02:00
|
|
|
for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) {
|
|
|
|
if((*it).equals(address)){
|
|
|
|
m_ignoreList.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set a custom callback for gap events.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] handler The function to call when gap events occur.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
2021-12-29 16:08:25 +01:00
|
|
|
/*STATIC*/
|
2020-03-30 01:44:20 +02:00
|
|
|
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){
|
|
|
|
NIMBLE_LOGI(LOG_TAG, "Already listening to GAP events.");
|
2024-07-03 21:11:03 +02:00
|
|
|
} else if (rc != 0) {
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "ble_gap_event_listener_register: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
2020-03-30 01:44:20 +02:00
|
|
|
}
|
2024-07-03 21:11:03 +02:00
|
|
|
|
2020-03-30 01:44:20 +02:00
|
|
|
} // setCustomGapHandler
|
|
|
|
|
2024-07-04 18:49:09 +02:00
|
|
|
#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) {
|
|
|
|
NIMBLE_LOGC("", "Assertion failed at %s:%u\n", file, line);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
#endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED
|
|
|
|
|
|
|
|
#endif // CONFIG_BT_ENABLED
|