summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-02-04 22:04:38 +0100
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-07-22 22:20:52 +0200
commitdfe6d5c3ec23c5b999261d989059aa35403d791d (patch)
treeecfb0dc1c15880dd2590c9ae3ccf79672ce14cac /net/bluetooth
parentBluetooth: Convert delayed discov_off to hci_sync (diff)
downloadlinux-dfe6d5c3ec23c5b999261d989059aa35403d791d.tar.xz
linux-dfe6d5c3ec23c5b999261d989059aa35403d791d.zip
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: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c32
-rw-r--r--net/bluetooth/hci_event.c3
2 files changed, 35 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e42824e82758..924c29517918 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -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)
{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b32ca92fc692..bab52ee99b11 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -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",