From e5b0ad69c97a04f42834b24a6a0323ab15ccc9bb Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Wed, 3 Mar 2021 08:34:04 -0800 Subject: Bluetooth: Remove unneeded commands for suspend During suspend, there are a few scan enable and set event filter commands that don't need to be sent unless there are actual BR/EDR devices capable of waking the system. Check the HCI_PSCAN bit before writing scan enable and use a new dev flag, HCI_EVENT_FILTER_CONFIGURED to control whether to clear the event filter. Signed-off-by: Abhishek Pandit-Subedi Reviewed-by: Archie Pusaka Reviewed-by: Alain Michaud Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e55976db4403..75a42178c82d 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1131,14 +1131,14 @@ static void hci_req_clear_event_filter(struct hci_request *req) { struct hci_cp_set_event_filter f; - memset(&f, 0, sizeof(f)); - f.flt_type = HCI_FLT_CLEAR_ALL; - hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f); + if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED)) + return; - /* Update page scan state (since we may have modified it when setting - * the event filter). - */ - __hci_req_update_scan(req); + if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) { + memset(&f, 0, sizeof(f)); + f.flt_type = HCI_FLT_CLEAR_ALL; + hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f); + } } static void hci_req_set_event_filter(struct hci_request *req) @@ -1147,6 +1147,10 @@ static void hci_req_set_event_filter(struct hci_request *req) struct hci_cp_set_event_filter f; struct hci_dev *hdev = req->hdev; u8 scan = SCAN_DISABLED; + bool scanning = test_bit(HCI_PSCAN, &hdev->flags); + + if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) + return; /* Always clear event filter when starting */ hci_req_clear_event_filter(req); @@ -1167,12 +1171,13 @@ static void hci_req_set_event_filter(struct hci_request *req) scan = SCAN_PAGE; } - if (scan) + if (scan && !scanning) { set_bit(SUSPEND_SCAN_ENABLE, hdev->suspend_tasks); - else + hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + } else if (!scan && scanning) { set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks); - - hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + } } static void cancel_adv_timeout(struct hci_dev *hdev) @@ -1315,9 +1320,14 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hdev->advertising_paused = true; hdev->advertising_old_state = old_state; - /* Disable page scan */ - page_scan = SCAN_DISABLED; - hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan); + + /* Disable page scan if enabled */ + if (test_bit(HCI_PSCAN, &hdev->flags)) { + page_scan = SCAN_DISABLED; + hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, + &page_scan); + set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks); + } /* Disable LE passive scan if enabled */ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { @@ -1328,9 +1338,6 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) /* Disable advertisement filters */ hci_req_add_set_adv_filter_enable(&req, false); - /* Mark task needing completion */ - set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks); - /* Prevent disconnects from causing scanning to be re-enabled */ hdev->scanning_paused = true; @@ -1364,7 +1371,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hdev->suspended = false; hdev->scanning_paused = false; + /* Clear any event filters and restore scan state */ hci_req_clear_event_filter(&req); + __hci_req_update_scan(&req); + /* Reset passive/background scanning to normal */ __hci_update_background_scan(&req); /* Enable all of the advertisement filters */ -- cgit v1.2.3 From ff02db13e9bfa01e0d66c5fa53da29bd1f1b208a Mon Sep 17 00:00:00 2001 From: Daniel Winkler Date: Wed, 3 Mar 2021 11:15:23 -0800 Subject: Bluetooth: Allow scannable adv with extended MGMT APIs An issue was found, where if a bluetooth client requests a broadcast advertisement with scan response data, it will not be properly registered with the controller. This is because at the time that the hci_cp_le_set_scan_param structure is created, the scan response will not yet have been received since it comes in a second MGMT call. With empty scan response, the request defaults to a non-scannable PDU type. On some controllers, the subsequent scan response request will fail due to incorrect PDU type, and others will succeed and not use the scan response. This fix allows the advertising parameters MGMT call to include a flag to let the kernel know whether a scan response will be coming, so that the correct PDU type is used in the first place. A bluetoothd change is also incoming to take advantage of it. To test this, I created a broadcast advertisement with scan response data and registered it on the hatch chromebook. Without this change, the request fails, and with it will succeed. Reviewed-by: Alain Michaud Reviewed-by: Sonny Sasaka Reviewed-by: Miao-chen Chou Signed-off-by: Daniel Winkler Signed-off-by: Marcel Holtmann --- include/net/bluetooth/mgmt.h | 1 + net/bluetooth/hci_request.c | 3 ++- net/bluetooth/mgmt.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 839a2028009e..a7cffb069565 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -578,6 +578,7 @@ struct mgmt_rp_add_advertising { #define MGMT_ADV_PARAM_TIMEOUT BIT(13) #define MGMT_ADV_PARAM_INTERVALS BIT(14) #define MGMT_ADV_PARAM_TX_POWER BIT(15) +#define MGMT_ADV_PARAM_SCAN_RSP BIT(16) #define MGMT_ADV_FLAG_SEC_MASK (MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \ MGMT_ADV_FLAG_SEC_CODED) diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 75a42178c82d..d7ee11ef70d3 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -2180,7 +2180,8 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND); else cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND); - } else if (adv_instance_is_scannable(hdev, instance)) { + } else if (adv_instance_is_scannable(hdev, instance) || + (flags & MGMT_ADV_PARAM_SCAN_RSP)) { if (secondary_adv) cp.evt_properties = cpu_to_le16(LE_EXT_ADV_SCAN_IND); else diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 74971b4bd457..90334ac4a135 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7432,6 +7432,7 @@ static u32 get_supported_adv_flags(struct hci_dev *hdev) flags |= MGMT_ADV_PARAM_TIMEOUT; flags |= MGMT_ADV_PARAM_INTERVALS; flags |= MGMT_ADV_PARAM_TX_POWER; + flags |= MGMT_ADV_PARAM_SCAN_RSP; /* In extended adv TX_POWER returned from Set Adv Param * will be always valid. -- cgit v1.2.3 From c06632a4ec3a7b823f0e9c04cd4836135bba44bf Mon Sep 17 00:00:00 2001 From: Sonny Sasaka Date: Mon, 15 Mar 2021 10:30:59 -0700 Subject: Bluetooth: Cancel le_scan_restart work when stopping discovery Not cancelling it has caused a bug where passive background scanning is disabled out of the blue, preventing BLE keyboards/mice to reconnect. Here is how it happens: After hci_req_stop_discovery, there is still le_scan_restart_work scheduled. Invocation of le_scan_restart_work causes a harmful le_scan_disable_work to be scheduled. This le_scan_disable_work will eventually disable passive scanning when the timer fires. Sample btmon trace: < HCI Command: LE Set Scan Parameters (0x08|0x000b) plen 7 Type: Passive (0x00) Interval: 367.500 msec (0x024c) Window: 37.500 msec (0x003c) Own address type: Public (0x00) Filter policy: Accept all advertisement (0x00) > HCI Event: Command Complete (0x0e) plen 4 LE Set Scan Parameters (0x08|0x000b) ncmd 1 Status: Success (0x00) < HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2 Scanning: Enabled (0x01) Filter duplicates: Disabled (0x00) > HCI Event: Command Complete (0x0e) plen 4 LE Set Scan Enable (0x08|0x000c) ncmd 2 Status: Success (0x00) ... < HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2 Scanning: Disabled (0x00) Filter duplicates: Disabled (0x00) > HCI Event: Command Complete (0x0e) plen 4 LE Set Scan Enable (0x08|0x000c) ncmd 2 Status: Success (0x00) // Background scanning is not working here onwards. Reviewed-by: Abhishek Pandit-Subedi Signed-off-by: Sonny Sasaka Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index d7ee11ef70d3..8ace5d34b01e 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -3252,6 +3252,7 @@ bool hci_req_stop_discovery(struct hci_request *req) if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { cancel_delayed_work(&hdev->le_scan_disable); + cancel_delayed_work(&hdev->le_scan_restart); hci_req_add_le_scan_disable(req, false); } -- cgit v1.2.3 From 149b3f13b4b11175c81105f32b048260e63fdc34 Mon Sep 17 00:00:00 2001 From: Meng Yu Date: Thu, 1 Apr 2021 14:50:39 +0800 Subject: Bluetooth: Coding style fix 1. Add space when needed; 2. Block comments style fix; 3. Move open brace '{' following function definitions to the next line; 4. Remove unnecessary braces '{}' for single statement blocks. Signed-off-by: Meng Yu Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 3 +-- net/bluetooth/hci_debugfs.c | 8 ++++---- net/bluetooth/hci_event.c | 2 +- net/bluetooth/hci_request.c | 6 ++---- net/bluetooth/l2cap_core.c | 5 +++-- 5 files changed, 11 insertions(+), 13 deletions(-) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 19f7e42db1b0..97617d02c8f9 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -205,8 +205,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev, } } - /* use the neighbour cache for matching addresses assigned by SLAAC - */ + /* use the neighbour cache for matching addresses assigned by SLAAC */ neigh = __ipv6_neigh_lookup(dev->netdev, nexthop); if (neigh) { list_for_each_entry_rcu(peer, &dev->peers, list) { diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c index 1a0ab58bfad0..47f4f21fbc1a 100644 --- a/net/bluetooth/hci_debugfs.c +++ b/net/bluetooth/hci_debugfs.c @@ -274,7 +274,7 @@ static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf, struct hci_dev *hdev = file->private_data; char buf[3]; - buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y': 'N'; + buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y' : 'N'; buf[1] = '\n'; buf[2] = '\0'; return simple_read_from_buffer(user_buf, count, ppos, buf, 2); @@ -292,7 +292,7 @@ static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, struct hci_dev *hdev = file->private_data; char buf[3]; - buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y': 'N'; + buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y' : 'N'; buf[1] = '\n'; buf[2] = '\0'; return simple_read_from_buffer(user_buf, count, ppos, buf, 2); @@ -428,7 +428,7 @@ static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf, struct hci_dev *hdev = file->private_data; char buf[3]; - buf[0] = hdev->ssp_debug_mode ? 'Y': 'N'; + buf[0] = hdev->ssp_debug_mode ? 'Y' : 'N'; buf[1] = '\n'; buf[2] = '\0'; return simple_read_from_buffer(user_buf, count, ppos, buf, 2); @@ -742,7 +742,7 @@ static ssize_t force_static_address_read(struct file *file, struct hci_dev *hdev = file->private_data; char buf[3]; - buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y': 'N'; + buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y' : 'N'; buf[1] = '\n'; buf[2] = '\0'; return simple_read_from_buffer(user_buf, count, ppos, buf, 2); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 341c8ce93648..593eafa282e3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5891,7 +5891,7 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, params->conn_latency = latency; params->supervision_timeout = timeout; store_hint = 0x01; - } else{ + } else { store_hint = 0x00; } diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 8ace5d34b01e..6cd9d41eda44 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1647,9 +1647,8 @@ static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) { u8 scan_rsp_len = 0; - if (hdev->appearance) { + if (hdev->appearance) scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len); - } return append_local_name(hdev, ptr, scan_rsp_len); } @@ -1667,9 +1666,8 @@ static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance, instance_flags = adv_instance->flags; - if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) { + if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len); - } memcpy(&ptr[scan_rsp_len], adv_instance->scan_rsp_data, adv_instance->scan_rsp_len); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a3b1d40b8750..140669456b6f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -652,7 +652,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; - switch(chan->mode) { + switch (chan->mode) { case L2CAP_MODE_BASIC: break; @@ -7770,7 +7770,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) return conn; } -static bool is_valid_psm(u16 psm, u8 dst_type) { +static bool is_valid_psm(u16 psm, u8 dst_type) +{ if (!psm) return false; -- cgit v1.2.3 From 06752d1678b49ac471f11950ebd6d29541828bba Mon Sep 17 00:00:00 2001 From: Archie Pusaka Date: Thu, 1 Apr 2021 11:11:33 +0800 Subject: Bluetooth: Check inquiry status before sending one There is a possibility where HCI_INQUIRY flag is set but we still send HCI_OP_INQUIRY anyway. Such a case can be reproduced by connecting to an LE device while active scanning. When the device is discovered, we initiate a connection, stop LE Scan, and send Discovery MGMT with status disabled, but we don't cancel the inquiry. Signed-off-by: Archie Pusaka Reviewed-by: Sonny Sasaka 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 6cd9d41eda44..5b4eb87b19f0 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -2950,6 +2950,9 @@ static int bredr_inquiry(struct hci_request *req, unsigned long opt) const u8 liac[3] = { 0x00, 0x8b, 0x9e }; struct hci_cp_inquiry cp; + if (test_bit(HCI_INQUIRY, &req->hdev->flags)) + return 0; + bt_dev_dbg(req->hdev, ""); hci_dev_lock(req->hdev); -- cgit v1.2.3 From abb638b311da86eba61c4b2be8eb13375a56b7be Mon Sep 17 00:00:00 2001 From: Sathish Narasimman Date: Mon, 5 Apr 2021 20:00:23 +0530 Subject: Bluetooth: Handle own address type change with HCI_ENABLE_LL_PRIVACY own_address_type has to changed to 0x02 and 0x03 only when HCI_ENABLE_LL_PRIVACY flag is set. Signed-off-by: Sathish Narasimman Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 6 ++++-- 1 file changed, 4 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 5b4eb87b19f0..0d78122342d5 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -2043,7 +2043,8 @@ 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 (use_ll_privacy(hdev) && + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; else *own_addr_type = ADDR_LE_DEV_RANDOM; @@ -2517,7 +2518,8 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, /* If Controller supports LL Privacy use own address type is * 0x03 */ - if (use_ll_privacy(hdev)) + if (use_ll_privacy(hdev) && + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED; else *own_addr_type = ADDR_LE_DEV_RANDOM; -- cgit v1.2.3 From 8ce85ada0a05e21a5386ba5c417c52ab00fcd0d1 Mon Sep 17 00:00:00 2001 From: Sathish Narasimman Date: Mon, 5 Apr 2021 20:00:41 +0530 Subject: Bluetooth: LL privacy allow RPA allow RPA to add bd address to whitelist Signed-off-by: Sathish Narasimman Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_request.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'net/bluetooth/hci_request.c') diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 0d78122342d5..560b74d421a8 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -847,6 +847,10 @@ static u8 update_white_list(struct hci_request *req) */ bool allow_rpa = hdev->suspended; + if (use_ll_privacy(hdev) && + hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) + allow_rpa = true; + /* Go through the current white list programmed into the * controller one by one and check if that address is still * in the list of pending connections or list of devices to -- cgit v1.2.3