summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-01-29 05:22:56 +0100
committerMarcel Holtmann <marcel@holtmann.org>2005-01-29 05:22:56 +0100
commit8e4a73f4b7f2b88fdba2f034c5f441fbc3c8e759 (patch)
treee765b7ff8ad88c5dfad7bd8fb523ce69331fc6c7
parent7af32eeba53677bf2c0ce6245252a0a17992b95f (diff)
[Bluetooth] Update inquiry cache from clock offset event
The HCI clock offset event contains the actual clock offset for the connection. 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>
-rw-r--r--include/net/bluetooth/hci.h7
-rw-r--r--net/bluetooth/hci_event.c28
2 files changed, 35 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 6a2fde5bf873..902ba988f187 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -576,6 +576,13 @@ struct hci_ev_rmt_version {
__u16 lmp_subver;
} __attribute__ ((packed));
+#define HCI_EV_CLOCK_OFFSET 0x01C
+struct hci_ev_clock_offset {
+ __u8 status;
+ __u16 handle;
+ __u16 clock_offset;
+} __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 e88d18da3b4f..47a1e90add30 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -818,6 +818,30 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
{
}
+/* Clock Offset */
+static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
+ struct hci_conn *conn = NULL;
+ __u16 handle = __le16_to_cpu(ev->handle);
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (conn && !ev->status) {
+ struct inquiry_entry *ie;
+
+ if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
+ ie->data.clock_offset = ev->clock_offset;
+ 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;
@@ -886,6 +910,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_link_key_notify_evt(hdev, skb);
break;
+ case HCI_EV_CLOCK_OFFSET:
+ hci_clock_offset_evt(hdev, skb);
+ break;
+
case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs));