@@ -246,6 +246,21 @@ CHIP_ERROR BLEManagerImpl::_Init()
246
246
return err;
247
247
}
248
248
249
+ void BLEManagerImpl::_Shutdown ()
250
+ {
251
+ BleLayer::Shutdown ();
252
+
253
+ // selectively setting kGATTServiceStarted flag, in order to notify the state machine to stop the CHIPoBLE GATT service
254
+ mFlags .ClearAll ().Set (Flags::kGATTServiceStarted );
255
+ mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled ;
256
+
257
+ #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER
258
+ OnChipBleConnectReceived = nullptr ;
259
+ #endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER
260
+
261
+ PlatformMgr ().ScheduleWork (DriveBLEState, 0 );
262
+ }
263
+
249
264
CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled (bool val)
250
265
{
251
266
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -806,7 +821,8 @@ void BLEManagerImpl::DriveBLEState(void)
806
821
// Stop the CHIPoBLE GATT service if needed.
807
822
if (mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags .Has (Flags::kGATTServiceStarted ))
808
823
{
809
- // TODO: Not supported
824
+ DeinitESPBleLayer ();
825
+ mFlags .ClearAll ();
810
826
}
811
827
812
828
exit :
@@ -932,6 +948,56 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void)
932
948
return err;
933
949
}
934
950
951
+ void BLEManagerImpl::DeinitESPBleLayer ()
952
+ {
953
+ VerifyOrReturn (DeinitBLE () == CHIP_NO_ERROR);
954
+ BLEManagerImpl::ClaimBLEMemory (nullptr , nullptr );
955
+ }
956
+
957
+ void BLEManagerImpl::ClaimBLEMemory (System::Layer *, void *)
958
+ {
959
+ TaskHandle_t handle = xTaskGetHandle (" nimble_host" );
960
+ if (handle)
961
+ {
962
+ ChipLogDetail (DeviceLayer, " Schedule ble memory reclaiming since nimble host is still running" );
963
+
964
+ // Rescheduling it for later, 2 seconds is an arbitrary value, keeping it a bit more so that
965
+ // we dont have to reschedule it again
966
+ SystemLayer ().StartTimer (System::Clock::Seconds32 (2 ), ClaimBLEMemory, nullptr );
967
+ }
968
+ else
969
+ {
970
+ // Free up all the space occupied by ble and add it to heap
971
+ esp_err_t err = ESP_OK;
972
+
973
+ #if CONFIG_IDF_TARGET_ESP32
974
+ err = esp_bt_mem_release (ESP_BT_MODE_BTDM);
975
+ #elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2 || \
976
+ CONFIG_IDF_TARGET_ESP32C6
977
+ err = esp_bt_mem_release (ESP_BT_MODE_BLE);
978
+ #endif
979
+
980
+ VerifyOrReturn (err == ESP_OK, ChipLogError (DeviceLayer, " BLE deinit failed" ));
981
+ ChipLogProgress (DeviceLayer, " BLE deinit successful and memory reclaimed" );
982
+ // TODO: post an event when ble is deinitialized and memory is added to heap
983
+ }
984
+ }
985
+
986
+ CHIP_ERROR BLEManagerImpl::DeinitBLE ()
987
+ {
988
+ VerifyOrReturnError (ble_hs_is_enabled (), CHIP_ERROR_INCORRECT_STATE, ChipLogProgress (DeviceLayer, " BLE already deinited" ));
989
+ VerifyOrReturnError (0 == nimble_port_stop (), MapBLEError (ESP_FAIL), ChipLogError (DeviceLayer, " nimble_port_stop() failed" ));
990
+
991
+ esp_err_t err = nimble_port_deinit ();
992
+ VerifyOrReturnError (err == ESP_OK, MapBLEError (err));
993
+
994
+ #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
995
+ err = esp_nimble_hci_and_controller_deinit ();
996
+ #endif
997
+
998
+ return MapBLEError (err);
999
+ }
1000
+
935
1001
CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData (void )
936
1002
{
937
1003
CHIP_ERROR err;
0 commit comments