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 .net_idx = key_net_idx,
1191 };
1192 const struct bt_mesh_msg_rsp_ctx rsp = {
1193 .ack = &cli->ack_ctx,
1194 .op = OP_KRP_STATUS,
1195 .user_data = ¶m,
1196 .timeout = msg_timeout,
1197 };
1198
1199 bt_mesh_model_msg_init(&msg, OP_KRP_GET);
1200 net_buf_simple_add_le16(&msg, key_net_idx);
1201
1202 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !phase ? NULL : &rsp);
1203 }
1204
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)1205 int bt_mesh_cfg_cli_krp_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1206 uint8_t transition, uint8_t *status, uint8_t *phase)
1207 {
1208 BT_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_SET, 3);
1209 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1210 struct krp_param param = {
1211 .status = status,
1212 .phase = phase,
1213 .net_idx = key_net_idx,
1214 };
1215 const struct bt_mesh_msg_rsp_ctx rsp = {
1216 .ack = &cli->ack_ctx,
1217 .op = OP_KRP_STATUS,
1218 .user_data = ¶m,
1219 .timeout = msg_timeout,
1220 };
1221
1222 bt_mesh_model_msg_init(&msg, OP_KRP_SET);
1223 net_buf_simple_add_le16(&msg, key_net_idx);
1224 net_buf_simple_add_u8(&msg, transition);
1225
1226 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !phase ? NULL : &rsp);
1227 }
1228
bt_mesh_cfg_cli_beacon_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1229 int bt_mesh_cfg_cli_beacon_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1230 {
1231 return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS, val, status);
1232 }
1233
bt_mesh_cfg_cli_ttl_get(uint16_t net_idx,uint16_t addr,uint8_t * ttl)1234 int bt_mesh_cfg_cli_ttl_get(uint16_t net_idx, uint16_t addr, uint8_t *ttl)
1235 {
1236 return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET, OP_DEFAULT_TTL_STATUS, ttl);
1237 }
1238
bt_mesh_cfg_cli_ttl_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * ttl)1239 int bt_mesh_cfg_cli_ttl_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *ttl)
1240 {
1241 return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET, OP_DEFAULT_TTL_STATUS, val, ttl);
1242 }
1243
bt_mesh_cfg_cli_friend_get(uint16_t net_idx,uint16_t addr,uint8_t * status)1244 int bt_mesh_cfg_cli_friend_get(uint16_t net_idx, uint16_t addr, uint8_t *status)
1245 {
1246 return get_state_u8(net_idx, addr, OP_FRIEND_GET, OP_FRIEND_STATUS, status);
1247 }
1248
bt_mesh_cfg_cli_friend_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1249 int bt_mesh_cfg_cli_friend_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1250 {
1251 return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS, val, status);
1252 }
1253
bt_mesh_cfg_cli_gatt_proxy_get(uint16_t net_idx,uint16_t addr,uint8_t * status)1254 int bt_mesh_cfg_cli_gatt_proxy_get(uint16_t net_idx, uint16_t addr, uint8_t *status)
1255 {
1256 return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET, OP_GATT_PROXY_STATUS, status);
1257 }
1258
bt_mesh_cfg_cli_gatt_proxy_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * status)1259 int bt_mesh_cfg_cli_gatt_proxy_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status)
1260 {
1261 return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET, OP_GATT_PROXY_STATUS, val, status);
1262 }
1263
bt_mesh_cfg_cli_net_transmit_set(uint16_t net_idx,uint16_t addr,uint8_t val,uint8_t * transmit)1264 int bt_mesh_cfg_cli_net_transmit_set(uint16_t net_idx, uint16_t addr, uint8_t val,
1265 uint8_t *transmit)
1266 {
1267 return set_state_u8(net_idx, addr, OP_NET_TRANSMIT_SET, OP_NET_TRANSMIT_STATUS, val,
1268 transmit);
1269 }
1270
bt_mesh_cfg_cli_net_transmit_get(uint16_t net_idx,uint16_t addr,uint8_t * transmit)1271 int bt_mesh_cfg_cli_net_transmit_get(uint16_t net_idx, uint16_t addr, uint8_t *transmit)
1272 {
1273 return get_state_u8(net_idx, addr, OP_NET_TRANSMIT_GET, OP_NET_TRANSMIT_STATUS, transmit);
1274 }
1275
bt_mesh_cfg_cli_relay_get(uint16_t net_idx,uint16_t addr,uint8_t * status,uint8_t * transmit)1276 int bt_mesh_cfg_cli_relay_get(uint16_t net_idx, uint16_t addr, uint8_t *status, uint8_t *transmit)
1277 {
1278 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_GET, 0);
1279 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1280 struct relay_param param = {
1281 .status = status,
1282 .transmit = transmit,
1283 };
1284 const struct bt_mesh_msg_rsp_ctx rsp = {
1285 .ack = &cli->ack_ctx,
1286 .op = OP_RELAY_STATUS,
1287 .user_data = ¶m,
1288 .timeout = msg_timeout,
1289 };
1290
1291 bt_mesh_model_msg_init(&msg, OP_RELAY_GET);
1292
1293 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !transmit ? NULL : &rsp);
1294 }
1295
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)1296 int bt_mesh_cfg_cli_relay_set(uint16_t net_idx, uint16_t addr, uint8_t new_relay,
1297 uint8_t new_transmit, uint8_t *status, uint8_t *transmit)
1298 {
1299 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2);
1300 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1301 struct relay_param param = {
1302 .status = status,
1303 .transmit = transmit,
1304 };
1305 const struct bt_mesh_msg_rsp_ctx rsp = {
1306 .ack = &cli->ack_ctx,
1307 .op = OP_RELAY_STATUS,
1308 .user_data = ¶m,
1309 .timeout = msg_timeout,
1310 };
1311
1312 bt_mesh_model_msg_init(&msg, OP_RELAY_SET);
1313 net_buf_simple_add_u8(&msg, new_relay);
1314 net_buf_simple_add_u8(&msg, new_transmit);
1315
1316 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !transmit ? NULL : &rsp);
1317 }
1318
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)1319 int bt_mesh_cfg_cli_net_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1320 const uint8_t net_key[16], uint8_t *status)
1321 {
1322 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18);
1323 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1324 struct net_key_param param = {
1325 .status = status,
1326 .net_idx = key_net_idx,
1327 };
1328 const struct bt_mesh_msg_rsp_ctx rsp = {
1329 .ack = &cli->ack_ctx,
1330 .op = OP_NET_KEY_STATUS,
1331 .user_data = ¶m,
1332 .timeout = msg_timeout,
1333 };
1334
1335 bt_mesh_model_msg_init(&msg, OP_NET_KEY_ADD);
1336 net_buf_simple_add_le16(&msg, key_net_idx);
1337 net_buf_simple_add_mem(&msg, net_key, 16);
1338
1339 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1340 }
1341
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)1342 int bt_mesh_cfg_cli_net_key_update(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1343 const uint8_t net_key[16], uint8_t *status)
1344 {
1345 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18);
1346 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1347 struct net_key_param param = {
1348 .status = status,
1349 .net_idx = key_net_idx,
1350 };
1351 const struct bt_mesh_msg_rsp_ctx rsp = {
1352 .ack = &cli->ack_ctx,
1353 .op = OP_NET_KEY_STATUS,
1354 .user_data = ¶m,
1355 .timeout = msg_timeout,
1356 };
1357
1358 bt_mesh_model_msg_init(&msg, OP_NET_KEY_UPDATE);
1359 net_buf_simple_add_le16(&msg, key_net_idx);
1360 net_buf_simple_add_mem(&msg, net_key, 16);
1361
1362 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1363 }
1364
bt_mesh_cfg_cli_net_key_get(uint16_t net_idx,uint16_t addr,uint16_t * keys,size_t * key_cnt)1365 int bt_mesh_cfg_cli_net_key_get(uint16_t net_idx, uint16_t addr, uint16_t *keys, size_t *key_cnt)
1366 {
1367 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_GET, 0);
1368 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1369 struct net_key_list_param param = {
1370 .keys = keys,
1371 .key_cnt = key_cnt,
1372 };
1373 const struct bt_mesh_msg_rsp_ctx rsp = {
1374 .ack = &cli->ack_ctx,
1375 .op = OP_NET_KEY_LIST,
1376 .user_data = ¶m,
1377 .timeout = msg_timeout,
1378 };
1379
1380 bt_mesh_model_msg_init(&msg, OP_NET_KEY_GET);
1381
1382 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !keys && !key_cnt ? NULL : &rsp);
1383 }
1384
bt_mesh_cfg_cli_net_key_del(uint16_t net_idx,uint16_t addr,uint16_t key_net_idx,uint8_t * status)1385 int bt_mesh_cfg_cli_net_key_del(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1386 uint8_t *status)
1387 {
1388 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_DEL, 2);
1389 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1390 struct net_key_param param = {
1391 .status = status,
1392 .net_idx = key_net_idx,
1393 };
1394 const struct bt_mesh_msg_rsp_ctx rsp = {
1395 .ack = &cli->ack_ctx,
1396 .op = OP_NET_KEY_STATUS,
1397 .user_data = ¶m,
1398 .timeout = msg_timeout,
1399 };
1400
1401 bt_mesh_model_msg_init(&msg, OP_NET_KEY_DEL);
1402 net_buf_simple_add_le16(&msg, key_net_idx);
1403
1404 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1405 }
1406
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)1407 int bt_mesh_cfg_cli_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1408 uint16_t key_app_idx, const uint8_t app_key[16], uint8_t *status)
1409 {
1410 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19);
1411 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1412 struct app_key_param param = {
1413 .status = status,
1414 .net_idx = key_net_idx,
1415 .app_idx = key_app_idx,
1416 };
1417 const struct bt_mesh_msg_rsp_ctx rsp = {
1418 .ack = &cli->ack_ctx,
1419 .op = OP_APP_KEY_STATUS,
1420 .user_data = ¶m,
1421 .timeout = msg_timeout,
1422 };
1423
1424 bt_mesh_model_msg_init(&msg, OP_APP_KEY_ADD);
1425 key_idx_pack_pair(&msg, key_net_idx, key_app_idx);
1426 net_buf_simple_add_mem(&msg, app_key, 16);
1427
1428 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1429 }
1430
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)1431 int bt_mesh_cfg_cli_app_key_update(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1432 uint16_t key_app_idx, const uint8_t app_key[16], uint8_t *status)
1433 {
1434 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19);
1435 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1436 struct app_key_param param = {
1437 .status = status,
1438 .net_idx = key_net_idx,
1439 .app_idx = key_app_idx,
1440 };
1441 const struct bt_mesh_msg_rsp_ctx rsp = {
1442 .ack = &cli->ack_ctx,
1443 .op = OP_APP_KEY_STATUS,
1444 .user_data = ¶m,
1445 .timeout = msg_timeout,
1446 };
1447
1448 bt_mesh_model_msg_init(&msg, OP_APP_KEY_UPDATE);
1449 key_idx_pack_pair(&msg, key_net_idx, key_app_idx);
1450 net_buf_simple_add_mem(&msg, app_key, 16);
1451
1452 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1453 }
1454
bt_mesh_cfg_cli_node_reset(uint16_t net_idx,uint16_t addr,bool * status)1455 int bt_mesh_cfg_cli_node_reset(uint16_t net_idx, uint16_t addr, bool *status)
1456 {
1457 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET, 0);
1458 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1459
1460 if (status) {
1461 *status = false;
1462 }
1463
1464 const struct bt_mesh_msg_rsp_ctx rsp = {
1465 .ack = &cli->ack_ctx,
1466 .op = OP_NODE_RESET_STATUS,
1467 .user_data = status,
1468 .timeout = msg_timeout,
1469 };
1470
1471 bt_mesh_model_msg_init(&msg, OP_NODE_RESET);
1472
1473 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1474 }
1475
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)1476 int bt_mesh_cfg_cli_app_key_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1477 uint8_t *status, uint16_t *keys, size_t *key_cnt)
1478 {
1479 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_GET, 2);
1480 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1481 struct app_key_list_param param = {
1482 .net_idx = key_net_idx,
1483 .status = status,
1484 .keys = keys,
1485 .key_cnt = key_cnt,
1486 };
1487 const struct bt_mesh_msg_rsp_ctx rsp = {
1488 .ack = &cli->ack_ctx,
1489 .op = OP_APP_KEY_LIST,
1490 .user_data = ¶m,
1491 .timeout = msg_timeout,
1492 };
1493
1494 bt_mesh_model_msg_init(&msg, OP_APP_KEY_GET);
1495 net_buf_simple_add_le16(&msg, key_net_idx);
1496
1497 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg,
1498 !status && (!keys || !key_cnt) ? NULL : &rsp);
1499 }
1500
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)1501 int bt_mesh_cfg_cli_app_key_del(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
1502 uint16_t key_app_idx, uint8_t *status)
1503 {
1504 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3);
1505 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1506 struct app_key_param param = {
1507 .status = status,
1508 .net_idx = key_net_idx,
1509 .app_idx = key_app_idx,
1510 };
1511 const struct bt_mesh_msg_rsp_ctx rsp = {
1512 .ack = &cli->ack_ctx,
1513 .op = OP_APP_KEY_STATUS,
1514 .user_data = ¶m,
1515 .timeout = msg_timeout,
1516 };
1517
1518 bt_mesh_model_msg_init(&msg, OP_APP_KEY_DEL);
1519 key_idx_pack_pair(&msg, key_net_idx, key_app_idx);
1520
1521 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1522 }
1523
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)1524 static int mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_app_idx,
1525 uint16_t mod_id, uint16_t cid, uint8_t *status)
1526 {
1527 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8);
1528 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1529 struct mod_app_param param = {
1530 .status = status,
1531 .elem_addr = elem_addr,
1532 .mod_app_idx = mod_app_idx,
1533 .mod_id = mod_id,
1534 .cid = cid,
1535 };
1536 const struct bt_mesh_msg_rsp_ctx rsp = {
1537 .ack = &cli->ack_ctx,
1538 .op = OP_MOD_APP_STATUS,
1539 .user_data = ¶m,
1540 .timeout = msg_timeout,
1541 };
1542
1543 bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND);
1544 net_buf_simple_add_le16(&msg, elem_addr);
1545 net_buf_simple_add_le16(&msg, mod_app_idx);
1546
1547 if (cid != CID_NVAL) {
1548 net_buf_simple_add_le16(&msg, cid);
1549 }
1550
1551 net_buf_simple_add_le16(&msg, mod_id);
1552
1553 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1554 }
1555
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)1556 int bt_mesh_cfg_cli_mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1557 uint16_t mod_app_idx, uint16_t mod_id, uint8_t *status)
1558 {
1559 return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1560 }
1561
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)1562 int bt_mesh_cfg_cli_mod_app_bind_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1563 uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid,
1564 uint8_t *status)
1565 {
1566 if (cid == CID_NVAL) {
1567 return -EINVAL;
1568 }
1569
1570 return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1571 }
1572
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)1573 static int mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_app_idx,
1574 uint16_t mod_id, uint16_t cid, uint8_t *status)
1575 {
1576 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8);
1577 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1578 struct mod_app_param param = {
1579 .status = status,
1580 .elem_addr = elem_addr,
1581 .mod_app_idx = mod_app_idx,
1582 .mod_id = mod_id,
1583 .cid = cid,
1584 };
1585 const struct bt_mesh_msg_rsp_ctx rsp = {
1586 .ack = &cli->ack_ctx,
1587 .op = OP_MOD_APP_STATUS,
1588 .user_data = ¶m,
1589 .timeout = msg_timeout,
1590 };
1591
1592 bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND);
1593 net_buf_simple_add_le16(&msg, elem_addr);
1594 net_buf_simple_add_le16(&msg, mod_app_idx);
1595
1596 if (cid != CID_NVAL) {
1597 net_buf_simple_add_le16(&msg, cid);
1598 }
1599
1600 net_buf_simple_add_le16(&msg, mod_id);
1601
1602 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1603 }
1604
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)1605 int bt_mesh_cfg_cli_mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1606 uint16_t mod_app_idx, uint16_t mod_id, uint8_t *status)
1607 {
1608 return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1609 }
1610
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)1611 int bt_mesh_cfg_cli_mod_app_unbind_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1612 uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid,
1613 uint8_t *status)
1614 {
1615 if (cid == CID_NVAL) {
1616 return -EINVAL;
1617 }
1618
1619 return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1620 }
1621
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)1622 static int mod_member_list_get(uint32_t op, uint32_t expect_op, uint16_t net_idx, uint16_t addr,
1623 uint16_t elem_addr, uint16_t mod_id, uint16_t cid, uint8_t *status,
1624 uint16_t *apps, size_t *app_cnt)
1625 {
1626 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6);
1627 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1628 struct mod_member_list_param param = {
1629 .status = status,
1630 .elem_addr = elem_addr,
1631 .mod_id = mod_id,
1632 .cid = cid,
1633 .members = apps,
1634 .member_cnt = app_cnt,
1635 };
1636 const struct bt_mesh_msg_rsp_ctx rsp = {
1637 .ack = &cli->ack_ctx,
1638 .op = expect_op,
1639 .user_data = ¶m,
1640 .timeout = msg_timeout,
1641 };
1642
1643 LOG_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x", net_idx, addr, elem_addr);
1644 LOG_DBG("mod_id 0x%04x cid 0x%04x op: %x", mod_id, cid, op);
1645
1646 bt_mesh_model_msg_init(&msg, op);
1647 net_buf_simple_add_le16(&msg, elem_addr);
1648
1649 if (cid != CID_NVAL) {
1650 net_buf_simple_add_le16(&msg, cid);
1651 }
1652
1653 net_buf_simple_add_le16(&msg, mod_id);
1654
1655 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg,
1656 !status && (!apps || !app_cnt) ? NULL : &rsp);
1657 }
1658
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)1659 int bt_mesh_cfg_cli_mod_app_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1660 uint16_t mod_id, uint8_t *status, uint16_t *apps, size_t *app_cnt)
1661 {
1662 return mod_member_list_get(OP_SIG_MOD_APP_GET, OP_SIG_MOD_APP_LIST, net_idx, addr,
1663 elem_addr, mod_id, CID_NVAL, status, apps, app_cnt);
1664 }
1665
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)1666 int bt_mesh_cfg_cli_mod_app_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1667 uint16_t mod_id, uint16_t cid, uint8_t *status, uint16_t *apps,
1668 size_t *app_cnt)
1669 {
1670 if (cid == CID_NVAL) {
1671 return -EINVAL;
1672 }
1673
1674 return mod_member_list_get(OP_VND_MOD_APP_GET, OP_VND_MOD_APP_LIST, net_idx, addr,
1675 elem_addr, mod_id, cid, status, apps, app_cnt);
1676 }
1677
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)1678 static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1679 uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status)
1680 {
1681 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 8);
1682 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1683 struct mod_sub_param param = {
1684 .status = status,
1685 .elem_addr = elem_addr,
1686 .expect_sub = &sub_addr,
1687 .mod_id = mod_id,
1688 .cid = cid,
1689 };
1690 const struct bt_mesh_msg_rsp_ctx rsp = {
1691 .ack = &cli->ack_ctx,
1692 .op = OP_MOD_SUB_STATUS,
1693 .user_data = ¶m,
1694 .timeout = msg_timeout,
1695 };
1696
1697 bt_mesh_model_msg_init(&msg, op);
1698 net_buf_simple_add_le16(&msg, elem_addr);
1699
1700 if (sub_addr != BT_MESH_ADDR_UNASSIGNED) {
1701 net_buf_simple_add_le16(&msg, sub_addr);
1702 }
1703
1704 if (cid != CID_NVAL) {
1705 net_buf_simple_add_le16(&msg, cid);
1706 }
1707
1708 net_buf_simple_add_le16(&msg, mod_id);
1709
1710 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
1711 }
1712
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)1713 int bt_mesh_cfg_cli_mod_sub_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1714 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1715 {
1716 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1717 return -EINVAL;
1718 }
1719
1720 return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1721 status);
1722 }
1723
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)1724 int bt_mesh_cfg_cli_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1725 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1726 uint8_t *status)
1727 {
1728 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1729 cid == CID_NVAL) {
1730 return -EINVAL;
1731 }
1732
1733 return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1734 }
1735
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)1736 int bt_mesh_cfg_cli_mod_sub_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1737 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1738 {
1739 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1740 return -EINVAL;
1741 }
1742
1743 return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1744 status);
1745 }
1746
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)1747 int bt_mesh_cfg_cli_mod_sub_del_all(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1748 uint16_t mod_id, uint8_t *status)
1749 {
1750 return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, BT_MESH_ADDR_UNASSIGNED,
1751 mod_id, CID_NVAL, status);
1752 }
1753
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)1754 int bt_mesh_cfg_cli_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1755 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1756 uint8_t *status)
1757 {
1758 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1759 cid == CID_NVAL) {
1760 return -EINVAL;
1761 }
1762
1763 return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1764 }
1765
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)1766 int bt_mesh_cfg_cli_mod_sub_del_all_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1767 uint16_t mod_id, uint16_t cid, uint8_t *status)
1768 {
1769 if (cid == CID_NVAL) {
1770 return -EINVAL;
1771 }
1772
1773 return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, BT_MESH_ADDR_UNASSIGNED,
1774 mod_id, cid, status);
1775 }
1776
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)1777 int bt_mesh_cfg_cli_mod_sub_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1778 uint16_t sub_addr, uint16_t mod_id, uint8_t *status)
1779 {
1780 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1781 return -EINVAL;
1782 }
1783
1784 return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL,
1785 status);
1786 }
1787
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)1788 int bt_mesh_cfg_cli_mod_sub_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1789 uint16_t sub_addr, uint16_t mod_id, uint16_t cid,
1790 uint8_t *status)
1791 {
1792 if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) ||
1793 cid == CID_NVAL) {
1794 return -EINVAL;
1795 }
1796
1797 return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, cid,
1798 status);
1799 }
1800
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)1801 static int mod_sub_va(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1802 const uint8_t label[16], uint16_t mod_id, uint16_t cid, uint16_t *virt_addr,
1803 uint8_t *status)
1804 {
1805 BT_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 22);
1806 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1807 struct mod_sub_param param = {
1808 .status = status,
1809 .elem_addr = elem_addr,
1810 .sub_addr = virt_addr,
1811 .mod_id = mod_id,
1812 .cid = cid,
1813 };
1814 const struct bt_mesh_msg_rsp_ctx rsp = {
1815 .ack = &cli->ack_ctx,
1816 .op = OP_MOD_SUB_STATUS,
1817 .user_data = ¶m,
1818 .timeout = msg_timeout,
1819 };
1820
1821 LOG_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", net_idx, addr, elem_addr,
1822 bt_hex(label, 16));
1823 LOG_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
1824
1825 bt_mesh_model_msg_init(&msg, op);
1826 net_buf_simple_add_le16(&msg, elem_addr);
1827 net_buf_simple_add_mem(&msg, label, 16);
1828
1829 if (cid != CID_NVAL) {
1830 net_buf_simple_add_le16(&msg, cid);
1831 }
1832
1833 net_buf_simple_add_le16(&msg, mod_id);
1834
1835 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !virt_addr ? NULL : &rsp);
1836 }
1837
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)1838 int bt_mesh_cfg_cli_mod_sub_va_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1839 const uint8_t label[16], uint16_t mod_id, uint16_t *virt_addr,
1840 uint8_t *status)
1841 {
1842 return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, CID_NVAL,
1843 virt_addr, status);
1844 }
1845
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)1846 int bt_mesh_cfg_cli_mod_sub_va_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1847 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1848 uint16_t *virt_addr, uint8_t *status)
1849 {
1850 if (cid == CID_NVAL) {
1851 return -EINVAL;
1852 }
1853
1854 return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, cid,
1855 virt_addr, status);
1856 }
1857
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)1858 int bt_mesh_cfg_cli_mod_sub_va_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1859 const uint8_t label[16], uint16_t mod_id, uint16_t *virt_addr,
1860 uint8_t *status)
1861 {
1862 return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, CID_NVAL,
1863 virt_addr, status);
1864 }
1865
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)1866 int bt_mesh_cfg_cli_mod_sub_va_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1867 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1868 uint16_t *virt_addr, uint8_t *status)
1869 {
1870 if (cid == CID_NVAL) {
1871 return -EINVAL;
1872 }
1873
1874 return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, cid,
1875 virt_addr, status);
1876 }
1877
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)1878 int bt_mesh_cfg_cli_mod_sub_va_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1879 const uint8_t label[16], uint16_t mod_id,
1880 uint16_t *virt_addr, uint8_t *status)
1881 {
1882 return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id,
1883 CID_NVAL, virt_addr, status);
1884 }
1885
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)1886 int bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1887 const uint8_t label[16], uint16_t mod_id, uint16_t cid,
1888 uint16_t *virt_addr, uint8_t *status)
1889 {
1890 if (cid == CID_NVAL) {
1891 return -EINVAL;
1892 }
1893
1894 return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id, cid,
1895 virt_addr, status);
1896 }
1897
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)1898 int bt_mesh_cfg_cli_mod_sub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1899 uint16_t mod_id, uint8_t *status, uint16_t *subs, size_t *sub_cnt)
1900 {
1901 return mod_member_list_get(OP_MOD_SUB_GET, OP_MOD_SUB_LIST, net_idx, addr, elem_addr,
1902 mod_id, CID_NVAL, status, subs, sub_cnt);
1903 }
1904
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)1905 int bt_mesh_cfg_cli_mod_sub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1906 uint16_t mod_id, uint16_t cid, uint8_t *status, uint16_t *subs,
1907 size_t *sub_cnt)
1908 {
1909 if (cid == CID_NVAL) {
1910 return -EINVAL;
1911 }
1912
1913 return mod_member_list_get(OP_MOD_SUB_GET_VND, OP_MOD_SUB_LIST_VND, net_idx, addr,
1914 elem_addr, mod_id, cid, status, subs, sub_cnt);
1915 }
1916
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)1917 static int mod_pub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
1918 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1919 {
1920 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6);
1921 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1922 struct mod_pub_param param = {
1923 .mod_id = mod_id,
1924 .cid = cid,
1925 .elem_addr = elem_addr,
1926 .status = status,
1927 .pub = pub,
1928 };
1929 const struct bt_mesh_msg_rsp_ctx rsp = {
1930 .ack = &cli->ack_ctx,
1931 .op = OP_MOD_PUB_STATUS,
1932 .user_data = ¶m,
1933 .timeout = msg_timeout,
1934 };
1935
1936 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET);
1937
1938 net_buf_simple_add_le16(&msg, elem_addr);
1939
1940 if (cid != CID_NVAL) {
1941 net_buf_simple_add_le16(&msg, cid);
1942 }
1943
1944 net_buf_simple_add_le16(&msg, mod_id);
1945
1946 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !pub ? NULL : &rsp);
1947 }
1948
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)1949 int bt_mesh_cfg_cli_mod_pub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1950 uint16_t mod_id, struct bt_mesh_cfg_cli_mod_pub *pub,
1951 uint8_t *status)
1952 {
1953 return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1954 }
1955
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)1956 int bt_mesh_cfg_cli_mod_pub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
1957 uint16_t mod_id, uint16_t cid,
1958 struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1959 {
1960 if (cid == CID_NVAL) {
1961 return -EINVAL;
1962 }
1963
1964 return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1965 }
1966
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)1967 static int mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
1968 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
1969 {
1970 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13);
1971 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
1972 struct mod_pub_param param = {
1973 .mod_id = mod_id,
1974 .cid = cid,
1975 .elem_addr = elem_addr,
1976 .status = status,
1977 .pub = pub,
1978 };
1979 const struct bt_mesh_msg_rsp_ctx rsp = {
1980 .ack = &cli->ack_ctx,
1981 .op = OP_MOD_PUB_STATUS,
1982 .user_data = ¶m,
1983 .timeout = msg_timeout,
1984 };
1985
1986 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_SET);
1987
1988 net_buf_simple_add_le16(&msg, elem_addr);
1989 net_buf_simple_add_le16(&msg, pub->addr);
1990 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
1991 net_buf_simple_add_u8(&msg, pub->ttl);
1992 net_buf_simple_add_u8(&msg, pub->period);
1993 net_buf_simple_add_u8(&msg, pub->transmit);
1994
1995 if (cid != CID_NVAL) {
1996 net_buf_simple_add_le16(&msg, cid);
1997 }
1998
1999 net_buf_simple_add_le16(&msg, mod_id);
2000
2001 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
2002 }
2003
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)2004 static int mod_pub_va_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id,
2005 uint16_t cid, struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
2006 {
2007 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27);
2008 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2009 struct mod_pub_param param = {
2010 .mod_id = mod_id,
2011 .cid = cid,
2012 .elem_addr = elem_addr,
2013 .status = status,
2014 .pub = pub,
2015 };
2016 const struct bt_mesh_msg_rsp_ctx rsp = {
2017 .ack = &cli->ack_ctx,
2018 .op = OP_MOD_PUB_STATUS,
2019 .user_data = ¶m,
2020 .timeout = msg_timeout,
2021 };
2022
2023 LOG_DBG("app_idx 0x%04x", pub->app_idx);
2024 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_VA_SET);
2025
2026 net_buf_simple_add_le16(&msg, elem_addr);
2027 net_buf_simple_add_mem(&msg, pub->uuid, 16);
2028 net_buf_simple_add_le16(&msg, (pub->app_idx | (pub->cred_flag << 12)));
2029 net_buf_simple_add_u8(&msg, pub->ttl);
2030 net_buf_simple_add_u8(&msg, pub->period);
2031 net_buf_simple_add_u8(&msg, pub->transmit);
2032
2033 if (cid != CID_NVAL) {
2034 net_buf_simple_add_le16(&msg, cid);
2035 }
2036
2037 net_buf_simple_add_le16(&msg, mod_id);
2038
2039 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
2040 }
2041
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)2042 int bt_mesh_cfg_cli_mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
2043 uint16_t mod_id, struct bt_mesh_cfg_cli_mod_pub *pub,
2044 uint8_t *status)
2045 {
2046 if (!pub) {
2047 return -EINVAL;
2048 }
2049
2050 if (pub->uuid) {
2051 return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
2052 } else {
2053 return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
2054 }
2055 }
2056
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)2057 int bt_mesh_cfg_cli_mod_pub_set_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
2058 uint16_t mod_id, uint16_t cid,
2059 struct bt_mesh_cfg_cli_mod_pub *pub, uint8_t *status)
2060 {
2061 if (!pub) {
2062 return -EINVAL;
2063 }
2064
2065 if (cid == CID_NVAL) {
2066 return -EINVAL;
2067 }
2068
2069 if (pub->uuid) {
2070 return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
2071 } else {
2072 return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
2073 }
2074 }
2075
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)2076 int bt_mesh_cfg_cli_hb_sub_set(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_sub *sub,
2077 uint8_t *status)
2078 {
2079 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5);
2080 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2081 struct hb_sub_param param = {
2082 .status = status,
2083 .sub = sub,
2084 };
2085
2086 if (!sub) {
2087 return -EINVAL;
2088 }
2089
2090 const struct bt_mesh_msg_rsp_ctx rsp = {
2091 .ack = &cli->ack_ctx,
2092 .op = OP_HEARTBEAT_SUB_STATUS,
2093 .user_data = ¶m,
2094 .timeout = msg_timeout,
2095 };
2096
2097 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_SET);
2098 net_buf_simple_add_le16(&msg, sub->src);
2099 net_buf_simple_add_le16(&msg, sub->dst);
2100 net_buf_simple_add_u8(&msg, sub->period);
2101
2102 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
2103 }
2104
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)2105 int bt_mesh_cfg_cli_hb_sub_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_sub *sub,
2106 uint8_t *status)
2107 {
2108 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_GET, 0);
2109 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2110 struct hb_sub_param param = {
2111 .status = status,
2112 .sub = sub,
2113 };
2114 const struct bt_mesh_msg_rsp_ctx rsp = {
2115 .ack = &cli->ack_ctx,
2116 .op = OP_HEARTBEAT_SUB_STATUS,
2117 .user_data = ¶m,
2118 .timeout = msg_timeout,
2119 };
2120
2121 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_GET);
2122
2123 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !sub ? NULL : &rsp);
2124 }
2125
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)2126 int bt_mesh_cfg_cli_hb_pub_set(uint16_t net_idx, uint16_t addr,
2127 const struct bt_mesh_cfg_cli_hb_pub *pub, uint8_t *status)
2128 {
2129 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9);
2130 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2131 struct hb_pub_param param = {
2132 .status = status,
2133 };
2134
2135 if (!pub) {
2136 return -EINVAL;
2137 }
2138
2139 const struct bt_mesh_msg_rsp_ctx rsp = {
2140 .ack = &cli->ack_ctx,
2141 .op = OP_HEARTBEAT_PUB_STATUS,
2142 .user_data = ¶m,
2143 .timeout = msg_timeout,
2144 };
2145
2146 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_SET);
2147 net_buf_simple_add_le16(&msg, pub->dst);
2148 net_buf_simple_add_u8(&msg, pub->count);
2149 net_buf_simple_add_u8(&msg, pub->period);
2150 net_buf_simple_add_u8(&msg, pub->ttl);
2151 net_buf_simple_add_le16(&msg, pub->feat);
2152 net_buf_simple_add_le16(&msg, pub->net_idx);
2153
2154 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status ? NULL : &rsp);
2155 }
2156
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)2157 int bt_mesh_cfg_cli_hb_pub_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_cli_hb_pub *pub,
2158 uint8_t *status)
2159 {
2160 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_GET, 0);
2161 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2162 struct hb_pub_param param = {
2163 .status = status,
2164 .pub = pub,
2165 };
2166 const struct bt_mesh_msg_rsp_ctx rsp = {
2167 .ack = &cli->ack_ctx,
2168 .op = OP_HEARTBEAT_PUB_STATUS,
2169 .user_data = ¶m,
2170 .timeout = msg_timeout,
2171 };
2172
2173 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_GET);
2174
2175 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !pub ? NULL : &rsp);
2176 }
2177
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)2178 int bt_mesh_cfg_cli_node_identity_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
2179 uint8_t new_identity, uint8_t *status, uint8_t *identity)
2180 {
2181 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_SET, 4);
2182 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2183 struct node_idt_param param = {
2184 .status = status,
2185 .net_idx = key_net_idx,
2186 .identity = identity,
2187 };
2188 const struct bt_mesh_msg_rsp_ctx rsp = {
2189 .ack = &cli->ack_ctx,
2190 .op = OP_NODE_IDENTITY_STATUS,
2191 .user_data = ¶m,
2192 .timeout = msg_timeout,
2193 };
2194
2195 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_SET);
2196 net_buf_simple_add_le16(&msg, key_net_idx);
2197 net_buf_simple_add_u8(&msg, new_identity);
2198
2199 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !identity ? NULL : &rsp);
2200 }
2201
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)2202 int bt_mesh_cfg_cli_node_identity_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
2203 uint8_t *status, uint8_t *identity)
2204 {
2205 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_GET, 2);
2206 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2207 struct node_idt_param param = {
2208 .status = status,
2209 .net_idx = key_net_idx,
2210 .identity = identity,
2211 };
2212 const struct bt_mesh_msg_rsp_ctx rsp = {
2213 .ack = &cli->ack_ctx,
2214 .op = OP_NODE_IDENTITY_STATUS,
2215 .user_data = ¶m,
2216 .timeout = msg_timeout,
2217 };
2218
2219 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_GET);
2220 net_buf_simple_add_le16(&msg, key_net_idx);
2221
2222 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !status && !identity ? NULL : &rsp);
2223 }
2224
bt_mesh_cfg_cli_lpn_timeout_get(uint16_t net_idx,uint16_t addr,uint16_t unicast_addr,int32_t * polltimeout)2225 int bt_mesh_cfg_cli_lpn_timeout_get(uint16_t net_idx, uint16_t addr, uint16_t unicast_addr,
2226 int32_t *polltimeout)
2227 {
2228 BT_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_GET, 2);
2229 struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
2230 struct lpn_timeout_param param = {
2231 .unicast_addr = unicast_addr,
2232 .polltimeout = polltimeout,
2233 };
2234 const struct bt_mesh_msg_rsp_ctx rsp = {
2235 .ack = &cli->ack_ctx,
2236 .op = OP_LPN_TIMEOUT_STATUS,
2237 .user_data = ¶m,
2238 .timeout = msg_timeout,
2239 };
2240
2241 bt_mesh_model_msg_init(&msg, OP_LPN_TIMEOUT_GET);
2242 net_buf_simple_add_le16(&msg, unicast_addr);
2243
2244 return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, !polltimeout ? NULL : &rsp);
2245 }
2246
bt_mesh_cfg_cli_timeout_get(void)2247 int32_t bt_mesh_cfg_cli_timeout_get(void)
2248 {
2249 return msg_timeout;
2250 }
2251
bt_mesh_cfg_cli_timeout_set(int32_t timeout)2252 void bt_mesh_cfg_cli_timeout_set(int32_t timeout)
2253 {
2254 msg_timeout = timeout;
2255 }
2256
bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 * page,struct net_buf_simple * buf)2257 int bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 *page,
2258 struct net_buf_simple *buf)
2259 {
2260 if (buf->len < 10) {
2261 return -EINVAL;
2262 }
2263
2264 page->cid = net_buf_simple_pull_le16(buf);
2265 page->pid = net_buf_simple_pull_le16(buf);
2266 page->vid = net_buf_simple_pull_le16(buf);
2267 page->crpl = net_buf_simple_pull_le16(buf);
2268 page->feat = net_buf_simple_pull_le16(buf);
2269 page->_buf = buf;
2270
2271 return 0;
2272 }
2273
bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 * page,struct bt_mesh_comp_p0_elem * elem)2274 struct bt_mesh_comp_p0_elem *bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 *page,
2275 struct bt_mesh_comp_p0_elem *elem)
2276 {
2277 size_t modlist_size;
2278
2279 if (page->_buf->len < 4) {
2280 LOG_DBG("Buffer is too short");
2281 return NULL;
2282 }
2283
2284 elem->loc = net_buf_simple_pull_le16(page->_buf);
2285 elem->nsig = net_buf_simple_pull_u8(page->_buf);
2286 elem->nvnd = net_buf_simple_pull_u8(page->_buf);
2287
2288 modlist_size = elem->nsig * 2 + elem->nvnd * 4;
2289
2290 if (page->_buf->len < modlist_size) {
2291 LOG_DBG("Buffer is shorter than number of claimed models");
2292 return NULL;
2293 }
2294
2295 elem->_buf = net_buf_simple_pull_mem(page->_buf, modlist_size);
2296
2297 return elem;
2298 }
2299
bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem * elem,int idx)2300 uint16_t bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem *elem, int idx)
2301 {
2302 CHECKIF(idx >= elem->nsig) {
2303 return 0xffff;
2304 }
2305
2306 return sys_get_le16(&elem->_buf[idx * 2]);
2307 }
2308
bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem * elem,int idx)2309 struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem *elem, int idx)
2310 {
2311 CHECKIF(idx >= elem->nvnd) {
2312 return (struct bt_mesh_mod_id_vnd){ 0xffff, 0xffff };
2313 }
2314
2315 size_t offset = elem->nsig * 2 + idx * 4;
2316 struct bt_mesh_mod_id_vnd mod = {
2317 .company = sys_get_le16(&elem->_buf[offset]),
2318 .id = sys_get_le16(&elem->_buf[offset + 2]),
2319 };
2320
2321 return mod;
2322 }
2323
bt_mesh_comp_p1_elem_pull(struct net_buf_simple * buf,struct bt_mesh_comp_p1_elem * elem)2324 struct bt_mesh_comp_p1_elem *bt_mesh_comp_p1_elem_pull(struct net_buf_simple *buf,
2325 struct bt_mesh_comp_p1_elem *elem)
2326 {
2327 if (buf->len < 4) {
2328 LOG_DBG("Buffer is too short");
2329 return NULL;
2330 }
2331 size_t elem_size = 0;
2332 uint8_t header, ext_item_cnt;
2333 bool fmt, cor_present;
2334 int i;
2335
2336 elem->nsig = net_buf_simple_pull_u8(buf);
2337 elem->nvnd = net_buf_simple_pull_u8(buf);
2338 for (i = 0; i < elem->nsig + elem->nvnd; i++) {
2339 if (buf->len < elem_size + 1) {
2340 LOG_DBG("Buffer is shorter than number of claimed models");
2341 return NULL;
2342 }
2343
2344 header = buf->data[elem_size];
2345 cor_present = COR_PRESENT(header);
2346 fmt = FMT(header);
2347 ext_item_cnt = EXT_ITEM_CNT(header);
2348
2349 LOG_DBG("header %d, cor_present %d, fmt %d, ext_item_cnt %d",
2350 header, cor_present, fmt, ext_item_cnt);
2351 /* Size of element equals 1 octet (header) + optional 1 octet
2352 * (Correspondence ID, if applies) + size of Extended Model Items
2353 * (each 1 or 2 octet long, depending on format)
2354 */
2355 elem_size += (1 + cor_present) + (fmt + 1) * ext_item_cnt;
2356 }
2357
2358 if (buf->len < elem_size) {
2359 LOG_DBG("No more elements to pull or missing data");
2360 return NULL;
2361 }
2362
2363 net_buf_simple_init_with_data(elem->_buf,
2364 net_buf_simple_pull_mem(buf, elem_size),
2365 elem_size);
2366 return elem;
2367 }
2368
bt_mesh_comp_p1_item_pull(struct bt_mesh_comp_p1_elem * elem,struct bt_mesh_comp_p1_model_item * item)2369 struct bt_mesh_comp_p1_model_item *bt_mesh_comp_p1_item_pull(
2370 struct bt_mesh_comp_p1_elem *elem, struct bt_mesh_comp_p1_model_item *item)
2371 {
2372 if (elem->_buf->len < 1) {
2373 LOG_ERR("Empty buffer");
2374 return NULL;
2375 }
2376 LOG_DBG("N_SIG %d, N_VND %d, buf len=%d:0x%s",
2377 elem->nsig, elem->nvnd, elem->_buf->len,
2378 bt_hex(elem->_buf->data, elem->_buf->len));
2379
2380 size_t item_size;
2381 uint8_t header;
2382
2383 header = net_buf_simple_pull_u8(elem->_buf);
2384 item->cor_present = COR_PRESENT(header);
2385 item->format = FMT(header);
2386 item->ext_item_cnt = EXT_ITEM_CNT(header);
2387 item_size = item->ext_item_cnt * (item->format + 1);
2388 if (item->cor_present) {
2389 if (elem->_buf->len < 1) {
2390 LOG_DBG("Coresponding_Present field is claimed but not present");
2391 return NULL;
2392 }
2393
2394 item->cor_id = net_buf_simple_pull_u8(elem->_buf);
2395 }
2396
2397 if (elem->_buf->len < item_size) {
2398 LOG_DBG("No more elements to pull or missing data");
2399 return NULL;
2400 }
2401
2402 net_buf_simple_init_with_data(item->_buf,
2403 net_buf_simple_pull_mem(elem->_buf, item_size),
2404 item_size);
2405 return item;
2406 }
2407
2408
comp_p1_pull_item_short(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_item_short * ext_item)2409 static struct bt_mesh_comp_p1_item_short *comp_p1_pull_item_short(
2410 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_item_short *ext_item)
2411 {
2412 if (item->_buf->len < 1) {
2413 LOG_ERR("Empty buffer");
2414 return NULL;
2415 }
2416
2417 LOG_DBG("Correspondence ID %s, format %s, extended items count=%d",
2418 item->cor_present ? "present" : "not present",
2419 item->format ? "long" : "short",
2420 item->ext_item_cnt);
2421 if (item->format == 1 || item->_buf->len != 1) {
2422 return NULL;
2423 }
2424 uint8_t item_data = net_buf_simple_pull_u8(item->_buf);
2425
2426 ext_item->elem_offset = OFFSET(item_data);
2427 ext_item->mod_item_idx = IDX(item_data);
2428 return ext_item;
2429 }
2430
comp_p1_pull_item_long(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_item_long * ext_item)2431 static struct bt_mesh_comp_p1_item_long *comp_p1_pull_item_long(
2432 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_item_long *ext_item)
2433 {
2434 if (item->_buf->len < 2) {
2435 LOG_ERR("Missing data, buf len=%d", item->_buf->len);
2436 return NULL;
2437 }
2438
2439 LOG_DBG("Correspondence ID %s, format %s, extended items count=%d",
2440 item->cor_present ? "present" : "not present",
2441 item->format ? "long" : "short",
2442 item->ext_item_cnt);
2443 if (item->format == 0 || item->_buf->len != 2) {
2444 return NULL;
2445 }
2446
2447 ext_item->elem_offset = net_buf_simple_pull_u8(item->_buf);
2448 ext_item->mod_item_idx = net_buf_simple_pull_u8(item->_buf);
2449
2450 return ext_item;
2451 }
2452
bt_mesh_comp_p1_pull_ext_item(struct bt_mesh_comp_p1_model_item * item,struct bt_mesh_comp_p1_ext_item * ext_item)2453 struct bt_mesh_comp_p1_ext_item *bt_mesh_comp_p1_pull_ext_item(
2454 struct bt_mesh_comp_p1_model_item *item, struct bt_mesh_comp_p1_ext_item *ext_item)
2455 {
2456 if (item->_buf->len < 1) {
2457 LOG_ERR("Empty buffer");
2458 return NULL;
2459 } else if (item->_buf->len < 2) {
2460 LOG_DBG("Item in short format");
2461 ext_item->type = SHORT;
2462 comp_p1_pull_item_short(item, &ext_item->short_item);
2463 } else {
2464 LOG_DBG("Item in long format");
2465 ext_item->type = LONG;
2466 comp_p1_pull_item_long(item, &ext_item->long_item);
2467 }
2468 return ext_item;
2469 }
2470
bt_mesh_comp_p2_record_pull(struct net_buf_simple * buf,struct bt_mesh_comp_p2_record * record)2471 struct bt_mesh_comp_p2_record *bt_mesh_comp_p2_record_pull(struct net_buf_simple *buf,
2472 struct bt_mesh_comp_p2_record *record)
2473 {
2474 if (buf->len < 8) {
2475 LOG_DBG("No more elements to pull or missing data");
2476 return NULL;
2477 }
2478
2479 uint8_t elem_offset_cnt;
2480 uint16_t data_len;
2481
2482 record->id = net_buf_simple_pull_le16(buf);
2483 record->version.x = net_buf_simple_pull_u8(buf);
2484 record->version.y = net_buf_simple_pull_u8(buf);
2485 record->version.z = net_buf_simple_pull_u8(buf);
2486 elem_offset_cnt = net_buf_simple_pull_u8(buf);
2487 if (buf->len < elem_offset_cnt + 2) {
2488 LOG_WRN("Invalid composition data offset count");
2489 return NULL;
2490 }
2491
2492 net_buf_simple_init_with_data(record->elem_buf,
2493 net_buf_simple_pull_mem(buf, elem_offset_cnt),
2494 elem_offset_cnt);
2495 data_len = net_buf_simple_pull_le16(buf);
2496 if (buf->len < data_len) {
2497 LOG_WRN("Invalid composition data additional data length");
2498 return NULL;
2499 }
2500
2501 net_buf_simple_init_with_data(record->data_buf,
2502 net_buf_simple_pull_mem(buf, data_len), data_len);
2503 return record;
2504 }
2505