Bluetooth: Reading remote device lmp_version from controller.
On ACL connection complete with a remote device, the remote device lmp version should be available with Controller. The current change is to read this information from controller to host and update to bluez userspace through management APIs. Change-Id: Ie152ed98fa0a6cf9ab170a6bb8c6a05b5b9dfcb0 Signed-off-by: Srinivas Krovvidi <skrovvid@codeaurora.org>
This commit is contained in:
@@ -1047,6 +1047,8 @@ int mgmt_encrypt_change(u16 index, bdaddr_t *bdaddr, u8 status);
|
|||||||
/* LE SMP Management interface */
|
/* LE SMP Management interface */
|
||||||
int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
|
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_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 */
|
/* HCI info for socket */
|
||||||
#define hci_pi(sk) ((struct hci_pinfo *) sk)
|
#define hci_pi(sk) ((struct hci_pinfo *) sk)
|
||||||
|
|||||||
@@ -347,3 +347,11 @@ struct mgmt_ev_remote_class {
|
|||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
__u8 dev_class[3];
|
__u8 dev_class[3];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
#define MGMT_EV_REMOTE_VERSION 0x0018
|
||||||
|
struct mgmt_ev_remote_version {
|
||||||
|
bdaddr_t bdaddr;
|
||||||
|
__u8 lmp_ver;
|
||||||
|
__u16 manufacturer;
|
||||||
|
__u16 lmp_subver;
|
||||||
|
} __packed;
|
||||||
|
|||||||
@@ -1606,11 +1606,11 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
|
|||||||
if (test_bit(HCI_ENCRYPT, &hdev->flags))
|
if (test_bit(HCI_ENCRYPT, &hdev->flags))
|
||||||
conn->link_mode |= HCI_LM_ENCRYPT;
|
conn->link_mode |= HCI_LM_ENCRYPT;
|
||||||
|
|
||||||
/* Get remote features */
|
/* Get remote version */
|
||||||
if (conn->type == ACL_LINK) {
|
if (conn->type == ACL_LINK) {
|
||||||
struct hci_cp_read_remote_features cp;
|
struct hci_cp_read_remote_version cp;
|
||||||
cp.handle = ev->handle;
|
cp.handle = ev->handle;
|
||||||
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
|
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_VERSION,
|
||||||
sizeof(cp), &cp);
|
sizeof(cp), &cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1959,7 +1959,24 @@ unlock:
|
|||||||
|
|
||||||
static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
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)
|
static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||||
|
|||||||
@@ -2893,3 +2893,18 @@ int mgmt_remote_class(u16 index, bdaddr_t *bdaddr, u8 dev_class[3])
|
|||||||
|
|
||||||
return mgmt_event(MGMT_EV_REMOTE_CLASS, index, &ev, sizeof(ev), NULL);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user