Pairing specific pairs among many

Hello, we're trying to make products using BLE with nRF52840(central) and nRF52833(peripheral).

We did make custom boards and also made a program that once paired(bonded), it won't connect with others.

(eg, once nRF52840 and nRF52833 is paired, it will not connect with others)

We were wondering is there a way to make specific central connect with specific peripheral?

Is there a way to make each central/peripheral unique so that pairing process can be done without interference?

We got concerned that wrongly paired(or bonded) devices might ship out.

At our current stage, pairing wrong central/peripheral is possible.

Other infos.

nRF52840-central has 2 buttons, while nRF52833-peripheral has none

We're using SDK 17.1.0 S140 Segger Studio

has NUS(communication) and BAS(battery check) BLE services

thanks

edit:

extra question: is there a way to write certain unique number/MAC address on flash during flash write and then read it during application?

How do I know which address of flash is used or not?(want to avoid  collision with bonded info)

Is there a download tool beside nRF Connect Programmer?

  • Thanks for the answer.

    I guess if I increase whitelist, the FDS part will increase too.

    About whitelist, I can't find much about whitelist create in SDK 17.1.0 version. Is there a way to create a whitelist without connection/pairing/bonding? (I have other address for connection)

    Old version SDK has pm_whitelist_create but newer version does not.

  • Hi,

    June20 said:
    I guess if I increase whitelist, the FDS part will increase too.

    The whitelist itself does not rely on FDS. But you need to store the information somewhere, and the most typical use case is to whitelist bonded peers. Those are stored in FDS (by the peer manager). The FDS pages are determined by sdk_config.h though, so this is static. It is just that the more data you have, the more of the allocated space you use. You can read more about FDS here if that is relevant.

    June20 said:
    About whitelist, I can't find much about whitelist create in SDK 17.1.0 version. Is there a way to create a whitelist without connection/pairing/bonding? (I have other address for connection)

    Yes, even though the SDK examples use bonding, you can do it with a raw address as well. Note one important point, though. Phones typically use resolvable addresses, and you only get the identity resolution key (IRK) via bonding. So whitelisting will not work properly with phones unless you bond with them. That said, to use whitelisting with specific addresses you build the whitelist yourself instead of using the peer manager (pm_whitelist_get()). So if you search for BLE_ADV_EVT_WHITELIST_REQUEST you can see where the whitelist is provided to the BLE stack, and this is where you need to insert your "manually" built whitelist instead.

  • Thanks for the reply

    I will be using nRF52840 and nRF52833 so I don't think I will use IRK.

    peripheral/ble_app_hids_keyboard has case BLE_ADV_EVT_WHITELIST_REQUEST: and pm_whitelist_get, but not pm_whitelist_set. pm_whitelist_set has weird parameter which is pm_peer_id_t also uint16_t. I don't think the parameter has to do with ble address (48bit or 6byte + BLE_GAP_ADDR_TYPE_RANDOM_STATIC).

    I did stumble upon sd_ble_gap_whitelist_set() but it did not affect pm_whitelist_get().

    Can you tell me how to add whitelist manually using address?

    EDITS:

    sample of code will be very nice, I can't really pull much from s140 hids keyboard BLE_ADV_EVT_WHITELIST_REQUEST.

  • Hi Joon,

    None of the pm_* APIs are relevant if you don't use bonding. I referred to pm_whitelist_get() just to see where it gets the whitelist (which is simply a list of addresses) from the peer manager and how to use it.

    You can see a very simple way to do whitelisting manually here:

    diff --git a/examples/ble_peripheral/ble_app_hrs/main.c b/examples/ble_peripheral/ble_app_hrs/main.c
    index 8e7c6f1..4bbfadc 100644
    --- a/examples/ble_peripheral/ble_app_hrs/main.c
    +++ b/examples/ble_peripheral/ble_app_hrs/main.c
    @@ -130,6 +130,8 @@
     
     #define DEAD_BEEF                           0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
     
    +#define WHITELIST_ADDRESS {0xD8, 0x1E, 0x41, 0x50, 0x54, 0xE4}
    +
     
     BLE_HRS_DEF(m_hrs);                                                 /**< Heart rate service instance. */
     BLE_BAS_DEF(m_bas);                                                 /**< Structure used to identify the battery service. */
    @@ -189,6 +191,27 @@ static void delete_bonds(void)
     }
     
     
    +/**@brief Function for setting filtered whitelist.
    + *
    + * @param[in] skip  Filter passed to @ref pm_peer_id_list.
    + */
    +static void whitelist_set(void)
    +{
    +    ret_code_t err_code;
    +
    +    ble_gap_addr_t whitelist_addr =
    +    {
    +        .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
    +        .addr = WHITELIST_ADDRESS
    +    };
    +
    +    ble_gap_addr_t const * const p_whitelist_addr = &whitelist_addr;
    +
    +    err_code = sd_ble_gap_whitelist_set(&p_whitelist_addr, 1);
    +    APP_ERROR_CHECK(err_code);
    +}
    +
    +
     /**@brief Function for starting advertising.
      */
     void advertising_start(bool erase_bonds)
    @@ -202,6 +225,8 @@ void advertising_start(bool erase_bonds)
         {
             ret_code_t err_code;
     
    +        whitelist_set();
    +
             err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
             APP_ERROR_CHECK(err_code);
         }
    @@ -663,9 +688,9 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
     
         switch (ble_adv_evt)
         {
    -        case BLE_ADV_EVT_FAST:
    -            NRF_LOG_INFO("Fast advertising.");
    -            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    +        case BLE_ADV_EVT_FAST_WHITELIST:
    +            NRF_LOG_INFO("Fast advertising with whitelist.");
    +            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_WHITELIST);
                 APP_ERROR_CHECK(err_code);
                 break;
     
    @@ -673,6 +698,25 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
                 sleep_mode_enter();
                 break;
     
    +        case BLE_ADV_EVT_WHITELIST_REQUEST:
    +        {
    +            NRF_LOG_INFO("Whitelist request")
    +            ble_gap_addr_t whitelist_addr =
    +            {
    +                .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
    +                .addr = WHITELIST_ADDRESS
    +            };
    +
    +            // Apply the whitelist.
    +            err_code = ble_advertising_whitelist_reply(&m_advertising,
    +                                                       &whitelist_addr,
    +                                                       1,
    +                                                       NULL,
    +                                                       0);
    +            APP_ERROR_CHECK(err_code);
    +        }
    +        break;
    +
             default:
                 break;
         }
    @@ -881,6 +925,7 @@ static void advertising_init(void)
         init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
         init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
     
    +    init.config.ble_adv_whitelist_enabled          = true;
         init.config.ble_adv_fast_enabled  = true;
         init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
         init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    

    (this is not very elegant as I just did minimal changes needed for the HRS example without caring about code duplication. As you can see if you compare with the HID mouse example it is basically the same thing, just that you provide the list of addresses (or just one address in this case) yourself instead of getting it from the peer manager.

  • Perfect!

    Could you be so kind to do another one for central/scanner please?

    Edit: Central looks very tricky. hrs_c has whitelist-ing stuffs but it's related to peers

    pm_peer_id_t says it is uint16_t, how does it carry whitelist data??

    does central has something like ble_advertising_whitelist_reply()?

    my central's NRF_BLE_SCAN_EVT_CONNECTED display totally different ble address compare to my peripheral's device address(NRF_FICR->DEVICEADDR[0,1]), is it possible?

    Also,

    Peripheral's side doesn't respond much but central's side constantly find connection and get disconnected for reason 2 and 3e

    what does it mean unknown connection identifier?

    I believe BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHEDd is due to constantly trying to connect?

Related