You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bluetooth: Host: Invoke tx callbacks when channel is deleted
When bt_l2cap_send_pdu() succeeds, it transfers buffer ownership to the
stack, which must eventually invoke the provided callback. This contract
is honored in all paths where transmission becomes impossible:
- Normal transmission: callback invoked with err=0 after HCI Number of
Completed Packets event (tx_notify_process)
- Send errors (after tx allocated): callback invoked with err=-ESHUTDOWN
via conn_tx_destroy
- Send errors (before tx allocated): callback invoked with the specific
error code in send_buf error_return path
- Connection disconnect: callbacks invoked with err=-ESHUTDOWN via
process_unack_tx -> conn_tx_destroy for all PDUs in tx_pending
However, when a channel is deleted (l2cap_chan_del), PDUs remaining in
the tx_queue are dropped without invoking their callbacks, violating the
ownership contract.
Fix this by extracting and invoking any non-NULL callbacks from the
closure stored in buf->user_data before releasing the buffers. The
callback is invoked with err=-ESHUTDOWN, making this path analogous to
process_unack_tx: both drain queues of unsent PDUs when transmission
becomes impossible due to external events (channel deletion vs connection
disconnect). The only difference is the buffer lifecycle stage - in
l2cap_chan_del, PDUs are still in tx_queue (closure in buf->user_data),
while in process_unack_tx, they've progressed to tx_pending (callback in
bt_conn_tx struct).
Note: conn_tx_destroy() cannot be used here because no bt_conn_tx struct
has been allocated yet - the closure is still in buf->user_data.
Signed-off-by: Aleksander Wasaznik <[email protected]>
0 commit comments