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