@@ -5406,12 +5406,101 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
5406
5406
hci_req_add (req , HCI_OP_LE_SET_SCAN_ENABLE , sizeof (cp ), & cp );
5407
5407
}
5408
5408
5409
+ static 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
+
5420
+ static 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
+
5409
5497
void hci_req_add_le_passive_scan (struct hci_request * req )
5410
5498
{
5411
5499
struct hci_cp_le_set_scan_param param_cp ;
5412
5500
struct hci_cp_le_set_scan_enable enable_cp ;
5413
5501
struct hci_dev * hdev = req -> hdev ;
5414
5502
u8 own_addr_type ;
5503
+ u8 filter_policy ;
5415
5504
5416
5505
/* Set require_privacy to false since no SCAN_REQ are send
5417
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
5511
if (hci_update_random_address (req , false, & own_addr_type ))
5423
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
5520
memset (& param_cp , 0 , sizeof (param_cp ));
5426
5521
param_cp .type = LE_SCAN_PASSIVE ;
5427
5522
param_cp .interval = cpu_to_le16 (hdev -> le_scan_interval );
5428
5523
param_cp .window = cpu_to_le16 (hdev -> le_scan_window );
5429
5524
param_cp .own_address_type = own_addr_type ;
5525
+ param_cp .filter_policy = filter_policy ;
5430
5526
hci_req_add (req , HCI_OP_LE_SET_SCAN_PARAM , sizeof (param_cp ),
5431
5527
& param_cp );
5432
5528
0 commit comments