1 /** @file
2 * @brief Bluetooth Link Layer functions
3 *
4 */
5
6 /*
7 * Copyright (c) 2017-2018 Nordic Semiconductor ASA
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <zephyr/kernel.h>
15
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/conn.h>
19
20 #include <zephyr/shell/shell.h>
21
22 #include "../controller/util/memq.h"
23 #include "../controller/include/ll.h"
24
25 #include "bt.h"
26
cmd_ll_addr_read(const struct shell * sh,size_t argc,char * argv[])27 int cmd_ll_addr_read(const struct shell *sh, size_t argc, char *argv[])
28 {
29 uint8_t addr_type;
30 const char *str_type;
31 bt_addr_t addr;
32 char str_addr[BT_ADDR_STR_LEN];
33
34 if (argc < 2) {
35 return -EINVAL;
36 }
37
38 str_type = argv[1];
39 if (!strcmp(str_type, "random")) {
40 addr_type = 1U;
41 } else if (!strcmp(str_type, "public")) {
42 addr_type = 0U;
43 } else {
44 return -EINVAL;
45 }
46
47 (void)ll_addr_read(addr_type, addr.val);
48 bt_addr_to_str(&addr, str_addr, sizeof(str_addr));
49
50 shell_print(sh, "Current %s address: %s", str_type, str_addr);
51
52 return 0;
53 }
54
55 #if defined(CONFIG_BT_CTLR_DTM)
56 #include "../controller/ll_sw/ll_test.h"
57
cmd_test_tx(const struct shell * sh,size_t argc,char * argv[])58 int cmd_test_tx(const struct shell *sh, size_t argc, char *argv[])
59 {
60 uint8_t chan, len, type, phy;
61 uint8_t err;
62
63 if (argc < 5) {
64 return -EINVAL;
65 }
66
67 chan = strtoul(argv[1], NULL, 16);
68 len = strtoul(argv[2], NULL, 16);
69 type = strtoul(argv[3], NULL, 16);
70 phy = strtoul(argv[4], NULL, 16);
71
72 err = ll_test_tx(chan, len, type, phy, BT_HCI_LE_TEST_CTE_DISABLED,
73 BT_HCI_LE_TEST_CTE_TYPE_ANY, BT_HCI_LE_TEST_SWITCH_PATTERN_LEN_ANY,
74 NULL, BT_HCI_TX_TEST_POWER_MAX_SET);
75 if (err) {
76 return -EINVAL;
77 }
78
79 shell_print(sh, "test_tx...");
80
81 return 0;
82 }
83
cmd_test_rx(const struct shell * sh,size_t argc,char * argv[])84 int cmd_test_rx(const struct shell *sh, size_t argc, char *argv[])
85 {
86 uint8_t chan, phy, mod_idx;
87 uint8_t err;
88
89 if (argc < 4) {
90 return -EINVAL;
91 }
92
93 chan = strtoul(argv[1], NULL, 16);
94 phy = strtoul(argv[2], NULL, 16);
95 mod_idx = strtoul(argv[3], NULL, 16);
96
97 err = ll_test_rx(chan, phy, mod_idx, BT_HCI_LE_TEST_CTE_DISABLED,
98 BT_HCI_LE_TEST_CTE_TYPE_ANY, BT_HCI_LE_TEST_SLOT_DURATION_ANY,
99 BT_HCI_LE_TEST_SWITCH_PATTERN_LEN_ANY, NULL);
100 if (err) {
101 return -EINVAL;
102 }
103
104 shell_print(sh, "test_rx...");
105
106 return 0;
107 }
108
cmd_test_end(const struct shell * sh,size_t argc,char * argv[])109 int cmd_test_end(const struct shell *sh, size_t argc, char *argv[])
110 {
111 uint16_t num_rx;
112 uint8_t err;
113
114 err = ll_test_end(&num_rx);
115 if (err) {
116 return -EINVAL;
117 }
118
119 shell_print(sh, "num_rx= %u.", num_rx);
120
121 return 0;
122 }
123 #endif /* CONFIG_BT_CTLR_DTM */
124
125 #if defined(CONFIG_BT_CTLR_ADV_EXT)
126 #include "../controller/ll_sw/lll.h"
127
128 #if defined(CONFIG_BT_BROADCASTER)
129 #define OWN_ADDR_TYPE 1
130 #define PEER_ADDR_TYPE 0
131 #define PEER_ADDR NULL
132 #define ADV_CHAN_MAP 0x07
133 #define FILTER_POLICY 0x00
134 #define ADV_TX_PWR NULL
135 #define ADV_SEC_SKIP 0
136 #define ADV_PHY_S 0x01
137 #define ADV_SID 0
138 #define SCAN_REQ_NOT 0
139
140 #define AD_OP 0x03
141 #define AD_FRAG_PREF 0x00
142
143 static const struct bt_data adv_data[] = {
144 BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
145 };
146
cmd_advx(const struct shell * sh,size_t argc,char * argv[])147 int cmd_advx(const struct shell *sh, size_t argc, char *argv[])
148 {
149 uint16_t adv_interval = 0x20;
150 uint16_t handle = 0U;
151 uint16_t evt_prop = 0U;
152 uint8_t adv_type;
153 uint8_t enable;
154 uint8_t ad = 0;
155 uint8_t phy_p;
156 int32_t err;
157
158 if (argc < 2) {
159 return -EINVAL;
160 }
161
162 if (argc > 1) {
163 if (!strcmp(argv[1], "on")) {
164 adv_type = 0x05; /* Adv. Ext. */
165 enable = 1U;
166 } else if (!strcmp(argv[1], "hdcd")) {
167 adv_type = 0x01; /* Directed */
168 adv_interval = 0U; /* High Duty Cycle */
169 phy_p = BIT(0);
170 enable = 1U;
171 goto do_enable;
172 } else if (!strcmp(argv[1], "ldcd")) {
173 adv_type = 0x04; /* Directed */
174 enable = 1U;
175 } else if (!strcmp(argv[1], "off")) {
176 enable = 0U;
177 } else {
178 return -EINVAL;
179 }
180 }
181
182 phy_p = BIT(0);
183
184 if (argc > 2) {
185 if (!strcmp(argv[2], "coded")) {
186 phy_p = BIT(2);
187 } else if (!strcmp(argv[2], "anon")) {
188 evt_prop |= BIT(5);
189 } else if (!strcmp(argv[2], "txp")) {
190 evt_prop |= BIT(6);
191 } else if (!strcmp(argv[2], "ad")) {
192 ad = 1;
193 } else {
194 handle = strtoul(argv[2], NULL, 16);
195 if (handle >= CONFIG_BT_CTLR_ADV_SET) {
196 return -EINVAL;
197 }
198 }
199 }
200
201 if (argc > 3) {
202 if (!strcmp(argv[3], "anon")) {
203 evt_prop |= BIT(5);
204 } else if (!strcmp(argv[3], "txp")) {
205 evt_prop |= BIT(6);
206 } else if (!strcmp(argv[3], "ad")) {
207 ad = 1;
208 } else {
209 handle = strtoul(argv[3], NULL, 16);
210 if (handle >= CONFIG_BT_CTLR_ADV_SET) {
211 return -EINVAL;
212 }
213 }
214 }
215
216 if (argc > 4) {
217 if (!strcmp(argv[4], "txp")) {
218 evt_prop |= BIT(6);
219 } else if (!strcmp(argv[4], "ad")) {
220 ad = 1;
221 } else {
222 handle = strtoul(argv[4], NULL, 16);
223 if (handle >= CONFIG_BT_CTLR_ADV_SET) {
224 return -EINVAL;
225 }
226 }
227 }
228
229 if (argc > 5) {
230 if (!strcmp(argv[5], "ad")) {
231 ad = 1;
232 } else {
233 handle = strtoul(argv[5], NULL, 16);
234 if (handle >= CONFIG_BT_CTLR_ADV_SET) {
235 return -EINVAL;
236 }
237 }
238 }
239
240 if (argc > 6) {
241 handle = strtoul(argv[6], NULL, 16);
242 if (handle >= CONFIG_BT_CTLR_ADV_SET) {
243 return -EINVAL;
244 }
245 }
246
247 if (!enable) {
248 goto disable;
249 }
250
251 do_enable:
252 shell_print(sh, "adv param set...");
253 err = ll_adv_params_set(handle, evt_prop, adv_interval, adv_type,
254 OWN_ADDR_TYPE, PEER_ADDR_TYPE, PEER_ADDR,
255 ADV_CHAN_MAP, FILTER_POLICY, ADV_TX_PWR,
256 phy_p, ADV_SEC_SKIP, ADV_PHY_S, ADV_SID,
257 SCAN_REQ_NOT);
258 if (err) {
259 goto exit;
260 }
261
262 if (ad) {
263 shell_print(sh, "ad data set...");
264 err = ll_adv_aux_ad_data_set(handle, AD_OP, AD_FRAG_PREF,
265 ARRAY_SIZE(adv_data),
266 (void *)adv_data);
267 if (err) {
268 goto exit;
269 }
270 }
271
272 disable:
273 shell_print(sh, "adv enable (%u)...", enable);
274 #if defined(CONFIG_BT_HCI_MESH_EXT)
275 err = ll_adv_enable(handle, enable, 0, 0, 0, 0, 0);
276 #else /* !CONFIG_BT_HCI_MESH_EXT */
277 err = ll_adv_enable(handle, enable, 0, 0);
278 #endif /* !CONFIG_BT_HCI_MESH_EXT */
279 if (err) {
280 goto exit;
281 }
282
283 if (!enable) {
284 err = ll_adv_aux_set_remove(handle);
285 if (err) {
286 goto exit;
287 }
288 }
289
290 exit:
291 shell_print(sh, "done (err= %d).", err);
292
293 return 0;
294 }
295 #endif /* CONFIG_BT_BROADCASTER */
296
297 #if defined(CONFIG_BT_OBSERVER)
298 #define SCAN_INTERVAL 0x0004
299 #define SCAN_WINDOW 0x0004
300 #define SCAN_OWN_ADDR_TYPE 1
301 #define SCAN_FILTER_POLICY 0
302
cmd_scanx(const struct shell * sh,size_t argc,char * argv[])303 int cmd_scanx(const struct shell *sh, size_t argc, char *argv[])
304 {
305 uint8_t type = 0U;
306 uint8_t enable;
307 int32_t err;
308
309 if (argc < 2) {
310 return -EINVAL;
311 }
312
313 if (argc > 1) {
314 if (!strcmp(argv[1], "on")) {
315 enable = 1U;
316 type = 1U;
317 } else if (!strcmp(argv[1], "passive")) {
318 enable = 1U;
319 type = 0U;
320 } else if (!strcmp(argv[1], "off")) {
321 enable = 0U;
322 goto disable;
323 } else {
324 return -EINVAL;
325 }
326 }
327
328 type |= BIT(1);
329
330 if (argc > 2) {
331 if (!strcmp(argv[2], "coded")) {
332 type &= BIT(0);
333 type |= BIT(3);
334 } else {
335 return -EINVAL;
336 }
337 }
338
339 shell_print(sh, "scan param set...");
340 err = ll_scan_params_set(type, SCAN_INTERVAL, SCAN_WINDOW,
341 SCAN_OWN_ADDR_TYPE, SCAN_FILTER_POLICY);
342 if (err) {
343 goto exit;
344 }
345
346 disable:
347 shell_print(sh, "scan enable (%u)...", enable);
348 err = ll_scan_enable(enable, 0, 0);
349 if (err) {
350 goto exit;
351 }
352
353 exit:
354 shell_print(sh, "done (err= %d).", err);
355
356 return err;
357 }
358 #endif /* CONFIG_BT_OBSERVER */
359 #endif /* CONFIG_BT_CTLR_ADV_EXT */
360