Bluetooth: hci_core: Introduce hci_recv_event_data

This introduces hci_recv_event_data to make it simpler to access the
contents of last received event rather than having to pass its contents
to the likes of *_ind/*_cfm callbacks.
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 0ef08313
...@@ -525,6 +525,7 @@ struct hci_dev { ...@@ -525,6 +525,7 @@ struct hci_dev {
struct sk_buff_head cmd_q; struct sk_buff_head cmd_q;
struct sk_buff *sent_cmd; struct sk_buff *sent_cmd;
struct sk_buff *recv_event;
struct mutex req_lock; struct mutex req_lock;
wait_queue_head_t req_wait_q; wait_queue_head_t req_wait_q;
...@@ -1747,6 +1748,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); ...@@ -1747,6 +1748,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
void *hci_recv_event_data(struct hci_dev *hdev, __u8 event);
u32 hci_conn_get_phy(struct hci_conn *conn); u32 hci_conn_get_phy(struct hci_conn *conn);
......
...@@ -2712,6 +2712,7 @@ void hci_release_dev(struct hci_dev *hdev) ...@@ -2712,6 +2712,7 @@ void hci_release_dev(struct hci_dev *hdev)
ida_simple_remove(&hci_index_ida, hdev->id); ida_simple_remove(&hci_index_ida, hdev->id);
kfree_skb(hdev->sent_cmd); kfree_skb(hdev->sent_cmd);
kfree_skb(hdev->recv_event);
kfree(hdev); kfree(hdev);
} }
EXPORT_SYMBOL(hci_release_dev); EXPORT_SYMBOL(hci_release_dev);
...@@ -3018,6 +3019,37 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) ...@@ -3018,6 +3019,37 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
} }
/* Get data from last received event */
void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
{
struct hci_event_hdr *hdr;
int offset;
if (!hdev->recv_event)
return NULL;
hdr = (void *)hdev->recv_event->data;
offset = sizeof(*hdr);
if (hdr->evt != event) {
/* In case of LE metaevent check the subevent match */
if (hdr->evt == HCI_EV_LE_META) {
struct hci_ev_le_meta *ev;
ev = (void *)hdev->recv_event->data + offset;
offset += sizeof(*ev);
if (ev->subevent == event)
goto found;
}
return NULL;
}
found:
bt_dev_dbg(hdev, "event 0x%2.2x", event);
return hdev->recv_event->data + offset;
}
/* Send ACL data */ /* Send ACL data */
static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
{ {
......
...@@ -6936,6 +6936,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -6936,6 +6936,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
goto done; goto done;
} }
kfree_skb(hdev->recv_event);
hdev->recv_event = skb_clone(skb, GFP_KERNEL);
event = hdr->evt; event = hdr->evt;
if (!event) { if (!event) {
bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x", bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment