Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Pauli Virtanen and committed by
Luiz Augusto von Dentz
7565bc56 15843c7f

+35 -4
+10 -1
include/net/bluetooth/bluetooth.h
··· 244 244 245 245 #define BT_ISO_BASE 20 246 246 247 + /* Socket option value 21 reserved */ 248 + 249 + #define BT_PKT_SEQNUM 22 250 + 251 + #define BT_SCM_PKT_SEQNUM 0x05 252 + 247 253 __printf(1, 2) 248 254 void bt_info(const char *fmt, ...); 249 255 __printf(1, 2) ··· 397 391 enum { 398 392 BT_SK_DEFER_SETUP, 399 393 BT_SK_SUSPEND, 400 - BT_SK_PKT_STATUS 394 + BT_SK_PKT_STATUS, 395 + BT_SK_PKT_SEQNUM, 401 396 }; 402 397 403 398 struct bt_sock_list { ··· 482 475 u8 pkt_type; 483 476 u8 force_active; 484 477 u16 expect; 478 + u16 pkt_seqnum; 485 479 u8 incoming:1; 486 480 u8 pkt_status:2; 487 481 union { ··· 496 488 497 489 #define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type 498 490 #define hci_skb_pkt_status(skb) bt_cb((skb))->pkt_status 491 + #define hci_skb_pkt_seqnum(skb) bt_cb((skb))->pkt_seqnum 499 492 #define hci_skb_expect(skb) bt_cb((skb))->expect 500 493 #define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode 501 494 #define hci_skb_event(skb) bt_cb((skb))->hci.req_event
+7
net/bluetooth/af_bluetooth.c
··· 364 364 put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS, 365 365 sizeof(pkt_status), &pkt_status); 366 366 } 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 + } 367 374 } 368 375 369 376 skb_free_datagram(sk, skb);
+18 -3
net/bluetooth/iso.c
··· 1687 1687 clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags); 1688 1688 break; 1689 1689 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 + 1690 1701 case BT_ISO_QOS: 1691 1702 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND && 1692 1703 sk->sk_state != BT_CONNECT2 && ··· 2289 2278 void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) 2290 2279 { 2291 2280 struct iso_conn *conn = hcon->iso_data; 2292 - __u16 pb, ts, len; 2281 + __u16 pb, ts, len, sn; 2293 2282 2294 2283 if (!conn) 2295 2284 goto drop; ··· 2319 2308 goto drop; 2320 2309 } 2321 2310 2311 + sn = __le16_to_cpu(hdr->sn); 2322 2312 len = __le16_to_cpu(hdr->slen); 2323 2313 } else { 2324 2314 struct hci_iso_data_hdr *hdr; ··· 2330 2318 goto drop; 2331 2319 } 2332 2320 2321 + sn = __le16_to_cpu(hdr->sn); 2333 2322 len = __le16_to_cpu(hdr->slen); 2334 2323 } 2335 2324 2336 2325 flags = hci_iso_data_flags(len); 2337 2326 len = hci_iso_data_len(len); 2338 2327 2339 - BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len, 2340 - skb->len, flags); 2328 + BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x sn %d", 2329 + len, skb->len, flags, sn); 2341 2330 2342 2331 if (len == skb->len) { 2343 2332 /* Complete frame received */ 2344 2333 hci_skb_pkt_status(skb) = flags & 0x03; 2334 + hci_skb_pkt_seqnum(skb) = sn; 2345 2335 iso_recv_frame(conn, skb); 2346 2336 return; 2347 2337 } ··· 2366 2352 goto drop; 2367 2353 2368 2354 hci_skb_pkt_status(conn->rx_skb) = flags & 0x03; 2355 + hci_skb_pkt_seqnum(conn->rx_skb) = sn; 2369 2356 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), 2370 2357 skb->len); 2371 2358 conn->rx_len = len - skb->len;