Skip to content

Commit feca61c

Browse files
pvNipaLocal
authored andcommitted
Bluetooth: ISO: add socket option to report packet seqnum via CMSG
User applications need a way to track which ISO interval a given SDU belongs to, to properly detect packet loss. All controllers do not set timestamps, and it's not guaranteed user application receives all packet reports (small socket buffer, or controller doesn't send all reports like Intel AX210 is doing). Add socket option BT_PKT_SEQNUM that enables reporting of received packet ISO sequence number in BT_SCM_PKT_SEQNUM CMSG. Use BT_PKT_SEQNUM == 22 for the socket option, as 21 was used earlier for a removed experimental feature that never got into mainline. Signed-off-by: Pauli Virtanen <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent ec027f7 commit feca61c

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ struct bt_codecs {
244244

245245
#define BT_ISO_BASE 20
246246

247+
/* Socket option value 21 reserved */
248+
249+
#define BT_PKT_SEQNUM 22
250+
251+
#define BT_SCM_PKT_SEQNUM 0x05
252+
247253
__printf(1, 2)
248254
void bt_info(const char *fmt, ...);
249255
__printf(1, 2)
@@ -391,7 +397,8 @@ struct bt_sock {
391397
enum {
392398
BT_SK_DEFER_SETUP,
393399
BT_SK_SUSPEND,
394-
BT_SK_PKT_STATUS
400+
BT_SK_PKT_STATUS,
401+
BT_SK_PKT_SEQNUM,
395402
};
396403

397404
struct bt_sock_list {
@@ -475,6 +482,7 @@ struct bt_skb_cb {
475482
u8 pkt_type;
476483
u8 force_active;
477484
u16 expect;
485+
u16 pkt_seqnum;
478486
u8 incoming:1;
479487
u8 pkt_status:2;
480488
union {
@@ -488,6 +496,7 @@ struct bt_skb_cb {
488496

489497
#define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type
490498
#define hci_skb_pkt_status(skb) bt_cb((skb))->pkt_status
499+
#define hci_skb_pkt_seqnum(skb) bt_cb((skb))->pkt_seqnum
491500
#define hci_skb_expect(skb) bt_cb((skb))->expect
492501
#define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode
493502
#define hci_skb_event(skb) bt_cb((skb))->hci.req_event

net/bluetooth/af_bluetooth.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,13 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
364364
put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
365365
sizeof(pkt_status), &pkt_status);
366366
}
367+
368+
if (test_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags)) {
369+
u16 pkt_seqnum = hci_skb_pkt_seqnum(skb);
370+
371+
put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_SEQNUM,
372+
sizeof(pkt_seqnum), &pkt_seqnum);
373+
}
367374
}
368375

369376
skb_free_datagram(sk, skb);

net/bluetooth/iso.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,17 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
16871687
clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
16881688
break;
16891689

1690+
case BT_PKT_SEQNUM:
1691+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
1692+
if (err)
1693+
break;
1694+
1695+
if (opt)
1696+
set_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
1697+
else
1698+
clear_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
1699+
break;
1700+
16901701
case BT_ISO_QOS:
16911702
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
16921703
sk->sk_state != BT_CONNECT2 &&
@@ -2278,7 +2289,7 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
22782289
void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
22792290
{
22802291
struct iso_conn *conn = hcon->iso_data;
2281-
__u16 pb, ts, len;
2292+
__u16 pb, ts, len, sn;
22822293

22832294
if (!conn)
22842295
goto drop;
@@ -2308,6 +2319,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
23082319
goto drop;
23092320
}
23102321

2322+
sn = __le16_to_cpu(hdr->sn);
23112323
len = __le16_to_cpu(hdr->slen);
23122324
} else {
23132325
struct hci_iso_data_hdr *hdr;
@@ -2318,18 +2330,20 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
23182330
goto drop;
23192331
}
23202332

2333+
sn = __le16_to_cpu(hdr->sn);
23212334
len = __le16_to_cpu(hdr->slen);
23222335
}
23232336

23242337
flags = hci_iso_data_flags(len);
23252338
len = hci_iso_data_len(len);
23262339

2327-
BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len,
2328-
skb->len, flags);
2340+
BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x sn %d",
2341+
len, skb->len, flags, sn);
23292342

23302343
if (len == skb->len) {
23312344
/* Complete frame received */
23322345
hci_skb_pkt_status(skb) = flags & 0x03;
2346+
hci_skb_pkt_seqnum(skb) = sn;
23332347
iso_recv_frame(conn, skb);
23342348
return;
23352349
}
@@ -2352,6 +2366,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
23522366
goto drop;
23532367

23542368
hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
2369+
hci_skb_pkt_seqnum(conn->rx_skb) = sn;
23552370
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
23562371
skb->len);
23572372
conn->rx_len = len - skb->len;

0 commit comments

Comments
 (0)