Commit dfe6d5c3 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ struct hci_dev {
	struct sk_buff_head	cmd_q;

	struct sk_buff		*sent_cmd;
	struct sk_buff		*recv_event;

	struct mutex		req_lock;
	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);
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_recv_event_data(struct hci_dev *hdev, __u8 event);

u32 hci_conn_get_phy(struct hci_conn *conn);

+32 −0
Original line number Diff line number Diff line
@@ -2712,6 +2712,7 @@ void hci_release_dev(struct hci_dev *hdev)

	ida_simple_remove(&hci_index_ida, hdev->id);
	kfree_skb(hdev->sent_cmd);
	kfree_skb(hdev->recv_event);
	kfree(hdev);
}
EXPORT_SYMBOL(hci_release_dev);
@@ -3018,6 +3019,37 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
	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 */
static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
{
+3 −0
Original line number Diff line number Diff line
@@ -6936,6 +6936,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
		goto done;
	}

	kfree_skb(hdev->recv_event);
	hdev->recv_event = skb_clone(skb, GFP_KERNEL);

	event = hdr->evt;
	if (!event) {
		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",