From 6baf8a6afc1e5bc30179112bf8c685e448372f43 Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Fri, 11 Sep 2020 15:32:20 -0700 Subject: Bluetooth: Set ext scan response only when it exists Only set extended scan response only when it exists. Otherwise, clear the scan response data. Per the core spec v5.2, Vol 4, Part E, 7.8.55 If the advertising set is non-scannable and the Host uses this command other than to discard existing data, the Controller shall return the error code Invalid HCI Command Parameters (0x12). On WCN3991, the controller correctly responds with Invalid Parameters when this is sent. That error causes __hci_req_hci_power_on to fail with -EINVAL and LE devices can't connect because background scanning isn't configured. Here is an hci trace of where this issue occurs during power on: < HCI Command: LE Set Extended Advertising Parameters (0x08|0x0036) plen 25 Handle: 0x00 Properties: 0x0010 Use legacy advertising PDUs: ADV_NONCONN_IND Min advertising interval: 181.250 msec (0x0122) Max advertising interval: 181.250 msec (0x0122) Channel map: 37, 38, 39 (0x07) Own address type: Random (0x01) Peer address type: Public (0x00) Peer address: 00:00:00:00:00:00 (OUI 00-00-00) Filter policy: Allow Scan Request from Any, Allow Connect... TX power: 127 dbm (0x7f) Primary PHY: LE 1M (0x01) Secondary max skip: 0x00 Secondary PHY: LE 1M (0x01) SID: 0x00 Scan request notifications: Disabled (0x00) > HCI Event: Command Complete (0x0e) plen 5 LE Set Extended Advertising Parameters (0x08|0x0036) ncmd 1 Status: Success (0x00) TX power (selected): 9 dbm (0x09) < HCI Command: LE Set Advertising Set Random Address (0x08|0x0035) plen 7 Advertising handle: 0x00 Advertising random address: 08:FD:55:ED:22:28 (OUI 08-FD-55) > HCI Event: Command Complete (0x0e) plen 4 LE Set Advertising Set Random Address (0x08|0x0035) ncmd Status: Success (0x00) < HCI Command: LE Set Extended Scan Response Data (0x08|0x0038) plen 35 Handle: 0x00 Operation: Complete scan response data (0x03) Fragment preference: Minimize fragmentation (0x01) Data length: 0x0d Name (short): Chromebook > HCI Event: Command Complete (0x0e) plen 4 LE Set Extended Scan Response Data (0x08|0x0038) ncmd 1 Status: Invalid HCI Command Parameters (0x12) Signed-off-by: Abhishek Pandit-Subedi Reviewed-by: Daniel Winkler Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e0269192f2e5..e17bc8a1c66d 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1533,11 +1533,14 @@ void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance) memset(&cp, 0, sizeof(cp)); - if (instance) + /* Extended scan response data doesn't allow a response to be + * set if the instance isn't scannable. + */ + if (get_adv_instance_scan_rsp_len(hdev, instance)) len = create_instance_scan_rsp_data(hdev, instance, cp.data); else - len = create_default_scan_rsp_data(hdev, cp.data); + len = 0; if (hdev->scan_rsp_data_len == len && !memcmp(cp.data, hdev->scan_rsp_data, len)) -- cgit v1.2.3 From 53274477acf23a7995428e981924e56379778874 Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Tue, 15 Sep 2020 14:14:27 -0700 Subject: Bluetooth: pause/resume advertising around suspend Currently, the controller will continue advertising when the system enters suspend. This patch makes sure that all advertising instances are paused when entering suspend, and resumed when suspend exits. The Advertising and Suspend/Resume test suites were both run on this change on 4.19 kernel with both hardware offloaded multi-advertising and software rotated multi-advertising. In addition, a new test was added that performs the following steps: * Register 3 advertisements via bluez RegisterAdvertisement * Verify reception of all advertisements by remote peer * Enter suspend on DUT * Verify failure to receive all advertisements by remote peer * Exit suspend on DUT * Verify reception of all advertisements by remote peer Signed-off-by: Daniel Winkler Reviewed-by: Abhishek Pandit-Subedi Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 67 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 10 deletions(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e17bc8a1c66d..413e3a5aabf5 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1111,6 +1111,53 @@ static void hci_req_config_le_suspend_scan(struct hci_request *req) set_bit(SUSPEND_SCAN_ENABLE, req->hdev->suspend_tasks); } +static void cancel_adv_timeout(struct hci_dev *hdev) +{ + if (hdev->adv_instance_timeout) { + hdev->adv_instance_timeout = 0; + cancel_delayed_work(&hdev->adv_instance_expire); + } +} + +/* This function requires the caller holds hdev->lock */ +static void hci_suspend_adv_instances(struct hci_request *req) +{ + bt_dev_dbg(req->hdev, "Suspending advertising instances"); + + /* Call to disable any advertisements active on the controller. + * This will succeed even if no advertisements are configured. + */ + __hci_req_disable_advertising(req); + + /* If we are using software rotation, pause the loop */ + if (!ext_adv_capable(req->hdev)) + cancel_adv_timeout(req->hdev); +} + +/* This function requires the caller holds hdev->lock */ +static void hci_resume_adv_instances(struct hci_request *req) +{ + struct adv_info *adv; + + bt_dev_dbg(req->hdev, "Resuming advertising instances"); + + if (ext_adv_capable(req->hdev)) { + /* Call for each tracked instance to be re-enabled */ + list_for_each_entry(adv, &req->hdev->adv_instances, list) { + __hci_req_enable_ext_advertising(req, + adv->instance); + } + + } else { + /* Schedule for most recent instance to be restarted and begin + * the software rotation loop + */ + __hci_req_schedule_adv_instance(req, + req->hdev->cur_adv_instance, + true); + } +} + static void suspend_req_complete(struct hci_dev *hdev, u8 status, u16 opcode) { bt_dev_dbg(hdev, "Request complete opcode=0x%x, status=0x%x", opcode, @@ -1153,7 +1200,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hdev->discovery_paused = true; hdev->discovery_old_state = old_state; - /* Stop advertising */ + /* Stop directed advertising */ old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING); if (old_state) { set_bit(SUSPEND_PAUSE_ADVERTISING, hdev->suspend_tasks); @@ -1162,6 +1209,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) &hdev->discov_off, 0); } + /* Pause other advertisements */ + if (hdev->adv_instance_cnt) + hci_suspend_adv_instances(&req); + hdev->advertising_paused = true; hdev->advertising_old_state = old_state; /* Disable page scan */ @@ -1212,7 +1263,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) /* Reset passive/background scanning to normal */ hci_req_config_le_suspend_scan(&req); - /* Unpause advertising */ + /* Unpause directed advertising */ hdev->advertising_paused = false; if (hdev->advertising_old_state) { set_bit(SUSPEND_UNPAUSE_ADVERTISING, @@ -1223,6 +1274,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hdev->advertising_old_state = 0; } + /* Resume other advertisements */ + if (hdev->adv_instance_cnt) + hci_resume_adv_instances(&req); + /* Unpause discovery */ hdev->discovery_paused = false; if (hdev->discovery_old_state != DISCOVERY_STOPPED && @@ -2186,14 +2241,6 @@ int __hci_req_schedule_adv_instance(struct hci_request *req, u8 instance, return 0; } -static void cancel_adv_timeout(struct hci_dev *hdev) -{ - if (hdev->adv_instance_timeout) { - hdev->adv_instance_timeout = 0; - cancel_delayed_work(&hdev->adv_instance_expire); - } -} - /* For a single instance: * - force == true: The instance will be removed even when its remaining * lifetime is not zero. -- cgit v1.2.3 From 291f0c550f43c7b1c985738208d8ca1c6808dc4f Mon Sep 17 00:00:00 2001 From: Howard Chung Date: Fri, 18 Sep 2020 11:11:49 +0800 Subject: Bluetooth: Set scan parameters for ADV Monitor Set scan parameters when there is at least one Advertisement monitor. Signed-off-by: Howard Chung Reviewed-by: Alain Michaud Reviewed-by: Manish Mandlik Reviewed-by: Abhishek Pandit-Subedi Reviewed-by: Miao-chen Chou Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 413e3a5aabf5..d2b06f5c9380 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1027,6 +1027,9 @@ void hci_req_add_le_passive_scan(struct hci_request *req) } else if (hci_is_le_conn_scanning(hdev)) { window = hdev->le_scan_window_connect; interval = hdev->le_scan_int_connect; + } else if (hci_is_adv_monitoring(hdev)) { + window = hdev->le_scan_window_adv_monitor; + interval = hdev->le_scan_int_adv_monitor; } else { window = hdev->le_scan_window; interval = hdev->le_scan_interval; -- cgit v1.2.3 From c0ee0644df5da3f877a53e402d03634080d6e766 Mon Sep 17 00:00:00 2001 From: Sathish Narasimman Date: Fri, 25 Sep 2020 18:02:15 +0530 Subject: Bluetooth: Fix update of own_addr_type if ll_privacy supported During system powercycle when trying to get the random address hci_get_random_address set own_addr_type as 0x01. In which if we enable ll_privacy it is supposed to be 0x03. Signed-off-by: Sathish Narasimman Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index d2b06f5c9380..6f12bab4d2fa 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1885,7 +1885,13 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, if (use_rpa) { int to; - *own_addr_type = ADDR_LE_DEV_RANDOM; + /* If Controller supports LL Privacy use own address type is + * 0x03 + */ + if (use_ll_privacy(hdev)) + *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; + else + *own_addr_type = ADDR_LE_DEV_RANDOM; if (adv_instance) { if (!adv_instance->rpa_expired && -- cgit v1.2.3