From 7f8fa70b8c7589f85f5a59c69c07efa46a843e44 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 14 Jun 2024 12:08:55 +0200 Subject: [PATCH] [nrf noup] bluetooth: conn: Allow for an extra ref in bt_l2cap_send_pdu Allow for an additional buffer reference if callback is provided. This can be used to extend lifetime of the net buffer until the data transmission is confirmed by ACK of the remote. Signed-off-by: Marek Pieta --- subsys/bluetooth/host/conn.c | 8 +++++++- subsys/bluetooth/host/l2cap.c | 8 ++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index bc3e43b73c2..bd3933d5b56 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -695,7 +695,13 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, uint16_t frag_len = MIN(conn_mtu(conn), len); - __ASSERT_NO_MSG(buf->ref == 1); + if (buf->ref > 1 + (cb ? 1 : 0)) { + /* Allow for an additional buffer reference if callback is provided. + * This can be used to extend lifetime of the net buffer until the + * data transmission is confirmed by ACK of the remote. + */ + __ASSERT_NO_MSG(false); + } if (buf->len > frag_len) { LOG_DBG("keep %p around", buf); diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 3b5cfe82864..1e3850fd591 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -721,13 +721,17 @@ int bt_l2cap_send_pdu(struct bt_l2cap_le_chan *le_chan, struct net_buf *pdu, return -ENOTCONN; } - if (pdu->ref != 1) { + /* Allow for an additional buffer reference if callback is provided. This can be used to + * extend lifetime of the net buffer until the data transmission is confirmed by ACK of the + * remote. + */ + if (pdu->ref > 1 + (cb ? 1 : 0)) { /* The host may alter the buf contents when fragmenting. Higher * layers cannot expect the buf contents to stay intact. Extra * refs suggests a silent data corruption would occur if not for * this error. */ - LOG_ERR("Expecting 1 ref, got %d", pdu->ref); + LOG_ERR("Expecting up to %d refs, got %d", cb ? 2 : 1, pdu->ref); return -EINVAL; }