How can an NCS Central pair with an nRF5 SDK Peripheral that only supports Legacy Pairing?

Environment

Central

  • nRF54

  • NCS v3.3.0 (Zephyr Bluetooth Host)

Peripheral

  • nRF52

  • nRF5 SDK v15.3.0

  • Existing commercial product (cannot be modified)

Problem

My nRF54 Central connects successfully to an nRF52 Peripheral and then initiates bonding.

The Peripheral is an existing product that cannot be modified, so I can only change the Central configuration.

During pairing, the Central reports:

BT_SECURITY_ERR_AUTH_REQUIREMENT (4)
"The requested security level could not be reached."

If I disable Secure Connections Only mode by setting:

CONFIG_BT_SMP_SC_PAIR_ONLY=n

the error changes to:

BT_SECURITY_ERR_UNSPECIFIED (9)
"Pairing failed but the exact reason could not be specified."

Peripheral Security Configuration

The Peripheral uses nRF5 SDK 15.3.0 Peer Manager with the following security parameters:

sec_param.bond         = true;
sec_param.mitm         = false;
sec_param.lesc         = false;
sec_param.keypress     = false;
sec_param.io_caps      = BLE_GAP_IO_CAPS_NONE;
sec_param.oob          = false;
sec_param.min_key_size = 7;
sec_param.max_key_size = 16;

Since this is an existing product, these settings cannot be changed.

Questions

  • Is it possible for an NCS 3.3.0 Central to pair with a Peripheral that only supports Legacy Pairing?

  • Besides setting CONFIG_BT_SMP_SC_PAIR_ONLY=n, are there any additional Kconfig options or API calls required on the Central?

  • Does Zephyr/NCS disable Legacy Pairing by default in any other way?

  • Has anyone successfully paired an NCS 3.3.0 Central with an nRF5 SDK Peripheral that has sec_param.lesc = false?

Any suggestions would be appreciated.

Parents
  • Hi,

    Is it possible for an NCS 3.3.0 Central to pair with a Peripheral that only supports Legacy Pairing?

    Yes, this should be possible.

    Besides setting CONFIG_BT_SMP_SC_PAIR_ONLY=n, are there any additional Kconfig options or API calls required on the Central?

    It looks like you also have to set CONFIG_BT_SMP_SC_ONLY=n.
    (And possibly also ensure still that CONFIG_BT_SMP=y.)

    Does Zephyr/NCS disable Legacy Pairing by default in any other way?

    Not that I am aware of, no. The change is documented in the migration notes for nRF Connect SDK v3.0.0.

    Has anyone successfully paired an NCS 3.3.0 Central with an nRF5 SDK Peripheral that has sec_param.lesc = false?

    Others have experienced what looks like the same issue as you are seeing now, and they seem to have made it work with the correct configs.

    Regards,
    Terje

  • Thank you for your reply.

    I checked my Central configuration, and I already have the following settings:

    CONFIG_BT=y
    CONFIG_BT_CENTRAL=y
    CONFIG_BT_GATT_CLIENT=y
    CONFIG_BT_SETTINGS=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_BONDABLE=y
    CONFIG_BT_PRIVACY=y
    CONFIG_BT_FILTER_ACCEPT_LIST=y
    CONFIG_BT_SMP=y
    CONFIG_BT_SMP_SC_ONLY=n
    CONFIG_BT_SMP_SC_PAIR_ONLY=n
    CONFIG_BT_SMP_ENFORCE_MITM=n
    CONFIG_BT_SMP_APP_PAIRING_ACCEPT=y
    CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
    After the connection is established, I request security with:

    bt_conn_set_security(conn, BT_SECURITY_L2);
    However, I still observe the same behavior:

    With CONFIG_BT_SMP_SC_PAIR_ONLY=y (default), security_changed_cb reports:
    BT_SECURITY_ERR_AUTH_REQUIREMENT (4).

    After changing CONFIG_BT_SMP_SC_PAIR_ONLY=n, the error changes to:
    BT_SECURITY_ERR_UNSPECIFIED (9).

    Is there anything else on the Central side that could prevent Legacy Pairing, or is there any additional log you would recommend collecting to help identify the root cause?

    Thank you.

Reply
  • Thank you for your reply.

    I checked my Central configuration, and I already have the following settings:

    CONFIG_BT=y
    CONFIG_BT_CENTRAL=y
    CONFIG_BT_GATT_CLIENT=y
    CONFIG_BT_SETTINGS=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_BONDABLE=y
    CONFIG_BT_PRIVACY=y
    CONFIG_BT_FILTER_ACCEPT_LIST=y
    CONFIG_BT_SMP=y
    CONFIG_BT_SMP_SC_ONLY=n
    CONFIG_BT_SMP_SC_PAIR_ONLY=n
    CONFIG_BT_SMP_ENFORCE_MITM=n
    CONFIG_BT_SMP_APP_PAIRING_ACCEPT=y
    CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
    After the connection is established, I request security with:

    bt_conn_set_security(conn, BT_SECURITY_L2);
    However, I still observe the same behavior:

    With CONFIG_BT_SMP_SC_PAIR_ONLY=y (default), security_changed_cb reports:
    BT_SECURITY_ERR_AUTH_REQUIREMENT (4).

    After changing CONFIG_BT_SMP_SC_PAIR_ONLY=n, the error changes to:
    BT_SECURITY_ERR_UNSPECIFIED (9).

    Is there anything else on the Central side that could prevent Legacy Pairing, or is there any additional log you would recommend collecting to help identify the root cause?

    Thank you.

Children
  • Hi Ethan, 

    Could you show your full code / minimal code  ? 
    I suspect that you may have a mismatch in the MITM configuration, meaning one side tried to do bonding with passkey or OOB. 
    I did a quick test here and it seems to work. Please take a look 
    NCS v3.3.0:
    5543.central_hr.zip

    nRF5 SDK v15.2: 
    ble_app_hrs - Copy.zip

  • Thank you for providing the example projects.

    I tested again using the same security configuration, but pairing still fails in my project.

    The central is based on NCS v3.3.0, and the peripheral is based on nRF5 SDK 15.3.0. The peripheral uses Legacy Pairing with bonding enabled, MITM disabled, OOB disabled.

    However, the connection still remains at security level 1, and the pairing procedure eventually fails.

    I noticed that the sample does not register `security_changed` or `bt_conn_auth_info_cb` callbacks. Could you explain why these callbacks are not required in the sample?

    My understanding is that these callbacks are only used to receive pairing and security status notifications, and should not affect whether the SMP procedure itself succeeds. Is that correct?

    One additional difference is that my peripheral provides the Nordic UART Service rather than the Heart Rate Service.

    Could the presence of NUS affect the pairing procedure in any way, for example through characteristic permissions, automatic security requests, or the timing of GATT discovery?

    As far as I understand, the GATT service type itself should not affect SMP pairing unless one of its attributes requires encryption or authentication. Please let me know whether this assumption is correct.

  • Hi Ethan, 

    Please confirm that my sample worked ? 

    If it's the case could you try to change my sample to match your configuration, step by step until it stop working ? 

    I don't see why `security_changed` or `bt_conn_auth_info_cb` would change the pairing result. 


    NUS service shouldn't be the problem. But what security level did you set to your service ? Did you set it to open or with some encryption/authentication requirement ? 

  • Hi Hung,

    I also compared it with my application step by step. During the investigation, I found something interesting.

    Initially, my application could connect, but the connection was disconnected during the connection parameter update procedure with HCI error 0x22 (LL Response Timeout). My le_param_req_cb() simply returned true to accept the requested parameters, and modifying the requested parameters caused the Peripheral side to report an error.

    I then enabled:

    CONFIG_BT_USER_DATA_LEN_UPDATE=y

    without calling bt_conn_le_data_len_update() in my application.

    After enabling this option, the connection became stable and the connection parameter update completed successfully. I already have the following callbacks registered:

    static struct bt_conn_cb conn_callbacks =
    {
    .connected = connected_cb,
    .disconnected = disconnected_cb,
    .security_changed = security_changed_cb,
    .le_param_req = le_param_req_cb,
    .le_param_updated = le_param_updated_cb,
    .le_data_len_updated = le_data_len_updated_cb,
    };

    At the moment, I haven't identified why enabling CONFIG_BT_USER_DATA_LEN_UPDATE changes the behavior, but it appears to be related to the connection procedure rather than the pairing logic itself.

    I'll continue comparing my application with the sample to identify the exact difference that causes this behavior.

    Thanks for your suggestions.

  • Hi Ethan,

    From what you described, it does sound like an issue with Data Length update procedure rather than pairing issue. We need to check if you handle this process properly, especially on the peripheral side. 
    Do you use nrf_ble_gatt  in your application ? 

    The reason you don't see the problem when you set CONFIG_BT_USER_DATA_LEN_UPDATE=y is that when you set that and you don't initiate the process on the central then the process will not be executed and you will not see the issue. But if you set the config to n , the stack will start it automatically and if you don't have the code to handle the process on the peripheral, you will have a response timeout. 

    But with CONFIG_BT_USER_DATA_LEN_UPDATE=y , do you still have issue with pairing or you can actually pair ? 

Related