summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann2005-08-10 05:28:02 +0200
committerDavid S. Miller2005-08-30 00:54:53 +0200
commit85a1e930bf628700e8e9c166b1f5c1c26d3651cc (patch)
tree3361d42b6c32145517df9ac95117221a01a8132c
parent[Bluetooth]: Workaround for inquiry results with RSSI and page scan mode (diff)
downloadkernel-qcow2-linux-85a1e930bf628700e8e9c166b1f5c1c26d3651cc.tar.gz
kernel-qcow2-linux-85a1e930bf628700e8e9c166b1f5c1c26d3651cc.tar.xz
kernel-qcow2-linux-85a1e930bf628700e8e9c166b1f5c1c26d3651cc.zip
[Bluetooth]: Track page scan repetition mode changes
The HCI page scan repetition mode change event contains the actual page scan repetition mode for the remote device. It is the same value that is received from an inquiry response and it can be used to make further reconnections faster. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/bluetooth/hci.h6
-rw-r--r--net/bluetooth/hci_event.c22
2 files changed, 28 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index cd075f197983..371e7d3f2e6f 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -593,6 +593,12 @@ struct hci_ev_clock_offset {
__u16 clock_offset;
} __attribute__ ((packed));
+#define HCI_EV_PSCAN_REP_MODE 0x20
+struct hci_ev_pscan_rep_mode {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+} __attribute__ ((packed));
+
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xFD
struct hci_ev_stack_internal {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 632f7a9c2bcb..a004284c4d98 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -894,6 +894,24 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_unlock(hdev);
}
+/* Page Scan Repetition Mode */
+static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
+ struct inquiry_entry *ie;
+
+ BT_DBG("%s", hdev->name);
+
+ hci_dev_lock(hdev);
+
+ if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
+ ie->data.pscan_rep_mode = ev->pscan_rep_mode;
+ ie->timestamp = jiffies;
+ }
+
+ hci_dev_unlock(hdev);
+}
+
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -966,6 +984,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_clock_offset_evt(hdev, skb);
break;
+ case HCI_EV_PSCAN_REP_MODE:
+ hci_pscan_rep_mode_evt(hdev, skb);
+ break;
+
case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs));