forked from mirrors/linux
		
	Bluetooth: hci_core: Remove le_restart_scan work
This removes le_restart_scan work and instead just disables controller duplicate filtering when discovery result_filtering is enabled and HCI_QUIRK_STRICT_DUPLICATE_FILTER is set. Link: https://github.com/bluez/bluez/issues/573 Link: https://github.com/bluez/bluez/issues/572 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
		
							parent
							
								
									ba9e401493
								
							
						
					
					
						commit
						78db544b5d
					
				
					 3 changed files with 7 additions and 107 deletions
				
			
		|  | @ -539,7 +539,6 @@ struct hci_dev { | |||
| 	struct work_struct	tx_work; | ||||
| 
 | ||||
| 	struct delayed_work	le_scan_disable; | ||||
| 	struct delayed_work	le_scan_restart; | ||||
| 
 | ||||
| 	struct sk_buff_head	rx_q; | ||||
| 	struct sk_buff_head	raw_q; | ||||
|  |  | |||
|  | @ -348,8 +348,6 @@ static void le_scan_disable(struct work_struct *work) | |||
| 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) | ||||
| 		goto _return; | ||||
| 
 | ||||
| 	cancel_delayed_work(&hdev->le_scan_restart); | ||||
| 
 | ||||
| 	status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL); | ||||
| 	if (status) { | ||||
| 		bt_dev_err(hdev, "failed to disable LE scan: %d", status); | ||||
|  | @ -397,71 +395,6 @@ static void le_scan_disable(struct work_struct *work) | |||
| 
 | ||||
| static int hci_le_set_scan_enable_sync(struct hci_dev *hdev, u8 val, | ||||
| 				       u8 filter_dup); | ||||
| static int hci_le_scan_restart_sync(struct hci_dev *hdev) | ||||
| { | ||||
| 	/* If controller is not scanning we are done. */ | ||||
| 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (hdev->scanning_paused) { | ||||
| 		bt_dev_dbg(hdev, "Scanning is paused for suspend"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	hci_le_set_scan_enable_sync(hdev, LE_SCAN_DISABLE, 0x00); | ||||
| 	return hci_le_set_scan_enable_sync(hdev, LE_SCAN_ENABLE, | ||||
| 					   LE_SCAN_FILTER_DUP_ENABLE); | ||||
| } | ||||
| 
 | ||||
| static void le_scan_restart(struct work_struct *work) | ||||
| { | ||||
| 	struct hci_dev *hdev = container_of(work, struct hci_dev, | ||||
| 					    le_scan_restart.work); | ||||
| 	unsigned long timeout, duration, scan_start, now; | ||||
| 	int status; | ||||
| 
 | ||||
| 	bt_dev_dbg(hdev, ""); | ||||
| 
 | ||||
| 	status = hci_le_scan_restart_sync(hdev); | ||||
| 	if (status) { | ||||
| 		bt_dev_err(hdev, "failed to restart LE scan: status %d", | ||||
| 			   status); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	hci_dev_lock(hdev); | ||||
| 
 | ||||
| 	if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) || | ||||
| 	    !hdev->discovery.scan_start) | ||||
| 		goto unlock; | ||||
| 
 | ||||
| 	/* When the scan was started, hdev->le_scan_disable has been queued
 | ||||
| 	 * after duration from scan_start. During scan restart this job | ||||
| 	 * has been canceled, and we need to queue it again after proper | ||||
| 	 * timeout, to make sure that scan does not run indefinitely. | ||||
| 	 */ | ||||
| 	duration = hdev->discovery.scan_duration; | ||||
| 	scan_start = hdev->discovery.scan_start; | ||||
| 	now = jiffies; | ||||
| 	if (now - scan_start <= duration) { | ||||
| 		int elapsed; | ||||
| 
 | ||||
| 		if (now >= scan_start) | ||||
| 			elapsed = now - scan_start; | ||||
| 		else | ||||
| 			elapsed = ULONG_MAX - scan_start + now; | ||||
| 
 | ||||
| 		timeout = duration - elapsed; | ||||
| 	} else { | ||||
| 		timeout = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	queue_delayed_work(hdev->req_workqueue, | ||||
| 			   &hdev->le_scan_disable, timeout); | ||||
| 
 | ||||
| unlock: | ||||
| 	hci_dev_unlock(hdev); | ||||
| } | ||||
| 
 | ||||
| static int reenable_adv_sync(struct hci_dev *hdev, void *data) | ||||
| { | ||||
|  | @ -630,7 +563,6 @@ void hci_cmd_sync_init(struct hci_dev *hdev) | |||
| 	INIT_WORK(&hdev->cmd_sync_cancel_work, hci_cmd_sync_cancel_work); | ||||
| 	INIT_WORK(&hdev->reenable_adv_work, reenable_adv); | ||||
| 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable); | ||||
| 	INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart); | ||||
| 	INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); | ||||
| } | ||||
| 
 | ||||
|  | @ -4960,7 +4892,6 @@ int hci_dev_close_sync(struct hci_dev *hdev) | |||
| 	cancel_delayed_work(&hdev->power_off); | ||||
| 	cancel_delayed_work(&hdev->ncmd_timer); | ||||
| 	cancel_delayed_work(&hdev->le_scan_disable); | ||||
| 	cancel_delayed_work(&hdev->le_scan_restart); | ||||
| 
 | ||||
| 	hci_request_cancel_all(hdev); | ||||
| 
 | ||||
|  | @ -5178,7 +5109,6 @@ int hci_stop_discovery_sync(struct hci_dev *hdev) | |||
| 
 | ||||
| 		if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { | ||||
| 			cancel_delayed_work(&hdev->le_scan_disable); | ||||
| 			cancel_delayed_work(&hdev->le_scan_restart); | ||||
| 
 | ||||
| 			err = hci_scan_disable_sync(hdev); | ||||
| 			if (err) | ||||
|  | @ -5686,19 +5616,18 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval) | |||
| 	if (err < 0) | ||||
| 		own_addr_type = ADDR_LE_DEV_PUBLIC; | ||||
| 
 | ||||
| 	if (hci_is_adv_monitoring(hdev)) { | ||||
| 	if (hci_is_adv_monitoring(hdev) || | ||||
| 	    (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) && | ||||
| 	    hdev->discovery.result_filtering)) { | ||||
| 		/* Duplicate filter should be disabled when some advertisement
 | ||||
| 		 * monitor is activated, otherwise AdvMon can only receive one | ||||
| 		 * advertisement for one peer(*) during active scanning, and | ||||
| 		 * might report loss to these peers. | ||||
| 		 * | ||||
| 		 * Note that different controllers have different meanings of | ||||
| 		 * |duplicate|. Some of them consider packets with the same | ||||
| 		 * address as duplicate, and others consider packets with the | ||||
| 		 * same address and the same RSSI as duplicate. Although in the | ||||
| 		 * latter case we don't need to disable duplicate filter, but | ||||
| 		 * it is common to have active scanning for a short period of | ||||
| 		 * time, the power impact should be neglectable. | ||||
| 		 * If controller does strict duplicate filtering and the | ||||
| 		 * discovery requires result filtering disables controller based | ||||
| 		 * filtering since that can cause reports that would match the | ||||
| 		 * host filter to not be reported. | ||||
| 		 */ | ||||
| 		filter_dup = LE_SCAN_FILTER_DUP_DISABLE; | ||||
| 	} | ||||
|  | @ -5778,17 +5707,6 @@ int hci_start_discovery_sync(struct hci_dev *hdev) | |||
| 
 | ||||
| 	bt_dev_dbg(hdev, "timeout %u ms", jiffies_to_msecs(timeout)); | ||||
| 
 | ||||
| 	/* When service discovery is used and the controller has a
 | ||||
| 	 * strict duplicate filter, it is important to remember the | ||||
| 	 * start and duration of the scan. This is required for | ||||
| 	 * restarting scanning during the discovery phase. | ||||
| 	 */ | ||||
| 	if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) && | ||||
| 	    hdev->discovery.result_filtering) { | ||||
| 		hdev->discovery.scan_start = jiffies; | ||||
| 		hdev->discovery.scan_duration = timeout; | ||||
| 	} | ||||
| 
 | ||||
| 	queue_delayed_work(hdev->req_workqueue, &hdev->le_scan_disable, | ||||
| 			   timeout); | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -10145,21 +10145,6 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16]) | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static void restart_le_scan(struct hci_dev *hdev) | ||||
| { | ||||
| 	/* If controller is not scanning we are done. */ | ||||
| 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (time_after(jiffies + DISCOV_LE_RESTART_DELAY, | ||||
| 		       hdev->discovery.scan_start + | ||||
| 		       hdev->discovery.scan_duration)) | ||||
| 		return; | ||||
| 
 | ||||
| 	queue_delayed_work(hdev->req_workqueue, &hdev->le_scan_restart, | ||||
| 			   DISCOV_LE_RESTART_DELAY); | ||||
| } | ||||
| 
 | ||||
| static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, | ||||
| 			    u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) | ||||
| { | ||||
|  | @ -10194,8 +10179,6 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir, | |||
| 	 * scanning to ensure updated result with updated RSSI values. | ||||
| 	 */ | ||||
| 	if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)) { | ||||
| 		restart_le_scan(hdev); | ||||
| 
 | ||||
| 		/* Validate RSSI value against the RSSI threshold once more. */ | ||||
| 		if (hdev->discovery.rssi != HCI_RSSI_INVALID && | ||||
| 		    rssi < hdev->discovery.rssi) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Luiz Augusto von Dentz
						Luiz Augusto von Dentz