nrf54l15: channel sounding `bt_le_cs_security_enable` fails

Hi,
I am stuck on the BLE channel sounding Initiator initialization. I took the code from the channel sounding connected initiator and integrated into my FW.

Due to unknown reason I am getting -EACCESS error from  bt_le_cs_security_enable(...). I looked inside and sending of BT_HCI_OP_LE_CS_SECURITY_ENABLE HCI command results in BT_HCI_ERR_CMD_DISALLOWED response. I was unable to figure out why.

My setup

  • NCS 3.1.1
  • Toolchain: arm-none-eabi-gcc version 14.2.0 (Arch Repository) 
  • OS: Archlinux

I have two devices:

A

  • Central
  • GATT client
  • CS reflector
  • Process:
    • Scans for advertising
    • Connects
    • Searches for custom Primary Service, characteristics and then subscribes to notifications
    • call `bt_le_cs_set_default_settings(...)` with success
      • const bt_le_cs_set_default_settings_param default_settings = {
            .enable_initiator_role = false,
            .enable_reflector_role = true,
            .cs_sync_antenna_selection = BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE,
            .max_tx_power = BT_HCI_OP_LE_CS_MAX_MAX_TX_POWER,
        };
    • inform device B about intent to start channel sounding
    • receives during initiator setup, receives callbacks
      • `bt_conn_cb::security_changed`
      • `bt_conn_cb::le_cs_read_remote_capabilities_complete`
      • `bt_conn_cb::le_cs_config_complete`

B

  • Peripheral
  • GATT server
  • CS Initiator
  • Process
    • Connection established 
    • receives intent from device A to start CS
    • calls bt_le_cs_set_default_settings(...), success
      • const bt_le_cs_set_default_settings_param default_settings = {
        	.enable_initiator_role = true,
        	.enable_reflector_role = false,
        	.cs_sync_antenna_selection = BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE,
        	.max_tx_power = BT_HCI_OP_LE_CS_MAX_MAX_TX_POWER,
        };
    • calls bt_conn_set_security(L2), success
    • callback bt_conn_cb::security_changed comes with success
    • calls bt_le_cs_read_remote_supported_capabilities(...), success
    • callback bt_conn_cb::le_cs_read_remote_capabilities_complete comes with success
    • calls bt_le_cs_create_config(...), success
      • bt_le_cs_create_config_params cs_config_params {
        	.id = CONFIG_ID, // 0
        	.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2,
        	.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_1,
        	.min_main_mode_steps = 20,
        	.max_main_mode_steps = 40,
        	.main_mode_repetition = 0,
        	.mode_0_steps = 1,
        	.role = BT_CONN_LE_CS_ROLE_INITIATOR,
        	.rtt_type = BT_CONN_LE_CS_RTT_TYPE_AA_ONLY,
        	.cs_sync_phy = BT_CONN_LE_CS_SYNC_1M_PHY,
        	.channel_map_repetition = 1,
        	.channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3B,
        	.ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_HAT,
        	.ch3c_jump = 2,
        };
    • callback bt_conn_cb::le_cs_config_complete comes with success
    • calls bt_le_cs_security_enable(...), fail with ) error -13 (EACCESS)

Am I missing some important step here?

In which scenarios does the softdevice report BT_HCI_ERR_CMD_DISALLOWED as a response to BT_HCI_OP_LE_CS_SECURITY_ENABLE?

The FW is written as asynchronous approach and all functions are dispatched in system WQ.

I am really stuck here. Let me know if you need some other parts of the code itself.

Related