diff options
author | Jakub Pawlowski <jpawlowski@google.com> | 2015-03-04 19:24:24 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-05 02:50:50 -0500 |
commit | 48f86b7f2673352d075e567a8f3425c548be8424 (patch) | |
tree | 5367e6ba3110b37f08eaf30f16e931b82f719f15 /net/bluetooth/mgmt.c | |
parent | 263be3326b89a1a4994b29cbe898637fd72e6f0b (diff) |
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/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 141 |
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) | |||
7280 | DISCOV_LE_RESTART_DELAY); | 7280 | DISCOV_LE_RESTART_DELAY); |
7281 | } | 7281 | } |
7282 | 7282 | ||
7283 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 7283 | static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, |
7284 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, | 7284 | u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) |
7285 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) | ||
7286 | { | 7285 | { |
7287 | char buf[512]; | ||
7288 | struct mgmt_ev_device_found *ev = (void *) buf; | ||
7289 | size_t ev_size; | ||
7290 | bool match; | 7286 | bool match; |
7291 | 7287 | ||
7292 | /* Don't send events for a non-kernel initiated discovery. With | 7288 | /* If a RSSI threshold has been specified, and |
7293 | * LE one exception is if we have pend_le_reports > 0 in which | 7289 | * HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, then all results with |
7294 | * case we're doing passive scanning and want these events. | 7290 | * a RSSI smaller than the RSSI threshold will be dropped. If the quirk |
7295 | */ | 7291 | * is set, let it through for further processing, as we might need to |
7296 | if (!hci_discovery_active(hdev)) { | 7292 | * restart the scan. |
7297 | if (link_type == ACL_LINK) | ||
7298 | return; | ||
7299 | if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports)) | ||
7300 | return; | ||
7301 | } | ||
7302 | |||
7303 | /* When using service discovery with a RSSI threshold, then check | ||
7304 | * if such a RSSI threshold is specified. If a RSSI threshold has | ||
7305 | * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, | ||
7306 | * then all results with a RSSI smaller than the RSSI threshold will be | ||
7307 | * dropped. If the quirk is set, let it through for further processing, | ||
7308 | * as we might need to restart the scan. | ||
7309 | * | 7293 | * |
7310 | * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, | 7294 | * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, |
7311 | * the results are also dropped. | 7295 | * the results are also dropped. |
@@ -7314,32 +7298,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
7314 | (rssi == HCI_RSSI_INVALID || | 7298 | (rssi == HCI_RSSI_INVALID || |
7315 | (rssi < hdev->discovery.rssi && | 7299 | (rssi < hdev->discovery.rssi && |
7316 | !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)))) | 7300 | !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)))) |
7317 | return; | 7301 | return false; |
7318 | |||
7319 | /* Make sure that the buffer is big enough. The 5 extra bytes | ||
7320 | * are for the potential CoD field. | ||
7321 | */ | ||
7322 | if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf)) | ||
7323 | return; | ||
7324 | |||
7325 | memset(buf, 0, sizeof(buf)); | ||
7326 | |||
7327 | /* In case of device discovery with BR/EDR devices (pre 1.2), the | ||
7328 | * RSSI value was reported as 0 when not available. This behavior | ||
7329 | * is kept when using device discovery. This is required for full | ||
7330 | * backwards compatibility with the API. | ||
7331 | * | ||
7332 | * However when using service discovery, the value 127 will be | ||
7333 | * returned when the RSSI is not available. | ||
7334 | */ | ||
7335 | if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi && | ||
7336 | link_type == ACL_LINK) | ||
7337 | rssi = 0; | ||
7338 | 7302 | ||
7339 | bacpy(&ev->addr.bdaddr, bdaddr); | ||
7340 | ev->addr.type = link_to_bdaddr(link_type, addr_type); | ||
7341 | ev->rssi = rssi; | ||
7342 | ev->flags = cpu_to_le32(flags); | ||
7343 | 7303 | ||
7344 | if (eir_len > 0) { | 7304 | if (eir_len > 0) { |
7345 | /* When using service discovery and a list of UUID is | 7305 | /* 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, | |||
7364 | } | 7324 | } |
7365 | 7325 | ||
7366 | if (!match && !scan_rsp_len) | 7326 | if (!match && !scan_rsp_len) |
7367 | return; | 7327 | return false; |
7368 | |||
7369 | /* Copy EIR or advertising data into event */ | ||
7370 | memcpy(ev->eir, eir, eir_len); | ||
7371 | } else { | 7328 | } else { |
7372 | /* When using service discovery and a list of UUID is | 7329 | /* When using service discovery and a list of UUID is |
7373 | * provided, results with empty EIR or advertising data | 7330 | * provided, results with empty EIR or advertising data |
7374 | * should be dropped since they do not match any UUID. | 7331 | * should be dropped since they do not match any UUID. |
7375 | */ | 7332 | */ |
7376 | if (hdev->discovery.uuid_count > 0 && !scan_rsp_len) | 7333 | if (hdev->discovery.uuid_count > 0 && !scan_rsp_len) |
7377 | return; | 7334 | return false; |
7378 | 7335 | ||
7379 | match = false; | 7336 | match = false; |
7380 | } | 7337 | } |
7381 | 7338 | ||
7382 | if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV)) | ||
7383 | eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, | ||
7384 | dev_class, 3); | ||
7385 | |||
7386 | if (scan_rsp_len > 0) { | 7339 | if (scan_rsp_len > 0) { |
7387 | /* When using service discovery and a list of UUID is | 7340 | /* When using service discovery and a list of UUID is |
7388 | * provided, results with no matching UUID should be | 7341 | * 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, | |||
7393 | if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len, | 7346 | if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len, |
7394 | hdev->discovery.uuid_count, | 7347 | hdev->discovery.uuid_count, |
7395 | hdev->discovery.uuids)) | 7348 | hdev->discovery.uuids)) |
7396 | return; | 7349 | return false; |
7397 | 7350 | ||
7398 | /* If duplicate filtering does not report RSSI changes, | 7351 | /* If duplicate filtering does not report RSSI changes, |
7399 | * then restart scanning to ensure updated result with | 7352 | * 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, | |||
7403 | &hdev->quirks)) | 7356 | &hdev->quirks)) |
7404 | restart_le_scan(hdev); | 7357 | restart_le_scan(hdev); |
7405 | } | 7358 | } |
7406 | |||
7407 | /* Append scan response data to event */ | ||
7408 | memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); | ||
7409 | } else { | 7359 | } else { |
7410 | /* When using service discovery and a list of UUID is | 7360 | /* When using service discovery and a list of UUID is |
7411 | * provided, results with empty scan response and no | 7361 | * provided, results with empty scan response and no |
7412 | * previous matched advertising data should be dropped. | 7362 | * previous matched advertising data should be dropped. |
7413 | */ | 7363 | */ |
7414 | if (hdev->discovery.uuid_count > 0 && !match) | 7364 | if (hdev->discovery.uuid_count > 0 && !match) |
7415 | return; | 7365 | return false; |
7416 | } | 7366 | } |
7417 | 7367 | ||
7418 | /* Validate the reported RSSI value against the RSSI threshold once more | 7368 | /* 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, | |||
7421 | */ | 7371 | */ |
7422 | if (hdev->discovery.rssi != HCI_RSSI_INVALID && | 7372 | if (hdev->discovery.rssi != HCI_RSSI_INVALID && |
7423 | rssi < hdev->discovery.rssi) | 7373 | rssi < hdev->discovery.rssi) |
7374 | return false; | ||
7375 | |||
7376 | return true; | ||
7377 | } | ||
7378 | |||
7379 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | ||
7380 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, | ||
7381 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) | ||
7382 | { | ||
7383 | char buf[512]; | ||
7384 | struct mgmt_ev_device_found *ev = (void *)buf; | ||
7385 | size_t ev_size; | ||
7386 | |||
7387 | /* Don't send events for a non-kernel initiated discovery. With | ||
7388 | * LE one exception is if we have pend_le_reports > 0 in which | ||
7389 | * case we're doing passive scanning and want these events. | ||
7390 | */ | ||
7391 | if (!hci_discovery_active(hdev)) { | ||
7392 | if (link_type == ACL_LINK) | ||
7393 | return; | ||
7394 | if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports)) | ||
7395 | return; | ||
7396 | } | ||
7397 | |||
7398 | if (hdev->discovery.rssi != HCI_RSSI_INVALID || | ||
7399 | hdev->discovery.uuid_count > 0) { | ||
7400 | /* We are using service discovery */ | ||
7401 | if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp, | ||
7402 | scan_rsp_len)) | ||
7403 | return; | ||
7404 | } | ||
7405 | |||
7406 | /* Make sure that the buffer is big enough. The 5 extra bytes | ||
7407 | * are for the potential CoD field. | ||
7408 | */ | ||
7409 | if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf)) | ||
7424 | return; | 7410 | return; |
7425 | 7411 | ||
7412 | memset(buf, 0, sizeof(buf)); | ||
7413 | |||
7414 | /* In case of device discovery with BR/EDR devices (pre 1.2), the | ||
7415 | * RSSI value was reported as 0 when not available. This behavior | ||
7416 | * is kept when using device discovery. This is required for full | ||
7417 | * backwards compatibility with the API. | ||
7418 | * | ||
7419 | * However when using service discovery, the value 127 will be | ||
7420 | * returned when the RSSI is not available. | ||
7421 | */ | ||
7422 | if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi && | ||
7423 | link_type == ACL_LINK) | ||
7424 | rssi = 0; | ||
7425 | |||
7426 | bacpy(&ev->addr.bdaddr, bdaddr); | ||
7427 | ev->addr.type = link_to_bdaddr(link_type, addr_type); | ||
7428 | ev->rssi = rssi; | ||
7429 | ev->flags = cpu_to_le32(flags); | ||
7430 | |||
7431 | if (eir_len > 0) | ||
7432 | /* Copy EIR or advertising data into event */ | ||
7433 | memcpy(ev->eir, eir, eir_len); | ||
7434 | |||
7435 | if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV)) | ||
7436 | eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, | ||
7437 | dev_class, 3); | ||
7438 | |||
7439 | if (scan_rsp_len > 0) | ||
7440 | /* Append scan response data to event */ | ||
7441 | memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len); | ||
7442 | |||
7426 | ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); | 7443 | ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); |
7427 | ev_size = sizeof(*ev) + eir_len + scan_rsp_len; | 7444 | ev_size = sizeof(*ev) + eir_len + scan_rsp_len; |
7428 | 7445 | ||