1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/sys/printk.h>
11 #include <zephyr/sys/util.h>
12
13 #include <zephyr/shell/shell.h>
14 #include <zephyr/settings/settings.h>
15
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/mesh.h>
18 #include <zephyr/bluetooth/mesh/shell.h>
19
20 /* Private includes for raw Network & Transport layer access */
21 #include "mesh/mesh.h"
22 #include "mesh/net.h"
23 #include "mesh/rpl.h"
24 #include "mesh/transport.h"
25 #include "mesh/foundation.h"
26 #include "mesh/settings.h"
27 #include "mesh/access.h"
28 #include "utils.h"
29 #include "dfu.h"
30 #include "blob.h"
31
32 #define CID_NVAL 0xffff
33 #define COMPANY_ID_LF 0x05F1
34 #define COMPANY_ID_NORDIC_SEMI 0x05F9
35
36 const struct shell *bt_mesh_shell_ctx_shell;
37
38 struct bt_mesh_shell_target bt_mesh_shell_target_ctx = {
39 .dst = BT_MESH_ADDR_UNASSIGNED,
40 };
41
42 #define shell_print_ctx(_ft, ...) \
43 do { \
44 if (bt_mesh_shell_ctx_shell != NULL) { \
45 shell_print(bt_mesh_shell_ctx_shell, _ft, ##__VA_ARGS__); \
46 } \
47 } while (0)
48
49 /* Default net, app & dev key values, unless otherwise specified */
50 const uint8_t bt_mesh_shell_default_key[16] = {
51 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
52 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
53 };
54
55 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE)
56 static uint8_t cur_faults[BT_MESH_SHELL_CUR_FAULTS_MAX];
57 static uint8_t reg_faults[BT_MESH_SHELL_CUR_FAULTS_MAX * 2];
58
get_faults(uint8_t * faults,uint8_t faults_size,uint8_t * dst,uint8_t * count)59 static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
60 {
61 uint8_t i, limit = *count;
62
63 for (i = 0U, *count = 0U; i < faults_size && *count < limit; i++) {
64 if (faults[i]) {
65 *dst++ = faults[i];
66 (*count)++;
67 }
68 }
69 }
70
fault_get_cur(const struct bt_mesh_model * model,uint8_t * test_id,uint16_t * company_id,uint8_t * faults,uint8_t * fault_count)71 static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id,
72 uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
73 {
74 shell_print_ctx("Sending current faults");
75
76 *test_id = 0x00;
77 *company_id = BT_COMP_ID_LF;
78
79 get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);
80
81 return 0;
82 }
83
fault_get_reg(const struct bt_mesh_model * model,uint16_t cid,uint8_t * test_id,uint8_t * faults,uint8_t * fault_count)84 static int fault_get_reg(const struct bt_mesh_model *model, uint16_t cid,
85 uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
86 {
87 if (cid != CONFIG_BT_COMPANY_ID) {
88 shell_print_ctx("Faults requested for unknown Company ID"
89 " 0x%04x", cid);
90 return -EINVAL;
91 }
92
93 shell_print_ctx("Sending registered faults");
94
95 *test_id = 0x00;
96
97 get_faults(reg_faults, sizeof(reg_faults), faults, fault_count);
98
99 return 0;
100 }
101
fault_clear(const struct bt_mesh_model * model,uint16_t cid)102 static int fault_clear(const struct bt_mesh_model *model, uint16_t cid)
103 {
104 if (cid != CONFIG_BT_COMPANY_ID) {
105 return -EINVAL;
106 }
107
108 (void)memset(reg_faults, 0, sizeof(reg_faults));
109
110 return 0;
111 }
112
fault_test(const struct bt_mesh_model * model,uint8_t test_id,uint16_t cid)113 static int fault_test(const struct bt_mesh_model *model, uint8_t test_id,
114 uint16_t cid)
115 {
116 if (cid != CONFIG_BT_COMPANY_ID) {
117 return -EINVAL;
118 }
119
120 if (test_id != 0x00) {
121 return -EINVAL;
122 }
123
124 return 0;
125 }
126
attention_on(const struct bt_mesh_model * model)127 static void attention_on(const struct bt_mesh_model *model)
128 {
129 shell_print_ctx("Attention On");
130 }
131
attention_off(const struct bt_mesh_model * model)132 static void attention_off(const struct bt_mesh_model *model)
133 {
134 shell_print_ctx("Attention Off");
135 }
136
137 static const struct bt_mesh_health_srv_cb health_srv_cb = {
138 .fault_get_cur = fault_get_cur,
139 .fault_get_reg = fault_get_reg,
140 .fault_clear = fault_clear,
141 .fault_test = fault_test,
142 .attn_on = attention_on,
143 .attn_off = attention_off,
144 };
145 #endif /* CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE */
146
147 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
148 static const uint8_t health_tests[] = {
149 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34, 0x15),
150 BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03),
151 };
152
153 const struct bt_mesh_models_metadata_entry health_srv_meta[] = {
154 BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests),
155 BT_MESH_MODELS_METADATA_END,
156 };
157 #endif
158
159 struct bt_mesh_health_srv bt_mesh_shell_health_srv = {
160 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE)
161 .cb = &health_srv_cb,
162 #endif
163 };
164
165 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_CLI)
show_faults(uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)166 static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
167 {
168 size_t i;
169
170 if (!fault_count) {
171 shell_print_ctx("Health Test ID 0x%02x Company ID "
172 "0x%04x: no faults", test_id, cid);
173 return;
174 }
175
176 shell_print_ctx("Health Test ID 0x%02x Company ID 0x%04x Fault "
177 "Count %zu:", test_id, cid, fault_count);
178
179 for (i = 0; i < fault_count; i++) {
180 shell_print_ctx("\t0x%02x", faults[i]);
181 }
182 }
183
health_current_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)184 static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
185 uint8_t test_id, uint16_t cid, uint8_t *faults,
186 size_t fault_count)
187 {
188 shell_print_ctx("Health Current Status from 0x%04x", addr);
189 show_faults(test_id, cid, faults, fault_count);
190 }
191
health_fault_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)192 static void health_fault_status(struct bt_mesh_health_cli *cli, uint16_t addr,
193 uint8_t test_id, uint16_t cid, uint8_t *faults,
194 size_t fault_count)
195 {
196 shell_print_ctx("Health Fault Status from 0x%04x", addr);
197 show_faults(test_id, cid, faults, fault_count);
198 }
199
health_attention_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t attention)200 static void health_attention_status(struct bt_mesh_health_cli *cli,
201 uint16_t addr, uint8_t attention)
202 {
203 shell_print_ctx("Health Attention Status from 0x%04x: %u", addr, attention);
204 }
205
health_period_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t period)206 static void health_period_status(struct bt_mesh_health_cli *cli, uint16_t addr,
207 uint8_t period)
208 {
209 shell_print_ctx("Health Fast Period Divisor Status from 0x%04x: %u", addr, period);
210 }
211
212 struct bt_mesh_health_cli bt_mesh_shell_health_cli = {
213 .current_status = health_current_status,
214 .fault_status = health_fault_status,
215 .attention_status = health_attention_status,
216 .period_status = health_period_status,
217 };
218 #endif /* CONFIG_BT_MESH_SHELL_HEALTH_CLI */
219
cmd_init(const struct shell * sh,size_t argc,char * argv[])220 static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
221 {
222
223 bt_mesh_shell_ctx_shell = sh;
224 shell_print(sh, "Mesh shell initialized");
225
226 #if defined(CONFIG_BT_MESH_SHELL_DFU_CLI) || defined(CONFIG_BT_MESH_SHELL_DFU_SRV)
227 bt_mesh_shell_dfu_cmds_init();
228 #endif
229 #if defined(CONFIG_BT_MESH_SHELL_BLOB_CLI) || defined(CONFIG_BT_MESH_SHELL_BLOB_SRV) || \
230 defined(CONFIG_BT_MESH_SHELL_BLOB_IO_FLASH)
231 bt_mesh_shell_blob_cmds_init();
232 #endif
233
234 if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
235 bt_mesh_prov_enable(BT_MESH_PROV_REMOTE);
236 }
237
238 return 0;
239 }
240
cmd_reset(const struct shell * sh,size_t argc,char * argv[])241 static int cmd_reset(const struct shell *sh, size_t argc, char *argv[])
242 {
243 #if defined(CONFIG_BT_MESH_CDB)
244 bt_mesh_cdb_clear();
245 # endif
246 bt_mesh_reset();
247 shell_print(sh, "Local node reset complete");
248
249 return 0;
250 }
251
252 #if defined(CONFIG_BT_MESH_SHELL_LOW_POWER)
cmd_lpn(const struct shell * sh,size_t argc,char * argv[])253 static int cmd_lpn(const struct shell *sh, size_t argc, char *argv[])
254 {
255 static bool enabled;
256 bool onoff;
257 int err = 0;
258
259 if (argc < 2) {
260 shell_print(sh, "%s", enabled ? "enabled" : "disabled");
261 return 0;
262 }
263
264 onoff = shell_strtobool(argv[1], 0, &err);
265 if (err) {
266 shell_warn(sh, "Unable to parse input string argument");
267 return err;
268 }
269
270 if (onoff) {
271 if (enabled) {
272 shell_print(sh, "LPN already enabled");
273 return 0;
274 }
275
276 err = bt_mesh_lpn_set(true);
277 if (err) {
278 shell_error(sh, "Enabling LPN failed (err %d)", err);
279 } else {
280 enabled = true;
281 }
282 } else {
283 if (!enabled) {
284 shell_print(sh, "LPN already disabled");
285 return 0;
286 }
287
288 err = bt_mesh_lpn_set(false);
289 if (err) {
290 shell_error(sh, "Enabling LPN failed (err %d)", err);
291 } else {
292 enabled = false;
293 }
294 }
295
296 return 0;
297 }
298
cmd_poll(const struct shell * sh,size_t argc,char * argv[])299 static int cmd_poll(const struct shell *sh, size_t argc, char *argv[])
300 {
301 int err;
302
303 err = bt_mesh_lpn_poll();
304 if (err) {
305 shell_error(sh, "Friend Poll failed (err %d)", err);
306 }
307
308 return 0;
309 }
310
lpn_established(uint16_t net_idx,uint16_t friend_addr,uint8_t queue_size,uint8_t recv_win)311 static void lpn_established(uint16_t net_idx, uint16_t friend_addr,
312 uint8_t queue_size, uint8_t recv_win)
313 {
314 shell_print_ctx("Friendship (as LPN) established to "
315 "Friend 0x%04x Queue Size %d Receive Window %d",
316 friend_addr, queue_size, recv_win);
317 }
318
lpn_terminated(uint16_t net_idx,uint16_t friend_addr)319 static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr)
320 {
321 shell_print_ctx("Friendship (as LPN) lost with Friend "
322 "0x%04x", friend_addr);
323 }
324
325 BT_MESH_LPN_CB_DEFINE(lpn_cb) = {
326 .established = lpn_established,
327 .terminated = lpn_terminated,
328 };
329 #endif /* CONFIG_BT_MESH_SHELL_LOW_POWER */
330
331 #if defined(CONFIG_BT_MESH_SHELL_GATT_PROXY)
332 #if defined(CONFIG_BT_MESH_GATT_PROXY)
cmd_ident(const struct shell * sh,size_t argc,char * argv[])333 static int cmd_ident(const struct shell *sh, size_t argc, char *argv[])
334 {
335 int err;
336
337 err = bt_mesh_proxy_identity_enable();
338 if (err) {
339 shell_error(sh, "Failed advertise using Node Identity (err "
340 "%d)", err);
341 }
342
343 return 0;
344 }
345 #endif /* CONFIG_BT_MESH_GATT_PROXY */
346
347 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
cmd_proxy_connect(const struct shell * sh,size_t argc,char * argv[])348 static int cmd_proxy_connect(const struct shell *sh, size_t argc,
349 char *argv[])
350 {
351 uint16_t net_idx;
352 int err = 0;
353
354 net_idx = shell_strtoul(argv[1], 0, &err);
355 if (err) {
356 shell_warn(sh, "Unable to parse input string argument");
357 return err;
358 }
359
360 err = bt_mesh_proxy_connect(net_idx);
361 if (err) {
362 shell_error(sh, "Proxy connect failed (err %d)", err);
363 }
364
365 return 0;
366 }
367
cmd_proxy_disconnect(const struct shell * sh,size_t argc,char * argv[])368 static int cmd_proxy_disconnect(const struct shell *sh, size_t argc,
369 char *argv[])
370 {
371 uint16_t net_idx;
372 int err = 0;
373
374 net_idx = shell_strtoul(argv[1], 0, &err);
375 if (err) {
376 shell_warn(sh, "Unable to parse input string argument");
377 return err;
378 }
379
380 err = bt_mesh_proxy_disconnect(net_idx);
381 if (err) {
382 shell_error(sh, "Proxy disconnect failed (err %d)", err);
383 }
384
385 return 0;
386 }
387 #endif /* CONFIG_BT_MESH_PROXY_CLIENT */
388
389 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
cmd_proxy_solicit(const struct shell * sh,size_t argc,char * argv[])390 static int cmd_proxy_solicit(const struct shell *sh, size_t argc,
391 char *argv[])
392 {
393 uint16_t net_idx;
394 int err = 0;
395
396 net_idx = shell_strtoul(argv[1], 0, &err);
397 if (err) {
398 shell_warn(sh, "Unable to parse input string argument");
399 return err;
400 }
401
402 err = bt_mesh_proxy_solicit(net_idx);
403 if (err) {
404 shell_error(sh, "Failed to advertise solicitation PDU (err %d)",
405 err);
406 }
407
408 return err;
409 }
410 #endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */
411 #endif /* CONFIG_BT_MESH_SHELL_GATT_PROXY */
412
413 #if defined(CONFIG_BT_MESH_SHELL_PROV)
cmd_input_num(const struct shell * sh,size_t argc,char * argv[])414 static int cmd_input_num(const struct shell *sh, size_t argc, char *argv[])
415 {
416 int err = 0;
417 uint32_t val;
418
419 val = shell_strtoul(argv[1], 10, &err);
420 if (err) {
421 shell_warn(sh, "Unable to parse input string argument");
422 return err;
423 }
424
425 err = bt_mesh_input_number(val);
426 if (err) {
427 shell_error(sh, "Numeric input failed (err %d)", err);
428 }
429
430 return 0;
431 }
432
cmd_input_str(const struct shell * sh,size_t argc,char * argv[])433 static int cmd_input_str(const struct shell *sh, size_t argc, char *argv[])
434 {
435 int err = bt_mesh_input_string(argv[1]);
436
437 if (err) {
438 shell_error(sh, "String input failed (err %d)", err);
439 }
440
441 return 0;
442 }
443
bearer2str(bt_mesh_prov_bearer_t bearer)444 static const char *bearer2str(bt_mesh_prov_bearer_t bearer)
445 {
446 switch (bearer) {
447 case BT_MESH_PROV_ADV:
448 return "PB-ADV";
449 case BT_MESH_PROV_GATT:
450 return "PB-GATT";
451 case BT_MESH_PROV_REMOTE:
452 return "PB-REMOTE";
453 default:
454 return "unknown";
455 }
456 }
457
458 #if defined(CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE)
459 static uint8_t dev_uuid[16] = { 0xdd, 0xdd };
460
prov_complete(uint16_t net_idx,uint16_t addr)461 static void prov_complete(uint16_t net_idx, uint16_t addr)
462 {
463
464 shell_print_ctx("Local node provisioned, net_idx 0x%04x address "
465 "0x%04x", net_idx, addr);
466
467 bt_mesh_shell_target_ctx.net_idx = net_idx,
468 bt_mesh_shell_target_ctx.dst = addr;
469 }
470
reprovisioned(uint16_t addr)471 static void reprovisioned(uint16_t addr)
472 {
473 shell_print(bt_mesh_shell_ctx_shell, "Local node re-provisioned, new address 0x%04x",
474 addr);
475
476 if (bt_mesh_shell_target_ctx.dst == bt_mesh_primary_addr()) {
477 bt_mesh_shell_target_ctx.dst = addr;
478 }
479 }
480
prov_node_added(uint16_t net_idx,uint8_t uuid[16],uint16_t addr,uint8_t num_elem)481 static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
482 uint8_t num_elem)
483 {
484 shell_print_ctx("Node provisioned, net_idx 0x%04x address "
485 "0x%04x elements %d", net_idx, addr, num_elem);
486
487 bt_mesh_shell_target_ctx.net_idx = net_idx,
488 bt_mesh_shell_target_ctx.dst = addr;
489 }
490
491 #if defined(CONFIG_BT_MESH_PROVISIONER)
492 static const char * const output_meth_string[] = {
493 "Blink",
494 "Beep",
495 "Vibrate",
496 "Display Number",
497 "Display String",
498 };
499
500 static const char *const input_meth_string[] = {
501 "Push",
502 "Twist",
503 "Enter Number",
504 "Enter String",
505 };
506
capabilities(const struct bt_mesh_dev_capabilities * cap)507 static void capabilities(const struct bt_mesh_dev_capabilities *cap)
508 {
509 shell_print_ctx("Provisionee capabilities:");
510 shell_print_ctx("\tStatic OOB is %ssupported", cap->oob_type & 1 ? "" : "not ");
511
512 shell_print_ctx("\tAvailable output actions (%d bytes max):%s", cap->output_size,
513 cap->output_actions ? "" : "\n\t\tNone");
514 for (int i = 0; i < ARRAY_SIZE(output_meth_string); i++) {
515 if (cap->output_actions & BIT(i)) {
516 shell_print_ctx("\t\t%s", output_meth_string[i]);
517 }
518 }
519
520 shell_print_ctx("\tAvailable input actions (%d bytes max):%s", cap->input_size,
521 cap->input_actions ? "" : "\n\t\tNone");
522 for (int i = 0; i < ARRAY_SIZE(input_meth_string); i++) {
523 if (cap->input_actions & BIT(i)) {
524 shell_print_ctx("\t\t%s", input_meth_string[i]);
525 }
526 }
527 }
528 #endif
529
prov_input_complete(void)530 static void prov_input_complete(void)
531 {
532 shell_print_ctx("Input complete");
533 }
534
prov_reset(void)535 static void prov_reset(void)
536 {
537 shell_print_ctx("The local node has been reset and needs "
538 "reprovisioning");
539 }
540
output_number(bt_mesh_output_action_t action,uint32_t number)541 static int output_number(bt_mesh_output_action_t action, uint32_t number)
542 {
543 switch (action) {
544 case BT_MESH_BLINK:
545 shell_print_ctx("OOB blink Number: %u", number);
546 break;
547 case BT_MESH_BEEP:
548 shell_print_ctx("OOB beep Number: %u", number);
549 break;
550 case BT_MESH_VIBRATE:
551 shell_print_ctx("OOB vibrate Number: %u", number);
552 break;
553 case BT_MESH_DISPLAY_NUMBER:
554 shell_print_ctx("OOB display Number: %u", number);
555 break;
556 default:
557 if (bt_mesh_shell_ctx_shell != NULL) {
558 shell_error(bt_mesh_shell_ctx_shell,
559 "Unknown Output action %u (number %u) requested!",
560 action, number);
561 }
562 return -EINVAL;
563 }
564
565 return 0;
566 }
567
output_string(const char * str)568 static int output_string(const char *str)
569 {
570 shell_print_ctx("OOB String: %s", str);
571 return 0;
572 }
573
input(bt_mesh_input_action_t act,uint8_t size)574 static int input(bt_mesh_input_action_t act, uint8_t size)
575 {
576
577 switch (act) {
578 case BT_MESH_ENTER_NUMBER:
579 shell_print_ctx("Enter a number (max %u digits) with: Input-num <num>", size);
580 break;
581 case BT_MESH_ENTER_STRING:
582 shell_print_ctx("Enter a string (max %u chars) with: Input-str <str>", size);
583 break;
584 case BT_MESH_TWIST:
585 shell_print_ctx("\"Twist\" a number (max %u digits) with: Input-num <num>", size);
586 break;
587 case BT_MESH_PUSH:
588 shell_print_ctx("\"Push\" a number (max %u digits) with: Input-num <num>", size);
589 break;
590 default:
591 if (bt_mesh_shell_ctx_shell != NULL) {
592 shell_error(bt_mesh_shell_ctx_shell,
593 "Unknown Input action %u (size %u) requested!", act, size);
594 }
595 return -EINVAL;
596 }
597
598 return 0;
599 }
600
link_open(bt_mesh_prov_bearer_t bearer)601 static void link_open(bt_mesh_prov_bearer_t bearer)
602 {
603 shell_print_ctx("Provisioning link opened on %s", bearer2str(bearer));
604 }
605
link_close(bt_mesh_prov_bearer_t bearer)606 static void link_close(bt_mesh_prov_bearer_t bearer)
607 {
608 shell_print_ctx("Provisioning link closed on %s", bearer2str(bearer));
609 }
610
611 static uint8_t static_val[32];
612
613 struct bt_mesh_prov bt_mesh_shell_prov = {
614 .uuid = dev_uuid,
615 .link_open = link_open,
616 .link_close = link_close,
617 .complete = prov_complete,
618 .reprovisioned = reprovisioned,
619 .node_added = prov_node_added,
620 .reset = prov_reset,
621 .static_val = NULL,
622 .static_val_len = 0,
623 .output_size = 6,
624 .output_actions = (BT_MESH_BLINK | BT_MESH_BEEP | BT_MESH_VIBRATE | BT_MESH_DISPLAY_NUMBER |
625 BT_MESH_DISPLAY_STRING),
626 .output_number = output_number,
627 .output_string = output_string,
628 .input_size = 6,
629 .input_actions =
630 (BT_MESH_ENTER_NUMBER | BT_MESH_ENTER_STRING | BT_MESH_TWIST | BT_MESH_PUSH),
631 .input = input,
632 .input_complete = prov_input_complete,
633 #if defined(CONFIG_BT_MESH_PROVISIONER)
634 .capabilities = capabilities
635 #endif
636 };
637
cmd_static_oob(const struct shell * sh,size_t argc,char * argv[])638 static int cmd_static_oob(const struct shell *sh, size_t argc, char *argv[])
639 {
640 if (argc < 2) {
641 bt_mesh_shell_prov.static_val = NULL;
642 bt_mesh_shell_prov.static_val_len = 0U;
643 } else {
644 bt_mesh_shell_prov.static_val_len = hex2bin(argv[1], strlen(argv[1]),
645 static_val, 32);
646 if (bt_mesh_shell_prov.static_val_len) {
647 bt_mesh_shell_prov.static_val = static_val;
648 } else {
649 bt_mesh_shell_prov.static_val = NULL;
650 }
651 }
652
653 if (bt_mesh_shell_prov.static_val) {
654 shell_print(sh, "Static OOB value set (length %u)",
655 bt_mesh_shell_prov.static_val_len);
656 } else {
657 shell_print(sh, "Static OOB value cleared");
658 }
659
660 return 0;
661 }
662
cmd_uuid(const struct shell * sh,size_t argc,char * argv[])663 static int cmd_uuid(const struct shell *sh, size_t argc, char *argv[])
664 {
665 uint8_t uuid[16];
666 size_t len;
667
668 if (argc < 2) {
669 char uuid_hex_str[32 + 1];
670
671 bin2hex(dev_uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
672
673 shell_print_ctx("Device UUID: %s", uuid_hex_str);
674 return 0;
675 }
676
677 len = hex2bin(argv[1], strlen(argv[1]), uuid, sizeof(uuid));
678 if (len < 1) {
679 return -EINVAL;
680 }
681
682 memcpy(dev_uuid, uuid, len);
683 (void)memset(dev_uuid + len, 0, sizeof(dev_uuid) - len);
684
685 shell_print(sh, "Device UUID set");
686
687 return 0;
688 }
689
print_unprovisioned_beacon(uint8_t uuid[16],bt_mesh_prov_oob_info_t oob_info,uint32_t * uri_hash)690 static void print_unprovisioned_beacon(uint8_t uuid[16],
691 bt_mesh_prov_oob_info_t oob_info,
692 uint32_t *uri_hash)
693 {
694 char uuid_hex_str[32 + 1];
695
696 bin2hex(uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
697
698 shell_print_ctx("PB-ADV UUID %s, OOB Info 0x%04x, URI Hash 0x%x",
699 uuid_hex_str, oob_info,
700 (uri_hash == NULL ? 0 : *uri_hash));
701 }
702
703 #if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
pb_gatt_unprovisioned(uint8_t uuid[16],bt_mesh_prov_oob_info_t oob_info)704 static void pb_gatt_unprovisioned(uint8_t uuid[16],
705 bt_mesh_prov_oob_info_t oob_info)
706 {
707 char uuid_hex_str[32 + 1];
708
709 bin2hex(uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
710
711 shell_print_ctx("PB-GATT UUID %s, OOB Info 0x%04x", uuid_hex_str, oob_info);
712 }
713 #endif
714
cmd_beacon_listen(const struct shell * sh,size_t argc,char * argv[])715 static int cmd_beacon_listen(const struct shell *sh, size_t argc,
716 char *argv[])
717 {
718 int err = 0;
719 bool val = shell_strtobool(argv[1], 0, &err);
720
721 if (err) {
722 shell_warn(sh, "Unable to parse input string argument");
723 return err;
724 }
725
726 if (!bt_mesh_is_provisioned()) {
727 shell_error(sh, "Not yet provisioned");
728 return -EINVAL;
729 }
730
731 if (val) {
732 bt_mesh_shell_prov.unprovisioned_beacon = print_unprovisioned_beacon;
733 #if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
734 bt_mesh_shell_prov.unprovisioned_beacon_gatt = pb_gatt_unprovisioned;
735 #endif
736 } else {
737 bt_mesh_shell_prov.unprovisioned_beacon = NULL;
738 bt_mesh_shell_prov.unprovisioned_beacon_gatt = NULL;
739 }
740
741 return 0;
742 }
743 #endif /* CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE */
744
745 #if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
cmd_provision_gatt(const struct shell * sh,size_t argc,char * argv[])746 static int cmd_provision_gatt(const struct shell *sh, size_t argc,
747 char *argv[])
748 {
749 static uint8_t uuid[16];
750 uint8_t attention_duration;
751 uint16_t net_idx;
752 uint16_t addr;
753 size_t len;
754 int err = 0;
755
756 len = hex2bin(argv[1], strlen(argv[1]), uuid, sizeof(uuid));
757 (void)memset(uuid + len, 0, sizeof(uuid) - len);
758
759 net_idx = shell_strtoul(argv[2], 0, &err);
760 addr = shell_strtoul(argv[3], 0, &err);
761 attention_duration = shell_strtoul(argv[4], 0, &err);
762 if (err) {
763 shell_warn(sh, "Unable to parse input string argument");
764 return err;
765 }
766
767 err = bt_mesh_provision_gatt(uuid, net_idx, addr, attention_duration);
768 if (err) {
769 shell_error(sh, "Provisioning failed (err %d)", err);
770 }
771
772 return 0;
773 }
774 #endif /* CONFIG_BT_MESH_PB_GATT_CLIENT */
775
776 #if defined(CONFIG_BT_MESH_PROVISIONEE)
cmd_pb(bt_mesh_prov_bearer_t bearer,const struct shell * sh,size_t argc,char * argv[])777 static int cmd_pb(bt_mesh_prov_bearer_t bearer, const struct shell *sh,
778 size_t argc, char *argv[])
779 {
780 int err = 0;
781 bool onoff;
782
783 if (argc < 2) {
784 return -EINVAL;
785 }
786
787 onoff = shell_strtobool(argv[1], 0, &err);
788 if (err) {
789 shell_warn(sh, "Unable to parse input string argument");
790 return err;
791 }
792
793 if (onoff) {
794 err = bt_mesh_prov_enable(bearer);
795 if (err) {
796 shell_error(sh, "Failed to enable %s (err %d)",
797 bearer2str(bearer), err);
798 } else {
799 shell_print(sh, "%s enabled", bearer2str(bearer));
800 }
801 } else {
802 err = bt_mesh_prov_disable(bearer);
803 if (err) {
804 shell_error(sh, "Failed to disable %s (err %d)",
805 bearer2str(bearer), err);
806 } else {
807 shell_print(sh, "%s disabled", bearer2str(bearer));
808 }
809 }
810
811 return 0;
812 }
813
814 #if defined(CONFIG_BT_MESH_PB_ADV)
cmd_pb_adv(const struct shell * sh,size_t argc,char * argv[])815 static int cmd_pb_adv(const struct shell *sh, size_t argc, char *argv[])
816 {
817 return cmd_pb(BT_MESH_PROV_ADV, sh, argc, argv);
818 }
819 #endif /* CONFIG_BT_MESH_PB_ADV */
820
821 #if defined(CONFIG_BT_MESH_PB_GATT)
cmd_pb_gatt(const struct shell * sh,size_t argc,char * argv[])822 static int cmd_pb_gatt(const struct shell *sh, size_t argc, char *argv[])
823 {
824 return cmd_pb(BT_MESH_PROV_GATT, sh, argc, argv);
825 }
826 #endif /* CONFIG_BT_MESH_PB_GATT */
827 #endif /* CONFIG_BT_MESH_PROVISIONEE */
828
829 #if defined(CONFIG_BT_MESH_PROVISIONER)
cmd_remote_pub_key_set(const struct shell * sh,size_t argc,char * argv[])830 static int cmd_remote_pub_key_set(const struct shell *sh, size_t argc, char *argv[])
831 {
832 size_t len;
833 uint8_t pub_key[64];
834 int err = 0;
835
836 len = hex2bin(argv[1], strlen(argv[1]), pub_key, sizeof(pub_key));
837 if (len < 1) {
838 shell_warn(sh, "Unable to parse input string argument");
839 return -EINVAL;
840 }
841
842 err = bt_mesh_prov_remote_pub_key_set(pub_key);
843
844 if (err) {
845 shell_error(sh, "Setting remote pub key failed (err %d)", err);
846 }
847
848 return 0;
849 }
850
cmd_auth_method_set_input(const struct shell * sh,size_t argc,char * argv[])851 static int cmd_auth_method_set_input(const struct shell *sh, size_t argc, char *argv[])
852 {
853 int err = 0;
854 bt_mesh_input_action_t action = shell_strtoul(argv[1], 10, &err);
855 uint8_t size = shell_strtoul(argv[2], 10, &err);
856
857 if (err) {
858 shell_warn(sh, "Unable to parse input string argument");
859 return err;
860 }
861
862 err = bt_mesh_auth_method_set_input(action, size);
863 if (err) {
864 shell_error(sh, "Setting input OOB authentication action failed (err %d)", err);
865 }
866
867 return 0;
868 }
869
cmd_auth_method_set_output(const struct shell * sh,size_t argc,char * argv[])870 static int cmd_auth_method_set_output(const struct shell *sh, size_t argc, char *argv[])
871 {
872 int err = 0;
873 bt_mesh_output_action_t action = shell_strtoul(argv[1], 10, &err);
874 uint8_t size = shell_strtoul(argv[2], 10, &err);
875
876 if (err) {
877 shell_warn(sh, "Unable to parse input string argument");
878 return err;
879 }
880
881 err = bt_mesh_auth_method_set_output(action, size);
882 if (err) {
883 shell_error(sh, "Setting output OOB authentication action failed (err %d)", err);
884 }
885 return 0;
886 }
887
cmd_auth_method_set_static(const struct shell * sh,size_t argc,char * argv[])888 static int cmd_auth_method_set_static(const struct shell *sh, size_t argc, char *argv[])
889 {
890 size_t len;
891 uint8_t static_oob_auth[32];
892 int err = 0;
893
894 len = hex2bin(argv[1], strlen(argv[1]), static_oob_auth, sizeof(static_oob_auth));
895 if (len < 1) {
896 shell_warn(sh, "Unable to parse input string argument");
897 return -EINVAL;
898 }
899
900 err = bt_mesh_auth_method_set_static(static_oob_auth, len);
901 if (err) {
902 shell_error(sh, "Setting static OOB authentication failed (err %d)", err);
903 }
904 return 0;
905 }
906
cmd_auth_method_set_none(const struct shell * sh,size_t argc,char * argv[])907 static int cmd_auth_method_set_none(const struct shell *sh, size_t argc, char *argv[])
908 {
909 int err = bt_mesh_auth_method_set_none();
910
911 if (err) {
912 shell_error(sh, "Disabling authentication failed (err %d)", err);
913 }
914 return 0;
915 }
916
cmd_provision_adv(const struct shell * sh,size_t argc,char * argv[])917 static int cmd_provision_adv(const struct shell *sh, size_t argc,
918 char *argv[])
919 {
920 uint8_t uuid[16];
921 uint8_t attention_duration;
922 uint16_t net_idx;
923 uint16_t addr;
924 size_t len;
925 int err = 0;
926
927 len = hex2bin(argv[1], strlen(argv[1]), uuid, sizeof(uuid));
928 (void)memset(uuid + len, 0, sizeof(uuid) - len);
929
930 net_idx = shell_strtoul(argv[2], 0, &err);
931 addr = shell_strtoul(argv[3], 0, &err);
932 attention_duration = shell_strtoul(argv[4], 0, &err);
933 if (err) {
934 shell_warn(sh, "Unable to parse input string argument");
935 return err;
936 }
937
938 err = bt_mesh_provision_adv(uuid, net_idx, addr, attention_duration);
939 if (err) {
940 shell_error(sh, "Provisioning failed (err %d)", err);
941 }
942
943 return 0;
944 }
945 #endif /* CONFIG_BT_MESH_PROVISIONER */
946
cmd_provision_local(const struct shell * sh,size_t argc,char * argv[])947 static int cmd_provision_local(const struct shell *sh, size_t argc, char *argv[])
948 {
949 uint8_t net_key[16];
950 uint16_t net_idx, addr;
951 uint32_t iv_index;
952 int err = 0;
953
954 net_idx = shell_strtoul(argv[1], 0, &err);
955 addr = shell_strtoul(argv[2], 0, &err);
956
957 if (argc > 3) {
958 iv_index = shell_strtoul(argv[3], 0, &err);
959 } else {
960 iv_index = 0U;
961 }
962
963 if (err) {
964 shell_warn(sh, "Unable to parse input string argument");
965 return err;
966 }
967
968 memcpy(net_key, bt_mesh_shell_default_key, sizeof(net_key));
969
970 if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
971 struct bt_mesh_cdb_subnet *sub;
972
973 sub = bt_mesh_cdb_subnet_get(net_idx);
974 if (!sub) {
975 shell_error(sh, "No cdb entry for subnet 0x%03x", net_idx);
976 return 0;
977 }
978
979 if (bt_mesh_cdb_subnet_key_export(sub, SUBNET_KEY_TX_IDX(sub), net_key)) {
980 shell_error(sh, "Unable to export key for subnet 0x%03x", net_idx);
981 return 0;
982 }
983 }
984
985 err = bt_mesh_provision(net_key, net_idx, 0, iv_index, addr, bt_mesh_shell_default_key);
986 if (err) {
987 shell_error(sh, "Provisioning failed (err %d)", err);
988 }
989
990 return 0;
991 }
992
cmd_comp_change(const struct shell * sh,size_t argc,char * argv[])993 static int cmd_comp_change(const struct shell *sh, size_t argc, char *argv[])
994 {
995 bt_mesh_comp_change_prepare();
996 return 0;
997 }
998 #endif /* CONFIG_BT_MESH_SHELL_PROV */
999
1000 #if defined(CONFIG_BT_MESH_SHELL_TEST)
cmd_net_send(const struct shell * sh,size_t argc,char * argv[])1001 static int cmd_net_send(const struct shell *sh, size_t argc, char *argv[])
1002 {
1003 NET_BUF_SIMPLE_DEFINE(msg, 32);
1004
1005 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT(bt_mesh_shell_target_ctx.net_idx,
1006 bt_mesh_shell_target_ctx.app_idx,
1007 bt_mesh_shell_target_ctx.dst,
1008 BT_MESH_TTL_DEFAULT);
1009 struct bt_mesh_net_tx tx = {
1010 .ctx = &ctx,
1011 .src = bt_mesh_primary_addr(),
1012 };
1013
1014 size_t len;
1015 int err;
1016
1017 len = hex2bin(argv[1], strlen(argv[1]),
1018 msg.data, net_buf_simple_tailroom(&msg) - 4);
1019 net_buf_simple_add(&msg, len);
1020
1021 err = bt_mesh_trans_send(&tx, &msg, NULL, NULL);
1022 if (err) {
1023 shell_error(sh, "Failed to send (err %d)", err);
1024 }
1025
1026 return 0;
1027 }
1028
1029 #if defined(CONFIG_BT_MESH_IV_UPDATE_TEST)
cmd_iv_update(const struct shell * sh,size_t argc,char * argv[])1030 static int cmd_iv_update(const struct shell *sh, size_t argc, char *argv[])
1031 {
1032 if (bt_mesh_iv_update()) {
1033 shell_print(sh, "Transitioned to IV Update In Progress "
1034 "state");
1035 } else {
1036 shell_print(sh, "Transitioned to IV Update Normal state");
1037 }
1038
1039 shell_print(sh, "IV Index is 0x%08x", bt_mesh.iv_index);
1040
1041 return 0;
1042 }
1043
cmd_iv_update_test(const struct shell * sh,size_t argc,char * argv[])1044 static int cmd_iv_update_test(const struct shell *sh, size_t argc,
1045 char *argv[])
1046 {
1047 int err = 0;
1048 bool enable;
1049
1050 enable = shell_strtobool(argv[1], 0, &err);
1051 if (err) {
1052 shell_warn(sh, "Unable to parse input string argument");
1053 return err;
1054 }
1055
1056 if (enable) {
1057 shell_print(sh, "Enabling IV Update test mode");
1058 } else {
1059 shell_print(sh, "Disabling IV Update test mode");
1060 }
1061
1062 bt_mesh_iv_update_test(enable);
1063
1064 return 0;
1065 }
1066 #endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */
1067
cmd_rpl_clear(const struct shell * sh,size_t argc,char * argv[])1068 static int cmd_rpl_clear(const struct shell *sh, size_t argc, char *argv[])
1069 {
1070 bt_mesh_rpl_clear();
1071 return 0;
1072 }
1073
1074 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE)
primary_element(void)1075 static const struct bt_mesh_elem *primary_element(void)
1076 {
1077 const struct bt_mesh_comp *comp = bt_mesh_comp_get();
1078
1079 if (comp) {
1080 return &comp->elem[0];
1081 }
1082
1083 return NULL;
1084 }
1085
cmd_add_fault(const struct shell * sh,size_t argc,char * argv[])1086 static int cmd_add_fault(const struct shell *sh, size_t argc, char *argv[])
1087 {
1088 uint8_t fault_id;
1089 uint8_t i;
1090 const struct bt_mesh_elem *elem;
1091 int err = 0;
1092
1093 elem = primary_element();
1094 if (elem == NULL) {
1095 shell_print(sh, "Element not found!");
1096 return -EINVAL;
1097 }
1098
1099 fault_id = shell_strtoul(argv[1], 0, &err);
1100 if (err) {
1101 shell_warn(sh, "Unable to parse input string argument");
1102 return err;
1103 }
1104
1105 if (!fault_id) {
1106 shell_print(sh, "The Fault ID must be non-zero!");
1107 return -EINVAL;
1108 }
1109
1110 for (i = 0U; i < sizeof(cur_faults); i++) {
1111 if (!cur_faults[i]) {
1112 cur_faults[i] = fault_id;
1113 break;
1114 }
1115 }
1116
1117 if (i == sizeof(cur_faults)) {
1118 shell_print(sh, "Fault array is full. Use \"del-fault\" to "
1119 "clear it");
1120 return 0;
1121 }
1122
1123 for (i = 0U; i < sizeof(reg_faults); i++) {
1124 if (!reg_faults[i]) {
1125 reg_faults[i] = fault_id;
1126 break;
1127 }
1128 }
1129
1130 if (i == sizeof(reg_faults)) {
1131 shell_print(sh, "No space to store more registered faults");
1132 }
1133
1134 bt_mesh_health_srv_fault_update(elem);
1135
1136 return 0;
1137 }
1138
cmd_del_fault(const struct shell * sh,size_t argc,char * argv[])1139 static int cmd_del_fault(const struct shell *sh, size_t argc, char *argv[])
1140 {
1141 uint8_t fault_id;
1142 uint8_t i;
1143 const struct bt_mesh_elem *elem;
1144 int err = 0;
1145
1146 elem = primary_element();
1147 if (elem == NULL) {
1148 shell_print(sh, "Element not found!");
1149 return -EINVAL;
1150 }
1151
1152 if (argc < 2) {
1153 (void)memset(cur_faults, 0, sizeof(cur_faults));
1154 shell_print(sh, "All current faults cleared");
1155 bt_mesh_health_srv_fault_update(elem);
1156 return 0;
1157 }
1158
1159 fault_id = shell_strtoul(argv[1], 0, &err);
1160 if (err) {
1161 shell_warn(sh, "Unable to parse input string argument");
1162 return err;
1163 }
1164
1165 if (!fault_id) {
1166 shell_print(sh, "The Fault ID must be non-zero!");
1167 return -EINVAL;
1168 }
1169
1170 for (i = 0U; i < sizeof(cur_faults); i++) {
1171 if (cur_faults[i] == fault_id) {
1172 cur_faults[i] = 0U;
1173 shell_print(sh, "Fault cleared");
1174 }
1175 }
1176
1177 bt_mesh_health_srv_fault_update(elem);
1178
1179 return 0;
1180 }
1181 #endif /* CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE */
1182 #endif /* CONFIG_BT_MESH_SHELL_TEST */
1183
1184 #if defined(CONFIG_BT_MESH_SHELL_CDB)
cmd_cdb_create(const struct shell * sh,size_t argc,char * argv[])1185 static int cmd_cdb_create(const struct shell *sh, size_t argc,
1186 char *argv[])
1187 {
1188 uint8_t net_key[16];
1189 size_t len;
1190 int err;
1191
1192 if (argc < 2) {
1193 bt_rand(net_key, 16);
1194 } else {
1195 len = hex2bin(argv[1], strlen(argv[1]), net_key,
1196 sizeof(net_key));
1197 memset(net_key + len, 0, sizeof(net_key) - len);
1198 }
1199
1200 err = bt_mesh_cdb_create(net_key);
1201 if (err < 0) {
1202 shell_print(sh, "Failed to create CDB (err %d)", err);
1203 }
1204
1205 return 0;
1206 }
1207
cmd_cdb_clear(const struct shell * sh,size_t argc,char * argv[])1208 static int cmd_cdb_clear(const struct shell *sh, size_t argc,
1209 char *argv[])
1210 {
1211 bt_mesh_cdb_clear();
1212
1213 shell_print(sh, "Cleared CDB");
1214
1215 return 0;
1216 }
1217
cdb_print_nodes(const struct shell * sh)1218 static void cdb_print_nodes(const struct shell *sh)
1219 {
1220 char key_hex_str[32 + 1], uuid_hex_str[32 + 1];
1221 struct bt_mesh_cdb_node *node;
1222 int i, total = 0;
1223 bool configured;
1224 uint8_t dev_key[16];
1225
1226 shell_print(sh, "Address Elements Flags %-32s DevKey", "UUID");
1227
1228 for (i = 0; i < ARRAY_SIZE(bt_mesh_cdb.nodes); ++i) {
1229 node = &bt_mesh_cdb.nodes[i];
1230 if (node->addr == BT_MESH_ADDR_UNASSIGNED) {
1231 continue;
1232 }
1233
1234 configured = atomic_test_bit(node->flags,
1235 BT_MESH_CDB_NODE_CONFIGURED);
1236
1237 total++;
1238 bin2hex(node->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
1239 if (bt_mesh_cdb_node_key_export(node, dev_key)) {
1240 shell_error(sh, "Unable to export key for node 0x%04x", node->addr);
1241 continue;
1242 }
1243 bin2hex(dev_key, 16, key_hex_str, sizeof(key_hex_str));
1244 shell_print(sh, "0x%04x %-8d %-5s %s %s", node->addr,
1245 node->num_elem, configured ? "C" : "-",
1246 uuid_hex_str, key_hex_str);
1247 }
1248
1249 shell_print(sh, "> Total nodes: %d", total);
1250 }
1251
cdb_print_subnets(const struct shell * sh)1252 static void cdb_print_subnets(const struct shell *sh)
1253 {
1254 struct bt_mesh_cdb_subnet *subnet;
1255 char key_hex_str[32 + 1];
1256 int i, total = 0;
1257 uint8_t net_key[16];
1258
1259 shell_print(sh, "NetIdx NetKey");
1260
1261 for (i = 0; i < ARRAY_SIZE(bt_mesh_cdb.subnets); ++i) {
1262 subnet = &bt_mesh_cdb.subnets[i];
1263 if (subnet->net_idx == BT_MESH_KEY_UNUSED) {
1264 continue;
1265 }
1266
1267 if (bt_mesh_cdb_subnet_key_export(subnet, 0, net_key)) {
1268 shell_error(sh, "Unable to export key for subnet 0x%03x",
1269 subnet->net_idx);
1270 continue;
1271 }
1272
1273 total++;
1274 bin2hex(net_key, 16, key_hex_str, sizeof(key_hex_str));
1275 shell_print(sh, "0x%03x %s", subnet->net_idx, key_hex_str);
1276 }
1277
1278 shell_print(sh, "> Total subnets: %d", total);
1279 }
1280
cdb_print_app_keys(const struct shell * sh)1281 static void cdb_print_app_keys(const struct shell *sh)
1282 {
1283 struct bt_mesh_cdb_app_key *key;
1284 char key_hex_str[32 + 1];
1285 int i, total = 0;
1286 uint8_t app_key[16];
1287
1288 shell_print(sh, "NetIdx AppIdx AppKey");
1289
1290 for (i = 0; i < ARRAY_SIZE(bt_mesh_cdb.app_keys); ++i) {
1291 key = &bt_mesh_cdb.app_keys[i];
1292 if (key->net_idx == BT_MESH_KEY_UNUSED) {
1293 continue;
1294 }
1295
1296 if (bt_mesh_cdb_app_key_export(key, 0, app_key)) {
1297 shell_error(sh, "Unable to export app key 0x%03x", key->app_idx);
1298 continue;
1299 }
1300
1301 total++;
1302 bin2hex(app_key, 16, key_hex_str, sizeof(key_hex_str));
1303 shell_print(sh, "0x%03x 0x%03x %s", key->net_idx, key->app_idx, key_hex_str);
1304 }
1305
1306 shell_print(sh, "> Total app-keys: %d", total);
1307 }
1308
cmd_cdb_show(const struct shell * sh,size_t argc,char * argv[])1309 static int cmd_cdb_show(const struct shell *sh, size_t argc,
1310 char *argv[])
1311 {
1312 if (!atomic_test_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID)) {
1313 shell_print(sh, "No valid networks");
1314 return 0;
1315 }
1316
1317 shell_print(sh, "Mesh Network Information");
1318 shell_print(sh, "========================");
1319
1320 cdb_print_nodes(sh);
1321 shell_print(sh, "---");
1322 cdb_print_subnets(sh);
1323 shell_print(sh, "---");
1324 cdb_print_app_keys(sh);
1325
1326 return 0;
1327 }
1328
cmd_cdb_node_add(const struct shell * sh,size_t argc,char * argv[])1329 static int cmd_cdb_node_add(const struct shell *sh, size_t argc,
1330 char *argv[])
1331 {
1332 struct bt_mesh_cdb_node *node;
1333 uint8_t uuid[16], dev_key[16];
1334 uint16_t addr, net_idx;
1335 uint8_t num_elem;
1336 size_t len;
1337 int err = 0;
1338
1339 len = hex2bin(argv[1], strlen(argv[1]), uuid, sizeof(uuid));
1340 memset(uuid + len, 0, sizeof(uuid) - len);
1341
1342 addr = shell_strtoul(argv[2], 0, &err);
1343 num_elem = shell_strtoul(argv[3], 0, &err);
1344 net_idx = shell_strtoul(argv[4], 0, &err);
1345 if (err) {
1346 shell_warn(sh, "Unable to parse input string argument");
1347 return err;
1348 }
1349
1350 if (argc < 6) {
1351 bt_rand(dev_key, 16);
1352 } else {
1353 len = hex2bin(argv[5], strlen(argv[5]), dev_key,
1354 sizeof(dev_key));
1355 memset(dev_key + len, 0, sizeof(dev_key) - len);
1356 }
1357
1358 node = bt_mesh_cdb_node_alloc(uuid, addr, num_elem, net_idx);
1359 if (node == NULL) {
1360 shell_print(sh, "Failed to allocate node");
1361 return 0;
1362 }
1363
1364 err = bt_mesh_cdb_node_key_import(node, dev_key);
1365 if (err) {
1366 shell_warn(sh, "Unable to import device key into cdb");
1367 return err;
1368 }
1369
1370 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1371 bt_mesh_cdb_node_store(node);
1372 }
1373
1374 shell_print(sh, "Added node 0x%04x", node->addr);
1375
1376 return 0;
1377 }
1378
cmd_cdb_node_del(const struct shell * sh,size_t argc,char * argv[])1379 static int cmd_cdb_node_del(const struct shell *sh, size_t argc,
1380 char *argv[])
1381 {
1382 struct bt_mesh_cdb_node *node;
1383 uint16_t addr;
1384 int err = 0;
1385
1386 addr = shell_strtoul(argv[1], 0, &err);
1387 if (err) {
1388 shell_warn(sh, "Unable to parse input string argument");
1389 return err;
1390 }
1391
1392 node = bt_mesh_cdb_node_get(addr);
1393 if (node == NULL) {
1394 shell_print(sh, "No node with address 0x%04x", addr);
1395 return 0;
1396 }
1397
1398 bt_mesh_cdb_node_del(node, true);
1399
1400 shell_print(sh, "Deleted node 0x%04x", addr);
1401
1402 return 0;
1403 }
1404
cmd_cdb_subnet_add(const struct shell * sh,size_t argc,char * argv[])1405 static int cmd_cdb_subnet_add(const struct shell *sh, size_t argc,
1406 char *argv[])
1407 {
1408 struct bt_mesh_cdb_subnet *sub;
1409 uint8_t net_key[16];
1410 uint16_t net_idx;
1411 size_t len;
1412 int err = 0;
1413
1414 net_idx = shell_strtoul(argv[1], 0, &err);
1415 if (err) {
1416 shell_warn(sh, "Unable to parse input string argument");
1417 return err;
1418 }
1419
1420 if (argc < 3) {
1421 bt_rand(net_key, 16);
1422 } else {
1423 len = hex2bin(argv[2], strlen(argv[2]), net_key,
1424 sizeof(net_key));
1425 memset(net_key + len, 0, sizeof(net_key) - len);
1426 }
1427
1428 sub = bt_mesh_cdb_subnet_alloc(net_idx);
1429 if (sub == NULL) {
1430 shell_print(sh, "Could not add subnet");
1431 return 0;
1432 }
1433
1434 if (bt_mesh_cdb_subnet_key_import(sub, 0, net_key)) {
1435 shell_error(sh, "Unable to import key for subnet 0x%03x", net_idx);
1436 return 0;
1437 }
1438
1439 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1440 bt_mesh_cdb_subnet_store(sub);
1441 }
1442
1443 shell_print(sh, "Added Subnet 0x%03x", net_idx);
1444
1445 return 0;
1446 }
1447
cmd_cdb_subnet_del(const struct shell * sh,size_t argc,char * argv[])1448 static int cmd_cdb_subnet_del(const struct shell *sh, size_t argc,
1449 char *argv[])
1450 {
1451 struct bt_mesh_cdb_subnet *sub;
1452 uint16_t net_idx;
1453 int err = 0;
1454
1455 net_idx = shell_strtoul(argv[1], 0, &err);
1456 if (err) {
1457 shell_warn(sh, "Unable to parse input string argument");
1458 return err;
1459 }
1460
1461 sub = bt_mesh_cdb_subnet_get(net_idx);
1462 if (sub == NULL) {
1463 shell_print(sh, "No subnet with NetIdx 0x%03x", net_idx);
1464 return 0;
1465 }
1466
1467 bt_mesh_cdb_subnet_del(sub, true);
1468
1469 shell_print(sh, "Deleted subnet 0x%03x", net_idx);
1470
1471 return 0;
1472 }
1473
cmd_cdb_app_key_add(const struct shell * sh,size_t argc,char * argv[])1474 static int cmd_cdb_app_key_add(const struct shell *sh, size_t argc,
1475 char *argv[])
1476 {
1477 struct bt_mesh_cdb_app_key *key;
1478 uint16_t net_idx, app_idx;
1479 uint8_t app_key[16];
1480 size_t len;
1481 int err = 0;
1482
1483 net_idx = shell_strtoul(argv[1], 0, &err);
1484 app_idx = shell_strtoul(argv[2], 0, &err);
1485 if (err) {
1486 shell_warn(sh, "Unable to parse input string argument");
1487 return err;
1488 }
1489
1490 if (argc < 4) {
1491 bt_rand(app_key, 16);
1492 } else {
1493 len = hex2bin(argv[3], strlen(argv[3]), app_key,
1494 sizeof(app_key));
1495 memset(app_key + len, 0, sizeof(app_key) - len);
1496 }
1497
1498 key = bt_mesh_cdb_app_key_alloc(net_idx, app_idx);
1499 if (key == NULL) {
1500 shell_print(sh, "Could not add AppKey");
1501 return 0;
1502 }
1503
1504 if (bt_mesh_cdb_app_key_import(key, 0, app_key)) {
1505 shell_error(sh, "Unable to import app key 0x%03x", app_idx);
1506 return 0;
1507 }
1508
1509 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1510 bt_mesh_cdb_app_key_store(key);
1511 }
1512
1513 shell_print(sh, "Added AppKey 0x%03x", app_idx);
1514
1515 return 0;
1516 }
1517
cmd_cdb_app_key_del(const struct shell * sh,size_t argc,char * argv[])1518 static int cmd_cdb_app_key_del(const struct shell *sh, size_t argc,
1519 char *argv[])
1520 {
1521 struct bt_mesh_cdb_app_key *key;
1522 uint16_t app_idx;
1523 int err = 0;
1524
1525 app_idx = shell_strtoul(argv[1], 0, &err);
1526 if (err) {
1527 shell_warn(sh, "Unable to parse input string argument");
1528 return err;
1529 }
1530
1531 key = bt_mesh_cdb_app_key_get(app_idx);
1532 if (key == NULL) {
1533 shell_print(sh, "No AppKey 0x%03x", app_idx);
1534 return 0;
1535 }
1536
1537 bt_mesh_cdb_app_key_del(key, true);
1538
1539 shell_print(sh, "Deleted AppKey 0x%03x", app_idx);
1540
1541 return 0;
1542 }
1543 #endif /* CONFIG_BT_MESH_SHELL_CDB */
1544
cmd_dst(const struct shell * sh,size_t argc,char * argv[])1545 static int cmd_dst(const struct shell *sh, size_t argc, char *argv[])
1546 {
1547 int err = 0;
1548
1549 if (argc < 2) {
1550 shell_print(sh, "Destination address: 0x%04x%s", bt_mesh_shell_target_ctx.dst,
1551 bt_mesh_shell_target_ctx.dst == bt_mesh_primary_addr()
1552 ? " (local)"
1553 : "");
1554 return 0;
1555 }
1556
1557 if (!strcmp(argv[1], "local")) {
1558 bt_mesh_shell_target_ctx.dst = bt_mesh_primary_addr();
1559 } else {
1560 bt_mesh_shell_target_ctx.dst = shell_strtoul(argv[1], 0, &err);
1561 if (err) {
1562 shell_warn(sh, "Unable to parse input string argument");
1563 return err;
1564 }
1565 }
1566
1567 shell_print(sh, "Destination address set to 0x%04x%s", bt_mesh_shell_target_ctx.dst,
1568 bt_mesh_shell_target_ctx.dst == bt_mesh_primary_addr() ? " (local)"
1569 : "");
1570 return 0;
1571 }
1572
cmd_netidx(const struct shell * sh,size_t argc,char * argv[])1573 static int cmd_netidx(const struct shell *sh, size_t argc, char *argv[])
1574 {
1575 int err = 0;
1576
1577 if (argc < 2) {
1578 shell_print(sh, "NetIdx: 0x%04x", bt_mesh_shell_target_ctx.net_idx);
1579 return 0;
1580 }
1581
1582 bt_mesh_shell_target_ctx.net_idx = shell_strtoul(argv[1], 0, &err);
1583 if (err) {
1584 shell_warn(sh, "Unable to parse input string argument");
1585 return err;
1586 }
1587
1588 shell_print(sh, "NetIdx set to 0x%04x", bt_mesh_shell_target_ctx.net_idx);
1589 return 0;
1590 }
1591
cmd_appidx(const struct shell * sh,size_t argc,char * argv[])1592 static int cmd_appidx(const struct shell *sh, size_t argc, char *argv[])
1593 {
1594 int err = 0;
1595
1596 if (argc < 2) {
1597 shell_print(sh, "AppIdx: 0x%04x", bt_mesh_shell_target_ctx.app_idx);
1598 return 0;
1599 }
1600
1601 bt_mesh_shell_target_ctx.app_idx = shell_strtoul(argv[1], 0, &err);
1602 if (err) {
1603 shell_warn(sh, "Unable to parse input string argument");
1604 return err;
1605 }
1606
1607 shell_print(sh, "AppIdx set to 0x%04x", bt_mesh_shell_target_ctx.app_idx);
1608 return 0;
1609 }
1610
1611 #if defined(CONFIG_BT_MESH_STATISTIC)
cmd_stat_get(const struct shell * sh,size_t argc,char * argv[])1612 static int cmd_stat_get(const struct shell *sh, size_t argc, char *argv[])
1613 {
1614 struct bt_mesh_statistic st;
1615
1616 bt_mesh_stat_get(&st);
1617
1618 shell_print(sh, "Received frames over:");
1619 shell_print(sh, "adv: %d", st.rx_adv);
1620 shell_print(sh, "loopback: %d", st.rx_loopback);
1621 shell_print(sh, "proxy: %d", st.rx_proxy);
1622 shell_print(sh, "unknown: %d", st.rx_uknown);
1623
1624 shell_print(sh, "Transmitted frames: <planned> - <succeeded>");
1625 shell_print(sh, "relay adv: %d - %d", st.tx_adv_relay_planned, st.tx_adv_relay_succeeded);
1626 shell_print(sh, "local adv: %d - %d", st.tx_local_planned, st.tx_local_succeeded);
1627 shell_print(sh, "friend: %d - %d", st.tx_friend_planned, st.tx_friend_succeeded);
1628
1629 return 0;
1630 }
1631
cmd_stat_clear(const struct shell * sh,size_t argc,char * argv[])1632 static int cmd_stat_clear(const struct shell *sh, size_t argc, char *argv[])
1633 {
1634 bt_mesh_stat_reset();
1635
1636 return 0;
1637 }
1638 #endif
1639
1640 #if defined(CONFIG_BT_MESH_SHELL_CDB)
1641 SHELL_STATIC_SUBCMD_SET_CREATE(
1642 cdb_cmds,
1643 /* Mesh Configuration Database Operations */
1644 SHELL_CMD_ARG(create, NULL, "[NetKey(1-16 hex)]", cmd_cdb_create, 1, 1),
1645 SHELL_CMD_ARG(clear, NULL, NULL, cmd_cdb_clear, 1, 0),
1646 SHELL_CMD_ARG(show, NULL, NULL, cmd_cdb_show, 1, 0),
1647 SHELL_CMD_ARG(node-add, NULL,
1648 "<UUID(1-16 hex)> <Addr> <ElemCnt> <NetKeyIdx> [DevKey(1-16 hex)]",
1649 cmd_cdb_node_add, 5, 1),
1650 SHELL_CMD_ARG(node-del, NULL, "<Addr>", cmd_cdb_node_del, 2, 0),
1651 SHELL_CMD_ARG(subnet-add, NULL, "<NetKeyIdx> [<NetKey(1-16 hex)>]", cmd_cdb_subnet_add, 2,
1652 1),
1653 SHELL_CMD_ARG(subnet-del, NULL, "<NetKeyIdx>", cmd_cdb_subnet_del, 2, 0),
1654 SHELL_CMD_ARG(app-key-add, NULL, "<NetKeyIdx> <AppKeyIdx> [<AppKey(1-16 hex)>]",
1655 cmd_cdb_app_key_add, 3, 1),
1656 SHELL_CMD_ARG(app-key-del, NULL, "<AppKeyIdx>", cmd_cdb_app_key_del, 2, 0),
1657 SHELL_SUBCMD_SET_END);
1658 #endif
1659
1660 #if defined(CONFIG_BT_MESH_SHELL_PROV)
1661 #if defined(CONFIG_BT_MESH_PROVISIONER)
1662 SHELL_STATIC_SUBCMD_SET_CREATE(auth_cmds,
1663 SHELL_CMD_ARG(input, NULL, "<Action> <Size>",
1664 cmd_auth_method_set_input, 3, 0),
1665 SHELL_CMD_ARG(output, NULL, "<Action> <Size>",
1666 cmd_auth_method_set_output, 3, 0),
1667 SHELL_CMD_ARG(static, NULL, "<Val(1-16 hex)>", cmd_auth_method_set_static, 2,
1668 0),
1669 SHELL_CMD_ARG(none, NULL, NULL, cmd_auth_method_set_none, 1, 0),
1670 SHELL_SUBCMD_SET_END);
1671 #endif
1672
1673 SHELL_STATIC_SUBCMD_SET_CREATE(
1674 prov_cmds, SHELL_CMD_ARG(input-num, NULL, "<Number>", cmd_input_num, 2, 0),
1675 SHELL_CMD_ARG(input-str, NULL, "<String>", cmd_input_str, 2, 0),
1676 SHELL_CMD_ARG(local, NULL, "<NetKeyIdx> <Addr> [IVI]", cmd_provision_local, 3, 1),
1677 #if defined(CONFIG_BT_MESH_SHELL_PROV_CTX_INSTANCE)
1678 SHELL_CMD_ARG(static-oob, NULL, "[Val]", cmd_static_oob, 2, 1),
1679 SHELL_CMD_ARG(uuid, NULL, "[UUID(1-16 hex)]", cmd_uuid, 1, 1),
1680 SHELL_CMD_ARG(beacon-listen, NULL, "<Val(off, on)>", cmd_beacon_listen, 2, 0),
1681 #endif
1682
1683 SHELL_CMD_ARG(comp-change, NULL, NULL, cmd_comp_change, 1, 0),
1684
1685 /* Provisioning operations */
1686 #if defined(CONFIG_BT_MESH_PROVISIONEE)
1687 #if defined(CONFIG_BT_MESH_PB_GATT)
1688 SHELL_CMD_ARG(pb-gatt, NULL, "<Val(off, on)>", cmd_pb_gatt, 2, 0),
1689 #endif
1690 #if defined(CONFIG_BT_MESH_PB_ADV)
1691 SHELL_CMD_ARG(pb-adv, NULL, "<Val(off, on)>", cmd_pb_adv, 2, 0),
1692 #endif
1693 #endif /* CONFIG_BT_MESH_PROVISIONEE */
1694
1695 #if defined(CONFIG_BT_MESH_PROVISIONER)
1696 SHELL_CMD(auth-method, &auth_cmds, "Authentication methods", bt_mesh_shell_mdl_cmds_help),
1697 SHELL_CMD_ARG(remote-pub-key, NULL, "<PubKey>", cmd_remote_pub_key_set, 2, 0),
1698 SHELL_CMD_ARG(remote-adv, NULL,
1699 "<UUID(1-16 hex)> <NetKeyIdx> <Addr> "
1700 "<AttDur(s)>",
1701 cmd_provision_adv, 5, 0),
1702 #endif
1703
1704 #if defined(CONFIG_BT_MESH_PB_GATT_CLIENT)
1705 SHELL_CMD_ARG(remote-gatt, NULL,
1706 "<UUID(1-16 hex)> <NetKeyIdx> <Addr> "
1707 "<AttDur(s)>",
1708 cmd_provision_gatt, 5, 0),
1709 #endif
1710 SHELL_SUBCMD_SET_END);
1711 #endif /* CONFIG_BT_MESH_SHELL_PROV */
1712
1713 #if defined(CONFIG_BT_MESH_SHELL_TEST)
1714 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE)
1715 SHELL_STATIC_SUBCMD_SET_CREATE(health_srv_cmds,
1716 /* Health Server Model Operations */
1717 SHELL_CMD_ARG(add-fault, NULL, "<FaultID>", cmd_add_fault, 2, 0),
1718 SHELL_CMD_ARG(del-fault, NULL, "[FaultID]", cmd_del_fault, 1, 1),
1719 SHELL_SUBCMD_SET_END);
1720 #endif
1721
1722 SHELL_STATIC_SUBCMD_SET_CREATE(test_cmds,
1723 /* Commands which access internal APIs, for testing only */
1724 SHELL_CMD_ARG(net-send, NULL, "<HexString>", cmd_net_send,
1725 2, 0),
1726 #if defined(CONFIG_BT_MESH_IV_UPDATE_TEST)
1727 SHELL_CMD_ARG(iv-update, NULL, NULL, cmd_iv_update, 1, 0),
1728 SHELL_CMD_ARG(iv-update-test, NULL, "<Val(off, on)>", cmd_iv_update_test, 2, 0),
1729 #endif
1730 SHELL_CMD_ARG(rpl-clear, NULL, NULL, cmd_rpl_clear, 1, 0),
1731 #if defined(CONFIG_BT_MESH_SHELL_HEALTH_SRV_INSTANCE)
1732 SHELL_CMD(health-srv, &health_srv_cmds, "Health Server test", bt_mesh_shell_mdl_cmds_help),
1733 #endif
1734 SHELL_SUBCMD_SET_END);
1735 #endif /* CONFIG_BT_MESH_SHELL_TEST */
1736
1737 #if defined(CONFIG_BT_MESH_SHELL_GATT_PROXY)
1738 SHELL_STATIC_SUBCMD_SET_CREATE(proxy_cmds,
1739 #if defined(CONFIG_BT_MESH_GATT_PROXY)
1740 SHELL_CMD_ARG(identity-enable, NULL, NULL, cmd_ident, 1, 0),
1741 #endif
1742
1743 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
1744 SHELL_CMD_ARG(connect, NULL, "<NetKeyIdx>", cmd_proxy_connect, 2, 0),
1745 SHELL_CMD_ARG(disconnect, NULL, "<NetKeyIdx>", cmd_proxy_disconnect, 2, 0),
1746 #endif
1747
1748 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
1749 SHELL_CMD_ARG(solicit, NULL, "<NetKeyIdx>",
1750 cmd_proxy_solicit, 2, 0),
1751 #endif
1752 SHELL_SUBCMD_SET_END);
1753 #endif /* CONFIG_BT_MESH_SHELL_GATT_PROXY */
1754
1755 #if defined(CONFIG_BT_MESH_SHELL_LOW_POWER)
1756 SHELL_STATIC_SUBCMD_SET_CREATE(low_pwr_cmds,
1757 SHELL_CMD_ARG(set, NULL, "<Val(off, on)>", cmd_lpn, 2, 0),
1758 SHELL_CMD_ARG(poll, NULL, NULL, cmd_poll, 1, 0),
1759 SHELL_SUBCMD_SET_END);
1760 #endif
1761
1762 SHELL_STATIC_SUBCMD_SET_CREATE(target_cmds,
1763 SHELL_CMD_ARG(dst, NULL, "[DstAddr]", cmd_dst, 1, 1),
1764 SHELL_CMD_ARG(net, NULL, "[NetKeyIdx]", cmd_netidx, 1, 1),
1765 SHELL_CMD_ARG(app, NULL, "[AppKeyIdx]", cmd_appidx, 1, 1),
1766 SHELL_SUBCMD_SET_END);
1767
1768 #if defined(CONFIG_BT_MESH_STATISTIC)
1769 SHELL_STATIC_SUBCMD_SET_CREATE(stat_cmds,
1770 SHELL_CMD_ARG(get, NULL, NULL, cmd_stat_get, 1, 0),
1771 SHELL_CMD_ARG(clear, NULL, NULL, cmd_stat_clear, 1, 0),
1772 SHELL_SUBCMD_SET_END);
1773 #endif
1774
1775 /* Placeholder for model shell modules that is configured in the application */
1776 SHELL_SUBCMD_SET_CREATE(model_cmds, (mesh, models));
1777
1778 /* List of Mesh subcommands.
1779 *
1780 * Each command is documented in doc/reference/bluetooth/mesh/shell.rst.
1781 *
1782 * Please keep the documentation up to date by adding any new commands to the
1783 * list.
1784 */
1785 SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds,
1786 SHELL_CMD_ARG(init, NULL, NULL, cmd_init, 1, 0),
1787 SHELL_CMD_ARG(reset-local, NULL, NULL, cmd_reset, 1, 0),
1788
1789 SHELL_CMD(models, &model_cmds, "Model commands", bt_mesh_shell_mdl_cmds_help),
1790
1791 #if defined(CONFIG_BT_MESH_SHELL_LOW_POWER)
1792 SHELL_CMD(lpn, &low_pwr_cmds, "Low Power commands", bt_mesh_shell_mdl_cmds_help),
1793 #endif
1794
1795 #if defined(CONFIG_BT_MESH_SHELL_CDB)
1796 SHELL_CMD(cdb, &cdb_cmds, "Configuration Database", bt_mesh_shell_mdl_cmds_help),
1797 #endif
1798
1799 #if defined(CONFIG_BT_MESH_SHELL_GATT_PROXY)
1800 SHELL_CMD(proxy, &proxy_cmds, "Proxy commands", bt_mesh_shell_mdl_cmds_help),
1801 #endif
1802
1803 #if defined(CONFIG_BT_MESH_SHELL_PROV)
1804 SHELL_CMD(prov, &prov_cmds, "Provisioning commands", bt_mesh_shell_mdl_cmds_help),
1805 #endif
1806
1807 #if defined(CONFIG_BT_MESH_SHELL_TEST)
1808 SHELL_CMD(test, &test_cmds, "Test commands", bt_mesh_shell_mdl_cmds_help),
1809 #endif
1810 SHELL_CMD(target, &target_cmds, "Target commands", bt_mesh_shell_mdl_cmds_help),
1811
1812 #if defined(CONFIG_BT_MESH_STATISTIC)
1813 SHELL_CMD(stat, &stat_cmds, "Statistic commands", bt_mesh_shell_mdl_cmds_help),
1814 #endif
1815
1816 SHELL_SUBCMD_SET_END
1817 );
1818
1819 SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth Mesh shell commands",
1820 bt_mesh_shell_mdl_cmds_help, 1, 1);
1821