From 31807370432abfc33f94347a3e4a33aa4b570352 Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 8 May 2025 10:51:26 -0600 Subject: [PATCH 1/2] Fix Coded phy scanning and scan filtering for esp h2/c6/c5/c2 --- src/NimBLEDevice.cpp | 36 ++++++++++++++++++++++++++++++++---- src/NimBLEDevice.h | 2 +- src/nimconfig_rename.h | 12 ++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 95343ea1..7674f154 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -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,16 @@ std::vector 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}; +# 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}; +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 +265,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 @@ -900,9 +907,12 @@ bool NimBLEDevice::init(const std::string& deviceName) { bt_cfg.nimble_max_connections = CONFIG_BT_NIMBLE_MAX_CONNECTIONS; # endif -# ifdef CONFIG_BTDM_BLE_SCAN_DUPL +# if CONFIG_BTDM_BLE_SCAN_DUPL bt_cfg.normal_adv_size = m_scanDuplicateSize; bt_cfg.scan_duplicate_type = m_scanFilterMode; +# 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 +920,24 @@ 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); +# 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); diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index a0f2f16e..6b32630a 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -248,7 +248,7 @@ 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; # endif diff --git a/src/nimconfig_rename.h b/src/nimconfig_rename.h index c32cd42f..ff2ad67d 100644 --- a/src/nimconfig_rename.h +++ b/src/nimconfig_rename.h @@ -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 From 112085f9228deb79ecd2e662196ef7ade8775eac Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 8 May 2025 11:32:13 -0600 Subject: [PATCH 2/2] 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. --- src/NimBLEDevice.cpp | 33 ++++++++++++++++++++++++++++----- src/NimBLEDevice.h | 2 ++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 7674f154..f017d387 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -116,9 +116,11 @@ uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC}; # 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_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); @@ -312,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) @@ -908,8 +929,9 @@ bool NimBLEDevice::init(const std::string& deviceName) { # endif # if CONFIG_BTDM_BLE_SCAN_DUPL - bt_cfg.normal_adv_size = m_scanDuplicateSize; - bt_cfg.scan_duplicate_type = m_scanFilterMode; + 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; @@ -936,6 +958,7 @@ bool NimBLEDevice::init(const std::string& deviceName) { 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); diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 6b32630a..4333d07f 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -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); @@ -251,6 +252,7 @@ class NimBLEDevice { # 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