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