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