summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg2014-03-25 13:40:52 +0100
committerMarcel Holtmann2014-03-26 17:31:40 +0100
commitff5cd29f5cb8de0f0bc9016874ddde467d4b0c85 (patch)
tree0ee4de289e83c9296948c5c0d320793b2d5a38e9
parentBluetooth: Don't send device found events for duplicate reports (diff)
downloadkernel-qcow2-linux-ff5cd29f5cb8de0f0bc9016874ddde467d4b0c85.tar.gz
kernel-qcow2-linux-ff5cd29f5cb8de0f0bc9016874ddde467d4b0c85.tar.xz
kernel-qcow2-linux-ff5cd29f5cb8de0f0bc9016874ddde467d4b0c85.zip
Bluetooth: Store also RSSI for pending advertising reports
Especially in crowded environments it can become frequent that we have to send out whatever pending event there is stored. Since user space has its own filtering of small RSSI changes sending a 0 value will essentially force user space to wake up the higher layers (e.g. over D-Bus) even though the RSSI didn't actually change more than the threshold value. This patch adds storing also of the RSSI for pending advertising reports so that we report an as accurate RSSI as possible when we have to send out the stored information to user space. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_event.c12
2 files changed, 8 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0ba7617ceb27..c2a419c2c5c7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -70,6 +70,7 @@ struct discovery_state {
__u32 timestamp;
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
+ s8 last_adv_rssi;
u8 last_adv_data[HCI_MAX_AD_LENGTH];
u8 last_adv_data_len;
};
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 1b2221d62007..2ecb34f2e2ad 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1049,12 +1049,13 @@ static void clear_pending_adv_report(struct hci_dev *hdev)
}
static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
- u8 bdaddr_type, u8 *data, u8 len)
+ u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
{
struct discovery_state *d = &hdev->discovery;
bacpy(&d->last_adv_addr, bdaddr);
d->last_adv_addr_type = bdaddr_type;
+ d->last_adv_rssi = rssi;
memcpy(d->last_adv_data, data, len);
d->last_adv_data_len = len;
}
@@ -4040,7 +4041,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
- data, len);
+ rssi, data, len);
return;
}
@@ -4061,8 +4062,9 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
/* Send out whatever is in the cache, but skip duplicates */
if (!match)
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
- d->last_adv_addr_type, NULL, 0,
- 0, 1, d->last_adv_data,
+ d->last_adv_addr_type, NULL,
+ d->last_adv_rssi, 0, 1,
+ d->last_adv_data,
d->last_adv_data_len, NULL, 0);
/* If the new report will trigger a SCAN_REQ store it for
@@ -4070,7 +4072,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
- data, len);
+ rssi, data, len);
return;
}