espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.44k stars 7.25k forks source link

(nimble) Cannot re-pair with a previously bonded device if other device deletes bond (IDFGH-13142) #14082

Closed jrahlf closed 3 months ago

jrahlf commented 3 months ago

Answers checklist.

IDF version.

v5.1.1

Espressif SoC revision.

ESP32-S3

Operating System used.

Windows

How did you build your project?

Command line with Make

If you are using Windows, please specify command line type.

PowerShell

Development Kit.

ESP32-S3-MINI-1

Power Supply used.

USB

What is the expected behavior?

I expect pairing process to always succeed, if at least one of the two sides have no relevant bond information. When the other side deletes bonding information, a new pairing process should be initiated and GAP event BLE_GAP_EVENT_PASSKEY_ACTIONshould be raised.

What is the actual behavior?

Pairing (and all subsequent connections, even after reboots) works as expected. However, if the other side deletes its bond information, re-connecting and re-pairing fails. It works again, when the bond information is also deleted on esp32 side.

ESP32-S3 side: GAP event BLE_GAP_EVENT_PASSKEY_ACTIONis never raised. This prevents us from generating a passkey and sending it to the other side.

Smartphone side: Pairing request comes up. However, the second request to enter the passkey never appears.

Steps to reproduce.

  1. Configure Bluetooth with Nimble stack as peripheral with security settings shown below.
  2. Pair/bond a device (e.g. smartphone with NRF applicatoin, desktop NRF application) with esp32 chip.
  3. Delete the bond on smartphone/PC.
  4. Attempt to connect with esp32 chip again. -> This fails, after a few seconds the connection is terminated with reason 531 (timeout). Re-pairing works again, when the relevant bond information is also deleted on esp32 (e.g. reboot or delete from nvs if persist is enabled).

Debug Logs.

Nimble logs (set to debug) have no information regarding this problem.

More Information.

Our bluetooth SM config:

ble_hs_cfg.reset_cb = ble_spp_server_on_reset;
ble_hs_cfg.sync_cb = ble_spp_server_on_sync;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;

ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY;
ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_their_key_dist =  BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_bonding = 1;
ble_hs_cfg.sm_mitm = 1;
ble_hs_cfg.sm_sc = 1;

ble_svc_gap_init();
ble_svc_gatt_init();

rc = gatt_svr_register();
assert(rc == 0);

ble_store_config_init();
print_ble_bonds();
//ble_store_clear();

Nimble and BLE SDK config:

#
# NimBLE Options
#
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set
# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set
CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG=y
CONFIG_BT_NIMBLE_LOG_LEVEL=0
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
CONFIG_BT_NIMBLE_MAX_BONDS=5
CONFIG_BT_NIMBLE_MAX_CCCDS=8
CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
# CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set
CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y
CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y
# CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set
CONFIG_BT_NIMBLE_NVS_PERSIST=y
CONFIG_BT_NIMBLE_SECURITY_ENABLE=y
# CONFIG_BT_NIMBLE_SM_LEGACY is not set
CONFIG_BT_NIMBLE_SM_SC=y
# CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS is not set
CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION=y
CONFIG_BT_NIMBLE_DEBUG=y
CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="example"
CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=512
CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0

#
# Memory Settings
#
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=512
CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=24
CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320
CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=24
CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=30
CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=8
# end of Memory Settings

CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4
# CONFIG_BT_NIMBLE_HS_FLOW_CTRL is not set
CONFIG_BT_NIMBLE_RPA_TIMEOUT=900
# CONFIG_BT_NIMBLE_MESH is not set
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=y
CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT=3
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=y
CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_2M_PHY=y
CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY=y
# CONFIG_BT_NIMBLE_EXT_ADV is not set
CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS=0
CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
CONFIG_BT_NIMBLE_WHITELIST_SIZE=12
# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set
CONFIG_BT_NIMBLE_USE_ESP_TIMER=y
CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y
CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER=y
# CONFIG_BT_NIMBLE_VS_SUPPORT is not set
# end of NimBLE Options

#
# Controller Options
#
CONFIG_BT_CTRL_MODE_EFF=1
CONFIG_BT_CTRL_BLE_MAX_ACT=2
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=2
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
CONFIG_BT_CTRL_PINNED_TO_CORE_0=y
# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set
CONFIG_BT_CTRL_PINNED_TO_CORE=0
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
CONFIG_BT_CTRL_HCI_TL=1
CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30
# CONFIG_BT_CTRL_HW_CCA is not set
CONFIG_BT_CTRL_HW_CCA_VAL=20
CONFIG_BT_CTRL_HW_CCA_EFF=0
CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set
CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y
# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y
# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3=y
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21 is not set
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=9
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100
CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
CONFIG_BT_CTRL_BLE_SCAN_DUPL=y
CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set
CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0
CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100
CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0
# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set
CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
rahult-github commented 3 months ago

Hi @jrahlf ,

Which smartphone is used ? The procedure here to be followed is that if peripheral has initiated security, the central has to send pairing request. Some phones ( iphones ) do not perform this and simply do not proceed. Can you try switching with Android phone and check ? Have confirmed this behavoiur previously too, where remote device doesn't initiate pairing in case bonding information is deleted on its end.

jrahlf commented 3 months ago

I am using a samsung A52 android phone (with NRF connect app) and the behaviour is the same if I use the NRF connect application on a desktop PC with a NRF52 dongle. It seems the problem comes from the esp32 "thinking" that no re-pairing is necessary, because it still has the bonding information for the peer device. So could be that ble_gap_security_initiate does not work correctly in this case or some other error is not correctly propagated up.

Edit: There is the GAP event BLE_GAP_EVENT_REPEAT_PAIRING which sounds like it should fix our problem. We did not catch this event before. Unfortunately the Nimble documentation is partially poor compared to the esp-idf documentation.

jrahlf commented 3 months ago

I can confirm that reacting to BLE_GAP_EVENT_REPEAT_PAIRING resolves the problem. So this was an implementation error on my side and is not a bug in Nimble/esp-idf.