diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 712d0461d1bd..2065555a4c30 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -382,7 +382,9 @@ Binary libraries Bluetooth libraries and services -------------------------------- -|no_changes_yet_note| +* :ref:`bt_fast_pair_readme` library: + + * Updated the :c:func:`bt_fast_pair_info_cb_register` API to allow registration of multiple callbacks. Common Application Framework ---------------------------- diff --git a/include/bluetooth/services/fast_pair/fast_pair.h b/include/bluetooth/services/fast_pair/fast_pair.h index 7c69014fd266..4b9c16814312 100644 --- a/include/bluetooth/services/fast_pair/fast_pair.h +++ b/include/bluetooth/services/fast_pair/fast_pair.h @@ -166,6 +166,9 @@ struct bt_fast_pair_info_cb { * @param conn Connection object that wrote the Account Key. */ void (*account_key_written)(struct bt_conn *conn); + + /** Internally used field for list handling. */ + sys_snode_t node; }; /** Enable Fast Pair. @@ -294,7 +297,7 @@ int bt_fast_pair_battery_set(enum bt_fast_pair_battery_comp battery_comp, * * This function registers an instance of information callbacks. The registered instance needs to * persist in the memory after this function exits, as it is used directly without the copy - * operation. It is possible to register only one instance of callbacks with this API. + * operation. * * This function can only be called before enabling Fast Pair with the @ref bt_fast_pair_enable * API. @@ -305,7 +308,7 @@ int bt_fast_pair_battery_set(enum bt_fast_pair_battery_comp battery_comp, * * @return Zero on success or negative error code otherwise */ -int bt_fast_pair_info_cb_register(const struct bt_fast_pair_info_cb *cb); +int bt_fast_pair_info_cb_register(struct bt_fast_pair_info_cb *cb); /** Perform a reset to the default factory settings for Google Fast Pair Service. * diff --git a/samples/bluetooth/fast_pair/input_device/src/main.c b/samples/bluetooth/fast_pair/input_device/src/main.c index fdb47ece5dd6..ed47fa34d6a5 100644 --- a/samples/bluetooth/fast_pair/input_device/src/main.c +++ b/samples/bluetooth/fast_pair/input_device/src/main.c @@ -419,7 +419,7 @@ static void init_work_handle(struct k_work *w) static struct bt_conn_auth_info_cb auth_info_cb = { .pairing_complete = pairing_complete }; - static const struct bt_fast_pair_info_cb fp_info_callbacks = { + static struct bt_fast_pair_info_cb fp_info_callbacks = { .account_key_written = fp_account_key_written, }; diff --git a/samples/bluetooth/fast_pair/locator_tag/src/main.c b/samples/bluetooth/fast_pair/locator_tag/src/main.c index 3d60b94db7a9..3ee44b1255a8 100644 --- a/samples/bluetooth/fast_pair/locator_tag/src/main.c +++ b/samples/bluetooth/fast_pair/locator_tag/src/main.c @@ -217,7 +217,7 @@ static void fp_account_key_written(struct bt_conn *conn) fp_account_key_present = bt_fast_pair_has_account_key(); } -static const struct bt_fast_pair_info_cb fp_info_callbacks = { +static struct bt_fast_pair_info_cb fp_info_callbacks = { .account_key_written = fp_account_key_written, }; diff --git a/subsys/bluetooth/services/fast_pair/fp_gatt_service.c b/subsys/bluetooth/services/fast_pair/fp_gatt_service.c index 6ff073f206e8..702cf9ebbdb7 100644 --- a/subsys/bluetooth/services/fast_pair/fp_gatt_service.c +++ b/subsys/bluetooth/services/fast_pair/fp_gatt_service.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -95,8 +96,10 @@ struct msg_seekers_passkey { uint32_t passkey; }; -/* Reference to the Fast Pair information callback structure. */ -static const struct bt_fast_pair_info_cb *fast_pair_info_cb; +/* Fast Pair information callback list. */ +static sys_slist_t fast_pair_info_cb_slist = SYS_SLIST_STATIC_INIT(&fast_pair_info_cb_slist); + +static void fp_info_cb_account_key_written_notify(struct bt_conn *conn); #if CONFIG_BT_FAST_PAIR_GATT_SERVICE_MODEL_ID static ssize_t read_model_id(struct bt_conn *conn, @@ -765,8 +768,8 @@ static ssize_t write_account_key(struct bt_conn *conn, finish: if (res < 0) { fp_keys_drop_key(conn); - } else if (fast_pair_info_cb && fast_pair_info_cb->account_key_written) { - fast_pair_info_cb->account_key_written(conn); + } else { + fp_info_cb_account_key_written_notify(conn); } LOG_DBG("Account Key write: res=%d conn=%p", res, (void *)conn); @@ -833,7 +836,20 @@ static ssize_t write_additional_data(struct bt_conn *conn, return res; } -int bt_fast_pair_info_cb_register(const struct bt_fast_pair_info_cb *cb) +static void fp_info_cb_account_key_written_notify(struct bt_conn *conn) +{ + struct bt_fast_pair_info_cb *listener; + + __ASSERT_NO_MSG(bt_fast_pair_is_ready()); + + SYS_SLIST_FOR_EACH_CONTAINER(&fast_pair_info_cb_slist, listener, node) { + if (listener->account_key_written) { + listener->account_key_written(conn); + } + } +} + +int bt_fast_pair_info_cb_register(struct bt_fast_pair_info_cb *cb) { /* It is assumed that this function executes in the cooperative thread context. */ __ASSERT_NO_MSG(!k_is_preempt_thread()); @@ -847,11 +863,11 @@ int bt_fast_pair_info_cb_register(const struct bt_fast_pair_info_cb *cb) return -EINVAL; } - if (fast_pair_info_cb) { - return -EALREADY; + if (sys_slist_find(&fast_pair_info_cb_slist, &cb->node, NULL)) { + return 0; } - fast_pair_info_cb = cb; + sys_slist_append(&fast_pair_info_cb_slist, &cb->node); return 0; }