How to use bt_ctlr_set_public_addr()

Hi!

This is my setup:
- dev tools: VSCode + nRF Connect extension
- hardware: nRF52840DK
- SDK: nRF Connect SDK v2.1.0
- sample project: central_and_peripheral_hr

By default, the example app uses a random address for advertising.  I want to make it a fixed public address.

Here is a snippet of my code.

	{
		uint8_t  BDA[BT_ADDR_SIZE] = { 0x46, 0xda, 0x08, 0x88, 0x15, 0x00 } ;
		bt_ctlr_set_public_addr(BDA);
	}
	err = bt_enable(NULL);
	if (err) {
		return;
	}

	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = bt_hrs_client_init(&hrs_c);
	if (err) {
		printk("Heart Rate Service client failed to init (err %d)\n", err);
		return;
	}

	scan_init();

	err = scan_start();
	if (err) {
		return;
	}

	printk("Scanning started\n");

	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
			      sd, ARRAY_SIZE(sd));
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}

Other than the inserted call to bt_ctlr_set_public_addr(), there are no other changes to the example code.
The first time I run it, bt_ctlr_set_public_addr() did not take effect.  The app is still advertising with a random address.

Then I comment out the call to settings_load().  I get the error below:

No ID address. App must call settings_load()

For the third run, I put back the call to settings_load().  I still get the "No ID address" error, but this time bt_ctlr_set_public_addr() took effect and the app is advertising with the address that I specified.


Can someone please explain (or point to the document with the explanation) what is going on?  How can I make bt_ctlr_set_public_addr() work the first time?

Thanks and best regards,
Joey

Parents Reply Children
  • Hello Hieu!

    Thank you so much for the response.

    Somehow I could no longer replicate the scenario I described above.  Anyway, it was just my initial attempts with  bt_ctlr_set_public_addr().

    I now have another scenario (which is closer to what we want to achieve) that is repeatable.

    	bt_ctlr_set_public_addr(m_BDA);
    	err = bt_enable(NULL);
    	load_settings();
    	while (1) {
    		k_sleep(K_SECONDS(10));
    		start_scan_and_gather_info();
    		k_sem_take(&wait_for_info_available,K_FOREVER);
    
    		if  ( do_connectable )
    		{
    			adv_param->options = BT_LE_ADV_OPT_CONNECTABLE;
    		}
    		else
    		{
    			adv_param->options = BT_LE_ADV_OPT_NONE;
    		}
    
    		err = bt_le_adv_start(adv_param, m_adv_data, m_adv_count, p_resp_data, m_resp_count);
    		k_sleep(K_SECONDS(10));
    		bt_le_adv_stop();
    	}

    The value of  do_connectable  is determined in another thread, depending on the results of the scan.

    When do_connectable is true, the advertising proceeds using the public address that I specified.   However, when it is false (advertising PDU type is ADV_NONCONN_IND), it uses a random address.

    BTW, I am flash the board using the Debug tool in the nRF Connect extension of VSCode

    Best regards,
    Joey

  • Hi Joey,

    It seems that when the advertising is non-connectable, you need to use the advertising option BT_LE_ADV_OPT_USE_IDENTITY for the device to advertise with its public address.

    So instead of BT_LE_ADV_OPT_NONE, use something that set BT_LE_ADV_OPT_USE_IDENTITY bit.

    Best regards,

    Hieu

  • Hi Hieu!

    That did the trick! 

    And your reply came just in time.  I was just starting to analyze bt_id_set_adv_own_addr();

    Best regards,

    Joey

Related