1 /** @file
2 * @brief Interactive Bluetooth LE shell application
3 *
4 * Application allows implement Bluetooth LE functional commands performing
5 * simple diagnostic interaction between LE host stack and LE controller
6 */
7
8 /*
9 * Copyright (c) 2017 Nordic Semiconductor ASA
10 * Copyright (c) 2015-2016 Intel Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 */
14
15 #include <errno.h>
16 #include <zephyr/types.h>
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <zephyr/sys/printk.h>
21 #include <zephyr/sys/byteorder.h>
22 #include <zephyr/kernel.h>
23 #include <zephyr/usb/usb_device.h>
24 #include <zephyr/drivers/uart.h>
25
26 #include <zephyr/shell/shell.h>
27
28 #include <zephyr/bluetooth/hci.h>
29 #include <zephyr/bluetooth/bluetooth.h>
30 #include <zephyr/bluetooth/uuid.h>
31 #include <zephyr/bluetooth/services/hrs.h>
32
33 #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
34
35 #if defined(CONFIG_BT_HRS)
36 static bool hrs_simulate;
37
38 static const struct bt_data ad[] = {
39 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
40 BT_DATA_BYTES(BT_DATA_UUID16_ALL,
41 BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
42 BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
43 BT_UUID_16_ENCODE(BT_UUID_DIS_VAL)),
44 };
45
cmd_hrs_simulate(const struct shell * sh,size_t argc,char * argv[])46 static int cmd_hrs_simulate(const struct shell *sh,
47 size_t argc, char *argv[])
48 {
49 static bool hrs_registered;
50 int err;
51
52 if (!strcmp(argv[1], "on")) {
53 if (!hrs_registered && IS_ENABLED(CONFIG_BT_BROADCASTER)) {
54 shell_print(sh, "Registering HRS Service");
55 hrs_registered = true;
56 err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad,
57 ARRAY_SIZE(ad), NULL, 0);
58 if (err) {
59 shell_error(sh, "Advertising failed to start"
60 " (err %d)\n", err);
61 return -ENOEXEC;
62 }
63
64 printk("Advertising successfully started\n");
65 }
66
67 shell_print(sh, "Start HRS simulation");
68 hrs_simulate = true;
69 } else if (!strcmp(argv[1], "off")) {
70 shell_print(sh, "Stop HRS simulation");
71
72 if (hrs_registered && IS_ENABLED(CONFIG_BT_BROADCASTER)) {
73 bt_le_adv_stop();
74 }
75
76 hrs_simulate = false;
77 } else {
78 shell_print(sh, "Incorrect value: %s", argv[1]);
79 shell_help(sh);
80 return -ENOEXEC;
81 }
82
83 return 0;
84 }
85 #endif /* CONFIG_BT_HRS */
86
87 #define HELP_NONE "[none]"
88 #define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
89
90 SHELL_STATIC_SUBCMD_SET_CREATE(hrs_cmds,
91 #if defined(CONFIG_BT_HRS)
92 SHELL_CMD_ARG(simulate, NULL,
93 "register and simulate Heart Rate Service <value: on, off>",
94 cmd_hrs_simulate, 2, 0),
95 #endif /* CONFIG_BT_HRS*/
96 SHELL_SUBCMD_SET_END
97 );
98
cmd_hrs(const struct shell * sh,size_t argc,char ** argv)99 static int cmd_hrs(const struct shell *sh, size_t argc, char **argv)
100 {
101 shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
102
103 return -ENOEXEC;
104 }
105
106 SHELL_CMD_ARG_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands",
107 cmd_hrs, 2, 0);
108
109 #if defined(CONFIG_BT_HRS)
hrs_notify(void)110 static void hrs_notify(void)
111 {
112 static uint8_t heartrate = 90U;
113
114 /* Heartrate measurements simulation */
115 heartrate++;
116 if (heartrate == 160U) {
117 heartrate = 90U;
118 }
119
120 bt_hrs_notify(heartrate);
121 }
122 #endif /* CONFIG_BT_HRS */
123
main(void)124 int main(void)
125 {
126 #if DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart)
127 const struct device *dev;
128 uint32_t dtr = 0;
129
130 dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart));
131 if (!device_is_ready(dev) || usb_enable(NULL)) {
132 return 0;
133 }
134
135 while (!dtr) {
136 uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
137 k_sleep(K_MSEC(100));
138 }
139 #endif
140
141 printk("Type \"help\" for supported commands.");
142 printk("Before any Bluetooth commands you must `bt init` to initialize"
143 " the stack.\n");
144
145 while (1) {
146 k_sleep(K_SECONDS(1));
147
148 #if defined(CONFIG_BT_HRS)
149 /* Heartrate measurements simulation */
150 if (hrs_simulate) {
151 hrs_notify();
152 }
153 #endif /* CONFIG_BT_HRS */
154 }
155 }
156