aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2014-02-26 18:21:51 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-26 22:41:35 -0500
commit6046dc3e0602256b9941241dfd6b2e4824999b01 (patch)
tree4afff3666f04427f71b6a84869d548837a1f7a75 /net/bluetooth
parentc54c3860e3dbaa68128dbb288b2806dd86c230cc (diff)
Bluetooth: Auto connection and power on
When hdev is closed (e.g. Mgmt power off command, RFKILL or controller is reset), the ongoing active connections are silently dropped by the controller (no Disconnection Complete Event is sent to host). For that reason, the devices that require HCI_AUTO_CONN_ALWAYS are not added to hdev->pend_le_conns list and they won't auto connect. So to fix this issue, during hdev closing, we remove all pending LE connections. After adapter is powered on, we add a pending LE connection for each HCI_AUTO_CONN_ALWAYS address. This way, the auto connection mechanism works propely after a power off and power on sequence as well as RFKILL block/unblock. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c1
-rw-r--r--net/bluetooth/mgmt.c13
2 files changed, 14 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 507a137a584b..9470a9c14324 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2266,6 +2266,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
2266 hci_dev_lock(hdev); 2266 hci_dev_lock(hdev);
2267 hci_inquiry_cache_flush(hdev); 2267 hci_inquiry_cache_flush(hdev);
2268 hci_conn_hash_flush(hdev); 2268 hci_conn_hash_flush(hdev);
2269 hci_pend_le_conns_clear(hdev);
2269 hci_dev_unlock(hdev); 2270 hci_dev_unlock(hdev);
2270 2271
2271 hci_notify(hdev, HCI_DEV_DOWN); 2272 hci_notify(hdev, HCI_DEV_DOWN);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a62e22ca73a1..f878267ba6ab 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4669,6 +4669,17 @@ void mgmt_index_removed(struct hci_dev *hdev)
4669 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); 4669 mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
4670} 4670}
4671 4671
4672/* This function requires the caller holds hdev->lock */
4673static void restart_le_auto_conns(struct hci_dev *hdev)
4674{
4675 struct hci_conn_params *p;
4676
4677 list_for_each_entry(p, &hdev->le_conn_params, list) {
4678 if (p->auto_connect == HCI_AUTO_CONN_ALWAYS)
4679 hci_pend_le_conn_add(hdev, &p->addr, p->addr_type);
4680 }
4681}
4682
4672static void powered_complete(struct hci_dev *hdev, u8 status) 4683static void powered_complete(struct hci_dev *hdev, u8 status)
4673{ 4684{
4674 struct cmd_lookup match = { NULL, hdev }; 4685 struct cmd_lookup match = { NULL, hdev };
@@ -4677,6 +4688,8 @@ static void powered_complete(struct hci_dev *hdev, u8 status)
4677 4688
4678 hci_dev_lock(hdev); 4689 hci_dev_lock(hdev);
4679 4690
4691 restart_le_auto_conns(hdev);
4692
4680 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); 4693 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
4681 4694
4682 new_settings(hdev, match.sk); 4695 new_settings(hdev, match.sk);