Bluetooth: af_bluetooth: Make BT_PKT_STATUS generic

This makes the handling of BT_PKT_STATUS more generic so it can be
reused by sockets other than SCO like BT_DEFER_SETUP, etc.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2023-07-13 13:41:31 -07:00
parent 0e72e3b12c
commit 3f19ffb2f9
5 changed files with 14 additions and 28 deletions

View File

@ -386,6 +386,7 @@ struct bt_sock {
enum {
BT_SK_DEFER_SETUP,
BT_SK_SUSPEND,
BT_SK_PKT_STATUS
};
struct bt_sock_list {
@ -432,10 +433,6 @@ struct l2cap_ctrl {
struct l2cap_chan *chan;
};
struct sco_ctrl {
u8 pkt_status;
};
struct hci_dev;
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
@ -466,9 +463,9 @@ struct bt_skb_cb {
u8 force_active;
u16 expect;
u8 incoming:1;
u8 pkt_status:2;
union {
struct l2cap_ctrl l2cap;
struct sco_ctrl sco;
struct hci_ctrl hci;
struct mgmt_ctrl mgmt;
struct scm_creds creds;
@ -477,6 +474,7 @@ struct bt_skb_cb {
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
#define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type
#define hci_skb_pkt_status(skb) bt_cb((skb))->pkt_status
#define hci_skb_expect(skb) bt_cb((skb))->expect
#define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode
#define hci_skb_event(skb) bt_cb((skb))->hci.req_event

View File

@ -46,6 +46,4 @@ struct sco_conninfo {
__u8 dev_class[3];
};
#define SCO_CMSG_PKT_STATUS 0x01
#endif /* __SCO_H */

View File

@ -333,8 +333,12 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
&msg->msg_namelen);
if (bt_sk(sk)->skb_put_cmsg)
bt_sk(sk)->skb_put_cmsg(skb, msg, sk);
if (test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags)) {
u8 pkt_status = hci_skb_pkt_status(skb);
put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
sizeof(pkt_status), &pkt_status);
}
}
skb_free_datagram(sk, skb);

View File

@ -3895,7 +3895,7 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
if (conn) {
/* Send to upper protocol */
bt_cb(skb)->sco.pkt_status = flags & 0x03;
hci_skb_pkt_status(skb) = flags & 0x03;
sco_recv_scodata(conn, skb);
return;
} else {

View File

@ -68,7 +68,6 @@ struct sco_pinfo {
bdaddr_t dst;
__u32 flags;
__u16 setting;
__u8 cmsg_mask;
struct bt_codec codec;
struct sco_conn *conn;
};
@ -471,15 +470,6 @@ static void sco_sock_close(struct sock *sk)
release_sock(sk);
}
static void sco_skb_put_cmsg(struct sk_buff *skb, struct msghdr *msg,
struct sock *sk)
{
if (sco_pi(sk)->cmsg_mask & SCO_CMSG_PKT_STATUS)
put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
sizeof(bt_cb(skb)->sco.pkt_status),
&bt_cb(skb)->sco.pkt_status);
}
static void sco_sock_init(struct sock *sk, struct sock *parent)
{
BT_DBG("sk %p", sk);
@ -488,8 +478,6 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
sk->sk_type = parent->sk_type;
bt_sk(sk)->flags = bt_sk(parent)->flags;
security_sk_clone(parent, sk);
} else {
bt_sk(sk)->skb_put_cmsg = sco_skb_put_cmsg;
}
}
@ -907,9 +895,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
}
if (opt)
sco_pi(sk)->cmsg_mask |= SCO_CMSG_PKT_STATUS;
set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
else
sco_pi(sk)->cmsg_mask &= SCO_CMSG_PKT_STATUS;
clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
break;
case BT_CODEC:
@ -1040,7 +1028,6 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
int len, err = 0;
struct bt_voice voice;
u32 phys;
int pkt_status;
int buf_len;
struct codec_list *c;
u8 num_codecs, i, __user *ptr;
@ -1094,9 +1081,8 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname,
break;
case BT_PKT_STATUS:
pkt_status = (sco_pi(sk)->cmsg_mask & SCO_CMSG_PKT_STATUS);
if (put_user(pkt_status, (int __user *)optval))
if (put_user(test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags),
(int __user *)optval))
err = -EFAULT;
break;