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