BLE failures with EIO

I'm developing a BLE application using several connections, and of course I'm advertising and scanning to establish those connections. I have up to 5 connections at a time and running both peripheral and central roles.

Occasionally I get an error when trying to do a BLE operation and it's not clear to me what the error means for how I should respond. In particular I sometimes get -EIO when calling bt_le_ext_adv_start() or bt_conn_disconnect(). A cursory look through the code in these functions doesn't show an obvious reason why EIO occurs, except that it may be caused by an error when sending an HCI command to the controller in bt_hci_cmd_send_sync(). Looking at the logs, I do sometimes see a warning like "bt_hci_core: opcode 0x200e status 0x0c" which is indeed generated in bt_hci_cmd_send_sync(). Since the EIO error only occurs occasionally I suspect it may be occurring due to a timing window where the host and controller are out of sync, or some other transient condition. In some cases retrying the operation later works eventually, sometimes not (advertising seems to often fail many times in a row and then succeed; disconnecting failures seem to never succeed with retries).

At the end of the day I just want my application to robustly handle error conditions like this. But, with the error code EIO I'm not sure how to respond. If it's dependent on the specific opcode/status code, the application doesn't have access to this information (only EIO). Can you give me any insight into what I should do in situations like this? Is there any way for the application to know more specific error codes so it can respond appropriately?

Details: I am using NCS 2.4.1 on the nRF5340 with the net core running the soft device controller. I think these are the relevant parts of my project configuration.

App core:

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y

CONFIG_BT_MAX_CONN=5

CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2

CONFIG_BT_GATT_DM=y

CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_TX_COUNT=20
CONFIG_BT_BUF_ACL_RX_SIZE=251

CONFIG_BT_FILTER_ACCEPT_LIST=y
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_SMP=y
CONFIG_BT_DEVICE_NAME="ABC"

CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n

CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y

CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1

Net core:

CONFIG_BT_MAX_CONN=5

CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_TX_COUNT=20
CONFIG_BT_BUF_ACL_RX_SIZE=251

CONFIG_BT_CTLR=y
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=255
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_SET=2
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_CTLR_RX_BUFFERS=10
CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y

CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=1

Related