diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index f34a522..c810e3a 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -62,6 +62,8 @@ std::list NimBLEDevice::m_cList; std::list NimBLEDevice::m_ignoreList; NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr; uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC; +uint16_t NimBLEDevice::m_scanDuplicateSize = CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE; +uint8_t NimBLEDevice::m_scanFilterMode = CONFIG_BTDM_SCAN_DUPL_TYPE; /** @@ -400,6 +402,53 @@ void NimBLEDevice::stopAdvertising() { } +/** + * @brief Set the duplicate filter mode 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; +} + + /** * @brief Host reset, we pass the message so we don't make calls until resynced. * @param [in] reason The reason code for the reset. @@ -499,8 +548,17 @@ void NimBLEDevice::stopAdvertising() { ESP_ERROR_CHECK(errRc); - ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + bt_cfg.mode = ESP_BT_MODE_BLE; + bt_cfg.ble_max_conn = CONFIG_BT_NIMBLE_MAX_CONNECTIONS; + bt_cfg.normal_adv_size = m_scanDuplicateSize; + bt_cfg.scan_duplicate_type = m_scanFilterMode; + + 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()); nimble_port_init(); // Setup callbacks for host events diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 2d586bb..27549ed 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -123,6 +123,8 @@ public: static bool isIgnored(const NimBLEAddress &address); static void addIgnored(const NimBLEAddress &address); static void removeIgnored(const NimBLEAddress &address); + static void setScanDuplicateCacheSize(uint16_t cacheSize); + static void setScanFilterMode(uint8_t type); #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) static NimBLEAdvertising* getAdvertising(); @@ -184,6 +186,8 @@ private: static ble_gap_event_listener m_listener; static gap_event_handler m_customGapHandler; static uint8_t m_own_addr_type; + static uint16_t m_scanDuplicateSize; + static uint8_t m_scanFilterMode; }; diff --git a/src/nimconfig.h b/src/nimconfig.h index d90921f..451b199 100644 --- a/src/nimconfig.h +++ b/src/nimconfig.h @@ -1,241 +1,93 @@ -/** @file - * +/** @file + * * IGNORE THIS FILE IF USING ESP-IDF, USE MENUCONFIG TO SET NIMBLE OPTIONS. * - * The config options here are for Arduino use only. + * The config options here are for doxygen documentation only. */ - + #pragma once #include "sdkconfig.h" - -/* - * For ESP-IDF compatibility - * Some versions of ESP-IDF used the config name format "CONFIG_NIMBLE_". - * This converts them to "CONFIG_BT_NIMBLE_" format used in the latest IDF. - */ - -/* Detect if using ESP-IDF or Arduino (Arduino won't have these defines in sdkconfig) - * - * Note: We do not use #ifdef CONFIG_BT_NIMBLE_ENABLED since we cannot enable NimBLE when using - * Arduino as a component and the esp-nimble-compnent, so we check if other config options are defined. - * We also need to use a config parameter that must be present and not likely defined in the command line. - */ -#if defined(CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN) || defined(CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN) - -#if defined(CONFIG_NIMBLE_ENABLED) && !defined(CONFIG_BT_NIMBLE_ENABLED) -#define CONFIG_BT_NIMBLE_ENABLED -#endif - -#if defined(CONFIG_NIMBLE_ROLE_OBSERVER) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) -#define CONFIG_BT_NIMBLE_ROLE_OBSERVER -#endif - -#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER -#endif - -#if defined(CONFIG_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) -#define CONFIG_BT_NIMBLE_ROLE_CENTRAL -#endif - -#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL -#endif - -#if defined(CONFIG_NIMBLE_DEBUG) && !defined(CONFIG_BT_NIMBLE_DEBUG) -#define CONFIG_BT_NIMBLE_DEBUG -#endif - -#else // Using Arduino - -/*********************************************** - * Arduino config options start here - **********************************************/ - -/** @brief Comment out if not using NimBLE Client functions \n - * Reduces flash size by approx. 7kB. - */ -#ifndef CONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED -#define CONFIG_BT_NIMBLE_ROLE_CENTRAL -#endif - -/** @brief Comment out if not using NimBLE Scan functions \n - * Reduces flash size by approx. 26kB. - */ -#ifndef CONFIG_BT_NIMBLE_ROLE_OBSERVER_DISABLED -#define CONFIG_BT_NIMBLE_ROLE_OBSERVER -#endif - -/** @brief Comment out if not using NimBLE Server functions \n - * Reduces flash size by approx. 16kB. - */ -#ifndef CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED -#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL -#endif - -/** @brief Comment out if not using NimBLE Advertising functions \n - * Reduces flash size by approx. 5kB. - */ -#ifndef CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED -#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER -#endif - -/* Uncomment to see debug log messages from the NimBLE host - * Uses approx. 32kB of flash memory. - */ -// #define CONFIG_BT_NIMBLE_DEBUG - -/* Uncomment to see NimBLE host return codes as text debug log messages. - * Uses approx. 7kB of flash memory. - */ -// #define CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT - -/* Uncomment to see GAP event codes as text in debug log messages. - * Uses approx. 1kB of flash memory. - */ -// #define CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT - -/* Uncomment to see advertisment types as text while scanning in debug log messages. - * Uses approx. 250 bytes of flash memory. - */ -// #define CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT - -/** @brief Sets the core NimBLE host runs on */ -#ifndef CONFIG_BT_NIMBLE_PINNED_TO_CORE -#define CONFIG_BT_NIMBLE_PINNED_TO_CORE 0 -#endif - -/** @brief Sets the stack size for the NimBLE host task */ -#ifndef CONFIG_BT_NIMBLE_TASK_STACK_SIZE -#define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096 -#endif - -/** - * @brief Sets the memory pool where NimBLE will be loaded - * @details By default NimBLE is loaded in internal ram.\n - * To use external PSRAM you must change this to `#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL 1` - */ -#ifndef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL -#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL 1 -#endif - -/** @brief Sets the number of simultaneous connections (esp controller max is 9) */ -#ifndef CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3 -#endif - -/** @brief Sets the number of devices allowed to store/bond with */ -#ifndef CONFIG_BT_NIMBLE_MAX_BONDS -#define CONFIG_BT_NIMBLE_MAX_BONDS 3 -#endif - -/** @brief Sets the maximum number of CCCD subscriptions to store */ -#ifndef CONFIG_BT_NIMBLE_MAX_CCCDS -#define CONFIG_BT_NIMBLE_MAX_CCCDS 8 -#endif - -/** @brief Default device name */ -#ifndef CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME -#define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME "nimble" -#endif - -/** @brief Set if CCCD's and bond data should be stored in NVS */ -#define CONFIG_BT_NIMBLE_NVS_PERSIST 1 - -/** @brief Allow legacy paring */ -#define CONFIG_BT_NIMBLE_SM_LEGACY 1 - -/** @brief Allow BLE secure connections */ -#define CONFIG_BT_NIMBLE_SM_SC 1 - -/** @brief Max device name length (bytes) */ -#define CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN 31 - -/** @brief Default MTU size */ -#define CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU 256 - -/** @brief Default GAP appearance */ -#define CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE 0x0 - -/** @brief ACL Buffer count */ -#define CONFIG_BT_NIMBLE_ACL_BUF_COUNT 12 - -/** @brief ACL Buffer size */ -#define CONFIG_BT_NIMBLE_ACL_BUF_SIZE 255 - -/** @brief HCI Event Buffer size */ -#define CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE 70 - -/** @brief Number of high priority HCI event buffers */ -#define CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT 30 - -/** @brief Number of low priority HCI event buffers */ -#define CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT 8 - -/** - * @brief Sets the number of MSYS buffers available. - * @details MSYS is a system level mbuf registry. For prepare write & prepare \n - * responses MBUFs are allocated out of msys_1 pool. This may need to be increased if\n - * you are sending large blocks of data with a low MTU. E.g: 512 bytes with 23 MTU will fail. - */ -#define CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT 12 - -/** @brief Random address refresh time in seconds */ -#define CONFIG_BT_NIMBLE_RPA_TIMEOUT 900 - -/** @brief Maximum number of connection oriented channels */ -#define CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM 0 - -/* These should not be altered */ -#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL 1 -#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL 1000 -#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH 2 -#define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT 1 - -#ifndef CONFIG_BT_ENABLED -#define CONFIG_BT_ENABLED -#endif - -#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY - -#endif // #if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE) - -/********************************** - End Arduino config -**********************************/ - - -/* Cannot use client without scan */ -#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) -#define CONFIG_BT_NIMBLE_ROLE_OBSERVER -#endif - -/* Cannot use server without advertise */ -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER -#endif - - +#include "nimconfig_rename.h" #ifdef _DOXYGEN_ -/** @brief Uncomment to see debug log messages from the NimBLE host \n + +/** @brief Un-comment to change the number of simultaneous connections (esp controller max is 9) */ +#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3 + +/** @brief Un-comment to change the default MTU size */ +#define CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU 255 + +/** @brief Un-comment to change default device name */ +#define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME "nimble" + +/** @brief Un-comment to see debug log messages from the NimBLE host * Uses approx. 32kB of flash memory. */ #define CONFIG_BT_NIMBLE_DEBUG -/** @brief Uncomment to see NimBLE host return codes as text debug log messages. \n +/** @brief Un-comment to see NimBLE host return codes as text debug log messages. * Uses approx. 7kB of flash memory. */ #define CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT -/** @brief Uncomment to see GAP event codes as text in debug log messages. \n +/** @brief Un-comment to see GAP event codes as text in debug log messages. * Uses approx. 1kB of flash memory. */ #define CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT -/** @brief Uncomment to see advertisment types as text while scanning in debug log messages. \n +/** @brief Un-comment to see advertisment types as text while scanning in debug log messages. * Uses approx. 250 bytes of flash memory. */ #define CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT + +/** @brief Un-comment to change the default GAP appearance */ +#define CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE 0x0 + + /** @brief Un-comment if not using NimBLE Client functions \n + * Reduces flash size by approx. 7kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED + +/** @brief Un-comment if not using NimBLE Scan functions \n + * Reduces flash size by approx. 26kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_OBSERVER_DISABLED + +/** @brief Un-comment if not using NimBLE Server functions \n + * Reduces flash size by approx. 16kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED + +/** @brief Un-comment if not using NimBLE Advertising functions \n + * Reduces flash size by approx. 5kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED + +/** @brief Un-comment to change the number of devices allowed to store/bond with */ +#define CONFIG_BT_NIMBLE_MAX_BONDS 3 + +/** @brief Un-comment to change the maximum number of CCCD subscriptions to store */ +#define CONFIG_BT_NIMBLE_MAX_CCCDS 8 + +/** @brief Un-comment to change the random address refresh time (in seconds) */ +#define CONFIG_BT_NIMBLE_RPA_TIMEOUT 900 + +/** + * @brief Un-comment to change the number of MSYS buffers available. + * @details MSYS is a system level mbuf registry. For prepare write & prepare \n + * responses MBUFs are allocated out of msys_1 pool. This may need to be increased if\n + * you are sending large blocks of data with a low MTU. E.g: 512 bytes with 23 MTU will fail. + */ +#define CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT 12 + +/** @brief Un-comment to use external PSRAM for the NimBLE host */ +#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL 1 + +/** @brief Un-comment to change the core NimBLE host runs on */ +#define CONFIG_BT_NIMBLE_PINNED_TO_CORE 0 + +/** @brief Un-comment to change the stack size for the NimBLE host task */ +#define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096 + #endif // _DOXYGEN_ diff --git a/src/nimconfig_rename.h b/src/nimconfig_rename.h new file mode 100644 index 0000000..3b96c1f --- /dev/null +++ b/src/nimconfig_rename.h @@ -0,0 +1,53 @@ +/* + * For ESP-IDF compatibility + * Some versions of ESP-IDF used the config name format "CONFIG_NIMBLE_". + * This converts them to "CONFIG_BT_NIMBLE_" format used in the latest IDF. + */ + +#if defined(CONFIG_NIMBLE_ENABLED) && !defined(CONFIG_BT_NIMBLE_ENABLED) +#define CONFIG_BT_NIMBLE_ENABLED +#endif + +#if defined(CONFIG_NIMBLE_ROLE_OBSERVER) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +#define CONFIG_BT_NIMBLE_ROLE_OBSERVER +#endif + +#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER +#endif + +#if defined(CONFIG_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#define CONFIG_BT_NIMBLE_ROLE_CENTRAL +#endif + +#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL +#endif + +#if defined(CONFIG_NIMBLE_DEBUG) && !defined(CONFIG_BT_NIMBLE_DEBUG) +#define CONFIG_BT_NIMBLE_DEBUG +#endif + +#if defined(CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE) +#define CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR +#endif + +#if defined(CONFIG_SCAN_DUPLICATE_BY_ADV_DATA ) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA) +#define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA CONFIG_SCAN_DUPLICATE_BY_ADV_DATA +#endif + +#if defined(CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE) +#define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR +#endif + +#if defined(CONFIG_SCAN_DUPLICATE_TYPE) && !defined(CONFIG_BTDM_SCAN_DUPL_TYPE) +#define CONFIG_BTDM_SCAN_DUPL_TYPE CONFIG_SCAN_DUPLICATE_TYPE +#endif + +#if defined(CONFIG_DUPLICATE_SCAN_CACHE_SIZE) && !defined(CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE) +#define CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE +#endif + +#if defined(CONFIG_NIMBLE_MAX_CONNECTIONS ) && !defined(CONFIG_BT_NIMBLE_MAX_CONNECTIONS) +#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS +#endif