samples: bluetooth: peripheral_ht: Health Thermometer sample
Adding Health Thermometer Service sample. Refer to Health Thermometer Profile Specification for detailed information about the Health Thermometer Profile. Signed-off-by: Aaron Tsui <aaron.tsui@outlook.com>
This commit is contained in:
parent
db167c606d
commit
b0e58d62ab
8 changed files with 298 additions and 0 deletions
|
@ -91,6 +91,10 @@ struct bt_uuid_128 {
|
|||
* @brief Current Time Service
|
||||
*/
|
||||
#define BT_UUID_CTS BT_UUID_DECLARE_16(0x1805)
|
||||
/** @def BT_UUID_HTS
|
||||
* @brief Health Thermometer Service
|
||||
*/
|
||||
#define BT_UUID_HTS BT_UUID_DECLARE_16(0x1809)
|
||||
/** @def BT_UUID_DIS
|
||||
* @brief Device Information Service
|
||||
*/
|
||||
|
@ -207,6 +211,10 @@ struct bt_uuid_128 {
|
|||
* @brief BAS Characteristic Battery Level
|
||||
*/
|
||||
#define BT_UUID_BAS_BATTERY_LEVEL BT_UUID_DECLARE_16(0x2a19)
|
||||
/** @def BT_UUID_HTS_MEASUREMENT
|
||||
* @brief HTS Characteristic Measurement Value
|
||||
*/
|
||||
#define BT_UUID_HTS_MEASUREMENT BT_UUID_DECLARE_16(0x2a1c)
|
||||
/** @def BT_UUID_HIDS_BOOT_KB_IN_REPORT
|
||||
* @brief HID Characteristic Boot Keyboard Input Report
|
||||
*/
|
||||
|
|
86
samples/bluetooth/gatt/hts.c
Normal file
86
samples/bluetooth/gatt/hts.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/** @file
|
||||
* @brief HTS Service sample
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Aaron Tsui <aaron.tsui@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <misc/printk.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <zephyr.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/uuid.h>
|
||||
#include <bluetooth/gatt.h>
|
||||
|
||||
static struct bt_gatt_ccc_cfg htmc_ccc_cfg[BT_GATT_CCC_MAX] = {};
|
||||
static u8_t simulate_htm;
|
||||
static u8_t indicating;
|
||||
static struct bt_gatt_indicate_params ind_params;
|
||||
|
||||
static u8_t temperature = 20U;
|
||||
|
||||
static void htmc_ccc_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
u16_t value)
|
||||
{
|
||||
simulate_htm = (value == BT_GATT_CCC_INDICATE) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void indicate_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
u8_t err)
|
||||
{
|
||||
printk("Indication %s\n", err != 0U ? "fail" : "success");
|
||||
indicating = 0U;
|
||||
}
|
||||
|
||||
/* Heart Rate Service Declaration */
|
||||
BT_GATT_SERVICE_DEFINE(hts_svc,
|
||||
BT_GATT_PRIMARY_SERVICE(BT_UUID_HTS),
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_HTS_MEASUREMENT, BT_GATT_CHRC_INDICATE,
|
||||
BT_GATT_PERM_NONE, NULL, NULL, NULL),
|
||||
BT_GATT_CCC(htmc_ccc_cfg, htmc_ccc_cfg_changed),
|
||||
/* more optional Characteristics */
|
||||
);
|
||||
|
||||
void hts_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void hts_indicate(void)
|
||||
{
|
||||
/* Temperature measurements simulation */
|
||||
if (simulate_htm) {
|
||||
if (indicating) {
|
||||
return;
|
||||
}
|
||||
|
||||
temperature++;
|
||||
if (temperature == 30U) {
|
||||
temperature = 20U;
|
||||
}
|
||||
|
||||
static u8_t htm[1 + 4];
|
||||
htm[0] = 0x0; /* uint8, temperature in celsius*/
|
||||
/* (IEEE-11073 32-bit FLOAT). */
|
||||
htm[1] = temperature; /* mantissa = temperature*/
|
||||
htm[2] = htm[3] = htm[4] = 0; /* sign = 0, exponent= 0 */
|
||||
|
||||
ind_params.attr = &hts_svc.attrs[2];
|
||||
ind_params.func = indicate_cb;
|
||||
ind_params.data = &htm;
|
||||
ind_params.len = sizeof(htm);
|
||||
|
||||
if (bt_gatt_indicate(NULL, &ind_params) == 0) {
|
||||
indicating = 1U;
|
||||
}
|
||||
}
|
||||
}
|
20
samples/bluetooth/gatt/hts.h
Normal file
20
samples/bluetooth/gatt/hts.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/** @file
|
||||
* @brief HTS Service sample
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Aaron Tsui <aaron.tsui@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void hts_init(void);
|
||||
void hts_indicate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
15
samples/bluetooth/peripheral_ht/CMakeLists.txt
Normal file
15
samples/bluetooth/peripheral_ht/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(peripheral_ht)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE
|
||||
${app_sources}
|
||||
../gatt/hts.c
|
||||
../gatt/bas.c
|
||||
)
|
||||
|
||||
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)
|
26
samples/bluetooth/peripheral_ht/README.rst
Normal file
26
samples/bluetooth/peripheral_ht/README.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
.. _peripheral_ht:
|
||||
|
||||
Bluetooth: Peripheral HT
|
||||
########################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
Similar to the :ref:`Peripheral <ble_peripheral>` sample, except that this
|
||||
application specifically exposes the HT (Health Thermometer) GATT Service. Once a device
|
||||
connects it will generate dummy temperature values.
|
||||
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
* BlueZ running on the host, or
|
||||
* A board with BLE support
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This sample can be found under :zephyr_file:`samples/bluetooth/peripheral_ht` in the
|
||||
Zephyr tree.
|
||||
|
||||
See :ref:`bluetooth samples section <bluetooth-samples>` for details.
|
9
samples/bluetooth/peripheral_ht/prj.conf
Normal file
9
samples/bluetooth/peripheral_ht/prj.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_BT_DEBUG_LOG=y
|
||||
CONFIG_BT_SMP=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_GATT_DIS=y
|
||||
CONFIG_BT_GATT_DIS_PNP=n
|
||||
CONFIG_BT_DEVICE_NAME="Zephyr Health Thermometer"
|
||||
CONFIG_BT_DEVICE_APPEARANCE=768
|
||||
CONFIG_BT_ATT_ENFORCE_FLOW=n
|
14
samples/bluetooth/peripheral_ht/sample.yaml
Normal file
14
samples/bluetooth/peripheral_ht/sample.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
sample:
|
||||
description: TBD
|
||||
name: TBD
|
||||
tests:
|
||||
sample.bluetooth.peripheral_ht:
|
||||
harness: bluetooth
|
||||
platform_whitelist: qemu_cortex_m3 qemu_x86
|
||||
tags: bluetooth
|
||||
sample.bluetooth.peripheral_ht.frdm_kw41z_shield:
|
||||
harness: bluetooth
|
||||
platform_whitelist: mimxrt1020_evk mimxrt1050_evk mimxrt1060_evk frdm_k64f
|
||||
tags: bluetooth
|
||||
extra_args: SHIELD=frdm_kw41z
|
||||
|
120
samples/bluetooth/peripheral_ht/src/main.c
Normal file
120
samples/bluetooth/peripheral_ht/src/main.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* main.c - Application main entry point */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Aaron Tsui <aaron.tsui@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <misc/printk.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <zephyr.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/uuid.h>
|
||||
#include <bluetooth/gatt.h>
|
||||
|
||||
#include <gatt/hts.h>
|
||||
#include <gatt/bas.h>
|
||||
|
||||
struct bt_conn *default_conn;
|
||||
|
||||
static const struct bt_data ad[] = {
|
||||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
|
||||
BT_DATA_BYTES(BT_DATA_UUID16_ALL,
|
||||
0x09, 0x18, /* Health Thermometer Service */
|
||||
0x0a, 0x18, /* Device Information Service */
|
||||
0x0f, 0x18), /* Battery Service */
|
||||
};
|
||||
|
||||
static void connected(struct bt_conn *conn, u8_t err)
|
||||
{
|
||||
if (err) {
|
||||
printk("Connection failed (err %u)\n", err);
|
||||
} else {
|
||||
default_conn = bt_conn_ref(conn);
|
||||
printk("Connected\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void disconnected(struct bt_conn *conn, u8_t reason)
|
||||
{
|
||||
printk("Disconnected (reason %u)\n", reason);
|
||||
|
||||
if (default_conn) {
|
||||
bt_conn_unref(default_conn);
|
||||
default_conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_callbacks = {
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
};
|
||||
|
||||
static void bt_ready(int err)
|
||||
{
|
||||
if (err) {
|
||||
printk("Bluetooth init failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
|
||||
hts_init();
|
||||
bas_init();
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
|
||||
if (err) {
|
||||
printk("Advertising failed to start (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Advertising successfully started\n");
|
||||
}
|
||||
|
||||
static void auth_cancel(struct bt_conn *conn)
|
||||
{
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
printk("Pairing cancelled: %s\n", addr);
|
||||
}
|
||||
|
||||
static struct bt_conn_auth_cb auth_cb_display = {
|
||||
.cancel = auth_cancel,
|
||||
};
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bt_enable(bt_ready);
|
||||
if (err) {
|
||||
printk("Bluetooth init failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
bt_conn_auth_cb_register(&auth_cb_display);
|
||||
|
||||
/* Implement indicate. At the moment there is no suitable way
|
||||
* of starting delayed work so we do it here
|
||||
*/
|
||||
while (1) {
|
||||
k_sleep(MSEC_PER_SEC);
|
||||
|
||||
/* Temperature measurements simulation */
|
||||
hts_indicate();
|
||||
|
||||
/* Battery level simulation */
|
||||
bas_notify();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue