1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/types.h>
8 #include <stddef.h>
9 #include <errno.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/printk.h>
12
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/direction.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/sys/util.h>
17
18 /* Length of CTE in unit of 8[us] */
19 #define CTE_LEN (0x14U)
20 /* Number of CTE send in single periodic advertising train */
21 #define PER_ADV_EVENT_CTE_COUNT 5
22
23 static void adv_sent_cb(struct bt_le_ext_adv *adv,
24 struct bt_le_ext_adv_sent_info *info);
25
26 static struct bt_le_ext_adv_cb adv_callbacks = {
27 .sent = adv_sent_cb,
28 };
29
30 static struct bt_le_ext_adv *adv_set;
31
32 static struct bt_le_adv_param param =
33 BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_EXT_ADV |
34 BT_LE_ADV_OPT_USE_IDENTITY,
35 BT_GAP_ADV_FAST_INT_MIN_2,
36 BT_GAP_ADV_FAST_INT_MAX_2,
37 NULL);
38
39 static struct bt_le_ext_adv_start_param ext_adv_start_param = {
40 .timeout = 0,
41 .num_events = 0,
42 };
43
44 static struct bt_le_per_adv_param per_adv_param = {
45 .interval_min = BT_GAP_PER_ADV_SLOW_INT_MIN,
46 .interval_max = BT_GAP_PER_ADV_SLOW_INT_MAX,
47 .options = BT_LE_ADV_OPT_USE_TX_POWER,
48 };
49
50 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
51 static uint8_t ant_patterns[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA };
52 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
53
54 struct bt_df_adv_cte_tx_param cte_params = { .cte_len = CTE_LEN,
55 .cte_count = PER_ADV_EVENT_CTE_COUNT,
56 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
57 .cte_type = BT_DF_CTE_TYPE_AOD_2US,
58 .num_ant_ids = ARRAY_SIZE(ant_patterns),
59 .ant_ids = ant_patterns
60 #else
61 .cte_type = BT_DF_CTE_TYPE_AOA,
62 .num_ant_ids = 0,
63 .ant_ids = NULL
64 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
65 };
66
67 static const struct bt_data ad[] = {
68 BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
69 };
70
adv_sent_cb(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_sent_info * info)71 static void adv_sent_cb(struct bt_le_ext_adv *adv,
72 struct bt_le_ext_adv_sent_info *info)
73 {
74 printk("Advertiser[%d] %p sent %d\n", bt_le_ext_adv_get_index(adv),
75 adv, info->num_sent);
76 }
77
main(void)78 int main(void)
79 {
80 char addr_s[BT_ADDR_LE_STR_LEN];
81 struct bt_le_oob oob_local;
82 int err;
83
84 printk("Starting Direction Finding periodic advertising Beacon Demo\n");
85
86 /* Initialize the Bluetooth Subsystem */
87 printk("Bluetooth initialization...");
88 err = bt_enable(NULL);
89 if (err) {
90 printk("failed (err %d)\n", err);
91 return 0;
92 }
93 printk("success\n");
94
95 printk("Advertising set create...");
96 err = bt_le_ext_adv_create(¶m, &adv_callbacks, &adv_set);
97 if (err) {
98 printk("failed (err %d)\n", err);
99 return 0;
100 }
101 printk("success\n");
102
103 err = bt_le_ext_adv_set_data(adv_set, ad, ARRAY_SIZE(ad), NULL, 0);
104 if (err) {
105 printk("failed (err %d)\n", err);
106 return 0;
107 }
108
109 printk("Update CTE params...");
110 err = bt_df_set_adv_cte_tx_param(adv_set, &cte_params);
111 if (err) {
112 printk("failed (err %d)\n", err);
113 return 0;
114 }
115 printk("success\n");
116
117 printk("Periodic advertising params set...");
118 err = bt_le_per_adv_set_param(adv_set, &per_adv_param);
119 if (err) {
120 printk("failed (err %d)\n", err);
121 return 0;
122 }
123 printk("success\n");
124
125 printk("Enable CTE...");
126 err = bt_df_adv_cte_tx_enable(adv_set);
127 if (err) {
128 printk("failed (err %d)\n", err);
129 return 0;
130 }
131 printk("success\n");
132
133 printk("Periodic advertising enable...");
134 err = bt_le_per_adv_start(adv_set);
135 if (err) {
136 printk("failed (err %d)\n", err);
137 return 0;
138 }
139 printk("success\n");
140
141 printk("Extended advertising enable...");
142 err = bt_le_ext_adv_start(adv_set, &ext_adv_start_param);
143 if (err) {
144 printk("failed (err %d)\n", err);
145 return 0;
146 }
147 printk("success\n");
148
149 printk("Get extended advertising address...");
150 err = bt_le_ext_adv_oob_get_local(adv_set, &oob_local);
151 if (err) {
152 printk("failed (err %d)\n", err);
153 return 0;
154 }
155 printk("success\n");
156
157 bt_addr_le_to_str(&oob_local.addr, addr_s, sizeof(addr_s));
158
159 printk("Started extended advertising as %s\n", addr_s);
160 return 0;
161 }
162