diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 63618dad6f9..0711e13ff47 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -150,7 +150,7 @@ static int att_send(struct bt_conn *conn, struct net_buf *buf, return 0; } -static void att_pdu_sent(struct bt_conn *conn, void *user_data) +void att_pdu_sent(struct bt_conn *conn, void *user_data) { struct bt_att *att = att_get(conn); struct net_buf *buf; @@ -175,7 +175,7 @@ static void att_pdu_sent(struct bt_conn *conn, void *user_data) k_sem_give(&att->tx_sem); } -static void att_cfm_sent(struct bt_conn *conn, void *user_data) +void att_cfm_sent(struct bt_conn *conn, void *user_data) { struct bt_att *att = att_get(conn); @@ -188,7 +188,7 @@ static void att_cfm_sent(struct bt_conn *conn, void *user_data) att_pdu_sent(conn, user_data); } -static void att_rsp_sent(struct bt_conn *conn, void *user_data) +void att_rsp_sent(struct bt_conn *conn, void *user_data) { struct bt_att *att = att_get(conn); @@ -201,7 +201,7 @@ static void att_rsp_sent(struct bt_conn *conn, void *user_data) att_pdu_sent(conn, user_data); } -static void att_req_sent(struct bt_conn *conn, void *user_data) +void att_req_sent(struct bt_conn *conn, void *user_data) { struct bt_att *att = att_get(conn); @@ -2048,6 +2048,9 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, u8_t op, size_t len) } buf = bt_l2cap_create_pdu(NULL, 0); + if (!buf) { + return NULL; + } hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = op; diff --git a/subsys/bluetooth/host/att_internal.h b/subsys/bluetooth/host/att_internal.h index 64ff21d93bd..52f499a5a56 100644 --- a/subsys/bluetooth/host/att_internal.h +++ b/subsys/bluetooth/host/att_internal.h @@ -236,6 +236,14 @@ struct bt_att_signed_write_cmd { u8_t value[0]; } __packed; +void att_pdu_sent(struct bt_conn *conn, void *user_data); + +void att_cfm_sent(struct bt_conn *conn, void *user_data); + +void att_rsp_sent(struct bt_conn *conn, void *user_data); + +void att_req_sent(struct bt_conn *conn, void *user_data); + void bt_att_init(void); u16_t bt_att_get_mtu(struct bt_conn *conn); struct net_buf *bt_att_create_pdu(struct bt_conn *conn, u8_t op, diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 4e72b607eb3..b177c96a778 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1178,6 +1178,19 @@ int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf, return 0; } +static bool conn_tx_internal(bt_conn_tx_cb_t cb) +{ + if (cb == att_pdu_sent || cb == att_cfm_sent || cb == att_rsp_sent || +#if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL) + cb == l2cap_chan_sdu_sent || +#endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */ + cb == att_req_sent) { + return true; + } + + return false; +} + void bt_conn_notify_tx(struct bt_conn *conn) { struct bt_conn_tx *tx; @@ -1189,7 +1202,12 @@ void bt_conn_notify_tx(struct bt_conn *conn) /* Only submit if there is a callback set */ if (tx->data.cb) { - k_work_submit(&tx->work); + /* Submit using RX thread if internal callback */ + if (conn_tx_internal(tx->data.cb)) { + tx_notify_cb(&tx->work); + } else { + k_work_submit(&tx->work); + } } else { tx_free(tx); } diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 6d2461796c4..e597dc4548b 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -1128,7 +1128,7 @@ segment: return seg; } -static void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data) +void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data) { struct bt_l2cap_chan *chan = user_data; diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index 3c4a1064500..2b24b0b98b8 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -222,6 +222,8 @@ struct bt_l2cap_br_fixed_chan { .accept = _accept, \ } +void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data); + /* Notify L2CAP channels of a new connection */ void bt_l2cap_connected(struct bt_conn *conn);