Commit 3c44a431 authored by Zhengping Jiang's avatar Zhengping Jiang Committed by Luiz Augusto von Dentz

Bluetooth: hci_sync: Resume adv with no RPA when active scan

The address resolution should be disabled during the active scan,
so all the advertisements can reach the host. The advertising
has to be paused before disabling the address resolution,
because the advertising will prevent any changes to the resolving
list and the address resolution status. Skipping this will cause
the hci error and the discovery failure.

According to the bluetooth specification:
"7.8.44 LE Set Address Resolution Enable command

This command shall not be used when:
- Advertising (other than periodic advertising) is enabled,
- Scanning is enabled, or
- an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
  HCI_LE_Periodic_Advertising_Create_Sync command is outstanding."

If the host is using RPA, the controller needs to generate RPA for
the advertising, so the advertising must remain paused during the
active scan.

If the host is not using RPA, the advertising can be resumed after
disabling the address resolution.

Fixes: 9afc675e ("Bluetooth: hci_sync: allow advertise when scan without RPA")
Signed-off-by: default avatarZhengping Jiang <jiangzp@google.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent bb765a74
...@@ -2367,6 +2367,45 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev) ...@@ -2367,6 +2367,45 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
return err; return err;
} }
static int hci_pause_addr_resolution(struct hci_dev *hdev)
{
int err;
if (!use_ll_privacy(hdev))
return 0;
if (!hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
return 0;
/* Cannot disable addr resolution if scanning is enabled or
* when initiating an LE connection.
*/
if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
hci_lookup_le_connect(hdev)) {
bt_dev_err(hdev, "Command not allowed when scan/LE connect");
return -EPERM;
}
/* Cannot disable addr resolution if advertising is enabled. */
err = hci_pause_advertising_sync(hdev);
if (err) {
bt_dev_err(hdev, "Pause advertising failed: %d", err);
return err;
}
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
if (err)
bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
err);
/* Return if address resolution is disabled and RPA is not used. */
if (!err && scan_use_rpa(hdev))
return err;
hci_resume_advertising_sync(hdev);
return err;
}
struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev,
bool extended, struct sock *sk) bool extended, struct sock *sk)
{ {
...@@ -2402,7 +2441,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) ...@@ -2402,7 +2441,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
u8 filter_policy; u8 filter_policy;
int err; int err;
/* Pause advertising if resolving list can be used as controllers are /* Pause advertising if resolving list can be used as controllers
* cannot accept resolving list modifications while advertising. * cannot accept resolving list modifications while advertising.
*/ */
if (use_ll_privacy(hdev)) { if (use_ll_privacy(hdev)) {
...@@ -5394,27 +5433,12 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval) ...@@ -5394,27 +5433,12 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
cancel_interleave_scan(hdev); cancel_interleave_scan(hdev);
/* Pause advertising since active scanning disables address resolution /* Pause address resolution for active scan and stop advertising if
* which advertising depend on in order to generate its RPAs. * privacy is enabled.
*/ */
if (use_ll_privacy(hdev) && hci_dev_test_flag(hdev, HCI_PRIVACY)) { err = hci_pause_addr_resolution(hdev);
err = hci_pause_advertising_sync(hdev); if (err)
if (err) {
bt_dev_err(hdev, "pause advertising failed: %d", err);
goto failed;
}
}
/* Disable address resolution while doing active scanning since the
* accept list shall not be used and all reports shall reach the host
* anyway.
*/
err = hci_le_set_addr_resolution_enable_sync(hdev, 0x00);
if (err) {
bt_dev_err(hdev, "Unable to disable Address Resolution: %d",
err);
goto failed; goto failed;
}
/* All active scans will be done with either a resolvable private /* All active scans will be done with either a resolvable private
* address (when privacy feature has been enabled) or non-resolvable * address (when privacy feature has been enabled) or non-resolvable
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment