diff --git a/subsys/bluetooth/host/Kconfig.gatt b/subsys/bluetooth/host/Kconfig.gatt index 310442423b9..ac1a751fa0b 100644 --- a/subsys/bluetooth/host/Kconfig.gatt +++ b/subsys/bluetooth/host/Kconfig.gatt @@ -30,6 +30,23 @@ config BT_ATT_RETRY_ON_SEC_ERR If an ATT request fails due to insufficient security, the host will try to elevate the security level and retry the ATT request. +config BT_ATT_SENT_CB_AFTER_TX + bool "Delay ATT sent callback until data transmission is done by controller [EXPERIMENTAL]" + select EXPERIMENTAL + help + By default, the BLE stack calls sent callback for ATT data when the + data is passed to BLE controller for transmission. Enabling this + Kconfig option delays calling the sent callback until data + transmission is finished by BLE controller (the callback is called + upon receiving the Number of Completed Packets HCI Event). + + The feature is not available in Zephyr RTOS (it's specific to NCS + Zephyr fork). It is a temporary solution allowing to control flow of + GATT notifications with HID reports for HID use-case. + + Enabling this option may require increasing CONFIG_BT_CONN_TX_MAX in + configuration, because ATT would use additional TX contexts. + config BT_EATT bool "Enhanced ATT Bearers support [EXPERIMENTAL]" depends on BT_L2CAP_ECRED diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 0efeccd76da..9f54f4965e1 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -260,6 +260,13 @@ static void att_sent(void *user_data) bt_att_sent(chan); } +static void chan_sent_cb(struct bt_conn *conn, void *user_data, int err) +{ + struct net_buf *nb = user_data; + + net_buf_unref(nb); +} + /* In case of success the ownership of the buffer is transferred to the stack * which takes care of releasing it when it completes transmitting to the * controller. @@ -353,7 +360,16 @@ static int chan_send(struct bt_att_chan *chan, struct net_buf *buf) data->att_chan = chan; - err = bt_l2cap_send(chan->att->conn, BT_L2CAP_CID_ATT, buf); + if (IS_ENABLED(CONFIG_BT_ATT_SENT_CB_AFTER_TX)) { + err = bt_l2cap_send_cb(chan->att->conn, BT_L2CAP_CID_ATT, buf, chan_sent_cb, + net_buf_ref(buf)); + if (err) { + net_buf_unref(buf); + } + } else { + err = bt_l2cap_send(chan->att->conn, BT_L2CAP_CID_ATT, buf); + } + if (err) { if (err == -ENOBUFS) { LOG_ERR("Ran out of TX buffers or contexts.");