Bluetooth: GATT: Add missing busy check for auto discover CCC

When using the auto discover CCC, and the function is called
more than once with the same parameters before the previous
discovery has completed, then that may cause issues when we
reset the parameters when we get the response.

This commit adds a small check for the callback function
which is only set to the specified function when the
discovery is in progress. This way we can return an error
if the application calls bt_gatt_subscribe multiple times
before the previous discovery has completed, rather
than asserting.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2024-01-15 15:51:29 +01:00 committed by Alberto Escolar
commit d26ba10640
2 changed files with 12 additions and 0 deletions

View file

@ -1896,6 +1896,11 @@ struct bt_gatt_subscribe_params {
* Allow a pending request to resolve before retrying, or call this function * Allow a pending request to resolve before retrying, or call this function
* outside the BT RX thread to get blocking behavior. Queue size is controlled * outside the BT RX thread to get blocking behavior. Queue size is controlled
* by @kconfig{CONFIG_BT_ATT_TX_COUNT}. * by @kconfig{CONFIG_BT_ATT_TX_COUNT}.
*
* @retval -EALREADY if there already exist a subscription using the @p params.
*
* @retval -EBUSY if @p params.ccc_handle is 0 and @kconfig{CONFIG_BT_GATT_AUTO_DISCOVER_CCC} is
* enabled and discovery for the @p params is already in progress.
*/ */
int bt_gatt_subscribe(struct bt_conn *conn, int bt_gatt_subscribe(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params); struct bt_gatt_subscribe_params *params);

View file

@ -5294,6 +5294,13 @@ int bt_gatt_subscribe(struct bt_conn *conn,
return -ENOMEM; return -ENOMEM;
} }
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
if (params->disc_params != NULL && params->disc_params->func == gatt_ccc_discover_cb) {
/* Already in progress */
return -EBUSY;
}
#endif
/* Lookup existing subscriptions */ /* Lookup existing subscriptions */
SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) { SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
/* Fail if entry already exists */ /* Fail if entry already exists */