Bluetooth: ATT: Fix bt_att_req_cancel clearing outstanding request

This adds a dummy cancel request which is used instead of NULL when
clearing and outstanding request thus prevent new request to take
place before a response is received while allowing the original request
to be reused.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-07-16 18:13:03 +03:00 committed by Carles Cufí
commit 662a519a17

View file

@ -96,6 +96,7 @@ struct bt_att {
}; };
static struct bt_att bt_req_pool[CONFIG_BT_MAX_CONN]; static struct bt_att bt_req_pool[CONFIG_BT_MAX_CONN];
static struct bt_att_req cancel;
static void att_req_destroy(struct bt_att_req *req) static void att_req_destroy(struct bt_att_req *req)
{ {
@ -358,6 +359,12 @@ static u8_t att_handle_rsp(struct bt_att *att, void *pdu, u16_t len, u8_t err)
goto process; goto process;
} }
/* Check if request has been cancelled */
if (att->req == &cancel) {
att->req = NULL;
goto process;
}
/* Release original buffer */ /* Release original buffer */
if (att->req->buf) { if (att->req->buf) {
net_buf_unref(att->req->buf); net_buf_unref(att->req->buf);
@ -1643,7 +1650,8 @@ static u8_t att_error_rsp(struct bt_att *att, struct net_buf *buf)
BT_DBG("request 0x%02x handle 0x%04x error 0x%02x", rsp->request, BT_DBG("request 0x%02x handle 0x%04x error 0x%02x", rsp->request,
sys_le16_to_cpu(rsp->handle), rsp->error); sys_le16_to_cpu(rsp->handle), rsp->error);
if (!att->req) { /* Don't retry if there is no req pending or it has been cancelled */
if (!att->req || att->req == &cancel) {
err = BT_ATT_ERR_UNLIKELY; err = BT_ATT_ERR_UNLIKELY;
goto done; goto done;
} }
@ -2318,7 +2326,7 @@ void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req)
/* Check if request is outstanding */ /* Check if request is outstanding */
if (att->req == req) { if (att->req == req) {
att->req = NULL; att->req = &cancel;
} else { } else {
/* Remove request from the list */ /* Remove request from the list */
sys_slist_find_and_remove(&att->reqs, &req->node); sys_slist_find_and_remove(&att->reqs, &req->node);