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