aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2015-03-04 19:24:24 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2015-03-05 02:50:50 -0500
commit48f86b7f2673352d075e567a8f3425c548be8424 (patch)
tree5367e6ba3110b37f08eaf30f16e931b82f719f15 /net/bluetooth/mgmt.c
parent263be3326b89a1a4994b29cbe898637fd72e6f0b (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.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)
7280 DISCOV_LE_RESTART_DELAY); 7280 DISCOV_LE_RESTART_DELAY);
7281} 7281}
7282 7282
7283void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 7283static 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
7379void 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