Bluetooth deinitialize and initialize process

akshaay24
Posts: 13
Joined: Wed Jul 14, 2021 5:21 am

Bluetooth deinitialize and initialize process

Postby akshaay24 » Thu Jul 21, 2022 2:32 pm

Hello,

We have a use case were we initialize bluetooth, disable/deinit bluetooth and initialize it again.

Considering ble gatt sever example.

Initialize bluetooth:
  1. void Bluetooth_Service_Initialize()
  2. {
  3.     esp_err_t ret;
  4.  
  5.         /* Initialize NVS. */
  6.         ret = nvs_flash_init();
  7.         if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
  8.             ESP_ERROR_CHECK(nvs_flash_erase());
  9.             ret = nvs_flash_init();
  10.         }
  11.         ESP_ERROR_CHECK( ret );
  12.  
  13.         ESP_ERROR_CHECK(nvs_flash_erase());
  14.  
  15.         ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  16.  
  17.         esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  18.         ret = esp_bt_controller_init(&bt_cfg);
  19.         if (ret) {
  20.             ESP_LOGE(EXAMPLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  21.             return;
  22.         }
  23.  
  24.         ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  25.         if (ret) {
  26.             ESP_LOGE(EXAMPLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  27.             return;
  28.         }
  29.  
  30.         ret = esp_bluedroid_init();
  31.         if (ret) {
  32.             ESP_LOGE(EXAMPLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
  33.             return;
  34.         }
  35.  
  36.         ret = esp_bluedroid_enable();
  37.         if (ret) {
  38.             ESP_LOGE(EXAMPLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
  39.             return;
  40.         }
  41.  
  42.         ret = esp_ble_gatts_register_callback(gatts_event_handler);
  43.         if (ret){
  44.             ESP_LOGE(EXAMPLE_TAG, "gatts register error, error code = %x", ret);
  45.             return;
  46.         }
  47.  
  48.         ret = esp_ble_gap_register_callback(gap_event_handler);
  49.         if (ret){
  50.             ESP_LOGE(EXAMPLE_TAG, "gap register error, error code = %x", ret);
  51.             return;
  52.         }
  53.  
  54.         ret = esp_ble_gatts_app_register(ESP_APP_ID);
  55.         if (ret){
  56.             ESP_LOGE(EXAMPLE_TAG, "gatts app register error, error code = %x", ret);
  57.             return;
  58.         }
  59.  
  60.         esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(33);
  61.         if (local_mtu_ret){
  62.             ESP_LOGE(EXAMPLE_TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
  63.         }
  64.  
  65.         /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
  66.         esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;     //bonding with peer device after authentication
  67.         esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;           //set the IO capability to No output No input
  68.         uint8_t key_size = 16;      //the key size should be 7~16 bytes
  69.         uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  70.         uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  71.         uint32_t passkey = 123456;
  72.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
  73.         esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
  74.         esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
  75.         esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
  76.         /* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
  77.         and the response key means which key you can distribute to the Master;
  78.         If your BLE device act as a master, the response key means you hope which types of key of the slave should distribute to you,
  79.         and the init key means which key you can distribute to the slave. */
  80.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
  81.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
  82. }

De-initialize Bluetooth:
  1. esp_err_t Bluetooth_Deinitialize (void)
  2. {
  3.   esp_err_t ret = 0;
  4.   esp_ble_gap_stop_advertising ();
  5.  
  6.   ret = esp_bluedroid_disable ();
  7.   if (ret != ESP_OK)
  8.     {
  9.       printf ("esp_bt_controller_disable FAILEd =%d\n", ret);
  10.       return ret;
  11.     }
  12.  
  13.   ret = esp_bluedroid_deinit ();
  14.   if (ret != ESP_OK)
  15.     {
  16.       printf ("esp_bluedroid_deinit FAILEd =%d\n", ret);
  17.       return ret;
  18.     }
  19.  
  20.   ret = esp_bt_controller_disable ();
  21.   if (ret != ESP_OK)
  22.     {
  23.       printf ("esp_bt_controller_disable FAILEd =%d\n", ret);
  24.       return ret;
  25.     }
  26.  
  27.   ret = esp_bt_controller_deinit ();
  28.   if (ret != ESP_OK)
  29.     {
  30.       printf ("ble deiniet FAILEd =%d\n", ret);
  31.       return ret;
  32.     }
  33.  
  34.   ret = esp_bt_controller_mem_release (ESP_BT_MODE_BLE);
  35.   if (ret != ESP_OK)
  36.     {
  37.       printf ("ble mem_release FAILEd =%d\n", ret);
  38.       return ret;
  39.     }
  40.  
  41.   return ret;
  42. }

First initialize is working fine and bluetooth is been de-initialize Successfully. After this when we again initialize, facing below error and code restarts:

Code: Select all

ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x4008feec
file: "../main/ble_compatibility_test.c" line 632
func: Bluetooth_Service_Initialize
expression: esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)

abort() was called at PC 0x4008feef on core 0


Backtrace:0x40081a5e:0x3ffbbf100x4008fef9:0x3ffbbf30 0x40095062:0x3ffbbf50 0x4008feef:0x3ffbbfc0 0x400d721c:0x3ffbbfe0 0x400d744d:0x3ffbc040 0x40141a3d:0x3ffbc060 0x40092af1:0x3ffbc080




ELF file SHA256: f4bf2cf85d852af7

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x32 (SPI_FAST_FLASH_BOOT)

What is the appropriate way to implement bluetooth re-initialization.

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Bluetooth deinitialize and initialize process

Postby Ritesh » Tue Jun 20, 2023 1:11 pm

akshaay24 wrote:
Thu Jul 21, 2022 2:32 pm
Hello,

We have a use case were we initialize bluetooth, disable/deinit bluetooth and initialize it again.

Considering ble gatt sever example.

Initialize bluetooth:
  1. void Bluetooth_Service_Initialize()
  2. {
  3.     esp_err_t ret;
  4.  
  5.         /* Initialize NVS. */
  6.         ret = nvs_flash_init();
  7.         if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
  8.             ESP_ERROR_CHECK(nvs_flash_erase());
  9.             ret = nvs_flash_init();
  10.         }
  11.         ESP_ERROR_CHECK( ret );
  12.  
  13.         ESP_ERROR_CHECK(nvs_flash_erase());
  14.  
  15.         ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  16.  
  17.         esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  18.         ret = esp_bt_controller_init(&bt_cfg);
  19.         if (ret) {
  20.             ESP_LOGE(EXAMPLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  21.             return;
  22.         }
  23.  
  24.         ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  25.         if (ret) {
  26.             ESP_LOGE(EXAMPLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  27.             return;
  28.         }
  29.  
  30.         ret = esp_bluedroid_init();
  31.         if (ret) {
  32.             ESP_LOGE(EXAMPLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
  33.             return;
  34.         }
  35.  
  36.         ret = esp_bluedroid_enable();
  37.         if (ret) {
  38.             ESP_LOGE(EXAMPLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
  39.             return;
  40.         }
  41.  
  42.         ret = esp_ble_gatts_register_callback(gatts_event_handler);
  43.         if (ret){
  44.             ESP_LOGE(EXAMPLE_TAG, "gatts register error, error code = %x", ret);
  45.             return;
  46.         }
  47.  
  48.         ret = esp_ble_gap_register_callback(gap_event_handler);
  49.         if (ret){
  50.             ESP_LOGE(EXAMPLE_TAG, "gap register error, error code = %x", ret);
  51.             return;
  52.         }
  53.  
  54.         ret = esp_ble_gatts_app_register(ESP_APP_ID);
  55.         if (ret){
  56.             ESP_LOGE(EXAMPLE_TAG, "gatts app register error, error code = %x", ret);
  57.             return;
  58.         }
  59.  
  60.         esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(33);
  61.         if (local_mtu_ret){
  62.             ESP_LOGE(EXAMPLE_TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
  63.         }
  64.  
  65.         /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
  66.         esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;     //bonding with peer device after authentication
  67.         esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;           //set the IO capability to No output No input
  68.         uint8_t key_size = 16;      //the key size should be 7~16 bytes
  69.         uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  70.         uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  71.         uint32_t passkey = 123456;
  72.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
  73.         esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
  74.         esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
  75.         esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
  76.         /* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
  77.         and the response key means which key you can distribute to the Master;
  78.         If your BLE device act as a master, the response key means you hope which types of key of the slave should distribute to you,
  79.         and the init key means which key you can distribute to the slave. */
  80.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
  81.         esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
  82. }

De-initialize Bluetooth:
  1. esp_err_t Bluetooth_Deinitialize (void)
  2. {
  3.   esp_err_t ret = 0;
  4.   esp_ble_gap_stop_advertising ();
  5.  
  6.   ret = esp_bluedroid_disable ();
  7.   if (ret != ESP_OK)
  8.     {
  9.       printf ("esp_bt_controller_disable FAILEd =%d\n", ret);
  10.       return ret;
  11.     }
  12.  
  13.   ret = esp_bluedroid_deinit ();
  14.   if (ret != ESP_OK)
  15.     {
  16.       printf ("esp_bluedroid_deinit FAILEd =%d\n", ret);
  17.       return ret;
  18.     }
  19.  
  20.   ret = esp_bt_controller_disable ();
  21.   if (ret != ESP_OK)
  22.     {
  23.       printf ("esp_bt_controller_disable FAILEd =%d\n", ret);
  24.       return ret;
  25.     }
  26.  
  27.   ret = esp_bt_controller_deinit ();
  28.   if (ret != ESP_OK)
  29.     {
  30.       printf ("ble deiniet FAILEd =%d\n", ret);
  31.       return ret;
  32.     }
  33.  
  34.   ret = esp_bt_controller_mem_release (ESP_BT_MODE_BLE);
  35.   if (ret != ESP_OK)
  36.     {
  37.       printf ("ble mem_release FAILEd =%d\n", ret);
  38.       return ret;
  39.     }
  40.  
  41.   return ret;
  42. }

First initialize is working fine and bluetooth is been de-initialize Successfully. After this when we again initialize, facing below error and code restarts:

Code: Select all

ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x4008feec
file: "../main/ble_compatibility_test.c" line 632
func: Bluetooth_Service_Initialize
expression: esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)

abort() was called at PC 0x4008feef on core 0


Backtrace:0x40081a5e:0x3ffbbf100x4008fef9:0x3ffbbf30 0x40095062:0x3ffbbf50 0x4008feef:0x3ffbbfc0 0x400d721c:0x3ffbbfe0 0x400d744d:0x3ffbc040 0x40141a3d:0x3ffbc060 0x40092af1:0x3ffbc080




ELF file SHA256: f4bf2cf85d852af7

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x32 (SPI_FAST_FLASH_BOOT)

What is the appropriate way to implement bluetooth re-initialization.
Hello,

Is your issue has been resolved or still looking for solutions?

Because we are also trying to do same at our end and we are facing similar kind of issue like device is going to restart with crash.

We are using ESP32 IDF 3.2 at our end for application development perspective.

Let me know if you have any workaround solution for the same.
Regards,
Ritesh Prajapati

MicroController
Posts: 1739
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Bluetooth deinitialize and initialize process

Postby MicroController » Tue Jun 20, 2023 4:15 pm

https://docs.espressif.com/projects/esp ... _bt_mode_t

"Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth mode which you have released by this function.

If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) then do not call this function."

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Bluetooth deinitialize and initialize process

Postby Ritesh » Wed Jun 21, 2023 4:56 am

MicroController wrote:
Tue Jun 20, 2023 4:15 pm
https://docs.espressif.com/projects/esp ... _bt_mode_t

"Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth mode which you have released by this function.

If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) then do not call this function."
Hello,

Thanks for your prompt response.

If I understood from note that once BT controller memory is released, then process can not be reversed means we can't initialize BT Controller again? Is there any reason that why this kind of limitation has been put into stack and controller side.

Because you know that there are already requirements to do commissioning through BT and other requirements where BT is required to disabled and enabled few times as per requirements.

We have also same kind of requirements where BT is required to disabled when Firmware Upgrade is on going and enabled it if any issue like connection broken or any other Firmware Update failure.

So, There is no any mechanism to re-initialize BT controller like we are generally doing Wi-Fi?
Regards,
Ritesh Prajapati

MicroController
Posts: 1739
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Bluetooth deinitialize and initialize process

Postby MicroController » Wed Jun 21, 2023 5:25 am

You can disable/de-init Bluetooth and then re-enable it. Just the mentioned release memory function, which the OP used, is "irreversible".

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Bluetooth deinitialize and initialize process

Postby Ritesh » Wed Jun 21, 2023 5:51 am

MicroController wrote:
Wed Jun 21, 2023 5:25 am
You can disable/de-init Bluetooth and then re-enable it. Just the mentioned release memory function, which the OP used, is "irreversible".
Hello MicroController,

Understood your point.

If you have any reference example to de-init and again initialize it then would you please share it for our reference?
Regards,
Ritesh Prajapati

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Bluetooth deinitialize and initialize process

Postby Ritesh » Fri Jun 23, 2023 11:13 am

Hello MicroController,

We moved further from our end with deinitialize and initialize Buetooth from our end which is working fine without any issue.

We have also looked and did some research regarding overall internal memory allocation and de-allocation when Bluetooth Init and De-Init is happened along with recursive process whenever required.

Right now, We are facing only one trouble in case of Bluetooth Application Task perspective is that we are not able to de-register callback for both GATT and GAP Profile for below
esp_err_t esp_ble_gatts_register_callback
esp_ble_gap_register_callback
So, We are looking API or solution to de-register for above callback so that when we de-init and init bluetooth again then we can register it again at runtime. We have checked API support into ESP32-IDF but not found it.

Let me know if you have any idea for the same.
Regards,
Ritesh Prajapati

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Bluetooth deinitialize and initialize process

Postby Ritesh » Fri Jun 23, 2023 11:29 am

Hello MicroController,

If we delete Task with below Register callback then we are not able to delete it and system is going to crash it with few backtrace as well.
ret = esp_ble_gatts_register_callback(gatts_event_handler);
if (ret){
DEBUG_LOGE(UART, GATTS_TAG, "gatts register error, error code = %x", ret);
return;
}
ret = esp_ble_gap_register_callback(gap_event_handler);
if (ret){
DEBUG_LOGE(UART, GATTS_TAG, "gap register error, error code = %x", ret);
return;
}
So, I just want to know that what will be state of both above callback when we de-init Bluetooth? Both callback will be vanished or still there will be any entry for that?
Regards,
Ritesh Prajapati

Who is online

Users browsing this forum: ESP_ondrej and 128 guests