aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2015-03-04 16:24:24 -0800
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-05 09:50:50 +0200
commit48f86b7f2673352d075e567a8f3425c548be8424 (patch)
tree5367e6ba3110b37f08eaf30f16e931b82f719f15 /net/bluetooth
parentat86rf230: restore trx len when needed (diff)
downloadlinux-dev-48f86b7f2673352d075e567a8f3425c548be8424.tar.xz
linux-dev-48f86b7f2673352d075e567a8f3425c548be8424.zip
Bluetooth: Move Service Discovery logic before refactoring
This patch moves whole packet filering logic of service discovery into new function is_filter_match. It's done because logic inside mgmt_device_found is very complicated and needs some simplification. Also having whole logic in one place will allow to simplify it in the future. Signed-off-by: Jakub Pawlowski <jpawlowski@google.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/mgmt.c141
1 files changed, 79 insertions, 62 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1e4635a3374d..a41a5efa4391 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -7280,32 +7280,16 @@ static void restart_le_scan(struct hci_dev *hdev)
DISCOV_LE_RESTART_DELAY);
}
-void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
- u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
- u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
+static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
+ u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
{
- char buf[512];
- struct mgmt_ev_device_found *ev = (void *) buf;
- size_t ev_size;
bool match;
- /* Don't send events for a non-kernel initiated discovery. With
- * LE one exception is if we have pend_le_reports > 0 in which
- * case we're doing passive scanning and want these events.
- */
- if (!hci_discovery_active(hdev)) {
- if (link_type == ACL_LINK)
- return;
- if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
- return;
- }
-
- /* When using service discovery with a RSSI threshold, then check
- * if such a RSSI threshold is specified. If a RSSI threshold has
- * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set,
- * then all results with a RSSI smaller than the RSSI threshold will be
- * dropped. If the quirk is set, let it through for further processing,
- * as we might need to restart the scan.
+ /* If a RSSI threshold has been specified, and
+ * HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, then all results with
+ * a RSSI smaller than the RSSI threshold will be dropped. If the quirk
+ * is set, let it through for further processing, as we might need to
+ * restart the scan.
*
* For BR/EDR devices (pre 1.2) providing no RSSI during inquiry,
* the results are also dropped.
@@ -7314,32 +7298,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
(rssi == HCI_RSSI_INVALID ||
(rssi < hdev->discovery.rssi &&
!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
- return;
-
- /* Make sure that the buffer is big enough. The 5 extra bytes
- * are for the potential CoD field.
- */
- if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf))
- return;
-
- memset(buf, 0, sizeof(buf));
-
- /* In case of device discovery with BR/EDR devices (pre 1.2), the
- * RSSI value was reported as 0 when not available. This behavior
- * is kept when using device discovery. This is required for full
- * backwards compatibility with the API.
- *
- * However when using service discovery, the value 127 will be
- * returned when the RSSI is not available.
- */
- if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi &&
- link_type == ACL_LINK)
- rssi = 0;
+ return false;
- bacpy(&ev->addr.bdaddr, bdaddr);
- ev->addr.type = link_to_bdaddr(link_type, addr_type);
- ev->rssi = rssi;
- ev->flags = cpu_to_le32(flags);
if (eir_len > 0) {
/* When using service discovery and a list of UUID is
@@ -7364,25 +7324,18 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
}
if (!match && !scan_rsp_len)
- return;
-
- /* Copy EIR or advertising data into event */
- memcpy(ev->eir, eir, eir_len);
+ return false;
} else {
/* When using service discovery and a list of UUID is
* provided, results with empty EIR or advertising data
* should be dropped since they do not match any UUID.
*/
if (hdev->discovery.uuid_count > 0 && !scan_rsp_len)
- return;
+ return false;
match = false;
}
- if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
- eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
- dev_class, 3);
-
if (scan_rsp_len > 0) {
/* When using service discovery and a list of UUID is
* provided, results with no matching UUID should be
@@ -7393,7 +7346,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len,
hdev->discovery.uuid_count,
hdev->discovery.uuids))
- return;
+ return false;
/* If duplicate filtering does not report RSSI changes,
* then restart scanning to ensure updated result with
@@ -7403,16 +7356,13 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
&hdev->quirks))
restart_le_scan(hdev);
}
-
- /* Append scan response data to event */
- memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
} else {
/* When using service discovery and a list of UUID is
* provided, results with empty scan response and no
* previous matched advertising data should be dropped.
*/
if (hdev->discovery.uuid_count > 0 && !match)
- return;
+ return false;
}
/* Validate the reported RSSI value against the RSSI threshold once more
@@ -7421,8 +7371,75 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
*/
if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
rssi < hdev->discovery.rssi)
+ return false;
+
+ return true;
+}
+
+void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+ u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
+ u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
+{
+ char buf[512];
+ struct mgmt_ev_device_found *ev = (void *)buf;
+ size_t ev_size;
+
+ /* Don't send events for a non-kernel initiated discovery. With
+ * LE one exception is if we have pend_le_reports > 0 in which
+ * case we're doing passive scanning and want these events.
+ */
+ if (!hci_discovery_active(hdev)) {
+ if (link_type == ACL_LINK)
+ return;
+ if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
+ return;
+ }
+
+ if (hdev->discovery.rssi != HCI_RSSI_INVALID ||
+ hdev->discovery.uuid_count > 0) {
+ /* We are using service discovery */
+ if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp,
+ scan_rsp_len))
+ return;
+ }
+
+ /* Make sure that the buffer is big enough. The 5 extra bytes
+ * are for the potential CoD field.
+ */
+ if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf))
return;
+ memset(buf, 0, sizeof(buf));
+
+ /* In case of device discovery with BR/EDR devices (pre 1.2), the
+ * RSSI value was reported as 0 when not available. This behavior
+ * is kept when using device discovery. This is required for full
+ * backwards compatibility with the API.
+ *
+ * However when using service discovery, the value 127 will be
+ * returned when the RSSI is not available.
+ */
+ if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi &&
+ link_type == ACL_LINK)
+ rssi = 0;
+
+ bacpy(&ev->addr.bdaddr, bdaddr);
+ ev->addr.type = link_to_bdaddr(link_type, addr_type);
+ ev->rssi = rssi;
+ ev->flags = cpu_to_le32(flags);
+
+ if (eir_len > 0)
+ /* Copy EIR or advertising data into event */
+ memcpy(ev->eir, eir, eir_len);
+
+ if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
+ eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
+ dev_class, 3);
+
+ if (scan_rsp_len > 0)
+ /* Append scan response data to event */
+ memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
+
ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
ev_size = sizeof(*ev) + eir_len + scan_rsp_len;