Skip to content

Commit

Permalink
Bluetooth: MGMT: Mark LL Privacy as stable
Browse files Browse the repository at this point in the history
This marks LL Privacy as stable by removing its experimental UUID and
move its functionality to Device Flag (HCI_CONN_FLAG_ADDRESS_RESOLUTION)
which can be set by MGMT Device Set Flags so userspace retain control of
the feature.

Link: https://github.com/bluez/bluez/issues/1028
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  • Loading branch information
Luiz Augusto von Dentz committed Jan 15, 2025
1 parent 0e6dfac commit e209e5c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 162 deletions.
1 change: 0 additions & 1 deletion include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ enum {
HCI_FORCE_BREDR_SMP,
HCI_FORCE_STATIC_ADDR,
HCI_LL_RPA_RESOLUTION,
HCI_ENABLE_LL_PRIVACY,
HCI_CMD_PENDING,
HCI_FORCE_NO_MITM,
HCI_QUALITY_REPORT,
Expand Down
11 changes: 4 additions & 7 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ struct bdaddr_list_with_irk {

/* Bitmask of connection flags */
enum hci_conn_flags {
HCI_CONN_FLAG_REMOTE_WAKEUP = 1,
HCI_CONN_FLAG_DEVICE_PRIVACY = 2,
HCI_CONN_FLAG_REMOTE_WAKEUP = BIT(0),
HCI_CONN_FLAG_DEVICE_PRIVACY = BIT(1),
HCI_CONN_FLAG_ADDRESS_RESOLUTION = BIT(2),
};
typedef u8 hci_conn_flags_t;

Expand Down Expand Up @@ -1919,11 +1920,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);

#define ll_privacy_capable(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)

/* Use LL Privacy based address resolution if supported */
#define use_ll_privacy(dev) (ll_privacy_capable(dev) && \
hci_dev_test_flag(dev, HCI_ENABLE_LL_PRIVACY))

#define privacy_mode_capable(dev) (use_ll_privacy(dev) && \
#define privacy_mode_capable(dev) (ll_privacy_capable(dev) && \
(hdev->commands[39] & 0x04))

#define read_key_size_capable(dev) \
Expand Down
52 changes: 30 additions & 22 deletions net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
/* If Controller supports LL Privacy use own address type is
* 0x03
*/
if (use_ll_privacy(hdev))
if (ll_privacy_capable(hdev))
*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
else
*own_addr_type = ADDR_LE_DEV_RANDOM;
Expand Down Expand Up @@ -2162,7 +2162,7 @@ static int hci_le_set_scan_enable_sync(struct hci_dev *hdev, u8 val,

static int hci_le_set_addr_resolution_enable_sync(struct hci_dev *hdev, u8 val)
{
if (!use_ll_privacy(hdev))
if (!ll_privacy_capable(hdev))
return 0;

/* If controller is not/already resolving we are done. */
Expand Down Expand Up @@ -2254,7 +2254,7 @@ static int hci_le_del_resolve_list_sync(struct hci_dev *hdev,
struct hci_cp_le_del_from_resolv_list cp;
struct bdaddr_list_with_irk *entry;

if (!use_ll_privacy(hdev))
if (!ll_privacy_capable(hdev))
return 0;

/* Check if the IRK has been programmed */
Expand Down Expand Up @@ -2319,7 +2319,7 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev,
struct bdaddr_list_with_irk *entry;
struct hci_conn_params *p;

if (!use_ll_privacy(hdev))
if (!ll_privacy_capable(hdev))
return 0;

/* Attempt to program local identity address, type and irk if params is
Expand All @@ -2332,7 +2332,8 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev,
hci_copy_identity_address(hdev, &cp.bdaddr, &cp.bdaddr_type);
memcpy(cp.peer_irk, hdev->irk, 16);
goto done;
}
} else if (!(params->flags & HCI_CONN_FLAG_ADDRESS_RESOLUTION))
return 0;

irk = hci_find_irk_by_addr(hdev, &params->addr, params->addr_type);
if (!irk)
Expand Down Expand Up @@ -2379,6 +2380,10 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev,
struct hci_cp_le_set_privacy_mode cp;
struct smp_irk *irk;

if (!ll_privacy_capable(hdev) ||
!(params->flags & HCI_CONN_FLAG_ADDRESS_RESOLUTION))
return 0;

/* If device privacy mode has already been set there is nothing to do */
if (params->privacy_mode == HCI_DEVICE_PRIVACY)
return 0;
Expand Down Expand Up @@ -2428,11 +2433,6 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev,
if (*num_entries >= hdev->le_accept_list_size)
return -ENOSPC;

/* Accept list can not be used with RPAs */
if (!use_ll_privacy(hdev) &&
hci_find_irk_by_addr(hdev, &params->addr, params->addr_type))
return -EINVAL;

/* Attempt to program the device in the resolving list first to avoid
* having to rollback in case it fails since the resolving list is
* dynamic it can probably be smaller than the accept list.
Expand Down Expand Up @@ -2567,7 +2567,7 @@ static int hci_pause_addr_resolution(struct hci_dev *hdev)
{
int err;

if (!use_ll_privacy(hdev))
if (!ll_privacy_capable(hdev))
return 0;

if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
Expand Down Expand Up @@ -2671,12 +2671,12 @@ static int hci_le_clear_accept_list_sync(struct hci_dev *hdev)
*
* Update is done using the following sequence:
*
* use_ll_privacy((Disable Advertising) -> Disable Resolving List) ->
* ll_privacy_capable((Disable Advertising) -> Disable Resolving List) ->
* Remove Devices From Accept List ->
* (has IRK && use_ll_privacy(Remove Devices From Resolving List))->
* (has IRK && ll_privacy_capable(Remove Devices From Resolving List))->
* Add Devices to Accept List ->
* (has IRK && use_ll_privacy(Remove Devices From Resolving List)) ->
* use_ll_privacy(Enable Resolving List -> (Enable Advertising)) ->
* (has IRK && ll_privacy_capable(Remove Devices From Resolving List)) ->
* ll_privacy_capable(Enable Resolving List -> (Enable Advertising)) ->
* Enable Scanning
*
* In case of failure advertising shall be restored to its original state and
Expand All @@ -2697,7 +2697,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
/* Pause advertising if resolving list can be used as controllers
* cannot accept resolving list modifications while advertising.
*/
if (use_ll_privacy(hdev)) {
if (ll_privacy_capable(hdev)) {
err = hci_pause_advertising_sync(hdev);
if (err) {
bt_dev_err(hdev, "pause advertising failed: %d", err);
Expand Down Expand Up @@ -2842,7 +2842,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
bt_dev_err(hdev, "Unable to enable LL privacy: %d", err);

/* Resume advertising if it was paused */
if (use_ll_privacy(hdev))
if (ll_privacy_capable(hdev))
hci_resume_advertising_sync(hdev);

/* Select filter policy to use accept list */
Expand Down Expand Up @@ -3100,7 +3100,7 @@ static int hci_passive_scan_sync(struct hci_dev *hdev)
* If there are devices to scan:
*
* Disable Scanning -> Update Accept List ->
* use_ll_privacy((Disable Advertising) -> Disable Resolving List ->
* ll_privacy_capable((Disable Advertising) -> Disable Resolving List ->
* Update Resolving List -> Enable Resolving List -> (Enable Advertising)) ->
* Enable Scanning
*
Expand Down Expand Up @@ -3454,7 +3454,7 @@ int hci_update_name_sync(struct hci_dev *hdev)
*
* HCI_SSP_ENABLED(Enable SSP)
* HCI_LE_ENABLED(Enable LE)
* HCI_LE_ENABLED(use_ll_privacy(Add local IRK to Resolving List) ->
* HCI_LE_ENABLED(ll_privacy_capable(Add local IRK to Resolving List) ->
* Update adv data)
* Enable Authentication
* lmp_bredr_capable(Set Fast Connectable -> Set Scan Type -> Set Class ->
Expand Down Expand Up @@ -4229,6 +4229,14 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
if (use_enhanced_conn_complete(hdev))
events[1] |= 0x02; /* LE Enhanced Connection Complete */

/* Mark Device Privacy if Privacy Mode is supported */
if (privacy_mode_capable(hdev))
hdev->conn_flags |= HCI_CONN_FLAG_DEVICE_PRIVACY;

/* Mark Address Resolution if LL Privacy is supported */
if (ll_privacy_capable(hdev))
hdev->conn_flags |= HCI_CONN_FLAG_ADDRESS_RESOLUTION;

/* If the controller supports Extended Scanner Filter
* Policies, enable the corresponding event.
*/
Expand Down Expand Up @@ -5385,7 +5393,7 @@ int hci_stop_discovery_sync(struct hci_dev *hdev)
}

/* Resume advertising if it was paused */
if (use_ll_privacy(hdev))
if (ll_privacy_capable(hdev))
hci_resume_advertising_sync(hdev);

/* No further actions needed for LE-only discovery */
Expand Down Expand Up @@ -5897,7 +5905,7 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)

failed:
/* Resume advertising if it was paused */
if (use_ll_privacy(hdev))
if (ll_privacy_capable(hdev))
hci_resume_advertising_sync(hdev);

/* Resume passive scanning */
Expand Down Expand Up @@ -6673,7 +6681,7 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
/* If Controller supports LL Privacy use own address type is
* 0x03
*/
if (use_ll_privacy(hdev))
if (ll_privacy_capable(hdev))
*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
else
*own_addr_type = ADDR_LE_DEV_RANDOM;
Expand Down
Loading

0 comments on commit e209e5c

Please sign in to comment.