diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index b39105d1285fac..4a2c06eb43ffe9 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -1176,8 +1176,8 @@ 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 172800 + default 900 help The amount of time (in seconds) after which the CHIP platform will close the Commissioning Window endmenu @@ -1200,4 +1200,13 @@ menu "CHIP Device Layer" endmenu + menu "Enable BLE Extended Advertisement" + config ENABLE_BLE_EXT_ADVERTISING + bool "Enable BLE Extended Advertisement" + default n + help + Enable BLE Extended Advertisement. + + endmenu + endmenu diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h index 5cb1421750786a..956d4cf3a5316c 100644 --- a/src/platform/ESP32/BLEManagerImpl.h +++ b/src/platform/ESP32/BLEManagerImpl.h @@ -232,6 +232,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 advertising. */ }; enum @@ -298,13 +299,10 @@ class BLEManagerImpl final : public BLEManager, CHIP_ERROR InitESPBleLayer(void); CHIP_ERROR ConfigureAdvertisingData(void); CHIP_ERROR StartAdvertising(void); + void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); + void CancelBleAdvTimeoutTimer(void); + static void BleAdvTimeoutHandler(TimerHandle_t xTimer); - 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(); #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 f0f28408a3ce12..b91243150ed815 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -106,6 +106,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_ADVERTISING // 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 877f49e5fb006c..fb797b77ec7ff7 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -67,6 +67,7 @@ #define CHIP_ADV_DATA_FLAGS 0x06 #define CHIP_ADV_DATA_TYPE_SERVICE_DATA 0x16 + using namespace ::chip; using namespace ::chip::Ble; @@ -76,6 +77,9 @@ 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 +127,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 +223,15 @@ 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 + // pdMS_TO_TICKS(50), + 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 +265,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 +277,32 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) return err; } -void BLEManagerImpl::HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context) +void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) { - static_cast(context)->HandleFastAdvertisementTimer(); -} + 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); -void BLEManagerImpl::HandleFastAdvertisementTimer() -{ - System::Clock::Timestamp currentTimestamp = System::SystemClock().GetMonotonicTimestamp(); +#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 (currentTimestamp - mAdvertiseStartTime >= kFastAdvertiseTimeout) + } +#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 +711,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,6 +1020,16 @@ 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); #endif @@ -1565,8 +1618,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)",