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

NCS/Zephyr: how to enable whitelist

My device is peripheral. I added a few lines before the advertisement start in main(). The whole project is in main and simply advertise and get connected and bonded.

    printk("Clear whitelist... ... ...\n", err);
	bt_le_whitelist_clear();
	bt_foreach_bond(BT_ID_DEFAULT, update_whitelist, NULL);
	
    printk("Start advertising... ... ...\n", err);
	err = bt_le_adv_start(BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE|BT_LE_ADV_OPT_FILTER_CONN,
						160, 1600, NULL),
						ad, ARRAY_SIZE(ad),
						sd, ARRAY_SIZE(sd));

update_whitelist() is like this:

static void update_whitelist(const struct bt_bond_info *info, void *user_data){
	char addr[BT_ADDR_LE_STR_LEN];
	bt_addr_le_to_str(&info->addr, addr, sizeof(addr));

	int err = bt_le_whitelist_add(&info->addr);
	if (err){
		printk("whitelist add: %s FAILED!\n", addr);
		error(99);
	}else{
		printk("whitelist add: %s\n", addr);
	}
}

Obviously this doesn't work. After bonded with another device, I reset my device. It seems bt_foreach_bond() doesn't find any bonded device because it doesn't print out anything. I verified bonding is successful. By looking at the serial debug output, I suspect these whitelist calls are too early because the two line "Clear whitelist" and "Start advertising" appeared ahead of board initialization. Is it something to worry? But the advertising works fine. Adding delay also doesn't solve the problem. So I'm not sure what is the problem. Maybe I didn't use the whitelist API correctly?

Any idea? Thanks!

Parents
  • Hi Bluebeam,

    Could test and make sure that the bond information is stored properly. The bt_foreach_bond() should return the for each of the peers you bonded. Regardless if you call bt_le_whitelist_clear() or not. 

    Please make sure you turned on CONFIG_BT_SETTINGS and the flash setting:


    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y

  • Aha... I missed CONFIG_SETTINGS. I must somehow mistaken that same as CONFIG_BT_SETTINGS. There're so many CONFIGs. How can I ever know which one is needed for a particular feature... it's frustrating.

    Back to whitelist... ok I think it's working now. bt_foreach_bond() does find all the existing bondings now.

    New question: it seems if the whitelist is empty and filtering is enabled, it will block any incoming connection. Is that expected? If so, I'll need to manually change the advertising options based on whether whitelist is empty or not? Is there any API can tell you how many bonded devices or how many devices in the whitelist?

    Further, how to delete the Settings? I can't find any information regarding how BLE module makes use of storage system and how bondings are stored, and how to delete the bonding. I do notice there's a bt_unpair() which works for a single bonding.Further more, is there something like Device manager/Peer manager in NCS? Or no need for them any more?

    Thanks for help!

  • Hi BlueBeam. 
    I would suggest to have a look at my blog here. It has some information about delete bond information and using filter. 
    You may want to catch scan_filter_no_match() and then manually/directly establish a connection when you acquired the address of the advertiser.

  • Hi Hung,

    Thanks for the info. The blog helps in overall understanding. But my device is peripheral. The main goal is to use whitelist to block unknown central to connect. But we have to allow the first central to connect and bond and then put it into the whitelist. It seems if advertise with an empty whitelist it will block any central device to connect. So I'll need to figure out if there's existing bonded device and adjust the white list.

    Another question, I don;t quite understand why there're so many CONFIG_xxxx. Are they completely compile time thing like macro? Can you change it at run time? For example I figured out I need these CONFIG for fixed passkey pairing:

    CONFIG_BT_FIXED_PASSKEY=y
    CONFIG_BT_SMP_SC_ONLY=y
    CONFIG_BT_TINYCRYPT_ECC=y

    Can these be changed during runtime? Is it possible to switch back and forth between simple pairing (just works) and fixed postcode pairing during run time? That's one of our application's requirements...

    Thanks!

Reply
  • Hi Hung,

    Thanks for the info. The blog helps in overall understanding. But my device is peripheral. The main goal is to use whitelist to block unknown central to connect. But we have to allow the first central to connect and bond and then put it into the whitelist. It seems if advertise with an empty whitelist it will block any central device to connect. So I'll need to figure out if there's existing bonded device and adjust the white list.

    Another question, I don;t quite understand why there're so many CONFIG_xxxx. Are they completely compile time thing like macro? Can you change it at run time? For example I figured out I need these CONFIG for fixed passkey pairing:

    CONFIG_BT_FIXED_PASSKEY=y
    CONFIG_BT_SMP_SC_ONLY=y
    CONFIG_BT_TINYCRYPT_ECC=y

    Can these be changed during runtime? Is it possible to switch back and forth between simple pairing (just works) and fixed postcode pairing during run time? That's one of our application's requirements...

    Thanks!

Children
  • Hi Bluebeam, 
    Could you show how you advertise with an empty whitelist ? 
    My understanding is that if bt_le_whitelist_add() is not called the empty whitelist will not be used to filter out connection. If you can provide a simple example that show the issue I can try to test here and figure out a solution. 

    The CONFIG_XXX is macro configuration so it's not possible to change at runtime. You can read more about the configuration here: https://devzone.nordicsemi.com/nordic/nrf-connect-sdk-guides/b/getting-started/posts/nrf-connect-sdk-tutorial---part-2-ncs-v1-4-0#h88sjwm54ukvkhdiku1qtdjdb1685yli

  • Hi Hung,

    I attached my project in the zip file. Thanks for taking a look at this.

    Now I tested it more carefully. I think I might misunderstood the following option. With this option as part of the advertising parameters, the empty whitelist will block any connection. Then I tried without this, just using the BT_LE_ADV_OPT_CONNECTABLE, then empty whitelist will not block any connection. So that works if it's the very first connection with no existing bonding. Then I realized with simply this option alone, a whitelist with some entries will work as expected: block unknown connection and only allow devices in the whitelist.

        /** Use whitelist to filter devices that can connect. */
        BT_LE_ADV_OPT_FILTER_CONN = BIT(7),

    So in summary, just use the BT_LE_ADV_OPT_CONNECTABLE option for advertising, whitelist works as what I expected. So I'm confused as to what BT_LE_ADV_OPT_FILTER_CONN(and BT_LE_ADV_OPT_FILTER_SCAN_REQ are for).

    Other question, just to confirm again that it's not possible to switch between simple pairing (JustWorks) and passcode pairing right? That's currently our application wants to do. I want to be very sure about this so I can ask designer to change it.

    I guess it's the same for things like max connection/pairing, since they are defined by CONFIG_BT_MAX_CONN, CONFIG_BT_MAX_PAIRED?

    Thanks!

    whitelist-fd4b6b7.zip

  • Hi Bluebeam, 

    What you described is about right. 
    Here is what in the spec: 

    So there is no mentioning about exception when there is an empty whitelist. Meaning if the whitelist is empty and if you use BT_LE_ADV_OPT_CONNECTABLE it won't allow connection from any central (either option #3 or #4). 

    So I was wrong when thinking if you don't add any device to the whitelist the whitelist will not be used. It's not automatically switch to option 1 when you use BT_LE_ADV_OPT_FILTER_CONN or BT_LE_ADV_OPT_FILTER_SCAN_REQ). See also: get_filter_policy() in adv.c 

    It's a little bit strange to me that even when you don't use BT_LE_ADV_OPT_FILTER_CONN   you still have the whitelist working. Did you use BT_LE_ADV_OPT_FILTER_SCAN_REQ ? 


    There could be a chance that the central use the scan response packet to filter your device and without the scan response they won't send the connect request. 

    Otherwise, this would mean that there is no way to advertise without whitelist unless we empty the whitelist. 

  • Hi Hung,

    Thanks for providing the info. It seems that the confusion comes from whether "whitelist not in use" is same as "white list is empty".

    Given that an empty white list is set (as I did in my code), then my test results regarding the advertising parameters being used are like this:

    -...CONNECTABLE:                             any device can connect
    -...CONNECTABLE|FILTER_SCAN_REQ:             any device can connect
    -...CONNECTABLE|FILTER_CONN:                 not able to connect
    -...CONNECTABLE|FILTER_SCAN_REQ|FILTER_CONN: not able to connect

    The scan policy does not affect connection. As soon as you use connection filter policy, the empty whitelist will block any connection. So it's pretty clear an empty whitelist is seen as "white list in use". So for the time being I'll need to manually look inside the white list and decide how to set up the adv parameters. I'm glad we got this figured out.

    And once more, I'd like to confirm with you that it's not possible to switch between Simple Pairing and Passcode Pairing right? Since they are defined by macros? (And in general this is the case for any feature defined by CONFIG_xxx macro) Sorry to keep asking you it. I just want to be sure about it so I can tell product manager that this is not possible and you have to change requirements. :-D Thanks!

  • Hi BlueBeam, 

    When you configure something with the CONFIG_xxx macro, it can't be changed in runtime. 

    However, what you are asking for to choose between just work and passkey pairing, it's flexible. It depends on the configuration of your characteristic if it requires MITM (passkey, OOB, nummeric comparison) or not. Please have a look at here. If a characteristic is defined with security level higher than the current security level established by pairing (just work for example) the read/write request will be rejected. 

    The configuration CONFIG_BT_FIXED_PASSKEY is just to set-up that if passkey is used, a pre-defined passkey (bt_passkey_set())will be used instead of being generated randomly.  It doesn't define that the device will reject justwork pairing. 

    CONFIG_BT_MAX_CONN, CONFIG_BT_MAX_PAIRED can't be changed in runtime. 

Related