aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-07-24 09:20:57 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2014-07-26 07:13:17 -0400
commit8540f6c0364722b141547c6c7ac366c3ea77390b (patch)
tree6296e647dbbac5e9ef94ba2c275bb4e048c13871 /net/bluetooth
parent4b9e7e7516135b1d5f047ad59188b5355bacc106 (diff)
Bluetooth: Add support for using controller white list filtering
The Bluetooth controller can use a white list filter when scanning to avoid waking up the host for devices that are of no interest. Devices marked as reporting, direct connection (incoming) or general connection are now added to the controller white list. The update of the white list happens just before enabling passive scanning. In case the white list is full and can not hold all devices, the white list is not used and the filter policy set to accept all advertisements. Using the white list for scanning allows for power saving with controllers that do not handle the duplicate filtering correctly. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d8f91d5b0e56..ecff30ab22a0 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -5406,12 +5406,101 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
5406 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 5406 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5407} 5407}
5408 5408
5409static void add_to_white_list(struct hci_request *req,
5410 struct hci_conn_params *params)
5411{
5412 struct hci_cp_le_add_to_white_list cp;
5413
5414 cp.bdaddr_type = params->addr_type;
5415 bacpy(&cp.bdaddr, &params->addr);
5416
5417 hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp);
5418}
5419
5420static u8 update_white_list(struct hci_request *req)
5421{
5422 struct hci_dev *hdev = req->hdev;
5423 struct hci_conn_params *params;
5424 struct bdaddr_list *b;
5425 uint8_t white_list_entries = 0;
5426
5427 /* Go through the current white list programmed into the
5428 * controller one by one and check if that address is still
5429 * in the list of pending connections or list of devices to
5430 * report. If not present in either list, then queue the
5431 * command to remove it from the controller.
5432 */
5433 list_for_each_entry(b, &hdev->le_white_list, list) {
5434 struct hci_cp_le_del_from_white_list cp;
5435
5436 if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
5437 &b->bdaddr, b->bdaddr_type) ||
5438 hci_pend_le_action_lookup(&hdev->pend_le_reports,
5439 &b->bdaddr, b->bdaddr_type)) {
5440 white_list_entries++;
5441 continue;
5442 }
5443
5444 cp.bdaddr_type = b->bdaddr_type;
5445 bacpy(&cp.bdaddr, &b->bdaddr);
5446
5447 hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
5448 sizeof(cp), &cp);
5449 }
5450
5451 /* Since all no longer valid white list entries have been
5452 * removed, walk through the list of pending connections
5453 * and ensure that any new device gets programmed into
5454 * the controller.
5455 *
5456 * If the list of the devices is larger than the list of
5457 * available white list entries in the controller, then
5458 * just abort and return filer policy value to not use the
5459 * white list.
5460 */
5461 list_for_each_entry(params, &hdev->pend_le_conns, action) {
5462 if (hci_bdaddr_list_lookup(&hdev->le_white_list,
5463 &params->addr, params->addr_type))
5464 continue;
5465
5466 if (white_list_entries >= hdev->le_white_list_size) {
5467 /* Select filter policy to accept all advertising */
5468 return 0x00;
5469 }
5470
5471 white_list_entries++;
5472 add_to_white_list(req, params);
5473 }
5474
5475 /* After adding all new pending connections, walk through
5476 * the list of pending reports and also add these to the
5477 * white list if there is still space.
5478 */
5479 list_for_each_entry(params, &hdev->pend_le_reports, action) {
5480 if (hci_bdaddr_list_lookup(&hdev->le_white_list,
5481 &params->addr, params->addr_type))
5482 continue;
5483
5484 if (white_list_entries >= hdev->le_white_list_size) {
5485 /* Select filter policy to accept all advertising */
5486 return 0x00;
5487 }
5488
5489 white_list_entries++;
5490 add_to_white_list(req, params);
5491 }
5492
5493 /* Select filter policy to use white list */
5494 return 0x01;
5495}
5496
5409void hci_req_add_le_passive_scan(struct hci_request *req) 5497void hci_req_add_le_passive_scan(struct hci_request *req)
5410{ 5498{
5411 struct hci_cp_le_set_scan_param param_cp; 5499 struct hci_cp_le_set_scan_param param_cp;
5412 struct hci_cp_le_set_scan_enable enable_cp; 5500 struct hci_cp_le_set_scan_enable enable_cp;
5413 struct hci_dev *hdev = req->hdev; 5501 struct hci_dev *hdev = req->hdev;
5414 u8 own_addr_type; 5502 u8 own_addr_type;
5503 u8 filter_policy;
5415 5504
5416 /* Set require_privacy to false since no SCAN_REQ are send 5505 /* Set require_privacy to false since no SCAN_REQ are send
5417 * during passive scanning. Not using an unresolvable address 5506 * during passive scanning. Not using an unresolvable address
@@ -5422,11 +5511,18 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
5422 if (hci_update_random_address(req, false, &own_addr_type)) 5511 if (hci_update_random_address(req, false, &own_addr_type))
5423 return; 5512 return;
5424 5513
5514 /* Adding or removing entries from the white list must
5515 * happen before enabling scanning. The controller does
5516 * not allow white list modification while scanning.
5517 */
5518 filter_policy = update_white_list(req);
5519
5425 memset(&param_cp, 0, sizeof(param_cp)); 5520 memset(&param_cp, 0, sizeof(param_cp));
5426 param_cp.type = LE_SCAN_PASSIVE; 5521 param_cp.type = LE_SCAN_PASSIVE;
5427 param_cp.interval = cpu_to_le16(hdev->le_scan_interval); 5522 param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
5428 param_cp.window = cpu_to_le16(hdev->le_scan_window); 5523 param_cp.window = cpu_to_le16(hdev->le_scan_window);
5429 param_cp.own_address_type = own_addr_type; 5524 param_cp.own_address_type = own_addr_type;
5525 param_cp.filter_policy = filter_policy;
5430 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), 5526 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
5431 &param_cp); 5527 &param_cp);
5432 5528