Skip to content

Commit 5e6dae8

Browse files
sondrepasilz
authored andcommitted
bluetooth: services: ble_hrs_c: add heart rate client srvc sample
Add BLE heart rate client service and sample. Co-authored-by: Asil Zogby <[email protected]> Signed-off-by: Sondre Pettersen <[email protected]> Signed-off-by: Eivind Jølsgard <[email protected]>
1 parent d0d53c4 commit 5e6dae8

File tree

12 files changed

+1444
-0
lines changed

12 files changed

+1444
-0
lines changed
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
* Copyright (c) 2012 - 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
/**
7+
* @file
8+
*
9+
* @defgroup ble_hrs_central Heart Rate Service Client
10+
* @{
11+
* @brief Heart Rate Service Client.
12+
*
13+
* @details This library contains the APIs and types exposed by the Heart Rate Service Client
14+
* library. The application can use these APIs and types to perform the discovery of
15+
* Heart Rate Service at the peer and to interact with it.
16+
*
17+
* @warning Currently, this library only supports the Heart Rate Measurement characteristic. This
18+
* means that it is able to enable notification of the characteristic at the peer and
19+
* is able to receive Heart Rate Measurement notifications from the peer. It does not
20+
* support the Body Sensor Location and the Heart Rate Control Point characteristics.
21+
* When a Heart Rate Measurement is received, this library decodes only the
22+
* Heart Rate Measurement value field (both 8-bit and 16-bit) and provides it to
23+
* the application.
24+
*/
25+
26+
#ifndef BLE_HRS_CENTRAL_H__
27+
#define BLE_HRS_CENTRAL_H__
28+
29+
#include <stdint.h>
30+
#include <ble.h>
31+
#include <bm/bluetooth/ble_db_discovery.h>
32+
#include <bm/bluetooth/ble_gq.h>
33+
#include <bm/softdevice_handler/nrf_sdh_ble.h>
34+
35+
#ifdef __cplusplus
36+
extern "C" {
37+
#endif
38+
39+
/**
40+
* @brief Macro for defining a ble_hrs_central instance.
41+
*
42+
* @param _name Name of the instance.
43+
* @hideinitializer
44+
*/
45+
#define BLE_HRS_CENTRAL_DEF(_name) \
46+
static struct ble_hrs_central _name; \
47+
NRF_SDH_BLE_OBSERVER(_name##_obs, ble_hrs_central_on_ble_evt, &_name, USER_LOW)
48+
49+
/**
50+
* @brief HRS Client event type.
51+
*/
52+
enum ble_hrs_central_evt_type {
53+
/** Event indicating that the Heart Rate Service was discovered at the peer. */
54+
BLE_HRS_CENTRAL_EVT_DISCOVERY_COMPLETE,
55+
/** Event indicating that a notification of the Heart Rate Measurement characteristic was
56+
* received from the peer.
57+
*/
58+
BLE_HRS_CENTRAL_EVT_HRM_NOTIFICATION,
59+
/** Error. */
60+
BLE_HRS_CENTRAL_EVT_ERROR,
61+
};
62+
63+
/**
64+
* @brief Heart Rate Measurement received from the peer.
65+
*/
66+
struct ble_hrm {
67+
/** Heart Rate Value. */
68+
uint16_t hr_value;
69+
/** Number of RR intervals. */
70+
uint8_t rr_intervals_cnt;
71+
/** RR intervals. */
72+
uint16_t rr_intervals[CONFIG_BLE_HRS_CENTRAL_RR_INTERVALS_MAX_COUNT];
73+
};
74+
75+
/**
76+
* @brief Database for handles related to the Heart Rate Service found on the peer.
77+
*/
78+
struct hrs_db {
79+
/** Handle of the CCCD of the Heart Rate Measurement characteristic. */
80+
uint16_t hrm_cccd_handle;
81+
/** Handle of the Heart Rate Measurement characteristic, as provided by the SoftDevice. */
82+
uint16_t hrm_handle;
83+
};
84+
85+
/**
86+
* @brief Heart Rate Event.
87+
*/
88+
struct ble_hrs_central_evt {
89+
/** Type of the event. */
90+
enum ble_hrs_central_evt_type evt_type;
91+
/** Connection handle on which the Heart Rate service was discovered on the peer device. */
92+
uint16_t conn_handle;
93+
union {
94+
/** Handles related to the Heart Rate, found on the peer device.
95+
* This is filled if the evt_type is @ref BLE_HRS_CENTRAL_EVT_DISCOVERY_COMPLETE.
96+
*/
97+
struct hrs_db peer_db;
98+
/** Heart Rate Measurement received. This is filled if the evt_type
99+
* is @ref BLE_HRS_CENTRAL_EVT_HRM_NOTIFICATION.
100+
*/
101+
struct ble_hrm hrm;
102+
/** Error event. This is filled if the evt_type
103+
* is @ref BLE_HRS_CENTRAL_EVT_ERROR. */
104+
struct {
105+
/** Error reason */
106+
uint32_t reason;
107+
} error;
108+
} params;
109+
};
110+
111+
/** Forward declaration. */
112+
struct ble_hrs_central;
113+
114+
/**
115+
* @brief Event handler type.
116+
*
117+
* @details This is the type of the event handler that is to be provided by the application
118+
* of this module to receive events.
119+
*/
120+
typedef void (*ble_hrs_central_evt_handler_t)(struct ble_hrs_central *ble_hrs_central,
121+
struct ble_hrs_central_evt *evt);
122+
123+
/**
124+
* @brief Heart Rate Client.
125+
*/
126+
struct ble_hrs_central {
127+
/** Connection handle, as provided by the SoftDevice. */
128+
uint16_t conn_handle;
129+
/** Handles related to HRS on the peer. */
130+
struct hrs_db peer_hrs_db;
131+
/** Application event handler to be called when there
132+
* is an event related to the Heart Rate Service.
133+
*/
134+
ble_hrs_central_evt_handler_t evt_handler;
135+
/** Bluetooth LE GATT Queue instance. */
136+
const struct ble_gq *gatt_queue;
137+
};
138+
139+
/**
140+
* @brief Heart Rate Client configuration structure.
141+
*/
142+
struct ble_hrs_central_config {
143+
/** Event handler to be called by the Heart Rate Client module when
144+
* there is an event related to the Heart Rate Service.
145+
*/
146+
ble_hrs_central_evt_handler_t evt_handler;
147+
/** Bluetooth LE GATT Queue instance. */
148+
const struct ble_gq *gatt_queue;
149+
/** Database discovery instance. */
150+
struct ble_db_discovery *db_discovery;
151+
};
152+
153+
/**
154+
* @brief Initialize the Heart Rate Client module.
155+
*
156+
* @details This function registers with the Database Discovery module for the Heart Rate Service.
157+
* The module looks for the presence of a Heart Rate Service instance at the peer
158+
* when a discovery is started.
159+
*
160+
* @param[in] ble_hrs_central Heart Rate Client structure.
161+
* @param[in] ble_hrs_central_init Heart Rate initialization structure that
162+
* contains the initialization information.
163+
*
164+
* @retval NRF_SUCCESS On successful initialization.
165+
* @return Otherwise, this function propagates the error code returned by the
166+
* Database Discovery module API @ref ble_db_discovery_service_register.
167+
*/
168+
uint32_t ble_hrs_central_init(struct ble_hrs_central *ble_hrs_central,
169+
struct ble_hrs_central_config *ble_hrs_central_init);
170+
171+
/**
172+
* @brief Handle Bluetooth LE events from the SoftDevice.
173+
*
174+
* @details This function handles the Bluetooth LE events received from the SoftDevice.
175+
* If an event is relevant to the Heart Rate Client module, the function uses
176+
* the event's data to update interval variables and, if necessary, send events to the
177+
* application.
178+
*
179+
* @param[in] ble_evt Bluetooth LE event.
180+
* @param[in] ctx Heart Rate Client structure.
181+
*/
182+
void ble_hrs_central_on_ble_evt(ble_evt_t const *ble_evt, void *ctx);
183+
184+
/**
185+
* @brief Request the peer to start sending notification of Heart Rate Measurement.
186+
*
187+
* @details This function enables notification of the Heart Rate Measurement at the peer
188+
* by writing to the CCCD of the Heart Rate Measurement characteristic.
189+
*
190+
* @param ble_hrs_central Heart Rate Client structure.
191+
*
192+
* @retval NRF_SUCCESS If the SoftDevice is requested to write to the CCCD of the peer.
193+
* @return Error code returned by the SoftDevice API @ref sd_ble_gattc_write.
194+
*/
195+
uint32_t ble_hrs_central_hrm_notif_enable(struct ble_hrs_central *ble_hrs_central);
196+
197+
/**
198+
* @brief Handle events from the Database Discovery module.
199+
*
200+
* @details Call this function when you get a callback event from the Database Discovery
201+
* module. This function handles an event from the Database Discovery module and determines
202+
* whether it relates to the discovery of Heart Rate Service at the peer. If it
203+
* does, the function calls the application's event handler to indicate that the Heart Rate
204+
* Service was discovered at the peer. The function also populates the event with
205+
* service-related information before providing it to the application.
206+
*
207+
* @param[in] ble_hrs_central Heart Rate Client structure instance for
208+
* associating the link.
209+
* @param[in] evt Event received from the Database Discovery module.
210+
*
211+
*/
212+
void ble_hrs_on_db_disc_evt(struct ble_hrs_central *ble_hrs_central,
213+
const struct ble_db_discovery_evt *evt);
214+
215+
/**
216+
* @brief Assign handles to an instance of hrs_c.
217+
*
218+
* @details Call this function when a link has been established with a peer to
219+
* associate the link to this instance of the module. This association makes it
220+
* possible to handle several links and associate each link to a particular
221+
* instance of this module. The connection handle and attribute handles are
222+
* provided from the discovery event @ref BLE_HRS_CENTRAL_EVT_DISCOVERY_COMPLETE.
223+
*
224+
* @param[in] ble_hrs_central Heart Rate Client structure instance for
225+
* associating the link.
226+
* @param[in] conn_handle Connection handle to associate with the given Heart Rate
227+
* Client Instance.
228+
* @param[in] peer_hrs_handles Attribute handles for the HRS server you want this HRS_C
229+
* client to interact with.
230+
*/
231+
uint32_t ble_hrs_central_handles_assign(struct ble_hrs_central *ble_hrs_central,
232+
uint16_t conn_handle,
233+
const struct hrs_db *peer_hrs_handles);
234+
235+
#ifdef __cplusplus
236+
}
237+
#endif
238+
239+
#endif /* BLE_HRS_CENTRAL_H__ */
240+
241+
/** @} */
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(ble_hrs)
11+
12+
target_sources(app PRIVATE src/main.c)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
menu "BLE HRS central sample"
8+
9+
config APP_USE_TARGET_PERIPHERAL_NAME
10+
bool "Use target peripheral name"
11+
default y
12+
13+
if APP_USE_TARGET_PERIPHERAL_NAME
14+
15+
config APP_TARGET_PERIPHERAL_NAME
16+
string "Target peripheral name"
17+
default "nRF_BM_HRS"
18+
19+
endif # APP_USE_TARGET_PERIPHERAL_NAME
20+
21+
config APP_USE_TARGET_PERIPHERAL_ADDR
22+
bool "Use target peripheral address"
23+
24+
if APP_USE_TARGET_PERIPHERAL_ADDR
25+
26+
config APP_TARGET_PERIPHERAL_ADDR
27+
hex "Target peripheral address"
28+
range 0x0 0xffffffffffff
29+
default 0x78E7F806C5D8
30+
31+
endif # APP_USE_TARGET_PERIPHERAL_ADDR
32+
33+
module=APP_BLE_HRS_CENTRAL_SAMPLE
34+
module-str=BLE Heart Rate Central Service Sample
35+
source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config"
36+
37+
endmenu # "BLE HRS central sample"
38+
39+
source "Kconfig.zephyr"

0 commit comments

Comments
 (0)