From 0072ec318a379a929830d7326615c3e6e5a4c2b3 Mon Sep 17 00:00:00 2001 From: Anne Jan Brouwer Date: Wed, 29 Jul 2026 03:26:36 +0200 Subject: [PATCH] ble_hci: use the LE packet boundary flag for outgoing ACL data hci_send_acl_pkt() marked the first fragment of every outgoing L2CAP PDU as ACL_DATA_PB_FIRST_FLUSH. That is the BR/EDR value, "first automatically flushable". On an LE-U link the first fragment is non-automatically-flushable, ACL_DATA_PB_FIRST_NON_FLUSH. Nordic's SoftDevice Controller accepts a packet marked that way, returning success, and then never transmits it. Measured on an nRF52840: no Number Of Completed Packets event ever arrived for any packet, and the peer eventually gave up and disconnected with reason 0x13, remote user terminated, rather than a supervision timeout. A client hung indefinitely discovering services. With the LE value the same connection completes discovery and stays up. --- devices/ble_hci/common-hal/_bleio/hci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devices/ble_hci/common-hal/_bleio/hci.c b/devices/ble_hci/common-hal/_bleio/hci.c index 126f05fbae2..063b69534c7 100644 --- a/devices/ble_hci/common-hal/_bleio/hci.c +++ b/devices/ble_hci/common-hal/_bleio/hci.c @@ -489,7 +489,9 @@ hci_result_t hci_send_acl_pkt(uint16_t handle, uint8_t cid, uint16_t data_len, u acl_data_t *acl_data = (acl_data_t *)acl_pkt->data; acl_pkt->pkt_type = H4_ACL; acl_pkt->handle = handle; - acl_pkt->pb = ACL_DATA_PB_FIRST_FLUSH; + // On an LE link the first fragment of an L2CAP PDU is + // non-automatically-flushable. ACL_DATA_PB_FIRST_FLUSH is the BR/EDR value. + acl_pkt->pb = ACL_DATA_PB_FIRST_NON_FLUSH; acl_pkt->bc = 0; acl_pkt->data_len = (uint16_t)(sizeof(acl_data_t) + data_len); acl_data->acl_data_len = data_len;