Add Scan duplicate cache reset time feature.

Adds the ability to set a time for the scan duplicate filter cache to reset which will start reporting devices previously seen again.
This commit is contained in:
h2zero
2025-05-08 11:32:13 -06:00
parent e29d1ce3cf
commit e615deb1af
3 changed files with 73 additions and 8 deletions

View File

@ -66,7 +66,7 @@
# if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
# include "NimBLEServer.h"
# if CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM > 0
# include "NimBLEL2CAPServer.h"
# include "NimBLEL2CAPServer.h"
# endif
# endif
@ -113,9 +113,18 @@ std::vector<NimBLEAddress> NimBLEDevice::m_whiteList{};
uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC};
# ifdef ESP_PLATFORM
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
# if 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_scanDuplicateResetTime{0};
# elif CONFIG_BT_LE_SCAN_DUPL
uint16_t NimBLEDevice::m_scanDuplicateSize{CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT};
uint8_t NimBLEDevice::m_scanFilterMode{CONFIG_BT_LE_SCAN_DUPL_TYPE};
uint16_t NimBLEDevice::m_scanDuplicateResetTime{0};
extern "C" int ble_vhci_disc_duplicate_set_max_cache_size(int max_cache_size);
extern "C" int ble_vhci_disc_duplicate_set_period_refresh_time(int refresh_period_time);
extern "C" int ble_vhci_disc_duplicate_mode_disable(int mode);
extern "C" int ble_vhci_disc_duplicate_mode_enable(int mode);
# endif
# endif
@ -258,7 +267,7 @@ NimBLEScan* NimBLEDevice::getScan() {
} // getScan
# ifdef ESP_PLATFORM
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
# if CONFIG_BTDM_BLE_SCAN_DUPL || CONFIG_BT_LE_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
@ -305,7 +314,26 @@ void NimBLEDevice::setScanFilterMode(uint8_t mode) {
m_scanFilterMode = mode;
}
# endif // CONFIG_BTDM_BLE_SCAN_DUPL
/**
* @brief Set the time in seconds to reset the duplicate cache.
* @param [in] time The time in seconds to reset the cache.
* @details When the cache is reset all scanned devices will be reported again
* even if already seen in the current scan. If set to 0 the cache will never be reset.
*/
void NimBLEDevice::setScanDuplicateCacheResetTime(uint16_t time) {
if (m_initialized) {
NIMBLE_LOGE(LOG_TAG, "Cannot change scan cache reset time while initialized");
return;
} else if (time > 1000) {
NIMBLE_LOGE(LOG_TAG, "Invalid scan cache reset time");
return;
}
NIMBLE_LOGD(LOG_TAG, "Set duplicate cache reset time to: %u", time);
m_scanDuplicateResetTime = time;
}
# endif // CONFIG_BTDM_BLE_SCAN_DUPL || CONFIG_BT_LE_SCAN_DUPL
# endif // ESP_PLATFORM
# endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
@ -900,9 +928,13 @@ bool NimBLEDevice::init(const std::string& deviceName) {
bt_cfg.nimble_max_connections = CONFIG_BT_NIMBLE_MAX_CONNECTIONS;
# endif
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
bt_cfg.normal_adv_size = m_scanDuplicateSize;
bt_cfg.scan_duplicate_type = m_scanFilterMode;
# if CONFIG_BTDM_BLE_SCAN_DUPL
bt_cfg.normal_adv_size = m_scanDuplicateSize;
bt_cfg.scan_duplicate_type = m_scanFilterMode;
bt_cfg.dup_list_refresh_period = m_scanDuplicateResetTime;
# elif CONFIG_BT_LE_SCAN_DUPL
bt_cfg.ble_ll_rsp_dup_list_count = m_scanDuplicateSize;
bt_cfg.ble_ll_adv_dup_list_count = m_scanDuplicateSize;
# endif
err = esp_bt_controller_init(&bt_cfg);
if (err != ESP_OK) {
@ -910,6 +942,25 @@ bool NimBLEDevice::init(const std::string& deviceName) {
return false;
}
# if CONFIG_BT_LE_SCAN_DUPL
int mode = (1UL << 4); // FILTER_DUPLICATE_EXCEPTION_FOR_MESH
switch (m_scanFilterMode) {
case 1:
mode |= (1UL << 3); // FILTER_DUPLICATE_ADVDATA
break;
case 2:
mode |= ((1UL << 2) | (1UL << 3)); // FILTER_DUPLICATE_ADDRESS | FILTER_DUPLICATE_ADVDATA
break;
default:
mode |= (1UL << 0) | (1UL << 2); // FILTER_DUPLICATE_PDUTYPE | FILTER_DUPLICATE_ADDRESS
}
ble_vhci_disc_duplicate_mode_disable(0xFFFFFFFF);
ble_vhci_disc_duplicate_mode_enable(mode);
ble_vhci_disc_duplicate_set_max_cache_size(m_scanDuplicateSize);
ble_vhci_disc_duplicate_set_period_refresh_time(m_scanDuplicateResetTime);
# endif
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);

View File

@ -138,6 +138,7 @@ class NimBLEDevice {
static void setDeviceCallbacks(NimBLEDeviceCallbacks* cb);
static void setScanDuplicateCacheSize(uint16_t cacheSize);
static void setScanFilterMode(uint8_t type);
static void setScanDuplicateCacheResetTime(uint16_t time);
static bool setCustomGapHandler(gap_event_handler handler);
static void setSecurityAuth(bool bonding, bool mitm, bool sc);
static void setSecurityAuth(uint8_t auth);
@ -248,9 +249,10 @@ class NimBLEDevice {
# endif
# ifdef ESP_PLATFORM
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
# if CONFIG_BTDM_BLE_SCAN_DUPL || CONFIG_BT_LE_SCAN_DUPL
static uint16_t m_scanDuplicateSize;
static uint8_t m_scanFilterMode;
static uint16_t m_scanDuplicateResetTime;
# endif
# endif

View File

@ -79,3 +79,15 @@
#if !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE) && defined(CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE)
#define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE
#endif
#ifdef CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
#define CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY
#endif
#ifdef CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY
#define CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_2M_PHY CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY
#endif
#ifdef CONFIG_BT_LE_50_FEATURE_SUPPORT
#define CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT CONFIG_BT_LE_50_FEATURE_SUPPORT
#endif