• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2  *  @brief Bluetooth Mesh shell
3  *
4  */
5 
6 /*
7  * Copyright (c) 2017 Intel Corporation
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include "syscfg/syscfg.h"
13 
14 #if MYNEWT_VAL(BLE_MESH_SHELL)
15 
16 #include <stdlib.h>
17 #include <ctype.h>
18 #include <errno.h>
19 #include "shell/shell.h"
20 #include "console/console.h"
21 #include "mesh/mesh.h"
22 #include "mesh/main.h"
23 #include "mesh/glue.h"
24 #include "mesh/testing.h"
25 
26 /* Private includes for raw Network & Transport layer access */
27 #include "net.h"
28 #include "access.h"
29 #include "mesh_priv.h"
30 #include "lpn.h"
31 #include "transport.h"
32 #include "foundation.h"
33 #include "testing.h"
34 #include "settings.h"
35 
36 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
37 #include "mesh/model_srv.h"
38 #include "mesh/model_cli.h"
39 #include "light_model.h"
40 #endif
41 
42 /* This should be higher priority (lower value) than main task priority */
43 #define BLE_MESH_SHELL_TASK_PRIO 126
44 #define BLE_MESH_SHELL_STACK_SIZE 768
45 
46 OS_TASK_STACK_DEFINE(g_blemesh_shell_stack, BLE_MESH_SHELL_STACK_SIZE);
47 
48 struct os_task mesh_shell_task;
49 static struct os_eventq mesh_shell_queue;
50 
51 #define CID_NVAL   0xffff
52 #define CID_VENDOR  0x05C3
53 
54 /* Vendor Model data */
55 #define VND_MODEL_ID_1 0x1234
56 
57 /* Default net, app & dev key values, unless otherwise specified */
58 static const u8_t default_key[16] = {
59     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
60     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
61 };
62 
63 static struct {
64     u16_t local;
65     u16_t dst;
66     u16_t net_idx;
67     u16_t app_idx;
68 } net = {
69     .local = BT_MESH_ADDR_UNASSIGNED,
70     .dst = BT_MESH_ADDR_UNASSIGNED,
71 };
72 
73 static struct bt_mesh_cfg_srv cfg_srv = {
74     .relay = BT_MESH_RELAY_DISABLED,
75     .beacon = BT_MESH_BEACON_ENABLED,
76 #if MYNEWT_VAL(BLE_MESH_FRIEND)
77     .frnd = BT_MESH_FRIEND_DISABLED,
78 #else
79     .frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
80 #endif
81 #if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
82     .gatt_proxy = BT_MESH_GATT_PROXY_DISABLED,
83 #else
84     .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
85 #endif
86 
87     .default_ttl = 7,
88 
89     /* 3 transmissions with 20ms interval */
90     .net_transmit = BT_MESH_TRANSMIT(2, 20),
91     .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
92 };
93 
94 #define CUR_FAULTS_MAX 4
95 
96 static u8_t cur_faults[CUR_FAULTS_MAX];
97 static u8_t reg_faults[CUR_FAULTS_MAX * 2];
98 
get_faults(u8_t * faults,u8_t faults_size,u8_t * dst,u8_t * count)99 static void get_faults(u8_t *faults, u8_t faults_size, u8_t *dst, u8_t *count)
100 {
101     u8_t i, limit = *count;
102 
103     for (i = 0, *count = 0; i < faults_size && *count < limit; i++) {
104         if (faults[i]) {
105             *dst++ = faults[i];
106             (*count)++;
107         }
108     }
109 }
110 
fault_get_cur(struct bt_mesh_model * model,u8_t * test_id,u16_t * company_id,u8_t * faults,u8_t * fault_count)111 static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id,
112                          u16_t *company_id, u8_t *faults, u8_t *fault_count)
113 {
114     printk("Sending current faults\n");
115     *test_id = 0x00;
116     *company_id = CID_VENDOR;
117     get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);
118     return 0;
119 }
120 
fault_get_reg(struct bt_mesh_model * model,u16_t cid,u8_t * test_id,u8_t * faults,u8_t * fault_count)121 static int fault_get_reg(struct bt_mesh_model *model, u16_t cid,
122                          u8_t *test_id, u8_t *faults, u8_t *fault_count)
123 {
124     if (cid != CID_VENDOR) {
125         printk("Faults requested for unknown Company ID 0x%04x\n", cid);
126         return -EINVAL;
127     }
128 
129     printk("Sending registered faults\n");
130     *test_id = 0x00;
131     get_faults(reg_faults, sizeof(reg_faults), faults, fault_count);
132     return 0;
133 }
134 
fault_clear(struct bt_mesh_model * model,uint16_t cid)135 static int fault_clear(struct bt_mesh_model *model, uint16_t cid)
136 {
137     if (cid != CID_VENDOR) {
138         return -EINVAL;
139     }
140 
141     memset(reg_faults, 0, sizeof(reg_faults));
142     return 0;
143 }
144 
fault_test(struct bt_mesh_model * model,uint8_t test_id,uint16_t cid)145 static int fault_test(struct bt_mesh_model *model, uint8_t test_id,
146                       uint16_t cid)
147 {
148     if (cid != CID_VENDOR) {
149         return -EINVAL;
150     }
151 
152     if (test_id != 0x00) {
153         return -EINVAL;
154     }
155 
156     return 0;
157 }
158 
159 static const struct bt_mesh_health_srv_cb health_srv_cb = {
160     .fault_get_cur = fault_get_cur,
161     .fault_get_reg = fault_get_reg,
162     .fault_clear = fault_clear,
163     .fault_test = fault_test,
164 };
165 
166 static struct bt_mesh_health_srv health_srv = {
167     .cb = &health_srv_cb,
168 };
169 
170 static struct bt_mesh_model_pub health_pub;
171 
health_pub_init(void)172 static void health_pub_init(void)
173 {
174     health_pub.msg  = BT_MESH_HEALTH_FAULT_MSG(CUR_FAULTS_MAX);
175 }
176 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
177 
178 static struct bt_mesh_cfg_cli cfg_cli = {
179 };
180 
181 #endif /* MYNEWT_VAL(BLE_MESH_CFG_CLI) */
182 
183 #if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
show_faults(u8_t test_id,u16_t cid,u8_t * faults,size_t fault_count)184 void show_faults(u8_t test_id, u16_t cid, u8_t *faults, size_t fault_count)
185 {
186     size_t i;
187 
188     if (!fault_count) {
189         printk("Health Test ID 0x%02x Company ID 0x%04x: no faults\n",
190                test_id, cid);
191         return;
192     }
193 
194     printk("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu:\n",
195            test_id, cid, fault_count);
196 
197     for (i = 0; i < fault_count; i++) {
198         printk("\t0x%02x\n", faults[i]);
199     }
200 }
201 
health_current_status(struct bt_mesh_health_cli * cli,u16_t addr,u8_t test_id,u16_t cid,u8_t * faults,size_t fault_count)202 static void health_current_status(struct bt_mesh_health_cli *cli, u16_t addr,
203                                   u8_t test_id, u16_t cid, u8_t *faults,
204                                   size_t fault_count)
205 {
206     printk("Health Current Status from 0x%04x\n", addr);
207     show_faults(test_id, cid, faults, fault_count);
208 }
209 
210 static struct bt_mesh_health_cli health_cli = {
211     .current_status = health_current_status,
212 };
213 
214 #endif /* MYNEWT_VAL(BLE_MESH_HEALTH_CLI) */
215 
216 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
217 static struct bt_mesh_gen_model_cli gen_onoff_cli;
218 static struct bt_mesh_model_pub gen_onoff_cli_pub;
219 static struct bt_mesh_model_pub gen_onoff_srv_pub;
220 static struct bt_mesh_gen_model_cli gen_level_cli;
221 static struct bt_mesh_model_pub gen_level_cli_pub;
222 static struct bt_mesh_model_pub gen_level_srv_pub;
223 static struct bt_mesh_model_pub light_lightness_pub;
224 static struct bt_mesh_gen_onoff_srv gen_onoff_srv = {
225     .get = light_model_gen_onoff_get,
226     .set = light_model_gen_onoff_set,
227 };
228 static struct bt_mesh_gen_level_srv gen_level_srv = {
229     .get = light_model_gen_level_get,
230     .set = light_model_gen_level_set,
231 };
232 static struct bt_mesh_light_lightness_srv light_lightness_srv = {
233     .get = light_model_light_lightness_get,
234     .set = light_model_light_lightness_set,
235 };
236 
bt_mesh_set_gen_onoff_srv_cb(int (* get)(struct bt_mesh_model * model,u8_t * state),int (* set)(struct bt_mesh_model * model,u8_t state))237 void bt_mesh_set_gen_onoff_srv_cb(int (*get)(struct bt_mesh_model *model, u8_t *state),
238                                   int (*set)(struct bt_mesh_model *model, u8_t state))
239 {
240     gen_onoff_srv.get = get;
241     gen_onoff_srv.set = set;
242 }
243 
bt_mesh_set_gen_level_srv_cb(int (* get)(struct bt_mesh_model * model,s16_t * level),int (* set)(struct bt_mesh_model * model,s16_t level))244 void bt_mesh_set_gen_level_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level),
245                                   int (*set)(struct bt_mesh_model *model, s16_t level))
246 {
247     gen_level_srv.get = get;
248     gen_level_srv.set = set;
249 }
250 
bt_mesh_set_light_lightness_srv_cb(int (* get)(struct bt_mesh_model * model,s16_t * level),int (* set)(struct bt_mesh_model * model,s16_t level))251 void bt_mesh_set_light_lightness_srv_cb(int (*get)(struct bt_mesh_model *model, s16_t *level),
252                                         int (*set)(struct bt_mesh_model *model, s16_t level))
253 {
254     light_lightness_srv.get = get;
255     light_lightness_srv.set = set;
256 }
257 #endif
258 
259 static struct bt_mesh_model root_models[] = {
260     BT_MESH_MODEL_CFG_SRV(&cfg_srv),
261     BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
262 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
263     BT_MESH_MODEL_CFG_CLI(&cfg_cli),
264 #endif
265 #if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
266     BT_MESH_MODEL_HEALTH_CLI(&health_cli),
267 #endif
268 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
269     BT_MESH_MODEL_GEN_ONOFF_SRV(&gen_onoff_srv, &gen_onoff_srv_pub),
270     BT_MESH_MODEL_GEN_ONOFF_CLI(&gen_onoff_cli, &gen_onoff_cli_pub),
271     BT_MESH_MODEL_GEN_LEVEL_SRV(&gen_level_srv, &gen_level_srv_pub),
272     BT_MESH_MODEL_GEN_LEVEL_CLI(&gen_level_cli, &gen_level_cli_pub),
273     BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(&light_lightness_srv, &light_lightness_pub),
274 #endif
275 };
276 
277 static struct bt_mesh_model vnd_models[] = {
278     BT_MESH_MODEL_VND(CID_VENDOR, VND_MODEL_ID_1,
279                       BT_MESH_MODEL_NO_OPS, NULL, NULL),
280 };
281 
282 static struct bt_mesh_elem elements[] = {
283     BT_MESH_ELEM(0, root_models, vnd_models),
284 };
285 
286 static const struct bt_mesh_comp comp = {
287     .cid = CID_VENDOR,
288     .elem = elements,
289     .elem_count = ARRAY_SIZE(elements),
290 };
291 
hex2val(char c)292 static u8_t hex2val(char c)
293 {
294     if (c >= '0' && c <= '9') {
295         return c - '0';
296     } else if (c >= 'a' && c <= 'f') {
297         return c - 'a' + 10; // 10:byte alignment
298     } else if (c >= 'A' && c <= 'F') {
299         return c - 'A' + 10; // 10:byte alignment
300     } else {
301         return 0;
302     }
303 }
304 
hex2bin(const char * hex,u8_t * bin,size_t bin_len)305 static size_t hex2bin(const char *hex, u8_t *bin, size_t bin_len)
306 {
307     size_t len = 0;
308 
309     while (*hex && len < bin_len) {
310         bin[len] = hex2val(*hex++) << 4; // 4:byte alignment
311 
312         if (!*hex) {
313             len++;
314             break;
315         }
316 
317         bin[len++] |= hex2val(*hex++);
318     }
319 
320     return len;
321 }
322 
prov_complete(u16_t net_idx,u16_t addr)323 static void prov_complete(u16_t net_idx, u16_t addr)
324 {
325     printk("Local node provisioned, net_idx 0x%04x address 0x%04x\n",
326            net_idx, addr);
327     net.local = addr;
328     net.net_idx = net_idx,
329     net.dst = addr;
330 }
331 
prov_node_added(u16_t net_idx,u16_t addr,u8_t num_elem)332 static void prov_node_added(u16_t net_idx, u16_t addr, u8_t num_elem)
333 {
334     printk("Node provisioned, net_idx 0x%04x address "
335            "0x%04x elements %d", net_idx, addr, num_elem);
336     net.net_idx = net_idx,
337     net.dst = addr;
338 }
339 
prov_input_complete(void)340 static void prov_input_complete(void)
341 {
342     printk("Input complete");
343 }
344 
prov_reset(void)345 static void prov_reset(void)
346 {
347     printk("The local node has been reset and needs reprovisioning\n");
348 }
349 
output_number(bt_mesh_output_action_t action,uint32_t number)350 static int output_number(bt_mesh_output_action_t action, uint32_t number)
351 {
352     printk("OOB Number: %lu\n", number);
353     return 0;
354 }
355 
output_string(const char * str)356 static int output_string(const char *str)
357 {
358     printk("OOB String: %s\n", str);
359     return 0;
360 }
361 
362 static bt_mesh_input_action_t input_act;
363 static u8_t input_size;
364 
cmd_input_num(int argc,char * argv[])365 static int cmd_input_num(int argc, char *argv[])
366 {
367     int err;
368 
369     if (argc < 2) { // 2:Number of parameters
370         return -EINVAL;
371     }
372 
373     if (input_act != BT_MESH_ENTER_NUMBER) {
374         printk("A number hasn't been requested!\n");
375         return 0;
376     }
377 
378     if (strlen(argv[1]) < input_size) {
379         printk("Too short input (%u digits required)\n",
380                input_size);
381         return 0;
382     }
383 
384     long ret = strtoul(argv[1], NULL, 10);
385     if (ret == 0) {
386         printk("strtoul error!\n");
387     }
388     err = bt_mesh_input_number(ret); // 10:byte alignment
389     if (err) {
390         printk("Numeric input failed (err %d)\n", err);
391         return 0;
392     }
393 
394     input_act = BT_MESH_NO_INPUT;
395     return 0;
396 }
397 
398 struct shell_cmd_help cmd_input_num_help = {
399     NULL, "<number>", NULL
400 };
401 
cmd_input_str(int argc,char * argv[])402 static int cmd_input_str(int argc, char *argv[])
403 {
404     int err;
405 
406     if (argc < 2) { // 2:Number of parameters
407         return -EINVAL;
408     }
409 
410     if (input_act != BT_MESH_ENTER_STRING) {
411         printk("A string hasn't been requested!\n");
412         return 0;
413     }
414 
415     if (strlen(argv[1]) < input_size) {
416         printk("Too short input (%u characters required)\n",
417                input_size);
418         return 0;
419     }
420 
421     err = bt_mesh_input_string(argv[1]);
422     if (err) {
423         printk("String input failed (err %d)\n", err);
424         return 0;
425     }
426 
427     input_act = BT_MESH_NO_INPUT;
428     return 0;
429 }
430 
431 struct shell_cmd_help cmd_input_str_help = {
432     NULL, "<string>", NULL
433 };
434 
input(bt_mesh_input_action_t act,u8_t size)435 static int input(bt_mesh_input_action_t act, u8_t size)
436 {
437     switch (act) {
438         case BT_MESH_ENTER_NUMBER:
439             printk("Enter a number (max %u digits) with: input-num <num>\n",
440                    size);
441             break;
442 
443         case BT_MESH_ENTER_STRING:
444             printk("Enter a string (max %u chars) with: input-str <str>\n",
445                    size);
446             break;
447 
448         default:
449             printk("Unknown input action %u (size %u) requested!\n",
450                    act, size);
451             return -EINVAL;
452     }
453 
454     input_act = act;
455     input_size = size;
456     return 0;
457 }
458 
bearer2str(bt_mesh_prov_bearer_t bearer)459 static const char *bearer2str(bt_mesh_prov_bearer_t bearer)
460 {
461     switch (bearer) {
462         case BT_MESH_PROV_ADV:
463             return "PB-ADV";
464 
465         case BT_MESH_PROV_GATT:
466             return "PB-GATT";
467 
468         default:
469             return "unknown";
470     }
471 }
472 
link_open(bt_mesh_prov_bearer_t bearer)473 static void link_open(bt_mesh_prov_bearer_t bearer)
474 {
475     printk("Provisioning link opened on %s\n", bearer2str(bearer));
476 }
477 
link_close(bt_mesh_prov_bearer_t bearer)478 static void link_close(bt_mesh_prov_bearer_t bearer)
479 {
480     printk("Provisioning link closed on %s\n", bearer2str(bearer));
481 }
482 
483 static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
484 
485 static u8_t static_val[16];
486 
487 static struct bt_mesh_prov prov = {
488     .uuid = dev_uuid,
489     .link_open = link_open,
490     .link_close = link_close,
491     .complete = prov_complete,
492     .node_added = prov_node_added,
493     .reset = prov_reset,
494     .static_val = NULL,
495     .static_val_len = 0,
496     .output_size = MYNEWT_VAL(BLE_MESH_OOB_OUTPUT_SIZE),
497     .output_actions = MYNEWT_VAL(BLE_MESH_OOB_OUTPUT_ACTIONS),
498     .output_number = output_number,
499     .output_string = output_string,
500     .input_size = MYNEWT_VAL(BLE_MESH_OOB_INPUT_SIZE),
501     .input_actions = MYNEWT_VAL(BLE_MESH_OOB_INPUT_ACTIONS),
502     .input = input,
503     .input_complete = prov_input_complete,
504 };
505 
cmd_static_oob(int argc,char * argv[])506 static int cmd_static_oob(int argc, char *argv[])
507 {
508     if (argc < 2) { // 2:Number of parameters
509         prov.static_val = NULL;
510         prov.static_val_len = 0;
511     } else {
512         prov.static_val_len = hex2bin(argv[1], static_val, 16); // 16:bin_len
513 
514         if (prov.static_val_len) {
515             prov.static_val = static_val;
516         } else {
517             prov.static_val = NULL;
518         }
519     }
520 
521     if (prov.static_val) {
522         printk("Static OOB value set (length %u)\n",
523                prov.static_val_len);
524     } else {
525         printk("Static OOB value cleared\n");
526     }
527 
528     return 0;
529 }
530 
531 struct shell_cmd_help cmd_static_oob_help = {
532     NULL, "[val: 1-16 hex values]", NULL
533 };
534 
cmd_uuid(int argc,char * argv[])535 static int cmd_uuid(int argc, char *argv[])
536 {
537     u8_t uuid[16];
538     size_t len;
539 
540     if (argc < 2) { // 2:Number of parameters
541         return -EINVAL;
542     }
543 
544     len = hex2bin(argv[1], uuid, sizeof(uuid));
545     if (len < 1) {
546         return -EINVAL;
547     }
548 
549     memcpy(dev_uuid, uuid, len);
550     memset(dev_uuid + len, 0, sizeof(dev_uuid) - len);
551     printk("Device UUID set\n");
552     return 0;
553 }
554 
555 struct shell_cmd_help cmd_uuid_help = {
556     NULL, "<UUID: 1-16 hex values>", NULL
557 };
558 
cmd_reset(int argc,char * argv[])559 static int cmd_reset(int argc, char *argv[])
560 {
561     bt_mesh_reset();
562     printk("Local node reset complete\n");
563     return 0;
564 }
565 
str2u8(const char * str)566 static u8_t str2u8(const char *str)
567 {
568     if (isdigit(str[0])) {
569         return strtoul(str, NULL, 0);
570     }
571 
572     return (!strcmp(str, "on") || !strcmp(str, "enable"));
573 }
574 
str2bool(const char * str)575 static bool str2bool(const char *str)
576 {
577     return str2u8(str);
578 }
579 
580 #if MYNEWT_VAL(BLE_MESH_LOW_POWER)
cmd_lpn(int argc,char * argv[])581 static int cmd_lpn(int argc, char *argv[])
582 {
583     static bool enabled;
584     int err;
585 
586     if (argc < 2) { // 2:Number of parameters
587         printk("%s\n", enabled ? "enabled" : "disabled");
588         return 0;
589     }
590 
591     if (str2bool(argv[1])) {
592         if (enabled) {
593             printk("LPN already enabled\n");
594             return 0;
595         }
596 
597         err = bt_mesh_lpn_set(true);
598         if (err) {
599             printk("Enabling LPN failed (err %d)\n", err);
600         } else {
601             enabled = true;
602         }
603     } else {
604         if (!enabled) {
605             printk("LPN already disabled\n");
606             return 0;
607         }
608 
609         err = bt_mesh_lpn_set(false);
610         if (err) {
611             printk("Enabling LPN failed (err %d)\n", err);
612         } else {
613             enabled = false;
614         }
615     }
616 
617     return 0;
618 }
619 
cmd_poll(int argc,char * argv[])620 static int cmd_poll(int argc, char *argv[])
621 {
622     int err;
623     err = bt_mesh_lpn_poll();
624     if (err) {
625         printk("Friend Poll failed (err %d)\n", err);
626     }
627 
628     return 0;
629 }
630 
lpn_cb(u16_t friend_addr,bool established)631 static void lpn_cb(u16_t friend_addr, bool established)
632 {
633     if (established) {
634         printk("Friendship (as LPN) established to Friend 0x%04x\n",
635                friend_addr);
636     } else {
637         printk("Friendship (as LPN) lost with Friend 0x%04x\n",
638                friend_addr);
639     }
640 }
641 
642 struct shell_cmd_help cmd_lpn_help = {
643     NULL, "<value: off, on>", NULL
644 };
645 
646 #endif /* MESH_LOW_POWER */
647 
check_pub_addr_unassigned(void)648 static int check_pub_addr_unassigned(void)
649 {
650 #ifdef ARCH_sim
651     return 0;
652 #else
653     uint8_t zero_addr[BLE_DEV_ADDR_LEN] = { 0 };
654     return memcmp(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR),
655                   zero_addr, BLE_DEV_ADDR_LEN) == 0;
656 #endif
657 }
658 
cmd_mesh_init(int argc,char * argv[])659 int cmd_mesh_init(int argc, char *argv[])
660 {
661     int err;
662     ble_addr_t addr;
663 
664     if (check_pub_addr_unassigned()) {
665         /* Use NRPA */
666         err = ble_hs_id_gen_rnd(1, &addr);
667         assert(err == 0);
668         err = ble_hs_id_set_rnd(addr.val);
669         assert(err == 0);
670         err = bt_mesh_init(addr.type, &prov, &comp);
671     } else {
672         err = bt_mesh_init(0, &prov, &comp);
673     }
674 
675     if (err) {
676         printk("Mesh initialization failed (err %d)\n", err);
677     }
678 
679     printk("Mesh initialized\n");
680 
681     if (IS_ENABLED(CONFIG_SETTINGS)) {
682         settings_load();
683     }
684 
685     if (bt_mesh_is_provisioned()) {
686         printk("Mesh network restored from flash\n");
687     } else {
688         printk("Use \"pb-adv on\" or \"pb-gatt on\" to enable"
689                " advertising\n");
690     }
691 
692 #if MYNEWT_VAL(BLE_MESH_LOW_POWER)
693     bt_mesh_lpn_set_cb(lpn_cb);
694 #endif
695     return 0;
696 }
697 
698 #if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
cmd_ident(int argc,char * argv[])699 static int cmd_ident(int argc, char *argv[])
700 {
701     int err;
702     err = bt_mesh_proxy_identity_enable();
703     if (err) {
704         printk("Failed advertise using Node Identity (err %d)\n", err);
705     }
706 
707     return 0;
708 }
709 #endif /* MESH_GATT_PROXY */
710 
cmd_dst(int argc,char * argv[])711 static int cmd_dst(int argc, char *argv[])
712 {
713     if (argc < 2) { // 2:Number of parameters
714         printk("Destination address: 0x%04x%s\n", net.dst,
715                net.dst == net.local ? " (local)" : "");
716         return 0;
717     }
718 
719     if (!strcmp(argv[1], "local")) {
720         net.dst = net.local;
721     } else {
722         net.dst = strtoul(argv[1], NULL, 0);
723     }
724 
725     printk("Destination address set to 0x%04x%s\n", net.dst,
726            net.dst == net.local ? " (local)" : "");
727     return 0;
728 }
729 
730 struct shell_cmd_help cmd_dst_help = {
731     NULL, "[destination address]", NULL
732 };
733 
cmd_netidx(int argc,char * argv[])734 static int cmd_netidx(int argc, char *argv[])
735 {
736     if (argc < 2) { // 2:Number of parameters
737         printk("NetIdx: 0x%04x\n", net.net_idx);
738         return 0;
739     }
740 
741     net.net_idx = strtoul(argv[1], NULL, 0);
742     printk("NetIdx set to 0x%04x\n", net.net_idx);
743     return 0;
744 }
745 
746 struct shell_cmd_help cmd_netidx_help = {
747     NULL, "[NetIdx]", NULL
748 };
749 
cmd_appidx(int argc,char * argv[])750 static int cmd_appidx(int argc, char *argv[])
751 {
752     if (argc < 2) { // 2:Number of parameters
753         printk("AppIdx: 0x%04x\n", net.app_idx);
754         return 0;
755     }
756 
757     net.app_idx = strtoul(argv[1], NULL, 0);
758     printk("AppIdx set to 0x%04x\n", net.app_idx);
759     return 0;
760 }
761 
762 struct shell_cmd_help cmd_appidx_help = {
763     NULL, "[AppIdx]", NULL
764 };
765 
cmd_net_send(int argc,char * argv[])766 static int cmd_net_send(int argc, char *argv[])
767 {
768     struct os_mbuf *msg = NET_BUF_SIMPLE(32);
769     struct bt_mesh_msg_ctx ctx = {
770         .send_ttl = BT_MESH_TTL_DEFAULT,
771         .net_idx = net.net_idx,
772         .addr = net.dst,
773         .app_idx = net.app_idx,
774 
775     };
776     struct bt_mesh_net_tx tx = {
777         .ctx = &ctx,
778         .src = net.local,
779         .xmit = bt_mesh_net_transmit_get(),
780         .sub = bt_mesh_subnet_get(net.net_idx),
781     };
782     size_t len;
783     int err = 0;
784 
785     if (argc < 2) { // 2:Number of parameters
786         err = -EINVAL;
787         goto done;
788     }
789 
790     if (!tx.sub) {
791         printk("No matching subnet for NetKey Index 0x%04x\n",
792                net.net_idx);
793         goto done;
794     }
795 
796     net_buf_simple_init(msg, 0);
797     len = hex2bin(argv[1], msg->om_data, net_buf_simple_tailroom(msg) - 4); // 4:byte alignment
798     net_buf_simple_add(msg, len);
799     err = bt_mesh_trans_send(&tx, msg, NULL, NULL);
800     if (err) {
801         printk("Failed to send (err %d)\n", err);
802     }
803 
804 done:
805     os_mbuf_free_chain(msg);
806     return err;
807 }
808 
809 struct shell_cmd_help cmd_net_send_help = {
810     NULL, "<hex string>", NULL
811 };
812 
cmd_rpl_clear(int argc,char * argv[])813 static int cmd_rpl_clear(int argc, char *argv[])
814 {
815     bt_mesh_rpl_clear();
816     return 0;
817 }
818 
819 #if MYNEWT_VAL(BLE_MESH_LOW_POWER)
cmd_lpn_subscribe(int argc,char * argv[])820 static int cmd_lpn_subscribe(int argc, char *argv[])
821 {
822     u16_t address;
823 
824     if (argc < 2) { // 2:Number of parameters
825         return -EINVAL;
826     }
827 
828     address = strtoul(argv[1], NULL, 0);
829     printk("address 0x%04x", address);
830     bt_mesh_lpn_group_add(address);
831     return 0;
832 }
833 
834 struct shell_cmd_help cmd_lpn_subscribe_help = {
835     NULL, "<addr>", NULL
836 };
837 
cmd_lpn_unsubscribe(int argc,char * argv[])838 static int cmd_lpn_unsubscribe(int argc, char *argv[])
839 {
840     u16_t address;
841 
842     if (argc < 2) { // 2:Number of parameters
843         return -EINVAL;
844     }
845 
846     address = strtoul(argv[1], NULL, 0);
847     printk("address 0x%04x", address);
848     bt_mesh_lpn_group_del(&address, 1);
849     return 0;
850 }
851 
852 struct shell_cmd_help cmd_lpn_unsubscribe_help = {
853     NULL, "<addr>", NULL
854 };
855 #endif
856 
857 #if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST)
cmd_iv_update(int argc,char * argv[])858 static int cmd_iv_update(int argc, char *argv[])
859 {
860     if (bt_mesh_iv_update()) {
861         printk("Transitioned to IV Update In Progress state\n");
862     } else {
863         printk("Transitioned to IV Update Normal state\n");
864     }
865 
866     printk("IV Index is 0x%08lx\n", bt_mesh.iv_index);
867     return 0;
868 }
869 
cmd_iv_update_test(int argc,char * argv[])870 static int cmd_iv_update_test(int argc, char *argv[])
871 {
872     bool enable;
873 
874     if (argc < 2) { // 2:Number of parameters
875         return -EINVAL;
876     }
877 
878     enable = str2bool(argv[1]);
879     if (enable) {
880         printk("Enabling IV Update test mode\n");
881     } else {
882         printk("Disabling IV Update test mode\n");
883     }
884 
885     bt_mesh_iv_update_test(enable);
886     return 0;
887 }
888 
889 struct shell_cmd_help cmd_iv_update_test_help = {
890     NULL, "<value: off, on>", NULL
891 };
892 #endif
893 
894 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
895 
cmd_timeout(int argc,char * argv[])896 int cmd_timeout(int argc, char *argv[])
897 {
898     s32_t timeout;
899 
900     if (argc < 2) { // 2:Number of parameters
901         timeout = bt_mesh_cfg_cli_timeout_get();
902         if (timeout == K_FOREVER) {
903             printk("Message timeout: forever\n");
904         } else {
905             printk("Message timeout: %lu seconds\n",
906                    timeout / 1000); // 1000:time unit
907         }
908 
909         return 0;
910     }
911 
912     timeout = strtol(argv[1], NULL, 0);
913     if (timeout < 0 || timeout > (INT32_MAX / 1000)) { // 1000:time unit
914         timeout = K_FOREVER;
915     } else {
916         timeout = timeout * 1000; // 1000:time unit
917     }
918 
919     bt_mesh_cfg_cli_timeout_set(timeout);
920 
921     if (timeout == K_FOREVER) {
922         printk("Message timeout: forever\n");
923     } else {
924         printk("Message timeout: %lu seconds\n",
925                timeout / 1000);
926     }
927 
928     return 0;
929 }
930 
931 struct shell_cmd_help cmd_timeout_help = {
932     NULL, "[timeout in seconds]", NULL
933 };
934 
cmd_get_comp(int argc,char * argv[])935 static int cmd_get_comp(int argc, char *argv[])
936 {
937     struct os_mbuf *comp = NET_BUF_SIMPLE(32);
938     u8_t status, page = 0x00;
939     int err = 0;
940 
941     if (argc > 1) {
942         page = strtol(argv[1], NULL, 0);
943     }
944 
945     net_buf_simple_init(comp, 0);
946     err = bt_mesh_cfg_comp_data_get(net.net_idx, net.dst, page,
947                                     &status, comp);
948     if (err) {
949         printk("Getting composition failed (err %d)\n", err);
950         goto done;
951     }
952 
953     if (status != 0x00) {
954         printk("Got non-success status 0x%02x\n", status);
955         goto done;
956     }
957 
958     printk("Got Composition Data for 0x%04x:\n", net.dst);
959     printk("\tCID      0x%04x\n", net_buf_simple_pull_le16(comp));
960     printk("\tPID      0x%04x\n", net_buf_simple_pull_le16(comp));
961     printk("\tVID      0x%04x\n", net_buf_simple_pull_le16(comp));
962     printk("\tCRPL     0x%04x\n", net_buf_simple_pull_le16(comp));
963     printk("\tFeatures 0x%04x\n", net_buf_simple_pull_le16(comp));
964 
965     while (comp->om_len > 4) { // 4:Analyzing conditions
966         u8_t sig, vnd;
967         u16_t loc;
968         int i;
969         loc = net_buf_simple_pull_le16(comp);
970         sig = net_buf_simple_pull_u8(comp);
971         vnd = net_buf_simple_pull_u8(comp);
972         printk("\n\tElement @ 0x%04x:\n", loc);
973 
974         if (comp->om_len < ((sig * 2) + (vnd * 4))) { // 4:byte alignment, 2:byte alignment
975             printk("\t\t...truncated data!\n");
976             break;
977         }
978 
979         if (sig) {
980             printk("\t\tSIG Models:\n");
981         } else {
982             printk("\t\tNo SIG Models\n");
983         }
984 
985         for (i = 0; i < sig; i++) {
986             u16_t mod_id = net_buf_simple_pull_le16(comp);
987             printk("\t\t\t0x%04x\n", mod_id);
988         }
989 
990         if (vnd) {
991             printk("\t\tVendor Models:\n");
992         } else {
993             printk("\t\tNo Vendor Models\n");
994         }
995 
996         for (i = 0; i < vnd; i++) {
997             u16_t cid = net_buf_simple_pull_le16(comp);
998             u16_t mod_id = net_buf_simple_pull_le16(comp);
999             printk("\t\t\tCompany 0x%04x: 0x%04x\n", cid, mod_id);
1000         }
1001     }
1002 
1003 done:
1004     os_mbuf_free_chain(comp);
1005     return err;
1006 }
1007 
1008 struct shell_cmd_help cmd_get_comp_help = {
1009     NULL, "[page]", NULL
1010 };
1011 
cmd_beacon(int argc,char * argv[])1012 static int cmd_beacon(int argc, char *argv[])
1013 {
1014     u8_t status;
1015     int err;
1016 
1017     if (argc < 2) { // 2:Number of parameters
1018         err = bt_mesh_cfg_beacon_get(net.net_idx, net.dst, &status);
1019     } else {
1020         u8_t val = str2u8(argv[1]);
1021         err = bt_mesh_cfg_beacon_set(net.net_idx, net.dst, val,
1022                                      &status);
1023     }
1024 
1025     if (err) {
1026         printk("Unable to send Beacon Get/Set message (err %d)\n", err);
1027         return 0;
1028     }
1029 
1030     printk("Beacon state is 0x%02x\n", status);
1031     return 0;
1032 }
1033 
1034 struct shell_cmd_help cmd_beacon_help = {
1035     NULL, "[val: off, on]", NULL
1036 };
1037 
cmd_ttl(int argc,char * argv[])1038 static int cmd_ttl(int argc, char *argv[])
1039 {
1040     u8_t ttl;
1041     int err;
1042 
1043     if (argc < 2) { // 2:Number of parameters
1044         err = bt_mesh_cfg_ttl_get(net.net_idx, net.dst, &ttl);
1045     } else {
1046         u8_t val = strtoul(argv[1], NULL, 0);
1047         err = bt_mesh_cfg_ttl_set(net.net_idx, net.dst, val, &ttl);
1048     }
1049 
1050     if (err) {
1051         printk("Unable to send Default TTL Get/Set (err %d)\n", err);
1052         return 0;
1053     }
1054 
1055     printk("Default TTL is 0x%02x\n", ttl);
1056     return 0;
1057 }
1058 
1059 struct shell_cmd_help cmd_ttl_help = {
1060     NULL, "[ttl: 0x00, 0x02-0x7f]", NULL
1061 };
1062 
cmd_friend(int argc,char * argv[])1063 static int cmd_friend(int argc, char *argv[])
1064 {
1065     u8_t frnd;
1066     int err;
1067 
1068     if (argc < 2) { // 2:Number of parameters
1069         err = bt_mesh_cfg_friend_get(net.net_idx, net.dst, &frnd);
1070     } else {
1071         u8_t val = str2u8(argv[1]);
1072         err = bt_mesh_cfg_friend_set(net.net_idx, net.dst, val, &frnd);
1073     }
1074 
1075     if (err) {
1076         printk("Unable to send Friend Get/Set (err %d)\n", err);
1077         return 0;
1078     }
1079 
1080     printk("Friend is set to 0x%02x\n", frnd);
1081     return 0;
1082 }
1083 
1084 struct shell_cmd_help cmd_friend_help = {
1085     NULL, "[val: off, on]", NULL
1086 };
1087 
cmd_gatt_proxy(int argc,char * argv[])1088 static int cmd_gatt_proxy(int argc, char *argv[])
1089 {
1090     u8_t proxy;
1091     int err;
1092 
1093     if (argc < 2) { // 2:Number of parameters
1094         err = bt_mesh_cfg_gatt_proxy_get(net.net_idx, net.dst, &proxy);
1095     } else {
1096         u8_t val = str2u8(argv[1]);
1097         err = bt_mesh_cfg_gatt_proxy_set(net.net_idx, net.dst, val,
1098                                          &proxy);
1099     }
1100 
1101     if (err) {
1102         printk("Unable to send GATT Proxy Get/Set (err %d)\n", err);
1103         return 0;
1104     }
1105 
1106     printk("GATT Proxy is set to 0x%02x\n", proxy);
1107     return 0;
1108 }
1109 
1110 struct shell_cmd_help cmd_gatt_proxy_help = {
1111     NULL, "[val: off, on]", NULL
1112 };
1113 
cmd_relay(int argc,char * argv[])1114 static int cmd_relay(int argc, char *argv[])
1115 {
1116     u8_t relay, transmit;
1117     int err;
1118 
1119     if (argc < 2) { // 2:Number of parameters
1120         err = bt_mesh_cfg_relay_get(net.net_idx, net.dst, &relay,
1121                                     &transmit);
1122     } else {
1123         u8_t val = str2u8(argv[1]);
1124         u8_t count, interval, new_transmit;
1125 
1126         if (val) {
1127             if (argc > 2) { // 2:Number of parameters
1128                 count = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1129             } else {
1130                 count = 2; // 2:value of count
1131             }
1132 
1133             if (argc > 3) { // 3:Number of parameters
1134                 interval = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1135             } else {
1136                 interval = 20; // 20:value of interval
1137             }
1138 
1139             new_transmit = BT_MESH_TRANSMIT(count, interval);
1140         } else {
1141             new_transmit = 0;
1142         }
1143 
1144         err = bt_mesh_cfg_relay_set(net.net_idx, net.dst, val,
1145                                     new_transmit, &relay, &transmit);
1146     }
1147 
1148     if (err) {
1149         printk("Unable to send Relay Get/Set (err %d)\n", err);
1150         return 0;
1151     }
1152 
1153     printk("Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)\n",
1154            relay, transmit, BT_MESH_TRANSMIT_COUNT(transmit),
1155            BT_MESH_TRANSMIT_INT(transmit));
1156     return 0;
1157 }
1158 
1159 struct shell_cmd_help cmd_relay_help = {
1160     NULL, "[val: off, on] [count: 0-7] [interval: 0-32]", NULL
1161 };
1162 
cmd_net_key_add(int argc,char * argv[])1163 static int cmd_net_key_add(int argc, char *argv[])
1164 {
1165     u8_t key_val[16];
1166     u16_t key_net_idx;
1167     u8_t status;
1168     int err;
1169 
1170     if (argc < 2) { // 2:Number of parameters
1171         return -EINVAL;
1172     }
1173 
1174     key_net_idx = strtoul(argv[1], NULL, 0);
1175 
1176     if (argc > 2) { // 2:Number of parameters
1177         size_t len;
1178         len = hex2bin(argv[3], key_val, sizeof(key_val)); // 3:Number of parameters
1179         memset(key_val, 0, sizeof(key_val) - len);
1180     } else {
1181         memcpy(key_val, default_key, sizeof(key_val));
1182     }
1183 
1184     err = bt_mesh_cfg_net_key_add(net.net_idx, net.dst, key_net_idx,
1185                                   key_val, &status);
1186     if (err) {
1187         printk("Unable to send NetKey Add (err %d)\n", err);
1188         return 0;
1189     }
1190 
1191     if (status) {
1192         printk("NetKeyAdd failed with status 0x%02x\n", status);
1193     } else {
1194         printk("NetKey added with NetKey Index 0x%03x\n", key_net_idx);
1195     }
1196 
1197     return 0;
1198 }
1199 
1200 struct shell_cmd_help cmd_net_key_add_help = {
1201     NULL, "<NetKeyIndex> [val]", NULL
1202 };
1203 
cmd_app_key_add(int argc,char * argv[])1204 static int cmd_app_key_add(int argc, char *argv[])
1205 {
1206     u8_t key_val[16];
1207     u16_t key_net_idx, key_app_idx;
1208     u8_t status;
1209     int err;
1210 
1211     if (argc < 3) { // 3:Number of parameters
1212         return -EINVAL;
1213     }
1214 
1215     key_net_idx = strtoul(argv[1], NULL, 0);
1216     key_app_idx = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1217 
1218     if (argc > 3) { // 3:Number of parameters
1219         size_t len;
1220         len = hex2bin(argv[3], key_val, sizeof(key_val)); // 3:Number of parameters
1221         memset(key_val, 0, sizeof(key_val) - len);
1222     } else {
1223         memcpy(key_val, default_key, sizeof(key_val));
1224     }
1225 
1226     err = bt_mesh_cfg_app_key_add(net.net_idx, net.dst, key_net_idx,
1227                                   key_app_idx, key_val, &status);
1228     if (err) {
1229         printk("Unable to send App Key Add (err %d)\n", err);
1230         return 0;
1231     }
1232 
1233     if (status) {
1234         printk("AppKeyAdd failed with status 0x%02x\n", status);
1235     } else {
1236         printk("AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x\n",
1237                key_net_idx, key_app_idx);
1238     }
1239 
1240     return 0;
1241 }
1242 
1243 struct shell_cmd_help cmd_app_key_add_help = {
1244     NULL, "<NetKeyIndex> <AppKeyIndex> [val]", NULL
1245 };
1246 
cmd_mod_app_bind(int argc,char * argv[])1247 static int cmd_mod_app_bind(int argc, char *argv[])
1248 {
1249     u16_t elem_addr, mod_app_idx, mod_id, cid;
1250     u8_t status;
1251     int err;
1252 
1253     if (argc < 4) { // 4:Number of parameters
1254         return -EINVAL;
1255     }
1256 
1257     elem_addr = strtoul(argv[1], NULL, 0);
1258     mod_app_idx = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1259     mod_id = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1260 
1261     if (argc > 4) { // 4:Number of parameters
1262         cid = strtoul(argv[4], NULL, 0); // 4:Number of parameters
1263         err = bt_mesh_cfg_mod_app_bind_vnd(net.net_idx, net.dst,
1264                                            elem_addr, mod_app_idx,
1265                                            mod_id, cid, &status);
1266     } else {
1267         err = bt_mesh_cfg_mod_app_bind(net.net_idx, net.dst, elem_addr,
1268                                        mod_app_idx, mod_id, &status);
1269     }
1270 
1271     if (err) {
1272         printk("Unable to send Model App Bind (err %d)\n", err);
1273         return 0;
1274     }
1275 
1276     if (status) {
1277         printk("Model App Bind failed with status 0x%02x\n", status);
1278     } else {
1279         printk("AppKey successfully bound\n");
1280     }
1281 
1282     return 0;
1283 }
1284 
1285 struct shell_cmd_help cmd_mod_app_bind_help = {
1286     NULL, "<addr> <AppIndex> <Model ID> [Company ID]", NULL
1287 };
1288 
cmd_mod_sub_add(int argc,char * argv[])1289 static int cmd_mod_sub_add(int argc, char *argv[])
1290 {
1291     u16_t elem_addr, sub_addr, mod_id, cid;
1292     u8_t status;
1293     int err;
1294 
1295     if (argc < 4) { // 4:Number of parameters
1296         return -EINVAL;
1297     }
1298 
1299     elem_addr = strtoul(argv[1], NULL, 0);
1300     sub_addr = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1301     mod_id = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1302 
1303     if (argc > 4) { // 4:Number of parameters
1304         cid = strtoul(argv[4], NULL, 0); // 4:Number of parameters
1305         err = bt_mesh_cfg_mod_sub_add_vnd(net.net_idx, net.dst,
1306                                           elem_addr, sub_addr, mod_id,
1307                                           cid, &status);
1308     } else {
1309         err = bt_mesh_cfg_mod_sub_add(net.net_idx, net.dst, elem_addr,
1310                                       sub_addr, mod_id, &status);
1311     }
1312 
1313     if (err) {
1314         printk("Unable to send Model Subscription Add (err %d)\n", err);
1315         return 0;
1316     }
1317 
1318     if (status) {
1319         printk("Model Subscription Add failed with status 0x%02x\n",
1320                status);
1321     } else {
1322         printk("Model subscription was successful\n");
1323     }
1324 
1325     return 0;
1326 }
1327 
1328 struct shell_cmd_help cmd_mod_sub_add_help = {
1329     NULL, "<elem addr> <sub addr> <Model ID> [Company ID]", NULL
1330 };
1331 
cmd_mod_sub_del(int argc,char * argv[])1332 static int cmd_mod_sub_del(int argc, char *argv[])
1333 {
1334     u16_t elem_addr, sub_addr, mod_id, cid;
1335     u8_t status;
1336     int err;
1337 
1338     if (argc < 4) { // 4:Number of parameters
1339         return -EINVAL;
1340     }
1341 
1342     elem_addr = strtoul(argv[1], NULL, 0);
1343     sub_addr = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1344     mod_id = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1345 
1346     if (argc > 4) { // 4:Number of parameters
1347         cid = strtoul(argv[4], NULL, 0); // 4:Number of parameters
1348         err = bt_mesh_cfg_mod_sub_del_vnd(net.net_idx, net.dst,
1349                                           elem_addr, sub_addr, mod_id,
1350                                           cid, &status);
1351     } else {
1352         err = bt_mesh_cfg_mod_sub_del(net.net_idx, net.dst, elem_addr,
1353                                       sub_addr, mod_id, &status);
1354     }
1355 
1356     if (err) {
1357         printk("Unable to send Model Subscription Delete (err %d)\n",
1358                err);
1359         return 0;
1360     }
1361 
1362     if (status) {
1363         printk("Model Subscription Delete failed with status 0x%02x\n",
1364                status);
1365     } else {
1366         printk("Model subscription deltion was successful\n");
1367     }
1368 
1369     return 0;
1370 }
1371 
1372 struct shell_cmd_help cmd_mod_sub_del_help = {
1373     NULL, "<elem addr> <sub addr> <Model ID> [Company ID]", NULL
1374 };
1375 
cmd_mod_sub_add_va(int argc,char * argv[])1376 static int cmd_mod_sub_add_va(int argc, char *argv[])
1377 {
1378     u16_t elem_addr, sub_addr, mod_id, cid;
1379     u8_t label[16];
1380     u8_t status;
1381     size_t len;
1382     int err;
1383 
1384     if (argc < 4) { // 4:Number of parameters
1385         return -EINVAL;
1386     }
1387 
1388     elem_addr = strtoul(argv[1], NULL, 0);
1389     len = hex2bin(argv[2], label, sizeof(label)); // 2:Number of parameters
1390     memset(label + len, 0, sizeof(label) - len);
1391     mod_id = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1392 
1393     if (argc > 4) { // 4:Number of parameters
1394         cid = strtoul(argv[4], NULL, 0); // 4:Number of parameters
1395         err = bt_mesh_cfg_mod_sub_va_add_vnd(net.net_idx, net.dst,
1396                                              elem_addr, label, mod_id,
1397                                              cid, &sub_addr, &status);
1398     } else {
1399         err = bt_mesh_cfg_mod_sub_va_add(net.net_idx, net.dst,
1400                                          elem_addr, label, mod_id,
1401                                          &sub_addr, &status);
1402     }
1403 
1404     if (err) {
1405         printk("Unable to send Mod Sub VA Add (err %d)\n", err);
1406         return 0;
1407     }
1408 
1409     if (status) {
1410         printk("Mod Sub VA Add failed with status 0x%02x\n",
1411                status);
1412     } else {
1413         printk("0x%04x subscribed to Label UUID %s (va 0x%04x)\n",
1414                elem_addr, argv[2], sub_addr);
1415     }
1416 
1417     return 0;
1418 }
1419 
1420 struct shell_cmd_help cmd_mod_sub_add_va_help = {
1421     NULL, "<elem addr> <Label UUID> <Model ID> [Company ID]", NULL
1422 };
1423 
cmd_mod_sub_del_va(int argc,char * argv[])1424 static int cmd_mod_sub_del_va(int argc, char *argv[])
1425 {
1426     u16_t elem_addr, sub_addr, mod_id, cid;
1427     u8_t label[16];
1428     u8_t status;
1429     size_t len;
1430     int err;
1431 
1432     if (argc < 4) { // 4:Number of parameters
1433         return -EINVAL;
1434     }
1435 
1436     elem_addr = strtoul(argv[1], NULL, 0);
1437     len = hex2bin(argv[2], label, sizeof(label)); // 2:Number of parameters
1438     memset(label + len, 0, sizeof(label) - len);
1439     mod_id = strtoul(argv[3], NULL, 0); // 3:Number of parameters
1440 
1441     if (argc > 4) { // 4:Number of parameters
1442         cid = strtoul(argv[4], NULL, 0); // 4:Number of parameters
1443         err = bt_mesh_cfg_mod_sub_va_del_vnd(net.net_idx, net.dst,
1444                                              elem_addr, label, mod_id,
1445                                              cid, &sub_addr, &status);
1446     } else {
1447         err = bt_mesh_cfg_mod_sub_va_del(net.net_idx, net.dst,
1448                                          elem_addr, label, mod_id,
1449                                          &sub_addr, &status);
1450     }
1451 
1452     if (err) {
1453         printk("Unable to send Model Subscription Delete (err %d)\n",
1454                err);
1455         return 0;
1456     }
1457 
1458     if (status) {
1459         printk("Model Subscription Delete failed with status 0x%02x\n",
1460                status);
1461     } else {
1462         printk("0x%04x unsubscribed from Label UUID %s (va 0x%04x)\n",
1463                elem_addr, argv[2], sub_addr);
1464     }
1465 
1466     return 0;
1467 }
1468 
1469 struct shell_cmd_help cmd_mod_sub_del_va_help = {
1470     NULL, "<elem addr> <Label UUID> <Model ID> [Company ID]", NULL
1471 };
1472 
mod_pub_get(u16_t addr,u16_t mod_id,u16_t cid)1473 static int mod_pub_get(u16_t addr, u16_t mod_id, u16_t cid)
1474 {
1475     struct bt_mesh_cfg_mod_pub pub;
1476     u8_t status;
1477     int err;
1478 
1479     if (cid == CID_NVAL) {
1480         err = bt_mesh_cfg_mod_pub_get(net.net_idx, net.dst, addr,
1481                                       mod_id, &pub, &status);
1482     } else {
1483         err = bt_mesh_cfg_mod_pub_get_vnd(net.net_idx, net.dst, addr,
1484                                           mod_id, cid, &pub, &status);
1485     }
1486 
1487     if (err) {
1488         printk("Model Publication Get failed (err %d)\n", err);
1489         return 0;
1490     }
1491 
1492     if (status) {
1493         printk("Model Publication Get failed (status 0x%02x)\n",
1494                status);
1495         return 0;
1496     }
1497 
1498     printk("Model Publication for Element 0x%04x, Model 0x%04x:\n"
1499            "\tPublish Address:                0x%04x\n"
1500            "\tAppKeyIndex:                    0x%04x\n"
1501            "\tCredential Flag:                %u\n"
1502            "\tPublishTTL:                     %u\n"
1503            "\tPublishPeriod:                  0x%02x\n"
1504            "\tPublishRetransmitCount:         %u\n"
1505            "\tPublishRetransmitInterval:      %ums\n",
1506            addr, mod_id, pub.addr, pub.app_idx, pub.cred_flag, pub.ttl,
1507            pub.period, BT_MESH_PUB_TRANSMIT_COUNT(pub.transmit),
1508            BT_MESH_PUB_TRANSMIT_INT(pub.transmit));
1509     return 0;
1510 }
1511 
mod_pub_set(u16_t addr,u16_t mod_id,u16_t cid,char * argv[])1512 static int mod_pub_set(u16_t addr, u16_t mod_id, u16_t cid, char *argv[])
1513 {
1514     struct bt_mesh_cfg_mod_pub pub;
1515     u8_t status, count;
1516     u16_t interval;
1517     int err;
1518     pub.addr = strtoul(argv[0], NULL, 0);
1519     pub.app_idx = strtoul(argv[1], NULL, 0);
1520     pub.cred_flag = str2bool(argv[2]); // 2:parameters 2
1521     pub.ttl = strtoul(argv[3], NULL, 0); // 3:parameters 3
1522     pub.period = strtoul(argv[4], NULL, 0); // 4:parameters 4
1523     count = strtoul(argv[5], NULL, 0); // 5:parameters 5
1524     if (count > 7) { // 7:Analyzing conditions
1525         printk("Invalid retransmit count\n");
1526         return -EINVAL;
1527     }
1528 
1529     interval = strtoul(argv[6], NULL, 0); // 6:parameters 6
1530     if (interval > (31 * 50) || (interval % 50)) { // 31:byte alignment, 50:byte alignment
1531         printk("Invalid retransmit interval %u\n", interval);
1532         return -EINVAL;
1533     }
1534 
1535     pub.transmit = BT_MESH_PUB_TRANSMIT(count, interval);
1536 
1537     if (cid == CID_NVAL) {
1538         err = bt_mesh_cfg_mod_pub_set(net.net_idx, net.dst, addr,
1539                                       mod_id, &pub, &status);
1540     } else {
1541         err = bt_mesh_cfg_mod_pub_set_vnd(net.net_idx, net.dst, addr,
1542                                           mod_id, cid, &pub, &status);
1543     }
1544 
1545     if (err) {
1546         printk("Model Publication Set failed (err %d)\n", err);
1547         return 0;
1548     }
1549 
1550     if (status) {
1551         printk("Model Publication Set failed (status 0x%02x)\n",
1552                status);
1553     } else {
1554         printk("Model Publication successfully set\n");
1555     }
1556 
1557     return 0;
1558 }
1559 
cmd_mod_pub(int argc,char * argv[])1560 static int cmd_mod_pub(int argc, char *argv[])
1561 {
1562     u16_t addr, mod_id, cid;
1563 
1564     if (argc < 3) { // 3:Number of parameters
1565         return -EINVAL;
1566     }
1567 
1568     addr = strtoul(argv[1], NULL, 0);
1569     mod_id = strtoul(argv[2], NULL, 0); // 2: parameters 2
1570     argc -= 3; // 3:byte alignment
1571     argv += 3; // 3:byte alignment
1572 
1573     if (argc == 1 || argc == 8) { // 8:parameters 8
1574         cid = strtoul(argv[0], NULL, 0);
1575         argc--;
1576         argv++;
1577     } else {
1578         cid = CID_NVAL;
1579     }
1580 
1581     if (argc > 0) {
1582         if (argc < 7) { // 7:Number of parameters
1583             return -EINVAL;
1584         }
1585 
1586         return mod_pub_set(addr, mod_id, cid, argv);
1587     } else {
1588         return mod_pub_get(addr, mod_id, cid);
1589     }
1590 }
1591 
1592 struct shell_cmd_help cmd_mod_pub_help = {
1593     NULL, "<addr> <mod id> [cid] [<PubAddr> <AppKeyIndex> <cred> <ttl> <period> <count> <interval>]", NULL
1594 };
1595 
hb_sub_print(struct bt_mesh_cfg_hb_sub * sub)1596 static void hb_sub_print(struct bt_mesh_cfg_hb_sub *sub)
1597 {
1598     printk("Heartbeat Subscription:\n"
1599            "\tSource:      0x%04x\n"
1600            "\tDestination: 0x%04x\n"
1601            "\tPeriodLog:   0x%02x\n"
1602            "\tCountLog:    0x%02x\n"
1603            "\tMinHops:     %u\n"
1604            "\tMaxHops:     %u\n",
1605            sub->src, sub->dst, sub->period, sub->count,
1606            sub->min, sub->max);
1607 }
1608 
hb_sub_get(int argc,char * argv[])1609 static int hb_sub_get(int argc, char *argv[])
1610 {
1611     struct bt_mesh_cfg_hb_sub sub;
1612     u8_t status;
1613     int err;
1614     err = bt_mesh_cfg_hb_sub_get(net.net_idx, net.dst, &sub, &status);
1615     if (err) {
1616         printk("Heartbeat Subscription Get failed (err %d)\n", err);
1617         return 0;
1618     }
1619 
1620     if (status) {
1621         printk("Heartbeat Subscription Get failed (status 0x%02x)\n",
1622                status);
1623     } else {
1624         hb_sub_print(&sub);
1625     }
1626 
1627     return 0;
1628 }
1629 
hb_sub_set(int argc,char * argv[])1630 static int hb_sub_set(int argc, char *argv[])
1631 {
1632     struct bt_mesh_cfg_hb_sub sub;
1633     u8_t status;
1634     int err;
1635     sub.src = strtoul(argv[1], NULL, 0);
1636     sub.dst = strtoul(argv[2], NULL, 0); // 2: parameters 2
1637     sub.period = strtoul(argv[3], NULL, 0); // 3: parameters 3
1638     err = bt_mesh_cfg_hb_sub_set(net.net_idx, net.dst, &sub, &status);
1639     if (err) {
1640         printk("Heartbeat Subscription Set failed (err %d)\n", err);
1641         return 0;
1642     }
1643 
1644     if (status) {
1645         printk("Heartbeat Subscription Set failed (status 0x%02x)\n",
1646                status);
1647     } else {
1648         hb_sub_print(&sub);
1649     }
1650 
1651     return 0;
1652 }
1653 
cmd_hb_sub(int argc,char * argv[])1654 static int cmd_hb_sub(int argc, char *argv[])
1655 {
1656     if (argc > 1) {
1657         if (argc < 4) { // 4:Number of parameters
1658             return -EINVAL;
1659         }
1660 
1661         return hb_sub_set(argc, argv);
1662     } else {
1663         return hb_sub_get(argc, argv);
1664     }
1665 }
1666 
1667 struct shell_cmd_help cmd_hb_sub_help = {
1668     NULL, "<src> <dst> <period>", NULL
1669 };
1670 
hb_pub_get(int argc,char * argv[])1671 static int hb_pub_get(int argc, char *argv[])
1672 {
1673     struct bt_mesh_cfg_hb_pub pub;
1674     u8_t status;
1675     int err;
1676     err = bt_mesh_cfg_hb_pub_get(net.net_idx, net.dst, &pub, &status);
1677     if (err) {
1678         printk("Heartbeat Publication Get failed (err %d)\n", err);
1679         return 0;
1680     }
1681 
1682     if (status) {
1683         printk("Heartbeat Publication Get failed (status 0x%02x)\n",
1684                status);
1685         return 0;
1686     }
1687 
1688     printk("Heartbeat publication:\n");
1689     printk("\tdst 0x%04x count 0x%02x period 0x%02x\n",
1690            pub.dst, pub.count, pub.period);
1691     printk("\tttl 0x%02x feat 0x%04x net_idx 0x%04x\n",
1692            pub.ttl, pub.feat, pub.net_idx);
1693     return 0;
1694 }
1695 
hb_pub_set(int argc,char * argv[])1696 static int hb_pub_set(int argc, char *argv[])
1697 {
1698     struct bt_mesh_cfg_hb_pub pub;
1699     u8_t status;
1700     int err;
1701     pub.dst = strtoul(argv[1], NULL, 0);
1702     pub.count = strtoul(argv[2], NULL, 0);
1703     pub.period = strtoul(argv[3], NULL, 0);
1704     pub.ttl = strtoul(argv[4], NULL, 0);
1705     pub.feat = strtoul(argv[5], NULL, 0);
1706     pub.net_idx = strtoul(argv[5], NULL, 0);
1707     err = bt_mesh_cfg_hb_pub_set(net.net_idx, net.dst, &pub, &status);
1708     if (err) {
1709         printk("Heartbeat Publication Set failed (err %d)\n", err);
1710         return 0;
1711     }
1712 
1713     if (status) {
1714         printk("Heartbeat Publication Set failed (status 0x%02x)\n",
1715                status);
1716     } else {
1717         printk("Heartbeat publication successfully set\n");
1718     }
1719 
1720     return 0;
1721 }
1722 
cmd_hb_pub(int argc,char * argv[])1723 static int cmd_hb_pub(int argc, char *argv[])
1724 {
1725     if (argc > 1) {
1726         if (argc < 7) { // 7:Number of parameters
1727             return -EINVAL;
1728         }
1729 
1730         return hb_pub_set(argc, argv);
1731     } else {
1732         return hb_pub_get(argc, argv);
1733     }
1734 }
1735 
1736 struct shell_cmd_help cmd_hb_pub_help = {
1737     NULL, "<dst> <count> <period> <ttl> <features> <NetKeyIndex>", NULL
1738 };
1739 
1740 #endif /* MYNEWT_VAL(BLE_MESH_CFG_CLI) */
1741 
1742 #if MYNEWT_VAL(BLE_MESH_PROV)
cmd_pb(bt_mesh_prov_bearer_t bearer,int argc,char * argv[])1743 static int cmd_pb(bt_mesh_prov_bearer_t bearer, int argc, char *argv[])
1744 {
1745     int err;
1746 
1747     if (argc < 2) { // 2:Number of parameters
1748         return -EINVAL;
1749     }
1750 
1751     if (str2bool(argv[1])) {
1752         err = bt_mesh_prov_enable(bearer);
1753         if (err) {
1754             printk("Failed to enable %s (err %d)\n",
1755                    bearer2str(bearer), err);
1756         } else {
1757             printk("%s enabled\n", bearer2str(bearer));
1758         }
1759     } else {
1760         err = bt_mesh_prov_disable(bearer);
1761         if (err) {
1762             printk("Failed to disable %s (err %d)\n",
1763                    bearer2str(bearer), err);
1764         } else {
1765             printk("%s disabled\n", bearer2str(bearer));
1766         }
1767     }
1768 
1769     return 0;
1770 }
1771 
1772 struct shell_cmd_help cmd_pb_help = {
1773     NULL, "<val: off, on>", NULL
1774 };
1775 
1776 #endif
1777 
1778 #if MYNEWT_VAL(BLE_MESH_PB_ADV)
cmd_pb_adv(int argc,char * argv[])1779 static int cmd_pb_adv(int argc, char *argv[])
1780 {
1781     return cmd_pb(BT_MESH_PROV_ADV, argc, argv);
1782 }
1783 
1784 #if MYNEWT_VAL(BLE_MESH_PROVISIONER)
cmd_provision_adv(int argc,char * argv[])1785 static int cmd_provision_adv(int argc, char *argv[])
1786 {
1787     u8_t uuid[16];
1788     u8_t attention_duration;
1789     u16_t net_idx;
1790     u16_t addr;
1791     size_t len;
1792     int err;
1793     len = hex2bin(argv[1], uuid, sizeof(uuid));
1794     (void)memset(uuid + len, 0, sizeof(uuid) - len);
1795     net_idx = strtoul(argv[2], NULL, 0);
1796     addr = strtoul(argv[3], NULL, 0);
1797     attention_duration = strtoul(argv[4], NULL, 0);
1798     err = bt_mesh_provision_adv(uuid, net_idx, addr, attention_duration);
1799     if (err) {
1800         printk("Provisioning failed (err %d)", err);
1801     }
1802 
1803     return 0;
1804 }
1805 
1806 struct shell_cmd_help cmd_provision_adv_help = {
1807     NULL, "<UUID> <NetKeyIndex> <addr> <AttentionDuration>", NULL
1808 };
1809 #endif /* CONFIG_BT_MESH_PROVISIONER */
1810 
1811 #endif /* CONFIG_BT_MESH_PB_ADV */
1812 
1813 #if MYNEWT_VAL(BLE_MESH_PB_GATT)
cmd_pb_gatt(int argc,char * argv[])1814 static int cmd_pb_gatt(int argc, char *argv[])
1815 {
1816     return cmd_pb(BT_MESH_PROV_GATT, argc, argv);
1817 }
1818 #endif /* CONFIG_BT_MESH_PB_GATT */
1819 
cmd_provision(int argc,char * argv[])1820 static int cmd_provision(int argc, char *argv[])
1821 {
1822     u16_t net_idx, addr;
1823     u32_t iv_index;
1824     int err;
1825 
1826     if (argc < 3) { // 3:Number of parameters
1827         return -EINVAL;
1828     }
1829 
1830     net_idx = strtoul(argv[1], NULL, 0);
1831     addr = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1832 
1833     if (argc > 3) { // 3:Number of parameters
1834         iv_index = strtoul(argv[3], NULL, 0); // 3:parameters 3
1835     } else {
1836         iv_index = 0;
1837     }
1838 
1839     err = bt_mesh_provision(default_key, net_idx, 0, iv_index, addr,
1840                             default_key);
1841     if (err) {
1842         printk("Provisioning failed (err %d)\n", err);
1843     }
1844 
1845     return 0;
1846 }
1847 
1848 struct shell_cmd_help cmd_provision_help = {
1849     NULL, "<NetKeyIndex> <addr> [IVIndex]", NULL
1850 };
1851 
1852 #if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
1853 
cmd_fault_get(int argc,char * argv[])1854 static int cmd_fault_get(int argc, char *argv[])
1855 {
1856     u8_t faults[32];
1857     size_t fault_count;
1858     u8_t test_id;
1859     u16_t cid;
1860     int err;
1861 
1862     if (argc < 2) { // 2:Number of parameters
1863         return -EINVAL;
1864     }
1865 
1866     cid = strtoul(argv[1], NULL, 0);
1867     fault_count = sizeof(faults);
1868     err = bt_mesh_health_fault_get(net.net_idx, net.dst, net.app_idx, cid,
1869                                    &test_id, faults, &fault_count);
1870     if (err) {
1871         printk("Failed to send Health Fault Get (err %d)\n", err);
1872     } else {
1873         show_faults(test_id, cid, faults, fault_count);
1874     }
1875 
1876     return 0;
1877 }
1878 
1879 struct shell_cmd_help cmd_fault_get_help = {
1880     NULL, "<Company ID>", NULL
1881 };
1882 
cmd_fault_clear(int argc,char * argv[])1883 static int cmd_fault_clear(int argc, char *argv[])
1884 {
1885     u8_t faults[32];
1886     size_t fault_count;
1887     u8_t test_id;
1888     u16_t cid;
1889     int err;
1890 
1891     if (argc < 2) { // 2:Number of parameters
1892         return -EINVAL;
1893     }
1894 
1895     cid = strtoul(argv[1], NULL, 0);
1896     fault_count = sizeof(faults);
1897     err = bt_mesh_health_fault_clear(net.net_idx, net.dst, net.app_idx,
1898                                      cid, &test_id, faults, &fault_count);
1899     if (err) {
1900         printk("Failed to send Health Fault Clear (err %d)\n", err);
1901     } else {
1902         show_faults(test_id, cid, faults, fault_count);
1903     }
1904 
1905     return 0;
1906 }
1907 
1908 struct shell_cmd_help cmd_fault_clear_help = {
1909     NULL, "<Company ID>", NULL
1910 };
1911 
cmd_fault_clear_unack(int argc,char * argv[])1912 static int cmd_fault_clear_unack(int argc, char *argv[])
1913 {
1914     u16_t cid;
1915     int err;
1916 
1917     if (argc < 2) { // 2:Number of parameters
1918         return -EINVAL;
1919     }
1920 
1921     cid = strtoul(argv[1], NULL, 0);
1922     err = bt_mesh_health_fault_clear(net.net_idx, net.dst, net.app_idx,
1923                                      cid, NULL, NULL, NULL);
1924     if (err) {
1925         printk("Health Fault Clear Unacknowledged failed (err %d)\n",
1926                err);
1927     }
1928 
1929     return 0;
1930 }
1931 
1932 struct shell_cmd_help cmd_fault_clear_unack_help = {
1933     NULL, "<Company ID>", NULL
1934 };
1935 
cmd_fault_test(int argc,char * argv[])1936 static int cmd_fault_test(int argc, char *argv[])
1937 {
1938     u8_t faults[32];
1939     size_t fault_count;
1940     u8_t test_id;
1941     u16_t cid;
1942     int err;
1943 
1944     if (argc < 3) { // 3:Number of parameters
1945         return -EINVAL;
1946     }
1947 
1948     cid = strtoul(argv[1], NULL, 0);
1949     test_id = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1950     fault_count = sizeof(faults);
1951     err = bt_mesh_health_fault_test(net.net_idx, net.dst, net.app_idx,
1952                                     cid, test_id, faults, &fault_count);
1953     if (err) {
1954         printk("Failed to send Health Fault Test (err %d)\n", err);
1955     } else {
1956         show_faults(test_id, cid, faults, fault_count);
1957     }
1958 
1959     return 0;
1960 }
1961 
1962 struct shell_cmd_help cmd_fault_test_help = {
1963     NULL, "<Company ID> <Test ID>", NULL
1964 };
1965 
cmd_fault_test_unack(int argc,char * argv[])1966 static int cmd_fault_test_unack(int argc, char *argv[])
1967 {
1968     u16_t cid;
1969     u8_t test_id;
1970     int err;
1971 
1972     if (argc < 3) { // 3:Number of parameters
1973         return -EINVAL;
1974     }
1975 
1976     cid = strtoul(argv[1], NULL, 0);
1977     test_id = strtoul(argv[2], NULL, 0); // 2:Number of parameters
1978     err = bt_mesh_health_fault_test(net.net_idx, net.dst, net.app_idx,
1979                                     cid, test_id, NULL, NULL);
1980     if (err) {
1981         printk("Health Fault Test Unacknowledged failed (err %d)\n",
1982                err);
1983     }
1984 
1985     return 0;
1986 }
1987 
1988 struct shell_cmd_help cmd_fault_test_unack_help = {
1989     NULL, "<Company ID> <Test ID>", NULL
1990 };
1991 
cmd_period_get(int argc,char * argv[])1992 static int cmd_period_get(int argc, char *argv[])
1993 {
1994     u8_t divisor;
1995     int err;
1996     err = bt_mesh_health_period_get(net.net_idx, net.dst, net.app_idx,
1997                                     &divisor);
1998     if (err) {
1999         printk("Failed to send Health Period Get (err %d)\n", err);
2000     } else {
2001         printk("Health FastPeriodDivisor: %u\n", divisor);
2002     }
2003 
2004     return 0;
2005 }
2006 
cmd_period_set(int argc,char * argv[])2007 static int cmd_period_set(int argc, char *argv[])
2008 {
2009     u8_t divisor, updated_divisor;
2010     int err;
2011 
2012     if (argc < 2) { // 2:Number of parameters
2013         return -EINVAL;
2014     }
2015 
2016     divisor = strtoul(argv[1], NULL, 0);
2017     err = bt_mesh_health_period_set(net.net_idx, net.dst, net.app_idx,
2018                                     divisor, &updated_divisor);
2019     if (err) {
2020         printk("Failed to send Health Period Set (err %d)\n", err);
2021     } else {
2022         printk("Health FastPeriodDivisor: %u\n", updated_divisor);
2023     }
2024 
2025     return 0;
2026 }
2027 
2028 struct shell_cmd_help cmd_period_set_help = {
2029     NULL, "<divisor>", NULL
2030 };
2031 
cmd_period_set_unack(int argc,char * argv[])2032 static int cmd_period_set_unack(int argc, char *argv[])
2033 {
2034     u8_t divisor;
2035     int err;
2036 
2037     if (argc < 2) { // 2:Number of parameters
2038         return -EINVAL;
2039     }
2040 
2041     divisor = strtoul(argv[1], NULL, 0);
2042     err = bt_mesh_health_period_set(net.net_idx, net.dst, net.app_idx,
2043                                     divisor, NULL);
2044     if (err) {
2045         printk("Failed to send Health Period Set (err %d)\n", err);
2046     }
2047 
2048     return 0;
2049 }
2050 
2051 struct shell_cmd_help cmd_period_set_unack_help = {
2052     NULL, "<divisor>", NULL
2053 };
2054 
cmd_attention_get(int argc,char * argv[])2055 static int cmd_attention_get(int argc, char *argv[])
2056 {
2057     u8_t attention;
2058     int err;
2059     err = bt_mesh_health_attention_get(net.net_idx, net.dst, net.app_idx,
2060                                        &attention);
2061     if (err) {
2062         printk("Failed to send Health Attention Get (err %d)\n", err);
2063     } else {
2064         printk("Health Attention Timer: %u\n", attention);
2065     }
2066 
2067     return 0;
2068 }
2069 
cmd_attention_set(int argc,char * argv[])2070 static int cmd_attention_set(int argc, char *argv[])
2071 {
2072     u8_t attention, updated_attention;
2073     int err;
2074 
2075     if (argc < 2) { // 2:Number of parameters
2076         return -EINVAL;
2077     }
2078 
2079     attention = strtoul(argv[1], NULL, 0);
2080     err = bt_mesh_health_attention_set(net.net_idx, net.dst, net.app_idx,
2081                                        attention, &updated_attention);
2082     if (err) {
2083         printk("Failed to send Health Attention Set (err %d)\n", err);
2084     } else {
2085         printk("Health Attention Timer: %u\n", updated_attention);
2086     }
2087 
2088     return 0;
2089 }
2090 
2091 struct shell_cmd_help cmd_attention_set_help = {
2092     NULL, "<timer>", NULL
2093 };
2094 
cmd_attention_set_unack(int argc,char * argv[])2095 static int cmd_attention_set_unack(int argc, char *argv[])
2096 {
2097     u8_t attention;
2098     int err;
2099 
2100     if (argc < 2) { // 2:Number of parameters
2101         return -EINVAL;
2102     }
2103 
2104     attention = strtoul(argv[1], NULL, 0);
2105     err = bt_mesh_health_attention_set(net.net_idx, net.dst, net.app_idx,
2106                                        attention, NULL);
2107     if (err) {
2108         printk("Failed to send Health Attention Set (err %d)\n", err);
2109     }
2110 
2111     return 0;
2112 }
2113 
2114 struct shell_cmd_help cmd_attention_set_unack_help = {
2115     NULL, "<timer>", NULL
2116 };
2117 
2118 #endif /* MYNEWT_VAL(BLE_MESH_HEALTH_CLI) */
2119 
cmd_add_fault(int argc,char * argv[])2120 static int cmd_add_fault(int argc, char *argv[])
2121 {
2122     u8_t fault_id;
2123     u8_t i;
2124 
2125     if (argc < 2) { // 2:Number of parameters
2126         return -EINVAL;
2127     }
2128 
2129     fault_id = strtoul(argv[1], NULL, 0);
2130     if (!fault_id) {
2131         printk("The Fault ID must be non-zero!\n");
2132         return -EINVAL;
2133     }
2134 
2135     for (i = 0; i < sizeof(cur_faults); i++) {
2136         if (!cur_faults[i]) {
2137             cur_faults[i] = fault_id;
2138             break;
2139         }
2140     }
2141 
2142     if (i == sizeof(cur_faults)) {
2143         printk("Fault array is full. Use \"del-fault\" to clear it\n");
2144         return 0;
2145     }
2146 
2147     for (i = 0; i < sizeof(reg_faults); i++) {
2148         if (!reg_faults[i]) {
2149             reg_faults[i] = fault_id;
2150             break;
2151         }
2152     }
2153 
2154     if (i == sizeof(reg_faults)) {
2155         printk("No space to store more registered faults\n");
2156     }
2157 
2158     bt_mesh_fault_update(&elements[0]);
2159     return 0;
2160 }
2161 
2162 struct shell_cmd_help cmd_add_fault_help = {
2163     NULL, "<Fault ID>", NULL
2164 };
2165 
cmd_del_fault(int argc,char * argv[])2166 static int cmd_del_fault(int argc, char *argv[])
2167 {
2168     u8_t fault_id;
2169     u8_t i;
2170 
2171     if (argc < 2) { // 2:Number of parameters
2172         memset(cur_faults, 0, sizeof(cur_faults));
2173         printk("All current faults cleared\n");
2174         bt_mesh_fault_update(&elements[0]);
2175         return 0;
2176     }
2177 
2178     fault_id = strtoul(argv[1], NULL, 0);
2179     if (!fault_id) {
2180         printk("The Fault ID must be non-zero!\n");
2181         return -EINVAL;
2182     }
2183 
2184     for (i = 0; i < sizeof(cur_faults); i++) {
2185         if (cur_faults[i] == fault_id) {
2186             cur_faults[i] = 0;
2187             printk("Fault cleared\n");
2188         }
2189     }
2190 
2191     bt_mesh_fault_update(&elements[0]);
2192     return 0;
2193 }
2194 
2195 struct shell_cmd_help cmd_del_fault_help = {
2196     NULL, "[Fault ID]", NULL
2197 };
2198 
2199 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
cmd_gen_onoff_get(int argc,char * argv[])2200 static int cmd_gen_onoff_get(int argc, char *argv[])
2201 {
2202     u8_t state;
2203     int err;
2204     err = bt_mesh_gen_onoff_get(net.net_idx, net.dst, net.app_idx,
2205                                 &state);
2206     if (err) {
2207         printk("Failed to send Generic OnOff Get (err %d)\n", err);
2208     } else {
2209         printk("Gen OnOff State %d\n", state);
2210     }
2211 
2212     return 0;
2213 }
2214 
cmd_gen_onoff_set(int argc,char * argv[])2215 static int cmd_gen_onoff_set(int argc, char *argv[])
2216 {
2217     u8_t state;
2218     u8_t val;
2219     int err;
2220 
2221     if (argc < 2) { // 2:Number of parameters
2222         return -EINVAL;
2223     }
2224 
2225     val = strtoul(argv[1], NULL, 0);
2226     err = bt_mesh_gen_onoff_set(net.net_idx, net.dst, net.app_idx,
2227                                 val, &state);
2228     if (err) {
2229         printk("Failed to send Generic OnOff Get (err %d)\n", err);
2230     } else {
2231         printk("Gen OnOff State %d\n", state);
2232     }
2233 
2234     return 0;
2235 }
2236 
2237 struct shell_cmd_help cmd_gen_onoff_set_help = {
2238     NULL, "<0|1>", NULL
2239 };
2240 
cmd_gen_onoff_set_unack(int argc,char * argv[])2241 static int cmd_gen_onoff_set_unack(int argc, char *argv[])
2242 {
2243     u8_t val;
2244     int err;
2245 
2246     if (argc < 2) { // 2:Number of parameters
2247         return -EINVAL;
2248     }
2249 
2250     val = strtoul(argv[1], NULL, 0);
2251     err = bt_mesh_gen_onoff_set(net.net_idx, net.dst, net.app_idx,
2252                                 val, NULL);
2253     if (err) {
2254         printk("Failed to send Generic OnOff Get (err %d)\n", err);
2255     }
2256 
2257     return 0;
2258 }
2259 
2260 struct shell_cmd_help cmd_gen_onoff_set_unack_help = {
2261     NULL, "<0|1>", NULL
2262 };
2263 
cmd_gen_level_get(int argc,char * argv[])2264 static int cmd_gen_level_get(int argc, char *argv[])
2265 {
2266     s16_t state;
2267     int err;
2268     err = bt_mesh_gen_level_get(net.net_idx, net.dst, net.app_idx,
2269                                 &state);
2270     if (err) {
2271         printk("Failed to send Generic Level Get (err %d)\n", err);
2272     } else {
2273         printk("Gen Level State %d\n", state);
2274     }
2275 
2276     return 0;
2277 }
2278 
cmd_gen_level_set(int argc,char * argv[])2279 static int cmd_gen_level_set(int argc, char *argv[])
2280 {
2281     s16_t state;
2282     s16_t val;
2283     int err;
2284 
2285     if (argc < 2) { // 2:Number of parameters
2286         return -EINVAL;
2287     }
2288 
2289     val = (s16_t)strtoul(argv[1], NULL, 0);
2290     err = bt_mesh_gen_level_set(net.net_idx, net.dst, net.app_idx,
2291                                 val, &state);
2292     if (err) {
2293         printk("Failed to send Generic Level Get (err %d)\n", err);
2294     } else {
2295         printk("Gen Level State %d\n", state);
2296     }
2297 
2298     return 0;
2299 }
2300 
2301 struct shell_cmd_help cmd_gen_level_set_help = {
2302     NULL, "<level>", NULL
2303 };
2304 
cmd_gen_level_set_unack(int argc,char * argv[])2305 static int cmd_gen_level_set_unack(int argc, char *argv[])
2306 {
2307     s16_t val;
2308     int err;
2309 
2310     if (argc < 2) { // 2:Number of parameters
2311         return -EINVAL;
2312     }
2313 
2314     val = (s16_t)strtoul(argv[1], NULL, 0);
2315     err = bt_mesh_gen_level_set(net.net_idx, net.dst, net.app_idx,
2316                                 val, NULL);
2317     if (err) {
2318         printk("Failed to send Generic Level Get (err %d)\n", err);
2319     }
2320 
2321     return 0;
2322 }
2323 
2324 struct shell_cmd_help cmd_gen_level_set_unack_help = {
2325     NULL, "<level>", NULL
2326 };
2327 
2328 #endif /* MYNEWT_VAL(BLE_MESH_SHELL_MODELS) */
2329 
cmd_print_credentials(int argc,char * argv[])2330 static int cmd_print_credentials(int argc, char *argv[])
2331 {
2332     bt_test_print_credentials();
2333     return 0;
2334 }
2335 
print_comp_elem(struct bt_mesh_elem * elem,bool primary)2336 static void print_comp_elem(struct bt_mesh_elem *elem,
2337                             bool primary)
2338 {
2339     struct bt_mesh_model *mod;
2340     int i;
2341     printk("Loc: %u\n", elem->loc);
2342     printk("Model count: %u\n", elem->model_count);
2343     printk("Vnd model count: %u\n", elem->vnd_model_count);
2344 
2345     for (i = 0; i < elem->model_count; i++) {
2346         mod = &elem->models[i];
2347         printk("  Model: %u\n", i);
2348         printk("    ID: 0x%04x\n", mod->id);
2349         printk("    Opcode: 0x%08lx\n", mod->op->opcode);
2350     }
2351 
2352     for (i = 0; i < elem->vnd_model_count; i++) {
2353         mod = &elem->vnd_models[i];
2354         printk("  Vendor model: %u\n", i);
2355         printk("    Company: 0x%04x\n", mod->vnd.company);
2356         printk("    ID: 0x%04x\n", mod->vnd.id);
2357         printk("    Opcode: 0x%08lx\n", mod->op->opcode);
2358     }
2359 }
2360 
cmd_print_composition_data(int argc,char * argv[])2361 static int cmd_print_composition_data(int argc, char *argv[])
2362 {
2363     const struct bt_mesh_comp *comp;
2364     int i;
2365     comp = bt_mesh_comp_get();
2366     printk("CID: %u\n", comp->cid);
2367     printk("PID: %u\n", comp->pid);
2368     printk("VID: %u\n", comp->vid);
2369 
2370     for (i = 0; i < comp->elem_count; i++) {
2371         print_comp_elem(&comp->elem[i], i == 0);
2372     }
2373 
2374     return 0;
2375 }
2376 
2377 static const struct shell_cmd mesh_commands[] = {
2378     {
2379         .sc_cmd = "init",
2380         .sc_cmd_func = cmd_mesh_init,
2381         .help = NULL,
2382     },
2383 #if MYNEWT_VAL(BLE_MESH_PB_ADV)
2384     {
2385         .sc_cmd = "pb-adv",
2386         .sc_cmd_func = cmd_pb_adv,
2387         .help = &cmd_pb_help,
2388     },
2389 #if MYNEWT_VAL(BLE_MESH_PROVISIONER)
2390     {
2391         .sc_cmd = "provision-adv",
2392         .sc_cmd_func = cmd_provision_adv,
2393         .help = &cmd_provision_adv_help,
2394     },
2395 #endif
2396 #endif
2397 #if MYNEWT_VAL(BLE_MESH_PB_GATT)
2398     {
2399         .sc_cmd = "pb-gatt",
2400         .sc_cmd_func = cmd_pb_gatt,
2401         .help = &cmd_pb_help,
2402     },
2403 #endif
2404     {
2405         .sc_cmd = "reset",
2406         .sc_cmd_func = cmd_reset,
2407         .help = NULL,
2408     },
2409     {
2410         .sc_cmd = "uuid",
2411         .sc_cmd_func = cmd_uuid,
2412         .help = &cmd_uuid_help,
2413     },
2414     {
2415         .sc_cmd = "input-num",
2416         .sc_cmd_func = cmd_input_num,
2417         .help = &cmd_input_num_help,
2418     },
2419     {
2420         .sc_cmd = "input-str",
2421         .sc_cmd_func = cmd_input_str,
2422         .help = &cmd_input_str_help,
2423     },
2424     {
2425         .sc_cmd = "static-oob",
2426         .sc_cmd_func = cmd_static_oob,
2427         .help = &cmd_static_oob_help,
2428     },
2429     {
2430         .sc_cmd = "provision",
2431         .sc_cmd_func = cmd_provision,
2432         .help = &cmd_provision_help,
2433     },
2434 #if MYNEWT_VAL(BLE_MESH_LOW_POWER)
2435     {
2436         .sc_cmd = "lpn",
2437         .sc_cmd_func = cmd_lpn,
2438         .help = &cmd_lpn_help,
2439     },
2440     {
2441         .sc_cmd = "poll",
2442         .sc_cmd_func = cmd_poll,
2443         .help = NULL,
2444     },
2445 #endif
2446 #if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
2447     {
2448         .sc_cmd = "ident",
2449         .sc_cmd_func = cmd_ident,
2450         .help = NULL,
2451     },
2452 #endif
2453     {
2454         .sc_cmd = "dst",
2455         .sc_cmd_func = cmd_dst,
2456         .help = &cmd_dst_help,
2457     },
2458     {
2459         .sc_cmd = "netidx",
2460         .sc_cmd_func = cmd_netidx,
2461         .help = &cmd_netidx_help,
2462     },
2463     {
2464         .sc_cmd = "appidx",
2465         .sc_cmd_func = cmd_appidx,
2466         .help = &cmd_appidx_help,
2467     },
2468 
2469     /* Commands which access internal APIs, for testing only */
2470     {
2471         .sc_cmd = "net-send",
2472         .sc_cmd_func = cmd_net_send,
2473         .help = &cmd_net_send_help,
2474     },
2475 #if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST)
2476     {
2477         .sc_cmd = "iv-update",
2478         .sc_cmd_func = cmd_iv_update,
2479         .help = NULL,
2480     },
2481     {
2482         .sc_cmd = "iv-update-test",
2483         .sc_cmd_func = cmd_iv_update_test,
2484         .help = &cmd_iv_update_test_help,
2485     },
2486 #endif
2487     {
2488         .sc_cmd = "rpl-clear",
2489         .sc_cmd_func = cmd_rpl_clear,
2490         .help = NULL,
2491     },
2492 #if MYNEWT_VAL(BLE_MESH_LOW_POWER)
2493     {
2494         .sc_cmd = "lpn-subscribe",
2495         .sc_cmd_func = cmd_lpn_subscribe,
2496         .help = &cmd_lpn_subscribe_help,
2497     },
2498     {
2499         .sc_cmd = "lpn-unsubscribe",
2500         .sc_cmd_func = cmd_lpn_unsubscribe,
2501         .help = &cmd_lpn_unsubscribe_help,
2502     },
2503 #endif
2504     {
2505         .sc_cmd = "print-credentials",
2506         .sc_cmd_func = cmd_print_credentials,
2507         .help = NULL,
2508     },
2509     {
2510         .sc_cmd = "print-composition-data",
2511         .sc_cmd_func = cmd_print_composition_data,
2512         .help = NULL,
2513     },
2514 
2515 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
2516     /* Configuration Client Model operations */
2517     {
2518         .sc_cmd = "timeout",
2519         .sc_cmd_func = cmd_timeout,
2520         .help = &cmd_timeout_help,
2521     },
2522     {
2523         .sc_cmd = "get-comp",
2524         .sc_cmd_func = cmd_get_comp,
2525         .help = &cmd_get_comp_help,
2526     },
2527     {
2528         .sc_cmd = "beacon",
2529         .sc_cmd_func = cmd_beacon,
2530         .help = &cmd_beacon_help,
2531     },
2532     {
2533         .sc_cmd = "ttl",
2534         .sc_cmd_func = cmd_ttl,
2535         .help = &cmd_ttl_help,
2536     },
2537     {
2538         .sc_cmd = "friend",
2539         .sc_cmd_func = cmd_friend,
2540         .help = &cmd_friend_help,
2541     },
2542     {
2543         .sc_cmd = "gatt-proxy",
2544         .sc_cmd_func = cmd_gatt_proxy,
2545         .help = &cmd_gatt_proxy_help,
2546     },
2547     {
2548         .sc_cmd = "relay",
2549         .sc_cmd_func = cmd_relay,
2550         .help = &cmd_relay_help,
2551     },
2552     {
2553         .sc_cmd = "net-key-add",
2554         .sc_cmd_func = cmd_net_key_add,
2555         .help = &cmd_net_key_add_help,
2556     },
2557     {
2558         .sc_cmd = "app-key-add",
2559         .sc_cmd_func = cmd_app_key_add,
2560         .help = &cmd_app_key_add_help,
2561     },
2562     {
2563         .sc_cmd = "mod-app-bind",
2564         .sc_cmd_func = cmd_mod_app_bind,
2565         .help = &cmd_mod_app_bind_help,
2566     },
2567     {
2568         .sc_cmd = "mod-pub",
2569         .sc_cmd_func = cmd_mod_pub,
2570         .help = &cmd_mod_pub_help,
2571     },
2572     {
2573         .sc_cmd = "mod-sub-add",
2574         .sc_cmd_func = cmd_mod_sub_add,
2575         .help = &cmd_mod_sub_add_help,
2576     },
2577     {
2578         .sc_cmd = "mod-sub-del",
2579         .sc_cmd_func = cmd_mod_sub_del,
2580         .help = &cmd_mod_sub_del_help,
2581     },
2582     {
2583         .sc_cmd = "mod-sub-add-va",
2584         .sc_cmd_func = cmd_mod_sub_add_va,
2585         .help = &cmd_mod_sub_add_va_help,
2586     },
2587     {
2588         .sc_cmd = "mod-sub-del-va",
2589         .sc_cmd_func = cmd_mod_sub_del_va,
2590         .help = &cmd_mod_sub_del_va_help,
2591     },
2592     {
2593         .sc_cmd = "hb-sub",
2594         .sc_cmd_func = cmd_hb_sub,
2595         .help = &cmd_hb_sub_help,
2596     },
2597     {
2598         .sc_cmd = "hb-pub",
2599         .sc_cmd_func = cmd_hb_pub,
2600         .help = &cmd_hb_pub_help,
2601     },
2602 #endif
2603 
2604 #if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
2605     /* Health Client Model Operations */
2606     {
2607         .sc_cmd = "fault-get",
2608         .sc_cmd_func = cmd_fault_get,
2609         .help = &cmd_fault_get_help,
2610     },
2611     {
2612         .sc_cmd = "fault-clear",
2613         .sc_cmd_func = cmd_fault_clear,
2614         .help = &cmd_fault_clear_help,
2615     },
2616     {
2617         .sc_cmd = "fault-clear-unack",
2618         .sc_cmd_func = cmd_fault_clear_unack,
2619         .help = &cmd_fault_clear_unack_help,
2620     },
2621     {
2622         .sc_cmd = "fault-test",
2623         .sc_cmd_func = cmd_fault_test,
2624         .help = &cmd_fault_test_help,
2625     },
2626     {
2627         .sc_cmd = "fault-test-unack",
2628         .sc_cmd_func = cmd_fault_test_unack,
2629         .help = &cmd_fault_test_unack_help,
2630     },
2631     {
2632         .sc_cmd = "period-get",
2633         .sc_cmd_func = cmd_period_get,
2634         .help = NULL,
2635     },
2636     {
2637         .sc_cmd = "period-set",
2638         .sc_cmd_func = cmd_period_set,
2639         .help = &cmd_period_set_help,
2640     },
2641     {
2642         .sc_cmd = "period-set-unack",
2643         .sc_cmd_func = cmd_period_set_unack,
2644         .help = &cmd_period_set_unack_help,
2645     },
2646     {
2647         .sc_cmd = "attention-get",
2648         .sc_cmd_func = cmd_attention_get,
2649         .help = NULL,
2650     },
2651     {
2652         .sc_cmd = "attention-set",
2653         .sc_cmd_func = cmd_attention_set,
2654         .help = &cmd_attention_set_help,
2655     },
2656     {
2657         .sc_cmd = "attention-set-unack",
2658         .sc_cmd_func = cmd_attention_set_unack,
2659         .help = &cmd_attention_set_unack_help,
2660     },
2661 #endif
2662 
2663     /* Health Server Model Operations */
2664     {
2665         .sc_cmd = "add-fault",
2666         .sc_cmd_func = cmd_add_fault,
2667         .help = &cmd_add_fault_help,
2668     },
2669     {
2670         .sc_cmd = "del-fault",
2671         .sc_cmd_func = cmd_del_fault,
2672         .help = &cmd_del_fault_help,
2673     },
2674 
2675 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
2676     /* Generic Client Model Operations */
2677     {
2678         .sc_cmd = "gen-onoff-get",
2679         .sc_cmd_func = cmd_gen_onoff_get,
2680         .help = NULL,
2681     },
2682     {
2683         .sc_cmd = "gen-onoff-set",
2684         .sc_cmd_func = cmd_gen_onoff_set,
2685         .help = &cmd_gen_onoff_set_help,
2686     },
2687     {
2688         .sc_cmd = "gen-onoff-set-unack",
2689         .sc_cmd_func = cmd_gen_onoff_set_unack,
2690         .help = &cmd_gen_onoff_set_unack_help,
2691     },
2692     {
2693         .sc_cmd = "gen-level-get",
2694         .sc_cmd_func = cmd_gen_level_get,
2695         .help = NULL,
2696     },
2697     {
2698         .sc_cmd = "gen-level-set",
2699         .sc_cmd_func = cmd_gen_level_set,
2700         .help = &cmd_gen_level_set_help,
2701     },
2702     {
2703         .sc_cmd = "gen-level-set-unack",
2704         .sc_cmd_func = cmd_gen_level_set_unack,
2705         .help = &cmd_gen_level_set_unack_help,
2706     },
2707 #endif
2708 
2709     { 0 },
2710 };
2711 
mesh_shell_thread(void * args)2712 static void mesh_shell_thread(void *args)
2713 {
2714     while (1) {
2715         os_eventq_run(&mesh_shell_queue);
2716     }
2717 }
2718 
bt_mesh_shell_task_init(void)2719 static void bt_mesh_shell_task_init(void)
2720 {
2721     os_eventq_init(&mesh_shell_queue);
2722     os_task_init(&mesh_shell_task, "mesh_sh", mesh_shell_thread, NULL,
2723                  BLE_MESH_SHELL_TASK_PRIO, OS_WAIT_FOREVER, g_blemesh_shell_stack,
2724                  BLE_MESH_SHELL_STACK_SIZE);
2725 }
2726 #endif
2727 
ble_mesh_shell_init(void)2728 void ble_mesh_shell_init(void)
2729 {
2730 #if (MYNEWT_VAL(BLE_MESH_SHELL))
2731     /* Initialize health pub message */
2732     health_pub_init();
2733     /* Shell and other mesh clients should use separate task to
2734        avoid deadlocks with mesh message processing queue */
2735     bt_mesh_shell_task_init();
2736     shell_evq_set(&mesh_shell_queue);
2737     shell_register("mesh", mesh_commands);
2738 #endif
2739 }