Skip to content

Commit

Permalink
Fixed the bluedroid build issue in ESP32
Browse files Browse the repository at this point in the history
- Fixed the build issue with bluedroid.
- Added extended ble advertising support.
- Implemented the missing bluedroid shutdown flow
  • Loading branch information
shripad621git committed Jun 28, 2024
1 parent ee49ebd commit fb343cb
Showing 1 changed file with 173 additions and 18 deletions.
191 changes: 173 additions & 18 deletions src/platform/ESP32/bluedroid/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ const uint16_t CHIPoBLEGATTAttrCount = sizeof(CHIPoBLEGATTAttrs) / sizeof(CHIPoB
ChipDeviceScanner & mDeviceScanner = Internal::ChipDeviceScanner::GetInstance();
#endif
BLEManagerImpl BLEManagerImpl::sInstance;
constexpr System::Clock::Timeout BLEManagerImpl::kFastAdvertiseTimeout;
#ifdef 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;
Expand Down Expand Up @@ -228,6 +227,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;
Expand All @@ -236,8 +252,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);
Expand All @@ -247,21 +262,29 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val)
return err;
}

void BLEManagerImpl::HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context)
{
static_cast<BLEManagerImpl *>(context)->HandleFastAdvertisementTimer();
}

void BLEManagerImpl::HandleFastAdvertisementTimer()
void BLEManagerImpl::BleAdvTimeoutHandler(System::Layer *, void *)
{
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)
Expand Down Expand Up @@ -841,8 +864,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<uint16_t>(data->DataLength()),
data->Start(), true /* need_confirm */));
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "esp_ble_gatts_send_indicate() failed: %s", ErrorStr(err));
Expand Down Expand Up @@ -910,6 +933,25 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr)
}
}

void BLEManagerImpl::CancelBleAdvTimeoutTimer(void)
{
if (SystemLayer().IsTimerActive(BleAdvTimeoutHandler, nullptr))
{
SystemLayer().CancelTimer(BleAdvTimeoutHandler, nullptr);
}
}

void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs)
{
CancelBleAdvTimeoutTimer();

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;
Expand Down Expand Up @@ -1033,7 +1075,8 @@ void BLEManagerImpl::DriveBLEState(void)
ExitNow();
}

mFlags.Set(Flags::kControlOpInProgress);
DeinitESPBleLayer();
mFlags.ClearAll();

ExitNow();
}
Expand Down Expand Up @@ -1136,6 +1179,25 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void)
return err;
}

#ifndef CONFIG_IDF_TARGET_ESP32
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;
}
#endif

CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
{
CHIP_ERROR err;
Expand All @@ -1161,6 +1223,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
Expand Down Expand Up @@ -1190,12 +1273,69 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
ExitNow();
}

#ifndef CONFIG_IDF_TARGET_ESP32
bluedroid_set_random_address();
#endif

mFlags.Set(Flags::kControlOpInProgress);

exit:
return err;
}

// TODO: Fix the ShutDown flow
void BLEManagerImpl::DeinitESPBleLayer()
{
esp_err_t err;

err = esp_ble_gatts_app_unregister(mAppIf);
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "Unregister failed: %d", err);
return;
}

err = esp_bluedroid_disable();
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_bluedroid_disable() failed: %d", err);
return;
}

err = esp_bluedroid_deinit();
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_bluedroid_deinit() failed: %d", err);
return;
}

err = esp_bt_controller_disable();
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_bt_controller_disable() failed: %d", err);
return;
}

err = esp_bt_controller_deinit();
if (err != ESP_OK)
{
ChipLogError(DeviceLayer, "esp_bt_controller_deinit() failed: %d", err);
return;
}

#ifdef CONFIG_IDF_TARGET_ESP32
VerifyOrReturn(ESP_OK == esp_bt_mem_release(ESP_BT_MODE_BTDM), ChipLogError(DeviceLayer, "Failed to release bt memory"));
#elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || \
defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6)
VerifyOrReturn(ESP_OK == esp_bt_mem_release(ESP_BT_MODE_BLE), ChipLogError(DeviceLayer, "Failed to release bt memory"));
#endif
ChipLogProgress(DeviceLayer, "BLE memory reclaimed");

ChipDeviceEvent event;
event.Type = DeviceEventType::kBLEDeinitialized;
VerifyOrDo(CHIP_NO_ERROR == PlatformMgr().PostEvent(&event), ChipLogError(DeviceLayer, "Failed to post BLE deinit event"));
}

CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
{
CHIP_ERROR err;
Expand Down Expand Up @@ -1226,8 +1366,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)",
Expand Down

0 comments on commit fb343cb

Please sign in to comment.