aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2015-02-02 02:07:55 -0500
committerMarcel Holtmann <marcel@holtmann.org>2015-02-02 02:52:34 -0500
commit4b0e0ceddf085a89173805cace44cd3c4c9d9d77 (patch)
tree3a21e7bfb48f6b548337ad9a1758783d6c5dbd21
parent2d28cfe7aada495f87bb439151e9bcc86998fb6d (diff)
Bluetooth: Add restarting to service discovery
When using LE_SCAN_FILTER_DUP_ENABLE, some controllers would send advertising report from each LE device only once. That means that we don't get any updates on RSSI value, and makes Service Discovery very slow. This patch adds restarting scan when in Service Discovery, and device with filtered uuid is found, but it's not in RSSI range to send event yet. This way if device moves into range, we will quickly get RSSI update. Signed-off-by: Jakub Pawlowski <jpawlowski@google.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/mgmt.c53
2 files changed, 49 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d3a232be9d9b..52863c3e0b13 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1334,6 +1334,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
1334#define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ 1334#define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */
1335#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 1335#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
1336#define DISCOV_BREDR_INQUIRY_LEN 0x08 1336#define DISCOV_BREDR_INQUIRY_LEN 0x08
1337#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */
1337 1338
1338int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); 1339int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
1339int mgmt_new_settings(struct hci_dev *hdev); 1340int mgmt_new_settings(struct hci_dev *hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8c2520a7f386..9e50b5c09b02 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -7262,6 +7262,21 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
7262 return false; 7262 return false;
7263} 7263}
7264 7264
7265static void restart_le_scan(struct hci_dev *hdev)
7266{
7267 /* If controller is not scanning we are done. */
7268 if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
7269 return;
7270
7271 if (time_after(jiffies + DISCOV_LE_RESTART_DELAY,
7272 hdev->discovery.scan_start +
7273 hdev->discovery.scan_duration))
7274 return;
7275
7276 queue_delayed_work(hdev->workqueue, &hdev->le_scan_restart,
7277 DISCOV_LE_RESTART_DELAY);
7278}
7279
7265void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 7280void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7266 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 7281 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
7267 u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) 7282 u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
@@ -7284,14 +7299,18 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7284 7299
7285 /* When using service discovery with a RSSI threshold, then check 7300 /* When using service discovery with a RSSI threshold, then check
7286 * if such a RSSI threshold is specified. If a RSSI threshold has 7301 * if such a RSSI threshold is specified. If a RSSI threshold has
7287 * been specified, then all results with a RSSI smaller than the 7302 * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set,
7288 * RSSI threshold will be dropped. 7303 * then all results with a RSSI smaller than the RSSI threshold will be
7304 * dropped. If the quirk is set, let it through for further processing,
7305 * as we might need to restart the scan.
7289 * 7306 *
7290 * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry, 7307 * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry,
7291 * the results are also dropped. 7308 * the results are also dropped.
7292 */ 7309 */
7293 if (hdev->discovery.rssi != HCI_RSSI_INVALID && 7310 if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
7294 (rssi < hdev->discovery.rssi || rssi == HCI_RSSI_INVALID)) 7311 (rssi == HCI_RSSI_INVALID ||
7312 (rssi < hdev->discovery.rssi &&
7313 !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
7295 return; 7314 return;
7296 7315
7297 /* Make sure that the buffer is big enough. The 5 extra bytes 7316 /* Make sure that the buffer is big enough. The 5 extra bytes
@@ -7326,12 +7345,20 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7326 * kept and checking possible scan response data 7345 * kept and checking possible scan response data
7327 * will be skipped. 7346 * will be skipped.
7328 */ 7347 */
7329 if (hdev->discovery.uuid_count > 0) 7348 if (hdev->discovery.uuid_count > 0) {
7330 match = eir_has_uuids(eir, eir_len, 7349 match = eir_has_uuids(eir, eir_len,
7331 hdev->discovery.uuid_count, 7350 hdev->discovery.uuid_count,
7332 hdev->discovery.uuids); 7351 hdev->discovery.uuids);
7333 else 7352 /* If duplicate filtering does not report RSSI changes,
7353 * then restart scanning to ensure updated result with
7354 * updated RSSI values.
7355 */
7356 if (match && test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
7357 &hdev->quirks))
7358 restart_le_scan(hdev);
7359 } else {
7334 match = true; 7360 match = true;
7361 }
7335 7362
7336 if (!match && !scan_rsp_len) 7363 if (!match && !scan_rsp_len)
7337 return; 7364 return;
@@ -7364,6 +7391,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7364 hdev->discovery.uuid_count, 7391 hdev->discovery.uuid_count,
7365 hdev->discovery.uuids)) 7392 hdev->discovery.uuids))
7366 return; 7393 return;
7394
7395 /* If duplicate filtering does not report RSSI changes,
7396 * then restart scanning to ensure updated result with
7397 * updated RSSI values.
7398 */
7399 if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
7400 &hdev->quirks))
7401 restart_le_scan(hdev);
7367 } 7402 }
7368 7403
7369 /* Append scan response data to event */ 7404 /* Append scan response data to event */
@@ -7377,6 +7412,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
7377 return; 7412 return;
7378 } 7413 }
7379 7414
7415 /* Validate the reported RSSI value against the RSSI threshold once more
7416 * incase HCI_QUIRK_STRICT_DUPLICATE_FILTER forced a restart of LE
7417 * scanning.
7418 */
7419 if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
7420 rssi < hdev->discovery.rssi)
7421 return;
7422
7380 ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); 7423 ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
7381 ev_size = sizeof(*ev) + eir_len + scan_rsp_len; 7424 ev_size = sizeof(*ev) + eir_len + scan_rsp_len;
7382 7425