BLE - ESP_GAP_BLE_PASSKEY_NOTIF_EVT not seen with certain Android phones
Posted: 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:
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));