1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  *  SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/types.h>
8 #include <stddef.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <zephyr/sys/printk.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/kernel.h>
14 
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/uuid.h>
19 #include <zephyr/bluetooth/gatt.h>
20 #include <zephyr/bluetooth/services/bas.h>
21 #include <zephyr/bluetooth/services/hrs.h>
22 #include <zephyr/bluetooth/direction.h>
23 
24 #define DF_FEAT_ENABLED BIT64(BT_LE_FEAT_BIT_CONN_CTE_RESP)
25 
26 static const struct bt_data ad[] = {
27 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
28 	BT_DATA_BYTES(BT_DATA_LE_SUPPORTED_FEATURES, BT_LE_SUPP_FEAT_24_ENCODE(DF_FEAT_ENABLED)),
29 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
30 };
31 
32 /* Latency set to zero, to enforce PDU exchange every connection event */
33 #define CONN_LATENCY 0U
34 /* Interval used to run CTE request procedure periodically.
35  * Value is a number of connection events.
36  */
37 #define CTE_REQ_INTERVAL (CONN_LATENCY + 10U)
38 /* Length of CTE in unit of 8 us */
39 #define CTE_LEN (0x14U)
40 
41 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
42 static const uint8_t ant_patterns[] = { 0x2, 0x0, 0x5, 0x6, 0x1, 0x4, 0xC, 0x9, 0xE, 0xD, 0x8 };
43 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
44 
enable_cte_response(struct bt_conn * conn)45 static void enable_cte_response(struct bt_conn *conn)
46 {
47 	int err;
48 
49 	const struct bt_df_conn_cte_tx_param cte_tx_params = {
50 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
51 		.cte_types = BT_DF_CTE_TYPE_ALL,
52 		.num_ant_ids = ARRAY_SIZE(ant_patterns),
53 		.ant_ids = ant_patterns,
54 #else
55 		.cte_types = BT_DF_CTE_TYPE_AOA,
56 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
57 	};
58 
59 	printk("Set CTE transmission params...");
60 	err = bt_df_set_conn_cte_tx_param(conn, &cte_tx_params);
61 	if (err) {
62 		printk("failed (err %d)\n", err);
63 		return;
64 	}
65 	printk("success.\n");
66 
67 	printk("Set CTE response enable...");
68 	err = bt_df_conn_cte_rsp_enable(conn);
69 	if (err) {
70 		printk("failed (err %d).\n", err);
71 		return;
72 	}
73 	printk("success.\n");
74 }
75 
connected(struct bt_conn * conn,uint8_t err)76 static void connected(struct bt_conn *conn, uint8_t err)
77 {
78 	if (err) {
79 		printk("Connection failed err 0x%02x %s\n", err, bt_hci_err_to_str(err));
80 	} else {
81 		printk("Connected\n");
82 	}
83 
84 	enable_cte_response(conn);
85 }
86 
disconnected(struct bt_conn * conn,uint8_t reason)87 static void disconnected(struct bt_conn *conn, uint8_t reason)
88 {
89 	printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));
90 }
91 
92 BT_CONN_CB_DEFINE(conn_callbacks) = {
93 	.connected = connected,
94 	.disconnected = disconnected,
95 };
96 
bt_ready(void)97 static void bt_ready(void)
98 {
99 	int err;
100 
101 	printk("Bluetooth initialized\n");
102 
103 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), NULL, 0);
104 	if (err) {
105 		printk("Advertising failed to start (err %d)\n", err);
106 		return;
107 	}
108 
109 	printk("Advertising successfully started\n");
110 }
111 
main(void)112 int main(void)
113 {
114 	int err;
115 
116 	err = bt_enable(NULL);
117 	if (err) {
118 		printk("Bluetooth init failed (err %d)\n", err);
119 		return 0;
120 	}
121 
122 	bt_ready();
123 	return 0;
124 }
125