|
@@ -721,6 +721,41 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
|
|
hdev->block_cnt, hdev->block_len);
|
|
hdev->block_cnt, hdev->block_len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
|
|
|
|
+{
|
|
|
|
+ struct hci_rp_read_clock *rp = (void *) skb->data;
|
|
|
|
+ struct hci_cp_read_clock *cp;
|
|
|
|
+ struct hci_conn *conn;
|
|
|
|
+
|
|
|
|
+ BT_DBG("%s", hdev->name);
|
|
|
|
+
|
|
|
|
+ if (skb->len < sizeof(*rp))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (rp->status)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ hci_dev_lock(hdev);
|
|
|
|
+
|
|
|
|
+ cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
|
|
|
|
+ if (!cp)
|
|
|
|
+ goto unlock;
|
|
|
|
+
|
|
|
|
+ if (cp->which == 0x00) {
|
|
|
|
+ hdev->clock = le32_to_cpu(rp->clock);
|
|
|
|
+ goto unlock;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
|
|
|
|
+ if (conn) {
|
|
|
|
+ conn->clock = le32_to_cpu(rp->clock);
|
|
|
|
+ conn->clock_accuracy = le16_to_cpu(rp->accuracy);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+unlock:
|
|
|
|
+ hci_dev_unlock(hdev);
|
|
|
|
+}
|
|
|
|
+
|
|
static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
|
|
static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
{
|
|
{
|
|
@@ -2597,6 +2632,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|
hci_cc_read_local_amp_info(hdev, skb);
|
|
hci_cc_read_local_amp_info(hdev, skb);
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ case HCI_OP_READ_CLOCK:
|
|
|
|
+ hci_cc_read_clock(hdev, skb);
|
|
|
|
+ break;
|
|
|
|
+
|
|
case HCI_OP_READ_LOCAL_AMP_ASSOC:
|
|
case HCI_OP_READ_LOCAL_AMP_ASSOC:
|
|
hci_cc_read_local_amp_assoc(hdev, skb);
|
|
hci_cc_read_local_amp_assoc(hdev, skb);
|
|
break;
|
|
break;
|