diff options
author | Johan Hedberg | 2014-07-09 12:59:15 +0300 |
---|---|---|
committer | Marcel Holtmann | 2014-07-09 12:25:27 +0200 |
commit | a397407f266f8dcb6ea7b28cbff9d9cbd87b6ca8 (patch) | |
tree | f62deae1e4270c5edf899046c814a9f6b5c129df /net | |
parent | 6659358efe617bb46237e62f7303c76e10568d70 (diff) |
Bluetooth: Update page scan when necessary for Add/Remove Device
When we're removing the last item in the white list or adding the first
one to it and HCI_CONNECTABLE is not set we need to update the current
page scan. This patch adds a simple helper function for the purpose and
calls it from the respective mgmt command handlers.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/mgmt.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 49581e99685c..72ff19f26991 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5198,6 +5198,27 @@ unlock: return err; } +/* Helper for Add/Remove Device commands */ +static void update_page_scan(struct hci_dev *hdev, u8 scan) +{ + if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) + return; + + if (!hdev_is_powered(hdev)) + return; + + /* If HCI_CONNECTABLE is set then Add/Remove Device should not + * make any changes to page scanning. + */ + if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) + return; + + if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) + scan |= SCAN_INQUIRY; + + hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); +} + static void device_added(struct sock *sk, struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, u8 action) { @@ -5233,6 +5254,8 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (cp->addr.type == BDADDR_BREDR) { + bool update_scan; + /* Only "connect" action supported for now */ if (cp->action != 0x01) { err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, @@ -5241,10 +5264,16 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, goto unlock; } + update_scan = list_empty(&hdev->whitelist); + err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr, cp->addr.type); if (err) goto unlock; + + if (update_scan) + update_page_scan(hdev, SCAN_PAGE); + goto added; } @@ -5324,6 +5353,9 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, goto unlock; } + if (list_empty(&hdev->whitelist)) + update_page_scan(hdev, SCAN_DISABLED); + device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); goto complete; @@ -5373,6 +5405,8 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, kfree(b); } + update_page_scan(hdev, SCAN_DISABLED); + list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { if (p->auto_connect == HCI_AUTO_CONN_DISABLED) continue; |