1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <zephyr/types.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/check.h>
15
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/mesh.h>
19
20 #include "common/bt_str.h"
21
22 #include "access.h"
23 #include "net.h"
24 #include "foundation.h"
25 #include "msg.h"
26
27 #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(bt_mesh_cfg_cli);
30
31 #define CID_NVAL 0xffff
32
33 /* 2 byte dummy opcode for getting compile time buffer sizes. */
34 #define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff)
35
36 #define COR_PRESENT(hdr) ((hdr) & BIT(0))
37 #define FMT(hdr) ((hdr) & BIT(1))
38 #define EXT_ITEM_CNT(hdr) ((hdr) >> 2)
39 #define OFFSET(item) (item & (uint8_t)BIT_MASK(5))
40 #define IDX(item) (item >> 3)
41
42 struct comp_data {
43 uint8_t *page;
44 struct net_buf_simple *comp;
45 };
46
47 static int32_t msg_timeout;
48
49 static struct bt_mesh_cfg_cli *cli;
50
comp_data_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)51 static int comp_data_status(struct bt_mesh_model *model,
52 struct bt_mesh_msg_ctx *ctx,
53 struct net_buf_simple *buf)
54 {
55 struct comp_data *param;
56 size_t to_copy;
57 uint8_t page;
58
59 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
60 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
61
62 page = net_buf_simple_pull_u8(buf);
63
64 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_DEV_COMP_DATA_STATUS, ctx->addr,
65 (void **)¶m)) {
66 if (param->page) {
67 *(param->page) = page;
68 }
69
70 if (param->comp) {
71 to_copy = MIN(net_buf_simple_tailroom(param->comp), buf->len);
72 net_buf_simple_add_mem(param->comp, buf->data, to_copy);
73 }
74
75 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
76 }
77 return 0;
78 }
79
state_status_u8(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,uint32_t expect_status)80 static uint8_t state_status_u8(struct bt_mesh_model *model,
81 struct bt_mesh_msg_ctx *ctx,
82 struct net_buf_simple *buf,
83 uint32_t expect_status)
84 {
85 uint8_t *param;
86 uint8_t status;
87
88 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
89 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
90
91 status = net_buf_simple_pull_u8(buf);
92
93 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, expect_status, ctx->addr,
94 (void **)¶m)) {
95
96 if (param) {
97 *param = status;
98 }
99
100 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
101 }
102
103 return status;
104 }
105
beacon_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)106 static int beacon_status(struct bt_mesh_model *model,
107 struct bt_mesh_msg_ctx *ctx,
108 struct net_buf_simple *buf)
109 {
110 uint8_t status;
111
112 status = state_status_u8(model, ctx, buf, OP_BEACON_STATUS);
113
114 if (cli->cb && cli->cb->beacon_status) {
115 cli->cb->beacon_status(cli, ctx->addr, status);
116 }
117
118 return 0;
119 }
120
ttl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)121 static int ttl_status(struct bt_mesh_model *model,
122 struct bt_mesh_msg_ctx *ctx,
123 struct net_buf_simple *buf)
124 {
125 uint8_t status;
126
127 status = state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS);
128
129 if (cli->cb && cli->cb->ttl_status) {
130 cli->cb->ttl_status(cli, ctx->addr, status);
131 }
132
133 return 0;
134 }
135
friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)136 static int friend_status(struct bt_mesh_model *model,
137 struct bt_mesh_msg_ctx *ctx,
138 struct net_buf_simple *buf)
139 {
140 uint8_t status;
141
142 status = state_status_u8(model, ctx, buf, OP_FRIEND_STATUS);
143
144 if (cli->cb && cli->cb->friend_status) {
145 cli->cb->friend_status(cli, ctx->addr, status);
146 }
147
148 return 0;
149 }
150
gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)151 static int gatt_proxy_status(struct bt_mesh_model *model,
152 struct bt_mesh_msg_ctx *ctx,
153 struct net_buf_simple *buf)
154 {
155
156 uint8_t status;
157
158 status = state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS);
159
160 if (cli->cb && cli->cb->gatt_proxy_status) {
161 cli->cb->gatt_proxy_status(cli, ctx->addr, status);
162 }
163
164 return 0;
165 }
166
167 struct krp_param {
168 uint8_t *status;
169 uint16_t net_idx;
170 uint8_t *phase;
171 };
172
krp_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)173 static int krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
174 struct net_buf_simple *buf)
175 {
176 struct krp_param *param;
177 uint16_t net_idx;
178 uint8_t status, phase;
179
180 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
181 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
182
183 status = net_buf_simple_pull_u8(buf);
184 net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
185 phase = net_buf_simple_pull_u8(buf);
186
187 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_KRP_STATUS, ctx->addr, (void **)¶m)) {
188 if (param->net_idx != net_idx) {
189 return -ENOENT;
190 }
191
192 if (param->status) {
193 *param->status = status;
194 }
195
196 if (param->phase) {
197 *param->phase = phase;
198 }
199
200 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
201 }
202
203 return 0;
204 }
205
206 struct relay_param {
207 uint8_t *status;
208 uint8_t *transmit;
209 };
210
relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)211 static int relay_status(struct bt_mesh_model *model,
212 struct bt_mesh_msg_ctx *ctx,
213 struct net_buf_simple *buf)
214 {
215 struct relay_param *param;
216 uint8_t status;
217 uint8_t transmit;
218
219 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
220 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
221
222 status = net_buf_simple_pull_u8(buf);
223 transmit = net_buf_simple_pull_u8(buf);
224
225 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_RELAY_STATUS, ctx->addr,
226 (void **)¶m)) {
227 if (param->status) {
228 *param->status = status;
229 }
230
231 if (param->transmit) {
232 *param->transmit = transmit;
233 }
234
235 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
236 }
237
238 if (cli->cb && cli->cb->relay_status) {
239 cli->cb->relay_status(cli, ctx->addr, status, transmit);
240 }
241
242 return 0;
243 }
244
net_transmit_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)245 static int net_transmit_status(struct bt_mesh_model *model,
246 struct bt_mesh_msg_ctx *ctx,
247 struct net_buf_simple *buf)
248 {
249 uint8_t status;
250
251 status = state_status_u8(model, ctx, buf, OP_NET_TRANSMIT_STATUS);
252
253 if (cli->cb && cli->cb->network_transmit_status) {
254 cli->cb->network_transmit_status(cli, ctx->addr, status);
255 }
256
257 return 0;
258 }
259
260 struct net_key_param {
261 uint8_t *status;
262 uint16_t net_idx;
263 };
264
net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)265 static int net_key_status(struct bt_mesh_model *model,
266 struct bt_mesh_msg_ctx *ctx,
267 struct net_buf_simple *buf)
268 {
269 struct net_key_param *param;
270 uint16_t net_idx;
271 uint8_t status;
272 int err;
273
274 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
275 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
276
277 status = net_buf_simple_pull_u8(buf);
278 net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
279
280 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_STATUS, ctx->addr,
281 (void **)¶m)) {
282
283 if (param->net_idx != net_idx) {
284 LOG_WRN("Net Key Status key index does not match");
285 err = -ENOENT;
286 goto done;
287 }
288
289 if (param->status) {
290 *param->status = status;
291 }
292
293 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
294 }
295
296 err = 0;
297
298 done:
299 if (cli->cb && cli->cb->net_key_status) {
300 cli->cb->net_key_status(cli, ctx->addr, status, net_idx);
301 }
302
303 return err;
304 }
305
306 struct net_key_list_param {
307 uint16_t *keys;
308 size_t *key_cnt;
309 };
310
net_key_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)311 static int net_key_list(struct bt_mesh_model *model,
312 struct bt_mesh_msg_ctx *ctx,
313 struct net_buf_simple *buf)
314 {
315 struct net_key_list_param *param;
316 int i;
317
318 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
319 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
320
321 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_LIST, ctx->addr,
322 (void **)¶m)) {
323
324 if (param->keys && param->key_cnt) {
325
326 for (i = 0; i < *param->key_cnt && buf->len >= 3; i += 2) {
327 key_idx_unpack(buf, ¶m->keys[i],
328 ¶m->keys[i + 1]);
329 }
330
331 if (i < *param->key_cnt && buf->len >= 2) {
332 param->keys[i++] =
333 net_buf_simple_pull_le16(buf) & 0xfff;
334 }
335
336 if (buf->len > 0) {
337 LOG_ERR("The message size for the application opcode is "
338 "incorrect.");
339 return -EMSGSIZE;
340 }
341
342 *param->key_cnt = i;
343 }
344
345 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
346 }
347
348 return 0;
349 }
350
node_reset_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)351 static int node_reset_status(struct bt_mesh_model *model,
352 struct bt_mesh_msg_ctx *ctx,
353 struct net_buf_simple *buf)
354 {
355 bool *param = NULL;
356
357 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", ctx->net_idx, ctx->app_idx, ctx->addr);
358
359 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_RESET_STATUS,
360 ctx->addr, (void **)¶m)) {
361
362 if (param) {
363 *param = true;
364 }
365
366 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
367 }
368
369 if (cli->cb && cli->cb->node_reset_status) {
370 cli->cb->node_reset_status(cli, ctx->addr);
371 }
372
373 return 0;
374 }
375
376 struct app_key_param {
377 uint8_t *status;
378 uint16_t net_idx;
379 uint16_t app_idx;
380 };
381
app_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)382 static int app_key_status(struct bt_mesh_model *model,
383 struct bt_mesh_msg_ctx *ctx,
384 struct net_buf_simple *buf)
385 {
386 struct app_key_param *param;
387 uint16_t net_idx, app_idx;
388 uint8_t status;
389 int err;
390
391 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
392 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
393
394 status = net_buf_simple_pull_u8(buf);
395 key_idx_unpack(buf, &net_idx, &app_idx);
396
397 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_STATUS, ctx->addr,
398 (void **)¶m)) {
399
400 if (param->net_idx != net_idx || param->app_idx != app_idx) {
401 LOG_WRN("App Key Status key indices did not match");
402 err = -ENOENT;
403 goto done;
404 }
405
406 if (param->status) {
407 *param->status = status;
408 }
409
410 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
411 }
412
413 err = 0;
414
415 done:
416 if (cli->cb && cli->cb->app_key_status) {
417 cli->cb->app_key_status(cli, ctx->addr, status, net_idx,
418 app_idx);
419 }
420
421 return err;
422 }
423
424 struct app_key_list_param {
425 uint16_t net_idx;
426 uint8_t *status;
427 uint16_t *keys;
428 size_t *key_cnt;
429 };
430
app_key_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)431 static int app_key_list(struct bt_mesh_model *model,
432 struct bt_mesh_msg_ctx *ctx,
433 struct net_buf_simple *buf)
434 {
435 struct app_key_list_param *param;
436 uint16_t net_idx;
437 uint8_t status;
438 int i;
439
440 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
441 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
442
443 status = net_buf_simple_pull_u8(buf);
444 net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
445
446 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_LIST, ctx->addr,
447 (void **)¶m)) {
448
449 if (param->net_idx != net_idx) {
450 LOG_WRN("App Key List Net Key index did not match");
451 return -ENOENT;
452 }
453
454 if (param->keys && param->key_cnt) {
455
456 for (i = 0; i < *param->key_cnt && buf->len >= 3; i += 2) {
457 key_idx_unpack(buf, ¶m->keys[i],
458 ¶m->keys[i + 1]);
459 }
460
461 if (i < *param->key_cnt && buf->len == 2) {
462 param->keys[i++] = net_buf_simple_pull_le16(buf) & 0xfff;
463 }
464
465 if (buf->len > 0U) {
466 LOG_ERR("The message size for the application opcode is "
467 "incorrect.");
468 return -EMSGSIZE;
469 }
470
471 *param->key_cnt = i;
472 }
473
474 if (param->status) {
475 *param->status = status;
476 }
477
478 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
479 }
480 return 0;
481 }
482
483 struct mod_app_param {
484 uint8_t *status;
485 uint16_t elem_addr;
486 uint16_t mod_app_idx;
487 uint16_t mod_id;
488 uint16_t cid;
489 };
490
mod_app_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)491 static int mod_app_status(struct bt_mesh_model *model,
492 struct bt_mesh_msg_ctx *ctx,
493 struct net_buf_simple *buf)
494 {
495 struct mod_app_param *param;
496 uint16_t elem_addr, mod_app_idx, mod_id, cid;
497 uint8_t status;
498 int err;
499
500 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
501 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
502
503 if ((buf->len != 7U) && (buf->len != 9U)) {
504 LOG_ERR("The message size for the application opcode is incorrect.");
505 return -EMSGSIZE;
506 }
507
508 status = net_buf_simple_pull_u8(buf);
509 elem_addr = net_buf_simple_pull_le16(buf);
510 mod_app_idx = net_buf_simple_pull_le16(buf);
511
512 if (buf->len >= 4U) {
513 cid = net_buf_simple_pull_le16(buf);
514 } else {
515 cid = CID_NVAL;
516 }
517
518 mod_id = net_buf_simple_pull_le16(buf);
519
520 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_APP_STATUS, ctx->addr,
521 (void **)¶m)) {
522
523 if (param->elem_addr != elem_addr ||
524 param->mod_app_idx != mod_app_idx ||
525 param->mod_id != mod_id || param->cid != cid) {
526 LOG_WRN("Model App Status parameters did not match");
527 err = -ENOENT;
528 goto done;
529 }
530
531 if (param->status) {
532 *param->status = status;
533 }
534
535 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
536 }
537
538 err = 0;
539
540 done:
541 if (cli->cb && cli->cb->mod_app_status) {
542 cli->cb->mod_app_status(cli, ctx->addr, status, elem_addr,
543 mod_app_idx, (cid << 16) | mod_id);
544 }
545
546 return err;
547 }
548
549 struct mod_member_list_param {
550 uint8_t *status;
551 uint16_t elem_addr;
552 uint16_t mod_id;
553 uint16_t cid;
554 uint16_t *members;
555 size_t *member_cnt;
556 };
557
mod_member_list_handle(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,uint16_t op,bool vnd)558 static int mod_member_list_handle(struct bt_mesh_msg_ctx *ctx,
559 struct net_buf_simple *buf, uint16_t op,
560 bool vnd)
561 {
562 struct mod_member_list_param *param;
563 uint16_t elem_addr, mod_id, cid;
564 uint8_t status;
565 int i;
566
567 if ((vnd && buf->len < 7U) || (buf->len < 5U)) {
568 LOG_ERR("The message size for the application opcode is incorrect.");
569 return -EMSGSIZE;
570 }
571
572 status = net_buf_simple_pull_u8(buf);
573 elem_addr = net_buf_simple_pull_le16(buf);
574 if (vnd) {
575 cid = net_buf_simple_pull_le16(buf);
576 }
577
578 mod_id = net_buf_simple_pull_le16(buf);
579
580 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, op, ctx->addr,
581 (void **)¶m)) {
582
583 if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
584 (vnd && param->cid != cid)) {
585 LOG_WRN("Model Member List parameters did not match");
586 return -ENOENT;
587 }
588
589 if (buf->len % 2) {
590 LOG_WRN("Model Member List invalid length");
591 return -EMSGSIZE;
592 }
593
594 if (param->member_cnt && param->members) {
595
596 for (i = 0; i < *param->member_cnt && buf->len; i++) {
597 param->members[i] = net_buf_simple_pull_le16(buf);
598 }
599
600 *param->member_cnt = i;
601 }
602
603 if (param->status) {
604 *param->status = status;
605 }
606
607 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
608 }
609 return 0;
610 }
611
mod_app_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)612 static int mod_app_list(struct bt_mesh_model *model,
613 struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
614 {
615 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
616 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
617
618 return mod_member_list_handle(ctx, buf, OP_SIG_MOD_APP_LIST, false);
619 }
620
mod_app_list_vnd(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)621 static int mod_app_list_vnd(struct bt_mesh_model *model,
622 struct bt_mesh_msg_ctx *ctx,
623 struct net_buf_simple *buf)
624 {
625 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
626 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
627
628 return mod_member_list_handle(ctx, buf, OP_VND_MOD_APP_LIST, true);
629 }
630
631 struct mod_pub_param {
632 uint16_t mod_id;
633 uint16_t cid;
634 uint16_t elem_addr;
635 uint8_t *status;
636 struct bt_mesh_cfg_cli_mod_pub *pub;
637 };
638
mod_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)639 static int mod_pub_status(struct bt_mesh_model *model,
640 struct bt_mesh_msg_ctx *ctx,
641 struct net_buf_simple *buf)
642 {
643 struct mod_pub_param *param;
644 uint16_t mod_id, cid, elem_addr;
645 struct bt_mesh_cfg_cli_mod_pub pub;
646 uint8_t status;
647
648 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
649 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
650
651 if ((buf->len != 12U) && (buf->len != 14U)) {
652 LOG_ERR("The message size for the application opcode is incorrect.");
653 return -EINVAL;
654 }
655
656 status = net_buf_simple_pull_u8(buf);
657
658 elem_addr = net_buf_simple_pull_le16(buf);
659
660 pub.addr = net_buf_simple_pull_le16(buf);
661 pub.app_idx = net_buf_simple_pull_le16(buf);
662 pub.cred_flag = (pub.app_idx & BIT(12));
663 pub.app_idx &= BIT_MASK(12);
664 pub.ttl = net_buf_simple_pull_u8(buf);
665 pub.period = net_buf_simple_pull_u8(buf);
666 pub.transmit = net_buf_simple_pull_u8(buf);
667
668 if (buf->len == 4U) {
669 cid = net_buf_simple_pull_le16(buf);
670 mod_id = net_buf_simple_pull_le16(buf);
671 } else {
672 cid = CID_NVAL;
673 mod_id = net_buf_simple_pull_le16(buf);
674 }
675
676 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_PUB_STATUS, ctx->addr,
677 (void **)¶m)) {
678 if (mod_id != param->mod_id || cid != param->cid) {
679 LOG_WRN("Mod Pub Model ID or Company ID mismatch");
680 return -ENOENT;
681 }
682
683 if (elem_addr != param->elem_addr) {
684 LOG_WRN("Model Pub Status for unexpected element (0x%04x)", elem_addr);
685 return -ENOENT;
686 }
687
688 if (param->status) {
689 *param->status = status;
690 }
691
692 if (param->pub) {
693 param->pub->addr = pub.addr;
694 param->pub->app_idx = pub.app_idx;
695 param->pub->cred_flag = pub.cred_flag;
696 param->pub->ttl = pub.ttl;
697 param->pub->period = pub.period;
698 param->pub->transmit = pub.transmit;
699 }
700
701 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
702 }
703 return 0;
704 }
705
706 struct mod_sub_param {
707 uint8_t *status;
708 uint16_t elem_addr;
709 uint16_t *sub_addr;
710 uint16_t *expect_sub;
711 uint16_t mod_id;
712 uint16_t cid;
713 };
714
mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)715 static int mod_sub_status(struct bt_mesh_model *model,
716 struct bt_mesh_msg_ctx *ctx,
717 struct net_buf_simple *buf)
718 {
719 struct mod_sub_param *param;
720 uint16_t elem_addr, sub_addr, mod_id, cid;
721 uint8_t status;
722 int err = 0;
723
724 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
725 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
726
727 if ((buf->len != 7U) && (buf->len != 9U)) {
728 LOG_ERR("The message size for the application opcode is incorrect.");
729 return -EINVAL;
730 }
731
732 status = net_buf_simple_pull_u8(buf);
733 elem_addr = net_buf_simple_pull_le16(buf);
734 sub_addr = net_buf_simple_pull_le16(buf);
735
736 if (buf->len >= 4U) {
737 cid = net_buf_simple_pull_le16(buf);
738 } else {
739 cid = CID_NVAL;
740 }
741
742 mod_id = net_buf_simple_pull_le16(buf);
743
744 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_STATUS,
745 ctx->addr, (void **)¶m)) {
746 if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
747 (param->expect_sub && *param->expect_sub != sub_addr) ||
748 param->cid != cid) {
749 LOG_WRN("Model Subscription Status parameters did not match");
750 err = -ENOENT;
751 goto done;
752 }
753
754 if (param->sub_addr) {
755 *param->sub_addr = sub_addr;
756 }
757
758 if (param->status) {
759 *param->status = status;
760 }
761
762 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
763 }
764
765 done:
766 if (cli->cb && cli->cb->mod_sub_status) {
767 cli->cb->mod_sub_status(cli, ctx->addr, status, elem_addr,
768 sub_addr, (cid << 16) | mod_id);
769 }
770
771 return err;
772 }
773
mod_sub_list(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)774 static int mod_sub_list(struct bt_mesh_model *model,
775 struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
776 {
777 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
778 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
779
780 return mod_member_list_handle(ctx, buf, OP_MOD_SUB_LIST, false);
781 }
782
mod_sub_list_vnd(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)783 static int mod_sub_list_vnd(struct bt_mesh_model *model,
784 struct bt_mesh_msg_ctx *ctx,
785 struct net_buf_simple *buf)
786 {
787 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
788 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
789
790 return mod_member_list_handle(ctx, buf, OP_MOD_SUB_LIST_VND, true);
791 }
792
793 struct hb_sub_param {
794 uint8_t *status;
795 struct bt_mesh_cfg_cli_hb_sub *sub;
796 };
797
hb_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)798 static int hb_sub_status(struct bt_mesh_model *model,
799 struct bt_mesh_msg_ctx *ctx,
800 struct net_buf_simple *buf)
801 {
802 struct hb_sub_param *param;
803 struct bt_mesh_cfg_cli_hb_sub sub;
804 uint8_t status;
805
806 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
807 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
808
809 status = net_buf_simple_pull_u8(buf);
810 sub.src = net_buf_simple_pull_le16(buf);
811 sub.dst = net_buf_simple_pull_le16(buf);
812 sub.period = net_buf_simple_pull_u8(buf);
813 sub.count = net_buf_simple_pull_u8(buf);
814 sub.min = net_buf_simple_pull_u8(buf);
815 sub.max = net_buf_simple_pull_u8(buf);
816
817 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_SUB_STATUS,
818 ctx->addr, (void **)¶m)) {
819 if (param->status) {
820 *param->status = status;
821 }
822
823 if (param->sub) {
824 *param->sub = sub;
825 }
826
827 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
828 }
829 return 0;
830 }
831
832 struct hb_pub_param {
833 uint8_t *status;
834 struct bt_mesh_cfg_cli_hb_pub *pub;
835 };
836
hb_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)837 static int hb_pub_status(struct bt_mesh_model *model,
838 struct bt_mesh_msg_ctx *ctx,
839 struct net_buf_simple *buf)
840 {
841 struct hb_pub_param *param;
842 uint8_t status;
843 struct bt_mesh_cfg_cli_hb_pub pub;
844
845 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
846 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
847
848 status = net_buf_simple_pull_u8(buf);
849 pub.dst = net_buf_simple_pull_le16(buf);
850 pub.count = net_buf_simple_pull_u8(buf);
851 pub.period = net_buf_simple_pull_u8(buf);
852 pub.ttl = net_buf_simple_pull_u8(buf);
853 pub.feat = net_buf_simple_pull_u8(buf);
854 pub.net_idx = net_buf_simple_pull_u8(buf);
855
856 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_PUB_STATUS,
857 ctx->addr, (void **)¶m)) {
858 if (param->status) {
859 *param->status = status;
860 }
861
862 if (param->pub) {
863 *param->pub = pub;
864 }
865
866 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
867 }
868 return 0;
869 }
870
871 struct node_idt_param {
872 uint8_t *status;
873 uint16_t net_idx;
874 uint8_t *identity;
875 };
876
node_identity_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)877 static int node_identity_status(struct bt_mesh_model *model,
878 struct bt_mesh_msg_ctx *ctx,
879 struct net_buf_simple *buf)
880 {
881 struct node_idt_param *param;
882 uint16_t net_idx, identity;
883 uint8_t status;
884
885 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
886 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
887
888 status = net_buf_simple_pull_u8(buf);
889 net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
890 identity = net_buf_simple_pull_u8(buf);
891
892 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_IDENTITY_STATUS, ctx->addr,
893 (void **)¶m)) {
894 if (param && param->status) {
895 *param->status = status;
896 }
897
898 if (param && param->identity) {
899 *param->identity = identity;
900 }
901
902 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
903 }
904
905 if (cli->cb && cli->cb->node_identity_status) {
906 cli->cb->node_identity_status(cli, ctx->addr, status,
907 net_idx, identity);
908 }
909
910 return 0;
911 }
912
913 struct lpn_timeout_param {
914 uint16_t unicast_addr;
915 int32_t *polltimeout;
916 };
917
lpn_timeout_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)918 static int lpn_timeout_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
919 struct net_buf_simple *buf)
920 {
921 struct lpn_timeout_param *param;
922 uint16_t unicast_addr;
923 int32_t polltimeout;
924 int err;
925
926 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
927 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
928
929 unicast_addr = net_buf_simple_pull_le16(buf);
930 polltimeout = net_buf_simple_pull_le24(buf);
931
932 if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_LPN_TIMEOUT_STATUS, ctx->addr,
933 (void **)¶m)) {
934 if (param->unicast_addr != unicast_addr) {
935 err = -ENOENT;
936 goto done;
937 }
938
939 if (param->polltimeout) {
940 *param->polltimeout = polltimeout;
941 }
942
943 bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
944 }
945
946 err = 0;
947
948 done:
949 if (cli->cb && cli->cb->lpn_timeout_status) {
950 cli->cb->lpn_timeout_status(cli, ctx->addr, unicast_addr,
951 polltimeout);
952 }
953
954 return err;
955 }
956
957 const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
958 { OP_DEV_COMP_DATA_STATUS, BT_MESH_LEN_MIN(5), comp_data_status },
959 { OP_BEACON_STATUS, BT_MESH_LEN_EXACT(1), beacon_status },
960 { OP_DEFAULT_TTL_STATUS, BT_MESH_LEN_EXACT(1), ttl_status },
961 { OP_FRIEND_STATUS, BT_MESH_LEN_EXACT(1), friend_status },
962 { OP_GATT_PROXY_STATUS, BT_MESH_LEN_EXACT(1), gatt_proxy_status },
963 { OP_RELAY_STATUS, BT_MESH_LEN_EXACT(2), relay_status },
964 { OP_NET_TRANSMIT_STATUS, BT_MESH_LEN_EXACT(1), net_transmit_status },
965 { OP_NET_KEY_STATUS, BT_MESH_LEN_EXACT(3), net_key_status },
966 { OP_NET_KEY_LIST, BT_MESH_LEN_MIN(0), net_key_list },
967 { OP_APP_KEY_STATUS, BT_MESH_LEN_EXACT(4), app_key_status },
968 { OP_APP_KEY_LIST, BT_MESH_LEN_MIN(3), app_key_list },
969 { OP_MOD_APP_STATUS, BT_MESH_LEN_MIN(7), mod_app_status },
970 { OP_SIG_MOD_APP_LIST, BT_MESH_LEN_MIN(5), mod_app_list },
971 { OP_VND_MOD_APP_LIST, BT_MESH_LEN_MIN(7), mod_app_list_vnd },
972 { OP_MOD_PUB_STATUS, BT_MESH_LEN_MIN(12), mod_pub_status },
973 { OP_MOD_SUB_STATUS, BT_MESH_LEN_MIN(7), mod_sub_status },
974 { OP_MOD_SUB_LIST, BT_MESH_LEN_MIN(5), mod_sub_list },
975 { OP_MOD_SUB_LIST_VND, BT_MESH_LEN_MIN(7), mod_sub_list_vnd },
976 { OP_HEARTBEAT_SUB_STATUS, BT_MESH_LEN_EXACT(9), hb_sub_status },
977 { OP_HEARTBEAT_PUB_STATUS, BT_MESH_LEN_EXACT(10), hb_pub_status },
978 { OP_NODE_RESET_STATUS, BT_MESH_LEN_EXACT(0), node_reset_status },
979 { OP_NODE_IDENTITY_STATUS, BT_MESH_LEN_EXACT(4), node_identity_status},
980 { OP_LPN_TIMEOUT_STATUS, BT_MESH_LEN_EXACT(5), lpn_timeout_status },
981 { OP_KRP_STATUS, BT_MESH_LEN_EXACT(4), krp_status},
982 BT_MESH_MODEL_OP_END,
983 };
984
cfg_cli_init(struct bt_mesh_model * model)985 static int cfg_cli_init(struct bt_mesh_model *model)
986 {
987 if (!bt_mesh_model_in_primary(model)) {
988 LOG_ERR("Configuration Client only allowed in primary element");
989 return -EINVAL;
990 }
991
992 if (!model->user_data) {
993 LOG_ERR("No Configuration Client context provided");
994 return -EINVAL;
995 }
996
997 cli = model->user_data;
998 cli->model = model;
999 msg_timeout = CONFIG_BT_MESH_CFG_CLI_TIMEOUT;
1000
1001 /*
1002 * Configuration Model security is device-key based and both the local
1003 * and remote keys are allowed to access this model.
1004 */
1005 model->keys[0] = BT_MESH_KEY_DEV_ANY;
1006 model->flags |= BT_MESH_MOD_DEVKEY_ONLY;
1007
1008 bt_mesh_msg_ack_ctx_init(&cli->ack_ctx);
1009
1010 return 0;
1011 }
1012
1013 const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb = {
1014 .init = cfg_cli_init,
1015 };
1016
bt_mesh_cfg_cli_comp_data_get(uint16_t net_idx,uint16_t addr,uint8_t page,uint8_t * rsp,struct net_buf_simple * comp)1017 int bt_mesh_cfg_cli_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, uint8_t *rsp,
1018 struct net_buf_simple *comp)
1019 {
1020 BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEV_COMP_DATA_GET, 1);
1021 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1022 struct comp_data param = {
1023 .page = rsp,
1024 .comp = comp,
1025 };
1026 const struct bt_mesh_msg_rsp_ctx rsp_ctx = {
1027 .ack = &cli->ack_ctx,
1028 .op = OP_DEV_COMP_DATA_STATUS,
1029 .user_data = ¶m,
1030 .timeout = msg_timeout,
1031 };
1032
1033 bt_mesh_model_msg_init(&msg, OP_DEV_COMP_DATA_GET);
1034 net_buf_simple_add_u8(&msg, page);
1035
1036 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !rsp && !comp ? NULL : &rsp_ctx);
1037 }
1038
get_state_u8(uint16_t net_idx,uint16_t addr,uint32_t op,uint32_t rsp,uint8_t * val)1039 static int get_state_u8(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t rsp, uint8_t *val)
1040 {
1041 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 0);
1042 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1043 const struct bt_mesh_msg_rsp_ctx rsp_ctx = {
1044 .ack = &cli->ack_ctx,
1045 .op = rsp,
1046 .user_data = val,
1047 .timeout = msg_timeout,
1048 };
1049
1050 bt_mesh_model_msg_init(&msg, op);
1051 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !val ? NULL : &rsp_ctx);
1052 }
1053
set_state_u8(uint16_t net_idx,uint16_t addr,uint32_t op,uint32_t rsp,uint8_t new_val,uint8_t * val)1054 static int set_state_u8(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t rsp, uint8_t new_val,
1055 uint8_t *val)
1056 {
1057 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 1);
1058 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1059 const struct bt_mesh_msg_rsp_ctx rsp_ctx = {
1060 .ack = &cli->ack_ctx,
1061 .op = rsp,
1062 .user_data = val,
1063 .timeout = msg_timeout,
1064 };
1065
1066 bt_mesh_model_msg_init(&msg, op);
1067 net_buf_simple_add_u8(&msg, new_val);
1068
1069 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !val ? NULL : &rsp_ctx);
1070 }
1071
bt_mesh_cfg_cli_beacon_get(uint16_t net_idx,uint16_t addr,uint8_t * status)1072 int bt_mesh_cfg_cli_beacon_get(uint16_t net_idx, uint16_t addr, uint8_t *status)
1073 {
1074 return get_state_u8(net_idx, addr, OP_BEACON_GET, OP_BEACON_STATUS, status);
1075 }
1076
bt_mesh_cfg_cli_krp_get(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t * status,uint8_t * phase)1077 int bt_mesh_cfg_cli_krp_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, uint8_t *status,
1078 uint8_t *phase)
1079 {
1080 BT_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_GET, 2);
1081 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1082 struct krp_param param = {
1083 .status = status,
1084 .phase = phase,
1085 };
1086 const struct bt_mesh_msg_rsp_ctx rsp = {
1087 .ack = &cli->ack_ctx,
1088 .op = OP_KRP_STATUS,
1089 .user_data = ¶m,
1090 .timeout = msg_timeout,
1091 };
1092
1093 bt_mesh_model_msg_init(&msg, OP_KRP_GET);
1094 net_buf_simple_add_le16(&msg, key_net_idx);
1095
1096 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !phase ? NULL : &rsp);
1097 }
1098
bt_mesh_cfg_cli_krp_set(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t transition,uint8_t * status,uint8_t * phase)1099 int bt_mesh_cfg_cli_krp_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1100 uint8_t transition, uint8_t *status, uint8_t *phase)
1101 {
1102 BT_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_SET, 3);
1103 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1104 struct krp_param param = {
1105 .status = status,
1106 .phase = phase,
1107 };
1108 const struct bt_mesh_msg_rsp_ctx rsp = {
1109 .ack = &cli->ack_ctx,
1110 .op = OP_KRP_STATUS,
1111 .user_data = ¶m,
1112 .timeout = msg_timeout,
1113 };
1114
1115 bt_mesh_model_msg_init(&msg, OP_KRP_SET);
1116 net_buf_simple_add_le16(&msg, key_net_idx);
1117 net_buf_simple_add_u8(&msg, transition);
1118
1119 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !phase ? NULL : &rsp);
1120 }
1121
bt_mesh_cfg_cli_beacon_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1122 int bt_mesh_cfg_cli_beacon_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1123 {
1124 return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS, val, status);
1125 }
1126
bt_mesh_cfg_cli_ttl_get(uint16_t net_idx,uint16_t addr,uint8_t * ttl)1127 int bt_mesh_cfg_cli_ttl_get(uint16_t net_idx, uint16_t addr, uint8_t *ttl)
1128 {
1129 return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET, OP_DEFAULT_TTL_STATUS, ttl);
1130 }
1131
bt_mesh_cfg_cli_ttl_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * ttl)1132 int bt_mesh_cfg_cli_ttl_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *ttl)
1133 {
1134 return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET, OP_DEFAULT_TTL_STATUS, val, ttl);
1135 }
1136
bt_mesh_cfg_cli_friend_get(uint16_t net_idx,uint16_t addr,uint8_t * status)1137 int bt_mesh_cfg_cli_friend_get(uint16_t net_idx, uint16_t addr, uint8_t *status)
1138 {
1139 return get_state_u8(net_idx, addr, OP_FRIEND_GET, OP_FRIEND_STATUS, status);
1140 }
1141
bt_mesh_cfg_cli_friend_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1142 int bt_mesh_cfg_cli_friend_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1143 {
1144 return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS, val, status);
1145 }
1146
bt_mesh_cfg_cli_gatt_proxy_get(uint16_t net_idx,uint16_t addr,uint8_t * status)1147 int bt_mesh_cfg_cli_gatt_proxy_get(uint16_t net_idx, uint16_t addr, uint8_t *status)
1148 {
1149 return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET, OP_GATT_PROXY_STATUS, status);
1150 }
1151
bt_mesh_cfg_cli_gatt_proxy_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1152 int bt_mesh_cfg_cli_gatt_proxy_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1153 {
1154 return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET, OP_GATT_PROXY_STATUS, val, status);
1155 }
1156
bt_mesh_cfg_cli_net_transmit_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * transmit)1157 int bt_mesh_cfg_cli_net_transmit_set(uint16_t net_idx, uint16_t addr, uint8_t val,
1158 uint8_t *transmit)
1159 {
1160 return set_state_u8(net_idx, addr, OP_NET_TRANSMIT_SET, OP_NET_TRANSMIT_STATUS, val,
1161 transmit);
1162 }
1163
bt_mesh_cfg_cli_net_transmit_get(uint16_t net_idx,uint16_t addr,uint8_t * transmit)1164 int bt_mesh_cfg_cli_net_transmit_get(uint16_t net_idx, uint16_t addr, uint8_t *transmit)
1165 {
1166 return get_state_u8(net_idx, addr, OP_NET_TRANSMIT_GET, OP_NET_TRANSMIT_STATUS, transmit);
1167 }
1168
bt_mesh_cfg_cli_relay_get(uint16_t net_idx,uint16_t addr,uint8_t * status,uint8_t * transmit)1169 int bt_mesh_cfg_cli_relay_get(uint16_t net_idx, uint16_t addr, uint8_t *status, uint8_t *transmit)
1170 {
1171 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_GET, 0);
1172 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1173 struct relay_param param = {
1174 .status = status,
1175 .transmit = transmit,
1176 };
1177 const struct bt_mesh_msg_rsp_ctx rsp = {
1178 .ack = &cli->ack_ctx,
1179 .op = OP_RELAY_STATUS,
1180 .user_data = ¶m,
1181 .timeout = msg_timeout,
1182 };
1183
1184 bt_mesh_model_msg_init(&msg, OP_RELAY_GET);
1185
1186 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !transmit ? NULL : &rsp);
1187 }
1188
bt_mesh_cfg_cli_relay_set(uint16_t net_idx,uint16_t addr,uint8_t new_relay,uint8_t new_transmit,uint8_t * status,uint8_t * transmit)1189 int bt_mesh_cfg_cli_relay_set(uint16_t net_idx, uint16_t addr, uint8_t new_relay,
1190 uint8_t new_transmit, uint8_t *status, uint8_t *transmit)
1191 {
1192 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2);
1193 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1194 struct relay_param param = {
1195 .status = status,
1196 .transmit = transmit,
1197 };
1198 const struct bt_mesh_msg_rsp_ctx rsp = {
1199 .ack = &cli->ack_ctx,
1200 .op = OP_RELAY_STATUS,
1201 .user_data = ¶m,
1202 .timeout = msg_timeout,
1203 };
1204
1205 bt_mesh_model_msg_init(&msg, OP_RELAY_SET);
1206 net_buf_simple_add_u8(&msg, new_relay);
1207 net_buf_simple_add_u8(&msg, new_transmit);
1208
1209 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !transmit ? NULL : &rsp);
1210 }
1211
bt_mesh_cfg_cli_net_key_add(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,const uint8_t net_key[16],uint8_t * status)1212 int bt_mesh_cfg_cli_net_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1213 const uint8_t net_key[16], uint8_t *status)
1214 {
1215 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18);
1216 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1217 struct net_key_param param = {
1218 .status = status,
1219 .net_idx = key_net_idx,
1220 };
1221 const struct bt_mesh_msg_rsp_ctx rsp = {
1222 .ack = &cli->ack_ctx,
1223 .op = OP_NET_KEY_STATUS,
1224 .user_data = ¶m,
1225 .timeout = msg_timeout,
1226 };
1227
1228 bt_mesh_model_msg_init(&msg, OP_NET_KEY_ADD);
1229 net_buf_simple_add_le16(&msg, key_net_idx);
1230 net_buf_simple_add_mem(&msg, net_key, 16);
1231
1232 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1233 }
1234
bt_mesh_cfg_cli_net_key_update(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,const uint8_t net_key[16],uint8_t * status)1235 int bt_mesh_cfg_cli_net_key_update(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1236 const uint8_t net_key[16], uint8_t *status)
1237 {
1238 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18);
1239 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1240 struct net_key_param param = {
1241 .status = status,
1242 .net_idx = key_net_idx,
1243 };
1244 const struct bt_mesh_msg_rsp_ctx rsp = {
1245 .ack = &cli->ack_ctx,
1246 .op = OP_NET_KEY_STATUS,
1247 .user_data = ¶m,
1248 .timeout = msg_timeout,
1249 };
1250
1251 bt_mesh_model_msg_init(&msg, OP_NET_KEY_UPDATE);
1252 net_buf_simple_add_le16(&msg, key_net_idx);
1253 net_buf_simple_add_mem(&msg, net_key, 16);
1254
1255 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1256 }
1257
bt_mesh_cfg_cli_net_key_get(uint16_t net_idx,uint16_t addr,uint16_t * keys,size_t * key_cnt)1258 int bt_mesh_cfg_cli_net_key_get(uint16_t net_idx, uint16_t addr, uint16_t *keys, size_t *key_cnt)
1259 {
1260 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_GET, 0);
1261 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1262 struct net_key_list_param param = {
1263 .keys = keys,
1264 .key_cnt = key_cnt,
1265 };
1266 const struct bt_mesh_msg_rsp_ctx rsp = {
1267 .ack = &cli->ack_ctx,
1268 .op = OP_NET_KEY_LIST,
1269 .user_data = ¶m,
1270 .timeout = msg_timeout,
1271 };
1272
1273 bt_mesh_model_msg_init(&msg, OP_NET_KEY_GET);
1274
1275 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !keys && !key_cnt ? NULL : &rsp);
1276 }
1277
bt_mesh_cfg_cli_net_key_del(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t * status)1278 int bt_mesh_cfg_cli_net_key_del(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1279 uint8_t *status)
1280 {
1281 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_DEL, 2);
1282 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1283 struct net_key_param param = {
1284 .status = status,
1285 .net_idx = key_net_idx,
1286 };
1287 const struct bt_mesh_msg_rsp_ctx rsp = {
1288 .ack = &cli->ack_ctx,
1289 .op = OP_NET_KEY_STATUS,
1290 .user_data = ¶m,
1291 .timeout = msg_timeout,
1292 };
1293
1294 bt_mesh_model_msg_init(&msg, OP_NET_KEY_DEL);
1295 net_buf_simple_add_le16(&msg, key_net_idx);
1296
1297 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1298 }
1299
bt_mesh_cfg_cli_app_key_add(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint16_t key_app_idx,const uint8_t app_key[16],uint8_t * status)1300 int bt_mesh_cfg_cli_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1301 uint16_t key_app_idx, const uint8_t app_key[16], uint8_t *status)
1302 {
1303 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19);
1304 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1305 struct app_key_param param = {
1306 .status = status,
1307 .net_idx = key_net_idx,
1308 .app_idx = key_app_idx,
1309 };
1310 const struct bt_mesh_msg_rsp_ctx rsp = {
1311 .ack = &cli->ack_ctx,
1312 .op = OP_APP_KEY_STATUS,
1313 .user_data = ¶m,
1314 .timeout = msg_timeout,
1315 };
1316
1317 bt_mesh_model_msg_init(&msg, OP_APP_KEY_ADD);
1318 key_idx_pack(&msg, key_net_idx, key_app_idx);
1319 net_buf_simple_add_mem(&msg, app_key, 16);
1320
1321 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1322 }
1323
bt_mesh_cfg_cli_app_key_update(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint16_t key_app_idx,const uint8_t app_key[16],uint8_t * status)1324 int bt_mesh_cfg_cli_app_key_update(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1325 uint16_t key_app_idx, const uint8_t app_key[16], uint8_t *status)
1326 {
1327 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19);
1328 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1329 struct app_key_param param = {
1330 .status = status,
1331 .net_idx = key_net_idx,
1332 .app_idx = key_app_idx,
1333 };
1334 const struct bt_mesh_msg_rsp_ctx rsp = {
1335 .ack = &cli->ack_ctx,
1336 .op = OP_APP_KEY_STATUS,
1337 .user_data = ¶m,
1338 .timeout = msg_timeout,
1339 };
1340
1341 bt_mesh_model_msg_init(&msg, OP_APP_KEY_UPDATE);
1342 key_idx_pack(&msg, key_net_idx, key_app_idx);
1343 net_buf_simple_add_mem(&msg, app_key, 16);
1344
1345 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1346 }
1347
bt_mesh_cfg_cli_node_reset(uint16_t net_idx,uint16_t addr,bool * status)1348 int bt_mesh_cfg_cli_node_reset(uint16_t net_idx, uint16_t addr, bool *status)
1349 {
1350 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET, 0);
1351 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1352
1353 if (status) {
1354 *status = false;
1355 }
1356
1357 const struct bt_mesh_msg_rsp_ctx rsp = {
1358 .ack = &cli->ack_ctx,
1359 .op = OP_NODE_RESET_STATUS,
1360 .user_data = status,
1361 .timeout = msg_timeout,
1362 };
1363
1364 bt_mesh_model_msg_init(&msg, OP_NODE_RESET);
1365
1366 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1367 }
1368
bt_mesh_cfg_cli_app_key_get(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t * status,uint16_t * keys,size_t * key_cnt)1369 int bt_mesh_cfg_cli_app_key_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1370 uint8_t *status, uint16_t *keys, size_t *key_cnt)
1371 {
1372 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_GET, 2);
1373 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1374 struct app_key_list_param param = {
1375 .net_idx = key_net_idx,
1376 .status = status,
1377 .keys = keys,
1378 .key_cnt = key_cnt,
1379 };
1380 const struct bt_mesh_msg_rsp_ctx rsp = {
1381 .ack = &cli->ack_ctx,
1382 .op = OP_APP_KEY_LIST,
1383 .user_data = ¶m,
1384 .timeout = msg_timeout,
1385 };
1386
1387 bt_mesh_model_msg_init(&msg, OP_APP_KEY_GET);
1388 net_buf_simple_add_le16(&msg, key_net_idx);
1389
1390 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg,
1391 !status && (!keys || !key_cnt) ? NULL : &rsp);
1392 }
1393
bt_mesh_cfg_cli_app_key_del(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint16_t key_app_idx,uint8_t * status)1394 int bt_mesh_cfg_cli_app_key_del(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1395 uint16_t key_app_idx, uint8_t *status)
1396 {
1397 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3);
1398 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1399 struct app_key_param param = {
1400 .status = status,
1401 .net_idx = key_net_idx,
1402 .app_idx = key_app_idx,
1403 };
1404 const struct bt_mesh_msg_rsp_ctx rsp = {
1405 .ack = &cli->ack_ctx,
1406 .op = OP_APP_KEY_STATUS,
1407 .user_data = ¶m,
1408 .timeout = msg_timeout,
1409 };
1410
1411 bt_mesh_model_msg_init(&msg, OP_APP_KEY_DEL);
1412 key_idx_pack(&msg, key_net_idx, key_app_idx);
1413
1414 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1415 }
1416
mod_app_bind(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint16_t cid,uint8_t * status)1417 static int mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_app_idx,
1418 uint16_t mod_id, uint16_t cid, uint8_t *status)
1419 {
1420 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8);
1421 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1422 struct mod_app_param param = {
1423 .status = status,
1424 .elem_addr = elem_addr,
1425 .mod_app_idx = mod_app_idx,
1426 .mod_id = mod_id,
1427 .cid = cid,
1428 };
1429 const struct bt_mesh_msg_rsp_ctx rsp = {
1430 .ack = &cli->ack_ctx,
1431 .op = OP_MOD_APP_STATUS,
1432 .user_data = ¶m,
1433 .timeout = msg_timeout,
1434 };
1435
1436 bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND);
1437 net_buf_simple_add_le16(&msg, elem_addr);
1438 net_buf_simple_add_le16(&msg, mod_app_idx);
1439
1440 if (cid != CID_NVAL) {
1441 net_buf_simple_add_le16(&msg, cid);
1442 }
1443
1444 net_buf_simple_add_le16(&msg, mod_id);
1445
1446 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1447 }
1448
bt_mesh_cfg_cli_mod_app_bind(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint8_t * status)1449 int bt_mesh_cfg_cli_mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1450 uint16_t mod_app_idx, uint16_t mod_id, uint8_t *status)
1451 {
1452 return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1453 }
1454
bt_mesh_cfg_cli_mod_app_bind_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint16_t cid,uint8_t * status)1455 int bt_mesh_cfg_cli_mod_app_bind_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1456 uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid,
1457 uint8_t *status)
1458 {
1459 if (cid == CID_NVAL) {
1460 return -EINVAL;
1461 }
1462
1463 return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1464 }
1465
mod_app_unbind(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint16_t cid,uint8_t * status)1466 static int mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_app_idx,
1467 uint16_t mod_id, uint16_t cid, uint8_t *status)
1468 {
1469 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8);
1470 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1471 struct mod_app_param param = {
1472 .status = status,
1473 .elem_addr = elem_addr,
1474 .mod_app_idx = mod_app_idx,
1475 .mod_id = mod_id,
1476 .cid = cid,
1477 };
1478 const struct bt_mesh_msg_rsp_ctx rsp = {
1479 .ack = &cli->ack_ctx,
1480 .op = OP_MOD_APP_STATUS,
1481 .user_data = ¶m,
1482 .timeout = msg_timeout,
1483 };
1484
1485 bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND);
1486 net_buf_simple_add_le16(&msg, elem_addr);
1487 net_buf_simple_add_le16(&msg, mod_app_idx);
1488
1489 if (cid != CID_NVAL) {
1490 net_buf_simple_add_le16(&msg, cid);
1491 }
1492
1493 net_buf_simple_add_le16(&msg, mod_id);
1494
1495 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1496 }
1497
bt_mesh_cfg_cli_mod_app_unbind(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint8_t * status)1498 int bt_mesh_cfg_cli_mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1499 uint16_t mod_app_idx, uint16_t mod_id, uint8_t *status)
1500 {
1501 return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1502 }
1503
bt_mesh_cfg_cli_mod_app_unbind_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_app_idx,uint16_t mod_id,uint16_t cid,uint8_t * status)1504 int bt_mesh_cfg_cli_mod_app_unbind_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1505 uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid,
1506 uint8_t *status)
1507 {
1508 if (cid == CID_NVAL) {
1509 return -EINVAL;
1510 }
1511
1512 return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1513 }
1514
mod_member_list_get(uint32_t op,uint32_t expect_op,uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,uint8_t * status,uint16_t * apps,size_t * app_cnt)1515 static int mod_member_list_get(uint32_t op, uint32_t expect_op, uint16_t net_idx, uint16_t addr,
1516 uint16_t elem_addr, uint16_t mod_id, uint16_t cid, uint8_t *status,
1517 uint16_t *apps, size_t *app_cnt)
1518 {
1519 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6);
1520 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1521 struct mod_member_list_param param = {
1522 .status = status,
1523 .elem_addr = elem_addr,
1524 .mod_id = mod_id,
1525 .cid = cid,
1526 .members = apps,
1527 .member_cnt = app_cnt,
1528 };
1529 const struct bt_mesh_msg_rsp_ctx rsp = {
1530 .ack = &cli->ack_ctx,
1531 .op = expect_op,
1532 .user_data = ¶m,
1533 .timeout = msg_timeout,
1534 };
1535
1536 LOG_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x", net_idx, addr, elem_addr);
1537 LOG_DBG("mod_id 0x%04x cid 0x%04x op: %x", mod_id, cid, op);
1538
1539 bt_mesh_model_msg_init(&msg, op);
1540 net_buf_simple_add_le16(&msg, elem_addr);
1541
1542 if (cid != CID_NVAL) {
1543 net_buf_simple_add_le16(&msg, cid);
1544 }
1545
1546 net_buf_simple_add_le16(&msg, mod_id);
1547
1548 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg,
1549 !status && (!apps || !app_cnt) ? NULL : &rsp);
1550 }
1551
bt_mesh_cfg_cli_mod_app_get(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint8_t * status,uint16_t * apps,size_t * app_cnt)1552 int bt_mesh_cfg_cli_mod_app_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1553 uint16_t mod_id, uint8_t *status, uint16_t *apps, size_t *app_cnt)
1554 {
1555 return mod_member_list_get(OP_SIG_MOD_APP_GET, OP_SIG_MOD_APP_LIST, net_idx, addr,
1556 elem_addr, mod_id, CID_NVAL, status, apps, app_cnt);
1557 }
1558
bt_mesh_cfg_cli_mod_app_get_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,uint8_t * status,uint16_t * apps,size_t * app_cnt)1559 int bt_mesh_cfg_cli_mod_app_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1560 uint16_t mod_id, uint16_t cid, uint8_t *status, uint16_t *apps,
1561 size_t *app_cnt)
1562 {
1563 if (cid == CID_NVAL) {
1564 return -EINVAL;
1565 }
1566
1567 return mod_member_list_get(OP_VND_MOD_APP_GET, OP_VND_MOD_APP_LIST, net_idx, addr,
1568 elem_addr, mod_id, cid, status, apps, app_cnt);
1569 }
1570
mod_sub(uint32_t op,uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid,uint8_t * status)1571 static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1572 uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status)
1573 {
1574 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 8);
1575 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1576 struct mod_sub_param param = {
1577 .status = status,
1578 .elem_addr = elem_addr,
1579 .expect_sub = &sub_addr,
1580 .mod_id = mod_id,
1581 .cid = cid,
1582 };
1583 const struct bt_mesh_msg_rsp_ctx rsp = {
1584 .ack = &cli->ack_ctx,
1585 .op = OP_MOD_SUB_STATUS,
1586 .user_data = ¶m,
1587 .timeout = msg_timeout,
1588 };
1589
1590 bt_mesh_model_msg_init(&msg, op);
1591 net_buf_simple_add_le16(&msg, elem_addr);
1592
1593 if (sub_addr != BT_MESH_ADDR_UNASSIGNED) {
1594 net_buf_simple_add_le16(&msg, sub_addr);
1595 }
1596
1597 if (cid != CID_NVAL) {
1598 net_buf_simple_add_le16(&msg, cid);
1599 }
1600
1601 net_buf_simple_add_le16(&msg, mod_id);
1602
1603 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1604 }
1605
bt_mesh_cfg_cli_mod_sub_add(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint8_t * status)1606 int bt_mesh_cfg_cli_mod_sub_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1607 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1608 {
1609 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1610 return -EINVAL;
1611 }
1612
1613 return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1614 status);
1615 }
1616
bt_mesh_cfg_cli_mod_sub_add_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid,uint8_t * status)1617 int bt_mesh_cfg_cli_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1618 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1619 uint8_t *status)
1620 {
1621 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1622 cid == CID_NVAL) {
1623 return -EINVAL;
1624 }
1625
1626 return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1627 }
1628
bt_mesh_cfg_cli_mod_sub_del(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint8_t * status)1629 int bt_mesh_cfg_cli_mod_sub_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1630 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1631 {
1632 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1633 return -EINVAL;
1634 }
1635
1636 return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1637 status);
1638 }
1639
bt_mesh_cfg_cli_mod_sub_del_all(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint8_t * status)1640 int bt_mesh_cfg_cli_mod_sub_del_all(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1641 uint16_t mod_id, uint8_t *status)
1642 {
1643 return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, BT_MESH_ADDR_UNASSIGNED,
1644 mod_id, CID_NVAL, status);
1645 }
1646
bt_mesh_cfg_cli_mod_sub_del_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid,uint8_t * status)1647 int bt_mesh_cfg_cli_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1648 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1649 uint8_t *status)
1650 {
1651 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1652 cid == CID_NVAL) {
1653 return -EINVAL;
1654 }
1655
1656 return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1657 }
1658
bt_mesh_cfg_cli_mod_sub_del_all_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,uint8_t * status)1659 int bt_mesh_cfg_cli_mod_sub_del_all_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1660 uint16_t mod_id, uint16_t cid, uint8_t *status)
1661 {
1662 if (cid == CID_NVAL) {
1663 return -EINVAL;
1664 }
1665
1666 return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, BT_MESH_ADDR_UNASSIGNED,
1667 mod_id, cid, status);
1668 }
1669
bt_mesh_cfg_cli_mod_sub_overwrite(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint8_t * status)1670 int bt_mesh_cfg_cli_mod_sub_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1671 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1672 {
1673 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1674 return -EINVAL;
1675 }
1676
1677 return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1678 status);
1679 }
1680
bt_mesh_cfg_cli_mod_sub_overwrite_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t sub_addr,uint16_t mod_id,uint16_t cid,uint8_t * status)1681 int bt_mesh_cfg_cli_mod_sub_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1682 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1683 uint8_t *status)
1684 {
1685 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1686 cid == CID_NVAL) {
1687 return -EINVAL;
1688 }
1689
1690 return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, cid,
1691 status);
1692 }
1693
mod_sub_va(uint32_t op,uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid,uint16_t * virt_addr,uint8_t * status)1694 static int mod_sub_va(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1695 const uint8_t label[16], uint16_t mod_id, uint16_t cid, uint16_t *virt_addr,
1696 uint8_t *status)
1697 {
1698 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 22);
1699 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1700 struct mod_sub_param param = {
1701 .status = status,
1702 .elem_addr = elem_addr,
1703 .sub_addr = virt_addr,
1704 .mod_id = mod_id,
1705 .cid = cid,
1706 };
1707 const struct bt_mesh_msg_rsp_ctx rsp = {
1708 .ack = &cli->ack_ctx,
1709 .op = OP_MOD_SUB_STATUS,
1710 .user_data = ¶m,
1711 .timeout = msg_timeout,
1712 };
1713
1714 LOG_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", net_idx, addr, elem_addr,
1715 bt_hex(label, 16));
1716 LOG_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
1717
1718 bt_mesh_model_msg_init(&msg, op);
1719 net_buf_simple_add_le16(&msg, elem_addr);
1720 net_buf_simple_add_mem(&msg, label, 16);
1721
1722 if (cid != CID_NVAL) {
1723 net_buf_simple_add_le16(&msg, cid);
1724 }
1725
1726 net_buf_simple_add_le16(&msg, mod_id);
1727
1728 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !virt_addr ? NULL : &rsp);
1729 }
1730
bt_mesh_cfg_cli_mod_sub_va_add(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t * virt_addr,uint8_t * status)1731 int bt_mesh_cfg_cli_mod_sub_va_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1732 const uint8_t label[16], uint16_t mod_id, uint16_t *virt_addr,
1733 uint8_t *status)
1734 {
1735 return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, CID_NVAL,
1736 virt_addr, status);
1737 }
1738
bt_mesh_cfg_cli_mod_sub_va_add_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid,uint16_t * virt_addr,uint8_t * status)1739 int bt_mesh_cfg_cli_mod_sub_va_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1740 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1741 uint16_t *virt_addr, uint8_t *status)
1742 {
1743 if (cid == CID_NVAL) {
1744 return -EINVAL;
1745 }
1746
1747 return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, cid,
1748 virt_addr, status);
1749 }
1750
bt_mesh_cfg_cli_mod_sub_va_del(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t * virt_addr,uint8_t * status)1751 int bt_mesh_cfg_cli_mod_sub_va_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1752 const uint8_t label[16], uint16_t mod_id, uint16_t *virt_addr,
1753 uint8_t *status)
1754 {
1755 return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, CID_NVAL,
1756 virt_addr, status);
1757 }
1758
bt_mesh_cfg_cli_mod_sub_va_del_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid,uint16_t * virt_addr,uint8_t * status)1759 int bt_mesh_cfg_cli_mod_sub_va_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1760 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1761 uint16_t *virt_addr, uint8_t *status)
1762 {
1763 if (cid == CID_NVAL) {
1764 return -EINVAL;
1765 }
1766
1767 return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, cid,
1768 virt_addr, status);
1769 }
1770
bt_mesh_cfg_cli_mod_sub_va_overwrite(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t * virt_addr,uint8_t * status)1771 int bt_mesh_cfg_cli_mod_sub_va_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1772 const uint8_t label[16], uint16_t mod_id,
1773 uint16_t *virt_addr, uint8_t *status)
1774 {
1775 return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id,
1776 CID_NVAL, virt_addr, status);
1777 }
1778
bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,const uint8_t label[16],uint16_t mod_id,uint16_t cid,uint16_t * virt_addr,uint8_t * status)1779 int bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1780 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1781 uint16_t *virt_addr, uint8_t *status)
1782 {
1783 if (cid == CID_NVAL) {
1784 return -EINVAL;
1785 }
1786
1787 return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id, cid,
1788 virt_addr, status);
1789 }
1790
bt_mesh_cfg_cli_mod_sub_get(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint8_t * status,uint16_t * subs,size_t * sub_cnt)1791 int bt_mesh_cfg_cli_mod_sub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1792 uint16_t mod_id, uint8_t *status, uint16_t *subs, size_t *sub_cnt)
1793 {
1794 return mod_member_list_get(OP_MOD_SUB_GET, OP_MOD_SUB_LIST, net_idx, addr, elem_addr,
1795 mod_id, CID_NVAL, status, subs, sub_cnt);
1796 }
1797
bt_mesh_cfg_cli_mod_sub_get_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,uint8_t * status,uint16_t * subs,size_t * sub_cnt)1798 int bt_mesh_cfg_cli_mod_sub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1799 uint16_t mod_id, uint16_t cid, uint8_t *status, uint16_t *subs,
1800 size_t *sub_cnt)
1801 {
1802 if (cid == CID_NVAL) {
1803 return -EINVAL;
1804 }
1805
1806 return mod_member_list_get(OP_MOD_SUB_GET_VND, OP_MOD_SUB_LIST_VND, net_idx, addr,
1807 elem_addr, mod_id, cid, status, subs, sub_cnt);
1808 }
1809
mod_pub_get(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1810 static int mod_pub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
1811 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1812 {
1813 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6);
1814 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1815 struct mod_pub_param param = {
1816 .mod_id = mod_id,
1817 .cid = cid,
1818 .elem_addr = elem_addr,
1819 .status = status,
1820 .pub = pub,
1821 };
1822 const struct bt_mesh_msg_rsp_ctx rsp = {
1823 .ack = &cli->ack_ctx,
1824 .op = OP_MOD_PUB_STATUS,
1825 .user_data = ¶m,
1826 .timeout = msg_timeout,
1827 };
1828
1829 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET);
1830
1831 net_buf_simple_add_le16(&msg, elem_addr);
1832
1833 if (cid != CID_NVAL) {
1834 net_buf_simple_add_le16(&msg, cid);
1835 }
1836
1837 net_buf_simple_add_le16(&msg, mod_id);
1838
1839 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !pub ? NULL : &rsp);
1840 }
1841
bt_mesh_cfg_cli_mod_pub_get(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1842 int bt_mesh_cfg_cli_mod_pub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1843 uint16_t mod_id, struct bt_mesh_cfg_cli_mod_pub *pub,
1844 uint8_t *status)
1845 {
1846 return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1847 }
1848
bt_mesh_cfg_cli_mod_pub_get_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1849 int bt_mesh_cfg_cli_mod_pub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1850 uint16_t mod_id, uint16_t cid,
1851 struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1852 {
1853 if (cid == CID_NVAL) {
1854 return -EINVAL;
1855 }
1856
1857 return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1858 }
1859
mod_pub_set(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1860 static int mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
1861 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1862 {
1863 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13);
1864 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1865 struct mod_pub_param param = {
1866 .mod_id = mod_id,
1867 .cid = cid,
1868 .elem_addr = elem_addr,
1869 .status = status,
1870 .pub = pub,
1871 };
1872 const struct bt_mesh_msg_rsp_ctx rsp = {
1873 .ack = &cli->ack_ctx,
1874 .op = OP_MOD_PUB_STATUS,
1875 .user_data = ¶m,
1876 .timeout = msg_timeout,
1877 };
1878
1879 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_SET);
1880
1881 net_buf_simple_add_le16(&msg, elem_addr);
1882 net_buf_simple_add_le16(&msg, pub->addr);
1883 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
1884 net_buf_simple_add_u8(&msg, pub->ttl);
1885 net_buf_simple_add_u8(&msg, pub->period);
1886 net_buf_simple_add_u8(&msg, pub->transmit);
1887
1888 if (cid != CID_NVAL) {
1889 net_buf_simple_add_le16(&msg, cid);
1890 }
1891
1892 net_buf_simple_add_le16(&msg, mod_id);
1893
1894 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1895 }
1896
mod_pub_va_set(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1897 static int mod_pub_va_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
1898 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1899 {
1900 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27);
1901 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1902 struct mod_pub_param param = {
1903 .mod_id = mod_id,
1904 .cid = cid,
1905 .elem_addr = elem_addr,
1906 .status = status,
1907 .pub = pub,
1908 };
1909 const struct bt_mesh_msg_rsp_ctx rsp = {
1910 .ack = &cli->ack_ctx,
1911 .op = OP_MOD_PUB_STATUS,
1912 .user_data = ¶m,
1913 .timeout = msg_timeout,
1914 };
1915
1916 LOG_DBG("app_idx 0x%04x", pub->app_idx);
1917 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_VA_SET);
1918
1919 net_buf_simple_add_le16(&msg, elem_addr);
1920 net_buf_simple_add_mem(&msg, pub->uuid, 16);
1921 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
1922 net_buf_simple_add_u8(&msg, pub->ttl);
1923 net_buf_simple_add_u8(&msg, pub->period);
1924 net_buf_simple_add_u8(&msg, pub->transmit);
1925
1926 if (cid != CID_NVAL) {
1927 net_buf_simple_add_le16(&msg, cid);
1928 }
1929
1930 net_buf_simple_add_le16(&msg, mod_id);
1931
1932 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1933 }
1934
bt_mesh_cfg_cli_mod_pub_set(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1935 int bt_mesh_cfg_cli_mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1936 uint16_t mod_id, struct bt_mesh_cfg_cli_mod_pub *pub,
1937 uint8_t *status)
1938 {
1939 if (!pub) {
1940 return -EINVAL;
1941 }
1942
1943 if (pub->uuid) {
1944 return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1945 } else {
1946 return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1947 }
1948 }
1949
bt_mesh_cfg_cli_mod_pub_set_vnd(uint16_t net_idx,uint16_t addr,uint16_t elem_addr,uint16_t mod_id,uint16_t cid,struct bt_mesh_cfg_cli_mod_pub * pub,uint8_t * status)1950 int bt_mesh_cfg_cli_mod_pub_set_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1951 uint16_t mod_id, uint16_t cid,
1952 struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1953 {
1954 if (!pub) {
1955 return -EINVAL;
1956 }
1957
1958 if (cid == CID_NVAL) {
1959 return -EINVAL;
1960 }
1961
1962 if (pub->uuid) {
1963 return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1964 } else {
1965 return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1966 }
1967 }
1968
bt_mesh_cfg_cli_hb_sub_set(uint16_t net_idx,uint16_t addr,struct bt_mesh_cfg_cli_hb_sub * sub,uint8_t * status)1969 int bt_mesh_cfg_cli_hb_sub_set(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_sub *sub,
1970 uint8_t *status)
1971 {
1972 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5);
1973 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1974 struct hb_sub_param param = {
1975 .status = status,
1976 .sub = sub,
1977 };
1978
1979 if (!sub) {
1980 return -EINVAL;
1981 }
1982
1983 const struct bt_mesh_msg_rsp_ctx rsp = {
1984 .ack = &cli->ack_ctx,
1985 .op = OP_HEARTBEAT_SUB_STATUS,
1986 .user_data = ¶m,
1987 .timeout = msg_timeout,
1988 };
1989
1990 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_SET);
1991 net_buf_simple_add_le16(&msg, sub->src);
1992 net_buf_simple_add_le16(&msg, sub->dst);
1993 net_buf_simple_add_u8(&msg, sub->period);
1994
1995 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1996 }
1997
bt_mesh_cfg_cli_hb_sub_get(uint16_t net_idx,uint16_t addr,struct bt_mesh_cfg_cli_hb_sub * sub,uint8_t * status)1998 int bt_mesh_cfg_cli_hb_sub_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_sub *sub,
1999 uint8_t *status)
2000 {
2001 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_GET, 0);
2002 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2003 struct hb_sub_param param = {
2004 .status = status,
2005 .sub = sub,
2006 };
2007 const struct bt_mesh_msg_rsp_ctx rsp = {
2008 .ack = &cli->ack_ctx,
2009 .op = OP_HEARTBEAT_SUB_STATUS,
2010 .user_data = ¶m,
2011 .timeout = msg_timeout,
2012 };
2013
2014 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_GET);
2015
2016 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !sub ? NULL : &rsp);
2017 }
2018
bt_mesh_cfg_cli_hb_pub_set(uint16_t net_idx,uint16_t addr,const struct bt_mesh_cfg_cli_hb_pub * pub,uint8_t * status)2019 int bt_mesh_cfg_cli_hb_pub_set(uint16_t net_idx, uint16_t addr,
2020 const struct bt_mesh_cfg_cli_hb_pub *pub, uint8_t *status)
2021 {
2022 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9);
2023 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2024 struct hb_pub_param param = {
2025 .status = status,
2026 };
2027
2028 if (!pub) {
2029 return -EINVAL;
2030 }
2031
2032 const struct bt_mesh_msg_rsp_ctx rsp = {
2033 .ack = &cli->ack_ctx,
2034 .op = OP_HEARTBEAT_PUB_STATUS,
2035 .user_data = ¶m,
2036 .timeout = msg_timeout,
2037 };
2038
2039 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_SET);
2040 net_buf_simple_add_le16(&msg, pub->dst);
2041 net_buf_simple_add_u8(&msg, pub->count);
2042 net_buf_simple_add_u8(&msg, pub->period);
2043 net_buf_simple_add_u8(&msg, pub->ttl);
2044 net_buf_simple_add_le16(&msg, pub->feat);
2045 net_buf_simple_add_le16(&msg, pub->net_idx);
2046
2047 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
2048 }
2049
bt_mesh_cfg_cli_hb_pub_get(uint16_t net_idx,uint16_t addr,struct bt_mesh_cfg_cli_hb_pub * pub,uint8_t * status)2050 int bt_mesh_cfg_cli_hb_pub_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_pub *pub,
2051 uint8_t *status)
2052 {
2053 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_GET, 0);
2054 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2055 struct hb_pub_param param = {
2056 .status = status,
2057 .pub = pub,
2058 };
2059 const struct bt_mesh_msg_rsp_ctx rsp = {
2060 .ack = &cli->ack_ctx,
2061 .op = OP_HEARTBEAT_PUB_STATUS,
2062 .user_data = ¶m,
2063 .timeout = msg_timeout,
2064 };
2065
2066 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_GET);
2067
2068 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !pub ? NULL : &rsp);
2069 }
2070
bt_mesh_cfg_cli_node_identity_set(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t new_identity,uint8_t * status,uint8_t * identity)2071 int bt_mesh_cfg_cli_node_identity_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
2072 uint8_t new_identity, uint8_t *status, uint8_t *identity)
2073 {
2074 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_SET, 4);
2075 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2076 struct node_idt_param param = {
2077 .status = status,
2078 .net_idx = key_net_idx,
2079 .identity = identity,
2080 };
2081 const struct bt_mesh_msg_rsp_ctx rsp = {
2082 .ack = &cli->ack_ctx,
2083 .op = OP_NODE_IDENTITY_STATUS,
2084 .user_data = ¶m,
2085 .timeout = msg_timeout,
2086 };
2087
2088 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_SET);
2089 net_buf_simple_add_le16(&msg, key_net_idx);
2090 net_buf_simple_add_u8(&msg, new_identity);
2091
2092 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !identity ? NULL : &rsp);
2093 }
2094
bt_mesh_cfg_cli_node_identity_get(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t * status,uint8_t * identity)2095 int bt_mesh_cfg_cli_node_identity_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
2096 uint8_t *status, uint8_t *identity)
2097 {
2098 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_GET, 2);
2099 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2100 struct node_idt_param param = {
2101 .status = status,
2102 .net_idx = key_net_idx,
2103 .identity = identity,
2104 };
2105 const struct bt_mesh_msg_rsp_ctx rsp = {
2106 .ack = &cli->ack_ctx,
2107 .op = OP_NODE_IDENTITY_STATUS,
2108 .user_data = ¶m,
2109 .timeout = msg_timeout,
2110 };
2111
2112 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_GET);
2113 net_buf_simple_add_le16(&msg, key_net_idx);
2114
2115 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !identity ? NULL : &rsp);
2116 }
2117
bt_mesh_cfg_cli_lpn_timeout_get(uint16_t net_idx,uint16_t addr,uint16_t unicast_addr,int32_t * polltimeout)2118 int bt_mesh_cfg_cli_lpn_timeout_get(uint16_t net_idx, uint16_t addr, uint16_t unicast_addr,
2119 int32_t *polltimeout)
2120 {
2121 BT_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_GET, 2);
2122 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2123 struct lpn_timeout_param param = {
2124 .unicast_addr = unicast_addr,
2125 .polltimeout = polltimeout,
2126 };
2127 const struct bt_mesh_msg_rsp_ctx rsp = {
2128 .ack = &cli->ack_ctx,
2129 .op = OP_LPN_TIMEOUT_STATUS,
2130 .user_data = ¶m,
2131 .timeout = msg_timeout,
2132 };
2133
2134 bt_mesh_model_msg_init(&msg, OP_LPN_TIMEOUT_GET);
2135 net_buf_simple_add_le16(&msg, unicast_addr);
2136
2137 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !polltimeout ? NULL : &rsp);
2138 }
2139
bt_mesh_cfg_cli_timeout_get(void)2140 int32_t bt_mesh_cfg_cli_timeout_get(void)
2141 {
2142 return msg_timeout;
2143 }
2144
bt_mesh_cfg_cli_timeout_set(int32_t timeout)2145 void bt_mesh_cfg_cli_timeout_set(int32_t timeout)
2146 {
2147 msg_timeout = timeout;
2148 }
2149
bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 * page,struct net_buf_simple * buf)2150 int bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 *page,
2151 struct net_buf_simple *buf)
2152 {
2153 if (buf->len < 10) {
2154 return -EINVAL;
2155 }
2156
2157 page->cid = net_buf_simple_pull_le16(buf);
2158 page->pid = net_buf_simple_pull_le16(buf);
2159 page->vid = net_buf_simple_pull_le16(buf);
2160 page->crpl = net_buf_simple_pull_le16(buf);
2161 page->feat = net_buf_simple_pull_le16(buf);
2162 page->_buf = buf;
2163
2164 return 0;
2165 }
2166
bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 * page,struct bt_mesh_comp_p0_elem * elem)2167 struct bt_mesh_comp_p0_elem *bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 *page,
2168 struct bt_mesh_comp_p0_elem *elem)
2169 {
2170 size_t modlist_size;
2171
2172 if (page->_buf->len < 4) {
2173 return NULL;
2174 }
2175
2176 elem->loc = net_buf_simple_pull_le16(page->_buf);
2177 elem->nsig = net_buf_simple_pull_u8(page->_buf);
2178 elem->nvnd = net_buf_simple_pull_u8(page->_buf);
2179
2180 modlist_size = elem->nsig * 2 + elem->nvnd * 4;
2181
2182 if (page->_buf->len < modlist_size) {
2183 return NULL;
2184 }
2185
2186 elem->_buf = net_buf_simple_pull_mem(page->_buf, modlist_size);
2187
2188 return elem;
2189 }
2190
bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem * elem,int idx)2191 uint16_t bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem *elem, int idx)
2192 {
2193 CHECKIF(idx >= elem->nsig) {
2194 return 0xffff;
2195 }
2196
2197 return sys_get_le16(&elem->_buf[idx * 2]);
2198 }
2199
bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem * elem,int idx)2200 struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem *elem, int idx)
2201 {
2202 CHECKIF(idx >= elem->nvnd) {
2203 return (struct bt_mesh_mod_id_vnd){ 0xffff, 0xffff };
2204 }
2205
2206 size_t offset = elem->nsig * 2 + idx * 4;
2207 struct bt_mesh_mod_id_vnd mod = {
2208 .company = sys_get_le16(&elem->_buf[offset]),
2209 .id = sys_get_le16(&elem->_buf[offset + 2]),
2210 };
2211
2212 return mod;
2213 }
2214
bt_mesh_comp_p1_elem_pull(struct net_buf_simple * buf,struct bt_mesh_comp_p1_elem * elem)2215 struct bt_mesh_comp_p1_elem *bt_mesh_comp_p1_elem_pull(struct net_buf_simple *buf,
2216 struct bt_mesh_comp_p1_elem *elem)
2217 {
2218 if (buf->len < 6) {
2219 LOG_ERR("No more elements to pull or missing data");
2220 return NULL;
2221 }
2222 size_t elem_size = 0;
2223 uint8_t header, ext_item_cnt;
2224 bool fmt, cor_present;
2225 int i;
2226
2227 elem->nsig = net_buf_simple_pull_u8(buf);
2228 elem->nvnd = net_buf_simple_pull_u8(buf);
2229 for (i = 0; i < elem->nsig + elem->nvnd; i++) {
2230 header = buf->data[elem_size];
2231 cor_present = COR_PRESENT(header);
2232 fmt = FMT(header);
2233 ext_item_cnt = EXT_ITEM_CNT(header);
2234
2235 LOG_DBG("header %d, cor_present %d, fmt %d, ext_item_cnt %d",
2236 header, cor_present, fmt, ext_item_cnt);
2237 /* Size of element equals 1 octet (header) + optional 1 octet
2238 * (Correspondence ID, if applies) + size of Extended Model Items
2239 * (each 1 or 2 octet long, depending on format)
2240 */
2241 elem_size += (1 + cor_present) + (fmt + 1) * ext_item_cnt;
2242 }
2243
2244 net_buf_simple_init_with_data(elem->_buf,
2245 net_buf_simple_pull_mem(buf, elem_size),
2246 elem_size);
2247 return elem;
2248 }
2249
bt_mesh_comp_p1_item_pull(struct bt_mesh_comp_p1_elem * elem,struct bt_mesh_comp_p1_model_item * item)2250 struct bt_mesh_comp_p1_model_item *bt_mesh_comp_p1_item_pull(
2251 struct bt_mesh_comp_p1_elem *elem, struct bt_mesh_comp_p1_model_item *item)
2252 {
2253 if (elem->_buf->len < 1) {
2254 LOG_ERR("Empty buffer");
2255 return NULL;
2256 }
2257 LOG_DBG("N_SIG %d, N_VND %d, buf len=%d:0x%s",
2258 elem->nsig, elem->nvnd, elem->_buf->len,
2259 bt_hex(elem->_buf->data, elem->_buf->len));
2260
2261 size_t item_size;
2262 uint8_t header;
2263
2264 header = net_buf_simple_pull_u8(elem->_buf);
2265 item->cor_present = COR_PRESENT(header);
2266 item->format = FMT(header);
2267 item->ext_item_cnt = EXT_ITEM_CNT(header);
2268 item_size = item->ext_item_cnt * (item->format + 1);
2269 if (item->cor_present) {
2270 item->cor_id = net_buf_simple_pull_u8(elem->_buf);
2271 }
2272
2273 net_buf_simple_init_with_data(item->_buf,
2274 net_buf_simple_pull_mem(elem->_buf, item_size),
2275 item_size);
2276 return item;
2277 }
2278
2279
comp_p1_pull_item_short(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_item_short * ext_item)2280 static struct bt_mesh_comp_p1_item_short *comp_p1_pull_item_short(
2281 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_item_short *ext_item)
2282 {
2283 if (item->_buf->len < 1) {
2284 LOG_ERR("Empty buffer");
2285 return NULL;
2286 }
2287
2288 LOG_DBG("Correspondence ID %s, format %s, extended items count=%d",
2289 item->cor_present ? "present" : "not present",
2290 item->format ? "long" : "short",
2291 item->ext_item_cnt);
2292 if (item->format == 1 || item->_buf->len != 1) {
2293 return NULL;
2294 }
2295 uint8_t item_data = net_buf_simple_pull_u8(item->_buf);
2296
2297 ext_item->elem_offset = OFFSET(item_data);
2298 ext_item->mod_item_idx = IDX(item_data);
2299 return ext_item;
2300 }
2301
comp_p1_pull_item_long(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_item_long * ext_item)2302 static struct bt_mesh_comp_p1_item_long *comp_p1_pull_item_long(
2303 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_item_long *ext_item)
2304 {
2305 if (item->_buf->len < 2) {
2306 LOG_ERR("Missing data, buf len=%d", item->_buf->len);
2307 return NULL;
2308 }
2309
2310 LOG_DBG("Correspondence ID %s, format %s, extended items count=%d",
2311 item->cor_present ? "present" : "not present",
2312 item->format ? "long" : "short",
2313 item->ext_item_cnt);
2314 if (item->format == 0 || item->_buf->len != 2) {
2315 return NULL;
2316 }
2317
2318 ext_item->elem_offset = net_buf_simple_pull_u8(item->_buf);
2319 ext_item->mod_item_idx = net_buf_simple_pull_u8(item->_buf);
2320
2321 return ext_item;
2322 }
2323
bt_mesh_comp_p1_pull_ext_item(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_ext_item * ext_item)2324 struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item(
2325 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_ext_item *ext_item)
2326 {
2327 if (item->_buf->len < 1) {
2328 LOG_ERR("Empty buffer");
2329 return NULL;
2330 } else if (item->_buf->len < 2) {
2331 LOG_DBG("Item in short format");
2332 ext_item->type = SHORT;
2333 comp_p1_pull_item_short(item, &ext_item->short_item);
2334 } else {
2335 LOG_DBG("Item in long format");
2336 ext_item->type = LONG;
2337 comp_p1_pull_item_long(item, &ext_item->long_item);
2338 }
2339 return ext_item;
2340 }
2341