Skip to content

Commit

Permalink
Bluetooth: Workaround privacy feature issue
Browse files Browse the repository at this point in the history
This fixes intercompatibility issues with controllers supporting
privacy feature.
Core Spec requires to use network privacy mode as a default when
peer device provides its IRK during bonding when LL Privacy is used,
which is the case for Zephyr. We've seen devices including PTS
which exchanges it's IRK but is not aware about network privacy
mode. This results in Zephyr not able do be reconnect to such bonded
devices.
This workaround sets device privacy mode to be able to reconnect
to such devices.

Fixes zephyrproject-rtos#4989
Fixes zephyrproject-rtos#5486

Signed-off-by: Mariusz Skamra <[email protected]>
  • Loading branch information
MariuszSkamra authored and carlescufi committed Mar 2, 2018
1 parent d4d2581 commit 777f9c8
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,32 @@ static void role_change(struct net_buf *buf)
#endif /* CONFIG_BT_BREDR */

#if defined(CONFIG_BT_SMP)
static int le_set_privacy_mode(const bt_addr_le_t *addr, u8_t mode)
{
struct bt_hci_cp_le_set_privacy_mode cp;
struct net_buf *buf;
int err;

BT_DBG("addr %s mode 0x%02x", bt_addr_le_str(addr), mode);

bt_addr_le_copy(&cp.id_addr, addr);
cp.mode = mode;

buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PRIVACY_MODE, sizeof(cp));
if (!buf) {
return -ENOBUFS;
}

net_buf_add_mem(buf, &cp, sizeof(cp));

err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PRIVACY_MODE, buf, NULL);
if (err) {
return err;
}

return 0;
}

static int addr_res_enable(u8_t enable)
{
struct net_buf *buf;
Expand Down Expand Up @@ -2400,6 +2426,24 @@ int bt_id_add(struct bt_keys *keys)

bt_dev.le.rl_entries++;

/*
* According to Core Spec. 5.0 Vol 1, Part A 5.4.5 Privacy Feature
*
* By default, network privacy mode is used when private addresses are
* resolved and generated by the Controller, so advertising packets from
* peer devices that contain private addresses will only be accepted.
* By changing to the device privacy mode device is only concerned about
* its privacy and will accept advertising packets from peer devices
* that contain their identity address as well as ones that contain
* a private address, even if the peer device has distributed its IRK in
* the past.
*/
err = le_set_privacy_mode(&keys->addr, BT_HCI_LE_PRIVACY_MODE_DEVICE);
if (err) {
BT_ERR("Failed to set privacy mode");
goto done;
}

done:
addr_res_enable(BT_HCI_ADDR_RES_ENABLE);

Expand Down

0 comments on commit 777f9c8

Please sign in to comment.