summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Guedes2011-11-04 18:16:53 +0100
committerGustavo F. Padovan2011-11-08 15:54:08 +0100
commit89352e7d3ab372ffad8efe2aa070e0b63df42b85 (patch)
tree90f0ef4e574bf48b3077efe7e7e5b6a8c4bfd7a0
parentBluetooth: Create hci_cancel_inquiry() (diff)
downloadkernel-qcow2-linux-89352e7d3ab372ffad8efe2aa070e0b63df42b85.tar.gz
kernel-qcow2-linux-89352e7d3ab372ffad8efe2aa070e0b63df42b85.tar.xz
kernel-qcow2-linux-89352e7d3ab372ffad8efe2aa070e0b63df42b85.zip
Bluetooth: Periodic Inquiry and Discovery
By using periodic inquiry command we're not able to detect correctly when the controller has started inquiry. Today we have this workaround in inquiry result event handler to set the HCI_INQUIRY flag when it sees the first inquiry result event. This workaround isn't enough because the device may be performing an inquiry but the HCI_INQUIRY flag is not set. For instance, if there is no device in range, no inquiry result event is generated, consequently, the HCI_INQUIRY flags isn't set when it should so. We rely on HCI_INQUIRY flag to implement the discovery procedure properly. So, as we aren't able to clear/set the HCI_INQUIRY flag in a reliable manner, periodic inquiry events shouldn't change the HCI_INQUIRY flag. Thus, due to that issue and in order to keep compatibility with userspace, periodic inquiry events shouldn't send mgmt discovering events. In future, we might track if periodic inquiry is enabled or not. By tracking this state we'll be able to do some improvements in Discovery such as failing MGMT_OP_START_DISCOVERY command in case periodic inquiry is on. We can also send no mgmt_device_found event if periodic inquiry is on. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--net/bluetooth/hci_event.c43
1 files changed, 11 insertions, 32 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9dc54db693a3..0c11203c261a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -58,9 +58,9 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
- if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
- test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 0);
+ clear_bit(HCI_INQUIRY, &hdev->flags);
+
+ mgmt_discovering(hdev->id, 0);
hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
@@ -76,10 +76,6 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
- if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
- test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 0);
-
hci_conn_check_pending(hdev);
}
@@ -986,9 +982,9 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
return;
}
- if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) &&
- test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 1);
+ set_bit(HCI_INQUIRY, &hdev->flags);
+
+ mgmt_discovering(hdev->id, 1);
}
static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
@@ -1367,13 +1363,14 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s status %d", hdev->name, status);
- if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
- test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 0);
-
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
+
+ if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
+ return;
+
+ mgmt_discovering(hdev->id, 0);
}
static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1389,12 +1386,6 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
- if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
-
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 1);
- }
-
for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
@@ -2395,12 +2386,6 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
- if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
-
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 1);
- }
-
if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
struct inquiry_info_with_rssi_and_pscan_mode *info;
info = (void *) (skb->data + 1);
@@ -2563,12 +2548,6 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
if (!num_rsp)
return;
- if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
-
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_discovering(hdev->id, 1);
- }
-
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {