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_LE_ADV_OPT_USE_NAME,
36 				     BT_GAP_ADV_FAST_INT_MIN_2,
37 				     BT_GAP_ADV_FAST_INT_MAX_2,
38 				     NULL);
39 
40 static struct bt_le_ext_adv_start_param ext_adv_start_param = {
41 	.timeout = 0,
42 	.num_events = 0,
43 };
44 
45 static struct bt_le_per_adv_param per_adv_param = {
46 	.interval_min = BT_GAP_ADV_SLOW_INT_MIN,
47 	.interval_max = BT_GAP_ADV_SLOW_INT_MAX,
48 	.options = BT_LE_ADV_OPT_USE_TX_POWER,
49 };
50 
51 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
52 static uint8_t ant_patterns[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA };
53 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
54 
55 struct bt_df_adv_cte_tx_param cte_params = { .cte_len = CTE_LEN,
56 					     .cte_count = PER_ADV_EVENT_CTE_COUNT,
57 #if defined(CONFIG_BT_DF_CTE_TX_AOD)
58 					     .cte_type = BT_DF_CTE_TYPE_AOD_2US,
59 					     .num_ant_ids = ARRAY_SIZE(ant_patterns),
60 					     .ant_ids = ant_patterns
61 #else
62 					     .cte_type = BT_DF_CTE_TYPE_AOA,
63 					     .num_ant_ids = 0,
64 					     .ant_ids = NULL
65 #endif /* CONFIG_BT_DF_CTE_TX_AOD */
66 };
67 
adv_sent_cb(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_sent_info * info)68 static void adv_sent_cb(struct bt_le_ext_adv *adv,
69 			struct bt_le_ext_adv_sent_info *info)
70 {
71 	printk("Advertiser[%d] %p sent %d\n", bt_le_ext_adv_get_index(adv),
72 	       adv, info->num_sent);
73 }
74 
main(void)75 int main(void)
76 {
77 	char addr_s[BT_ADDR_LE_STR_LEN];
78 	struct bt_le_oob oob_local;
79 	int err;
80 
81 	printk("Starting Direction Finding periodic advertising Beacon Demo\n");
82 
83 	/* Initialize the Bluetooth Subsystem */
84 	printk("Bluetooth initialization...");
85 	err = bt_enable(NULL);
86 	if (err) {
87 		printk("failed (err %d)\n", err);
88 		return 0;
89 	}
90 	printk("success\n");
91 
92 	printk("Advertising set create...");
93 	err = bt_le_ext_adv_create(&param, &adv_callbacks, &adv_set);
94 	if (err) {
95 		printk("failed (err %d)\n", err);
96 		return 0;
97 	}
98 	printk("success\n");
99 
100 	printk("Update CTE params...");
101 	err = bt_df_set_adv_cte_tx_param(adv_set, &cte_params);
102 	if (err) {
103 		printk("failed (err %d)\n", err);
104 		return 0;
105 	}
106 	printk("success\n");
107 
108 	printk("Periodic advertising params set...");
109 	err = bt_le_per_adv_set_param(adv_set, &per_adv_param);
110 	if (err) {
111 		printk("failed (err %d)\n", err);
112 		return 0;
113 	}
114 	printk("success\n");
115 
116 	printk("Enable CTE...");
117 	err = bt_df_adv_cte_tx_enable(adv_set);
118 	if (err) {
119 		printk("failed (err %d)\n", err);
120 		return 0;
121 	}
122 	printk("success\n");
123 
124 	printk("Periodic advertising enable...");
125 	err = bt_le_per_adv_start(adv_set);
126 	if (err) {
127 		printk("failed (err %d)\n", err);
128 		return 0;
129 	}
130 	printk("success\n");
131 
132 	printk("Extended advertising enable...");
133 	err = bt_le_ext_adv_start(adv_set, &ext_adv_start_param);
134 	if (err) {
135 		printk("failed (err %d)\n", err);
136 		return 0;
137 	}
138 	printk("success\n");
139 
140 	printk("Get extended advertising address...");
141 	err = bt_le_ext_adv_oob_get_local(adv_set, &oob_local);
142 	if (err) {
143 		printk("failed (err %d)\n", err);
144 		return 0;
145 	}
146 	printk("success\n");
147 
148 	bt_addr_le_to_str(&oob_local.addr, addr_s, sizeof(addr_s));
149 
150 	printk("Started extended advertising as %s\n", addr_s);
151 	return 0;
152 }
153