@@ -212,14 +212,6 @@ CHIP_ERROR BLEManagerImpl::_Init()
212
212
{
213
213
CHIP_ERROR err;
214
214
215
- // Initialize the Chip BleLayer.
216
- #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER
217
- err = BleLayer::Init (this , this , this , &DeviceLayer::SystemLayer ());
218
- #else
219
- err = BleLayer::Init (this , this , &DeviceLayer::SystemLayer ());
220
- #endif
221
- SuccessOrExit (err);
222
-
223
215
// Create FreeRTOS sw timer for BLE timeouts and interval change.
224
216
sbleAdvTimeoutTimer = xTimerCreate (" BleAdvTimer" , // Just a text name, not used by the RTOS kernel
225
217
1 , // == default timer period
@@ -228,6 +220,16 @@ CHIP_ERROR BLEManagerImpl::_Init()
228
220
BleAdvTimeoutHandler // timer callback handler
229
221
);
230
222
223
+ VerifyOrReturnError (sbleAdvTimeoutTimer != nullptr , CHIP_ERROR_NO_MEMORY);
224
+
225
+ // Initialize the Chip BleLayer.
226
+ #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER
227
+ err = BleLayer::Init (this , this , this , &DeviceLayer::SystemLayer ());
228
+ #else
229
+ err = BleLayer::Init (this , this , &DeviceLayer::SystemLayer ());
230
+ #endif
231
+ SuccessOrExit (err);
232
+
231
233
mRXCharAttrHandle = 0 ;
232
234
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
233
235
mC3CharAttrHandle = 0 ;
@@ -253,6 +255,25 @@ CHIP_ERROR BLEManagerImpl::_Init()
253
255
return err;
254
256
}
255
257
258
+ void BLEManagerImpl::_Shutdown ()
259
+ {
260
+ VerifyOrReturn (sbleAdvTimeoutTimer != nullptr );
261
+ xTimerDelete (sbleAdvTimeoutTimer, portMAX_DELAY);
262
+ sbleAdvTimeoutTimer = nullptr ;
263
+
264
+ BleLayer::Shutdown ();
265
+
266
+ // selectively setting kGATTServiceStarted flag, in order to notify the state machine to stop the CHIPoBLE GATT service
267
+ mFlags .ClearAll ().Set (Flags::kGATTServiceStarted );
268
+ mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled ;
269
+
270
+ #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER
271
+ OnChipBleConnectReceived = nullptr ;
272
+ #endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
273
+
274
+ PlatformMgr ().ScheduleWork (DriveBLEState, 0 );
275
+ }
276
+
256
277
CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled (bool val)
257
278
{
258
279
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -708,13 +729,17 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr)
708
729
}
709
730
void BLEManagerImpl::CancelBleAdvTimeoutTimer (void )
710
731
{
732
+ VerifyOrReturn (sbleAdvTimeoutTimer != nullptr );
733
+
711
734
if (xTimerStop (sbleAdvTimeoutTimer, pdMS_TO_TICKS (0 )) == pdFAIL)
712
735
{
713
736
ChipLogError (DeviceLayer, " Failed to stop BledAdv timeout timer" );
714
737
}
715
738
}
716
739
void BLEManagerImpl::StartBleAdvTimeoutTimer (uint32_t aTimeoutInMs)
717
740
{
741
+ VerifyOrReturn (sbleAdvTimeoutTimer != nullptr );
742
+
718
743
if (xTimerIsTimerActive (sbleAdvTimeoutTimer))
719
744
{
720
745
CancelBleAdvTimeoutTimer ();
@@ -844,7 +869,8 @@ void BLEManagerImpl::DriveBLEState(void)
844
869
// Stop the CHIPoBLE GATT service if needed.
845
870
if (mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags .Has (Flags::kGATTServiceStarted ))
846
871
{
847
- // TODO: Not supported
872
+ DeinitESPBleLayer ();
873
+ mFlags .ClearAll ();
848
874
}
849
875
850
876
exit :
@@ -970,6 +996,56 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void)
970
996
return err;
971
997
}
972
998
999
+ void BLEManagerImpl::DeinitESPBleLayer ()
1000
+ {
1001
+ VerifyOrReturn (DeinitBLE () == CHIP_NO_ERROR);
1002
+ BLEManagerImpl::ClaimBLEMemory (nullptr , nullptr );
1003
+ }
1004
+
1005
+ void BLEManagerImpl::ClaimBLEMemory (System::Layer *, void *)
1006
+ {
1007
+ TaskHandle_t handle = xTaskGetHandle (" nimble_host" );
1008
+ if (handle)
1009
+ {
1010
+ ChipLogDetail (DeviceLayer, " Schedule ble memory reclaiming since nimble host is still running" );
1011
+
1012
+ // Rescheduling it for later, 2 seconds is an arbitrary value, keeping it a bit more so that
1013
+ // we dont have to reschedule it again
1014
+ SystemLayer ().StartTimer (System::Clock::Seconds32 (2 ), ClaimBLEMemory, nullptr );
1015
+ }
1016
+ else
1017
+ {
1018
+ // Free up all the space occupied by ble and add it to heap
1019
+ esp_err_t err = ESP_OK;
1020
+
1021
+ #if CONFIG_IDF_TARGET_ESP32
1022
+ err = esp_bt_mem_release (ESP_BT_MODE_BTDM);
1023
+ #elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2 || \
1024
+ CONFIG_IDF_TARGET_ESP32C6
1025
+ err = esp_bt_mem_release (ESP_BT_MODE_BLE);
1026
+ #endif
1027
+
1028
+ VerifyOrReturn (err == ESP_OK, ChipLogError (DeviceLayer, " BLE deinit failed" ));
1029
+ ChipLogProgress (DeviceLayer, " BLE deinit successful and memory reclaimed" );
1030
+ // TODO: post an event when ble is deinitialized and memory is added to heap
1031
+ }
1032
+ }
1033
+
1034
+ CHIP_ERROR BLEManagerImpl::DeinitBLE ()
1035
+ {
1036
+ VerifyOrReturnError (ble_hs_is_enabled (), CHIP_ERROR_INCORRECT_STATE, ChipLogProgress (DeviceLayer, " BLE already deinited" ));
1037
+ VerifyOrReturnError (0 == nimble_port_stop (), MapBLEError (ESP_FAIL), ChipLogError (DeviceLayer, " nimble_port_stop() failed" ));
1038
+
1039
+ esp_err_t err = nimble_port_deinit ();
1040
+ VerifyOrReturnError (err == ESP_OK, MapBLEError (err));
1041
+
1042
+ #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
1043
+ err = esp_nimble_hci_and_controller_deinit ();
1044
+ #endif
1045
+
1046
+ return MapBLEError (err);
1047
+ }
1048
+
973
1049
CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData (void )
974
1050
{
975
1051
CHIP_ERROR err;
0 commit comments