Bluetooth: conn: Add pending tx before calling bt_send()

It's possible that the controller will emit the number of completed
packets event before bt_send() returns, or possibly preempt
send_frag() before it manages to call add_pending_tx(). We have to
therefore add the pending TX entry before calling bt_send().

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-06-22 15:52:35 +03:00 committed by Johan Hedberg
commit 9b1653061a

View file

@ -1099,7 +1099,7 @@ void bt_conn_notify_tx(struct bt_conn *conn)
}
}
static void add_pending_tx(struct bt_conn *conn, bt_conn_tx_cb_t cb)
static sys_snode_t *add_pending_tx(struct bt_conn *conn, bt_conn_tx_cb_t cb)
{
sys_snode_t *node;
unsigned int key;
@ -1114,6 +1114,19 @@ static void add_pending_tx(struct bt_conn *conn, bt_conn_tx_cb_t cb)
key = irq_lock();
sys_slist_append(&conn->tx_pending, node);
irq_unlock(key);
return node;
}
static void remove_pending_tx(struct bt_conn *conn, sys_snode_t *node)
{
unsigned int key;
key = irq_lock();
sys_slist_find_and_remove(&conn->tx_pending, node);
irq_unlock(key);
tx_free(CONTAINER_OF(node, struct bt_conn_tx, node));
}
static bool send_frag(struct bt_conn *conn, struct net_buf *buf, u8_t flags,
@ -1121,6 +1134,7 @@ static bool send_frag(struct bt_conn *conn, struct net_buf *buf, u8_t flags,
{
struct bt_hci_acl_hdr *hdr;
bt_conn_tx_cb_t cb;
sys_snode_t *node;
int err;
BT_DBG("conn %p buf %p len %u flags 0x%02x", conn, buf, buf->len,
@ -1144,13 +1158,15 @@ static bool send_frag(struct bt_conn *conn, struct net_buf *buf, u8_t flags,
cb = conn_tx(buf)->cb;
bt_buf_set_type(buf, BT_BUF_ACL_OUT);
node = add_pending_tx(conn, cb);
err = bt_send(buf);
if (err) {
BT_ERR("Unable to send to driver (err %d)", err);
remove_pending_tx(conn, node);
goto fail;
}
add_pending_tx(conn, cb);
return true;
fail: