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(¶m, 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(¶m, 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(¶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 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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(¶m, 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