1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <zephyr/shell/shell.h>
9 #include <zephyr/bluetooth/mesh.h>
10
11 #include "mesh/net.h"
12 #include "mesh/access.h"
13 #include "utils.h"
14 #include <zephyr/bluetooth/mesh/shell.h>
15
16 #define CID_NVAL 0xffff
17
18 /* Default net & app key values, unless otherwise specified */
19 extern const uint8_t bt_mesh_shell_default_key[16];
20
cmd_reset(const struct shell * sh,size_t argc,char * argv[])21 static int cmd_reset(const struct shell *sh, size_t argc, char *argv[])
22 {
23 int err;
24 bool reset = false;
25
26 err = bt_mesh_cfg_cli_node_reset(bt_mesh_shell_target_ctx.net_idx,
27 bt_mesh_shell_target_ctx.dst, &reset);
28 if (err) {
29 shell_error(sh, "Unable to send Remote Node Reset (err %d)", err);
30 return 0;
31 }
32
33 if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
34 struct bt_mesh_cdb_node *node = bt_mesh_cdb_node_get(bt_mesh_shell_target_ctx.dst);
35
36 if (node) {
37 bt_mesh_cdb_node_del(node, true);
38 }
39 }
40
41 shell_print(sh, "Remote node reset complete");
42
43 return 0;
44 }
45
cmd_timeout(const struct shell * sh,size_t argc,char * argv[])46 static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[])
47 {
48 int32_t timeout_ms;
49 int err = 0;
50
51 if (argc == 2) {
52 int32_t timeout_s = shell_strtol(argv[1], 0, &err);
53
54 if (err) {
55 shell_warn(sh, "Unable to parse input string argument");
56 return err;
57 }
58
59 if (timeout_s < 0 || timeout_s > (INT32_MAX / 1000)) {
60 timeout_ms = SYS_FOREVER_MS;
61 } else {
62 timeout_ms = timeout_s * MSEC_PER_SEC;
63 }
64
65 bt_mesh_cfg_cli_timeout_set(timeout_ms);
66 }
67
68 timeout_ms = bt_mesh_cfg_cli_timeout_get();
69 if (timeout_ms == SYS_FOREVER_MS) {
70 shell_print(sh, "Message timeout: forever");
71 } else {
72 shell_print(sh, "Message timeout: %u seconds", timeout_ms / 1000);
73 }
74
75 return 0;
76 }
77
cmd_get_comp(const struct shell * sh,size_t argc,char * argv[])78 static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
79 {
80 NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX);
81 struct bt_mesh_comp_p0_elem elem;
82 struct bt_mesh_comp_p0 comp;
83 uint8_t page = 0x00;
84 int err = 0;
85
86 if (argc > 1) {
87 page = shell_strtoul(argv[1], 0, &err);
88 if (err) {
89 shell_warn(sh, "Unable to parse input string argument");
90 return err;
91 }
92 }
93
94 err = bt_mesh_cfg_cli_comp_data_get(bt_mesh_shell_target_ctx.net_idx,
95 bt_mesh_shell_target_ctx.dst, page, &page, &buf);
96 if (err) {
97 shell_error(sh, "Getting composition failed (err %d)", err);
98 return 0;
99 }
100
101 if (page != 0 && page != 128 &&
102 ((page != 1 && page != 129) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) &&
103 ((page != 2 && page != 130) || !IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2))) {
104 shell_print(sh, "Got page %d. No parser available.", page);
105 return 0;
106 }
107
108 if (page == 0 || page == 128) {
109 err = bt_mesh_comp_p0_get(&comp, &buf);
110
111 if (err) {
112 shell_error(sh, "Couldn't parse Composition data (err %d)",
113 err);
114 return 0;
115 }
116
117 shell_print(sh, "Got Composition Data for 0x%04x, page: %d:",
118 bt_mesh_shell_target_ctx.dst, page);
119 shell_print(sh, "\tCID 0x%04x", comp.cid);
120 shell_print(sh, "\tPID 0x%04x", comp.pid);
121 shell_print(sh, "\tVID 0x%04x", comp.vid);
122 shell_print(sh, "\tCRPL 0x%04x", comp.crpl);
123 shell_print(sh, "\tFeatures 0x%04x", comp.feat);
124
125 while (bt_mesh_comp_p0_elem_pull(&comp, &elem)) {
126 int i;
127
128 shell_print(sh, "\tElement @ 0x%04x:", elem.loc);
129
130 if (elem.nsig) {
131 shell_print(sh, "\t\tSIG Models:");
132 } else {
133 shell_print(sh, "\t\tNo SIG Models");
134 }
135
136 for (i = 0; i < elem.nsig; i++) {
137 uint16_t mod_id = bt_mesh_comp_p0_elem_mod(&elem, i);
138
139 shell_print(sh, "\t\t\t0x%04x", mod_id);
140 }
141
142 if (elem.nvnd) {
143 shell_print(sh, "\t\tVendor Models:");
144 } else {
145 shell_print(sh, "\t\tNo Vendor Models");
146 }
147
148 for (i = 0; i < elem.nvnd; i++) {
149 struct bt_mesh_mod_id_vnd mod =
150 bt_mesh_comp_p0_elem_mod_vnd(&elem, i);
151
152 shell_print(sh, "\t\t\tCompany 0x%04x: 0x%04x",
153 mod.company, mod.id);
154 }
155 }
156 }
157
158 if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
159 /* size of 32 is chosen arbitrary, as sufficient for testing purposes */
160 NET_BUF_SIMPLE_DEFINE(p1_buf, 32);
161 NET_BUF_SIMPLE_DEFINE(p1_item_buf, 32);
162 struct bt_mesh_comp_p1_elem p1_elem = { ._buf = &p1_buf };
163 struct bt_mesh_comp_p1_model_item mod_item = { ._buf = &p1_item_buf };
164 struct bt_mesh_comp_p1_ext_item ext_item = { 0 };
165 int mod_idx = 1;
166
167 if (!buf.len) {
168 shell_error(sh, "Composition data empty");
169 return 0;
170 }
171 shell_print(sh,
172 "Got Composition Data for 0x%04x, page: %d:",
173 bt_mesh_shell_target_ctx.dst, page);
174
175 while (bt_mesh_comp_p1_elem_pull(&buf, &p1_elem)) {
176 int i, j;
177
178 shell_print(sh, "\tElement #%d description", mod_idx);
179
180 for (i = 0; i < p1_elem.nsig; i++) {
181 if (bt_mesh_comp_p1_item_pull(&p1_elem, &mod_item)) {
182 shell_print(sh, "\t\tSIG Model Item #%d:", i+1);
183 if (mod_item.cor_present) {
184 shell_print(sh,
185 "\t\t\tWith Corresponding ID %u",
186 mod_item.cor_id);
187 } else {
188 shell_print(sh,
189 "\t\t\tWithout Corresponding ID");
190 }
191 shell_print(sh,
192 "\t\t\tWith %u Extended Model Item(s)",
193 mod_item.ext_item_cnt);
194 }
195 for (j = 0; j < mod_item.ext_item_cnt; j++) {
196 bt_mesh_comp_p1_pull_ext_item(&mod_item,
197 &ext_item);
198 shell_print(sh,
199 "\t\t\t\tExtended Item #%d:", j+1);
200 if (ext_item.type == SHORT) {
201 shell_print(sh,
202 "\t\t\t\t\toffset: %u",
203 ext_item.short_item.elem_offset);
204 shell_print(sh,
205 "\t\t\t\t\tindex: %u",
206 ext_item.short_item.mod_item_idx);
207 } else {
208 shell_print(sh,
209 "\t\t\t\t\toffset: %u",
210 ext_item.long_item.elem_offset);
211 shell_print(sh,
212 "\t\t\t\t\tindex: %u",
213 ext_item.long_item.mod_item_idx);
214 }
215 }
216 }
217 for (i = 0; i < p1_elem.nvnd; i++) {
218 if (bt_mesh_comp_p1_item_pull(&p1_elem, &mod_item)) {
219 shell_print(sh, "\t\tVendor Model Item #%d:", i+1);
220 if (mod_item.cor_present) {
221 shell_print(sh,
222 "\t\t\tWith Corresponding ID %u",
223 mod_item.cor_id);
224 } else {
225 shell_print(sh,
226 "\t\t\tWithout Corresponding ID");
227 }
228 shell_print(sh,
229 "\t\t\tWith %u Extended Model Item(s)",
230 mod_item.ext_item_cnt);
231 }
232 for (j = 0; j < mod_item.ext_item_cnt; j++) {
233 bt_mesh_comp_p1_pull_ext_item(&mod_item,
234 &ext_item);
235 shell_print(sh,
236 "\t\t\t\tExtended Item #%d:", j+1);
237 if (ext_item.type == SHORT) {
238 shell_print(sh,
239 "\t\t\t\t\toffset: %u",
240 ext_item.short_item.elem_offset);
241 shell_print(sh,
242 "\t\t\t\t\tindex: %u",
243 ext_item.short_item.mod_item_idx);
244 } else {
245 shell_print(sh,
246 "\t\t\t\t\toffset: %u",
247 ext_item.long_item.elem_offset);
248 shell_print(sh,
249 "\t\t\t\t\tindex: %u",
250 ext_item.long_item.mod_item_idx);
251 }
252 }
253 }
254 mod_idx++;
255 }
256 }
257
258 if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) {
259 /* size of 32 is chosen arbitrary, as sufficient for testing purposes */
260 NET_BUF_SIMPLE_DEFINE(p2_elem_offset_buf, 32);
261 NET_BUF_SIMPLE_DEFINE(p2_data_buf, 32);
262 struct bt_mesh_comp_p2_record p2_elem = {
263 .elem_buf = &p2_elem_offset_buf,
264 .data_buf = &p2_data_buf
265 };
266
267 if (!buf.len) {
268 shell_error(sh, "Composition data empty");
269 return 0;
270 }
271 shell_print(sh, "Got Composition Data for 0x%04x, page: %d:",
272 bt_mesh_shell_target_ctx.dst, page);
273
274 while (bt_mesh_comp_p2_record_pull(&buf, &p2_elem)) {
275
276 shell_print(sh, "\tMesh Profile id: %04x ", p2_elem.id);
277 shell_print(sh, "\t\tVersion: %d.%d.%d ", p2_elem.version.x,
278 p2_elem.version.y, p2_elem.version.z);
279 shell_print(sh, "\t\tElement offsets:");
280
281 while (p2_elem.elem_buf->len) {
282 shell_print(sh, "\t\t\t%d ",
283 net_buf_simple_pull_u8(p2_elem.elem_buf));
284 }
285
286 if (p2_elem.data_buf->len) {
287 shell_print(sh, "\t\t%d bytes of additional data is available",
288 p2_elem.data_buf->len);
289 }
290 }
291 }
292
293 if (buf.len) {
294 shell_print(sh, "\t\t...truncated data!");
295 }
296
297 return 0;
298 }
299
cmd_beacon(const struct shell * sh,size_t argc,char * argv[])300 static int cmd_beacon(const struct shell *sh, size_t argc, char *argv[])
301 {
302 uint8_t status;
303 int err = 0;
304
305 if (argc < 2) {
306 err = bt_mesh_cfg_cli_beacon_get(bt_mesh_shell_target_ctx.net_idx,
307 bt_mesh_shell_target_ctx.dst, &status);
308 } else {
309 uint8_t val = shell_strtobool(argv[1], 0, &err);
310
311 if (err) {
312 shell_warn(sh, "Unable to parse input string argument");
313 return err;
314 }
315
316 err = bt_mesh_cfg_cli_beacon_set(bt_mesh_shell_target_ctx.net_idx,
317 bt_mesh_shell_target_ctx.dst, val, &status);
318 }
319
320 if (err) {
321 shell_error(sh, "Unable to send Beacon Get/Set message (err %d)", err);
322 return 0;
323 }
324
325 shell_print(sh, "Beacon state is 0x%02x", status);
326
327 return 0;
328 }
329
cmd_ttl(const struct shell * sh,size_t argc,char * argv[])330 static int cmd_ttl(const struct shell *sh, size_t argc, char *argv[])
331 {
332 uint8_t ttl;
333 int err = 0;
334
335 if (argc < 2) {
336 err = bt_mesh_cfg_cli_ttl_get(bt_mesh_shell_target_ctx.net_idx,
337 bt_mesh_shell_target_ctx.dst, &ttl);
338 } else {
339 uint8_t val = shell_strtoul(argv[1], 0, &err);
340
341 if (err) {
342 shell_warn(sh, "Unable to parse input string argument");
343 return err;
344 }
345
346 err = bt_mesh_cfg_cli_ttl_set(bt_mesh_shell_target_ctx.net_idx,
347 bt_mesh_shell_target_ctx.dst, val, &ttl);
348 }
349
350 if (err) {
351 shell_error(sh, "Unable to send Default TTL Get/Set (err %d)", err);
352 return 0;
353 }
354
355 shell_print(sh, "Default TTL is 0x%02x", ttl);
356
357 return 0;
358 }
359
cmd_friend(const struct shell * sh,size_t argc,char * argv[])360 static int cmd_friend(const struct shell *sh, size_t argc, char *argv[])
361 {
362 uint8_t frnd;
363 int err = 0;
364
365 if (argc < 2) {
366 err = bt_mesh_cfg_cli_friend_get(bt_mesh_shell_target_ctx.net_idx,
367 bt_mesh_shell_target_ctx.dst, &frnd);
368 } else {
369 uint8_t val = shell_strtobool(argv[1], 0, &err);
370
371 if (err) {
372 shell_warn(sh, "Unable to parse input string argument");
373 return err;
374 }
375
376 err = bt_mesh_cfg_cli_friend_set(bt_mesh_shell_target_ctx.net_idx,
377 bt_mesh_shell_target_ctx.dst, val, &frnd);
378 }
379
380 if (err) {
381 shell_error(sh, "Unable to send Friend Get/Set (err %d)", err);
382 return 0;
383 }
384
385 shell_print(sh, "Friend is set to 0x%02x", frnd);
386
387 return 0;
388 }
389
cmd_gatt_proxy(const struct shell * sh,size_t argc,char * argv[])390 static int cmd_gatt_proxy(const struct shell *sh, size_t argc, char *argv[])
391 {
392 uint8_t proxy;
393 int err = 0;
394
395 if (argc < 2) {
396 err = bt_mesh_cfg_cli_gatt_proxy_get(bt_mesh_shell_target_ctx.net_idx,
397 bt_mesh_shell_target_ctx.dst, &proxy);
398 } else {
399 uint8_t val = shell_strtobool(argv[1], 0, &err);
400
401 if (err) {
402 shell_warn(sh, "Unable to parse input string argument");
403 return err;
404 }
405
406 err = bt_mesh_cfg_cli_gatt_proxy_set(bt_mesh_shell_target_ctx.net_idx,
407 bt_mesh_shell_target_ctx.dst, val, &proxy);
408 }
409
410 if (err) {
411 shell_print(sh, "Unable to send GATT Proxy Get/Set (err %d)", err);
412 return 0;
413 }
414
415 shell_print(sh, "GATT Proxy is set to 0x%02x", proxy);
416
417 return 0;
418 }
419
cmd_polltimeout_get(const struct shell * sh,size_t argc,char * argv[])420 static int cmd_polltimeout_get(const struct shell *sh, size_t argc, char *argv[])
421 {
422 uint16_t lpn_address;
423 int32_t poll_timeout;
424 int err = 0;
425
426 lpn_address = shell_strtoul(argv[1], 0, &err);
427 if (err) {
428 shell_warn(sh, "Unable to parse input string argument");
429 return err;
430 }
431
432 err = bt_mesh_cfg_cli_lpn_timeout_get(bt_mesh_shell_target_ctx.net_idx,
433 bt_mesh_shell_target_ctx.dst, lpn_address, &poll_timeout);
434 if (err) {
435 shell_error(sh, "Unable to send LPN PollTimeout Get (err %d)", err);
436 return 0;
437 }
438
439 shell_print(sh, "PollTimeout value %d", poll_timeout);
440
441 return 0;
442 }
443
cmd_net_transmit(const struct shell * sh,size_t argc,char * argv[])444 static int cmd_net_transmit(const struct shell *sh, size_t argc, char *argv[])
445 {
446 uint8_t transmit;
447 int err = 0;
448
449 if (argc < 2) {
450 err = bt_mesh_cfg_cli_net_transmit_get(bt_mesh_shell_target_ctx.net_idx,
451 bt_mesh_shell_target_ctx.dst, &transmit);
452 } else {
453 if (argc != 3) {
454 shell_warn(sh, "Wrong number of input arguments"
455 "(2 arguments are required)");
456 return -EINVAL;
457 }
458
459 uint8_t count, interval, new_transmit;
460
461 count = shell_strtoul(argv[1], 0, &err);
462 interval = shell_strtoul(argv[2], 0, &err);
463 if (err) {
464 shell_warn(sh, "Unable to parse input string argument");
465 return err;
466 }
467
468 new_transmit = BT_MESH_TRANSMIT(count, interval);
469
470 err = bt_mesh_cfg_cli_net_transmit_set(bt_mesh_shell_target_ctx.net_idx,
471 bt_mesh_shell_target_ctx.dst, new_transmit,
472 &transmit);
473 }
474
475 if (err) {
476 shell_error(sh, "Unable to send network transmit Get/Set (err %d)", err);
477 return 0;
478 }
479
480 shell_print(sh, "Transmit 0x%02x (count %u interval %ums)", transmit,
481 BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));
482
483 return 0;
484 }
485
cmd_relay(const struct shell * sh,size_t argc,char * argv[])486 static int cmd_relay(const struct shell *sh, size_t argc, char *argv[])
487 {
488 uint8_t relay, transmit;
489 int err = 0;
490
491 if (argc < 2) {
492 err = bt_mesh_cfg_cli_relay_get(bt_mesh_shell_target_ctx.net_idx,
493 bt_mesh_shell_target_ctx.dst, &relay, &transmit);
494 } else {
495 uint8_t count, interval, new_transmit;
496 uint8_t val = shell_strtobool(argv[1], 0, &err);
497
498 if (val) {
499 if (argc > 2) {
500 count = shell_strtoul(argv[2], 0, &err);
501 } else {
502 count = 2U;
503 }
504
505 if (argc > 3) {
506 interval = shell_strtoul(argv[3], 0, &err);
507 } else {
508 interval = 20U;
509 }
510
511 new_transmit = BT_MESH_TRANSMIT(count, interval);
512 } else {
513 new_transmit = 0U;
514 }
515
516 if (err) {
517 shell_warn(sh, "Unable to parse input string argument");
518 return err;
519 }
520
521 err = bt_mesh_cfg_cli_relay_set(bt_mesh_shell_target_ctx.net_idx,
522 bt_mesh_shell_target_ctx.dst, val, new_transmit, &relay,
523 &transmit);
524 }
525
526 if (err) {
527 shell_error(sh, "Unable to send Relay Get/Set (err %d)", err);
528 return 0;
529 }
530
531 shell_print(sh, "Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)", relay,
532 transmit, BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));
533
534 return 0;
535 }
536
cmd_net_key_add(const struct shell * sh,size_t argc,char * argv[])537 static int cmd_net_key_add(const struct shell *sh, size_t argc, char *argv[])
538 {
539 bool has_key_val = (argc > 2);
540 uint8_t key_val[16];
541 uint16_t key_net_idx;
542 uint8_t status;
543 int err = 0;
544
545 key_net_idx = shell_strtoul(argv[1], 0, &err);
546 if (err) {
547 shell_warn(sh, "Unable to parse input string argument");
548 return err;
549 }
550
551 if (has_key_val) {
552 size_t len;
553
554 len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
555 (void)memset(key_val + len, 0, sizeof(key_val) - len);
556 } else {
557 memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
558 }
559
560 if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
561 struct bt_mesh_cdb_subnet *subnet;
562
563 subnet = bt_mesh_cdb_subnet_get(key_net_idx);
564 if (subnet) {
565 if (has_key_val) {
566 shell_error(sh, "Subnet 0x%03x already has a value", key_net_idx);
567 return 0;
568 }
569
570 if (bt_mesh_cdb_subnet_key_export(subnet, 0, key_val)) {
571 shell_error(sh, "Unable to export subnet key from cdb 0x%03x",
572 key_net_idx);
573 return 0;
574 }
575 } else {
576 subnet = bt_mesh_cdb_subnet_alloc(key_net_idx);
577 if (!subnet) {
578 shell_error(sh, "No space for subnet in cdb");
579 return 0;
580 }
581
582 if (bt_mesh_cdb_subnet_key_import(subnet, 0, key_val)) {
583 shell_error(sh, "Unable to import subnet key into cdb 0x%03x",
584 key_net_idx);
585 return 0;
586 }
587 bt_mesh_cdb_subnet_store(subnet);
588 }
589 }
590
591 err = bt_mesh_cfg_cli_net_key_add(bt_mesh_shell_target_ctx.net_idx,
592 bt_mesh_shell_target_ctx.dst, key_net_idx, key_val, &status);
593 if (err) {
594 shell_print(sh, "Unable to send NetKey Add (err %d)", err);
595 return 0;
596 }
597
598 if (status) {
599 shell_print(sh, "NetKeyAdd failed with status 0x%02x", status);
600 } else {
601 shell_print(sh, "NetKey added with NetKey Index 0x%03x", key_net_idx);
602 }
603
604 return 0;
605 }
606
cmd_net_key_update(const struct shell * sh,size_t argc,char * argv[])607 static int cmd_net_key_update(const struct shell *sh, size_t argc, char *argv[])
608 {
609 bool has_key_val = (argc > 2);
610 uint8_t key_val[16];
611 uint16_t key_net_idx;
612 uint8_t status;
613 int err = 0;
614
615 key_net_idx = shell_strtoul(argv[1], 0, &err);
616 if (err) {
617 shell_warn(sh, "Unable to parse input string argument");
618 return err;
619 }
620
621 if (has_key_val) {
622 size_t len;
623
624 len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
625 (void)memset(key_val + len, 0, sizeof(key_val) - len);
626 } else {
627 memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
628 }
629
630 err = bt_mesh_cfg_cli_net_key_update(bt_mesh_shell_target_ctx.net_idx,
631 bt_mesh_shell_target_ctx.dst, key_net_idx, key_val,
632 &status);
633 if (err) {
634 shell_print(sh, "Unable to send NetKey Update (err %d)", err);
635 return 0;
636 }
637
638 if (status) {
639 shell_print(sh, "NetKeyUpdate failed with status 0x%02x", status);
640 } else {
641 shell_print(sh, "NetKey updated with NetKey Index 0x%03x", key_net_idx);
642 }
643
644 return 0;
645 }
646
cmd_net_key_get(const struct shell * sh,size_t argc,char * argv[])647 static int cmd_net_key_get(const struct shell *sh, size_t argc, char *argv[])
648 {
649 uint16_t keys[16];
650 size_t cnt;
651 int err, i;
652
653 cnt = ARRAY_SIZE(keys);
654
655 err = bt_mesh_cfg_cli_net_key_get(bt_mesh_shell_target_ctx.net_idx,
656 bt_mesh_shell_target_ctx.dst, keys, &cnt);
657 if (err) {
658 shell_print(sh, "Unable to send NetKeyGet (err %d)", err);
659 return 0;
660 }
661
662 shell_print(sh, "NetKeys known by 0x%04x:", bt_mesh_shell_target_ctx.dst);
663 for (i = 0; i < cnt; i++) {
664 shell_print(sh, "\t0x%03x", keys[i]);
665 }
666
667 return 0;
668 }
669
cmd_net_key_del(const struct shell * sh,size_t argc,char * argv[])670 static int cmd_net_key_del(const struct shell *sh, size_t argc, char *argv[])
671 {
672 uint16_t key_net_idx;
673 uint8_t status;
674 int err = 0;
675
676 key_net_idx = shell_strtoul(argv[1], 0, &err);
677 if (err) {
678 shell_warn(sh, "Unable to parse input string argument");
679 return err;
680 }
681
682 err = bt_mesh_cfg_cli_net_key_del(bt_mesh_shell_target_ctx.net_idx,
683 bt_mesh_shell_target_ctx.dst, key_net_idx, &status);
684 if (err) {
685 shell_print(sh, "Unable to send NetKeyDel (err %d)", err);
686 return 0;
687 }
688
689 if (status) {
690 shell_print(sh, "NetKeyDel failed with status 0x%02x", status);
691 } else {
692 shell_print(sh, "NetKey 0x%03x deleted", key_net_idx);
693 }
694
695 return 0;
696 }
697
cmd_app_key_add(const struct shell * sh,size_t argc,char * argv[])698 static int cmd_app_key_add(const struct shell *sh, size_t argc, char *argv[])
699 {
700 uint8_t key_val[16];
701 uint16_t key_net_idx, key_app_idx;
702 bool has_key_val = (argc > 3);
703 uint8_t status;
704 int err = 0;
705
706 key_net_idx = shell_strtoul(argv[1], 0, &err);
707 key_app_idx = shell_strtoul(argv[2], 0, &err);
708 if (err) {
709 shell_warn(sh, "Unable to parse input string argument");
710 return err;
711 }
712
713 if (has_key_val) {
714 size_t len;
715
716 len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
717 (void)memset(key_val + len, 0, sizeof(key_val) - len);
718 } else {
719 memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
720 }
721
722 if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
723 struct bt_mesh_cdb_app_key *app_key;
724
725 app_key = bt_mesh_cdb_app_key_get(key_app_idx);
726 if (app_key) {
727 if (has_key_val) {
728 shell_error(sh, "App key 0x%03x already has a value", key_app_idx);
729 return 0;
730 }
731
732 if (bt_mesh_cdb_app_key_export(app_key, 0, key_val)) {
733 shell_error(sh, "Unable to export app key 0x%03x from cdb",
734 key_app_idx);
735 return 0;
736 }
737 } else {
738 app_key = bt_mesh_cdb_app_key_alloc(key_net_idx, key_app_idx);
739 if (!app_key) {
740 shell_error(sh, "No space for app key in cdb");
741 return 0;
742 }
743
744 if (bt_mesh_cdb_app_key_import(app_key, 0, key_val)) {
745 shell_error(sh, "Unable to import app key 0x%03x into cdb",
746 key_app_idx);
747 return 0;
748 }
749 bt_mesh_cdb_app_key_store(app_key);
750 }
751 }
752
753 err = bt_mesh_cfg_cli_app_key_add(bt_mesh_shell_target_ctx.net_idx,
754 bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
755 key_val, &status);
756 if (err) {
757 shell_error(sh, "Unable to send App Key Add (err %d)", err);
758 return 0;
759 }
760
761 if (status) {
762 shell_print(sh, "AppKeyAdd failed with status 0x%02x", status);
763 } else {
764 shell_print(sh, "AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x", key_net_idx,
765 key_app_idx);
766 }
767
768 return 0;
769 }
770
cmd_app_key_upd(const struct shell * sh,size_t argc,char * argv[])771 static int cmd_app_key_upd(const struct shell *sh, size_t argc, char *argv[])
772 {
773 uint8_t key_val[16];
774 uint16_t key_net_idx, key_app_idx;
775 bool has_key_val = (argc > 3);
776 uint8_t status;
777 int err = 0;
778
779 key_net_idx = shell_strtoul(argv[1], 0, &err);
780 key_app_idx = shell_strtoul(argv[2], 0, &err);
781 if (err) {
782 shell_warn(sh, "Unable to parse input string argument");
783 return err;
784 }
785
786 if (has_key_val) {
787 size_t len;
788
789 len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
790 (void)memset(key_val + len, 0, sizeof(key_val) - len);
791 } else {
792 memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
793 }
794
795 err = bt_mesh_cfg_cli_app_key_update(bt_mesh_shell_target_ctx.net_idx,
796 bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
797 key_val, &status);
798 if (err) {
799 shell_error(sh, "Unable to send App Key Update (err %d)", err);
800 return 0;
801 }
802
803 if (status) {
804 shell_print(sh, "AppKey update failed with status 0x%02x", status);
805 } else {
806 shell_print(sh, "AppKey updated, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
807 key_net_idx, key_app_idx);
808 }
809
810 return 0;
811 }
812
cmd_app_key_get(const struct shell * sh,size_t argc,char * argv[])813 static int cmd_app_key_get(const struct shell *sh, size_t argc, char *argv[])
814 {
815 uint16_t net_idx;
816 uint16_t keys[16];
817 size_t cnt;
818 uint8_t status;
819 int err = 0;
820 int i;
821
822 cnt = ARRAY_SIZE(keys);
823 net_idx = shell_strtoul(argv[1], 0, &err);
824 if (err) {
825 shell_warn(sh, "Unable to parse input string argument");
826 return err;
827 }
828
829 err = bt_mesh_cfg_cli_app_key_get(bt_mesh_shell_target_ctx.net_idx,
830 bt_mesh_shell_target_ctx.dst, net_idx, &status, keys, &cnt);
831 if (err) {
832 shell_print(sh, "Unable to send AppKeyGet (err %d)", err);
833 return 0;
834 }
835
836 if (status) {
837 shell_print(sh, "AppKeyGet failed with status 0x%02x", status);
838 return 0;
839 }
840
841 shell_print(sh, "AppKeys for NetKey 0x%03x known by 0x%04x:", net_idx,
842 bt_mesh_shell_target_ctx.dst);
843 for (i = 0; i < cnt; i++) {
844 shell_print(sh, "\t0x%03x", keys[i]);
845 }
846
847 return 0;
848 }
849
cmd_node_id(const struct shell * sh,size_t argc,char * argv[])850 static int cmd_node_id(const struct shell *sh, size_t argc, char *argv[])
851 {
852 uint16_t net_idx;
853 uint8_t status, identify;
854 int err = 0;
855
856 net_idx = shell_strtoul(argv[1], 0, &err);
857 if (err) {
858 shell_warn(sh, "Unable to parse input string argument");
859 return err;
860 }
861
862 if (argc <= 2) {
863 err = bt_mesh_cfg_cli_node_identity_get(bt_mesh_shell_target_ctx.net_idx,
864 bt_mesh_shell_target_ctx.dst, net_idx, &status,
865 &identify);
866 if (err) {
867 shell_print(sh, "Unable to send Node Identify Get (err %d)", err);
868 return 0;
869 }
870 } else {
871 uint8_t new_identify = shell_strtoul(argv[2], 0, &err);
872
873 if (err) {
874 shell_warn(sh, "Unable to parse input string argument");
875 return err;
876 }
877
878 err = bt_mesh_cfg_cli_node_identity_set(bt_mesh_shell_target_ctx.net_idx,
879 bt_mesh_shell_target_ctx.dst, net_idx,
880 new_identify, &status, &identify);
881 if (err) {
882 shell_print(sh, "Unable to send Node Identify Set (err %d)", err);
883 return 0;
884 }
885 }
886
887 if (status) {
888 shell_print(sh, "Node Identify Get/Set failed with status 0x%02x", status);
889 } else {
890 shell_print(sh, "Node Identify Get/Set successful with identify 0x%02x", identify);
891 }
892
893 return 0;
894 }
895
cmd_app_key_del(const struct shell * sh,size_t argc,char * argv[])896 static int cmd_app_key_del(const struct shell *sh, size_t argc, char *argv[])
897 {
898 uint16_t key_net_idx, key_app_idx;
899 uint8_t status;
900 int err = 0;
901
902 key_net_idx = shell_strtoul(argv[1], 0, &err);
903 key_app_idx = shell_strtoul(argv[2], 0, &err);
904 if (err) {
905 shell_warn(sh, "Unable to parse input string argument");
906 return err;
907 }
908
909 err = bt_mesh_cfg_cli_app_key_del(bt_mesh_shell_target_ctx.net_idx,
910 bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
911 &status);
912 if (err) {
913 shell_error(sh, "Unable to send App Key del(err %d)", err);
914 return 0;
915 }
916
917 if (status) {
918 shell_print(sh, "AppKeyDel failed with status 0x%02x", status);
919 } else {
920 shell_print(sh, "AppKey deleted, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
921 key_net_idx, key_app_idx);
922 }
923
924 return 0;
925 }
926
cmd_mod_app_bind(const struct shell * sh,size_t argc,char * argv[])927 static int cmd_mod_app_bind(const struct shell *sh, size_t argc, char *argv[])
928 {
929 uint16_t elem_addr, mod_app_idx, mod_id, cid;
930 uint8_t status;
931 int err = 0;
932
933 elem_addr = shell_strtoul(argv[1], 0, &err);
934 mod_app_idx = shell_strtoul(argv[2], 0, &err);
935 mod_id = shell_strtoul(argv[3], 0, &err);
936 if (err) {
937 shell_warn(sh, "Unable to parse input string argument");
938 return err;
939 }
940
941 if (argc > 4) {
942 cid = shell_strtoul(argv[4], 0, &err);
943 if (err) {
944 shell_warn(sh, "Unable to parse input string argument");
945 return err;
946 }
947
948 err = bt_mesh_cfg_cli_mod_app_bind_vnd(bt_mesh_shell_target_ctx.net_idx,
949 bt_mesh_shell_target_ctx.dst, elem_addr,
950 mod_app_idx, mod_id, cid, &status);
951 } else {
952 err = bt_mesh_cfg_cli_mod_app_bind(bt_mesh_shell_target_ctx.net_idx,
953 bt_mesh_shell_target_ctx.dst, elem_addr, mod_app_idx,
954 mod_id, &status);
955 }
956
957 if (err) {
958 shell_error(sh, "Unable to send Model App Bind (err %d)", err);
959 return 0;
960 }
961
962 if (status) {
963 shell_print(sh, "Model App Bind failed with status 0x%02x", status);
964 } else {
965 shell_print(sh, "AppKey successfully bound");
966 }
967
968 return 0;
969 }
970
cmd_mod_app_unbind(const struct shell * sh,size_t argc,char * argv[])971 static int cmd_mod_app_unbind(const struct shell *sh, size_t argc, char *argv[])
972 {
973 uint16_t elem_addr, mod_app_idx, mod_id, cid;
974 uint8_t status;
975 int err = 0;
976
977 elem_addr = shell_strtoul(argv[1], 0, &err);
978 mod_app_idx = shell_strtoul(argv[2], 0, &err);
979 mod_id = shell_strtoul(argv[3], 0, &err);
980 if (err) {
981 shell_warn(sh, "Unable to parse input string argument");
982 return err;
983 }
984
985 if (argc > 4) {
986 cid = shell_strtoul(argv[4], 0, &err);
987 if (err) {
988 shell_warn(sh, "Unable to parse input string argument");
989 return err;
990 }
991
992 err = bt_mesh_cfg_cli_mod_app_unbind_vnd(bt_mesh_shell_target_ctx.net_idx,
993 bt_mesh_shell_target_ctx.dst, elem_addr,
994 mod_app_idx, mod_id, cid, &status);
995 } else {
996 err = bt_mesh_cfg_cli_mod_app_unbind(bt_mesh_shell_target_ctx.net_idx,
997 bt_mesh_shell_target_ctx.dst, elem_addr,
998 mod_app_idx, mod_id, &status);
999 }
1000
1001 if (err) {
1002 shell_error(sh, "Unable to send Model App Unbind (err %d)", err);
1003 return 0;
1004 }
1005
1006 if (status) {
1007 shell_print(sh, "Model App Unbind failed with status 0x%02x", status);
1008 } else {
1009 shell_print(sh, "AppKey successfully unbound");
1010 }
1011
1012 return 0;
1013 }
1014
cmd_mod_app_get(const struct shell * sh,size_t argc,char * argv[])1015 static int cmd_mod_app_get(const struct shell *sh, size_t argc, char *argv[])
1016 {
1017 uint16_t elem_addr, mod_id, cid;
1018 uint16_t apps[16];
1019 uint8_t status;
1020 size_t cnt;
1021 int err = 0;
1022 int i;
1023
1024 cnt = ARRAY_SIZE(apps);
1025 elem_addr = shell_strtoul(argv[1], 0, &err);
1026 mod_id = shell_strtoul(argv[2], 0, &err);
1027 if (err) {
1028 shell_warn(sh, "Unable to parse input string argument");
1029 return err;
1030 }
1031
1032 if (argc > 3) {
1033 cid = shell_strtoul(argv[3], 0, &err);
1034 if (err) {
1035 shell_warn(sh, "Unable to parse input string argument");
1036 return err;
1037 }
1038
1039 err = bt_mesh_cfg_cli_mod_app_get_vnd(bt_mesh_shell_target_ctx.net_idx,
1040 bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
1041 cid, &status, apps, &cnt);
1042 } else {
1043 err = bt_mesh_cfg_cli_mod_app_get(bt_mesh_shell_target_ctx.net_idx,
1044 bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
1045 &status, apps, &cnt);
1046 }
1047
1048 if (err) {
1049 shell_error(sh, "Unable to send Model App Get (err %d)", err);
1050 return 0;
1051 }
1052
1053 if (status) {
1054 shell_print(sh, "Model App Get failed with status 0x%02x", status);
1055 } else {
1056 shell_print(sh, "Apps bound to Element 0x%04x, Model 0x%04x %s:", elem_addr, mod_id,
1057 argc > 3 ? argv[3] : "(SIG)");
1058
1059 if (!cnt) {
1060 shell_print(sh, "\tNone.");
1061 }
1062
1063 for (i = 0; i < cnt; i++) {
1064 shell_print(sh, "\t0x%04x", apps[i]);
1065 }
1066 }
1067
1068 return 0;
1069 }
1070
cmd_mod_sub_add(const struct shell * sh,size_t argc,char * argv[])1071 static int cmd_mod_sub_add(const struct shell *sh, size_t argc, char *argv[])
1072 {
1073 uint16_t elem_addr, sub_addr, mod_id, cid;
1074 uint8_t status;
1075 int err = 0;
1076
1077 elem_addr = shell_strtoul(argv[1], 0, &err);
1078 sub_addr = shell_strtoul(argv[2], 0, &err);
1079 mod_id = shell_strtoul(argv[3], 0, &err);
1080 if (err) {
1081 shell_warn(sh, "Unable to parse input string argument");
1082 return err;
1083 }
1084
1085 if (argc > 4) {
1086 cid = shell_strtoul(argv[4], 0, &err);
1087 if (err) {
1088 shell_warn(sh, "Unable to parse input string argument");
1089 return err;
1090 }
1091
1092 err = bt_mesh_cfg_cli_mod_sub_add_vnd(bt_mesh_shell_target_ctx.net_idx,
1093 bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
1094 mod_id, cid, &status);
1095 } else {
1096 err = bt_mesh_cfg_cli_mod_sub_add(bt_mesh_shell_target_ctx.net_idx,
1097 bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
1098 mod_id, &status);
1099 }
1100
1101 if (err) {
1102 shell_error(sh, "Unable to send Model Subscription Add (err %d)", err);
1103 return 0;
1104 }
1105
1106 if (status) {
1107 shell_print(sh, "Model Subscription Add failed with status 0x%02x", status);
1108 } else {
1109 shell_print(sh, "Model subscription was successful");
1110 }
1111
1112 return 0;
1113 }
1114
cmd_mod_sub_del(const struct shell * sh,size_t argc,char * argv[])1115 static int cmd_mod_sub_del(const struct shell *sh, size_t argc, char *argv[])
1116 {
1117 uint16_t elem_addr, sub_addr, mod_id, cid;
1118 uint8_t status;
1119 int err = 0;
1120
1121 elem_addr = shell_strtoul(argv[1], 0, &err);
1122 sub_addr = shell_strtoul(argv[2], 0, &err);
1123 mod_id = shell_strtoul(argv[3], 0, &err);
1124 if (err) {
1125 shell_warn(sh, "Unable to parse input string argument");
1126 return err;
1127 }
1128
1129 if (argc > 4) {
1130 cid = shell_strtoul(argv[4], 0, &err);
1131 if (err) {
1132 shell_warn(sh, "Unable to parse input string argument");
1133 return err;
1134 }
1135
1136 err = bt_mesh_cfg_cli_mod_sub_del_vnd(bt_mesh_shell_target_ctx.net_idx,
1137 bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
1138 mod_id, cid, &status);
1139 } else {
1140 err = bt_mesh_cfg_cli_mod_sub_del(bt_mesh_shell_target_ctx.net_idx,
1141 bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
1142 mod_id, &status);
1143 }
1144
1145 if (err) {
1146 shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
1147 return 0;
1148 }
1149
1150 if (status) {
1151 shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
1152 } else {
1153 shell_print(sh, "Model subscription deletion was successful");
1154 }
1155
1156 return 0;
1157 }
1158
cmd_mod_sub_add_va(const struct shell * sh,size_t argc,char * argv[])1159 static int cmd_mod_sub_add_va(const struct shell *sh, size_t argc, char *argv[])
1160 {
1161 uint16_t elem_addr, sub_addr, mod_id, cid;
1162 uint8_t label[16];
1163 uint8_t status;
1164 size_t len;
1165 int err = 0;
1166
1167 elem_addr = shell_strtoul(argv[1], 0, &err);
1168
1169 len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
1170 (void)memset(label + len, 0, sizeof(label) - len);
1171
1172 mod_id = shell_strtoul(argv[3], 0, &err);
1173 if (err) {
1174 shell_warn(sh, "Unable to parse input string argument");
1175 return err;
1176 }
1177
1178 if (argc > 4) {
1179 cid = shell_strtoul(argv[4], 0, &err);
1180 if (err) {
1181 shell_warn(sh, "Unable to parse input string argument");
1182 return err;
1183 }
1184
1185 err = bt_mesh_cfg_cli_mod_sub_va_add_vnd(bt_mesh_shell_target_ctx.net_idx,
1186 bt_mesh_shell_target_ctx.dst, elem_addr, label,
1187 mod_id, cid, &sub_addr, &status);
1188 } else {
1189 err = bt_mesh_cfg_cli_mod_sub_va_add(bt_mesh_shell_target_ctx.net_idx,
1190 bt_mesh_shell_target_ctx.dst, elem_addr, label,
1191 mod_id, &sub_addr, &status);
1192 }
1193
1194 if (err) {
1195 shell_error(sh, "Unable to send Mod Sub VA Add (err %d)", err);
1196 return 0;
1197 }
1198
1199 if (status) {
1200 shell_print(sh, "Mod Sub VA Add failed with status 0x%02x", status);
1201 } else {
1202 shell_print(sh, "0x%04x subscribed to Label UUID %s (va 0x%04x)", elem_addr,
1203 argv[2], sub_addr);
1204 }
1205
1206 return 0;
1207 }
1208
cmd_mod_sub_del_va(const struct shell * sh,size_t argc,char * argv[])1209 static int cmd_mod_sub_del_va(const struct shell *sh, size_t argc, char *argv[])
1210 {
1211 uint16_t elem_addr, sub_addr, mod_id, cid;
1212 uint8_t label[16];
1213 uint8_t status;
1214 size_t len;
1215 int err = 0;
1216
1217 elem_addr = shell_strtoul(argv[1], 0, &err);
1218
1219 len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
1220 (void)memset(label + len, 0, sizeof(label) - len);
1221
1222 mod_id = shell_strtoul(argv[3], 0, &err);
1223 if (err) {
1224 shell_warn(sh, "Unable to parse input string argument");
1225 return err;
1226 }
1227
1228 if (argc > 4) {
1229 cid = shell_strtoul(argv[4], 0, &err);
1230 if (err) {
1231 shell_warn(sh, "Unable to parse input string argument");
1232 return err;
1233 }
1234
1235 err = bt_mesh_cfg_cli_mod_sub_va_del_vnd(bt_mesh_shell_target_ctx.net_idx,
1236 bt_mesh_shell_target_ctx.dst, elem_addr, label,
1237 mod_id, cid, &sub_addr, &status);
1238 } else {
1239 err = bt_mesh_cfg_cli_mod_sub_va_del(bt_mesh_shell_target_ctx.net_idx,
1240 bt_mesh_shell_target_ctx.dst, elem_addr, label,
1241 mod_id, &sub_addr, &status);
1242 }
1243
1244 if (err) {
1245 shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
1246 return 0;
1247 }
1248
1249 if (status) {
1250 shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
1251 } else {
1252 shell_print(sh, "0x%04x unsubscribed from Label UUID %s (va 0x%04x)", elem_addr,
1253 argv[2], sub_addr);
1254 }
1255
1256 return 0;
1257 }
1258
cmd_mod_sub_ow(const struct shell * sh,size_t argc,char * argv[])1259 static int cmd_mod_sub_ow(const struct shell *sh, size_t argc, char *argv[])
1260 {
1261 uint16_t elem_addr, sub_addr, mod_id, cid;
1262 uint8_t status;
1263 int err = 0;
1264
1265 elem_addr = shell_strtoul(argv[1], 0, &err);
1266 sub_addr = shell_strtoul(argv[2], 0, &err);
1267 mod_id = shell_strtoul(argv[3], 0, &err);
1268 if (err) {
1269 shell_warn(sh, "Unable to parse input string argument");
1270 return err;
1271 }
1272
1273 if (argc > 4) {
1274 cid = shell_strtoul(argv[4], 0, &err);
1275 if (err) {
1276 shell_warn(sh, "Unable to parse input string argument");
1277 return err;
1278 }
1279
1280 err = bt_mesh_cfg_cli_mod_sub_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
1281 bt_mesh_shell_target_ctx.dst, elem_addr,
1282 sub_addr, mod_id, cid, &status);
1283 } else {
1284 err = bt_mesh_cfg_cli_mod_sub_overwrite(bt_mesh_shell_target_ctx.net_idx,
1285 bt_mesh_shell_target_ctx.dst, elem_addr,
1286 sub_addr, mod_id, &status);
1287 }
1288
1289 if (err) {
1290 shell_error(sh, "Unable to send Model Subscription Overwrite (err %d)", err);
1291 return 0;
1292 }
1293
1294 if (status) {
1295 shell_print(sh, "Model Subscription Overwrite failed with status 0x%02x", status);
1296 } else {
1297 shell_print(sh, "Model subscription overwrite was successful");
1298 }
1299
1300 return 0;
1301 }
1302
cmd_mod_sub_ow_va(const struct shell * sh,size_t argc,char * argv[])1303 static int cmd_mod_sub_ow_va(const struct shell *sh, size_t argc, char *argv[])
1304 {
1305 uint16_t elem_addr, sub_addr, mod_id, cid;
1306 uint8_t label[16];
1307 uint8_t status;
1308 size_t len;
1309 int err = 0;
1310
1311 elem_addr = shell_strtoul(argv[1], 0, &err);
1312
1313 len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
1314 (void)memset(label + len, 0, sizeof(label) - len);
1315
1316 mod_id = shell_strtoul(argv[3], 0, &err);
1317 if (err) {
1318 shell_warn(sh, "Unable to parse input string argument");
1319 return err;
1320 }
1321
1322 if (argc > 4) {
1323 cid = 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 err = bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
1330 bt_mesh_shell_target_ctx.dst, elem_addr,
1331 label, mod_id, cid, &sub_addr, &status);
1332 } else {
1333 err = bt_mesh_cfg_cli_mod_sub_va_overwrite(bt_mesh_shell_target_ctx.net_idx,
1334 bt_mesh_shell_target_ctx.dst, elem_addr,
1335 label, mod_id, &sub_addr, &status);
1336 }
1337
1338 if (err) {
1339 shell_error(sh, "Unable to send Mod Sub VA Overwrite (err %d)", err);
1340 return 0;
1341 }
1342
1343 if (status) {
1344 shell_print(sh, "Mod Sub VA Overwrite failed with status 0x%02x", status);
1345 } else {
1346 shell_print(sh, "0x%04x overwrite to Label UUID %s (va 0x%04x)", elem_addr, argv[2],
1347 sub_addr);
1348 }
1349
1350 return 0;
1351 }
1352
cmd_mod_sub_del_all(const struct shell * sh,size_t argc,char * argv[])1353 static int cmd_mod_sub_del_all(const struct shell *sh, size_t argc, char *argv[])
1354 {
1355 uint16_t elem_addr, mod_id, cid;
1356 uint8_t status;
1357 int err = 0;
1358
1359 elem_addr = shell_strtoul(argv[1], 0, &err);
1360 mod_id = shell_strtoul(argv[2], 0, &err);
1361 if (err) {
1362 shell_warn(sh, "Unable to parse input string argument");
1363 return err;
1364 }
1365
1366 if (argc > 3) {
1367 cid = shell_strtoul(argv[3], 0, &err);
1368 if (err) {
1369 shell_warn(sh, "Unable to parse input string argument");
1370 return err;
1371 }
1372
1373 err = bt_mesh_cfg_cli_mod_sub_del_all_vnd(bt_mesh_shell_target_ctx.net_idx,
1374 bt_mesh_shell_target_ctx.dst, elem_addr,
1375 mod_id, cid, &status);
1376 } else {
1377 err = bt_mesh_cfg_cli_mod_sub_del_all(bt_mesh_shell_target_ctx.net_idx,
1378 bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
1379 &status);
1380 }
1381
1382 if (err) {
1383 shell_error(sh, "Unable to send Model Subscription Delete All (err %d)", err);
1384 return 0;
1385 }
1386
1387 if (status) {
1388 shell_print(sh, "Model Subscription Delete All failed with status 0x%02x", status);
1389 } else {
1390 shell_print(sh, "Model subscription deletion all was successful");
1391 }
1392
1393 return 0;
1394 }
1395
cmd_mod_sub_get(const struct shell * sh,size_t argc,char * argv[])1396 static int cmd_mod_sub_get(const struct shell *sh, size_t argc, char *argv[])
1397 {
1398 uint16_t elem_addr, mod_id, cid;
1399 uint16_t subs[16];
1400 uint8_t status;
1401 size_t cnt;
1402 int err = 0;
1403 int i;
1404
1405 cnt = ARRAY_SIZE(subs);
1406 elem_addr = shell_strtoul(argv[1], 0, &err);
1407 mod_id = shell_strtoul(argv[2], 0, &err);
1408 if (err) {
1409 shell_warn(sh, "Unable to parse input string argument");
1410 return err;
1411 }
1412
1413 if (argc > 3) {
1414 cid = shell_strtoul(argv[3], 0, &err);
1415 if (err) {
1416 shell_warn(sh, "Unable to parse input string argument");
1417 return err;
1418 }
1419
1420 err = bt_mesh_cfg_cli_mod_sub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
1421 bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
1422 cid, &status, subs, &cnt);
1423 } else {
1424 err = bt_mesh_cfg_cli_mod_sub_get(bt_mesh_shell_target_ctx.net_idx,
1425 bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
1426 &status, subs, &cnt);
1427 }
1428
1429 if (err) {
1430 shell_error(sh, "Unable to send Model Subscription Get (err %d)", err);
1431 return 0;
1432 }
1433
1434 if (status) {
1435 shell_print(sh, "Model Subscription Get failed with status 0x%02x", status);
1436 } else {
1437 shell_print(sh,
1438 "Model Subscriptions for Element 0x%04x, Model 0x%04x %s:", elem_addr,
1439 mod_id, argc > 3 ? argv[3] : "(SIG)");
1440
1441 if (!cnt) {
1442 shell_print(sh, "\tNone.");
1443 }
1444
1445 for (i = 0; i < cnt; i++) {
1446 shell_print(sh, "\t0x%04x", subs[i]);
1447 }
1448 }
1449
1450 return 0;
1451 }
1452
cmd_krp(const struct shell * sh,size_t argc,char * argv[])1453 static int cmd_krp(const struct shell *sh, size_t argc, char *argv[])
1454 {
1455 uint8_t status, phase;
1456 uint16_t key_net_idx;
1457 int err = 0;
1458
1459 key_net_idx = shell_strtoul(argv[1], 0, &err);
1460 if (err) {
1461 shell_warn(sh, "Unable to parse input string argument");
1462 return err;
1463 }
1464
1465 if (argc < 3) {
1466 err = bt_mesh_cfg_cli_krp_get(bt_mesh_shell_target_ctx.net_idx,
1467 bt_mesh_shell_target_ctx.dst, key_net_idx, &status,
1468 &phase);
1469 } else {
1470 uint16_t trans = shell_strtoul(argv[2], 0, &err);
1471
1472 if (err) {
1473 shell_warn(sh, "Unable to parse input string argument");
1474 return err;
1475 }
1476
1477 err = bt_mesh_cfg_cli_krp_set(bt_mesh_shell_target_ctx.net_idx,
1478 bt_mesh_shell_target_ctx.dst, key_net_idx, trans, &status,
1479 &phase);
1480 }
1481
1482 if (err) {
1483 shell_error(sh, "Unable to send key refresh phase Get/Set (err %d)", err);
1484 return 0;
1485 }
1486
1487 shell_print(sh, "Key refresh phase Get/Set with status 0x%02x and phase 0x%02x", status,
1488 phase);
1489
1490 return 0;
1491 }
1492
mod_pub_get(const struct shell * sh,uint16_t addr,uint16_t mod_id,uint16_t cid)1493 static int mod_pub_get(const struct shell *sh, uint16_t addr, uint16_t mod_id, uint16_t cid)
1494 {
1495 struct bt_mesh_cfg_cli_mod_pub pub;
1496 uint8_t status;
1497 int err;
1498
1499 if (cid == CID_NVAL) {
1500 err = bt_mesh_cfg_cli_mod_pub_get(bt_mesh_shell_target_ctx.net_idx,
1501 bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
1502 &status);
1503 } else {
1504 err = bt_mesh_cfg_cli_mod_pub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
1505 bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
1506 &pub, &status);
1507 }
1508
1509 if (err) {
1510 shell_error(sh, "Model Publication Get failed (err %d)", err);
1511 return 0;
1512 }
1513
1514 if (status) {
1515 shell_print(sh, "Model Publication Get failed (status 0x%02x)", status);
1516 return 0;
1517 }
1518
1519 shell_print(sh,
1520 "Model Publication for Element 0x%04x, Model 0x%04x:\n"
1521 "\tPublish Address: 0x%04x\n"
1522 "\tAppKeyIndex: 0x%04x\n"
1523 "\tCredential Flag: %u\n"
1524 "\tPublishTTL: %u\n"
1525 "\tPublishPeriod: 0x%02x\n"
1526 "\tPublishRetransmitCount: %u\n"
1527 "\tPublishRetransmitInterval: %ums",
1528 addr, mod_id, pub.addr, pub.app_idx, pub.cred_flag, pub.ttl, pub.period,
1529 BT_MESH_PUB_TRANSMIT_COUNT(pub.transmit),
1530 BT_MESH_PUB_TRANSMIT_INT(pub.transmit));
1531
1532 return 0;
1533 }
1534
mod_pub_set(const struct shell * sh,uint16_t addr,bool is_va,uint16_t mod_id,uint16_t cid,char * argv[])1535 static int mod_pub_set(const struct shell *sh, uint16_t addr, bool is_va, uint16_t mod_id,
1536 uint16_t cid, char *argv[])
1537 {
1538 struct bt_mesh_cfg_cli_mod_pub pub;
1539 uint8_t status, count, res_step, steps;
1540 uint16_t interval;
1541 uint8_t uuid[16];
1542 uint8_t len;
1543 int err = 0;
1544
1545 if (!is_va) {
1546 pub.addr = shell_strtoul(argv[0], 0, &err);
1547 pub.uuid = NULL;
1548 } else {
1549 len = hex2bin(argv[0], strlen(argv[0]), uuid, sizeof(uuid));
1550 memset(uuid + len, 0, sizeof(uuid) - len);
1551 pub.uuid = (const uint8_t *)&uuid;
1552 }
1553
1554 pub.app_idx = shell_strtoul(argv[1], 0, &err);
1555 pub.cred_flag = shell_strtobool(argv[2], 0, &err);
1556 pub.ttl = shell_strtoul(argv[3], 0, &err);
1557 res_step = shell_strtoul(argv[4], 0, &err);
1558 steps = shell_strtoul(argv[5], 0, &err);
1559 if ((res_step > 3) || (steps > 0x3F)) {
1560 shell_print(sh, "Invalid period");
1561 return -EINVAL;
1562 }
1563
1564 pub.period = (steps << 2) + res_step;
1565 count = shell_strtoul(argv[6], 0, &err);
1566 if (count > 7) {
1567 shell_print(sh, "Invalid retransmit count");
1568 return -EINVAL;
1569 }
1570
1571 interval = shell_strtoul(argv[7], 0, &err);
1572 if (err) {
1573 shell_warn(sh, "Unable to parse input string argument");
1574 return err;
1575 }
1576
1577 if (interval > (31 * 50) || (interval % 50)) {
1578 shell_print(sh, "Invalid retransmit interval %u", interval);
1579 return -EINVAL;
1580 }
1581
1582 pub.transmit = BT_MESH_PUB_TRANSMIT(count, interval);
1583
1584 if (cid == CID_NVAL) {
1585 err = bt_mesh_cfg_cli_mod_pub_set(bt_mesh_shell_target_ctx.net_idx,
1586 bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
1587 &status);
1588 } else {
1589 err = bt_mesh_cfg_cli_mod_pub_set_vnd(bt_mesh_shell_target_ctx.net_idx,
1590 bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
1591 &pub, &status);
1592 }
1593
1594 if (err) {
1595 shell_error(sh, "Model Publication Set failed (err %d)", err);
1596 return 0;
1597 }
1598
1599 if (status) {
1600 shell_print(sh, "Model Publication Set failed (status 0x%02x)", status);
1601 } else {
1602 shell_print(sh, "Model Publication successfully set");
1603 }
1604
1605 return 0;
1606 }
1607
cmd_mod_pub(const struct shell * sh,size_t argc,char * argv[])1608 static int cmd_mod_pub(const struct shell *sh, size_t argc, char *argv[])
1609 {
1610 int err = 0;
1611 uint16_t addr, mod_id, cid;
1612
1613 addr = shell_strtoul(argv[1], 0, &err);
1614 mod_id = shell_strtoul(argv[2], 0, &err);
1615
1616 argc -= 3;
1617 argv += 3;
1618
1619 if (argc == 1 || argc == 9) {
1620 cid = shell_strtoul(argv[0], 0, &err);
1621 argc--;
1622 argv++;
1623 } else {
1624 cid = CID_NVAL;
1625 }
1626
1627 if (err) {
1628 shell_warn(sh, "Unable to parse input string argument");
1629 return err;
1630 }
1631
1632 if (argc > 0) {
1633 if (argc < 7) {
1634 shell_warn(sh, "Invalid number of argument");
1635 return -EINVAL;
1636 }
1637
1638 return mod_pub_set(sh, addr, false, mod_id, cid, argv);
1639 } else {
1640 return mod_pub_get(sh, addr, mod_id, cid);
1641 }
1642 }
1643
cmd_mod_pub_va(const struct shell * sh,size_t argc,char * argv[])1644 static int cmd_mod_pub_va(const struct shell *sh, size_t argc, char *argv[])
1645 {
1646 int err = 0;
1647 uint16_t addr, mod_id, cid = CID_NVAL;
1648
1649 addr = shell_strtoul(argv[1], 0, &err);
1650 mod_id = shell_strtoul(argv[9], 0, &err);
1651
1652 if (argc > 10) {
1653 cid = shell_strtoul(argv[10], 0, &err);
1654 }
1655
1656 if (err) {
1657 shell_warn(sh, "Unable to parse input string argument");
1658 return err;
1659 }
1660
1661 argv += 2;
1662
1663 return mod_pub_set(sh, addr, true, mod_id, cid, argv);
1664 }
1665
hb_sub_print(const struct shell * sh,struct bt_mesh_cfg_cli_hb_sub * sub)1666 static void hb_sub_print(const struct shell *sh, struct bt_mesh_cfg_cli_hb_sub *sub)
1667 {
1668 shell_print(sh,
1669 "Heartbeat Subscription:\n"
1670 "\tSource: 0x%04x\n"
1671 "\tDestination: 0x%04x\n"
1672 "\tPeriodLog: 0x%02x\n"
1673 "\tCountLog: 0x%02x\n"
1674 "\tMinHops: %u\n"
1675 "\tMaxHops: %u",
1676 sub->src, sub->dst, sub->period, sub->count, sub->min, sub->max);
1677 }
1678
hb_sub_get(const struct shell * sh,size_t argc,char * argv[])1679 static int hb_sub_get(const struct shell *sh, size_t argc, char *argv[])
1680 {
1681 struct bt_mesh_cfg_cli_hb_sub sub;
1682 uint8_t status;
1683 int err;
1684
1685 err = bt_mesh_cfg_cli_hb_sub_get(bt_mesh_shell_target_ctx.net_idx,
1686 bt_mesh_shell_target_ctx.dst, &sub, &status);
1687 if (err) {
1688 shell_error(sh, "Heartbeat Subscription Get failed (err %d)", err);
1689 return 0;
1690 }
1691
1692 if (status) {
1693 shell_print(sh, "Heartbeat Subscription Get failed (status 0x%02x)", status);
1694 } else {
1695 hb_sub_print(sh, &sub);
1696 }
1697
1698 return 0;
1699 }
1700
hb_sub_set(const struct shell * sh,size_t argc,char * argv[])1701 static int hb_sub_set(const struct shell *sh, size_t argc, char *argv[])
1702 {
1703 struct bt_mesh_cfg_cli_hb_sub sub;
1704 uint8_t status;
1705 int err = 0;
1706
1707 sub.src = shell_strtoul(argv[1], 0, &err);
1708 sub.dst = shell_strtoul(argv[2], 0, &err);
1709 sub.period = shell_strtoul(argv[3], 0, &err);
1710 if (err) {
1711 shell_warn(sh, "Unable to parse input string argument");
1712 return err;
1713 }
1714
1715 err = bt_mesh_cfg_cli_hb_sub_set(bt_mesh_shell_target_ctx.net_idx,
1716 bt_mesh_shell_target_ctx.dst, &sub, &status);
1717 if (err) {
1718 shell_error(sh, "Heartbeat Subscription Set failed (err %d)", err);
1719 return 0;
1720 }
1721
1722 if (status) {
1723 shell_print(sh, "Heartbeat Subscription Set failed (status 0x%02x)", status);
1724 } else {
1725 hb_sub_print(sh, &sub);
1726 }
1727
1728 return 0;
1729 }
1730
cmd_hb_sub(const struct shell * sh,size_t argc,char * argv[])1731 static int cmd_hb_sub(const struct shell *sh, size_t argc, char *argv[])
1732 {
1733 if (argc > 1) {
1734 if (argc < 4) {
1735 shell_warn(sh, "Invalid number of argument");
1736 return -EINVAL;
1737 }
1738
1739 return hb_sub_set(sh, argc, argv);
1740 } else {
1741 return hb_sub_get(sh, argc, argv);
1742 }
1743 }
1744
hb_pub_get(const struct shell * sh,size_t argc,char * argv[])1745 static int hb_pub_get(const struct shell *sh, size_t argc, char *argv[])
1746 {
1747 struct bt_mesh_cfg_cli_hb_pub pub;
1748 uint8_t status;
1749 int err;
1750
1751 err = bt_mesh_cfg_cli_hb_pub_get(bt_mesh_shell_target_ctx.net_idx,
1752 bt_mesh_shell_target_ctx.dst, &pub, &status);
1753 if (err) {
1754 shell_error(sh, "Heartbeat Publication Get failed (err %d)", err);
1755 return 0;
1756 }
1757
1758 if (status) {
1759 shell_print(sh, "Heartbeat Publication Get failed (status 0x%02x)", status);
1760 return 0;
1761 }
1762
1763 shell_print(sh, "Heartbeat publication:");
1764 shell_print(sh, "\tdst 0x%04x count 0x%02x period 0x%02x", pub.dst, pub.count, pub.period);
1765 shell_print(sh, "\tttl 0x%02x feat 0x%04x net_idx 0x%04x", pub.ttl, pub.feat, pub.net_idx);
1766
1767 return 0;
1768 }
1769
hb_pub_set(const struct shell * sh,size_t argc,char * argv[])1770 static int hb_pub_set(const struct shell *sh, size_t argc, char *argv[])
1771 {
1772 struct bt_mesh_cfg_cli_hb_pub pub;
1773 uint8_t status;
1774 int err = 0;
1775
1776 pub.dst = shell_strtoul(argv[1], 0, &err);
1777 pub.count = shell_strtoul(argv[2], 0, &err);
1778 pub.period = shell_strtoul(argv[3], 0, &err);
1779 pub.ttl = shell_strtoul(argv[4], 0, &err);
1780 pub.feat = shell_strtoul(argv[5], 0, &err);
1781 pub.net_idx = shell_strtoul(argv[6], 0, &err);
1782 if (err) {
1783 shell_warn(sh, "Unable to parse input string argument");
1784 return err;
1785 }
1786
1787 err = bt_mesh_cfg_cli_hb_pub_set(bt_mesh_shell_target_ctx.net_idx,
1788 bt_mesh_shell_target_ctx.dst, &pub, &status);
1789 if (err) {
1790 shell_error(sh, "Heartbeat Publication Set failed (err %d)", err);
1791 return 0;
1792 }
1793
1794 if (status) {
1795 shell_print(sh, "Heartbeat Publication Set failed (status 0x%02x)", status);
1796 } else {
1797 shell_print(sh, "Heartbeat publication successfully set");
1798 }
1799
1800 return 0;
1801 }
1802
cmd_hb_pub(const struct shell * sh,size_t argc,char * argv[])1803 static int cmd_hb_pub(const struct shell *sh, size_t argc, char *argv[])
1804 {
1805 if (argc > 1) {
1806 if (argc < 7) {
1807 shell_warn(sh, "Invalid number of argument");
1808 return -EINVAL;
1809 }
1810
1811 return hb_pub_set(sh, argc, argv);
1812 } else {
1813 return hb_pub_get(sh, argc, argv);
1814 }
1815 }
1816
1817 SHELL_STATIC_SUBCMD_SET_CREATE(model_cmds,
1818 SHELL_CMD_ARG(app-bind, NULL, "<Addr> <AppKeyIdx> <MID> [CID]",
1819 cmd_mod_app_bind, 4, 1),
1820 SHELL_CMD_ARG(app-get, NULL, "<ElemAddr> <MID> [CID]", cmd_mod_app_get,
1821 3, 1),
1822 SHELL_CMD_ARG(app-unbind, NULL, "<Addr> <AppKeyIdx> <MID> [CID]",
1823 cmd_mod_app_unbind, 4, 1),
1824 SHELL_CMD_ARG(pub, NULL,
1825 "<Addr> <MID> [CID] [<PubAddr> "
1826 "<AppKeyIdx> <Cred(off, on)> <TTL> <PerRes> <PerSteps> <Count> "
1827 "<Int(ms)>]",
1828 cmd_mod_pub, 3, 1 + 8),
1829 SHELL_CMD_ARG(pub-va, NULL,
1830 "<Addr> <UUID(1-16 hex)> "
1831 "<AppKeyIdx> <Cred(off, on)> <TTL> <PerRes> <PerSteps> <Count> "
1832 "<Int(ms)> <MID> [CID]",
1833 cmd_mod_pub_va, 11, 1),
1834 SHELL_CMD_ARG(sub-add, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
1835 cmd_mod_sub_add, 4, 1),
1836 SHELL_CMD_ARG(sub-del, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
1837 cmd_mod_sub_del, 4, 1),
1838 SHELL_CMD_ARG(sub-add-va, NULL,
1839 "<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]", cmd_mod_sub_add_va, 4, 1),
1840 SHELL_CMD_ARG(sub-del-va, NULL,
1841 "<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]", cmd_mod_sub_del_va, 4, 1),
1842 SHELL_CMD_ARG(sub-ow, NULL, "<ElemAddr> <SubAddr> <MID> [CID]",
1843 cmd_mod_sub_ow, 4, 1),
1844 SHELL_CMD_ARG(sub-ow-va, NULL, "<ElemAddr> <LabelUUID(1-16 hex)> <MID> [CID]",
1845 cmd_mod_sub_ow_va, 4, 1),
1846 SHELL_CMD_ARG(sub-del-all, NULL, "<ElemAddr> <MID> [CID]",
1847 cmd_mod_sub_del_all, 3, 1),
1848 SHELL_CMD_ARG(sub-get, NULL, "<ElemAddr> <MID> [CID]", cmd_mod_sub_get,
1849 3, 1),
1850 SHELL_SUBCMD_SET_END);
1851
1852 SHELL_STATIC_SUBCMD_SET_CREATE(netkey_cmds,
1853 SHELL_CMD_ARG(add, NULL, "<NetKeyIdx> [Key(1-16 hex)]", cmd_net_key_add, 2, 1),
1854 SHELL_CMD_ARG(upd, NULL, "<NetKeyIdx> [Key(1-16 hex)]", cmd_net_key_update, 2, 1),
1855 SHELL_CMD_ARG(get, NULL, NULL, cmd_net_key_get, 1, 0),
1856 SHELL_CMD_ARG(del, NULL, "<NetKeyIdx>", cmd_net_key_del, 2, 0),
1857 SHELL_SUBCMD_SET_END);
1858
1859 SHELL_STATIC_SUBCMD_SET_CREATE(appkey_cmds,
1860 SHELL_CMD_ARG(add, NULL, "<NetKeyIdx> <AppKeyIdx> [Key(1-16 hex)]", cmd_app_key_add,
1861 3, 1),
1862 SHELL_CMD_ARG(upd, NULL, "<NetKeyIdx> <AppKeyIdx> [Key(1-16 hex)]", cmd_app_key_upd,
1863 3, 1),
1864 SHELL_CMD_ARG(del, NULL, "<NetKeyIdx> <AppKeyIdx>", cmd_app_key_del, 3, 0),
1865 SHELL_CMD_ARG(get, NULL, "<NetKeyIdx>", cmd_app_key_get, 2, 0),
1866 SHELL_SUBCMD_SET_END);
1867
1868
1869 SHELL_STATIC_SUBCMD_SET_CREATE(
1870 cfg_cli_cmds,
1871 /* Configuration Client Model operations */
1872 SHELL_CMD_ARG(reset, NULL, NULL, cmd_reset, 1, 0),
1873 SHELL_CMD_ARG(timeout, NULL, "[Timeout(s)]", cmd_timeout, 1, 1),
1874 SHELL_CMD_ARG(get-comp, NULL, "[Page]", cmd_get_comp, 1, 1),
1875 SHELL_CMD_ARG(beacon, NULL, "[Val(off, on)]", cmd_beacon, 1, 1),
1876 SHELL_CMD_ARG(ttl, NULL, "[TTL]", cmd_ttl, 1, 1),
1877 SHELL_CMD_ARG(friend, NULL, "[Val(off, on)]", cmd_friend, 1, 1),
1878 SHELL_CMD_ARG(gatt-proxy, NULL, "[Val(off, on)]", cmd_gatt_proxy, 1, 1),
1879 SHELL_CMD_ARG(relay, NULL, "[<Val(off, on)> [<Count> [Int(ms)]]]", cmd_relay,
1880 1, 3),
1881 SHELL_CMD_ARG(node-id, NULL, "<NetKeyIdx> [Identify]", cmd_node_id, 2, 1),
1882 SHELL_CMD_ARG(polltimeout-get, NULL, "<LPNAddr>", cmd_polltimeout_get, 2, 0),
1883 SHELL_CMD_ARG(net-transmit-param, NULL, "[<Count> <Int(ms)>]",
1884 cmd_net_transmit, 1, 2),
1885 SHELL_CMD_ARG(krp, NULL, "<NetKeyIdx> [Phase]", cmd_krp, 2, 1),
1886 SHELL_CMD_ARG(hb-sub, NULL, "[<Src> <Dst> <Per>]", cmd_hb_sub, 1, 3),
1887 SHELL_CMD_ARG(hb-pub, NULL, "[<Dst> <Count> <Per> <TTL> <Features> <NetKeyIdx>]",
1888 cmd_hb_pub, 1, 6),
1889 SHELL_CMD(appkey, &appkey_cmds, "Appkey config commands", bt_mesh_shell_mdl_cmds_help),
1890 SHELL_CMD(netkey, &netkey_cmds, "Netkey config commands", bt_mesh_shell_mdl_cmds_help),
1891 SHELL_CMD(model, &model_cmds, "Model config commands", bt_mesh_shell_mdl_cmds_help),
1892 SHELL_SUBCMD_SET_END);
1893
1894 SHELL_SUBCMD_ADD((mesh, models), cfg, &cfg_cli_cmds, "Config Cli commands",
1895 bt_mesh_shell_mdl_cmds_help, 1, 1);
1896