Bluetooth: ISO: Add support for BT_PKT_STATUS
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 13 Jul 2023 21:02:37 +0000 (14:02 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 11 Aug 2023 18:49:45 +0000 (11:49 -0700)
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>
net/bluetooth/iso.c

index efac284..cbe3299 100644 (file)
@@ -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;