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.

Parents
  • 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

  • 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.

Reply Children
No Data
Related