From d26ba10640436ed4a2bade6f8906dd7aee477a82 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 15 Jan 2024 15:51:29 +0100 Subject: [PATCH] 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 --- include/zephyr/bluetooth/gatt.h | 5 +++++ subsys/bluetooth/host/gatt.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index b5c355fad21..2cbe96a7285 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -1896,6 +1896,11 @@ struct bt_gatt_subscribe_params { * 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 * 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, struct bt_gatt_subscribe_params *params); diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 451c3d29f7f..eda7d2dff26 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -5294,6 +5294,13 @@ int bt_gatt_subscribe(struct bt_conn *conn, 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 */ SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) { /* Fail if entry already exists */