Unable to change Bluetooth name with Zephyr

Hello,

I'm trying to change Bluetooth name at runtime using Zephyr on the nRF700-DK. So for now I have a name defined with CONFIG_BT_DEVICE_NAME in my prj.conf that I tried to override using the following code (based on this ticket ). Unfortunately, my device always appears with the old name. Is something missing in my prj.conf file ?

static const struct bt_data sd[] = 
{
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, MY_SERVICE_UUID),
};


static struct bt_data ad[] = 
{
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR), BT_LE_ADV_OPT_USE_NAME ),
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};

static void bt_ready(int err)
{
	if (err) 
	{
		printk("BLE init failed with error code %d\n", err);
		return;
	}
	//Configure connection callbacks
	bt_conn_cb_register(&conn_callbacks);

	//Initialize services
	err = hc_bt_nus_init();
	if(err){
		printk("Failed to init NUS service (err:%d)\n", err);
		return;
	}

	err = hc_ble_identity_init();
	if(err){
		printk("Failed to init Identity service (err:%d)\n", err);
		return;
	}

	bt_set_name(BLE_NAME);
	bt_le_adv_update_data(ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));

	//Start advertising
	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;
	}

	printk("Advertising successfully started\n");

	k_sem_give(&ble_init_ok);
}

int hc_bt_init(){
    int err = 0;
    
    err = bt_enable(bt_ready);

    if (err) 
	{
		printk("BLE initialization failed\n");
		printk("Error is %d\n", err);
	}

	err = k_sem_take(&ble_init_ok, K_MSEC(500));

    if (!err) 
	{
		printk("Bluetooth initialized\n");
	} else 
	{
		printk("BLE initialization did not complete in time\n");
	}

	return err;
}

prj.conf :

CONFIG_NEWLIB_LIBC=y

#Global attroibutes
CONFIG_GPIO=y

#SPI attributes
CONFIG_SPI=y

#PWM attributes
CONFIG_NRFX_PWM0=y

#BLE attributes
CONFIG_BT=y
CONFIG_BT_NUS=y
CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_MAX_CONN=1
CONFIG_BT_L2CAP_TX_BUF_COUNT=5
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="My_Device"
CONFIG_BT_DEVICE_APPEARANCE=962

CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_DEVICE_NAME_MAX=30

#Tests
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

Thank you,
Best regards

Parents
  • [Update] Something I missed in this thread was the usage of the BT_LE_ADV_OPT_USE_NAME option, so I changed my code to

    static void bt_ready(int err)
    {
    	if (err){
    		printk("BLE init failed with error code %d\n", err);
    		return;
    	}
    
    	struct bt_le_adv_param param;
    	memcpy(&param, &BT_LE_ADV_CONN_NAME, sizeof(struct bt_le_adv_param));
    
    	bt_set_name("BLETestName");
    
    
    	//Configure connection callbacks
    	bt_conn_cb_register(&conn_callbacks);
    
    	//Initialize services
    	err = hc_bt_nus_init();
    	if(err){
    		printk("Failed to init NUS service (err:%d)\n", err);
    		return;
    	}
    
    	err = hc_ble_identity_init();
    	if(err){
    		printk("Failed to init Identity service (err:%d)\n", err);
    		return;
    	}
    
    	//Start advertising
    	err = bt_le_adv_start(&param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    	if (err) 
    	{
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    
    	printk("Advertising successfully started\n");
    	k_sem_give(&ble_init_ok);
    }

    as it appears that BT_LE_ADV_CONN_NAME is BT_LE_ADV_CONN with the addition of the mentioned option.

    With this code, bt_le_adv_start() function returns -22 error.

    Bluetooth advertising is working fine when I use BT_LE_ADV_CONN instead of BT_LE_ADV_CONN_NAME but it still advertise with the name defined by CONFIG_BT_DEVICE_NAME in prj.conf instead of my new name.

    Thank you,
    Regards

Reply
  • [Update] Something I missed in this thread was the usage of the BT_LE_ADV_OPT_USE_NAME option, so I changed my code to

    static void bt_ready(int err)
    {
    	if (err){
    		printk("BLE init failed with error code %d\n", err);
    		return;
    	}
    
    	struct bt_le_adv_param param;
    	memcpy(&param, &BT_LE_ADV_CONN_NAME, sizeof(struct bt_le_adv_param));
    
    	bt_set_name("BLETestName");
    
    
    	//Configure connection callbacks
    	bt_conn_cb_register(&conn_callbacks);
    
    	//Initialize services
    	err = hc_bt_nus_init();
    	if(err){
    		printk("Failed to init NUS service (err:%d)\n", err);
    		return;
    	}
    
    	err = hc_ble_identity_init();
    	if(err){
    		printk("Failed to init Identity service (err:%d)\n", err);
    		return;
    	}
    
    	//Start advertising
    	err = bt_le_adv_start(&param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    	if (err) 
    	{
    		printk("Advertising failed to start (err %d)\n", err);
    		return;
    	}
    
    	printk("Advertising successfully started\n");
    	k_sem_give(&ble_init_ok);
    }

    as it appears that BT_LE_ADV_CONN_NAME is BT_LE_ADV_CONN with the addition of the mentioned option.

    With this code, bt_le_adv_start() function returns -22 error.

    Bluetooth advertising is working fine when I use BT_LE_ADV_CONN instead of BT_LE_ADV_CONN_NAME but it still advertise with the name defined by CONFIG_BT_DEVICE_NAME in prj.conf instead of my new name.

    Thank you,
    Regards

Children
  • It seems that BT_LE_ADV_CONN_NAME  option is not mandatory and that bt_le_adv_update_data() just need to be called after bt_le_adv_start()

    [EDIT] It that behaviour depend on the used Bluetooth application, ly smartphone sees the new name but nRFConnect sees the old one...

    [EDIT 2] : nRFConnect seems to use the name defined in the scan data instead of the advertising data, using my new name in the scan data seems to mitigate my issue

    Regards

Related