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

Multi-peripheral, bonding and whitelisting

Hi,

I need a way to have a concurrent connection (multi-peripheral), with whitelisting and bonding. Is there any example of this?

I found an example for multi-peripherals, but this is not for concurrent connections. I also found the HID-Mouse example which uses whitelisting and bonding, but it's only supporting single links (because it uses the advertising module).

I some sort of managed to include those two together, but then sometimes the softdevice asserts. So I was wondering if there are any other examples of doing this?

  • Hello,

    We don't have any example doing all these things together. 

    Multiperhipheral: SDK\examples\ble_peripheral\experimental\ble_app_multiperipheral (should support multiple concurrent connections as a peripheral).

    Whitelisting and bonding: ble_app_gls, and maybe also the HID mouse example.

    You need to stitch together these examples. 

     

    which uses whitelisting and bonding, but it's only supporting single links (because it uses the advertising module).

     That is not true. You can support multiple connections when the advertising module is used. Just look at the multiperipheral example.

     

    I some sort of managed to include those two together, but then sometimes the softdevice asserts.

     What did that look like? What happened when the "softdevice asserted"? Can you show me a screenshot, or any other observation you did to conclude with that?

    Best Regards,
    Edvin

  •  That is not true. You can support multiple connections when the advertising module is used. Just look at the multiperipheral example.

    The advertising API notes: "Note: The Advertising Module supports only applications with a single peripheral link."

    The multiperipheral example doesn't use the advertising module if I understand correctly. It uses the Advertising and Scan Response Data Encoder

    Or am I confusing things?

    What did that look like? What happened when the "softdevice asserted"? Can you show me a screenshot, or any other observation you did to conclude with that?

    For instance, when I disconnect, I get:

    00> <info> app: Connection with link 0x0 established.
    00> <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 27 bytes.
    00> <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: max_rx_octets: 27
    00> <debug> nrf_ble_gatt: max_tx_octets: 27
    00> <debug> nrf_ble_gatt: max_rx_time: 328
    00> <debug> nrf_ble_gatt: max_tx_time: 2120
    00> <debug> app: PHY update request.
    00> <error> app: Fatal error

    But it doesn't happen always, but the fact that it happens makes it unreliable. 

    So probably something is wrong in my code. 

    I can send you my code, how can I do that?

  • Gueston said:

    The multiperipheral example doesn't use the advertising module if I understand correctly. It uses the Advertising and Scan Response Data Encoder

    Or am I confusing things?

     You are absolutely correct. I didn't realize this before. 

     

    Gueston said:

    So probably something is wrong in my code. 

    I can send you my code, how can I do that?

     The log is a good thing. It is probably something you can fix. 

    Whenever you see "Fatal error" in the log, it means that one of your APP_ERROR_CHECK(err_code); has received an err_code != 0.

    To find out which one that triggered it, add "DEBUG" to your preprocessor definitions. Let me know what IDE you are using if you are not sure how to do this. 

    When you added this, the log should point to an APP_ERROR_CHECK(err_code) in your project, and a value for err_code. Which one does it point to, and what function returned that err_code, and what value did err_code have?

    BR,
    Edvin

  • See the log below:

    00> <info> app: Connection with link 0x0 established.
    00> <info> app:   m_whitelist_peer_cnt 1, MAX_PEERS_WLIST 8
    00> <info> app: Fast advertising.
    00> <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 27 bytes.
    00> <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: max_rx_octets: 27
    00> <debug> nrf_ble_gatt: max_tx_octets: 27
    00> <debug> nrf_ble_gatt: max_rx_time: 328
    00> <debug> app: PHY update request.
    00> <debug> app: pm_whitelist_get returns 0 addr in whitelist and 0 irk whitelist
    00> <error> app: ERROR 12804 [Unknown error code] at ../../../main.c:252
    00> PC at: 0x00032B87

    The code at line 252 (and 251 which is the function it checks):

        err_code = pm_device_identities_list_set(peer_ids, peer_id_count);
        APP_ERROR_CHECK(err_code);

    This only happens when the central disconnects. 

  • Hello,

    Thank you. Just to show you how I usually look up these values:

    The error handler prints a decimal number, but the SDK return values are typically hexadecimal (at least the large ones). Decimal 12804 = hecadecimal 0x3204.

    The error codes are usually divided into groups based on the first and second integer. To explain, look at the file nrf_error.h. In that file, all the common error codes are listed. That is, 0-19 (decimal). Above that, you can see:

    #define NRF_ERROR_BASE_NUM      (0x0)       ///< Global error base
    #define NRF_ERROR_SDM_BASE_NUM  (0x1000)    ///< SDM error base
    #define NRF_ERROR_SOC_BASE_NUM  (0x2000)    ///< SoC error base
    #define NRF_ERROR_STK_BASE_NUM  (0x3000)    ///< STK error base

    So since your error code is starting with 3, it is probably using the STK base, NRF_ERROR_STK_BASE_NUM.

    If you search your project for this name (NRF_ERROR_STK_BASE_NUM), you will see a couple of hits in the file ble_err.h. When you open that file, you will see:

    #define NRF_L2CAP_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
    #define NRF_GAP_ERR_BASE               (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
    #define NRF_GATTC_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
    #define NRF_GATTS_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */

    Since your error code starts with 0x32... it is coming from the NRF_GAP_ERR_BASE. Searching for this macro, you will find some hits in ble_gap.h, and there it is:

    BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE  = (NRF_GAP_ERR_BASE + 0x004) = 0x3204.

    If you search for BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE in your project, you will see that it is used in peer_manager.h, specifically in the description for pm_device_identities_list_set():

    * @retval BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE   If the device identities list is in use and
     *                                                  cannot be set.

    So this means that the device identities list is currently in use, and can't be changed. If you at that point in time is scanning or advertising, this return value is expected. To work around this, you need to stop scanning and advertising, then call pm_device_identities_list_set(), and then resume scanning or advertising. 

    The reason you are seeing this error is probably because the hids keyboard example only supports one connection, and will not be advertising or scanning when it tries to edit the device identities list. 

Related