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