diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-12-19 15:26:00 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-19 16:06:37 -0500 |
commit | 2cf22218b00f46f93b39a9355b830e9e8e4fd077 (patch) | |
tree | 8baa3725b8712eab8c446c431ad73840bd69f038 /net | |
parent | 0857dd3bed62d8f905f61a399d1ed76464b5270f (diff) |
Bluetooth: Add hci_request support for hci_update_background_scan
Many places using hci_update_background_scan() try to synchronize
whatever they're doing with the help of hci_request callbacks. However,
since the hci_update_background_scan() function hasn't so far accepted a
hci_request pointer any commands triggered by it have been left out by
the synchronization. This patch modifies the API in a similar way as was
done for hci_update_page_scan, i.e. there's a variant that takes a
hci_request and another one that takes a hci_dev.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 89 | ||||
-rw-r--r-- | net/bluetooth/hci_request.c | 96 | ||||
-rw-r--r-- | net/bluetooth/hci_request.h | 3 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 12 |
4 files changed, 105 insertions, 95 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 2cfaaa6acb04..def6fba01b45 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -5312,95 +5312,6 @@ static void hci_cmd_work(struct work_struct *work) | |||
5312 | } | 5312 | } |
5313 | } | 5313 | } |
5314 | 5314 | ||
5315 | static void update_background_scan_complete(struct hci_dev *hdev, u8 status) | ||
5316 | { | ||
5317 | if (status) | ||
5318 | BT_DBG("HCI request failed to update background scanning: " | ||
5319 | "status 0x%2.2x", status); | ||
5320 | } | ||
5321 | |||
5322 | /* This function controls the background scanning based on hdev->pend_le_conns | ||
5323 | * list. If there are pending LE connection we start the background scanning, | ||
5324 | * otherwise we stop it. | ||
5325 | * | ||
5326 | * This function requires the caller holds hdev->lock. | ||
5327 | */ | ||
5328 | void hci_update_background_scan(struct hci_dev *hdev) | ||
5329 | { | ||
5330 | struct hci_request req; | ||
5331 | struct hci_conn *conn; | ||
5332 | int err; | ||
5333 | |||
5334 | if (!test_bit(HCI_UP, &hdev->flags) || | ||
5335 | test_bit(HCI_INIT, &hdev->flags) || | ||
5336 | test_bit(HCI_SETUP, &hdev->dev_flags) || | ||
5337 | test_bit(HCI_CONFIG, &hdev->dev_flags) || | ||
5338 | test_bit(HCI_AUTO_OFF, &hdev->dev_flags) || | ||
5339 | test_bit(HCI_UNREGISTER, &hdev->dev_flags)) | ||
5340 | return; | ||
5341 | |||
5342 | /* No point in doing scanning if LE support hasn't been enabled */ | ||
5343 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) | ||
5344 | return; | ||
5345 | |||
5346 | /* If discovery is active don't interfere with it */ | ||
5347 | if (hdev->discovery.state != DISCOVERY_STOPPED) | ||
5348 | return; | ||
5349 | |||
5350 | /* Reset RSSI and UUID filters when starting background scanning | ||
5351 | * since these filters are meant for service discovery only. | ||
5352 | * | ||
5353 | * The Start Discovery and Start Service Discovery operations | ||
5354 | * ensure to set proper values for RSSI threshold and UUID | ||
5355 | * filter list. So it is safe to just reset them here. | ||
5356 | */ | ||
5357 | hci_discovery_filter_clear(hdev); | ||
5358 | |||
5359 | hci_req_init(&req, hdev); | ||
5360 | |||
5361 | if (list_empty(&hdev->pend_le_conns) && | ||
5362 | list_empty(&hdev->pend_le_reports)) { | ||
5363 | /* If there is no pending LE connections or devices | ||
5364 | * to be scanned for, we should stop the background | ||
5365 | * scanning. | ||
5366 | */ | ||
5367 | |||
5368 | /* If controller is not scanning we are done. */ | ||
5369 | if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
5370 | return; | ||
5371 | |||
5372 | hci_req_add_le_scan_disable(&req); | ||
5373 | |||
5374 | BT_DBG("%s stopping background scanning", hdev->name); | ||
5375 | } else { | ||
5376 | /* If there is at least one pending LE connection, we should | ||
5377 | * keep the background scan running. | ||
5378 | */ | ||
5379 | |||
5380 | /* If controller is connecting, we should not start scanning | ||
5381 | * since some controllers are not able to scan and connect at | ||
5382 | * the same time. | ||
5383 | */ | ||
5384 | conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); | ||
5385 | if (conn) | ||
5386 | return; | ||
5387 | |||
5388 | /* If controller is currently scanning, we stop it to ensure we | ||
5389 | * don't miss any advertising (due to duplicates filter). | ||
5390 | */ | ||
5391 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
5392 | hci_req_add_le_scan_disable(&req); | ||
5393 | |||
5394 | hci_req_add_le_passive_scan(&req); | ||
5395 | |||
5396 | BT_DBG("%s starting background scanning", hdev->name); | ||
5397 | } | ||
5398 | |||
5399 | err = hci_req_run(&req, update_background_scan_complete); | ||
5400 | if (err) | ||
5401 | BT_ERR("Failed to run HCI request: err %d", err); | ||
5402 | } | ||
5403 | |||
5404 | static bool disconnected_whitelist_entries(struct hci_dev *hdev) | 5315 | static bool disconnected_whitelist_entries(struct hci_dev *hdev) |
5405 | { | 5316 | { |
5406 | struct bdaddr_list *b; | 5317 | struct bdaddr_list *b; |
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index eba83a2a6556..e49f682f1550 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -395,3 +395,99 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, | |||
395 | 395 | ||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | |||
399 | /* This function controls the background scanning based on hdev->pend_le_conns | ||
400 | * list. If there are pending LE connection we start the background scanning, | ||
401 | * otherwise we stop it. | ||
402 | * | ||
403 | * This function requires the caller holds hdev->lock. | ||
404 | */ | ||
405 | void __hci_update_background_scan(struct hci_request *req) | ||
406 | { | ||
407 | struct hci_dev *hdev = req->hdev; | ||
408 | struct hci_conn *conn; | ||
409 | |||
410 | if (!test_bit(HCI_UP, &hdev->flags) || | ||
411 | test_bit(HCI_INIT, &hdev->flags) || | ||
412 | test_bit(HCI_SETUP, &hdev->dev_flags) || | ||
413 | test_bit(HCI_CONFIG, &hdev->dev_flags) || | ||
414 | test_bit(HCI_AUTO_OFF, &hdev->dev_flags) || | ||
415 | test_bit(HCI_UNREGISTER, &hdev->dev_flags)) | ||
416 | return; | ||
417 | |||
418 | /* No point in doing scanning if LE support hasn't been enabled */ | ||
419 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) | ||
420 | return; | ||
421 | |||
422 | /* If discovery is active don't interfere with it */ | ||
423 | if (hdev->discovery.state != DISCOVERY_STOPPED) | ||
424 | return; | ||
425 | |||
426 | /* Reset RSSI and UUID filters when starting background scanning | ||
427 | * since these filters are meant for service discovery only. | ||
428 | * | ||
429 | * The Start Discovery and Start Service Discovery operations | ||
430 | * ensure to set proper values for RSSI threshold and UUID | ||
431 | * filter list. So it is safe to just reset them here. | ||
432 | */ | ||
433 | hci_discovery_filter_clear(hdev); | ||
434 | |||
435 | if (list_empty(&hdev->pend_le_conns) && | ||
436 | list_empty(&hdev->pend_le_reports)) { | ||
437 | /* If there is no pending LE connections or devices | ||
438 | * to be scanned for, we should stop the background | ||
439 | * scanning. | ||
440 | */ | ||
441 | |||
442 | /* If controller is not scanning we are done. */ | ||
443 | if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
444 | return; | ||
445 | |||
446 | hci_req_add_le_scan_disable(req); | ||
447 | |||
448 | BT_DBG("%s stopping background scanning", hdev->name); | ||
449 | } else { | ||
450 | /* If there is at least one pending LE connection, we should | ||
451 | * keep the background scan running. | ||
452 | */ | ||
453 | |||
454 | /* If controller is connecting, we should not start scanning | ||
455 | * since some controllers are not able to scan and connect at | ||
456 | * the same time. | ||
457 | */ | ||
458 | conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); | ||
459 | if (conn) | ||
460 | return; | ||
461 | |||
462 | /* If controller is currently scanning, we stop it to ensure we | ||
463 | * don't miss any advertising (due to duplicates filter). | ||
464 | */ | ||
465 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | ||
466 | hci_req_add_le_scan_disable(req); | ||
467 | |||
468 | hci_req_add_le_passive_scan(req); | ||
469 | |||
470 | BT_DBG("%s starting background scanning", hdev->name); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static void update_background_scan_complete(struct hci_dev *hdev, u8 status) | ||
475 | { | ||
476 | if (status) | ||
477 | BT_DBG("HCI request failed to update background scanning: " | ||
478 | "status 0x%2.2x", status); | ||
479 | } | ||
480 | |||
481 | void hci_update_background_scan(struct hci_dev *hdev) | ||
482 | { | ||
483 | int err; | ||
484 | struct hci_request req; | ||
485 | |||
486 | hci_req_init(&req, hdev); | ||
487 | |||
488 | __hci_update_background_scan(&req); | ||
489 | |||
490 | err = hci_req_run(&req, update_background_scan_complete); | ||
491 | if (err && err != -ENODATA) | ||
492 | BT_ERR("Failed to run HCI request: err %d", err); | ||
493 | } | ||
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h index 1793a46fea65..adf074d33544 100644 --- a/net/bluetooth/hci_request.h +++ b/net/bluetooth/hci_request.h | |||
@@ -49,3 +49,6 @@ void __hci_update_page_scan(struct hci_request *req); | |||
49 | 49 | ||
50 | int hci_update_random_address(struct hci_request *req, bool require_privacy, | 50 | int hci_update_random_address(struct hci_request *req, bool require_privacy, |
51 | u8 *own_addr_type); | 51 | u8 *own_addr_type); |
52 | |||
53 | void hci_update_background_scan(struct hci_dev *hdev); | ||
54 | void __hci_update_background_scan(struct hci_request *req); | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 95473e966703..3afe1e175eb8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2228,9 +2228,8 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status) | |||
2228 | hci_req_init(&req, hdev); | 2228 | hci_req_init(&req, hdev); |
2229 | update_adv_data(&req); | 2229 | update_adv_data(&req); |
2230 | update_scan_rsp_data(&req); | 2230 | update_scan_rsp_data(&req); |
2231 | __hci_update_background_scan(&req); | ||
2231 | hci_req_run(&req, NULL); | 2232 | hci_req_run(&req, NULL); |
2232 | |||
2233 | hci_update_background_scan(hdev); | ||
2234 | } | 2233 | } |
2235 | 2234 | ||
2236 | unlock: | 2235 | unlock: |
@@ -6038,8 +6037,9 @@ void mgmt_index_removed(struct hci_dev *hdev) | |||
6038 | } | 6037 | } |
6039 | 6038 | ||
6040 | /* This function requires the caller holds hdev->lock */ | 6039 | /* This function requires the caller holds hdev->lock */ |
6041 | static void restart_le_actions(struct hci_dev *hdev) | 6040 | static void restart_le_actions(struct hci_request *req) |
6042 | { | 6041 | { |
6042 | struct hci_dev *hdev = req->hdev; | ||
6043 | struct hci_conn_params *p; | 6043 | struct hci_conn_params *p; |
6044 | 6044 | ||
6045 | list_for_each_entry(p, &hdev->le_conn_params, list) { | 6045 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
@@ -6061,7 +6061,7 @@ static void restart_le_actions(struct hci_dev *hdev) | |||
6061 | } | 6061 | } |
6062 | } | 6062 | } |
6063 | 6063 | ||
6064 | hci_update_background_scan(hdev); | 6064 | __hci_update_background_scan(req); |
6065 | } | 6065 | } |
6066 | 6066 | ||
6067 | static void powered_complete(struct hci_dev *hdev, u8 status) | 6067 | static void powered_complete(struct hci_dev *hdev, u8 status) |
@@ -6072,8 +6072,6 @@ static void powered_complete(struct hci_dev *hdev, u8 status) | |||
6072 | 6072 | ||
6073 | hci_dev_lock(hdev); | 6073 | hci_dev_lock(hdev); |
6074 | 6074 | ||
6075 | restart_le_actions(hdev); | ||
6076 | |||
6077 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); | 6075 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); |
6078 | 6076 | ||
6079 | new_settings(hdev, match.sk); | 6077 | new_settings(hdev, match.sk); |
@@ -6131,6 +6129,8 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
6131 | 6129 | ||
6132 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | 6130 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) |
6133 | enable_advertising(&req); | 6131 | enable_advertising(&req); |
6132 | |||
6133 | restart_le_actions(&req); | ||
6134 | } | 6134 | } |
6135 | 6135 | ||
6136 | link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); | 6136 | link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); |