Bluetooth: Host: Fix type mismatch in bt_gatt_cancel

`bt_gatt_cancel` takes a `bt_gatt_.._params` pointer. The `params`
pointer is mistakenly passed on to `bt_att_req_cancel`, which expects a
`bt_att_req`.

This change makes bt_gatt_cancel locate the `req` and pass that to
`bt_att_req_cancel`.

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Co-authored-by: Emil Gydesen <Thalley@users.noreply.github.com>
This commit is contained in:
Aleksander Wasaznik 2021-11-11 12:29:05 +01:00 committed by Anas Nashif
commit e97413057a
4 changed files with 64 additions and 4 deletions

View file

@ -1675,10 +1675,22 @@ int bt_gatt_resubscribe(uint8_t id, const bt_addr_le_t *peer,
int bt_gatt_unsubscribe(struct bt_conn *conn, int bt_gatt_unsubscribe(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params); struct bt_gatt_subscribe_params *params);
/** @brief Cancel GATT pending request /** @brief Try to cancel the first pending request identified by @p params.
* *
* @param conn Connection object. * This function does not release @p params for reuse. The usual callbacks
* @param params Requested params address. * for the request still apply. A successful cancel simulates a
* #BT_ATT_ERR_UNLIKELY response from the server.
*
* This function can cancel the following request functions:
* - #bt_gatt_exchange_mtu
* - #bt_gatt_discover
* - #bt_gatt_read
* - #bt_gatt_write
* - #bt_gatt_subscribe
* - #bt_gatt_unsubscribe
*
* @param conn The connection the request was issued on.
* @param params The address `params` used in the request function call.
*/ */
void bt_gatt_cancel(struct bt_conn *conn, void *params); void bt_gatt_cancel(struct bt_conn *conn, void *params);

View file

@ -3228,3 +3228,29 @@ void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req)
bt_att_req_free(req); bt_att_req_free(req);
} }
struct bt_att_req *bt_att_find_req_by_user_data(struct bt_conn *conn, const void *user_data)
{
struct bt_att *att;
struct bt_att_chan *chan;
struct bt_att_req *req;
att = att_get(conn);
if (!att) {
return NULL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&att->chans, chan, node) {
if (chan->req->user_data == user_data) {
return chan->req;
}
}
SYS_SLIST_FOR_EACH_CONTAINER(&att->reqs, req, node) {
if (req->user_data == user_data) {
return req;
}
}
return NULL;
}

View file

@ -304,3 +304,10 @@ int bt_eatt_connect(struct bt_conn *conn, uint8_t num_channels);
/* Disconnect EATT channels */ /* Disconnect EATT channels */
int bt_eatt_disconnect(struct bt_conn *conn); int bt_eatt_disconnect(struct bt_conn *conn);
/** @brief Find a pending ATT request by its user_data pointer.
* @param conn The connection the request was issued on.
* @param user_data The pointer value to look for.
* @return The found request. NULL if not found.
*/
struct bt_att_req *bt_att_find_req_by_user_data(struct bt_conn *conn, const void *user_data);

View file

@ -4650,7 +4650,22 @@ int bt_gatt_unsubscribe(struct bt_conn *conn,
void bt_gatt_cancel(struct bt_conn *conn, void *params) void bt_gatt_cancel(struct bt_conn *conn, void *params)
{ {
bt_att_req_cancel(conn, params); struct bt_att_req *req;
bt_att_func_t func = NULL;
k_sched_lock();
req = bt_att_find_req_by_user_data(conn, params);
if (req) {
func = req->func;
bt_att_req_cancel(conn, req);
}
k_sched_unlock();
if (func) {
func(conn, BT_ATT_ERR_UNLIKELY, NULL, 0, params);
}
} }
static void add_subscriptions(struct bt_conn *conn) static void add_subscriptions(struct bt_conn *conn)