Merge "Bluetooth: Reading remote device lmp_version from controller." into msm-3.0
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 857f654..8e66a25 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1047,6 +1047,8 @@
/* LE SMP Management interface */
int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
int mgmt_remote_class(u16 index, bdaddr_t *bdaddr, u8 dev_class[3]);
+int mgmt_remote_version(u16 index, bdaddr_t *bdaddr, u8 ver, u16 mnf,
+ u16 sub_ver);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index de61c32..9e79fb3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -347,3 +347,11 @@
bdaddr_t bdaddr;
__u8 dev_class[3];
} __packed;
+
+#define MGMT_EV_REMOTE_VERSION 0x0018
+struct mgmt_ev_remote_version {
+ bdaddr_t bdaddr;
+ __u8 lmp_ver;
+ __u16 manufacturer;
+ __u16 lmp_subver;
+} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f98a90e..675b34f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1606,12 +1606,12 @@
if (test_bit(HCI_ENCRYPT, &hdev->flags))
conn->link_mode |= HCI_LM_ENCRYPT;
- /* Get remote features */
+ /* Get remote version */
if (conn->type == ACL_LINK) {
- struct hci_cp_read_remote_features cp;
+ struct hci_cp_read_remote_version cp;
cp.handle = ev->handle;
- hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
- sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_READ_REMOTE_VERSION,
+ sizeof(cp), &cp);
}
/* Set packet type for incoming connection */
@@ -1959,7 +1959,24 @@
static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- BT_DBG("%s", hdev->name);
+ struct hci_ev_remote_version *ev = (void *) skb->data;
+ struct hci_cp_read_remote_features cp;
+ struct hci_conn *conn;
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+ cp.handle = ev->handle;
+ hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
+ sizeof(cp), &cp);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+ if (!conn)
+ goto unlock;
+ if (!ev->status)
+ mgmt_remote_version(hdev->id, &conn->dst, ev->lmp_ver,
+ ev->manufacturer, ev->lmp_subver);
+unlock:
+ hci_dev_unlock(hdev);
}
static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 67a2900..74b1d2d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2893,3 +2893,18 @@
return mgmt_event(MGMT_EV_REMOTE_CLASS, index, &ev, sizeof(ev), NULL);
}
+
+int mgmt_remote_version(u16 index, bdaddr_t *bdaddr, u8 ver, u16 mnf,
+ u16 sub_ver)
+{
+ struct mgmt_ev_remote_version ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ bacpy(&ev.bdaddr, bdaddr);
+ ev.lmp_ver = ver;
+ ev.manufacturer = mnf;
+ ev.lmp_subver = sub_ver;
+
+ return mgmt_event(MGMT_EV_REMOTE_VERSION, index, &ev, sizeof(ev), NULL);
+}