Bluetooth: Disable page scan if all whitelisted devices are connected
authorJohan Hedberg <johan.hedberg@intel.com>
Fri, 1 Aug 2014 08:13:32 +0000 (11:13 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 14 Aug 2014 06:49:10 +0000 (08:49 +0200)
When we're not connectable and all whitelisted (BR/EDR) devices are
connected it doesn't make sense to keep page scan enabled. This patch
adds code to check for any disconnected whitelist devices and if there
are none take the appropriate action in the hci_update_page_scan()
function to disable page scan.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c

index a031589598b27c67f837190e2ec4a7f2975422a0..217ef83fb5413c572a21d96c4f0fccdf2627b7c0 100644 (file)
@@ -5681,6 +5681,24 @@ void hci_update_background_scan(struct hci_dev *hdev)
                BT_ERR("Failed to run HCI request: err %d", err);
 }
 
+static bool disconnected_whitelist_entries(struct hci_dev *hdev)
+{
+       struct bdaddr_list *b;
+
+       list_for_each_entry(b, &hdev->whitelist, list) {
+               struct hci_conn *conn;
+
+               conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
+               if (!conn)
+                       return true;
+
+               if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
+                       return true;
+       }
+
+       return false;
+}
+
 void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
 {
        u8 scan;
@@ -5695,7 +5713,7 @@ void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
                return;
 
        if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
-           !list_empty(&hdev->whitelist))
+           disconnected_whitelist_entries(hdev))
                scan = SCAN_PAGE;
        else
                scan = SCAN_DISABLED;
index be35598984d9b9b3120cd178f67f0418858b2774..da7ab6b9bb691383d977e039b39e94f8714507d4 100644 (file)
@@ -2071,6 +2071,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                        cp.handle = ev->handle;
                        hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
                                     sizeof(cp), &cp);
+
+                       hci_update_page_scan(hdev, NULL);
                }
 
                /* Set packet type for incoming connection */
@@ -2247,9 +2249,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
                                reason, mgmt_connected);
 
-       if (conn->type == ACL_LINK &&
-           test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
-               hci_remove_link_key(hdev, &conn->dst);
+       if (conn->type == ACL_LINK) {
+               if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
+                       hci_remove_link_key(hdev, &conn->dst);
+
+               hci_update_page_scan(hdev, NULL);
+       }
 
        params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
        if (params) {
This page took 0.028403 seconds and 5 git commands to generate.