Bluetooth: Store also RSSI for pending advertising reports
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 25 Mar 2014 12:40:52 +0000 (14:40 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 26 Mar 2014 16:31:40 +0000 (09:31 -0700)
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>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c

index 0ba7617ceb27419d8155cbd7a1a06fcfc51907b5..c2a419c2c5c7a896a2eb2e7438745810ac6c1280 100644 (file)
@@ -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;
 };
index 1b2221d620072b293bde4d1799e51fa84f197451..2ecb34f2e2adad68cf7a874cce8ce8ac6dea7bfb 100644 (file)
@@ -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;
                }