diff --git a/net/bluetooth/conn.c b/net/bluetooth/conn.c index 3fcf130e5a9..dfc6631bf1b 100644 --- a/net/bluetooth/conn.c +++ b/net/bluetooth/conn.c @@ -317,6 +317,8 @@ static void conn_tx_fiber(int arg1, int arg2) BT_DBG("passing buf %p len %u to driver\n", buf, buf->len); bt_dev.drv->send(buf); bt_buf_put(buf); + + conn->pending_pkts++; } BT_DBG("handle %u disconnected - cleaning up\n", conn->handle); @@ -326,6 +328,13 @@ static void conn_tx_fiber(int arg1, int arg2) bt_buf_put(buf); } + /* Return any unacknowledged packets */ + if (conn->pending_pkts) { + while (conn->pending_pkts--) { + nano_fiber_sem_give(&bt_dev.le_pkts_sem); + } + } + bt_conn_reset_rx_state(conn); BT_DBG("handle %u exiting\n", conn->handle); diff --git a/net/bluetooth/conn_internal.h b/net/bluetooth/conn_internal.h index 1863a62b70a..ec047cdee8e 100644 --- a/net/bluetooth/conn_internal.h +++ b/net/bluetooth/conn_internal.h @@ -60,6 +60,8 @@ struct bt_conn { bt_addr_le_t init_addr; bt_addr_le_t resp_addr; + uint8_t pending_pkts; + uint8_t encrypt; bt_security_t sec_level; bt_security_t required_sec_level; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 89b4359a9dd..06cd6758c0f 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -473,14 +473,30 @@ static void hci_num_completed_packets(struct bt_buf *buf) for (i = 0; i < num_handles; i++) { uint16_t handle, count; + struct bt_conn *conn; handle = sys_le16_to_cpu(evt->h[i].handle); count = sys_le16_to_cpu(evt->h[i].count); BT_DBG("handle %u count %u\n", handle, count); - while (count--) + conn = bt_conn_lookup_handle(handle); + if (conn) { + if (conn->pending_pkts >= count) { + conn->pending_pkts -= count; + } else { + BT_ERR("completed packets mismatch: %u > %u\n", + count, conn->pending_pkts); + conn->pending_pkts = 0; + } + bt_conn_put(conn); + } else { + BT_ERR("No matching connection for handle %u", handle); + } + + while (count--) { nano_fiber_sem_give(&bt_dev.le_pkts_sem); + } } }