From 692e9e126592b57b84049ddb3ae2d9cfc1cf9de0 Mon Sep 17 00:00:00 2001 From: SAYON DEEP Date: Wed, 17 Apr 2024 19:21:08 +0530 Subject: [PATCH] [ESP32] Enable extended ble announcement for esp32 platform (#32389) * enable extended ble advertisement for esp32 platform * changed extended advertisement to extended announcement * restlyed * made discoverty timeout range and default dependent on extended announcement. * help section for extended ble announcement * fixed eliding of extended data during extended announcement. * fixed setting of Additional data flag --- config/esp32/components/chip/Kconfig | 16 ++- src/platform/ESP32/BLEManagerImpl.h | 11 +- src/platform/ESP32/CHIPDevicePlatformConfig.h | 1 + src/platform/ESP32/nimble/BLEManagerImpl.cpp | 100 +++++++++++++++--- 4 files changed, 104 insertions(+), 24 deletions(-) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 1c0b5afe2bcb61..d176d6571ef205 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -1192,8 +1192,11 @@ menu "CHIP Device Layer" menu "Commissioning Window Options" config CHIP_DISCOVERY_TIMEOUT_SECS int "Commissioning Window Timeout in seconds" - range 180 900 - default 900 + range 180 900 if !ENABLE_BLE_EXT_ANNOUNCEMENT + range 901 172800 if ENABLE_BLE_EXT_ANNOUNCEMENT + default 900 if !ENABLE_BLE_EXT_ANNOUNCEMENT + default 172800 if ENABLE_BLE_EXT_ANNOUNCEMENT + help The amount of time (in seconds) after which the CHIP platform will close the Commissioning Window endmenu @@ -1216,4 +1219,13 @@ menu "CHIP Device Layer" endmenu + menu "Enable BLE Extended Announcement" + config ENABLE_BLE_EXT_ANNOUNCEMENT + bool "Enable BLE Extended Announcement" + default n + help + Enable BLE Extended Announcement.To be used with CHIP_DISCOVERY_TIMEOUT_SECS for extended announcement duration. + + endmenu + endmenu diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h index fc946c9aae3359..aa740295d03eed 100644 --- a/src/platform/ESP32/BLEManagerImpl.h +++ b/src/platform/ESP32/BLEManagerImpl.h @@ -234,6 +234,7 @@ class BLEManagerImpl final : public BLEManager, kFastAdvertisingEnabled = 0x0200, /**< The application has enabled fast advertising. */ kUseCustomDeviceName = 0x0400, /**< The application has configured a custom BLE device name. */ kAdvertisingRefreshNeeded = 0x0800, /**< The advertising configuration/state in ESP BLE layer needs to be updated. */ + kExtAdvertisingEnabled = 0x1000, /**< The application has enabled Extended BLE announcement. */ }; enum @@ -300,13 +301,9 @@ class BLEManagerImpl final : public BLEManager, CHIP_ERROR InitESPBleLayer(void); CHIP_ERROR ConfigureAdvertisingData(void); CHIP_ERROR StartAdvertising(void); - - static constexpr System::Clock::Timeout kFastAdvertiseTimeout = - System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); - System::Clock::Timestamp mAdvertiseStartTime; - - static void HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context); - void HandleFastAdvertisementTimer(); + void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); + void CancelBleAdvTimeoutTimer(void); + static void BleAdvTimeoutHandler(TimerHandle_t xTimer); #if CONFIG_BT_BLUEDROID_ENABLED void HandleGATTControlEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param); diff --git a/src/platform/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index ef6f850b36fb14..273fd562d60883 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -105,6 +105,7 @@ #define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS CONFIG_CHIP_DISCOVERY_TIMEOUT_SECS #define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE CONFIG_ENABLE_ESP32_BLE_CONTROLLER #define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART +#define CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING CONFIG_ENABLE_BLE_EXT_ANNOUNCEMENT // Options for background chip task #define CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING CONFIG_ENABLE_BG_EVENT_PROCESSING diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index 5092828d750f66..5407e9969b50e3 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -76,6 +76,7 @@ namespace Internal { namespace { +TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER static constexpr uint16_t kNewConnectionScanTimeout = 60; static constexpr uint16_t kConnectTimeout = 20; @@ -123,8 +124,6 @@ uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM; ChipDeviceScanner & mDeviceScanner = Internal::ChipDeviceScanner::GetInstance(); #endif BLEManagerImpl BLEManagerImpl::sInstance; -constexpr System::Clock::Timeout BLEManagerImpl::kFastAdvertiseTimeout; - const struct ble_gatt_svc_def BLEManagerImpl::CHIPoBLEGATTAttrs[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = (ble_uuid_t *) (&ShortUUID_CHIPoBLEService), @@ -221,6 +220,14 @@ CHIP_ERROR BLEManagerImpl::_Init() #endif SuccessOrExit(err); + // Create FreeRTOS sw timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel + 1, // == default timer period + false, // no timer reload (==one-shot) + (void *) this, // init timer id = ble obj context + BleAdvTimeoutHandler // timer callback handler + ); + mRXCharAttrHandle = 0; #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING mC3CharAttrHandle = 0; @@ -254,8 +261,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (val) { - mAdvertiseStartTime = System::SystemClock().GetMonotonicTimestamp(); - ReturnErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); } mFlags.Set(Flags::kFastAdvertisingEnabled, val); @@ -267,21 +273,31 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) return err; } -void BLEManagerImpl::HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context) -{ - static_cast(context)->HandleFastAdvertisementTimer(); -} - -void BLEManagerImpl::HandleFastAdvertisementTimer() +void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) { - System::Clock::Timestamp currentTimestamp = System::SystemClock().GetMonotonicTimestamp(); + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + ChipLogProgress(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); + BLEMgrImpl().mFlags.Set(Flags::kFastAdvertisingEnabled, 0); + BLEMgrImpl().mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); - if (currentTimestamp - mAdvertiseStartTime >= kFastAdvertiseTimeout) +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + BLEMgrImpl().mFlags.Clear(Flags::kExtAdvertisingEnabled); + BLEMgrImpl().StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS); +#endif + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + else { - mFlags.Set(Flags::kFastAdvertisingEnabled, 0); - mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); + ChipLogProgress(DeviceLayer, "bleAdv Timeout : Start extended advertisement"); + BLEMgrImpl().mFlags.Set(Flags::kAdvertising); + BLEMgrImpl().mFlags.Set(Flags::kExtAdvertisingEnabled); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + BLEMgrImpl().mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); PlatformMgr().ScheduleWork(DriveBLEState, 0); } +#endif } CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) @@ -690,6 +706,28 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) return CHIP_ERROR(ChipError::Range::kPlatform, CHIP_DEVICE_CONFIG_ESP32_BLE_ERROR_MIN + bleErr); } } +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + if (xTimerStop(sbleAdvTimeoutTimer, pdMS_TO_TICKS(0)) == pdFAIL) + { + ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + } +} +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) + { + CancelBleAdvTimeoutTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs), pdMS_TO_TICKS(100)) != pdPASS) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} void BLEManagerImpl::DriveBLEState(void) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -977,8 +1015,25 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) ExitNow(); } +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + // Check for extended advertisement interval and redact VID/PID if past the initial period. + if (mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + deviceIdInfo.SetVendorId(0); + deviceIdInfo.SetProductId(0); + deviceIdInfo.SetExtendedAnnouncementFlag(true); + } +#endif + #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - deviceIdInfo.SetAdditionalDataFlag(true); + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + deviceIdInfo.SetAdditionalDataFlag(true); + } + else + { + deviceIdInfo.SetAdditionalDataFlag(false); + } #endif VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(advData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG); @@ -1565,8 +1620,23 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) } else { +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + adv_params.itvl_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + adv_params.itvl_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + } + else + { + adv_params.itvl_min = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN; + adv_params.itvl_max = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX; + } +#else + adv_params.itvl_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; adv_params.itvl_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + +#endif } ChipLogProgress(DeviceLayer, "Configuring CHIPoBLE advertising (interval %" PRIu32 " ms, %sconnectable)",