summaryrefslogtreecommitdiff
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-07-08 15:07:53 +0300
committerMarcel Holtmann <marcel@holtmann.org>2014-07-08 14:22:06 +0200
commite8bb6b9739e2e80e0e413f56816af3871388cfe8 (patch)
tree19cd939c436586fc2857a0160dc0e655c1e435e6 /net/bluetooth/hci_event.c
parent376f54c171674ac1f9a2eefe67d413db4836d25a (diff)
Bluetooth: Fix advertising and active scanning co-existence
Many controllers allow simultaneous active scanning and advertising (e.g. Intel and Broadcom) but some do not (e.g. CSR). It's therefore safest to implement mutual exclusion of these states in the kernel. This patch ensures that the two states are never entered simultaneously. Extra precaution needs to be taken for outgoing connection attempts in slave role (i.e. through directed advertising) in which case the operation that came first has precedence and the one that comes after gets a rejection. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8fbf604ba228..5d3095d7d4b0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1176,13 +1176,21 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
cancel_delayed_work(&hdev->le_scan_disable);
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
+
/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
* interrupted scanning due to a connect request. Mark
- * therefore discovery as stopped.
+ * therefore discovery as stopped. If this was not
+ * because of a connect request advertising might have
+ * been disabled because of active scanning, so
+ * re-enable it again if necessary.
*/
if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
&hdev->dev_flags))
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ else if (!test_bit(HCI_LE_ADV, &hdev->dev_flags) &&
+ hdev->discovery.state != DISCOVERY_STARTING)
+ mgmt_reenable_advertising(hdev);
+
break;
default: