Bluetooth: Dispatch internal callbacks using RX thread
This is safer now that bt_conn_create_pdu can return NULL when using syswq which can prevent things like signalling of L2CAP and ATT layers. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
6b0242cfeb
commit
b563f4440a
5 changed files with 37 additions and 6 deletions
|
@ -150,7 +150,7 @@ static int att_send(struct bt_conn *conn, struct net_buf *buf,
|
||||||
return 0;
|
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 bt_att *att = att_get(conn);
|
||||||
struct net_buf *buf;
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
buf = bt_l2cap_create_pdu(NULL, 0);
|
||||||
|
if (!buf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||||
hdr->code = op;
|
hdr->code = op;
|
||||||
|
|
|
@ -236,6 +236,14 @@ struct bt_att_signed_write_cmd {
|
||||||
u8_t value[0];
|
u8_t value[0];
|
||||||
} __packed;
|
} __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);
|
void bt_att_init(void);
|
||||||
u16_t bt_att_get_mtu(struct bt_conn *conn);
|
u16_t bt_att_get_mtu(struct bt_conn *conn);
|
||||||
struct net_buf *bt_att_create_pdu(struct bt_conn *conn, u8_t op,
|
struct net_buf *bt_att_create_pdu(struct bt_conn *conn, u8_t op,
|
||||||
|
|
|
@ -1178,6 +1178,19 @@ int bt_conn_send_cb(struct bt_conn *conn, struct net_buf *buf,
|
||||||
return 0;
|
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)
|
void bt_conn_notify_tx(struct bt_conn *conn)
|
||||||
{
|
{
|
||||||
struct bt_conn_tx *tx;
|
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 */
|
/* Only submit if there is a callback set */
|
||||||
if (tx->data.cb) {
|
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 {
|
} else {
|
||||||
tx_free(tx);
|
tx_free(tx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1128,7 +1128,7 @@ segment:
|
||||||
return seg;
|
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;
|
struct bt_l2cap_chan *chan = user_data;
|
||||||
|
|
||||||
|
|
|
@ -222,6 +222,8 @@ struct bt_l2cap_br_fixed_chan {
|
||||||
.accept = _accept, \
|
.accept = _accept, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void l2cap_chan_sdu_sent(struct bt_conn *conn, void *user_data);
|
||||||
|
|
||||||
/* Notify L2CAP channels of a new connection */
|
/* Notify L2CAP channels of a new connection */
|
||||||
void bt_l2cap_connected(struct bt_conn *conn);
|
void bt_l2cap_connected(struct bt_conn *conn);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue