• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include "syscfg/syscfg.h"
10 #define MESH_LOG_MODULE BLE_MESH_MODEL_LOG
11 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
12 
13 #include "mesh/mesh.h"
14 
15 #include <string.h>
16 #include <errno.h>
17 #include <stdbool.h>
18 
19 #include "net.h"
20 #include "foundation.h"
21 
22 #define CID_NVAL 0xffff
23 
24 /* 2 byte dummy opcode for getting compile time buffer sizes. */
25 #define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff)
26 
27 struct comp_data {
28     u8_t *status;
29     struct os_mbuf *comp;
30 };
31 
32 static s32_t msg_timeout = K_SECONDS(5); // 5:5s
33 
34 static struct bt_mesh_cfg_cli *cli;
35 
comp_data_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)36 static void comp_data_status(struct bt_mesh_model *model,
37                              struct bt_mesh_msg_ctx *ctx,
38                              struct os_mbuf *buf)
39 {
40     struct comp_data *param;
41     size_t to_copy;
42     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
43            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
44            bt_hex(buf->om_data, buf->om_len));
45 
46     if (cli->op_pending != OP_DEV_COMP_DATA_STATUS) {
47         BT_WARN("Unexpected Composition Data Status");
48         return;
49     }
50 
51     param = cli->op_param;
52     *(param->status) = net_buf_simple_pull_u8(buf);
53     to_copy  = min(net_buf_simple_tailroom(param->comp), buf->om_len);
54     net_buf_simple_add_mem(param->comp, buf->om_data, to_copy);
55     k_sem_give(&cli->op_sync);
56 }
57 
state_status_u8(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf,u32_t expect_status)58 static void state_status_u8(struct bt_mesh_model *model,
59                             struct bt_mesh_msg_ctx *ctx,
60                             struct os_mbuf *buf,
61                             u32_t expect_status)
62 {
63     u8_t *status;
64     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
65            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
66            bt_hex(buf->om_data, buf->om_len));
67 
68     if (cli->op_pending != expect_status) {
69         BT_WARN("Unexpected Status (0x%08x != 0x%08x)",
70                 (unsigned) cli->op_pending, (unsigned) expect_status);
71         return;
72     }
73 
74     status = cli->op_param;
75     *status = net_buf_simple_pull_u8(buf);
76     k_sem_give(&cli->op_sync);
77 }
78 
beacon_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)79 static void beacon_status(struct bt_mesh_model *model,
80                           struct bt_mesh_msg_ctx *ctx,
81                           struct os_mbuf *buf)
82 {
83     state_status_u8(model, ctx, buf, OP_BEACON_STATUS);
84 }
85 
ttl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)86 static void ttl_status(struct bt_mesh_model *model,
87                        struct bt_mesh_msg_ctx *ctx,
88                        struct os_mbuf *buf)
89 {
90     state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS);
91 }
92 
friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)93 static void friend_status(struct bt_mesh_model *model,
94                           struct bt_mesh_msg_ctx *ctx,
95                           struct os_mbuf *buf)
96 {
97     state_status_u8(model, ctx, buf, OP_FRIEND_STATUS);
98 }
99 
gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)100 static void gatt_proxy_status(struct bt_mesh_model *model,
101                               struct bt_mesh_msg_ctx *ctx,
102                               struct os_mbuf *buf)
103 {
104     state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS);
105 }
106 
107 struct relay_param {
108     u8_t *status;
109     u8_t *transmit;
110 };
111 
relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)112 static void relay_status(struct bt_mesh_model *model,
113                          struct bt_mesh_msg_ctx *ctx,
114                          struct os_mbuf *buf)
115 {
116     struct relay_param *param;
117     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
118            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
119            bt_hex(buf->om_data, buf->om_len));
120 
121     if (cli->op_pending != OP_RELAY_STATUS) {
122         BT_WARN("Unexpected Relay Status message");
123         return;
124     }
125 
126     param = cli->op_param;
127     *param->status = net_buf_simple_pull_u8(buf);
128     *param->transmit = net_buf_simple_pull_u8(buf);
129     k_sem_give(&cli->op_sync);
130 }
131 
132 struct net_key_param {
133     u8_t *status;
134     u16_t net_idx;
135 };
136 
net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)137 static void net_key_status(struct bt_mesh_model *model,
138                            struct bt_mesh_msg_ctx *ctx,
139                            struct os_mbuf *buf)
140 {
141     struct net_key_param *param;
142     u16_t net_idx, app_idx;
143     u8_t status;
144     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
145            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
146            bt_hex(buf->om_data, buf->om_len));
147 
148     if (cli->op_pending != OP_NET_KEY_STATUS) {
149         BT_WARN("Unexpected Net Key Status message");
150         return;
151     }
152 
153     status = net_buf_simple_pull_u8(buf);
154     key_idx_unpack(buf, &net_idx, &app_idx);
155     param = cli->op_param;
156 
157     if (param->net_idx != net_idx) {
158         BT_WARN("Net Key Status key index does not match");
159         return;
160     }
161 
162     if (param->status) {
163         *param->status = status;
164     }
165 
166     k_sem_give(&cli->op_sync);
167 }
168 
169 struct app_key_param {
170     u8_t *status;
171     u16_t net_idx;
172     u16_t app_idx;
173 };
174 
app_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)175 static void app_key_status(struct bt_mesh_model *model,
176                            struct bt_mesh_msg_ctx *ctx,
177                            struct os_mbuf *buf)
178 {
179     struct app_key_param *param;
180     u16_t net_idx, app_idx;
181     u8_t status;
182     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
183            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
184            bt_hex(buf->om_data, buf->om_len));
185 
186     if (cli->op_pending != OP_APP_KEY_STATUS) {
187         BT_WARN("Unexpected App Key Status message");
188         return;
189     }
190 
191     status = net_buf_simple_pull_u8(buf);
192     key_idx_unpack(buf, &net_idx, &app_idx);
193     param = cli->op_param;
194 
195     if (param->net_idx != net_idx || param->app_idx != app_idx) {
196         BT_WARN("App Key Status key indices did not match");
197         return;
198     }
199 
200     if (param->status) {
201         *param->status = status;
202     }
203 
204     k_sem_give(&cli->op_sync);
205 }
206 
207 struct mod_app_param {
208     u8_t *status;
209     u16_t elem_addr;
210     u16_t mod_app_idx;
211     u16_t mod_id;
212     u16_t cid;
213 };
214 
mod_app_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)215 static void mod_app_status(struct bt_mesh_model *model,
216                            struct bt_mesh_msg_ctx *ctx,
217                            struct os_mbuf *buf)
218 {
219     u16_t elem_addr, mod_app_idx, mod_id, cid;
220     struct mod_app_param *param;
221     u8_t status;
222     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
223            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
224            bt_hex(buf->om_data, buf->om_len));
225 
226     if (cli->op_pending != OP_MOD_APP_STATUS) {
227         BT_WARN("Unexpected Model App Status message");
228         return;
229     }
230 
231     status = net_buf_simple_pull_u8(buf);
232     elem_addr = net_buf_simple_pull_le16(buf);
233     mod_app_idx = net_buf_simple_pull_le16(buf);
234 
235     if (buf->om_len >= 4) { // 4:Analyzing conditions
236         cid = net_buf_simple_pull_le16(buf);
237     } else {
238         cid = CID_NVAL;
239     }
240 
241     mod_id = net_buf_simple_pull_le16(buf);
242     param = cli->op_param;
243 
244     if (param->elem_addr != elem_addr ||
245             param->mod_app_idx != mod_app_idx || param->mod_id != mod_id ||
246             param->cid != cid) {
247         BT_WARN("Model App Status parameters did not match");
248         return;
249     }
250 
251     if (param->status) {
252         *param->status = status;
253     }
254 
255     k_sem_give(&cli->op_sync);
256 }
257 
258 struct mod_pub_param {
259     u16_t                       mod_id;
260     u16_t                       cid;
261     u16_t                       elem_addr;
262     u8_t                       *status;
263     struct bt_mesh_cfg_mod_pub *pub;
264 };
265 
mod_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)266 static void mod_pub_status(struct bt_mesh_model *model,
267                            struct bt_mesh_msg_ctx *ctx,
268                            struct os_mbuf *buf)
269 {
270     u16_t mod_id, cid, elem_addr;
271     struct mod_pub_param *param;
272     u8_t status;
273     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
274            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
275            bt_hex(buf->om_data, buf->om_len));
276 
277     if (cli->op_pending != OP_MOD_PUB_STATUS) {
278         BT_WARN("Unexpected Model Pub Status message");
279         return;
280     }
281 
282     param = cli->op_param;
283 
284     if (param->cid != CID_NVAL) {
285         if (buf->om_len < 14) { // 14:Analyzing conditions
286             BT_WARN("Unexpected Mod Pub Status with SIG Model");
287             return;
288         }
289 
290         cid = sys_get_le16(&buf->om_data[10]); // 10:array element
291         mod_id = sys_get_le16(&buf->om_data[12]); // 12:array element
292     } else {
293         if (buf->om_len > 12) { // 12:Analyzing conditions
294             BT_WARN("Unexpected Mod Pub Status with Vendor Model");
295             return;
296         }
297 
298         cid = CID_NVAL;
299         mod_id = sys_get_le16(&buf->om_data[10]); // 10:array element
300     }
301 
302     if (mod_id != param->mod_id || cid != param->cid) {
303         BT_WARN("Mod Pub Model ID or Company ID mismatch");
304         return;
305     }
306 
307     status = net_buf_simple_pull_u8(buf);
308     elem_addr = net_buf_simple_pull_le16(buf);
309     if (elem_addr != param->elem_addr) {
310         BT_WARN("Model Pub Status for unexpected element (0x%04x)",
311                 elem_addr);
312         return;
313     }
314 
315     if (param->status) {
316         *param->status = status;
317     }
318 
319     if (param->pub) {
320         param->pub->addr = net_buf_simple_pull_le16(buf);
321         param->pub->app_idx = net_buf_simple_pull_le16(buf);
322         param->pub->cred_flag = (param->pub->app_idx & BIT(12)); // 12:byte alignment
323         param->pub->app_idx &= BIT_MASK(12); // 12:byte alignment
324         param->pub->ttl = net_buf_simple_pull_u8(buf);
325         param->pub->period = net_buf_simple_pull_u8(buf);
326         param->pub->transmit = net_buf_simple_pull_u8(buf);
327     }
328 
329     k_sem_give(&cli->op_sync);
330 }
331 
332 struct mod_sub_param {
333     u8_t *status;
334     u16_t elem_addr;
335     u16_t *sub_addr;
336     u16_t *expect_sub;
337     u16_t mod_id;
338     u16_t cid;
339 };
340 
mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)341 static void mod_sub_status(struct bt_mesh_model *model,
342                            struct bt_mesh_msg_ctx *ctx,
343                            struct os_mbuf *buf)
344 {
345     u16_t elem_addr, sub_addr, mod_id, cid;
346     struct mod_sub_param *param;
347     u8_t status;
348     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
349            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
350            bt_hex(buf->om_data, buf->om_len));
351 
352     if (cli->op_pending != OP_MOD_SUB_STATUS) {
353         BT_WARN("Unexpected Model Subscription Status message");
354         return;
355     }
356 
357     status = net_buf_simple_pull_u8(buf);
358     elem_addr = net_buf_simple_pull_le16(buf);
359     sub_addr = net_buf_simple_pull_le16(buf);
360 
361     if (buf->om_len >= 4) { // 4:Analyzing conditions
362         cid = net_buf_simple_pull_le16(buf);
363     } else {
364         cid = CID_NVAL;
365     }
366 
367     mod_id = net_buf_simple_pull_le16(buf);
368     param = cli->op_param;
369 
370     if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
371        (param->expect_sub && *param->expect_sub != sub_addr) ||
372         param->cid != cid) {
373         BT_WARN("Model Subscription Status parameters did not match");
374         return;
375     }
376 
377     if (param->sub_addr) {
378         *param->sub_addr = sub_addr;
379     }
380 
381     if (param->status) {
382         *param->status = status;
383     }
384 
385     k_sem_give(&cli->op_sync);
386 }
387 
388 struct hb_sub_param {
389     u8_t *status;
390     struct bt_mesh_cfg_hb_sub *sub;
391 };
392 
hb_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)393 static void hb_sub_status(struct bt_mesh_model *model,
394                           struct bt_mesh_msg_ctx *ctx,
395                           struct os_mbuf *buf)
396 {
397     struct hb_sub_param *param;
398     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
399            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
400            bt_hex(buf->om_data, buf->om_len));
401 
402     if (cli->op_pending != OP_HEARTBEAT_SUB_STATUS) {
403         BT_WARN("Unexpected Heartbeat Subscription Status message");
404         return;
405     }
406 
407     param = cli->op_param;
408     *param->status = net_buf_simple_pull_u8(buf);
409     param->sub->src = net_buf_simple_pull_le16(buf);
410     param->sub->dst = net_buf_simple_pull_le16(buf);
411     param->sub->period = net_buf_simple_pull_u8(buf);
412     param->sub->count = net_buf_simple_pull_u8(buf);
413     param->sub->min = net_buf_simple_pull_u8(buf);
414     param->sub->max = net_buf_simple_pull_u8(buf);
415     k_sem_give(&cli->op_sync);
416 }
417 
418 struct hb_pub_param {
419     u8_t *status;
420     struct bt_mesh_cfg_hb_pub *pub;
421 };
422 
hb_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)423 static void hb_pub_status(struct bt_mesh_model *model,
424                           struct bt_mesh_msg_ctx *ctx,
425                           struct os_mbuf *buf)
426 {
427     struct hb_pub_param *param;
428     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
429            ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
430            bt_hex(buf->om_data, buf->om_len));
431 
432     if (cli->op_pending != OP_HEARTBEAT_PUB_STATUS) {
433         BT_WARN("Unexpected Heartbeat Publication Status message");
434         return;
435     }
436 
437     param = cli->op_param;
438     *param->status = net_buf_simple_pull_u8(buf);
439 
440     if (param->pub) {
441         param->pub->dst = net_buf_simple_pull_le16(buf);
442         param->pub->count = net_buf_simple_pull_u8(buf);
443         param->pub->period = net_buf_simple_pull_u8(buf);
444         param->pub->ttl = net_buf_simple_pull_u8(buf);
445         param->pub->feat = net_buf_simple_pull_u8(buf);
446         param->pub->net_idx = net_buf_simple_pull_u8(buf);
447     }
448 
449     k_sem_give(&cli->op_sync);
450 }
451 
452 const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
453     { OP_DEV_COMP_DATA_STATUS,   15,  comp_data_status },
454     { OP_BEACON_STATUS,          1,   beacon_status },
455     { OP_DEFAULT_TTL_STATUS,     1,   ttl_status },
456     { OP_FRIEND_STATUS,          1,   friend_status },
457     { OP_GATT_PROXY_STATUS,      1,   gatt_proxy_status },
458     { OP_RELAY_STATUS,           2,   relay_status },
459     { OP_NET_KEY_STATUS,         3,   net_key_status },
460     { OP_APP_KEY_STATUS,         4,   app_key_status },
461     { OP_MOD_APP_STATUS,         7,   mod_app_status },
462     { OP_MOD_PUB_STATUS,         12,  mod_pub_status },
463     { OP_MOD_SUB_STATUS,         7,   mod_sub_status },
464     { OP_HEARTBEAT_SUB_STATUS,   9,   hb_sub_status },
465     { OP_HEARTBEAT_PUB_STATUS,   10,  hb_pub_status },
466     BT_MESH_MODEL_OP_END,
467 };
468 
cfg_cli_init(struct bt_mesh_model * model)469 static int cfg_cli_init(struct bt_mesh_model *model)
470 {
471     BT_DBG("");
472 
473     if (!bt_mesh_model_in_primary(model)) {
474         BT_ERR("Configuration Client only allowed in primary element");
475         return -EINVAL;
476     }
477 
478     if (!model->user_data) {
479         BT_ERR("No Configuration Client context provided");
480         return -EINVAL;
481     }
482 
483     cli = model->user_data;
484     cli->model = model;
485     /*
486      * Configuration Model security is device-key based and both the local
487      * and remote keys are allowed to access this model.
488      */
489     model->keys[0] = BT_MESH_KEY_DEV_ANY;
490     k_sem_init(&cli->op_sync, 0, 1);
491     return 0;
492 }
493 
494 const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb = {
495     .init = cfg_cli_init,
496 };
497 
cli_prepare(void * param,u32_t op)498 static int cli_prepare(void *param, u32_t op)
499 {
500     if (!cli) {
501         BT_ERR("No available Configuration Client context!");
502         return -EINVAL;
503     }
504 
505     if (cli->op_pending) {
506         BT_WARN("Another synchronous operation pending");
507         return -EBUSY;
508     }
509 
510     cli->op_param = param;
511     cli->op_pending = op;
512     return 0;
513 }
514 
cli_reset(void)515 static void cli_reset(void)
516 {
517     cli->op_pending = 0;
518     cli->op_param = NULL;
519 }
520 
cli_wait(void)521 static int cli_wait(void)
522 {
523     int err;
524     err = k_sem_take(&cli->op_sync, msg_timeout);
525     cli_reset();
526     return err;
527 }
528 
bt_mesh_cfg_comp_data_get(u16_t net_idx,u16_t addr,u8_t page,u8_t * status,struct os_mbuf * comp)529 int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page,
530                               u8_t *status, struct os_mbuf *comp)
531 {
532     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEV_COMP_DATA_GET, 1);
533     struct bt_mesh_msg_ctx ctx = {
534         .net_idx = net_idx,
535         .app_idx = BT_MESH_KEY_DEV_REMOTE,
536         .addr = addr,
537         .send_ttl = BT_MESH_TTL_DEFAULT,
538     };
539     struct comp_data param = {
540         .status = status,
541         .comp = comp,
542     };
543     int err;
544     err = cli_prepare(&param, OP_DEV_COMP_DATA_STATUS);
545     if (err) {
546         goto done;
547     }
548 
549     bt_mesh_model_msg_init(msg, OP_DEV_COMP_DATA_GET);
550     net_buf_simple_add_u8(msg, page);
551     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
552     if (err) {
553         BT_ERR("model_send() failed (err %d)", err);
554         cli_reset();
555         goto done;
556     }
557 
558     err = cli_wait();
559 done:
560     os_mbuf_free_chain(msg);
561     return err;
562 }
563 
get_state_u8(u16_t net_idx,u16_t addr,u32_t op,u32_t rsp,u8_t * val)564 static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
565                         u8_t *val)
566 {
567     struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 0);
568     struct bt_mesh_msg_ctx ctx = {
569         .net_idx = net_idx,
570         .app_idx = BT_MESH_KEY_DEV_REMOTE,
571         .addr = addr,
572         .send_ttl = BT_MESH_TTL_DEFAULT,
573     };
574     int err;
575     err = cli_prepare(val, rsp);
576     if (err) {
577         goto done;
578     }
579 
580     bt_mesh_model_msg_init(msg, op);
581     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
582     if (err) {
583         BT_ERR("model_send() failed (err %d)", err);
584         cli_reset();
585         goto done;
586     }
587 
588     err = cli_wait();
589 done:
590     os_mbuf_free_chain(msg);
591     return err;
592 }
593 
set_state_u8(u16_t net_idx,u16_t addr,u32_t op,u32_t rsp,u8_t new_val,u8_t * val)594 static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
595                         u8_t new_val, u8_t *val)
596 {
597     struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 1);
598     struct bt_mesh_msg_ctx ctx = {
599         .net_idx = net_idx,
600         .app_idx = BT_MESH_KEY_DEV_REMOTE,
601         .addr = addr,
602         .send_ttl = BT_MESH_TTL_DEFAULT,
603     };
604     int err;
605     err = cli_prepare(val, rsp);
606     if (err) {
607         goto done;
608     }
609 
610     bt_mesh_model_msg_init(msg, op);
611     net_buf_simple_add_u8(msg, new_val);
612     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
613     if (err) {
614         BT_ERR("model_send() failed (err %d)", err);
615         cli_reset();
616         goto done;
617     }
618 
619     err = cli_wait();
620 done:
621     os_mbuf_free_chain(msg);
622     return err;
623 }
624 
bt_mesh_cfg_beacon_get(u16_t net_idx,u16_t addr,u8_t * status)625 int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status)
626 {
627     return get_state_u8(net_idx, addr, OP_BEACON_GET, OP_BEACON_STATUS,
628                         status);
629 }
630 
bt_mesh_cfg_beacon_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)631 int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
632 {
633     return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS,
634                         val, status);
635 }
636 
bt_mesh_cfg_ttl_get(u16_t net_idx,u16_t addr,u8_t * ttl)637 int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl)
638 {
639     return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET,
640                         OP_DEFAULT_TTL_STATUS, ttl);
641 }
642 
bt_mesh_cfg_ttl_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * ttl)643 int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl)
644 {
645     return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET,
646                         OP_DEFAULT_TTL_STATUS, val, ttl);
647 }
648 
bt_mesh_cfg_friend_get(u16_t net_idx,u16_t addr,u8_t * status)649 int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status)
650 {
651     return get_state_u8(net_idx, addr, OP_FRIEND_GET,
652                         OP_FRIEND_STATUS, status);
653 }
654 
bt_mesh_cfg_friend_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)655 int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
656 {
657     return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS,
658                         val, status);
659 }
660 
bt_mesh_cfg_gatt_proxy_get(u16_t net_idx,u16_t addr,u8_t * status)661 int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status)
662 {
663     return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET,
664                         OP_GATT_PROXY_STATUS, status);
665 }
666 
bt_mesh_cfg_gatt_proxy_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)667 int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val,
668                                u8_t *status)
669 {
670     return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET,
671                         OP_GATT_PROXY_STATUS, val, status);
672 }
673 
bt_mesh_cfg_relay_get(u16_t net_idx,u16_t addr,u8_t * status,u8_t * transmit)674 int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status,
675                           u8_t *transmit)
676 {
677     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_GET, 0);
678     struct bt_mesh_msg_ctx ctx = {
679         .net_idx = net_idx,
680         .app_idx = BT_MESH_KEY_DEV_REMOTE,
681         .addr = addr,
682         .send_ttl = BT_MESH_TTL_DEFAULT,
683     };
684     struct relay_param param = {
685         .status = status,
686         .transmit = transmit,
687     };
688     int err;
689     err = cli_prepare(&param, OP_RELAY_STATUS);
690     if (err) {
691         goto done;
692     }
693 
694     bt_mesh_model_msg_init(msg, OP_RELAY_GET);
695     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
696     if (err) {
697         BT_ERR("model_send() failed (err %d)", err);
698         cli_reset();
699         goto done;
700     }
701     err = cli_wait();
702 done:
703     os_mbuf_free_chain(msg);
704     return err;
705 }
706 
bt_mesh_cfg_relay_set(u16_t net_idx,u16_t addr,u8_t new_relay,u8_t new_transmit,u8_t * status,u8_t * transmit)707 int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay,
708                           u8_t new_transmit, u8_t *status, u8_t *transmit)
709 {
710     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_SET, 2);
711     struct bt_mesh_msg_ctx ctx = {
712         .net_idx = net_idx,
713         .app_idx = BT_MESH_KEY_DEV_REMOTE,
714         .addr = addr,
715         .send_ttl = BT_MESH_TTL_DEFAULT,
716     };
717     struct relay_param param = {
718         .status = status,
719         .transmit = transmit,
720     };
721     int err;
722     err = cli_prepare(&param, OP_RELAY_STATUS);
723     if (err) {
724         goto done;
725     }
726 
727     bt_mesh_model_msg_init(msg, OP_RELAY_SET);
728     net_buf_simple_add_u8(msg, new_relay);
729     net_buf_simple_add_u8(msg, new_transmit);
730     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
731     if (err) {
732         BT_ERR("model_send() failed (err %d)", err);
733         cli_reset();
734         goto done;
735     }
736 
737     err = cli_wait();
738 done:
739     os_mbuf_free_chain(msg);
740     return err;
741 }
742 
bt_mesh_cfg_net_key_add(u16_t net_idx,u16_t addr,u16_t key_net_idx,const u8_t net_key[16],u8_t * status)743 int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
744                             const u8_t net_key[16], u8_t *status)
745 {
746     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_ADD, 18);
747     struct bt_mesh_msg_ctx ctx = {
748         .net_idx = net_idx,
749         .app_idx = BT_MESH_KEY_DEV_REMOTE,
750         .addr = addr,
751         .send_ttl = BT_MESH_TTL_DEFAULT,
752     };
753     struct net_key_param param = {
754         .status = status,
755         .net_idx = key_net_idx,
756     };
757     int err;
758     err = cli_prepare(&param, OP_NET_KEY_STATUS);
759     if (err) {
760         goto done;
761     }
762 
763     bt_mesh_model_msg_init(msg, OP_NET_KEY_ADD);
764     net_buf_simple_add_le16(msg, key_net_idx);
765     net_buf_simple_add_mem(msg, net_key, 16); // 16:byte alignment
766     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
767     if (err) {
768         BT_ERR("model_send() failed (err %d)", err);
769         cli_reset();
770         goto done;
771     }
772 
773     if (!status) {
774         cli_reset();
775         goto done;
776     }
777 
778     err = cli_wait();
779 done:
780     os_mbuf_free_chain(msg);
781     return err;
782 }
783 
bt_mesh_cfg_app_key_add(u16_t net_idx,u16_t addr,u16_t key_net_idx,u16_t key_app_idx,const u8_t app_key[16],u8_t * status)784 int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
785                             u16_t key_app_idx, const u8_t app_key[16], // 16:array length
786                             u8_t *status)
787 {
788     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_ADD, 19); // 19:array length
789     struct bt_mesh_msg_ctx ctx = {
790         .net_idx = net_idx,
791         .app_idx = BT_MESH_KEY_DEV_REMOTE,
792         .addr = addr,
793         .send_ttl = BT_MESH_TTL_DEFAULT,
794     };
795     struct app_key_param param = {
796         .status = status,
797         .net_idx = key_net_idx,
798         .app_idx = key_app_idx,
799     };
800     int err;
801     err = cli_prepare(&param, OP_APP_KEY_STATUS);
802     if (err) {
803         goto done;
804     }
805 
806     bt_mesh_model_msg_init(msg, OP_APP_KEY_ADD);
807     key_idx_pack(msg, key_net_idx, key_app_idx);
808     net_buf_simple_add_mem(msg, app_key, 16); // 16:array length
809     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
810     if (err) {
811         BT_ERR("model_send() failed (err %d)", err);
812         cli_reset();
813         goto done;
814     }
815 
816     if (!status) {
817         cli_reset();
818         goto done;
819     }
820 
821     err = cli_wait();
822 done:
823     os_mbuf_free_chain(msg);
824     return err;
825 }
826 
mod_app_bind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)827 static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
828                         u16_t mod_app_idx, u16_t mod_id, u16_t cid,
829                         u8_t *status)
830 {
831     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_BIND, 8);
832     struct bt_mesh_msg_ctx ctx = {
833         .net_idx = net_idx,
834         .app_idx = BT_MESH_KEY_DEV_REMOTE,
835         .addr = addr,
836         .send_ttl = BT_MESH_TTL_DEFAULT,
837     };
838     struct mod_app_param param = {
839         .status = status,
840         .elem_addr = elem_addr,
841         .mod_app_idx = mod_app_idx,
842         .mod_id = mod_id,
843         .cid = cid,
844     };
845     int err;
846     err = cli_prepare(&param, OP_MOD_APP_STATUS);
847     if (err) {
848         goto done;
849     }
850 
851     bt_mesh_model_msg_init(msg, OP_MOD_APP_BIND);
852     net_buf_simple_add_le16(msg, elem_addr);
853     net_buf_simple_add_le16(msg, mod_app_idx);
854 
855     if (cid != CID_NVAL) {
856         net_buf_simple_add_le16(msg, cid);
857     }
858 
859     net_buf_simple_add_le16(msg, mod_id);
860     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
861     if (err) {
862         BT_ERR("model_send() failed (err %d)", err);
863         cli_reset();
864         goto done;
865     }
866 
867     if (!status) {
868         cli_reset();
869         goto done;
870     }
871 
872     err = cli_wait();
873 done:
874     os_mbuf_free_chain(msg);
875     return err;
876 }
877 
bt_mesh_cfg_mod_app_bind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u8_t * status)878 int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
879                              u16_t mod_app_idx, u16_t mod_id, u8_t *status)
880 {
881     return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id,
882                         CID_NVAL, status);
883 }
884 
bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)885 int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
886                                  u16_t mod_app_idx, u16_t mod_id, u16_t cid,
887                                  u8_t *status)
888 {
889     if (cid == CID_NVAL) {
890         return -EINVAL;
891     }
892 
893     return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid,
894                         status);
895 }
896 
mod_sub(u32_t op,u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)897 static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
898                    u16_t sub_addr, u16_t mod_id, u16_t cid, u8_t *status)
899 {
900     struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 8);
901     struct bt_mesh_msg_ctx ctx = {
902         .net_idx = net_idx,
903         .app_idx = BT_MESH_KEY_DEV_REMOTE,
904         .addr = addr,
905         .send_ttl = BT_MESH_TTL_DEFAULT,
906     };
907     struct mod_sub_param param = {
908         .status = status,
909         .elem_addr = elem_addr,
910         .expect_sub = &sub_addr,
911         .mod_id = mod_id,
912         .cid = cid,
913     };
914     int err;
915     err = cli_prepare(&param, OP_MOD_SUB_STATUS);
916     if (err) {
917         goto done;
918     }
919 
920     bt_mesh_model_msg_init(msg, op);
921     net_buf_simple_add_le16(msg, elem_addr);
922     net_buf_simple_add_le16(msg, sub_addr);
923 
924     if (cid != CID_NVAL) {
925         net_buf_simple_add_le16(msg, cid);
926     }
927 
928     net_buf_simple_add_le16(msg, mod_id);
929     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
930     if (err) {
931         BT_ERR("model_send() failed (err %d)", err);
932         cli_reset();
933         goto done;
934     }
935 
936     if (!status) {
937         cli_reset();
938         goto done;
939     }
940 
941     err = cli_wait();
942 done:
943     os_mbuf_free_chain(msg);
944     return err;
945 }
946 
bt_mesh_cfg_mod_sub_add(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)947 int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
948                             u16_t sub_addr, u16_t mod_id, u8_t *status)
949 {
950     return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr,
951                    mod_id, CID_NVAL, status);
952 }
953 
bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)954 int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
955                                 u16_t sub_addr, u16_t mod_id, u16_t cid,
956                                 u8_t *status)
957 {
958     if (cid == CID_NVAL) {
959         return -EINVAL;
960     }
961 
962     return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr,
963                    mod_id, cid, status);
964 }
965 
bt_mesh_cfg_mod_sub_del(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)966 int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
967                             u16_t sub_addr, u16_t mod_id, u8_t *status)
968 {
969     return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr,
970                    mod_id, CID_NVAL, status);
971 }
972 
bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)973 int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
974                                 u16_t sub_addr, u16_t mod_id, u16_t cid,
975                                 u8_t *status)
976 {
977     if (cid == CID_NVAL) {
978         return -EINVAL;
979     }
980 
981     return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr,
982                    mod_id, cid, status);
983 }
984 
bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)985 int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr,
986                                   u16_t sub_addr, u16_t mod_id, u8_t *status)
987 {
988     return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr,
989                    sub_addr, mod_id, CID_NVAL, status);
990 }
991 
bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)992 int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr,
993                                       u16_t elem_addr, u16_t sub_addr,
994                                       u16_t mod_id, u16_t cid, u8_t *status)
995 {
996     if (cid == CID_NVAL) {
997         return -EINVAL;
998     }
999 
1000     return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr,
1001                    sub_addr, mod_id, cid, status);
1002 }
1003 
mod_sub_va(u32_t op,u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1004 static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
1005                       const u8_t label[16], u16_t mod_id, u16_t cid, // 16:array length
1006                       u16_t *virt_addr, u8_t *status)
1007 {
1008     struct os_mbuf *msg = BT_MESH_MODEL_BUF(DUMMY_2_BYTE_OP, 22); // 22:array length
1009     struct bt_mesh_msg_ctx ctx = {
1010         .net_idx = net_idx,
1011         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1012         .addr = addr,
1013         .send_ttl = BT_MESH_TTL_DEFAULT,
1014     };
1015     struct mod_sub_param param = {
1016         .status = status,
1017         .elem_addr = elem_addr,
1018         .sub_addr = virt_addr,
1019         .mod_id = mod_id,
1020         .cid = cid,
1021     };
1022     int err;
1023     err = cli_prepare(&param, OP_MOD_SUB_STATUS);
1024     if (err) {
1025         goto done;
1026     }
1027 
1028     BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s",
1029            net_idx, addr, elem_addr, label);
1030     BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
1031     bt_mesh_model_msg_init(msg, op);
1032     net_buf_simple_add_le16(msg, elem_addr);
1033     net_buf_simple_add_mem(msg, label, 16); // 16:array length
1034 
1035     if (cid != CID_NVAL) {
1036         net_buf_simple_add_le16(msg, cid);
1037     }
1038 
1039     net_buf_simple_add_le16(msg, mod_id);
1040     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1041     if (err) {
1042         BT_ERR("model_send() failed (err %d)", err);
1043         cli_reset();
1044         goto done;
1045     }
1046 
1047     if (!status) {
1048         cli_reset();
1049         goto done;
1050     }
1051 
1052     err = cli_wait();
1053 done:
1054     os_mbuf_free_chain(msg);
1055     return err;
1056 }
1057 
bt_mesh_cfg_mod_sub_va_add(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1058 int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
1059                                const u8_t label[16], u16_t mod_id, // 16:array length
1060                                u16_t *virt_addr, u8_t *status)
1061 {
1062     return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
1063                       mod_id, CID_NVAL, virt_addr, status);
1064 }
1065 
bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1066 int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1067                                    const u8_t label[16], u16_t mod_id, // 16:array length
1068                                    u16_t cid, u16_t *virt_addr, u8_t *status)
1069 {
1070     if (cid == CID_NVAL) {
1071         return -EINVAL;
1072     }
1073 
1074     return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
1075                       mod_id, cid, virt_addr, status);
1076 }
1077 
bt_mesh_cfg_mod_sub_va_del(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1078 int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
1079                                const u8_t label[16], u16_t mod_id, // 16:array length
1080                                u16_t *virt_addr, u8_t *status)
1081 {
1082     return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
1083                       mod_id, CID_NVAL, virt_addr, status);
1084 }
1085 
bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1086 int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1087                                    const u8_t label[16], u16_t mod_id, // 16:array length
1088                                    u16_t cid, u16_t *virt_addr, u8_t *status)
1089 {
1090     if (cid == CID_NVAL) {
1091         return -EINVAL;
1092     }
1093 
1094     return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
1095                       mod_id, cid, virt_addr, status);
1096 }
1097 
bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1098 int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr,
1099                                      u16_t elem_addr, const u8_t label[16], // 16:array length
1100                                      u16_t mod_id, u16_t *virt_addr,
1101                                      u8_t *status)
1102 {
1103     return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
1104                       label, mod_id, CID_NVAL, virt_addr, status);
1105 }
1106 
bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1107 int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr,
1108     u16_t elem_addr, const u8_t label[16], // 16:array length
1109     u16_t mod_id, u16_t cid,
1110     u16_t *virt_addr, u8_t *status)
1111 {
1112     if (cid == CID_NVAL) {
1113         return -EINVAL;
1114     }
1115 
1116     return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
1117                       label, mod_id, cid, virt_addr, status);
1118 }
1119 
mod_pub_get(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1120 static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
1121                        u16_t mod_id, u16_t cid,
1122                        struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1123 {
1124     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_GET, 6);
1125     struct bt_mesh_msg_ctx ctx = {
1126         .net_idx = net_idx,
1127         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1128         .addr = addr,
1129         .send_ttl = BT_MESH_TTL_DEFAULT,
1130     };
1131     struct mod_pub_param param = {
1132         .mod_id = mod_id,
1133         .cid = cid,
1134         .elem_addr = elem_addr,
1135         .status = status,
1136         .pub = pub,
1137     };
1138     int err;
1139     err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1140     if (err) {
1141         goto done;
1142     }
1143 
1144     bt_mesh_model_msg_init(msg, OP_MOD_PUB_GET);
1145     net_buf_simple_add_le16(msg, elem_addr);
1146 
1147     if (cid != CID_NVAL) {
1148         net_buf_simple_add_le16(msg, cid);
1149     }
1150 
1151     net_buf_simple_add_le16(msg, mod_id);
1152     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1153     if (err) {
1154         BT_ERR("model_send() failed (err %d)", err);
1155         cli_reset();
1156         goto done;
1157     }
1158 
1159     if (!status) {
1160         cli_reset();
1161         goto done;
1162     }
1163 
1164     err = cli_wait();
1165 done:
1166     os_mbuf_free_chain(msg);
1167     return err;
1168 }
1169 
bt_mesh_cfg_mod_pub_get(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1170 int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
1171                             u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1172                             u8_t *status)
1173 {
1174     return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL,
1175                        pub, status);
1176 }
1177 
bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1178 int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1179                                 u16_t mod_id, u16_t cid,
1180                                 struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1181 {
1182     if (cid == CID_NVAL) {
1183         return -EINVAL;
1184     }
1185 
1186     return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1187 }
1188 
mod_pub_set(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1189 static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
1190                        u16_t mod_id, u16_t cid,
1191                        struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1192 {
1193     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_SET, 13); // 13:array length
1194     struct bt_mesh_msg_ctx ctx = {
1195         .net_idx = net_idx,
1196         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1197         .addr = addr,
1198         .send_ttl = BT_MESH_TTL_DEFAULT,
1199     };
1200     struct mod_pub_param param = {
1201         .mod_id = mod_id,
1202         .cid = cid,
1203         .elem_addr = elem_addr,
1204         .status = status,
1205         .pub = pub,
1206     };
1207     int err;
1208     err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1209     if (err) {
1210         goto done;
1211     }
1212 
1213     bt_mesh_model_msg_init(msg, OP_MOD_PUB_SET);
1214     net_buf_simple_add_le16(msg, elem_addr);
1215     net_buf_simple_add_le16(msg, pub->addr);
1216     net_buf_simple_add_le16(msg, (pub->app_idx | (pub->cred_flag << 12))); // 12:byte alignment
1217     net_buf_simple_add_u8(msg, pub->ttl);
1218     net_buf_simple_add_u8(msg, pub->period);
1219     net_buf_simple_add_u8(msg, pub->transmit);
1220 
1221     if (cid != CID_NVAL) {
1222         net_buf_simple_add_le16(msg, cid);
1223     }
1224 
1225     net_buf_simple_add_le16(msg, mod_id);
1226     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1227     if (err) {
1228         BT_ERR("model_send() failed (err %d)", err);
1229         cli_reset();
1230         goto done;
1231     }
1232 
1233     if (!status) {
1234         cli_reset();
1235         goto done;
1236     }
1237 
1238     err = cli_wait();
1239 done:
1240     os_mbuf_free_chain(msg);
1241     return err;
1242 }
1243 
bt_mesh_cfg_mod_pub_set(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1244 int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
1245                             u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1246                             u8_t *status)
1247 {
1248     return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL,
1249                        pub, status);
1250 }
1251 
bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1252 int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1253                                 u16_t mod_id, u16_t cid,
1254                                 struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1255 {
1256     if (cid == CID_NVAL) {
1257         return -EINVAL;
1258     }
1259 
1260     return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1261 }
1262 
bt_mesh_cfg_hb_sub_set(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1263 int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
1264                            struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1265 {
1266     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_SET, 5); // 5:array length
1267     struct bt_mesh_msg_ctx ctx = {
1268         .net_idx = net_idx,
1269         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1270         .addr = addr,
1271         .send_ttl = BT_MESH_TTL_DEFAULT,
1272     };
1273     struct hb_sub_param param = {
1274         .status = status,
1275         .sub = sub,
1276     };
1277     int err;
1278     err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1279     if (err) {
1280         goto done;
1281     }
1282 
1283     bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_SET);
1284     net_buf_simple_add_le16(msg, sub->src);
1285     net_buf_simple_add_le16(msg, sub->dst);
1286     net_buf_simple_add_u8(msg, sub->period);
1287     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1288     if (err) {
1289         BT_ERR("model_send() failed (err %d)", err);
1290         cli_reset();
1291         goto done;
1292     }
1293 
1294     if (!status) {
1295         cli_reset();
1296         goto done;
1297     }
1298 
1299     err = cli_wait();
1300 done:
1301     os_mbuf_free_chain(msg);
1302     return err;
1303 }
1304 
bt_mesh_cfg_hb_sub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1305 int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr,
1306                            struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1307 {
1308     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_GET, 0);
1309     struct bt_mesh_msg_ctx ctx = {
1310         .net_idx = net_idx,
1311         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1312         .addr = addr,
1313         .send_ttl = BT_MESH_TTL_DEFAULT,
1314     };
1315     struct hb_sub_param param = {
1316         .status = status,
1317         .sub = sub,
1318     };
1319     int err;
1320     err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1321     if (err) {
1322         goto done;
1323     }
1324 
1325     bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_GET);
1326     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1327     if (err) {
1328         BT_ERR("model_send() failed (err %d)", err);
1329         cli_reset();
1330         goto done;
1331     }
1332 
1333     if (!status) {
1334         cli_reset();
1335         goto done;
1336     }
1337 
1338     err = cli_wait();
1339 done:
1340     os_mbuf_free_chain(msg);
1341     return err;
1342 }
1343 
bt_mesh_cfg_hb_pub_set(u16_t net_idx,u16_t addr,const struct bt_mesh_cfg_hb_pub * pub,u8_t * status)1344 int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr,
1345                            const struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
1346 {
1347     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_SET, 9); // 9:array length
1348     struct bt_mesh_msg_ctx ctx = {
1349         .net_idx = net_idx,
1350         .app_idx = BT_MESH_KEY_DEV_REMOTE,
1351         .addr = addr,
1352         .send_ttl = BT_MESH_TTL_DEFAULT,
1353     };
1354     struct hb_pub_param param = {
1355         .status = status,
1356     };
1357     int err;
1358     err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
1359     if (err) {
1360         goto done;
1361     }
1362 
1363     bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_SET);
1364     net_buf_simple_add_le16(msg, pub->dst);
1365     net_buf_simple_add_u8(msg, pub->count);
1366     net_buf_simple_add_u8(msg, pub->period);
1367     net_buf_simple_add_u8(msg, pub->ttl);
1368     net_buf_simple_add_le16(msg, pub->feat);
1369     net_buf_simple_add_le16(msg, pub->net_idx);
1370     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1371     if (err) {
1372         BT_ERR("model_send() failed (err %d)", err);
1373         cli_reset();
1374         goto done;
1375     }
1376 
1377     if (!status) {
1378         cli_reset();
1379         goto done;
1380     }
1381 
1382     err = cli_wait();
1383 done:
1384     os_mbuf_free_chain(msg);
1385     return err;
1386 }
1387 
bt_mesh_cfg_hb_pub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_pub * pub,u8_t * status)1388 int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr,
1389                            struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
1390 {
1391     struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_GET, 0);
1392     struct bt_mesh_msg_ctx ctx = {
1393         .net_idx = net_idx,
1394         .app_idx = BT_MESH_KEY_DEV,
1395         .addr = addr,
1396         .send_ttl = BT_MESH_TTL_DEFAULT,
1397     };
1398     struct hb_pub_param param = {
1399         .status = status,
1400         .pub = pub,
1401     };
1402     int err;
1403     err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
1404     if (err) {
1405         goto done;
1406     }
1407 
1408     bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_GET);
1409     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1410     if (err) {
1411         BT_ERR("model_send() failed (err %d)", err);
1412         cli_reset();
1413         goto done;
1414     }
1415 
1416     if (!status) {
1417         cli_reset();
1418         goto done;
1419     }
1420 
1421     err = cli_wait();
1422 done:
1423     os_mbuf_free_chain(msg);
1424     return err;
1425 }
1426 
bt_mesh_cfg_cli_timeout_get(void)1427 s32_t bt_mesh_cfg_cli_timeout_get(void)
1428 {
1429     return msg_timeout;
1430 }
1431 
bt_mesh_cfg_cli_timeout_set(s32_t timeout)1432 void bt_mesh_cfg_cli_timeout_set(s32_t timeout)
1433 {
1434     msg_timeout = timeout;
1435 }
1436 
1437 #endif