How to use public-addr and non-resolvable-addr on nrf connect SDK

I want to use  public-addr and non-resolvable-addr for advertising on nrf connect SDK.

I was able to advertise using a random static addr.

But,
1. can not set public addr.
2. can not create non-resolvable-addr 's bt_id.

Following test code.

static bt_addr_le_t random_bdaddr = {
	.type = BT_ADDR_LE_RANDOM,
	.a = {
		.val = {0xC1, 0x11, 0x11, 0x11, 0x11, 0xC1},
	}
};

static struct bt_le_adv_param adv_param = {
	.id				= 0,
	.options		= BT_LE_ADV_OPT_USE_IDENTITY | BT_LE_ADV_OPT_EXT_ADV,
	.interval_min	= 0x20,
	.interval_max	= 0x20,
};

	bt_ctlr_set_public_addr(public_addr);
	(or sdc_hci_cmd_vs_zephyr_write_bd_addr(&public_addr);)

	bt_enable(NULL);

	int id0 = bt_id_create(&random_bdaddr, NULL);

	bt_addr_le_t nrpa_bdaddr;
	bt_addr_le_create_nrpa(&nrpa_bdaddr);
	int id1 = bt_id_create(&nrpa_bdaddr, NULL); /* this is ERROR!! */

	adv_param.id = 0; /* bt_id */
	bt_le_ext_adv_create(&adv_param, &adv_cb, &adv);
	bt_le_ext_adv_set_data(adv, bdata, 1, NULL, 0);
	bt_le_ext_adv_start(adv, &adv_start_param);

  • Hi,

    It is not allowed to use a public identity address here, only a static random one. That is enforced by the stack. You can see an example of making a static random identity and using that here (which is your sample slightly modified):

    /* main.c - Application main entry point */
    
    /*
     * Copyright (c) 2015-2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/util.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <sdc_hci_vs.h> 
    #include <mpsl_timeslot.h>
    #include <mpsl.h>
    #include <hal/nrf_timer.h>
    
    static void adv_sent(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_sent_info *info);
    
    
    static struct bt_le_adv_param adv_param = {
    	.options	= BT_LE_ADV_OPT_USE_IDENTITY,
    	.interval_min	= 0x00a0,
    	.interval_max	= 0x00a0,
    };
    
    static const struct bt_le_ext_adv_cb adv_cb = {
    	.sent			= adv_sent,
    };
    
    static const uint8_t ManufData[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    static const struct bt_data bdata[1] = {
    	BT_DATA(0xFF, ManufData, sizeof(ManufData))
    };
    
    static struct bt_le_ext_adv* ext_adv0;
    static struct bt_le_ext_adv_start_param adv_start_param = { 0, 0 };
    
    static void adv_sent(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_sent_info *info)
    {
    }
    
    static int set_addr(void)
    {
    	int id;
    
    	static bt_addr_le_t addr = {
    		.type		= BT_ADDR_LE_RANDOM,
    		.a.val		= {0xba, 0xde, 0xba, 0x11, 0xca, 0xfe},
    	};
    
    	id = bt_id_create(&addr, NULL);
    	if (id < 0) {
    		printk("Creating new ID failed (%d)\n", id);
    	}
    	else
    	{
    		printk("Id created: %i\n", id);
    	}
    
    	return id;
    }
    
    void main(void)
    {
    	int err;
    	int id;
    
    	printk("Starting Scanner/Advertiser Demo\n");
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	id = set_addr();
    
    	adv_param.id = id;
    
    	err = bt_le_ext_adv_create(&adv_param, &adv_cb, &ext_adv0);
    	if (err) {
    		printk("adv create failed (err %d)\n", err);
    		return;
    	}
    
    	err = bt_le_ext_adv_set_data(ext_adv0, bdata, 1, NULL, 0);
    	if (err) {
    		printk("adv set data failed (err %d)\n", err);
    		return;
    	}
    
    	err = bt_le_ext_adv_start(ext_adv0, &adv_start_param);
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    
    
    	do {
    		k_sleep(K_MSEC(400));
    
    	} while (1);
    }
    

  • Really?

    So I can't use public addr for advertising?

  • No, you can use a public address for advertising. And that works with some APIs in nRF Connect SDK 2.2.0, so for instance if you just call bt_ctlr_set_public_addr() before bt_enable() in the beacon sample, it works out of the box. However you cannot create a public ID with br_id_create(), which is what I was referring to in my previous post.

    I was wrong about public address in extended advertising,  though. That should work, but does not due to a bug. This is fixed in this PR.

Related