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