Bluetooth: services: Move Heart rate service

This commit moves the BLE GATT heart rate service from
samples/bluetooth/gatt to subsys/bluetooth/services and adds a Kconfig
entry to enable and configure the service.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2019-07-04 16:44:29 +02:00 committed by Johan Hedberg
commit 029a66a195
23 changed files with 171 additions and 65 deletions

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_HRS_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_HRS_H_
/**
* @brief Heart Rate Service (HRS)
* @defgroup bt_gatt_hrs Heart Rate Service (HRS)
* @ingroup bluetooth
* @{
*
* [Experimental] Users should note that the APIs can change
* as a part of ongoing development.
*/
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Notify heart rate measurement.
*
* This will send a GATT notification to all current subscribers.
*
* @param heartrate The heartrate measuremennt in beats per minute.
*
* @return Zero in case of success and error code in case of error.
*/
int bt_gatt_hrs_notify(u16_t heartrate);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_HRS_H_ */

View file

@ -1,20 +0,0 @@
/** @file
* @brief HRS Service sample
*/
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __cplusplus
extern "C" {
#endif
void hrs_init(u8_t blsc);
void hrs_notify(void);
#ifdef __cplusplus
}
#endif

View file

@ -6,7 +6,6 @@ project(peripheral)
target_sources(app PRIVATE target_sources(app PRIVATE
src/main.c src/main.c
../gatt/hrs.c
../gatt/cts.c ../gatt/cts.c
) )

View file

@ -9,6 +9,7 @@ CONFIG_BT_PERIPHERAL=y
CONFIG_BT_GATT_DIS=y CONFIG_BT_GATT_DIS=y
CONFIG_BT_ATT_PREPARE_COUNT=5 CONFIG_BT_ATT_PREPARE_COUNT=5
CONFIG_BT_GATT_BAS=y CONFIG_BT_GATT_BAS=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_PRIVACY=y CONFIG_BT_PRIVACY=y
CONFIG_BT_DEVICE_NAME="Zephyr Peripheral Sample Long Name" CONFIG_BT_DEVICE_NAME="Zephyr Peripheral Sample Long Name"
CONFIG_BT_DEVICE_APPEARANCE=833 CONFIG_BT_DEVICE_APPEARANCE=833

View file

@ -22,8 +22,8 @@
#include <bluetooth/uuid.h> #include <bluetooth/uuid.h>
#include <bluetooth/gatt.h> #include <bluetooth/gatt.h>
#include <bluetooth/services/bas.h> #include <bluetooth/services/bas.h>
#include <bluetooth/services/hrs.h>
#include <gatt/hrs.h>
#include <gatt/cts.h> #include <gatt/cts.h>
/* Custom Service Variables */ /* Custom Service Variables */
@ -254,7 +254,6 @@ static void bt_ready(int err)
printk("Bluetooth initialized\n"); printk("Bluetooth initialized\n");
hrs_init(0x01);
cts_init(); cts_init();
if (IS_ENABLED(CONFIG_SETTINGS)) { if (IS_ENABLED(CONFIG_SETTINGS)) {
@ -307,6 +306,19 @@ static void bas_notify(void)
bt_gatt_bas_set_battery_level(battery_level); bt_gatt_bas_set_battery_level(battery_level);
} }
static void hrs_notify(void)
{
static u8_t heartrate = 90U;
/* Heartrate measurements simulation */
heartrate++;
if (heartrate == 160U) {
heartrate = 90U;
}
bt_gatt_hrs_notify(heartrate);
}
void main(void) void main(void)
{ {
int err; int err;

View file

@ -8,7 +8,6 @@ project(peripheral_hr)
FILE(GLOB app_sources src/*.c) FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE target_sources(app PRIVATE
${app_sources} ${app_sources}
../gatt/hrs.c
) )
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth) zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)

View file

@ -5,5 +5,6 @@ CONFIG_BT_PERIPHERAL=y
CONFIG_BT_GATT_DIS=y CONFIG_BT_GATT_DIS=y
CONFIG_BT_GATT_DIS_PNP=n CONFIG_BT_GATT_DIS_PNP=n
CONFIG_BT_GATT_BAS=y CONFIG_BT_GATT_BAS=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_DEVICE_NAME="Zephyr Heartrate Sensor" CONFIG_BT_DEVICE_NAME="Zephyr Heartrate Sensor"
CONFIG_BT_DEVICE_APPEARANCE=833 CONFIG_BT_DEVICE_APPEARANCE=833

View file

@ -20,8 +20,7 @@
#include <bluetooth/uuid.h> #include <bluetooth/uuid.h>
#include <bluetooth/gatt.h> #include <bluetooth/gatt.h>
#include <bluetooth/services/bas.h> #include <bluetooth/services/bas.h>
#include <bluetooth/services/hrs.h>
#include <gatt/hrs.h>
struct bt_conn *default_conn; struct bt_conn *default_conn;
@ -64,8 +63,6 @@ static void bt_ready(int err)
printk("Bluetooth initialized\n"); printk("Bluetooth initialized\n");
hrs_init(0x01);
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) { if (err) {
printk("Advertising failed to start (err %d)\n", err); printk("Advertising failed to start (err %d)\n", err);
@ -101,6 +98,19 @@ static void bas_notify(void)
bt_gatt_bas_set_battery_level(battery_level); bt_gatt_bas_set_battery_level(battery_level);
} }
static void hrs_notify(void)
{
static u8_t heartrate = 90U;
/* Heartrate measurements simulation */
heartrate++;
if (heartrate == 160U) {
heartrate = 90U;
}
bt_gatt_hrs_notify(heartrate);
}
void main(void) void main(void)
{ {
int err; int err;

View file

@ -4,3 +4,5 @@
zephyr_sources_ifdef(CONFIG_BT_GATT_DIS dis.c) zephyr_sources_ifdef(CONFIG_BT_GATT_DIS dis.c)
zephyr_sources_ifdef(CONFIG_BT_GATT_BAS bas.c) zephyr_sources_ifdef(CONFIG_BT_GATT_BAS bas.c)
zephyr_sources_ifdef(CONFIG_BT_GATT_HRS hrs.c)

View file

@ -13,6 +13,8 @@ source "subsys/bluetooth/services/Kconfig.dis"
source "subsys/bluetooth/services/Kconfig.bas" source "subsys/bluetooth/services/Kconfig.bas"
source "subsys/bluetooth/services/Kconfig.hrs"
endmenu endmenu
endif #BT_CONN endif #BT_CONN

View file

@ -0,0 +1,28 @@
# Kconfig - Bluetooth GATT Heart Rate service
#
# Copyright (c) 2018 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#
menuconfig BT_GATT_HRS
bool "Enable GATT Heart Rate service"
default n
if BT_GATT_HRS
config BT_GATT_HRS_LOG_LEVEL
int "Heart Rate service log level"
depends on LOG
range 0 4
default 0
help
Sets log level for the Heart Rate service.
Levels are:
0 OFF, do not write
1 ERROR, only write LOG_ERR
2 WARNING, write LOG_WRN in addition to previous level
3 INFO, write LOG_INF in addition to previous levels
4 DEBUG, write LOG_DBG in addition to previous levels
endif #BT_GATT_BAS

View file

@ -12,9 +12,8 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/printk.h>
#include <sys/byteorder.h>
#include <zephyr.h> #include <zephyr.h>
#include <init.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h> #include <bluetooth/hci.h>
@ -22,15 +21,20 @@
#include <bluetooth/uuid.h> #include <bluetooth/uuid.h>
#include <bluetooth/gatt.h> #include <bluetooth/gatt.h>
#define LOG_LEVEL CONFIG_BT_GATT_HRS_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(hrs);
static struct bt_gatt_ccc_cfg hrmc_ccc_cfg[BT_GATT_CCC_MAX] = {}; static struct bt_gatt_ccc_cfg hrmc_ccc_cfg[BT_GATT_CCC_MAX] = {};
static u8_t simulate_hrm;
static u8_t heartrate = 90U;
static u8_t hrs_blsc; static u8_t hrs_blsc;
static void hrmc_ccc_cfg_changed(const struct bt_gatt_attr *attr, static void hrmc_ccc_cfg_changed(const struct bt_gatt_attr *attr, u16_t value)
u16_t value)
{ {
simulate_hrm = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0; ARG_UNUSED(attr);
bool notif_enabled = (value == BT_GATT_CCC_NOTIFY);
LOG_INF("HRS notifications %s", notif_enabled ? "enabled" : "disabled");
} }
static ssize_t read_blsc(struct bt_conn *conn, const struct bt_gatt_attr *attr, static ssize_t read_blsc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
@ -52,27 +56,26 @@ BT_GATT_SERVICE_DEFINE(hrs_svc,
BT_GATT_PERM_NONE, NULL, NULL, NULL), BT_GATT_PERM_NONE, NULL, NULL, NULL),
); );
void hrs_init(u8_t blsc) static int hrs_init(struct device *dev)
{ {
hrs_blsc = blsc; ARG_UNUSED(dev);
hrs_blsc = 0x01;
return 0;
} }
void hrs_notify(void) int bt_gatt_hrs_notify(u16_t heartrate)
{ {
int rc;
static u8_t hrm[2]; static u8_t hrm[2];
/* Heartrate measurements simulation */
if (!simulate_hrm) {
return;
}
heartrate++;
if (heartrate == 160U) {
heartrate = 90U;
}
hrm[0] = 0x06; /* uint8, sensor contact */ hrm[0] = 0x06; /* uint8, sensor contact */
hrm[1] = heartrate; hrm[1] = heartrate;
bt_gatt_notify(NULL, &hrs_svc.attrs[1], &hrm, sizeof(hrm)); rc = bt_gatt_notify(NULL, &hrs_svc.attrs[1], &hrm, sizeof(hrm));
return rc == -ENOTCONN ? 0 : rc;
} }
SYS_INIT(hrs_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

View file

@ -17,7 +17,6 @@ target_sources(app PRIVATE
src/test_empty.c src/test_empty.c
src/test_connect1.c src/test_connect1.c
src/test_connect2.c src/test_connect2.c
../../../../samples/bluetooth/gatt/hrs.c
) )
zephyr_include_directories( zephyr_include_directories(

View file

@ -6,6 +6,7 @@ CONFIG_BT_PRIVACY=y
CONFIG_BT_SMP=y CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y CONFIG_BT_SIGNING=y
CONFIG_BT_GATT_BAS=y CONFIG_BT_GATT_BAS=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y

View file

@ -6,6 +6,7 @@ CONFIG_BT_PRIVACY=y
CONFIG_BT_SMP=y CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y CONFIG_BT_SIGNING=y
CONFIG_BT_GATT_BAS=y CONFIG_BT_GATT_BAS=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y

View file

@ -23,9 +23,9 @@
#include <bluetooth/uuid.h> #include <bluetooth/uuid.h>
#include <bluetooth/gatt.h> #include <bluetooth/gatt.h>
#include <bluetooth/services/bas.h> #include <bluetooth/services/bas.h>
#include <sys/byteorder.h> #include <bluetooth/services/hrs.h>
#include <gatt/hrs.h> #include <sys/byteorder.h>
static struct bt_conn *default_conn; static struct bt_conn *default_conn;
@ -108,8 +108,6 @@ static void bt_ready(int err)
printk("Bluetooth initialized\n"); printk("Bluetooth initialized\n");
hrs_init(0x01);
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) { if (err) {
FAIL("Advertising failed to start (err %d)\n", err); FAIL("Advertising failed to start (err %d)\n", err);
@ -132,6 +130,19 @@ static void bas_notify(void)
bt_gatt_bas_set_battery_level(battery_level); bt_gatt_bas_set_battery_level(battery_level);
} }
static void hrs_notify(void)
{
static u8_t heartrate = 90U;
/* Heartrate measurements simulation */
heartrate++;
if (heartrate == 160U) {
heartrate = 90U;
}
bt_gatt_hrs_notify(heartrate);
}
static void test_con2_main(void) static void test_con2_main(void)
{ {
static int notify_count; static int notify_count;

View file

@ -7,4 +7,3 @@ project(bluetooth_shell)
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth) zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)
target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/main.c)
target_sources_ifdef(CONFIG_BT_CONN app PRIVATE src/hrs.c)

View file

@ -17,6 +17,7 @@ CONFIG_SHELL=y
CONFIG_BT_SHELL=y CONFIG_BT_SHELL=y
CONFIG_BT_DEVICE_NAME="test shell" CONFIG_BT_DEVICE_NAME="test shell"
CONFIG_BT_L2CAP_TX_BUF_COUNT=6 CONFIG_BT_L2CAP_TX_BUF_COUNT=6
CONFIG_BT_GATT_HRS=y
CONFIG_BT_L2CAP_RX_MTU=69 CONFIG_BT_L2CAP_RX_MTU=69
CONFIG_BT_L2CAP_TX_MTU=69 CONFIG_BT_L2CAP_TX_MTU=69

View file

@ -21,6 +21,7 @@ CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_L2CAP_TX_BUF_COUNT=4 CONFIG_BT_L2CAP_TX_BUF_COUNT=4
CONFIG_BT_ID_MAX=2 CONFIG_BT_ID_MAX=2
CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_SETTINGS=y CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y CONFIG_FLASH=y

View file

@ -8,6 +8,7 @@ CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y CONFIG_BT_SIGNING=y
CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_TINYCRYPT_ECC=y CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_SHELL=y CONFIG_SHELL=y

View file

@ -12,6 +12,7 @@ CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y CONFIG_BT_SIGNING=y
CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_TINYCRYPT_ECC=y CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_BT_DEVICE_NAME="test shell" CONFIG_BT_DEVICE_NAME="test shell"

View file

@ -1,2 +0,0 @@
/* Workaround build system bug that will put objects in source dir */
#include "../../../../samples/bluetooth/gatt/hrs.c"

View file

@ -23,11 +23,11 @@
#include <shell/shell.h> #include <shell/shell.h>
#include <gatt/hrs.h> #include <bluetooth/services/hrs.h>
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_GATT_HRS)
static bool hrs_simulate; static bool hrs_simulate;
static int cmd_hrs_simulate(const struct shell *shell, static int cmd_hrs_simulate(const struct shell *shell,
@ -38,7 +38,6 @@ static int cmd_hrs_simulate(const struct shell *shell,
if (!hrs_registered) { if (!hrs_registered) {
shell_print(shell, "Registering HRS Service"); shell_print(shell, "Registering HRS Service");
hrs_init(0x01);
hrs_registered = true; hrs_registered = true;
} }
@ -55,17 +54,17 @@ static int cmd_hrs_simulate(const struct shell *shell,
return 0; return 0;
} }
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_GATT_HRS */
#define HELP_NONE "[none]" #define HELP_NONE "[none]"
#define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>" #define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
SHELL_STATIC_SUBCMD_SET_CREATE(hrs_cmds, SHELL_STATIC_SUBCMD_SET_CREATE(hrs_cmds,
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_GATT_HRS)
SHELL_CMD_ARG(hrs-simulate, NULL, SHELL_CMD_ARG(hrs-simulate, NULL,
"register and simulate Heart Rate Service <value: on, off>", "register and simulate Heart Rate Service <value: on, off>",
cmd_hrs_simulate, 2, 0), cmd_hrs_simulate, 2, 0),
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_GATT_HRS*/
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
); );
@ -79,6 +78,21 @@ static int cmd_hrs(const struct shell *shell, size_t argc, char **argv)
SHELL_CMD_ARG_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands", SHELL_CMD_ARG_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands",
cmd_hrs, 2, 0); cmd_hrs, 2, 0);
#if defined(CONFIG_BT_GATT_HRS)
static void hrs_notify(void)
{
static u8_t heartrate = 90U;
/* Heartrate measurements simulation */
heartrate++;
if (heartrate == 160U) {
heartrate = 90U;
}
bt_gatt_hrs_notify(heartrate);
}
#endif /* CONFIG_BT_GATT_HRS */
void main(void) void main(void)
{ {
printk("Type \"help\" for supported commands."); printk("Type \"help\" for supported commands.");
@ -88,11 +102,11 @@ void main(void)
while (1) { while (1) {
k_sleep(MSEC_PER_SEC); k_sleep(MSEC_PER_SEC);
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_GATT_HRS)
/* Heartrate measurements simulation */ /* Heartrate measurements simulation */
if (hrs_simulate) { if (hrs_simulate) {
hrs_notify(); hrs_notify();
} }
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_GATT_HRS */
} }
} }