Skip to content

Commit

Permalink
samples: bluetooth: peripheral_ht: Health Thermometer sample
Browse files Browse the repository at this point in the history
Adding Health Thermometer Service sample. Refer to Health Thermometer
Profile Specification for detailed information about the Health
Thermometer Profile.

Signed-off-by: Aaron Tsui <[email protected]>
  • Loading branch information
overheat authored and jhedberg committed Jul 2, 2019
1 parent db167c6 commit b0e58d6
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/bluetooth/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
*/
Expand Down
86 changes: 86 additions & 0 deletions samples/bluetooth/gatt/hts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/** @file
* @brief HTS Service sample
*/

/*
* Copyright (c) 2019 Aaron Tsui <[email protected]>
*
* 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 changes: 20 additions & 0 deletions samples/bluetooth/gatt/hts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @file
* @brief HTS Service sample
*/

/*
* Copyright (c) 2019 Aaron Tsui <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifdef __cplusplus
extern "C" {
#endif

void hts_init(void);
void hts_indicate(void);

#ifdef __cplusplus
}
#endif
15 changes: 15 additions & 0 deletions samples/bluetooth/peripheral_ht/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions samples/bluetooth/peripheral_ht/README.rst
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions samples/bluetooth/peripheral_ht/prj.conf
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions samples/bluetooth/peripheral_ht/sample.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 120 additions & 0 deletions samples/bluetooth/peripheral_ht/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* main.c - Application main entry point */

/*
* Copyright (c) 2019 Aaron Tsui <[email protected]>
*
* 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();
}
}

0 comments on commit b0e58d6

Please sign in to comment.