aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-12-19 15:26:00 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-12-19 16:06:37 -0500
commit2cf22218b00f46f93b39a9355b830e9e8e4fd077 (patch)
tree8baa3725b8712eab8c446c431ad73840bd69f038 /net
parent0857dd3bed62d8f905f61a399d1ed76464b5270f (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.c89
-rw-r--r--net/bluetooth/hci_request.c96
-rw-r--r--net/bluetooth/hci_request.h3
-rw-r--r--net/bluetooth/mgmt.c12
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
5315static 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 */
5328void 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
5404static bool disconnected_whitelist_entries(struct hci_dev *hdev) 5315static 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 */
405void __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
474static 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
481void 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
50int hci_update_random_address(struct hci_request *req, bool require_privacy, 50int hci_update_random_address(struct hci_request *req, bool require_privacy,
51 u8 *own_addr_type); 51 u8 *own_addr_type);
52
53void hci_update_background_scan(struct hci_dev *hdev);
54void __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
2236unlock: 2235unlock:
@@ -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 */
6041static void restart_le_actions(struct hci_dev *hdev) 6040static 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
6067static void powered_complete(struct hci_dev *hdev, u8 status) 6067static 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);