Bluetooth: services: Add HRS notification changed app callback

It is useful for an application to be informed when there is
a subscriber waiting for HRS service notification.
Extend HRS service API and add required code to service implementation.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
Piotr Pryga 2023-08-14 11:25:51 +02:00 committed by Johan Hedberg
commit 4d0ef142f3
2 changed files with 75 additions and 0 deletions

View file

@ -19,10 +19,50 @@
#include <stdint.h>
#include <zephyr/sys/slist.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Heart rate service callback structure */
struct bt_hrs_cb {
/** @brief Heart rate notifications changed
*
* @param enabled Flag that is true if notifications were enabled, false
* if they were disabled.
*/
void (*ntf_changed)(bool enabled);
/** Internal member to form a list of callbacks */
sys_snode_t _node;
};
/** @brief Heart rate service callback register
*
* This function will register callbacks that will be called in
* certain events related to Heart rate service.
*
* @param cb Pointer to callbacks structure. Must point to memory that remains valid
* until unregistered.
*
* @return 0 on success
* @return -EINVAL in case @p cb is NULL
*/
int bt_hrs_cb_register(struct bt_hrs_cb *cb);
/** @brief Heart rate service callback unregister
*
* This function will unregister callback from Heart rate service.
*
* @param cb Pointer to callbacks structure
*
* @return 0 on success
* @return -EINVAL in case @p cb is NULL
* @return -ENOENT in case the @p cb was not found in registered callbacks
*/
int bt_hrs_cb_unregister(struct bt_hrs_cb *cb);
/** @brief Notify heart rate measurement.
*
* This will send a GATT notification to all current subscribers.

View file

@ -14,12 +14,14 @@
#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/sys/check.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/services/hrs.h>
#define LOG_LEVEL CONFIG_BT_HRS_LOG_LEVEL
#include <zephyr/logging/log.h>
@ -51,14 +53,23 @@ LOG_MODULE_REGISTER(hrs);
(BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)) \
static uint8_t hrs_blsc;
static sys_slist_t hrs_cbs = SYS_SLIST_STATIC_INIT(&hrs_cbs);
static void hrmc_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
ARG_UNUSED(attr);
struct bt_hrs_cb *listener;
bool notif_enabled = (value == BT_GATT_CCC_NOTIFY);
LOG_INF("HRS notifications %s", notif_enabled ? "enabled" : "disabled");
SYS_SLIST_FOR_EACH_CONTAINER(&hrs_cbs, listener, _node) {
if (listener->ntf_changed) {
listener->ntf_changed(notif_enabled);
}
}
}
static ssize_t read_blsc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
@ -91,6 +102,30 @@ static int hrs_init(void)
return 0;
}
int bt_hrs_cb_register(struct bt_hrs_cb *cb)
{
CHECKIF(cb == NULL) {
return -EINVAL;
}
sys_slist_append(&hrs_cbs, &cb->_node);
return 0;
}
int bt_hrs_cb_unregister(struct bt_hrs_cb *cb)
{
CHECKIF(cb == NULL) {
return -EINVAL;
}
if (!sys_slist_find_and_remove(&hrs_cbs, &cb->_node)) {
return -ENOENT;
}
return 0;
}
int bt_hrs_notify(uint16_t heartrate)
{
int rc;