summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-07-13 14:02:37 -0700
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 11:49:45 -0700
commit0731c5ab4d510501a6a2da491ac68aea858bf834 (patch)
tree3f80cf017c0a66a18618d1a20e67d768fe5b8283 /net/bluetooth
parent3f19ffb2f924db5b0925c77818d18ac1f6f08a44 (diff)
downloadlinux-0731c5ab4d510501a6a2da491ac68aea858bf834.tar.gz
linux-0731c5ab4d510501a6a2da491ac68aea858bf834.tar.bz2
linux-0731c5ab4d510501a6a2da491ac68aea858bf834.zip
Bluetooth: ISO: Add support for BT_PKT_STATUS
This adds support for BT_PKT_STATUS socketopt by setting BT_SK_PKT_STATUS. Then upon receiving an ISO packet the code would attempt to store the Packet_Status_Flag to hci_skb_pkt_status which is then forward to userspace in the form of BT_SCM_PKT_STATUS whenever BT_PKT_STATUS has been enabled/set. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/iso.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index efac284badbc..cbe3299b4a41 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -1288,6 +1288,18 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
break;
+ case BT_PKT_STATUS:
+ if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
+ err = -EFAULT;
+ break;
+ }
+
+ if (opt)
+ set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
+ else
+ clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
+ break;
+
case BT_ISO_QOS:
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
sk->sk_state != BT_CONNECT2) {
@@ -1373,6 +1385,12 @@ static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
break;
+ case BT_PKT_STATUS:
+ if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
+ (int __user *)optval))
+ err = -EFAULT;
+ break;
+
case BT_ISO_QOS:
qos = iso_sock_get_qos(sk);
@@ -1767,6 +1785,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
if (len == skb->len) {
/* Complete frame received */
+ hci_skb_pkt_status(skb) = flags & 0x03;
iso_recv_frame(conn, skb);
return;
}
@@ -1788,6 +1807,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
if (!conn->rx_skb)
goto drop;
+ hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
skb->len);
conn->rx_len = len - skb->len;