This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Questions about implementing BLE bonding with NUS

Hi

This is Joe.
I would like to ask questions about implementing BLE bonding.

SDK:
16.0.0 (nRF5SDK160098a08e2)

Projects:
The base project I start with is NUS example (both Peripheral and Central)
example/ble_peripheral/ble_app_uart
example/ble_central/ble_app_uart_c

What I have done / tried:
1. First of all I just build both projects and run on 2 devices. Make sure the NUS example is working correctly.

2. Then, by referencing the code from another example (ble_app_hrs and ble_app_hrs_c), I added peer manager and bonding related code, such as pm_evt_handler, peer_manager_init, delete_bonds, etc to both projects (ble_app_uart & ble_app_uart_c).

3. And also according to this forum post (https://devzone.nordicsemi.com/f/nordic-q-a/43400/peer_manager_sm-could-not-perform-security-procedure-smd_params_reply-or-smd_link_secure-returned-nrf_error_invalid_addr), cc310 is also added to the project.

The project structure looks like this:


What is the current status:
1. The Peripheral (ble_app_uart) is able to connect to the iOS app "nRF Connect".
When connected to iOS app "nRF Connect", I can see the device advertising, connect to the device, notify from the device, disconnect from the device. Everything working correctly.

2. The Peripheral (ble_app_uart) is not able to connect to Central (ble_app_uart_c).
When try to connect to the Central device (ble_app_uart_c), it shows connected (green rectangle in below image) at first but then disconnected (red rectangle in below image) after 1 second.
(P.S. To minimize unknown problem, I execute delete_bonds everytime when the Peripheral or Central is power on)

This is the RTT output of Central device.


The error message shows that connection failed due to connection security failed (error 4352).
In this forum post (https://devzone.nordicsemi.com/f/nordic-q-a/49894/peermanager-error-error-4352), 4352 is PM_CONN_SEC_ERROR_DISCONNECT.

What my question is:
1. I cannot figure out what caused the problem and now I have no idea how to fix this. Could anyone give me some help or some hints to guide me to the correct way?
2. Actually what I would like to archive is that I want the previously paired devices remember each other. Just like our earphone always connect to our smartphone when both power on. Therefore even if there are multiple peripherals and centrals are power on, the devices will not paired to a device that is not paired before.
As far as my understanding, the original example of NUS, Central will search for any Peripheral device with NUS UUID. So I cannot guarantee which device connect to which if I have multiple Peripheral advertising and Central scanning at the same time. So I googled and found bonding seems to be the solution. Is my understanding correct? Please correct me if I am wrong.

Thank you very much.

Best Regards
Joe

  • Hello,

    You can see where this error is printed:

    It is from the PM_EVT_CONN_SEC_FAILED event in pm_handler_pm_evt_log() from peer_manager_handler.c:

                NRF_LOG_INFO("Connection security failed: role: %s, conn_handle: 0x%x, procedure: %s, error: %d",
                             m_roles_str[ble_conn_state_role(p_pm_evt->conn_handle)],
                             p_pm_evt->conn_handle,
                             m_sec_procedure_str[p_pm_evt->params.conn_sec_start.procedure],
                             p_pm_evt->params.conn_sec_failed.error);

    You can see that the error number is printed as a decimal value (%d), so this means that the decimal value is 0x1100. So what does that mean?

    Looking at the type of the p_pm_evt->params.conn_sec_failed.error, which is an pm_sec_error_code_t, you can see from the description that it is:

    /**@brief Errors from security procedures in Peer Manager.
     *
     * @details Possible values are defined in @ref PM_SEC_ERRORS and @ref BLE_GAP_SEC_STATUS.
     */
    typedef uint16_t pm_sec_error_code_t;

    (from peer_manager_types.h, line 74-78)

    So from @defgroup PM_SEC_ERRORS:

    #define PM_CONN_SEC_ERROR_DISCONNECT         (PM_CONN_SEC_ERROR_BASE + 0x100) /**< @brief Pairing or encryption did not finish before the link disconnected for an unrelated reason. */

    (PM_CONN_SEC_ERROR_BASE is 0x1000)

    So the error you receive is because of the disconnect.

    Are you prompted with any pairing questions when connecting with nRF Connect for Desktop? Did you try to click the settings icon of the connection and click pair (and check of "bond")?

     

    2. Actually what I would like to archive is that I want the previously paired devices remember each other. Just like our earphone always connect to our smartphone when both power on. Therefore even if there are multiple peripherals and centrals are power on, the devices will not paired to a device that is not paired before.
    As far as my understanding, the original example of NUS, Central will search for any Peripheral device with NUS UUID. So I cannot guarantee which device connect to which if I have multiple Peripheral advertising and Central scanning at the same time. So I googled and found bonding seems to be the solution. Is my understanding correct? Please correct me if I am wrong.

     That is almost correct. Bonding means that you store the encryption keys of the connection. After you have bonded, either your central or peripheral (or both) may use something called a whitelist when it is scanning/advertising. If you do this, it will only accept connections to that device.

    That being said. Even if you bond with a phone, it doesn't mean that this phone will try to connect to the peripheral whenever it is advertising. I don't know the exact details about earphones, because that is not BLE, but Classic Bluetooth. However, I suspect that it is similar to HID devices. You will see that if you try to flash the ble_app_hids_keyboard example, the phone will automatically reconnect to that device. The reason for this is that it is a HID [device] (Human Interface Device), and the phone's OS finds it useful. However, if you use most other examples, the phone will not automatically connect even though they are bonded. If you want something custom to automatically connect to your phone, you must write an application on the phone that will scan for and connect to your peripheral.

    Back to whitelists: The main purpose of whitelists is to look for specific devices, and deny connection from others. One example that uses a whitelist is the ble_app_gls, and the ble_app_hrs_c.

    Best regards,

    Edvin

  • Hi Edvin

    Thank you for your reply.

    Looks like the connection is disconnected due to fatal error on Peripheral.
    Here is the RTT log of Peripheral.

    I cannot figure it out where did it come from yet. When I try to debug, it always jump to NRF_BREAKPOINT_COND.

    And some supplementary about the devices behavior:
    Both Peripheral and Central are nRF52 devices. If Central is not paired, it keeps scanning for Peripheral. On the other hand, when Peripheral is not paired, it keeps advertising until it is connected. So basically when both are power on, it should be connected immediately.

    That mean to archive my goal, I have to:
    Once the bonding is completed, I can "add it to whitelist".
    So it will always only connect to each other, unless I clear the bonding (the devices become a unpaired "new device")

    To create a bonding, do I need to implement on both side (Peripheral and Central)? Or i just have to implement on one side, say the Central device?

    Best Regards
    Joe

  • Hello,

    When you see the "fatal error" in the log, define DEBUG in your preprocessor definitions, and the log should point to where the error is coming from.

    For the bonding questions, I suggest you look into some of the examples that use bonding. A peripheral that use this is the ble_app_gls, and a central project that use it is the ble_app_hrs_c.

    sdtjoe said:
    To create a bonding, do I need to implement on both side (Peripheral and Central)? Or i just have to implement on one side, say the Central device?

    Both sides. If not, then the devices without the whitelist will always accept connections from other devices.

     

    Best regards,

    Edvin

  • Hello

    Sorry I was busy on other project so I was unable to update the progress.

    After referencing the examples, looks like I am able to bond two nRF52 devices.
    According to the log, the peer data was updated in flash.


    If I just turn the Peripheral device off and on again, the Central remain on, the devices reconnected successfully and no change is made in flash.


    Problem #1:
    However, if I turn the Central off, and turn it on again, it shows the following error:
    ERROR 12 [NRF_ERROR_DATA_SIZE]
    (The error is occurred on Central side, not Peripheral side)
    (The Central program is based on the example ble_uart_c)

    case APP_UART_COMMUNICATION_ERROR:
    NRF_LOG_ERROR("Communication error occurred while handling UART.");
    APP_ERROR_HANDLER(p_event->data.error_communication); // Line 1006
    break;


    And I can only erase the Central and re-download the program again.
    I have read several posts talking about this.
    Most are on Peripheral side, but mine is on Central side.


    Problem #2:
    After problem #1 occured, the pairing no long success.
    When trying to connect, the error of 4102 is returned.
    4102 => 0x1006 => PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING


    Is there any hint on the above two problems?


    Best Regards
    Joe

  • Hello Joe,

    Problem #1:

    The value in p_evt->data.error_communication refers to the errorsrc register on the UART peripheral:

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/uarte.html?cp=4_2_0_34_9_4#register.ERRORSRC

    When this is 12, it means you have a framing error. Are your UART pins connected to anything? If not, perhaps you should skip the uart_init(), if you are not using it.

    Problem #2:

    At this point, does one of the devices contain bonding information, while the other doesn't?

Related