This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BLE Reject new devices attempting to pair, only allow old bonded device

Hi All,

I am running nrfConnect SDK v1.8.0 ad started a new sample LBS project. I ultimately want to have 3 devices, 1 being a Central and 2 Peripherals both running LBS. This will be reworked and extended in the future but for now that is fine.

My plan is to initially using the LBS peripheral app on my nrf52840 devkit set it up to allow a single mobile phone to connect and bond. Then reject any new pairing attempts by other phones or devices. If I remove the bonding on the device it will allow phones to pair and bond once again.

Currently, by default it allows only 1 device to bond, but once that device disconnects a new device can pair and hold the connection hostage. While the new device cannot be bonded, it still holds the connection hostage and my other device cannot re-establish a connection. Once I disconnect the new device, my old one can connect and resume its bonded state as it once was.

Thus far for code, I added the bonded device check on boot and load this into a variable so I knows its address.

 

struct
{
	int count;
	bt_addr_le_t addr;
} Bonded;

static void verify_bond(const struct bt_bond_info *info, void *user_data)
{
	Bonded.count++;
	bt_addr_le_copy(&Bonded.addr, &info->addr);

	char str[32];
	bt_addr_to_str(&info->addr.a, str, 18);
	
	
bt_foreach_bond(BT_ID_DEFAULT, verify_bond, NULL);

I also extended the connected callback function to reject all new connections. Though unfortunately as you can see in my printk statements, I am trying to see which address to use to know what to reject the connection based on. I know that all my addresses coming through are doing to be set to Random/Private addressing, so I can't take them on face value.

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err)
	{
		printk("Connection failed (err %u)\n", err);
		return;
	}

	printk("Connected\n");

	dk_set_led_on(CON_STATUS_LED);

	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	if (err)
	{
		printk("Disconnection failed (err %d).\n", err);
	}
	else
	{
		char str[32];
		bt_addr_to_str(&conn->le.dst.a, str, 18);
		printk("dst: %s\n", str);

		bt_addr_to_str(&conn->le.init_addr.a, str, 18);
		printk("init: %s\n", str);

		bt_addr_to_str(&conn->le.resp_addr.a, str, 18);
		printk("resp: %s\n", str);

		printk("Disconnection forced success\n");
	}
}

What would be the more appropriate way to do this? I personally don't actually know if the "bond" value is actually my genuine mac address for my device either, or its some special number thingy.

  • Hi

    As far as I know there is no way to blacklist devices from the peripheral side, but what you could do is to check the peer address when the periphearl gets a CONNECTED event, and disconnect immediately if it's not the address it is bonded to.

    Best regards,

    Simon

  • Hey,

    Thanks for the reply Simon.

    Though as mentioned, this is what I am currently trying to do, though don't know the best (or appropriate) way to match the private addresses (IRK?) to the bonded address I discover through the bt_foreach_bond function.

    After a more reading around. Turns out what I get is the random address and can be resolved by doing an AES decryption. My issue is all the examples that I could find online were all for the previous NRF SDK, rather than NRF Connect SDK (ncs).

    Is there any APIs based on the Zephyr implementation that come to mind that could work like an example provided on this forum for the nrf sdk:

    devzone.nordicsemi.com/.../resolving-private-resolvable-addresses

    Security changed: 6A:05:8D:39:63:AF (random) level 4
    Pairing completed: 94:XX:XX:XX:XX:9B (public), bonded: 1
    irk: 000000000000000xxxETCxxx0000715d

    i got my IRK from

     

    struct bt_keys *keys = bt_keys_find_irk(BT_ID_DEFAULT, bt_conn_get_dst(conn));
    		// keys->irk
    		printk("irk: %s\n", bt_hex(keys->irk.val, 16));

    Cheers,

    Ryan.

  • Hi Ryan

    I think what you're looking for is the Connection Management API in the nRFConnect SDK. As long as you store the first connected central's data you can compare it in the next CONNECTED event and trigger a disconnect if it doesn't match.

    Best regards,

    Simon

  • Hi Simonr,

    What if I have a bonded device and my peripheral restarts. Can I still compare this the way you speak of?

    Could you please identify the functions that I should look into? I've been scraping through quite a few of these functions in various header files all day and don't quite know what I am looking at to be honest.

    Cheers,

    Ryan.

  • Hi again Ryan

    Yes, as long as you store this data in flash, which won't be lost if you reset or go to system OFF mode this should indeed be possible.

    To get information from the device you connect to you can use the bt_conn_get_remote_info() I think and compare it to the stored data.

    Best regards,

    Simon

Related