Bluetooth: fix service discovery behaviour for empty uuids filter
authorJakub Pawlowski <jpawlowski@google.com>
Thu, 5 Mar 2015 00:24:26 +0000 (16:24 -0800)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 5 Mar 2015 07:50:50 +0000 (09:50 +0200)
This patch fixes service discovery behaviour, when provided uuid filter
is empty and HCI_QUIRK_STRICT_DUPLICATE_FILTER is set. Before this
patch, empty uuid filter was unable to trigger scan restart, and that
caused inconsistent behaviour in applications.

Example: two DBus clients call BlueZ, one to find all devices with
service abcd, second to find all devices with rssi smaller than -90.
Sum of those filters, that is passed to mgmt_service_scan is empty
filter, with no rssi or uuids set.
That caused kernel not to restart scan when quirk was set.
That was inconsistent with what happen when there's only one of those
two filters set (scan is restarted and reports devices).

To fix that, new variable hdev->discovery.result_filtering was
introduced. It can indicate that filtered scan is running, no matter
what uuid or rssi filter is set.

Signed-off-by: Jakub Pawlowski <jpawlowski@google.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/mgmt.c

index acec9140c3f9a5ea12b452845373b8d74ee9471f..15c761c1f82a1c8859ce088da74ba0c67ac72ea8 100644 (file)
@@ -76,6 +76,7 @@ struct discovery_state {
        u8                      last_adv_data[HCI_MAX_AD_LENGTH];
        u8                      last_adv_data_len;
        bool                    report_invalid_rssi;
+       bool                    result_filtering;
        s8                      rssi;
        u16                     uuid_count;
        u8                      (*uuids)[16];
@@ -525,6 +526,7 @@ static inline void discovery_init(struct hci_dev *hdev)
 
 static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
 {
+       hdev->discovery.result_filtering = false;
        hdev->discovery.report_invalid_rssi = true;
        hdev->discovery.rssi = HCI_RSSI_INVALID;
        hdev->discovery.uuid_count = 0;
index bc09c5a37032ce0a18c7179be5aa9feb1682d971..967f07fdbbbe8f37c0f3b9405f4b3dd63e7c14b5 100644 (file)
@@ -3933,8 +3933,7 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status,
                 */
                if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
                             &hdev->quirks) &&
-                   (hdev->discovery.uuid_count > 0 ||
-                    hdev->discovery.rssi != HCI_RSSI_INVALID)) {
+                   hdev->discovery.result_filtering) {
                        hdev->discovery.scan_start = jiffies;
                        hdev->discovery.scan_duration = timeout;
                }
@@ -4087,6 +4086,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
         */
        hci_discovery_filter_clear(hdev);
 
+       hdev->discovery.result_filtering = true;
        hdev->discovery.type = cp->type;
        hdev->discovery.rssi = cp->rssi;
        hdev->discovery.uuid_count = uuid_count;
@@ -7344,8 +7344,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
                        return;
        }
 
-       if (hdev->discovery.rssi != HCI_RSSI_INVALID ||
-           hdev->discovery.uuid_count > 0) {
+       if (hdev->discovery.result_filtering) {
                /* We are using service discovery */
                if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp,
                                     scan_rsp_len))