Skip to content

Commit 321533c

Browse files
committed
transport/common/hci_h4: propagate OOM instead of asserting
When hci_h4_sm_w4_header() or hci_h4_sm_w4_payload() returns -1 because the underlying allocator returned NULL (transport ACL pool exhausted), hci_h4_sm_rx() currently asserts via two `assert(rc >= 0)` checks. This turns a recoverable pool-pressure event into a fatal crash. The condition is reachable in practice on host-side transports such as SiFli SF32LB52: the H4 RX task allocates ACL mbufs from mpool_acl and queues them on ble_hs_rx_q for the host event loop to drain. If the host is parked (e.g. blocked while serving GATT notifications into a downstream buffer that drains slowly) the queue grows until the pool is empty; the next allocation returns NULL and the assert fires. Remove both `assert(rc >= 0)` so -1 propagates through hci_h4_sm_rx() to the transport. Callers can then back off (e.g. block until a buffer is returned to the pool via the put callback) and retry with the same input. The existing `assert(rc < 0)` at the bottom of hci_h4_sm_rx() still enforces the legitimate "consumed nothing => rc indicates error" invariant. Note that when the input source is destructive, callers must retry with the same buffer rather than drop bytes on -1, otherwise the H4 framing desyncs. The state machine already preserves partial state across calls so retry is safe. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
1 parent d58cdfd commit 321533c

1 file changed

Lines changed: 3 additions & 2 deletions

File tree

  • nimble/transport/common/hci_h4/src

nimble/transport/common/hci_h4/src/hci_h4.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,16 @@ hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len)
289289
/* no break */
290290
case HCI_H4_SM_W4_HEADER:
291291
rc = hci_h4_sm_w4_header(h4sm, &ib);
292-
assert(rc >= 0);
293292
if (rc) {
293+
/* rc == 1: need more data; rc < 0: alloc failed, propagate
294+
* to caller so it can back off and retry instead of crashing.
295+
*/
294296
break;
295297
}
296298
h4sm->state = HCI_H4_SM_W4_PAYLOAD;
297299
/* no break */
298300
case HCI_H4_SM_W4_PAYLOAD:
299301
rc = hci_h4_sm_w4_payload(h4sm, &ib);
300-
assert(rc >= 0);
301302
if (rc) {
302303
break;
303304
}

0 commit comments

Comments
 (0)