From 7f9eef251cf8b95ae980b1dda2bb6483c5b8e65c Mon Sep 17 00:00:00 2001 From: shripad621git <79364691+shripad621git@users.noreply.github.com> Date: Sat, 8 Feb 2025 02:15:49 +0530 Subject: [PATCH] [ESP32] Fixed the bluedroid build issue in ESP32. (#34133) - Fixed the build issue due to missing bits in bluedroid BLEManagerImpl. - Added extended ble advertising support. --- .../ESP32/bluedroid/BLEManagerImpl.cpp | 131 +++++++++++++++--- 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp index e86f7dfd3cd805..277f384ec30b70 100644 --- a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp +++ b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp @@ -152,7 +152,6 @@ const uint16_t CHIPoBLEGATTAttrCount = sizeof(CHIPoBLEGATTAttrs) / sizeof(CHIPoB ChipDeviceScanner & mDeviceScanner = Internal::ChipDeviceScanner::GetInstance(); #endif BLEManagerImpl BLEManagerImpl::sInstance; -constexpr System::Clock::Timeout BLEManagerImpl::kFastAdvertiseTimeout; #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER static esp_gattc_char_elem_t * char_elem_result = NULL; static esp_gattc_descr_elem_t * descr_elem_result = NULL; @@ -235,6 +234,23 @@ CHIP_ERROR BLEManagerImpl::_Init() return err; } +void BLEManagerImpl::_Shutdown() +{ + CancelBleAdvTimeoutTimer(); + + BleLayer::Shutdown(); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + + // selectively setting kGATTServiceStarted flag, in order to notify the state machine to stop the CHIPoBLE gatt service + mFlags.ClearAll().Set(Flags::kGATTServiceStarted); + +#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER + OnChipBleConnectReceived = nullptr; +#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER + + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -243,8 +259,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); mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); @@ -254,21 +269,29 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) return err; } -void BLEManagerImpl::HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context) +void BLEManagerImpl::BleAdvTimeoutHandler(System::Layer *, void *) { - static_cast(context)->HandleFastAdvertisementTimer(); -} - -void BLEManagerImpl::HandleFastAdvertisementTimer() -{ - System::Clock::Timestamp currentTimestamp = System::SystemClock().GetMonotonicTimestamp(); - - if (currentTimestamp - mAdvertiseStartTime >= kFastAdvertiseTimeout) + 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 CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + BLEMgrImpl().mFlags.Clear(Flags::kExtAdvertisingEnabled); + BLEMgrImpl().StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS); +#endif + } +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + else { - mFlags.Clear(Flags::kFastAdvertisingEnabled); - mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + 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); } +#endif + PlatformMgr().ScheduleWork(DriveBLEState, 0); } CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) @@ -853,8 +876,8 @@ bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUU #endif // Set param need_confirm as false will send notification, otherwise indication. - err = MapBLEError( - esp_ble_gatts_send_indicate(mAppIf, conId, mTXCharAttrHandle, data->DataLength(), data->Start(), true /* need_confirm */)); + err = MapBLEError(esp_ble_gatts_send_indicate(mAppIf, conId, mTXCharAttrHandle, static_cast(data->DataLength()), + data->Start(), true /* need_confirm */)); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "esp_ble_gatts_send_indicate() failed: %s", ErrorStr(err)); @@ -936,6 +959,20 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) } } +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + SystemLayer().CancelTimer(BleAdvTimeoutHandler, nullptr); +} + +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + CHIP_ERROR err = SystemLayer().StartTimer(System::Clock::Milliseconds32(aTimeoutInMs), BleAdvTimeoutHandler, nullptr); + if ((err != CHIP_NO_ERROR)) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + void BLEManagerImpl::DriveBLEState(void) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1059,7 +1096,8 @@ void BLEManagerImpl::DriveBLEState(void) ExitNow(); } - mFlags.Set(Flags::kControlOpInProgress); + DeinitESPBleLayer(); + mFlags.ClearAll(); ExitNow(); } @@ -1162,6 +1200,23 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) return err; } +esp_err_t bluedroid_set_random_address() +{ + esp_bd_addr_t rand_addr; + + esp_fill_random(rand_addr, sizeof(esp_bd_addr_t)); + rand_addr[0] = (rand_addr[0] & 0x3F) | 0xC0; + + esp_err_t ret = esp_ble_gap_set_rand_addr(rand_addr); + if (ret != ESP_OK) + { + ChipLogError(DeviceLayer, "Failed to set random address: %s", esp_err_to_name(ret)); + return ret; + } + + return ESP_OK; +} + CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) { CHIP_ERROR err; @@ -1187,6 +1242,27 @@ 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 + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + deviceIdInfo.SetAdditionalDataFlag(true); + } + else + { + deviceIdInfo.SetAdditionalDataFlag(false); + } +#endif + memset(advData, 0, sizeof(advData)); advData[index++] = 0x02; // length advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags @@ -1216,12 +1292,16 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) ExitNow(); } + bluedroid_set_random_address(); mFlags.Set(Flags::kControlOpInProgress); exit: return err; } +// TODO(#36919): Fix the Bluedroid ShutDown flow for ESP32. +void BLEManagerImpl::DeinitESPBleLayer() {} + CHIP_ERROR BLEManagerImpl::StartAdvertising(void) { CHIP_ERROR err; @@ -1252,8 +1332,23 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) } else { +#if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + } + else + { + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN; + advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX; + } +#else + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + +#endif } ChipLogProgress(DeviceLayer, "Configuring CHIPoBLE advertising (interval %" PRIu32 " ms, %sconnectable, device name %s)",