Removing bond from device, Windows keeps trying to connectn

I'm using the BLE mouse example, and the problem I'm having is if I remove the pairing/bonding information from the device, Windows will keep trying to pair with the device:





Essentially, what I want is to only have one bond on the device. If a user presses a button, it should disconnect any active connections, remove the bonding information, then start advertising again. Because Windows has the old bonding information still stored, it tries to connect repeatedly. How can this be avoided, without saying to someone to remove the bond from their PC. If I take for example my MX mouse, I remove the bonding on it, by connecting to a different device, go back into pairing mode, my Windows PC doesn't keep trying to connect to the device. In fact.

Parents
  • Hi,

    There are two separate aspects of this question. First, to remove bonds you use bt_unpair(). If you pass NULL as the second parameters, alls bonds are deleted. You can also delte all identities, in the same way as is done in bt_fast_pair_factory_reset_user_action_perform() in the nrf desktop application.

    When it comes to preventing old computers from connecting, there are a few possible approaches, which can be combined. First of all, you want to advertise with filer accept list (whitelisting). This is demonstrated in this excercise in our BLE dev academy course. This will not prevent the computer from trying to connect, but will make sure that the bluetooth stack ingores the connection attempts. Secondly, a common approach for HID divces that supprort multiple computers via a button or similar, is to use different Bluetooth address for each device. You can do the same even if you only have a single bond at a time, for instance by changing address every time you delete the bond. This way, the computer will see the mouse as a new device after the address is changed, and not try to connect.

  • Ok thanks, I figured it was something to do with changing the device address.

    I've merged the filter accept functions from the academy example, so when the mouse HID example runs, it only allows filtered devices to connect. I've used a button to call BT unpair, the same as the academy example.


    This causes the same problem as before, of Windows keep on trying to connect. This is probably due to me not changing the address.

    My question is, how do I change the address?

    My current implementation is shown below, but I'm getting errors

    		int err = bt_le_adv_stop();
    
    		if (err) {
    			printk("Cannot stop Bluetooth LE advertising (err: %d)", err);
    			return err;
    		}
    		
    		err = bt_unpair(BT_ID_DEFAULT, NULL);
    		if (err) {
    			printk("Cannot unpair for default ID");
    			return err;
    		}
    
    		bt_addr_le_t addr;
    		int err = bt_addr_le_from_str("FF:EE:DD:CC:BB:AA", "random", &addr);
    		if (err) {
    			printk("Invalid BT address (err %d)\n", err);
    		}
    
    		err = bt_id_create(&addr, NULL);
    		if (err < 0) {
    			printk("Creating new ID failed (err %d)\n", err);
    		}
    
    		k_work_submit(&advertise_acceptlist_work);


    Errors

    Accept list cleared succesfully
    Creating new ID failed (err -12)
    Cannot start open advertising (err: -12)
    I: BAS Notifications disabled
    Disconnected from D8:80:83:21:0F:12 (public) (reason 22)
    Advertising with no Accept list
    Advertising successfully started
    Connected D8:80:83:21:0F:12 (public)
    Disconnected from D8:80:83:21:0F:12 (public) (reason 19)
    Advertising with no Accept list
    Advertising successfully started
    Connected D8:80:83:21:0F:12 (public)
    Disconnected from D8:80:83:21:0F:12 (public) (reason 19)
    Advertising with no Accept list
    Advertising successfully started
    Connected D8:80:83:21:0F:12 (public)
    Disconnected from D8:80:83:21:0F:12 (public) (reason 19)

  • Update

    I've changed the code to use bt_id_reset and passed in an address, but getting:

    Accept list cleared succesfully
    Cannot start open advertising (err: -12)

    		err = bt_unpair(BT_ID_DEFAULT, NULL);
    		if (err) {
    			printk("Cannot unpair for default ID");
    			return err;
    		}
    		
    		int err_code = bt_le_adv_stop();
    		if (err_code) {
    			printk("Cannot stop advertising err= %d \n", err_code);
    			return;
    		}
    
    		err_code = bt_le_filter_accept_list_clear();
    		if (err_code) {
    			printk("Cannot clear accept list (err: %d)\n", err_code);
    		} else {
    			printk("Accept list cleared succesfully\n");
    		}
    
    		bt_addr_le_t addr;
    		err = bt_addr_le_from_str("FF:EE:DD:CC:BB:AA", "random", &addr);
    		if (err) {
    			printk("Invalid BT address (err %d)\n", err);
    		}
    
    		for (size_t i = 1; i < CONFIG_BT_ID_MAX; i++) {
    			err = bt_id_reset(i, &addr, NULL);
    			if (err < 0) {
    				LOG_ERR("Cannot reset id %zu (err %d)", i, err);
    				return err;
    			}
    		}
    
    		err_code = bt_le_adv_start(BT_LE_ADV_CONN_NO_ACCEPT_LIST, ad,
    						ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    
    		if (err_code) {
    			printk("Cannot start open advertising (err: %d)\n", err_code);
    		} else {
    			printk("Advertising in pairing mode started");
    		}

  • Hi,

    -12 is ENOMEM, and this is returned from bt_le_adv_start() when there are no more available connections. This typically happens because there is still an active connection(?), or that the connection object has not been freed yet from a disconnect that occured immediately before. See the description of that situation here. If this is it, the simplest is to set CONFIG_BT_MAX_CONN in your prj.conf to a higher number.

    PS: You can refer to the Bluetooth: Peripheral with multiple identities sample to see how to configure more identities/addresses.

Reply Children
  • Hello, thanks for the response.

    Due to the very limited amount of RAM, in the .conf file I've set

    CONFIG_BT_MAX_CONN=1
    CONFIG_BT_MAX_PAIRED=1
    CONFIG_BT_HIDS_MAX_CLIENT_COUNT=1
    CONFIG_BT_ID_MAX=2


    So I've set the CONFIG_ID_MAX to 2 as I've read in one post that you can reset the address of default ID. In main create another ID

     bt_addr_le_t addr;
    size_t id_count;
    
    bt_id_get(&addr, &id_count);
        if (id_count < CONFIG_BT_ID_MAX)
        {
            err = bt_id_create(NULL, NULL);
            if (err < 0) {
                printk("Creating new ID failed (err %d)\n", err);
        }
    }


    Everything seems to work, but if there is no connection and the button to clear the filter and reset the ID is pressed, the device will still advertise but nothing can connect to it.


    		err = bt_le_adv_stop();
    		if (err) {
    			printk("Cannot stop advertising err= %d \n", err);
    			return;
    		}
    		
    		err = bt_le_filter_accept_list_clear();
    		if (err) {
    			printk("Cannot clear accept list (err: %d)\n", err);
    		} else {
    			printk("Accept list cleared succesfully\n");
    		}
    
    		for (size_t i = 1; i < CONFIG_BT_ID_MAX; i++) {
    			err = bt_id_reset(i, NULL, NULL);
    			if (err < 0) {
    				printk("Cannot reset id %zu (err %d)\n", i, err);
    			}
    			else
    				printk("Reset id: %d\n", i);
    		}
    
    		k_work_submit(&advertise_acceptlist_work);



    If I press the reset button, then it will start working as normal, so I wonder if something is going wrong and bt_enable() needs to be called again.
  • Hi,

    There should not be a need to disable and re-enable the Bluetooth stack. When the central is not able to connect, is the advertising connectable? And is the device advertising without a whitelist? Could it be that the whitelist is still populated, perhaps becaue the bond has not been deleted (I don't see bt_unpair() here anymore, but perhaps that is just that it was not copy pasted in here)? Do you have logs and a sniffer trace that shows what is happening?

  • I've been changing the code around which is why it wasn't there, sorry.

    I've captured packets, but I'm not sure that's it's giving useful information



    I've also seen these packets



    Pressing the button to clear the bonds, filter list and change the address looks like this

    		int err;
    
    		pairing_button = true;
    
    		err = bt_conn_disconnect(conn_mode->conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
    		if (err) {
    			printk("Cannot disconnect err= %d \n", err);
    		}
    		else
    			printk("Disconnected device\n");
    
    		err = bt_le_adv_stop();
    		if (err) {
    			printk("Cannot stop advertising err= %d \n", err);
    			return;
    		}
    		else
    			printk("Advertising stopped\n");
    		
    		err = bt_unpair(BT_ID_1, NULL);
    		if (err) {
    			printk("Cannot unpair for default ID");
    			return err;
    		}
    		else
    			printk("Unpaired\n");
    
    		for (size_t i = 1; i < CONFIG_BT_ID_MAX; i++) {
    			err = bt_id_reset(i, NULL, NULL);
    			if (err < 0) {
    				printk("Cannot reset id %zu (err %d)\n", i, err);
    			}
    			else
    				printk("Reset id: %d\n", i);
    		}
    
    		err = bt_le_filter_accept_list_clear();
    		if (err) {
    			printk("Cannot clear accept list (err: %d)\n", err);
    		} else {
    			printk("Accept list cleared succesfully\n");
    		}
    
    		k_work_submit(&advertise_acceptlist_work);
    
    		pairing_button = false;



  • I've figured out what the problem was. When turning off the BLE from the PC, I advertise using the accept list 

    adv_param.options |= BT_LE_ADV_OPT_FILTER_CONN;

    But after pressing the button to clear the bonds I don't remove BT_LE_ADV_OPT_FILTER_CONN, but I've added the else clause which fixed it.

    	if (option != 0)
    	{
    		adv_param.options |= BT_LE_ADV_OPT_FILTER_CONN;
    		printk("Using filter accept list\n");
    	}
    	else
    	{
    		adv_param.options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME),
    		printk("Not using filter accept list\n");
    	}



    Out of curiosity, does scanning the packets show these parameters, because I couldn't see it on wireshark

Related