How to properly Disable/Enable BLE during the run time

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

How to properly Disable/Enable BLE during the run time

Postby zazas321 » Fri Dec 03, 2021 10:03 am

Hello. For my project, I would like to implement the following BLE logic:

1. When the device first starts up, the BLE will be active for 10 minutes. If there is a client connected to the server, the BLE will continuosly run and should not be disabled. As soon as the program detects that there are no clients detected, the timer will start and count to 10 minutes. If within within 10 minutes no one connects to my device, the BLE will be disabled and the only way to enable it back ON is to press a button on my device.


At the moment, I am just trying to implement the logic of switching ON/OFF the BLE while the device is running. After that I will handle all the timer logic and etc..

My BLE setup function looks like this;

Code: Select all


void BLE_setup()
{

    esp_err_t ret;
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        ESP_LOGE(GATTS_TABLE_TAG, "%s init controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
        ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    ESP_LOGI(GATTS_TABLE_TAG, "%s init bluetooth", __func__);
    ret = esp_bluedroid_init();
    if (ret) {
        ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }
    ret = esp_bluedroid_enable();
    if (ret) {
        ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }
    const uint8_t* point = esp_bt_dev_get_address();
    for (int i = 0; i < 6; i++) {
        char str[3];
        sprintf(str, "%02X", (int)point[i]);
        printf(str);
        if (i < 5){
            printf(":");
        }
    }

    ret = esp_ble_gatts_register_callback(gatts_event_handler);
    if (ret){
        ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret);
        return;
    }
    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret){
        ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret);
        return;
    }
    ret = esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID);
    if (ret){
        ESP_LOGE(GATTS_TABLE_TAG, "gatts app register error, error code = %x", ret);
        return;
    }

    /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
    esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;     //bonding with peer device after authentication
    esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;           //set the IO capability to No output No input
    uint8_t key_size = 16;      //the key size should be 7~16 bytes
    uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
    uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
    //set static passkey
    //uint32_t passkey = 123456;
    uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
    uint8_t oob_support = ESP_BLE_OOB_DISABLE;
    esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &BLE_passkey, sizeof(uint32_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
    /* If your BLE device acts as a Slave, the init_key means you hope which types of key of the master should distribute to you,
    and the response key means which key you can distribute to the master;
    If your BLE device acts as a master, the response key means you hope which types of key of the slave should distribute to you,
    and the init key means which key you can distribute to the slave. */
    esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
    esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));

    

    /* Just show how to clear all the bonded devices
     * Delay 30s, clear all the bonded devices
     *
     * vTaskDelay(30000 / portTICK_PERIOD_MS);
     * remove_all_bonded_devices();
     */

}

and my BLE_disable function looks like;

Code: Select all


bool BLE_disable(){
    esp_err_t ret;

    ESP_LOGI(GATTS_TABLE_TAG, "Disabling Bluetooth");

    if ((ret = esp_bluedroid_disable()) != ESP_OK) {
    ESP_LOGE(GATTS_TABLE_TAG, "%s disable bluedroid failed: %s\n", __func__,
    esp_err_to_name(ret));
    return 1;
    }

    if ((ret = esp_bluedroid_deinit()) != ESP_OK) {
    ESP_LOGE(GATTS_TABLE_TAG, "%s deinitialize bluedroid failed: %s\n", __func__,
    esp_err_to_name(ret));
    return 1;
    }

    if ((ret = esp_bt_controller_disable()) != ESP_OK) {
    ESP_LOGE(GATTS_TABLE_TAG, "%s disable controller failed: %s\n", __func__,
    esp_err_to_name(ret));
    return 1;
    }

    if ((ret = esp_bt_controller_deinit()) != ESP_OK) {
    ESP_LOGE(GATTS_TABLE_TAG, "%s deinitialize controller failed: %s\n", __func__,
    esp_err_to_name(ret));
    return 1;
    }

    esp_bt_mem_release(ESP_BT_MODE_BLE);

    return 0;
}


I have implemented a few serial commands
"ble_eanble" will execute the BLE_setup() and 'ble_disable" will execute the BLE_disable();






When the device starts up, the BLE_setup() is called automatically and the BLE is active. It works fine and I am able to connect to it via mobile phone without any issues. When I execute "ble_disable" command, the BLE is deactivated"

Code: Select all

ble_disable
[1B][0;32mI (118897) SEC_GATTS_DEMO: Disabling Bluetooth[1B][0m
[1B][0;32mI (118907) SEC_GATTS_DEMO: ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x16[1B][0m
[1B][0;32mI (118917) SEC_GATTS_DEMO: advertising start success[1B][0m
At this moment, I can no longer see the device in bluetooth devices list so it seems that it sucesfully disabled the BLE interface. However, when I try to enable it back on by executing the "ble_enable" command, I get the following error:

Code: Select all

ble_enable
ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x4008f870
file: "../components/BLE/BLE_custom.cpp" line 1841
func: void BLE_setup()
expression: esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)

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

Backtrace:0x4009074b:0x3ffd6e70 0x40090f49:0x3ffd6e90 0x4009569e:0x3ffd6eb0 0x4008f873:0x3ffd6f20 0x400da892:0x3ffd6f40 0x400dd90d:0x3ffd6fa0 0x400dcea5:0x3ffd73b0 0x40091359:0x3ffd77d0


ELF file SHA256: 58111efb501f0ef7

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7056
load:0x40078000,len:14308
ho 0 tail 12 room 4
load:0x40080400,len:3716
entry 0x40080680
[1B][0;32mI (29) boot: ESP-IDF v4.3.1-dirty 2nd stage bootloader[1B][0m
and then the device resets.. Could someone help me understand and point me in the right direction how this should be done the proper way?

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 106 guests