BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby dldtechnology » Thu Apr 23, 2020 3:59 pm

We have an IDF 3.3 application that creates a BLE server which is based off a few of the existing demo sources available.

We use passkey protection, so ESP32 shows a 6 digit key on LCD screen, mobile user enters that key on phone.

Everything works fine when using my Samsung phone, but we've found that some phones (Huawei Y6) ask to pair but then don't ask for the key.

Looking at the logs, everything seems the same except the Samsung gets the ESP_GAP_BLE_PASSKEY_NOTIF_EVT but the Huawei doesn't.

Has anyone seen this behavior before??

Interesting bits of the code:

Code: Select all


/// Navigation Service
static const uint16_t datastore_svc = ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC;

#define CHAR_DECLARATION_SIZE   (sizeof(uint8_t))
static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
static const uint8_t char_prop_notify = ESP_GATT_CHAR_PROP_BIT_NOTIFY;
static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
static const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE|ESP_GATT_CHAR_PROP_BIT_READ;
static const uint8_t char_prop_notify_write = ESP_GATT_CHAR_PROP_BIT_NOTIFY|ESP_GATT_CHAR_PROP_BIT_WRITE;

static const uint8_t notify_ccc[2] ={ 0x00, 0x00};

Code: Select all

/// Full HRS Database Description - Used to add attributes into the database
static const esp_gatts_attr_db_t datastore_gatt_db[DATASTORE_IDX_NB] =
{
    // Datastore Service Declaration
    [DATASTORE_IDX_SVC]                    =
    {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ_ENC_MITM,
      sizeof(uint16_t), sizeof(datastore_svc), (uint8_t *)&datastore_svc}},

    // Datastore Name Characteristic Declaration
    [DATASTORE_IDX_NAME_CHAR]            =
    {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ_ENC_MITM,
      CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}},
    // Datastore Name Characteristic Value
    [DATASTORE_IDX_NAME_VAL]             =
    {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&datastore_name_receive_uuid, ESP_GATT_PERM_READ_ENC_MITM|ESP_GATT_PERM_WRITE_ENC_MITM,
    DATASTORE_DATA_MAX_LEN,sizeof(datastore_name_receive_val), (uint8_t *)datastore_name_receive_val}},

	etc..

Code: Select all

// in gatts_profile_event_handler()

        case ESP_GATTS_CONNECT_EVT:
            ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT");
            /* start security connect with peer device when receive the connect event sent by the master */
            uint32_t passkey = esp_random() % 1000000;
            esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));         
            esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
            break;

Code: Select all

// startup code
    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;
    }

    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, &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));

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby dldtechnology » Fri Apr 24, 2020 2:32 pm

Also seeing same behavior on Arduino using ESP-WROVER-KIT and:

https://raw.githubusercontent.com/choic ... ng_Key.ino

Works on Samsung, not on Huawei


Bottle of very nice whisky / vodka / rum etc to be posted to anyone with the answer!

chegewara
Posts: 1211
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby chegewara » Fri Apr 24, 2020 4:55 pm

dldtechnology wrote: Works on Samsung, not on Huawei
I can confirm the same. I will try to hookup bluetooth sniffer and see what is going on.

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby dldtechnology » Sun Apr 26, 2020 8:49 am

I can confirm the same. I will try to hookup bluetooth sniffer and see what is going on.
That would be awesome!

We've also tested a (new) Nokia and that works OK. Beginning to suspect its a bug on the Huawei..

chegewara
Posts: 1211
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby chegewara » Mon Apr 27, 2020 12:51 pm

This is most likely huawei smartphone issue. What is strange using nRF connect huawei usually didnt ask for pairing but sometimes it did ask for pairing. Here is wireshark sniffer packet when pairing between huawei and esp32. After first pairing request each next connection also was with pairing request as long as i didnt pair and bond correctly.

Second file is when huawei didnt ask pairing (failed). When you compare in wireshark (filter by btl2cap) you can see that in working connection master (huawei) is sending this Opcode few time

Code: Select all

Opcode: Pairing Failed (0x05)
and slave (esp32) is repeating Auth request.
In fail situation huawei is not sending, just disconnect:

Code: Select all

Opcode: Pairing Failed (0x05)
Attachments
huawei_failed.pcapng.txt
(438.13 KiB) Downloaded 52 times
huawei.pcapng.txt
(510.36 KiB) Downloaded 54 times

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby dldtechnology » Tue Apr 28, 2020 10:28 am

Thanks for the traces - I'm trying to get my head around all the stuff in there! :roll:

One thing I noticed is that there's a lot of failures looking for certain characteristics - I'm not sure if this is just being blocked because the authentication hasn't occurred, or if the phone was expecting the ESP32 to advertise some critical information before authentication?

We are planning to test with other brands of phone ASAP and will update.

chegewara
Posts: 1211
Joined: Wed Jun 14, 2017 9:00 pm

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby chegewara » Tue Apr 28, 2020 11:46 am

dldtechnology wrote: I'm not sure if this is just being blocked because the authentication hasn't occurred, or if the phone was expecting the ESP32 to advertise some critical information before authentication?
It is expected to see those errors, because esp32 app is setup to connect with authentication.

xiaoyao
Posts: 16
Joined: Wed Apr 10, 2019 9:04 am

Re: BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones

Postby xiaoyao » Thu Jul 16, 2020 1:29 am

Hi,
I have the same error.My IDF is 4.1, and the phone is Redmi 6,the system is Android 9. My phenomenon is that for the first time, the connection can be normally paired, and then the device can no longer connect after deleting the binding information.So is this a bug for IDF or the phone? Can anyone give me some adivce?

Who is online

Users browsing this forum: No registered users and 42 guests