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

Setting the BLE Public Address on nRF5340

I am trying to set the public ble mac address from the application core of a nRF5340, I understand that I need to use bt_ctlr_set_public_addr() but I can't seem to get my project to compile when I include bluetooth/controller.h, due to the source file that defines bt_ctlr_set_public_addr() not being added to the project. I am using the SoftDevice currently that is CONFIG_BT_LL_SOFTDEVICE. So my question is what configurations do I need to set to make this work? I have also been thinking that it might be that it is only possible to use the function from the network core, if this is the case then where do I find the source so that I can make the changes that I need or should I instead of change the source use rpc?

If I forgot to mention something important then I apologise in advance.

  • Hi,

    The developers got back to me now.

    They confirmed that what I suggested in my previous reply is possible, and that you just need to add an implementation of this in the hci_rpmsg driver. You can also use the vendor specific HCI command "Zephyr Write BD ADDR, sdc_hci_cmd_vs_zephyr_write_bd_addr, to set the public address, which is supported by the SoftDevice Controller. To use this you must enable CONFIG_BT_HCI_VS and CONFIG_BT_HCI_VS_EXT. See API documentation — nrfxlib 1.6.99 documentation (nordicsemi.com) for more information.

    Best regards,

    Marte

  • Sorry that I did not respond sooner but some new priorities came up so I did not get time to look at this before my holiday.

    I was stuck for a bit because I had not understood that everything needed to talk with the network core was already in place.

    But if anyone else ends up on this page here is how I did it.

    main.c

    #include <bluetooth/hci_vs.h>
    #include <settings/settings.h>
    #include <logging/log.h>
    
    LOG_MODULE_REGISTER(ble);
    #define REPORT_ERROR(_ERR_CODE_)	LOG_WRN("Error: %d\tFun: %s:%d\tFile: %s", (_ERR_CODE_), __func__, __LINE__, __FILE__)
    
    static char ble_device_name[30];
    static bt_addr_le_t addrs[1];
    
    void ble_set_mac(bt_addr_t* addr) {
    	struct net_buf *buf;
    	int err;
    
    	buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_BD_ADDR, sizeof(*addr));
    	if(!buf) {
    		REPORT_ERROR(-ENOBUFS);
    	}
    
    	net_buf_add_mem(buf, addr, sizeof(*addr));
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_BD_ADDR, buf, NULL);
    	if(err) {
    		REPORT_ERROR(err);
    	}
    }
    
    uint8_t* ble_get_mac() {
    	size_t count = 1;
    	bt_id_get(addrs, &count);
    	return addrs[0].a.val;
    }
    
    int ble_advertise() {
    	uint8_t* mac = ble_get_mac();
    	snprintk(ble_device_name, 30, "%02X%02X%02X%02X%02X%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
    
    	struct bt_data adx[] = {
    		BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    		BT_DATA(BT_DATA_NAME_COMPLETE, ble_device_name, strlen(ble_device_name)),
    	};
    
    	int err = bt_le_adv_start(BT_LE_ADV_CONN, adx, ARRAY_SIZE(adx), NULL, 0);
    	if(err) {
    		LOG_ERR("Advertising failed to start (err %d)", err);
    	} else {
    		LOG_INF("Advertising started");
    	}
    	return err;
    }
    
    void main(void) {
    	int err = bt_enable(NULL);
    	if(err) {
    		LOG_ERR("Failed to enable Bluetooth (err: %d)", err);
    		return;
    	}
    	
    	bt_addr_t addr = {{0xFE, 0xCA, 0xA0, 0xAC, 0xDC, 0xBA}};
    	ble_set_mac(&addr);
    
    	settings_load();
    	
    	ble_advertise();
    	
    	LOG_INF("Bluetooth initialized");
    	
    	while(true) {
    		k_msleep(100);
    	}
    }
    

    prj.conf
    # Config BT
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_APPEARANCE=833
    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    CONFIG_BT_MAX_CONN=1
    
    CONFIG_BT_HCI_VS=y
    CONFIG_BT_HCI_VS_EXT=y
    
    # Config logger
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=n
    
    # Enable Settings
    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y

  • Hi,

    I hope you had a nice vacation, and I am glad to hear that you figured it out.

    Thank you so much for sharing what you did here for others to find, it is very appreciated!

    Best regards,

    Marte

  • hi Marte,

       I follow Capn Odin's sample code and it can change the BLE mac address after system just boot up.

       But after boot up, I want to change  the BLE mac address again, it doesn't work and the ble MAC address keep unchanged, it is expected?  Is it possible to change the desired BLE mac address at real time without HW reset?

  • This was helpful to me, so just to add on a bit more:

    This code didn't work for me until I added BT_LE_ADV_OPT_USE_IDENTITY to my advertising params.

Related