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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 **)&param)) {
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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 = &param,
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