1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <zephyr/sys/util.h>
11 #include <zephyr/sys/byteorder.h>
12 
13 #include <zephyr/net/buf.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/mesh.h>
16 
17 #include "common/bt_str.h"
18 
19 #include "host/testing.h"
20 
21 #include "mesh.h"
22 #include "net.h"
23 #include "lpn.h"
24 #include "transport.h"
25 #include "access.h"
26 #include "foundation.h"
27 #include "op_agg.h"
28 #include "settings.h"
29 #include "va.h"
30 #include "delayable_msg.h"
31 
32 #define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL
33 #include <zephyr/logging/log.h>
34 LOG_MODULE_REGISTER(bt_mesh_access);
35 
36 /* 20 - 50ms */
37 #define RANDOM_DELAY_SHORT 30
38 /* 20 - 500ms */
39 #define RANDOM_DELAY_LONG 480
40 
41 /* Model publication information for persistent storage. */
42 struct mod_pub_val {
43 	struct {
44 		uint16_t addr;
45 		uint16_t key;
46 		uint8_t  ttl;
47 		uint8_t  retransmit;
48 		uint8_t  period;
49 		uint8_t  period_div:4,
50 			 cred:1;
51 	} base;
52 	uint16_t uuidx;
53 };
54 
55 struct comp_foreach_model_arg {
56 	struct net_buf_simple *buf;
57 	size_t *offset;
58 };
59 
60 static const struct bt_mesh_comp *dev_comp;
61 static const struct bt_mesh_comp2 *dev_comp2;
62 static uint16_t dev_primary_addr;
63 static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
64 
65 /* Structure containing information about model extension */
66 struct mod_relation {
67 	/** Element that composition data base model belongs to. */
68 	uint8_t elem_base;
69 	/** Index of composition data base model in its element. */
70 	uint8_t idx_base;
71 	/** Element that composition data extension model belongs to. */
72 	uint8_t elem_ext;
73 	/** Index of composition data extension model in its element. */
74 	uint8_t idx_ext;
75 	/** Type of relation; value in range 0x00-0xFE marks correspondence
76 	 * and equals to Correspondence ID; value 0xFF marks extension
77 	 */
78 	uint8_t type;
79 };
80 
81 #ifdef CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE
82 #define MOD_REL_LIST_SIZE CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE
83 #else
84 #define MOD_REL_LIST_SIZE 0
85 #endif
86 
87 /* List of all existing extension relations between models */
88 static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE];
89 
90 #define MOD_REL_LIST_FOR_EACH(idx) \
91 	for ((idx) = 0; \
92 		(idx) < ARRAY_SIZE(mod_rel_list) && \
93 		!(mod_rel_list[(idx)].elem_base == 0 && \
94 		  mod_rel_list[(idx)].idx_base == 0 && \
95 		  mod_rel_list[(idx)].elem_ext == 0 && \
96 		  mod_rel_list[(idx)].idx_ext == 0); \
97 		 (idx)++)
98 
99 #define IS_MOD_BASE(mod, idx, offset) \
100 	(mod_rel_list[(idx)].elem_base == mod->rt->elem_idx && \
101 	 mod_rel_list[(idx)].idx_base == mod->rt->mod_idx + (offset))
102 
103 #define IS_MOD_EXTENSION(mod, idx, offset) \
104 	 (mod_rel_list[(idx)].elem_ext == mod->rt->elem_idx && \
105 	  mod_rel_list[(idx)].idx_ext == mod->rt->mod_idx + (offset))
106 
107 #define RELATION_TYPE_EXT 0xFF
108 
109 static const struct {
110 	uint8_t *path;
111 	uint8_t page;
112 } comp_data_pages[] = {
113 	{ "bt/mesh/cmp/0", 0, },
114 #if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)
115 	{ "bt/mesh/cmp/1", 1, },
116 #endif
117 #if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)
118 	{ "bt/mesh/cmp/2", 2, },
119 #endif
120 };
121 
bt_mesh_model_foreach(void (* func)(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data),void * user_data)122 void bt_mesh_model_foreach(void (*func)(const struct bt_mesh_model *mod,
123 					const struct bt_mesh_elem *elem,
124 					bool vnd, bool primary,
125 					void *user_data),
126 			   void *user_data)
127 {
128 	int i, j;
129 
130 	for (i = 0; i < dev_comp->elem_count; i++) {
131 		const struct bt_mesh_elem *elem = &dev_comp->elem[i];
132 
133 		for (j = 0; j < elem->model_count; j++) {
134 			const struct bt_mesh_model *model = &elem->models[j];
135 
136 			func(model, elem, false, i == 0, user_data);
137 		}
138 
139 		for (j = 0; j < elem->vnd_model_count; j++) {
140 			const struct bt_mesh_model *model = &elem->vnd_models[j];
141 
142 			func(model, elem, true, i == 0, user_data);
143 		}
144 	}
145 }
146 
bt_mesh_comp_elem_size(const struct bt_mesh_elem * elem)147 static size_t bt_mesh_comp_elem_size(const struct bt_mesh_elem *elem)
148 {
149 	return (4 + (elem->model_count * 2U) + (elem->vnd_model_count * 4U));
150 }
151 
data_buf_add_u8_offset(struct net_buf_simple * buf,uint8_t val,size_t * offset)152 static uint8_t *data_buf_add_u8_offset(struct net_buf_simple *buf,
153 				       uint8_t val, size_t *offset)
154 {
155 	if (*offset >= 1) {
156 		*offset -= 1;
157 		return NULL;
158 	}
159 
160 	return net_buf_simple_add_u8(buf, val);
161 }
162 
data_buf_add_le16_offset(struct net_buf_simple * buf,uint16_t val,size_t * offset)163 static void data_buf_add_le16_offset(struct net_buf_simple *buf,
164 				     uint16_t val, size_t *offset)
165 {
166 	if (*offset >= 2) {
167 		*offset -= 2;
168 		return;
169 	} else if (*offset == 1) {
170 		*offset -= 1;
171 		net_buf_simple_add_u8(buf, (val >> 8));
172 	} else {
173 		net_buf_simple_add_le16(buf, val);
174 	}
175 }
176 
data_buf_add_mem_offset(struct net_buf_simple * buf,uint8_t * data,size_t len,size_t * offset)177 static void data_buf_add_mem_offset(struct net_buf_simple *buf, uint8_t *data, size_t len,
178 				    size_t *offset)
179 {
180 	if (*offset >= len) {
181 		*offset -= len;
182 		return;
183 	}
184 
185 	net_buf_simple_add_mem(buf, data + *offset, len - *offset);
186 	*offset = 0;
187 }
188 
comp_add_model(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,void * user_data)189 static void comp_add_model(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem,
190 			   bool vnd, void *user_data)
191 {
192 	struct comp_foreach_model_arg *arg = user_data;
193 
194 	if (vnd) {
195 		data_buf_add_le16_offset(arg->buf, mod->vnd.company, arg->offset);
196 		data_buf_add_le16_offset(arg->buf, mod->vnd.id, arg->offset);
197 	} else {
198 		data_buf_add_le16_offset(arg->buf, mod->id, arg->offset);
199 	}
200 }
201 
202 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
203 
metadata_model_size(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd)204 static size_t metadata_model_size(const struct bt_mesh_model *mod,
205 				  const struct bt_mesh_elem *elem, bool vnd)
206 {
207 	const struct bt_mesh_models_metadata_entry *entry;
208 	size_t size = 0;
209 
210 	if (!mod->metadata) {
211 		return size;
212 	}
213 
214 	if (vnd) {
215 		size += sizeof(mod->vnd.company);
216 		size += sizeof(mod->vnd.id);
217 	} else {
218 		size += sizeof(mod->id);
219 	}
220 
221 	size += sizeof(uint8_t);
222 
223 	for (entry = *mod->metadata; entry && entry->len; ++entry) {
224 		size += sizeof(entry->len) + sizeof(entry->id) + entry->len;
225 	}
226 
227 	return size;
228 }
229 
bt_mesh_metadata_page_0_size(void)230 size_t bt_mesh_metadata_page_0_size(void)
231 {
232 	const struct bt_mesh_comp *comp;
233 	size_t size = 0;
234 	int i, j;
235 
236 	comp = bt_mesh_comp_get();
237 
238 	for (i = 0; i < dev_comp->elem_count; i++) {
239 		const struct bt_mesh_elem *elem = &dev_comp->elem[i];
240 
241 		size += sizeof(elem->model_count) +
242 			sizeof(elem->vnd_model_count);
243 
244 		for (j = 0; j < elem->model_count; j++) {
245 			const struct bt_mesh_model *model = &elem->models[j];
246 
247 			size += metadata_model_size(model, elem, false);
248 		}
249 
250 		for (j = 0; j < elem->vnd_model_count; j++) {
251 			const struct bt_mesh_model *model = &elem->vnd_models[j];
252 
253 			size += metadata_model_size(model, elem, true);
254 		}
255 	}
256 
257 	return size;
258 }
259 
metadata_add_model(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,void * user_data)260 static int metadata_add_model(const struct bt_mesh_model *mod,
261 			      const struct bt_mesh_elem *elem, bool vnd,
262 			      void *user_data)
263 {
264 	const struct bt_mesh_models_metadata_entry *entry;
265 	struct comp_foreach_model_arg *arg = user_data;
266 	struct net_buf_simple *buf = arg->buf;
267 	size_t *offset = arg->offset;
268 	size_t model_size;
269 	uint8_t count = 0;
270 	uint8_t *count_ptr;
271 
272 	model_size = metadata_model_size(mod, elem, vnd);
273 
274 	if (*offset >= model_size) {
275 		*offset -= model_size;
276 		return 0;
277 	}
278 
279 	if (net_buf_simple_tailroom(buf) < (model_size + BT_MESH_MIC_SHORT)) {
280 		LOG_DBG("Model metadata didn't fit in the buffer");
281 		return -E2BIG;
282 	}
283 
284 	comp_add_model(mod, elem, vnd, user_data);
285 
286 	count_ptr = data_buf_add_u8_offset(buf, 0, offset);
287 
288 	if (mod->metadata) {
289 		for (entry = *mod->metadata; entry && entry->data != NULL; ++entry) {
290 			data_buf_add_le16_offset(buf, entry->len, offset);
291 			data_buf_add_le16_offset(buf, entry->id, offset);
292 			data_buf_add_mem_offset(buf, entry->data, entry->len, offset);
293 			count++;
294 		}
295 	}
296 
297 	if (count_ptr) {
298 		*count_ptr = count;
299 	}
300 
301 	return 0;
302 }
303 
bt_mesh_metadata_get_page_0(struct net_buf_simple * buf,size_t offset)304 int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset)
305 {
306 	const struct bt_mesh_comp *comp;
307 	struct comp_foreach_model_arg arg = {
308 		.buf = buf,
309 		.offset = &offset,
310 	};
311 	uint8_t *mod_count_ptr;
312 	uint8_t *vnd_count_ptr;
313 	int i, j, err;
314 
315 	comp = bt_mesh_comp_get();
316 
317 	for (i = 0; i < comp->elem_count; i++) {
318 		const struct bt_mesh_elem *elem = &dev_comp->elem[i];
319 
320 		/* Check that the buffer has available tailroom for metadata item counts */
321 		if (net_buf_simple_tailroom(buf) < (((offset == 0) ? 2 : (offset == 1) ? 1 : 0)
322 				+ BT_MESH_MIC_SHORT)) {
323 			LOG_DBG("Model metadata didn't fit in the buffer");
324 			return -E2BIG;
325 		}
326 		mod_count_ptr = data_buf_add_u8_offset(buf, 0, &offset);
327 		vnd_count_ptr = data_buf_add_u8_offset(buf, 0, &offset);
328 
329 		for (j = 0; j < elem->model_count; j++) {
330 			const struct bt_mesh_model *model = &elem->models[j];
331 
332 			if (!model->metadata) {
333 				continue;
334 			}
335 
336 			err = metadata_add_model(model, elem, false, &arg);
337 			if (err) {
338 				return err;
339 			}
340 
341 			if (mod_count_ptr) {
342 				(*mod_count_ptr) += 1;
343 			}
344 		}
345 
346 		for (j = 0; j < elem->vnd_model_count; j++) {
347 			const struct bt_mesh_model *model = &elem->vnd_models[j];
348 
349 			if (!model->metadata) {
350 				continue;
351 			}
352 
353 			err = metadata_add_model(model, elem, true, &arg);
354 			if (err) {
355 				return err;
356 			}
357 
358 			if (vnd_count_ptr) {
359 				(*vnd_count_ptr) += 1;
360 			}
361 		}
362 	}
363 
364 	return 0;
365 }
366 #endif
367 
comp_add_elem(struct net_buf_simple * buf,const struct bt_mesh_elem * elem,size_t * offset)368 static int comp_add_elem(struct net_buf_simple *buf, const struct bt_mesh_elem *elem,
369 			 size_t *offset)
370 {
371 	struct comp_foreach_model_arg arg = {
372 		.buf = buf,
373 		.offset = offset,
374 	};
375 	const size_t elem_size = bt_mesh_comp_elem_size(elem);
376 	int i;
377 
378 	if (*offset >= elem_size) {
379 		*offset -= elem_size;
380 		return 0;
381 	}
382 
383 	if (net_buf_simple_tailroom(buf) < ((elem_size - *offset) + BT_MESH_MIC_SHORT)) {
384 		if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) {
385 			/* MshPRTv1.1: 4.4.1.2.2:
386 			 * If the complete list of models does not fit in the Data field,
387 			 * the element shall not be reported.
388 			 */
389 			LOG_DBG("Element 0x%04x didn't fit in the Data field",
390 				elem->rt->addr);
391 			return 0;
392 		}
393 
394 		LOG_ERR("Too large device composition");
395 		return -E2BIG;
396 	}
397 
398 	data_buf_add_le16_offset(buf, elem->loc, offset);
399 
400 	data_buf_add_u8_offset(buf, elem->model_count, offset);
401 	data_buf_add_u8_offset(buf, elem->vnd_model_count, offset);
402 
403 	for (i = 0; i < elem->model_count; i++) {
404 		const struct bt_mesh_model *model = &elem->models[i];
405 
406 		comp_add_model(model, elem, false, &arg);
407 	}
408 
409 	for (i = 0; i < elem->vnd_model_count; i++) {
410 		const struct bt_mesh_model *model = &elem->vnd_models[i];
411 
412 		comp_add_model(model, elem, true, &arg);
413 	}
414 
415 	return 0;
416 }
417 
bt_mesh_comp_data_get_page_0(struct net_buf_simple * buf,size_t offset)418 int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset)
419 {
420 	uint16_t feat = 0U;
421 	const struct bt_mesh_comp *comp;
422 	int i;
423 
424 	comp = bt_mesh_comp_get();
425 
426 	if (IS_ENABLED(CONFIG_BT_MESH_RELAY)) {
427 		feat |= BT_MESH_FEAT_RELAY;
428 	}
429 
430 	if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
431 		feat |= BT_MESH_FEAT_PROXY;
432 	}
433 
434 	if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
435 		feat |= BT_MESH_FEAT_FRIEND;
436 	}
437 
438 	if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
439 		feat |= BT_MESH_FEAT_LOW_POWER;
440 	}
441 
442 	data_buf_add_le16_offset(buf, comp->cid, &offset);
443 	data_buf_add_le16_offset(buf, comp->pid, &offset);
444 	data_buf_add_le16_offset(buf, comp->vid, &offset);
445 	data_buf_add_le16_offset(buf, CONFIG_BT_MESH_CRPL, &offset);
446 	data_buf_add_le16_offset(buf, feat, &offset);
447 
448 	for (i = 0; i < comp->elem_count; i++) {
449 		int err;
450 
451 		err = comp_add_elem(buf, &comp->elem[i], &offset);
452 		if (err) {
453 			return err;
454 		}
455 	}
456 
457 	return 0;
458 }
459 
count_mod_ext(const struct bt_mesh_model * mod,uint8_t * max_offset,uint8_t sig_offset)460 static uint8_t count_mod_ext(const struct bt_mesh_model *mod,
461 			     uint8_t *max_offset, uint8_t sig_offset)
462 {
463 	int i;
464 	uint8_t extensions = 0;
465 	int8_t offset, offset_record = 0;
466 
467 	MOD_REL_LIST_FOR_EACH(i) {
468 		if (IS_MOD_EXTENSION(mod, i, sig_offset) &&
469 		    mod_rel_list[i].type == RELATION_TYPE_EXT) {
470 			extensions++;
471 			offset = mod_rel_list[i].elem_ext -
472 				mod_rel_list[i].elem_base;
473 			if (abs(offset) > abs(offset_record)) {
474 				offset_record = offset;
475 			}
476 		}
477 	}
478 
479 	if (max_offset) {
480 		memcpy(max_offset, &offset_record, sizeof(uint8_t));
481 	}
482 	return extensions;
483 }
484 
is_cor_present(const struct bt_mesh_model * mod,uint8_t * cor_id,uint8_t sig_offset)485 static bool is_cor_present(const struct bt_mesh_model *mod, uint8_t *cor_id, uint8_t sig_offset)
486 {
487 	int i;
488 
489 	MOD_REL_LIST_FOR_EACH(i)
490 	{
491 		if ((IS_MOD_BASE(mod, i, sig_offset) ||
492 		     IS_MOD_EXTENSION(mod, i, sig_offset)) &&
493 		    mod_rel_list[i].type < RELATION_TYPE_EXT) {
494 			if (cor_id) {
495 				memcpy(cor_id, &mod_rel_list[i].type, sizeof(uint8_t));
496 			}
497 			return true;
498 		}
499 	}
500 	return false;
501 }
502 
prep_model_item_header(const struct bt_mesh_model * mod,uint8_t * cor_id,uint8_t * mod_cnt,struct net_buf_simple * buf,size_t * offset,uint8_t sig_offset)503 static void prep_model_item_header(const struct bt_mesh_model *mod, uint8_t *cor_id,
504 				   uint8_t *mod_cnt, struct net_buf_simple *buf,
505 				   size_t *offset, uint8_t sig_offset)
506 {
507 	uint8_t ext_mod_cnt;
508 	bool cor_present;
509 	uint8_t mod_elem_info = 0;
510 	int8_t max_offset;
511 
512 	ext_mod_cnt = count_mod_ext(mod, &max_offset, sig_offset);
513 	cor_present = is_cor_present(mod, cor_id, sig_offset);
514 
515 	mod_elem_info = ext_mod_cnt << 2;
516 	if (ext_mod_cnt > 31 ||
517 		max_offset > 3 ||
518 		max_offset < -4) {
519 		mod_elem_info |= BIT(1);
520 	}
521 	if (cor_present) {
522 		mod_elem_info |= BIT(0);
523 	}
524 	data_buf_add_u8_offset(buf, mod_elem_info, offset);
525 
526 	if (cor_present) {
527 		data_buf_add_u8_offset(buf, *cor_id, offset);
528 	}
529 	memset(mod_cnt, ext_mod_cnt, sizeof(uint8_t));
530 }
531 
add_items_to_page(struct net_buf_simple * buf,const struct bt_mesh_model * mod,uint8_t ext_mod_cnt,size_t * offset,uint8_t sig_offset)532 static void add_items_to_page(struct net_buf_simple *buf, const struct bt_mesh_model *mod,
533 			      uint8_t ext_mod_cnt, size_t *offset, uint8_t sig_offset)
534 {
535 	int i, elem_offset;
536 	uint8_t mod_idx;
537 
538 	MOD_REL_LIST_FOR_EACH(i) {
539 		if (IS_MOD_EXTENSION(mod, i, sig_offset) &&
540 		    mod_rel_list[i].type == RELATION_TYPE_EXT) {
541 			elem_offset = mod->rt->elem_idx - mod_rel_list[i].elem_base;
542 			mod_idx = mod_rel_list[i].idx_base;
543 			if (ext_mod_cnt < 32 &&
544 				elem_offset < 4 &&
545 				elem_offset > -5) {
546 				/* short format */
547 				if (elem_offset < 0) {
548 					elem_offset += 8;
549 				}
550 
551 				elem_offset |= mod_idx << 3;
552 				data_buf_add_u8_offset(buf, elem_offset, offset);
553 			} else {
554 				/* long format */
555 				if (elem_offset < 0) {
556 					elem_offset += 256;
557 				}
558 				data_buf_add_u8_offset(buf, elem_offset, offset);
559 				data_buf_add_u8_offset(buf, mod_idx, offset);
560 			}
561 		}
562 	}
563 }
564 
mod_items_size(const struct bt_mesh_model * mod,uint8_t sig_offset)565 static size_t mod_items_size(const struct bt_mesh_model *mod, uint8_t sig_offset)
566 {
567 	int i, offset;
568 	size_t temp_size = 0;
569 	int ext_mod_cnt = count_mod_ext(mod, NULL, sig_offset);
570 
571 	if (!ext_mod_cnt) {
572 		return 0;
573 	}
574 
575 	MOD_REL_LIST_FOR_EACH(i) {
576 		if (IS_MOD_EXTENSION(mod, i, sig_offset)) {
577 			offset = mod->rt->elem_idx - mod_rel_list[i].elem_base;
578 			temp_size += (ext_mod_cnt < 32 && offset < 4 && offset > -5) ? 1 : 2;
579 		}
580 	}
581 
582 	return temp_size;
583 }
584 
page1_elem_size(const struct bt_mesh_elem * elem)585 static size_t page1_elem_size(const struct bt_mesh_elem *elem)
586 {
587 	size_t temp_size = 2;
588 
589 	for (int i = 0; i < elem->model_count; i++) {
590 		temp_size += is_cor_present(&elem->models[i], NULL, 0) ? 2 : 1;
591 		temp_size += mod_items_size(&elem->models[i], 0);
592 	}
593 
594 	for (int i = 0; i < elem->vnd_model_count; i++) {
595 		temp_size += is_cor_present(&elem->vnd_models[i], NULL, elem->model_count) ? 2 : 1;
596 		temp_size += mod_items_size(&elem->vnd_models[i], elem->model_count);
597 	}
598 
599 	return temp_size;
600 }
601 
bt_mesh_comp_data_get_page_1(struct net_buf_simple * buf,size_t offset)602 static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf, size_t offset)
603 {
604 	const struct bt_mesh_comp *comp;
605 	uint8_t cor_id = 0;
606 	uint8_t ext_mod_cnt = 0;
607 	int i, j;
608 
609 	comp = bt_mesh_comp_get();
610 
611 	for (i = 0; i < comp->elem_count; i++) {
612 		size_t elem_size = page1_elem_size(&comp->elem[i]);
613 
614 		if (offset >= elem_size) {
615 			offset -= elem_size;
616 			continue;
617 		}
618 
619 		if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) {
620 			if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) {
621 				/* MshPRTv1.1: 4.4.1.2.2:
622 				 * If the complete list of models does not fit in the Data field,
623 				 * the element shall not be reported.
624 				 */
625 				LOG_DBG("Element 0x%04x didn't fit in the Data field",
626 					comp->elem[i].rt->addr);
627 				return 0;
628 			}
629 
630 			LOG_ERR("Too large device composition");
631 			return -E2BIG;
632 		}
633 
634 		data_buf_add_u8_offset(buf, comp->elem[i].model_count, &offset);
635 		data_buf_add_u8_offset(buf, comp->elem[i].vnd_model_count, &offset);
636 		for (j = 0; j < comp->elem[i].model_count; j++) {
637 			prep_model_item_header(&comp->elem[i].models[j], &cor_id, &ext_mod_cnt, buf,
638 					       &offset, 0);
639 			if (ext_mod_cnt != 0) {
640 				add_items_to_page(buf, &comp->elem[i].models[j], ext_mod_cnt,
641 						  &offset,
642 						  0);
643 			}
644 		}
645 
646 		for (j = 0; j < comp->elem[i].vnd_model_count; j++) {
647 			prep_model_item_header(&comp->elem[i].vnd_models[j], &cor_id, &ext_mod_cnt,
648 					       buf, &offset,
649 						   comp->elem[i].model_count);
650 			if (ext_mod_cnt != 0) {
651 				add_items_to_page(buf, &comp->elem[i].vnd_models[j], ext_mod_cnt,
652 						  &offset,
653 						  comp->elem[i].model_count);
654 			}
655 		}
656 	}
657 	return 0;
658 }
659 
bt_mesh_comp_data_get_page_2(struct net_buf_simple * buf,size_t offset)660 static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf, size_t offset)
661 {
662 	if (!dev_comp2) {
663 		LOG_ERR("Composition data P2 not registered");
664 		return -ENODEV;
665 	}
666 
667 	size_t elem_size;
668 
669 	for (int i = 0; i < dev_comp2->record_cnt; i++) {
670 		elem_size =
671 			8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len;
672 		if (offset >= elem_size) {
673 			offset -= elem_size;
674 			continue;
675 		}
676 
677 		if (net_buf_simple_tailroom(buf) < ((elem_size - offset) + BT_MESH_MIC_SHORT)) {
678 			if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) {
679 				/* MshPRTv1.1: 4.4.1.2.2:
680 				 * If the complete list of models does not fit in the Data field,
681 				 * the element shall not be reported.
682 				 */
683 				LOG_DBG("Record 0x%04x didn't fit in the Data field", i);
684 				return 0;
685 			}
686 
687 			LOG_ERR("Too large device composition");
688 			return -E2BIG;
689 		}
690 
691 		data_buf_add_le16_offset(buf, dev_comp2->record[i].id, &offset);
692 		data_buf_add_u8_offset(buf, dev_comp2->record[i].version.x, &offset);
693 		data_buf_add_u8_offset(buf, dev_comp2->record[i].version.y, &offset);
694 		data_buf_add_u8_offset(buf, dev_comp2->record[i].version.z, &offset);
695 		data_buf_add_u8_offset(buf, dev_comp2->record[i].elem_offset_cnt, &offset);
696 		if (dev_comp2->record[i].elem_offset_cnt) {
697 			data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].elem_offset,
698 						dev_comp2->record[i].elem_offset_cnt, &offset);
699 		}
700 
701 		data_buf_add_le16_offset(buf, dev_comp2->record[i].data_len, &offset);
702 		if (dev_comp2->record[i].data_len) {
703 			data_buf_add_mem_offset(buf, (uint8_t *)dev_comp2->record[i].data,
704 						dev_comp2->record[i].data_len, &offset);
705 		}
706 	}
707 
708 	return 0;
709 }
710 
bt_mesh_model_pub_period_get(const struct bt_mesh_model * mod)711 int32_t bt_mesh_model_pub_period_get(const struct bt_mesh_model *mod)
712 {
713 	int32_t period;
714 
715 	if (!mod->pub) {
716 		return 0;
717 	}
718 
719 	switch (mod->pub->period >> 6) {
720 	case 0x00:
721 		/* 1 step is 100 ms */
722 		period = (mod->pub->period & BIT_MASK(6)) * 100U;
723 		break;
724 	case 0x01:
725 		/* 1 step is 1 second */
726 		period = (mod->pub->period & BIT_MASK(6)) * MSEC_PER_SEC;
727 		break;
728 	case 0x02:
729 		/* 1 step is 10 seconds */
730 		period = (mod->pub->period & BIT_MASK(6)) * 10U * MSEC_PER_SEC;
731 		break;
732 	case 0x03:
733 		/* 1 step is 10 minutes */
734 		period = (mod->pub->period & BIT_MASK(6)) * 600U * MSEC_PER_SEC;
735 		break;
736 	default:
737 		CODE_UNREACHABLE;
738 	}
739 
740 	if (mod->pub->fast_period) {
741 		if (!period) {
742 			return 0;
743 		}
744 
745 		return MAX(period >> mod->pub->period_div, 100);
746 	} else {
747 		return period;
748 	}
749 }
750 
next_period(const struct bt_mesh_model * mod)751 static int32_t next_period(const struct bt_mesh_model *mod)
752 {
753 	struct bt_mesh_model_pub *pub = mod->pub;
754 	uint32_t period = 0;
755 	uint32_t elapsed;
756 
757 	elapsed = k_uptime_get_32() - pub->period_start;
758 	LOG_DBG("Publishing took %ums", elapsed);
759 
760 	if (mod->pub->count) {
761 		/* If a message is to be retransmitted, period should include time since the first
762 		 * publication until the last publication.
763 		 */
764 		period = BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit);
765 		period *= BT_MESH_PUB_MSG_NUM(mod->pub);
766 
767 		if (period && elapsed >= period) {
768 			LOG_WRN("Retransmission interval is too short");
769 
770 			if (!!pub->delayable) {
771 				LOG_WRN("Publication period is too short for"
772 					" retransmissions");
773 			}
774 
775 			/* Keep retransmitting the message with the interval sacrificing the
776 			 * next publication period start.
777 			 */
778 			return BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit);
779 		}
780 	}
781 
782 	if (!period) {
783 		period = bt_mesh_model_pub_period_get(mod);
784 		if (!period) {
785 			return 0;
786 		}
787 	}
788 
789 	if (elapsed >= period) {
790 		LOG_WRN("Publication sending took longer than the period");
791 
792 		if (!!pub->delayable) {
793 			LOG_WRN("Publication period is too short to be delayable");
794 		}
795 
796 		/* Return smallest positive number since 0 means disabled */
797 		return 1;
798 	}
799 
800 	return period - elapsed;
801 }
802 
publish_sent(int err,void * user_data)803 static void publish_sent(int err, void *user_data)
804 {
805 	const struct bt_mesh_model *mod = user_data;
806 	int32_t delay;
807 
808 	LOG_DBG("err %d, time %u", err, k_uptime_get_32());
809 
810 	delay = next_period(mod);
811 
812 	if (delay) {
813 		LOG_DBG("Publishing next time in %dms", delay);
814 		/* Using schedule() in case the application has already called
815 		 * bt_mesh_publish, and a publication is pending.
816 		 */
817 		k_work_schedule(&mod->pub->timer, K_MSEC(delay));
818 	}
819 }
820 
publish_start(uint16_t duration,int err,void * user_data)821 static void publish_start(uint16_t duration, int err, void *user_data)
822 {
823 	if (err) {
824 		LOG_ERR("Failed to publish: err %d", err);
825 		publish_sent(err, user_data);
826 		return;
827 	}
828 }
829 
830 static const struct bt_mesh_send_cb pub_sent_cb = {
831 	.start = publish_start,
832 	.end = publish_sent,
833 };
834 
publish_transmit(const struct bt_mesh_model * mod)835 static int publish_transmit(const struct bt_mesh_model *mod)
836 {
837 	NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
838 	struct bt_mesh_model_pub *pub = mod->pub;
839 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_PUB(pub);
840 	struct bt_mesh_net_tx tx = {
841 		.ctx = &ctx,
842 		.src = bt_mesh_model_elem(mod)->rt->addr,
843 		.friend_cred = pub->cred,
844 	};
845 
846 	net_buf_simple_add_mem(&sdu, pub->msg->data, pub->msg->len);
847 
848 	return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, (void *)mod);
849 }
850 
pub_period_start(struct bt_mesh_model_pub * pub)851 static int pub_period_start(struct bt_mesh_model_pub *pub)
852 {
853 	int err;
854 
855 	pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit);
856 
857 	if (!pub->update) {
858 		return 0;
859 	}
860 
861 	err = pub->update(pub->mod);
862 
863 	pub->period_start = k_uptime_get_32();
864 
865 	if (err) {
866 		/* Skip this publish attempt. */
867 		LOG_DBG("Update failed, skipping publish (err: %d)", err);
868 		pub->count = 0;
869 		publish_sent(err, (void *)pub->mod);
870 		return err;
871 	}
872 
873 	return 0;
874 }
875 
pub_delay_get(int random_delay_window)876 static uint16_t pub_delay_get(int random_delay_window)
877 {
878 	if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) {
879 		return 0;
880 	}
881 
882 	uint16_t num = 0;
883 
884 	(void)bt_rand(&num, sizeof(num));
885 
886 	return 20 + (num % random_delay_window);
887 }
888 
pub_delay_schedule(struct bt_mesh_model_pub * pub,int delay)889 static int pub_delay_schedule(struct bt_mesh_model_pub *pub, int delay)
890 {
891 	uint16_t random;
892 	int err;
893 
894 	if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) {
895 		return -ENOTSUP;
896 	}
897 
898 	random = pub_delay_get(delay);
899 	err = k_work_reschedule(&pub->timer, K_MSEC(random));
900 	if (err < 0) {
901 		LOG_ERR("Unable to delay publication (err %d)", err);
902 		return err;
903 	}
904 
905 	LOG_DBG("Publication delayed by %dms", random);
906 	return 0;
907 }
908 
mod_publish(struct k_work * work)909 static void mod_publish(struct k_work *work)
910 {
911 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
912 	struct bt_mesh_model_pub *pub = CONTAINER_OF(dwork,
913 						     struct bt_mesh_model_pub,
914 						     timer);
915 	int err;
916 
917 	if (pub->addr == BT_MESH_ADDR_UNASSIGNED ||
918 	    atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
919 		/* Publication is no longer active, but the cancellation of the
920 		 * delayed work failed. Abandon recurring timer.
921 		 */
922 		return;
923 	}
924 
925 	LOG_DBG("timestamp: %u", k_uptime_get_32());
926 
927 	if (pub->count) {
928 		pub->count--;
929 
930 		if (pub->retr_update && pub->update &&
931 		    bt_mesh_model_pub_is_retransmission(pub->mod)) {
932 			err = pub->update(pub->mod);
933 			if (err) {
934 				publish_sent(err, (void *)pub->mod);
935 				return;
936 			}
937 		}
938 	} else {
939 		/* First publication in this period */
940 		err = pub_period_start(pub);
941 		if (err) {
942 			return;
943 		}
944 
945 		/* Delay the first publication in a period. */
946 		if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_SHORT)) {
947 			/* Increment count as it would do BT_MESH_PUB_MSG_TOTAL */
948 			pub->count++;
949 			return;
950 		}
951 	}
952 
953 	err = publish_transmit(pub->mod);
954 	if (err) {
955 		LOG_ERR("Failed to publish (err %d)", err);
956 		publish_sent(err, (void *)pub->mod);
957 	}
958 }
959 
bt_mesh_model_elem(const struct bt_mesh_model * mod)960 const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod)
961 {
962 	return &dev_comp->elem[mod->rt->elem_idx];
963 }
964 
bt_mesh_model_get(bool vnd,uint8_t elem_idx,uint8_t mod_idx)965 const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx)
966 {
967 	const struct bt_mesh_elem *elem;
968 
969 	if (elem_idx >= dev_comp->elem_count) {
970 		LOG_ERR("Invalid element index %u", elem_idx);
971 		return NULL;
972 	}
973 
974 	elem = &dev_comp->elem[elem_idx];
975 
976 	if (vnd) {
977 		if (mod_idx >= elem->vnd_model_count) {
978 			LOG_ERR("Invalid vendor model index %u", mod_idx);
979 			return NULL;
980 		}
981 
982 		return &elem->vnd_models[mod_idx];
983 	} else {
984 		if (mod_idx >= elem->model_count) {
985 			LOG_ERR("Invalid SIG model index %u", mod_idx);
986 			return NULL;
987 		}
988 
989 		return &elem->models[mod_idx];
990 	}
991 }
992 
993 #if defined(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)
bt_mesh_vnd_mod_msg_cid_check(const struct bt_mesh_model * mod)994 static int bt_mesh_vnd_mod_msg_cid_check(const struct bt_mesh_model *mod)
995 {
996 	uint16_t cid;
997 	const struct bt_mesh_model_op *op;
998 
999 	for (op = mod->op; op->func; op++) {
1000 		cid = (uint16_t)(op->opcode & 0xffff);
1001 
1002 		if (cid == mod->vnd.company) {
1003 			continue;
1004 		}
1005 
1006 		LOG_ERR("Invalid vendor model(company:0x%04x"
1007 		       " id:0x%04x) message opcode 0x%08x",
1008 		       mod->vnd.company, mod->vnd.id, op->opcode);
1009 
1010 		return -EINVAL;
1011 	}
1012 
1013 	return 0;
1014 }
1015 #endif
1016 
mod_init(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)1017 static void mod_init(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem,
1018 		     bool vnd, bool primary, void *user_data)
1019 {
1020 	int i;
1021 	int *err = user_data;
1022 
1023 	if (*err) {
1024 		return;
1025 	}
1026 
1027 	if (mod->pub) {
1028 		mod->pub->mod = mod;
1029 		k_work_init_delayable(&mod->pub->timer, mod_publish);
1030 	}
1031 
1032 	for (i = 0; i < mod->keys_cnt; i++) {
1033 		mod->keys[i] = BT_MESH_KEY_UNUSED;
1034 	}
1035 
1036 	mod->rt->elem_idx = elem - dev_comp->elem;
1037 	if (vnd) {
1038 		mod->rt->mod_idx = mod - elem->vnd_models;
1039 
1040 		if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)) {
1041 			*err = bt_mesh_vnd_mod_msg_cid_check(mod);
1042 			if (*err) {
1043 				return;
1044 			}
1045 		}
1046 
1047 	} else {
1048 		mod->rt->mod_idx = mod - elem->models;
1049 	}
1050 
1051 	if (mod->cb && mod->cb->init) {
1052 		*err = mod->cb->init(mod);
1053 	}
1054 }
1055 
bt_mesh_comp_register(const struct bt_mesh_comp * comp)1056 int bt_mesh_comp_register(const struct bt_mesh_comp *comp)
1057 {
1058 	int err;
1059 
1060 	/* There must be at least one element */
1061 	if (!comp || !comp->elem_count) {
1062 		return -EINVAL;
1063 	}
1064 
1065 	dev_comp = comp;
1066 
1067 	err = 0;
1068 
1069 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1070 		memset(mod_rel_list, 0, sizeof(mod_rel_list));
1071 	}
1072 
1073 	bt_mesh_model_foreach(mod_init, &err);
1074 
1075 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1076 		int i;
1077 
1078 		MOD_REL_LIST_FOR_EACH(i) {
1079 			LOG_DBG("registered %s",
1080 				mod_rel_list[i].type < RELATION_TYPE_EXT ?
1081 				"correspondence" : "extension");
1082 			LOG_DBG("\tbase: elem %u idx %u",
1083 				mod_rel_list[i].elem_base,
1084 				mod_rel_list[i].idx_base);
1085 			LOG_DBG("\text: elem %u idx %u",
1086 				mod_rel_list[i].elem_ext,
1087 				mod_rel_list[i].idx_ext);
1088 		}
1089 		if (i < MOD_REL_LIST_SIZE) {
1090 			LOG_WRN("Unused space in relation list: %d",
1091 				MOD_REL_LIST_SIZE - i);
1092 		}
1093 	}
1094 
1095 	return err;
1096 }
1097 
bt_mesh_comp2_register(const struct bt_mesh_comp2 * comp2)1098 int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2)
1099 {
1100 	if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) {
1101 		return -EINVAL;
1102 	}
1103 
1104 	dev_comp2 = comp2;
1105 
1106 	return 0;
1107 }
1108 
bt_mesh_comp_provision(uint16_t addr)1109 void bt_mesh_comp_provision(uint16_t addr)
1110 {
1111 	int i;
1112 
1113 	dev_primary_addr = addr;
1114 
1115 	LOG_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count);
1116 
1117 	for (i = 0; i < dev_comp->elem_count; i++) {
1118 		const struct bt_mesh_elem *elem = &dev_comp->elem[i];
1119 
1120 		elem->rt->addr = addr++;
1121 
1122 		LOG_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", elem->rt->addr,
1123 			elem->model_count, elem->vnd_model_count);
1124 	}
1125 }
1126 
bt_mesh_comp_unprovision(void)1127 void bt_mesh_comp_unprovision(void)
1128 {
1129 	LOG_DBG("");
1130 
1131 	dev_primary_addr = BT_MESH_ADDR_UNASSIGNED;
1132 
1133 	for (int i = 0; i < dev_comp->elem_count; i++) {
1134 		const struct bt_mesh_elem *elem = &dev_comp->elem[i];
1135 
1136 		elem->rt->addr = BT_MESH_ADDR_UNASSIGNED;
1137 	}
1138 }
1139 
bt_mesh_primary_addr(void)1140 uint16_t bt_mesh_primary_addr(void)
1141 {
1142 	return dev_primary_addr;
1143 }
1144 
model_group_get(const struct bt_mesh_model * mod,uint16_t addr)1145 static uint16_t *model_group_get(const struct bt_mesh_model *mod, uint16_t addr)
1146 {
1147 	int i;
1148 
1149 	for (i = 0; i < mod->groups_cnt; i++) {
1150 		if (mod->groups[i] == addr) {
1151 			return &mod->groups[i];
1152 		}
1153 	}
1154 
1155 	return NULL;
1156 }
1157 
1158 struct find_group_visitor_ctx {
1159 	uint16_t *entry;
1160 	const struct bt_mesh_model *mod;
1161 	uint16_t addr;
1162 };
1163 
find_group_mod_visitor(const struct bt_mesh_model * mod,void * user_data)1164 static enum bt_mesh_walk find_group_mod_visitor(const struct bt_mesh_model *mod, void *user_data)
1165 {
1166 	struct find_group_visitor_ctx *ctx = user_data;
1167 
1168 	if (mod->rt->elem_idx != ctx->mod->rt->elem_idx) {
1169 		return BT_MESH_WALK_CONTINUE;
1170 	}
1171 
1172 	ctx->entry = model_group_get(mod, ctx->addr);
1173 	if (ctx->entry) {
1174 		ctx->mod = mod;
1175 		return BT_MESH_WALK_STOP;
1176 	}
1177 
1178 	return BT_MESH_WALK_CONTINUE;
1179 }
1180 
bt_mesh_model_find_group(const struct bt_mesh_model ** mod,uint16_t addr)1181 uint16_t *bt_mesh_model_find_group(const struct bt_mesh_model **mod, uint16_t addr)
1182 {
1183 	struct find_group_visitor_ctx ctx = {
1184 		.mod = *mod,
1185 		.entry = NULL,
1186 		.addr = addr,
1187 	};
1188 
1189 	bt_mesh_model_extensions_walk(*mod, find_group_mod_visitor, &ctx);
1190 
1191 	*mod = ctx.mod;
1192 	return ctx.entry;
1193 }
1194 
1195 #if CONFIG_BT_MESH_LABEL_COUNT > 0
model_uuid_get(const struct bt_mesh_model * mod,const uint8_t * uuid)1196 static const uint8_t **model_uuid_get(const struct bt_mesh_model *mod, const uint8_t *uuid)
1197 {
1198 	int i;
1199 
1200 	for (i = 0; i < CONFIG_BT_MESH_LABEL_COUNT; i++) {
1201 		if (mod->uuids[i] == uuid) {
1202 			/* If we are looking for a new entry, ensure that we find a model where
1203 			 * there is empty entry in both, uuids and groups list.
1204 			 */
1205 			if (uuid == NULL && !model_group_get(mod, BT_MESH_ADDR_UNASSIGNED)) {
1206 				continue;
1207 			}
1208 
1209 			return &mod->uuids[i];
1210 		}
1211 	}
1212 
1213 	return NULL;
1214 }
1215 
1216 struct find_uuid_visitor_ctx {
1217 	const uint8_t **entry;
1218 	const struct bt_mesh_model *mod;
1219 	const uint8_t *uuid;
1220 };
1221 
find_uuid_mod_visitor(const struct bt_mesh_model * mod,void * user_data)1222 static enum bt_mesh_walk find_uuid_mod_visitor(const struct bt_mesh_model *mod, void *user_data)
1223 {
1224 	struct find_uuid_visitor_ctx *ctx = user_data;
1225 
1226 	if (mod->rt->elem_idx != ctx->mod->rt->elem_idx) {
1227 		return BT_MESH_WALK_CONTINUE;
1228 	}
1229 
1230 	ctx->entry = model_uuid_get(mod, ctx->uuid);
1231 	if (ctx->entry) {
1232 		ctx->mod = mod;
1233 		return BT_MESH_WALK_STOP;
1234 	}
1235 
1236 	return BT_MESH_WALK_CONTINUE;
1237 }
1238 #endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */
1239 
bt_mesh_model_find_uuid(const struct bt_mesh_model ** mod,const uint8_t * uuid)1240 const uint8_t **bt_mesh_model_find_uuid(const struct bt_mesh_model **mod, const uint8_t *uuid)
1241 {
1242 #if CONFIG_BT_MESH_LABEL_COUNT > 0
1243 	struct find_uuid_visitor_ctx ctx = {
1244 		.mod = *mod,
1245 		.entry = NULL,
1246 		.uuid = uuid,
1247 	};
1248 
1249 	bt_mesh_model_extensions_walk(*mod, find_uuid_mod_visitor, &ctx);
1250 
1251 	*mod = ctx.mod;
1252 	return ctx.entry;
1253 #else
1254 	return NULL;
1255 #endif
1256 }
1257 
bt_mesh_elem_find_group(const struct bt_mesh_elem * elem,uint16_t group_addr)1258 static const struct bt_mesh_model *bt_mesh_elem_find_group(const struct bt_mesh_elem *elem,
1259 						     uint16_t group_addr)
1260 {
1261 	const struct bt_mesh_model *model;
1262 	uint16_t *match;
1263 	int i;
1264 
1265 	for (i = 0; i < elem->model_count; i++) {
1266 		model = &elem->models[i];
1267 
1268 		match = model_group_get(model, group_addr);
1269 		if (match) {
1270 			return model;
1271 		}
1272 	}
1273 
1274 	for (i = 0; i < elem->vnd_model_count; i++) {
1275 		model = &elem->vnd_models[i];
1276 
1277 		match = model_group_get(model, group_addr);
1278 		if (match) {
1279 			return model;
1280 		}
1281 	}
1282 
1283 	return NULL;
1284 }
1285 
bt_mesh_elem_find(uint16_t addr)1286 const struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
1287 {
1288 	uint16_t index;
1289 
1290 	if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
1291 		return NULL;
1292 	}
1293 
1294 	index = addr - dev_comp->elem[0].rt->addr;
1295 	if (index >= dev_comp->elem_count) {
1296 		return NULL;
1297 	}
1298 
1299 	return &dev_comp->elem[index];
1300 }
1301 
bt_mesh_has_addr(uint16_t addr)1302 bool bt_mesh_has_addr(uint16_t addr)
1303 {
1304 	uint16_t index;
1305 
1306 	if (BT_MESH_ADDR_IS_UNICAST(addr)) {
1307 		return bt_mesh_elem_find(addr) != NULL;
1308 	}
1309 
1310 	if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
1311 		return true;
1312 	}
1313 
1314 	for (index = 0; index < dev_comp->elem_count; index++) {
1315 		const struct bt_mesh_elem *elem = &dev_comp->elem[index];
1316 
1317 		if (bt_mesh_elem_find_group(elem, addr)) {
1318 			return true;
1319 		}
1320 	}
1321 
1322 	return false;
1323 }
1324 
1325 #if defined(CONFIG_BT_MESH_ACCESS_LAYER_MSG)
bt_mesh_msg_cb_set(void (* cb)(uint32_t opcode,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf))1326 void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx,
1327 			struct net_buf_simple *buf))
1328 {
1329 	msg_cb = cb;
1330 }
1331 #endif
1332 
bt_mesh_access_send(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,uint16_t src_addr,const struct bt_mesh_send_cb * cb,void * cb_data)1333 int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr,
1334 			const struct bt_mesh_send_cb *cb, void *cb_data)
1335 {
1336 	struct bt_mesh_net_tx tx = {
1337 		.ctx = ctx,
1338 		.src = src_addr,
1339 	};
1340 
1341 	LOG_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx, tx.ctx->app_idx,
1342 		tx.ctx->addr);
1343 	LOG_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
1344 
1345 	if (!bt_mesh_is_provisioned()) {
1346 		LOG_ERR("Local node is not yet provisioned");
1347 		return -EAGAIN;
1348 	}
1349 
1350 	return bt_mesh_trans_send(&tx, buf, cb, cb_data);
1351 }
1352 
bt_mesh_elem_count(void)1353 uint8_t bt_mesh_elem_count(void)
1354 {
1355 	return dev_comp->elem_count;
1356 }
1357 
bt_mesh_model_has_key(const struct bt_mesh_model * mod,uint16_t key)1358 bool bt_mesh_model_has_key(const struct bt_mesh_model *mod, uint16_t key)
1359 {
1360 	int i;
1361 
1362 	for (i = 0; i < mod->keys_cnt; i++) {
1363 		if (mod->keys[i] == key ||
1364 		    (mod->keys[i] == BT_MESH_KEY_DEV_ANY &&
1365 		     BT_MESH_IS_DEV_KEY(key))) {
1366 			return true;
1367 		}
1368 	}
1369 
1370 	return false;
1371 }
1372 
model_has_dst(const struct bt_mesh_model * mod,uint16_t dst,const uint8_t * uuid)1373 static bool model_has_dst(const struct bt_mesh_model *mod, uint16_t dst, const uint8_t *uuid)
1374 {
1375 	if (BT_MESH_ADDR_IS_UNICAST(dst)) {
1376 		return (dev_comp->elem[mod->rt->elem_idx].rt->addr == dst);
1377 	} else if (BT_MESH_ADDR_IS_VIRTUAL(dst)) {
1378 		return !!bt_mesh_model_find_uuid(&mod, uuid);
1379 	} else if (BT_MESH_ADDR_IS_GROUP(dst) ||
1380 		  (BT_MESH_ADDR_IS_FIXED_GROUP(dst) &&  mod->rt->elem_idx != 0)) {
1381 		return !!bt_mesh_model_find_group(&mod, dst);
1382 	}
1383 
1384 	/* If a message with a fixed group address is sent to the access layer,
1385 	 * the lower layers have already confirmed that we are subscribing to
1386 	 * it. All models on the primary element should receive the message.
1387 	 */
1388 	return mod->rt->elem_idx == 0;
1389 }
1390 
find_op(const struct bt_mesh_elem * elem,uint32_t opcode,const struct bt_mesh_model ** model)1391 static const struct bt_mesh_model_op *find_op(const struct bt_mesh_elem *elem,
1392 					      uint32_t opcode, const struct bt_mesh_model **model)
1393 {
1394 	uint8_t i;
1395 	uint8_t count;
1396 	/* This value shall not be used in shipping end products. */
1397 	uint32_t cid = UINT32_MAX;
1398 	const struct bt_mesh_model *models;
1399 
1400 	/* SIG models cannot contain 3-byte (vendor) OpCodes, and
1401 	 * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so
1402 	 * we only need to do the lookup in one of the model lists.
1403 	 */
1404 	if (BT_MESH_MODEL_OP_LEN(opcode) < 3) {
1405 		models = elem->models;
1406 		count = elem->model_count;
1407 	} else {
1408 		models = elem->vnd_models;
1409 		count = elem->vnd_model_count;
1410 
1411 		cid = (uint16_t)(opcode & 0xffff);
1412 	}
1413 
1414 	for (i = 0U; i < count; i++) {
1415 
1416 		const struct bt_mesh_model_op *op;
1417 
1418 		if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) &&
1419 		     cid != UINT32_MAX &&
1420 		     cid != models[i].vnd.company) {
1421 			continue;
1422 		}
1423 
1424 		*model = &models[i];
1425 
1426 		for (op = (*model)->op; op->func; op++) {
1427 			if (op->opcode == opcode) {
1428 				return op;
1429 			}
1430 		}
1431 	}
1432 
1433 	*model = NULL;
1434 	return NULL;
1435 }
1436 
get_opcode(struct net_buf_simple * buf,uint32_t * opcode)1437 static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode)
1438 {
1439 	switch (buf->data[0] >> 6) {
1440 	case 0x00:
1441 	case 0x01:
1442 		if (buf->data[0] == 0x7f) {
1443 			LOG_ERR("Ignoring RFU OpCode");
1444 			return -EINVAL;
1445 		}
1446 
1447 		*opcode = net_buf_simple_pull_u8(buf);
1448 		return 0;
1449 	case 0x02:
1450 		if (buf->len < 2) {
1451 			LOG_ERR("Too short payload for 2-octet OpCode");
1452 			return -EINVAL;
1453 		}
1454 
1455 		*opcode = net_buf_simple_pull_be16(buf);
1456 		return 0;
1457 	case 0x03:
1458 		if (buf->len < 3) {
1459 			LOG_ERR("Too short payload for 3-octet OpCode");
1460 			return -EINVAL;
1461 		}
1462 
1463 		*opcode = net_buf_simple_pull_u8(buf) << 16;
1464 		/* Using LE for the CID since the model layer is defined as
1465 		 * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
1466 		 * will declare the opcode in this way.
1467 		 */
1468 		*opcode |= net_buf_simple_pull_le16(buf);
1469 		return 0;
1470 	}
1471 
1472 	CODE_UNREACHABLE;
1473 }
1474 
element_model_recv(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,const struct bt_mesh_elem * elem,uint32_t opcode)1475 static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf,
1476 			      const struct bt_mesh_elem *elem, uint32_t opcode)
1477 {
1478 	const struct bt_mesh_model_op *op;
1479 	const struct bt_mesh_model *model;
1480 	struct net_buf_simple_state state;
1481 	int err;
1482 
1483 	op = find_op(elem, opcode, &model);
1484 	if (!op) {
1485 		LOG_DBG("No OpCode 0x%08x for elem 0x%02x", opcode, elem->rt->addr);
1486 		return ACCESS_STATUS_WRONG_OPCODE;
1487 	}
1488 
1489 	if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
1490 		LOG_ERR("Wrong key");
1491 		return ACCESS_STATUS_WRONG_KEY;
1492 	}
1493 
1494 	if (!model_has_dst(model, ctx->recv_dst, ctx->uuid)) {
1495 		LOG_ERR("Invalid address 0x%02x", ctx->recv_dst);
1496 		return ACCESS_STATUS_INVALID_ADDRESS;
1497 	}
1498 
1499 	if ((op->len >= 0) && (buf->len < (size_t)op->len)) {
1500 		LOG_ERR("Too short message for OpCode 0x%08x", opcode);
1501 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1502 	} else if ((op->len < 0) && (buf->len != (size_t)(-op->len))) {
1503 		LOG_ERR("Invalid message size for OpCode 0x%08x", opcode);
1504 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1505 	}
1506 
1507 	if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED)) {
1508 		ctx->rnd_delay = true;
1509 	}
1510 
1511 	net_buf_simple_save(buf, &state);
1512 	err = op->func(model, ctx, buf);
1513 	net_buf_simple_restore(buf, &state);
1514 
1515 	if (err) {
1516 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1517 	}
1518 	return ACCESS_STATUS_SUCCESS;
1519 }
1520 
bt_mesh_model_recv(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1521 int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
1522 {
1523 	int err = ACCESS_STATUS_SUCCESS;
1524 	uint32_t opcode;
1525 	uint16_t index;
1526 
1527 	LOG_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", ctx->app_idx, ctx->addr,
1528 		ctx->recv_dst);
1529 	LOG_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
1530 
1531 	if (IS_ENABLED(CONFIG_BT_TESTING)) {
1532 		bt_test_mesh_model_recv(ctx->addr, ctx->recv_dst, buf->data,
1533 					buf->len);
1534 	}
1535 
1536 	if (get_opcode(buf, &opcode) < 0) {
1537 		LOG_WRN("Unable to decode OpCode");
1538 		return ACCESS_STATUS_WRONG_OPCODE;
1539 	}
1540 
1541 	LOG_DBG("OpCode 0x%08x", opcode);
1542 
1543 	if (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
1544 		index = ctx->recv_dst - dev_comp->elem[0].rt->addr;
1545 
1546 		if (index >= dev_comp->elem_count) {
1547 			LOG_ERR("Invalid address 0x%02x", ctx->recv_dst);
1548 			err = ACCESS_STATUS_INVALID_ADDRESS;
1549 		} else {
1550 			const struct bt_mesh_elem *elem = &dev_comp->elem[index];
1551 
1552 			err = element_model_recv(ctx, buf, elem, opcode);
1553 		}
1554 	} else {
1555 		for (index = 0; index < dev_comp->elem_count; index++) {
1556 			const struct bt_mesh_elem *elem = &dev_comp->elem[index];
1557 
1558 			(void)element_model_recv(ctx, buf, elem, opcode);
1559 		}
1560 	}
1561 
1562 	if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
1563 		msg_cb(opcode, ctx, buf);
1564 	}
1565 
1566 	return err;
1567 }
1568 
bt_mesh_model_send(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * msg,const struct bt_mesh_send_cb * cb,void * cb_data)1569 int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
1570 		       struct net_buf_simple *msg,
1571 		       const struct bt_mesh_send_cb *cb, void *cb_data)
1572 {
1573 	if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_SRV) && bt_mesh_op_agg_srv_accept(ctx, msg)) {
1574 		return bt_mesh_op_agg_srv_send(model, msg);
1575 	} else if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) && bt_mesh_op_agg_cli_accept(ctx, msg)) {
1576 		return bt_mesh_op_agg_cli_send(model, msg);
1577 	}
1578 
1579 	if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
1580 		LOG_ERR("Model not bound to AppKey 0x%04x", ctx->app_idx);
1581 		return -EINVAL;
1582 	}
1583 
1584 #if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
1585 	/* No sense to use delayable message for unicast loopback. */
1586 	if (ctx->rnd_delay &&
1587 	    !(bt_mesh_has_addr(ctx->addr) && BT_MESH_ADDR_IS_UNICAST(ctx->addr))) {
1588 		return bt_mesh_delayable_msg_manage(ctx, msg, bt_mesh_model_elem(model)->rt->addr,
1589 						    cb, cb_data);
1590 	}
1591 #endif
1592 
1593 	return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->rt->addr, cb, cb_data);
1594 }
1595 
bt_mesh_model_publish(const struct bt_mesh_model * model)1596 int bt_mesh_model_publish(const struct bt_mesh_model *model)
1597 {
1598 	struct bt_mesh_model_pub *pub = model->pub;
1599 
1600 	if (!pub) {
1601 		return -ENOTSUP;
1602 	}
1603 
1604 	LOG_DBG("");
1605 
1606 	if (pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1607 		return -EADDRNOTAVAIL;
1608 	}
1609 
1610 	if (!pub->msg || !pub->msg->len) {
1611 		LOG_ERR("No publication message");
1612 		return -EINVAL;
1613 	}
1614 
1615 	if (pub->msg->len + BT_MESH_MIC_SHORT > BT_MESH_TX_SDU_MAX) {
1616 		LOG_ERR("Message does not fit maximum SDU size");
1617 		return -EMSGSIZE;
1618 	}
1619 
1620 	if (pub->count) {
1621 		LOG_WRN("Clearing publish retransmit timer");
1622 	}
1623 
1624 	/* Account for initial transmission */
1625 	pub->count = BT_MESH_PUB_MSG_TOTAL(pub);
1626 	pub->period_start = k_uptime_get_32();
1627 
1628 	LOG_DBG("Publish Retransmit Count %u Interval %ums", pub->count,
1629 		BT_MESH_PUB_TRANSMIT_INT(pub->retransmit));
1630 
1631 	/* Delay the publication for longer time when the publication is triggered manually (section
1632 	 * 3.7.3.1):
1633 	 *
1634 	 * When the publication of a message is the result of a power-up, a state transition
1635 	 * progress update, or completion of a state transition, multiple nodes may be reporting the
1636 	 * state change at the same time. To reduce the probability of a message collision, these
1637 	 * messages should be sent with a random delay between 20 and 500 milliseconds.
1638 	 */
1639 	if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_LONG)) {
1640 		return 0;
1641 	}
1642 
1643 	k_work_reschedule(&pub->timer, K_NO_WAIT);
1644 
1645 	return 0;
1646 }
1647 
bt_mesh_model_find_vnd(const struct bt_mesh_elem * elem,uint16_t company,uint16_t id)1648 const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
1649 					     uint16_t company, uint16_t id)
1650 {
1651 	uint8_t i;
1652 
1653 	for (i = 0U; i < elem->vnd_model_count; i++) {
1654 		if (elem->vnd_models[i].vnd.company == company &&
1655 		    elem->vnd_models[i].vnd.id == id) {
1656 			return &elem->vnd_models[i];
1657 		}
1658 	}
1659 
1660 	return NULL;
1661 }
1662 
bt_mesh_model_find(const struct bt_mesh_elem * elem,uint16_t id)1663 const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
1664 					 uint16_t id)
1665 {
1666 	uint8_t i;
1667 
1668 	for (i = 0U; i < elem->model_count; i++) {
1669 		if (elem->models[i].id == id) {
1670 			return &elem->models[i];
1671 		}
1672 	}
1673 
1674 	return NULL;
1675 }
1676 
bt_mesh_comp_get(void)1677 const struct bt_mesh_comp *bt_mesh_comp_get(void)
1678 {
1679 	return dev_comp;
1680 }
1681 
bt_mesh_model_extensions_walk(const struct bt_mesh_model * model,enum bt_mesh_walk (* cb)(const struct bt_mesh_model * mod,void * user_data),void * user_data)1682 void bt_mesh_model_extensions_walk(const struct bt_mesh_model *model,
1683 				   enum bt_mesh_walk (*cb)(const struct bt_mesh_model *mod,
1684 							   void *user_data),
1685 				   void *user_data)
1686 {
1687 #ifndef CONFIG_BT_MESH_MODEL_EXTENSIONS
1688 	(void)cb(model, user_data);
1689 	return;
1690 #else
1691 	const struct bt_mesh_model *it;
1692 
1693 	if (cb(model, user_data) == BT_MESH_WALK_STOP || !model->rt->next) {
1694 		return;
1695 	}
1696 
1697 	/* List is circular. Step through all models until we reach the start: */
1698 	for (it = model->rt->next; it != model; it = it->rt->next) {
1699 		if (cb(it, user_data) == BT_MESH_WALK_STOP) {
1700 			return;
1701 		}
1702 	}
1703 #endif
1704 }
1705 
1706 #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS
1707 /* For vendor models, determine the offset within the model relation list
1708  * by counting the number of standard SIG models in the associated element.
1709  */
get_sig_offset(const struct bt_mesh_model * mod)1710 static uint8_t get_sig_offset(const struct bt_mesh_model *mod)
1711 {
1712 	const struct bt_mesh_elem *elem = bt_mesh_model_elem(mod);
1713 	uint8_t i;
1714 
1715 	for (i = 0U; i < elem->vnd_model_count; i++) {
1716 		if (&elem->vnd_models[i] == mod) {
1717 			return elem->model_count;
1718 		}
1719 	}
1720 	return 0;
1721 }
1722 
mod_rel_register(const struct bt_mesh_model * base,const struct bt_mesh_model * ext,uint8_t type)1723 static int mod_rel_register(const struct bt_mesh_model *base,
1724 				 const struct bt_mesh_model *ext,
1725 				 uint8_t type)
1726 {
1727 	LOG_DBG("");
1728 	struct mod_relation extension = {
1729 		base->rt->elem_idx,
1730 		base->rt->mod_idx + get_sig_offset(base),
1731 		ext->rt->elem_idx,
1732 		ext->rt->mod_idx + get_sig_offset(ext),
1733 		type,
1734 	};
1735 	int i;
1736 
1737 	for (i = 0; i < ARRAY_SIZE(mod_rel_list); i++) {
1738 		if (mod_rel_list[i].elem_base == 0 &&
1739 			mod_rel_list[i].idx_base == 0 &&
1740 			mod_rel_list[i].elem_ext == 0 &&
1741 			mod_rel_list[i].idx_ext == 0) {
1742 			memcpy(&mod_rel_list[i], &extension,
1743 			       sizeof(extension));
1744 			return 0;
1745 		}
1746 	}
1747 	LOG_ERR("Failed to extend");
1748 	return -ENOMEM;
1749 }
1750 
bt_mesh_model_extend(const struct bt_mesh_model * extending_mod,const struct bt_mesh_model * base_mod)1751 int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod,
1752 			 const struct bt_mesh_model *base_mod)
1753 {
1754 	const struct bt_mesh_model *a = extending_mod;
1755 	const struct bt_mesh_model *b = base_mod;
1756 	const struct bt_mesh_model *a_next = a->rt->next;
1757 	const struct bt_mesh_model *b_next = b->rt->next;
1758 	const struct bt_mesh_model *it;
1759 
1760 	base_mod->rt->flags |= BT_MESH_MOD_EXTENDED;
1761 
1762 	if (a == b) {
1763 		return 0;
1764 	}
1765 
1766 	/* Check if a's list contains b */
1767 	for (it = a; (it != NULL) && (it->rt->next != a); it = it->rt->next) {
1768 		if (it == b) {
1769 			goto register_extension;
1770 		}
1771 	}
1772 
1773 	/* Merge lists */
1774 	if (a_next) {
1775 		b->rt->next = a_next;
1776 	} else {
1777 		b->rt->next = a;
1778 	}
1779 
1780 	if (b_next) {
1781 		a->rt->next = b_next;
1782 	} else {
1783 		a->rt->next = b;
1784 	}
1785 
1786 register_extension:
1787 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1788 		return mod_rel_register(base_mod, extending_mod, RELATION_TYPE_EXT);
1789 	}
1790 
1791 	return 0;
1792 }
1793 
bt_mesh_model_correspond(const struct bt_mesh_model * corresponding_mod,const struct bt_mesh_model * base_mod)1794 int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod,
1795 			     const struct bt_mesh_model *base_mod)
1796 {
1797 	int i, err;
1798 	uint8_t cor_id = 0;
1799 
1800 	if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1801 		return -ENOTSUP;
1802 	}
1803 
1804 	uint8_t base_offset = get_sig_offset(base_mod);
1805 	uint8_t corresponding_offset = get_sig_offset(corresponding_mod);
1806 
1807 	MOD_REL_LIST_FOR_EACH(i) {
1808 		if (mod_rel_list[i].type < RELATION_TYPE_EXT &&
1809 		    mod_rel_list[i].type > cor_id) {
1810 			cor_id = mod_rel_list[i].type;
1811 		}
1812 
1813 		if ((IS_MOD_BASE(base_mod, i, base_offset) ||
1814 		     IS_MOD_EXTENSION(base_mod, i, base_offset) ||
1815 		     IS_MOD_BASE(corresponding_mod, i, corresponding_offset) ||
1816 		     IS_MOD_EXTENSION(corresponding_mod, i, corresponding_offset)) &&
1817 		    mod_rel_list[i].type < RELATION_TYPE_EXT) {
1818 			return mod_rel_register(base_mod, corresponding_mod, mod_rel_list[i].type);
1819 		}
1820 	}
1821 	err = mod_rel_register(base_mod, corresponding_mod, cor_id);
1822 	if (err) {
1823 		return err;
1824 	}
1825 	return 0;
1826 }
1827 #endif /* CONFIG_BT_MESH_MODEL_EXTENSIONS */
1828 
bt_mesh_model_is_extended(const struct bt_mesh_model * model)1829 bool bt_mesh_model_is_extended(const struct bt_mesh_model *model)
1830 {
1831 	return model->rt->flags & BT_MESH_MOD_EXTENDED;
1832 }
1833 
mod_set_bind(const struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1834 static int mod_set_bind(const struct bt_mesh_model *mod, size_t len_rd,
1835 			settings_read_cb read_cb, void *cb_arg)
1836 {
1837 	ssize_t len;
1838 	int i;
1839 
1840 	/* Start with empty array regardless of cleared or set value */
1841 	for (i = 0; i < mod->keys_cnt; i++) {
1842 		mod->keys[i] = BT_MESH_KEY_UNUSED;
1843 	}
1844 
1845 	if (len_rd == 0) {
1846 		LOG_DBG("Cleared bindings for model");
1847 		return 0;
1848 	}
1849 
1850 	len = read_cb(cb_arg, mod->keys, mod->keys_cnt * sizeof(mod->keys[0]));
1851 	if (len < 0) {
1852 		LOG_ERR("Failed to read value (err %zd)", len);
1853 		return len;
1854 	}
1855 
1856 	LOG_HEXDUMP_DBG(mod->keys, len, "val");
1857 
1858 	LOG_DBG("Decoded %zu bound keys for model", len / sizeof(mod->keys[0]));
1859 	return 0;
1860 }
1861 
mod_set_sub(const struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1862 static int mod_set_sub(const struct bt_mesh_model *mod, size_t len_rd,
1863 		       settings_read_cb read_cb, void *cb_arg)
1864 {
1865 	size_t size = mod->groups_cnt * sizeof(mod->groups[0]);
1866 	ssize_t len;
1867 
1868 	/* Start with empty array regardless of cleared or set value */
1869 	(void)memset(mod->groups, 0, size);
1870 
1871 	if (len_rd == 0) {
1872 		LOG_DBG("Cleared subscriptions for model");
1873 		return 0;
1874 	}
1875 
1876 	len = read_cb(cb_arg, mod->groups, size);
1877 	if (len < 0) {
1878 		LOG_ERR("Failed to read value (err %zd)", len);
1879 		return len;
1880 	}
1881 
1882 	LOG_HEXDUMP_DBG(mod->groups, len, "val");
1883 
1884 	LOG_DBG("Decoded %zu subscribed group addresses for model", len / sizeof(mod->groups[0]));
1885 
1886 #if !IS_ENABLED(CONFIG_BT_MESH_LABEL_NO_RECOVER) && (CONFIG_BT_MESH_LABEL_COUNT > 0)
1887 	/* If uuids[0] is NULL, then either the model is not subscribed to virtual addresses or
1888 	 * uuids are not yet recovered.
1889 	 */
1890 	if (mod->uuids[0] == NULL) {
1891 		int i, j = 0;
1892 
1893 		for (i = 0; i < mod->groups_cnt && j < CONFIG_BT_MESH_LABEL_COUNT; i++) {
1894 			if (BT_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) {
1895 				/* Recover from implementation where uuid was not stored for
1896 				 * virtual address. It is safe to pick first matched label because
1897 				 * previously the stack wasn't able to store virtual addresses with
1898 				 * collisions.
1899 				 */
1900 				mod->uuids[j] = bt_mesh_va_uuid_get(mod->groups[i], NULL, NULL);
1901 				j++;
1902 			}
1903 		}
1904 	}
1905 #endif
1906 	return 0;
1907 }
1908 
mod_set_sub_va(const struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1909 static int mod_set_sub_va(const struct bt_mesh_model *mod, size_t len_rd,
1910 			  settings_read_cb read_cb, void *cb_arg)
1911 {
1912 #if CONFIG_BT_MESH_LABEL_COUNT > 0
1913 	uint16_t uuidxs[CONFIG_BT_MESH_LABEL_COUNT];
1914 	ssize_t len;
1915 	int i;
1916 	int count;
1917 
1918 	/* Start with empty array regardless of cleared or set value */
1919 	(void)memset(mod->uuids, 0, CONFIG_BT_MESH_LABEL_COUNT * sizeof(mod->uuids[0]));
1920 
1921 	if (len_rd == 0) {
1922 		LOG_DBG("Cleared subscriptions for model");
1923 		return 0;
1924 	}
1925 
1926 	len = read_cb(cb_arg, uuidxs, sizeof(uuidxs));
1927 	if (len < 0) {
1928 		LOG_ERR("Failed to read value (err %zd)", len);
1929 		return len;
1930 	}
1931 
1932 	LOG_HEXDUMP_DBG(uuidxs, len, "val");
1933 
1934 	for (i = 0, count = 0; i < len / sizeof(uint16_t); i++) {
1935 		mod->uuids[count] = bt_mesh_va_get_uuid_by_idx(uuidxs[i]);
1936 		if (mod->uuids[count] != NULL) {
1937 			count++;
1938 		}
1939 	}
1940 
1941 	LOG_DBG("Decoded %zu subscribed virtual addresses for model", count);
1942 #endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */
1943 	return 0;
1944 }
1945 
mod_set_pub(const struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1946 static int mod_set_pub(const struct bt_mesh_model *mod, size_t len_rd,
1947 		       settings_read_cb read_cb, void *cb_arg)
1948 {
1949 	struct mod_pub_val pub;
1950 	int err;
1951 
1952 	if (!mod->pub) {
1953 		LOG_WRN("Model has no publication context!");
1954 		return -EINVAL;
1955 	}
1956 
1957 	if (len_rd == 0) {
1958 		mod->pub->addr = BT_MESH_ADDR_UNASSIGNED;
1959 		mod->pub->key = 0U;
1960 		mod->pub->cred = 0U;
1961 		mod->pub->ttl = 0U;
1962 		mod->pub->period = 0U;
1963 		mod->pub->retransmit = 0U;
1964 		mod->pub->count = 0U;
1965 		mod->pub->uuid = NULL;
1966 
1967 		LOG_DBG("Cleared publication for model");
1968 		return 0;
1969 	}
1970 
1971 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
1972 		return 0;
1973 	}
1974 
1975 	if (!IS_ENABLED(CONFIG_BT_MESH_LABEL_NO_RECOVER)) {
1976 		err = bt_mesh_settings_set(read_cb, cb_arg, &pub, sizeof(pub.base));
1977 		if (!err) {
1978 			/* Recover from implementation where uuid was not stored for virtual
1979 			 * address. It is safe to pick first matched label because previously the
1980 			 * stack wasn't able to store virtual addresses with collisions.
1981 			 */
1982 			if (BT_MESH_ADDR_IS_VIRTUAL(pub.base.addr)) {
1983 				mod->pub->uuid = bt_mesh_va_uuid_get(pub.base.addr, NULL, NULL);
1984 			}
1985 
1986 			goto pub_base_set;
1987 		}
1988 	}
1989 
1990 	err = bt_mesh_settings_set(read_cb, cb_arg, &pub, sizeof(pub));
1991 	if (err) {
1992 		LOG_ERR("Failed to set \'model-pub\'");
1993 		return err;
1994 	}
1995 
1996 	if (BT_MESH_ADDR_IS_VIRTUAL(pub.base.addr)) {
1997 		mod->pub->uuid = bt_mesh_va_get_uuid_by_idx(pub.uuidx);
1998 	}
1999 
2000 pub_base_set:
2001 	mod->pub->addr = pub.base.addr;
2002 	mod->pub->key = pub.base.key;
2003 	mod->pub->cred = pub.base.cred;
2004 	mod->pub->ttl = pub.base.ttl;
2005 	mod->pub->period = pub.base.period;
2006 	mod->pub->retransmit = pub.base.retransmit;
2007 	mod->pub->period_div = pub.base.period_div;
2008 	mod->pub->count = 0U;
2009 
2010 	LOG_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", pub.base.addr,
2011 		pub.base.key);
2012 
2013 	return 0;
2014 }
2015 
mod_data_set(const struct bt_mesh_model * mod,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2016 static int mod_data_set(const struct bt_mesh_model *mod,
2017 			const char *name, size_t len_rd,
2018 			settings_read_cb read_cb, void *cb_arg)
2019 {
2020 	const char *next;
2021 
2022 	settings_name_next(name, &next);
2023 
2024 	if (mod->cb && mod->cb->settings_set) {
2025 		return mod->cb->settings_set(mod, next, len_rd,
2026 			read_cb, cb_arg);
2027 	}
2028 
2029 	return 0;
2030 }
2031 
mod_set(bool vnd,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2032 static int mod_set(bool vnd, const char *name, size_t len_rd,
2033 		   settings_read_cb read_cb, void *cb_arg)
2034 {
2035 	const struct bt_mesh_model *mod;
2036 	uint8_t elem_idx, mod_idx;
2037 	uint16_t mod_key;
2038 	int len;
2039 	const char *next;
2040 
2041 	if (!name) {
2042 		LOG_ERR("Insufficient number of arguments");
2043 		return -ENOENT;
2044 	}
2045 
2046 	mod_key = strtol(name, NULL, 16);
2047 	elem_idx = mod_key >> 8;
2048 	mod_idx = mod_key;
2049 
2050 	LOG_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u", mod_key, elem_idx, mod_idx);
2051 
2052 	mod = bt_mesh_model_get(vnd, elem_idx, mod_idx);
2053 	if (!mod) {
2054 		LOG_ERR("Failed to get model for elem_idx %u mod_idx %u", elem_idx, mod_idx);
2055 		return -ENOENT;
2056 	}
2057 
2058 	len = settings_name_next(name, &next);
2059 	if (!next) {
2060 		LOG_ERR("Insufficient number of arguments");
2061 		return -ENOENT;
2062 	}
2063 
2064 	/* `len` contains length of model id string representation. Call settings_name_next() again
2065 	 * to get length of `next`.
2066 	 */
2067 	switch (settings_name_next(next, NULL)) {
2068 	case 4:
2069 		if (!strncmp(next, "bind", 4)) {
2070 			return mod_set_bind(mod, len_rd, read_cb, cb_arg);
2071 		} else if (!strncmp(next, "subv", 4)) {
2072 			return mod_set_sub_va(mod, len_rd, read_cb, cb_arg);
2073 		} else if (!strncmp(next, "data", 4)) {
2074 			return mod_data_set(mod, next, len_rd, read_cb, cb_arg);
2075 		}
2076 
2077 		break;
2078 	case 3:
2079 		if (!strncmp(next, "sub", 3)) {
2080 			return mod_set_sub(mod, len_rd, read_cb, cb_arg);
2081 		} else if (!strncmp(next, "pub", 3)) {
2082 			return mod_set_pub(mod, len_rd, read_cb, cb_arg);
2083 		}
2084 
2085 		break;
2086 	default:
2087 		break;
2088 	}
2089 
2090 	LOG_WRN("Unknown module key %s", next);
2091 	return -ENOENT;
2092 }
2093 
sig_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2094 static int sig_mod_set(const char *name, size_t len_rd,
2095 		       settings_read_cb read_cb, void *cb_arg)
2096 {
2097 	return mod_set(false, name, len_rd, read_cb, cb_arg);
2098 }
2099 
2100 BT_MESH_SETTINGS_DEFINE(sig_mod, "s", sig_mod_set);
2101 
vnd_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2102 static int vnd_mod_set(const char *name, size_t len_rd,
2103 		       settings_read_cb read_cb, void *cb_arg)
2104 {
2105 	return mod_set(true, name, len_rd, read_cb, cb_arg);
2106 }
2107 
2108 BT_MESH_SETTINGS_DEFINE(vnd_mod, "v", vnd_mod_set);
2109 
comp_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2110 static int comp_set(const char *name, size_t len_rd, settings_read_cb read_cb,
2111 		    void *cb_arg)
2112 {
2113 	/* Only need to know that the entry exists. Will load the contents on
2114 	 * demand.
2115 	 */
2116 	if (len_rd > 0) {
2117 		atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
2118 	}
2119 
2120 	return 0;
2121 }
2122 BT_MESH_SETTINGS_DEFINE(comp, "cmp", comp_set);
2123 
encode_mod_path(const struct bt_mesh_model * mod,bool vnd,const char * key,char * path,size_t path_len)2124 static void encode_mod_path(const struct bt_mesh_model *mod, bool vnd,
2125 			    const char *key, char *path, size_t path_len)
2126 {
2127 	uint16_t mod_key = (((uint16_t)mod->rt->elem_idx << 8) | mod->rt->mod_idx);
2128 
2129 	if (vnd) {
2130 		snprintk(path, path_len, "bt/mesh/v/%x/%s", mod_key, key);
2131 	} else {
2132 		snprintk(path, path_len, "bt/mesh/s/%x/%s", mod_key, key);
2133 	}
2134 }
2135 
store_pending_mod_bind(const struct bt_mesh_model * mod,bool vnd)2136 static void store_pending_mod_bind(const struct bt_mesh_model *mod, bool vnd)
2137 {
2138 	uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
2139 	char path[20];
2140 	int i, count, err;
2141 
2142 	for (i = 0, count = 0; i < mod->keys_cnt; i++) {
2143 		if (mod->keys[i] != BT_MESH_KEY_UNUSED) {
2144 			keys[count++] = mod->keys[i];
2145 			LOG_DBG("model key 0x%04x", mod->keys[i]);
2146 		}
2147 	}
2148 
2149 	encode_mod_path(mod, vnd, "bind", path, sizeof(path));
2150 
2151 	if (count) {
2152 		err = settings_save_one(path, keys, count * sizeof(keys[0]));
2153 	} else {
2154 		err = settings_delete(path);
2155 	}
2156 
2157 	if (err) {
2158 		LOG_ERR("Failed to store %s value", path);
2159 	} else {
2160 		LOG_DBG("Stored %s value", path);
2161 	}
2162 }
2163 
store_pending_mod_sub(const struct bt_mesh_model * mod,bool vnd)2164 static void store_pending_mod_sub(const struct bt_mesh_model *mod, bool vnd)
2165 {
2166 	uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
2167 	char path[20];
2168 	int i, count, err;
2169 
2170 	for (i = 0, count = 0; i < mod->groups_cnt; i++) {
2171 		if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
2172 			groups[count++] = mod->groups[i];
2173 		}
2174 	}
2175 
2176 	encode_mod_path(mod, vnd, "sub", path, sizeof(path));
2177 
2178 	if (count) {
2179 		err = settings_save_one(path, groups, count * sizeof(groups[0]));
2180 	} else {
2181 		err = settings_delete(path);
2182 	}
2183 
2184 	if (err) {
2185 		LOG_ERR("Failed to store %s value", path);
2186 	} else {
2187 		LOG_DBG("Stored %s value", path);
2188 	}
2189 }
2190 
store_pending_mod_sub_va(const struct bt_mesh_model * mod,bool vnd)2191 static void store_pending_mod_sub_va(const struct bt_mesh_model *mod, bool vnd)
2192 {
2193 #if CONFIG_BT_MESH_LABEL_COUNT > 0
2194 	uint16_t uuidxs[CONFIG_BT_MESH_LABEL_COUNT];
2195 	char path[20];
2196 	int i, count, err;
2197 
2198 	for (i = 0, count = 0; i < CONFIG_BT_MESH_LABEL_COUNT; i++) {
2199 		if (mod->uuids[i] != NULL) {
2200 			err = bt_mesh_va_get_idx_by_uuid(mod->uuids[i], &uuidxs[count]);
2201 			if (!err) {
2202 				count++;
2203 			}
2204 		}
2205 	}
2206 
2207 	encode_mod_path(mod, vnd, "subv", path, sizeof(path));
2208 
2209 	if (count) {
2210 		err = settings_save_one(path, uuidxs, count * sizeof(uuidxs[0]));
2211 	} else {
2212 		err = settings_delete(path);
2213 	}
2214 
2215 	if (err) {
2216 		LOG_ERR("Failed to store %s value", path);
2217 	} else {
2218 		LOG_DBG("Stored %s value", path);
2219 	}
2220 #endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */
2221 }
2222 
store_pending_mod_pub(const struct bt_mesh_model * mod,bool vnd)2223 static void store_pending_mod_pub(const struct bt_mesh_model *mod, bool vnd)
2224 {
2225 	struct mod_pub_val pub = {0};
2226 	char path[20];
2227 	int err;
2228 
2229 	encode_mod_path(mod, vnd, "pub", path, sizeof(path));
2230 
2231 	if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
2232 		err = settings_delete(path);
2233 	} else {
2234 		pub.base.addr = mod->pub->addr;
2235 		pub.base.key = mod->pub->key;
2236 		pub.base.ttl = mod->pub->ttl;
2237 		pub.base.retransmit = mod->pub->retransmit;
2238 		pub.base.period = mod->pub->period;
2239 		pub.base.period_div = mod->pub->period_div;
2240 		pub.base.cred = mod->pub->cred;
2241 
2242 		if (BT_MESH_ADDR_IS_VIRTUAL(mod->pub->addr)) {
2243 			(void)bt_mesh_va_get_idx_by_uuid(mod->pub->uuid, &pub.uuidx);
2244 		}
2245 
2246 		err = settings_save_one(path, &pub, sizeof(pub));
2247 	}
2248 
2249 	if (err) {
2250 		LOG_ERR("Failed to store %s value", path);
2251 	} else {
2252 		LOG_DBG("Stored %s value", path);
2253 	}
2254 }
2255 
store_pending_mod(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)2256 static void store_pending_mod(const struct bt_mesh_model *mod,
2257 			      const struct bt_mesh_elem *elem, bool vnd,
2258 			      bool primary, void *user_data)
2259 {
2260 	if (!mod->rt->flags) {
2261 		return;
2262 	}
2263 
2264 	if (mod->rt->flags & BT_MESH_MOD_BIND_PENDING) {
2265 		mod->rt->flags &= ~BT_MESH_MOD_BIND_PENDING;
2266 		store_pending_mod_bind(mod, vnd);
2267 	}
2268 
2269 	if (mod->rt->flags & BT_MESH_MOD_SUB_PENDING) {
2270 		mod->rt->flags &= ~BT_MESH_MOD_SUB_PENDING;
2271 		store_pending_mod_sub(mod, vnd);
2272 		store_pending_mod_sub_va(mod, vnd);
2273 	}
2274 
2275 	if (mod->rt->flags & BT_MESH_MOD_PUB_PENDING) {
2276 		mod->rt->flags &= ~BT_MESH_MOD_PUB_PENDING;
2277 		store_pending_mod_pub(mod, vnd);
2278 	}
2279 
2280 	if (mod->rt->flags & BT_MESH_MOD_DATA_PENDING) {
2281 		mod->rt->flags &= ~BT_MESH_MOD_DATA_PENDING;
2282 		mod->cb->pending_store(mod);
2283 	}
2284 }
2285 
bt_mesh_model_pending_store(void)2286 void bt_mesh_model_pending_store(void)
2287 {
2288 	bt_mesh_model_foreach(store_pending_mod, NULL);
2289 }
2290 
bt_mesh_model_bind_store(const struct bt_mesh_model * mod)2291 void bt_mesh_model_bind_store(const struct bt_mesh_model *mod)
2292 {
2293 	mod->rt->flags |= BT_MESH_MOD_BIND_PENDING;
2294 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
2295 }
2296 
bt_mesh_model_sub_store(const struct bt_mesh_model * mod)2297 void bt_mesh_model_sub_store(const struct bt_mesh_model *mod)
2298 {
2299 	mod->rt->flags |= BT_MESH_MOD_SUB_PENDING;
2300 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
2301 }
2302 
bt_mesh_model_pub_store(const struct bt_mesh_model * mod)2303 void bt_mesh_model_pub_store(const struct bt_mesh_model *mod)
2304 {
2305 	mod->rt->flags |= BT_MESH_MOD_PUB_PENDING;
2306 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
2307 }
2308 
bt_mesh_comp_data_get_page(struct net_buf_simple * buf,size_t page,size_t offset)2309 int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t offset)
2310 {
2311 	if (page == 0 || page == 128) {
2312 		return bt_mesh_comp_data_get_page_0(buf, offset);
2313 	} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
2314 		return bt_mesh_comp_data_get_page_1(buf, offset);
2315 	} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) {
2316 		return bt_mesh_comp_data_get_page_2(buf, offset);
2317 	}
2318 
2319 	return -EINVAL;
2320 }
2321 
comp_page_0_size(void)2322 size_t comp_page_0_size(void)
2323 {
2324 	const struct bt_mesh_comp *comp;
2325 	const struct bt_mesh_elem *elem;
2326 	size_t size = 10; /* Non-variable length params of comp page 0. */
2327 
2328 	comp = bt_mesh_comp_get();
2329 
2330 	for (int i = 0; i < comp->elem_count; i++) {
2331 		elem = &comp->elem[i];
2332 		size += bt_mesh_comp_elem_size(elem);
2333 	}
2334 
2335 	return size;
2336 }
2337 
comp_page_1_size(void)2338 size_t comp_page_1_size(void)
2339 {
2340 	const struct bt_mesh_comp *comp;
2341 	size_t size = 0;
2342 
2343 	comp = bt_mesh_comp_get();
2344 
2345 	for (int i = 0; i < comp->elem_count; i++) {
2346 
2347 		size += page1_elem_size(&comp->elem[i]);
2348 	}
2349 
2350 	return size;
2351 }
2352 
comp_page_2_size(void)2353 size_t comp_page_2_size(void)
2354 {
2355 	size_t size = 0;
2356 
2357 	if (!dev_comp2) {
2358 		LOG_ERR("Composition data P2 not registered");
2359 		return size;
2360 	}
2361 
2362 	for (int i = 0; i < dev_comp2->record_cnt; i++) {
2363 		size += 8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len;
2364 	}
2365 	return size;
2366 }
2367 
bt_mesh_comp_page_size(uint8_t page)2368 size_t bt_mesh_comp_page_size(uint8_t page)
2369 {
2370 	if (page == 0 || page == 128) {
2371 		return comp_page_0_size();
2372 	} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
2373 		return comp_page_1_size();
2374 	} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) {
2375 		return comp_page_2_size();
2376 	}
2377 
2378 	return 0;
2379 }
2380 
bt_mesh_comp_store(void)2381 int bt_mesh_comp_store(void)
2382 {
2383 	NET_BUF_SIMPLE_DEFINE(buf, CONFIG_BT_MESH_COMP_PST_BUF_SIZE);
2384 	int err;
2385 
2386 	for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
2387 		size_t page_size = bt_mesh_comp_page_size(i);
2388 
2389 		if (page_size > CONFIG_BT_MESH_COMP_PST_BUF_SIZE) {
2390 			LOG_WRN("CDP%d is larger than the CDP persistence buffer. "
2391 				"Please increase the CDP persistence buffer size "
2392 				"to the required size (%d bytes)",
2393 				i, page_size);
2394 		}
2395 
2396 		net_buf_simple_reset(&buf);
2397 
2398 		err = bt_mesh_comp_data_get_page(&buf, comp_data_pages[i].page, 0);
2399 		if (err) {
2400 			LOG_ERR("Failed to read CDP%d: %d", comp_data_pages[i].page, err);
2401 			return err;
2402 		}
2403 
2404 		err = settings_save_one(comp_data_pages[i].path, buf.data, buf.len);
2405 		if (err) {
2406 			LOG_ERR("Failed to store CDP%d: %d", comp_data_pages[i].page, err);
2407 			return err;
2408 		}
2409 
2410 		LOG_DBG("Stored CDP%d", comp_data_pages[i].page);
2411 	}
2412 
2413 	return 0;
2414 }
2415 
bt_mesh_comp_change_prepare(void)2416 int bt_mesh_comp_change_prepare(void)
2417 {
2418 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
2419 		return -ENOTSUP;
2420 	}
2421 
2422 	return bt_mesh_comp_store();
2423 }
2424 
comp_data_clear(void)2425 static void comp_data_clear(void)
2426 {
2427 	int err;
2428 
2429 	for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
2430 		err = settings_delete(comp_data_pages[i].path);
2431 		if (err) {
2432 			LOG_ERR("Failed to clear CDP%d: %d", comp_data_pages[i].page,
2433 				err);
2434 		}
2435 	}
2436 
2437 	atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
2438 }
2439 
read_comp_cb(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)2440 static int read_comp_cb(const char *key, size_t len, settings_read_cb read_cb,
2441 			void *cb_arg, void *param)
2442 {
2443 	struct net_buf_simple *buf = param;
2444 
2445 	if (len > net_buf_simple_tailroom(buf)) {
2446 		return -ENOBUFS;
2447 	}
2448 
2449 	len = read_cb(cb_arg, net_buf_simple_tail(buf), len);
2450 	if (len > 0) {
2451 		net_buf_simple_add(buf, len);
2452 	}
2453 
2454 	return -EALREADY;
2455 }
2456 
bt_mesh_comp_read(struct net_buf_simple * buf,uint8_t page)2457 int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page)
2458 {
2459 	size_t original_len = buf->len;
2460 	int i;
2461 	int err;
2462 
2463 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
2464 		return -ENOTSUP;
2465 	}
2466 
2467 	for (i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
2468 		if (comp_data_pages[i].page == page) {
2469 			break;
2470 		}
2471 	}
2472 
2473 	if (i == ARRAY_SIZE(comp_data_pages)) {
2474 		return -ENOENT;
2475 	}
2476 
2477 	err = settings_load_subtree_direct(comp_data_pages[i].path, read_comp_cb, buf);
2478 
2479 	if (err) {
2480 		LOG_ERR("Failed reading composition data: %d", err);
2481 		return err;
2482 	}
2483 	if (buf->len == original_len) {
2484 		return -ENOENT;
2485 	}
2486 	return 0;
2487 }
2488 
bt_mesh_model_data_store(const struct bt_mesh_model * mod,bool vnd,const char * name,const void * data,size_t data_len)2489 int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd,
2490 			     const char *name, const void *data,
2491 			     size_t data_len)
2492 {
2493 	char path[30];
2494 	int err;
2495 
2496 	encode_mod_path(mod, vnd, "data", path, sizeof(path));
2497 	if (name) {
2498 		strcat(path, "/");
2499 		strncat(path, name, SETTINGS_MAX_DIR_DEPTH);
2500 	}
2501 
2502 	if (data_len) {
2503 		err = settings_save_one(path, data, data_len);
2504 	} else {
2505 		err = settings_delete(path);
2506 	}
2507 
2508 	if (err) {
2509 		LOG_ERR("Failed to store %s value", path);
2510 	} else {
2511 		LOG_DBG("Stored %s value", path);
2512 	}
2513 	return err;
2514 }
2515 
2516 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
metadata_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)2517 static int metadata_set(const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg)
2518 {
2519 	/* Only need to know that the entry exists. Will load the contents on
2520 	 * demand.
2521 	 */
2522 	if (len_rd > 0) {
2523 		atomic_set_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY);
2524 	}
2525 
2526 	return 0;
2527 }
2528 BT_MESH_SETTINGS_DEFINE(metadata, "metadata", metadata_set);
2529 
bt_mesh_models_metadata_store(void)2530 int bt_mesh_models_metadata_store(void)
2531 {
2532 	NET_BUF_SIMPLE_DEFINE(buf, CONFIG_BT_MESH_MODELS_METADATA_PAGE_LEN);
2533 	size_t total_size;
2534 	int err;
2535 
2536 	total_size = bt_mesh_metadata_page_0_size();
2537 	LOG_DBG("bt/mesh/metadata total %d", total_size);
2538 
2539 	net_buf_simple_init(&buf, 0);
2540 	net_buf_simple_add_le16(&buf, total_size);
2541 
2542 	err = bt_mesh_metadata_get_page_0(&buf, 0);
2543 	if (err == -E2BIG) {
2544 		LOG_ERR("Metadata too large");
2545 		return err;
2546 	}
2547 	if (err) {
2548 		LOG_ERR("Failed to read models metadata: %d", err);
2549 		return err;
2550 	}
2551 
2552 	LOG_DBG("bt/mesh/metadata len %d", buf.len);
2553 
2554 	err = settings_save_one("bt/mesh/metadata", buf.data, buf.len);
2555 	if (err) {
2556 		LOG_ERR("Failed to store models metadata: %d", err);
2557 	} else {
2558 		LOG_DBG("Stored models metadata");
2559 	}
2560 
2561 	return err;
2562 }
2563 
bt_mesh_models_metadata_read(struct net_buf_simple * buf,size_t offset)2564 int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset)
2565 {
2566 	NET_BUF_SIMPLE_DEFINE(stored_buf, CONFIG_BT_MESH_MODELS_METADATA_PAGE_LEN);
2567 	size_t original_len = buf->len;
2568 	int err;
2569 
2570 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
2571 		return -ENOTSUP;
2572 	}
2573 
2574 	net_buf_simple_init(&stored_buf, 0);
2575 
2576 	err = settings_load_subtree_direct("bt/mesh/metadata", read_comp_cb, &stored_buf);
2577 	if (err) {
2578 		LOG_ERR("Failed reading models metadata: %d", err);
2579 		return err;
2580 	}
2581 
2582 	/* First two bytes are total length */
2583 	offset += 2;
2584 
2585 	net_buf_simple_add_mem(buf, &stored_buf.data, MIN(net_buf_simple_tailroom(buf), 2));
2586 
2587 	if (offset >= stored_buf.len) {
2588 		return 0;
2589 	}
2590 
2591 	net_buf_simple_add_mem(buf, &stored_buf.data[offset],
2592 			       MIN(net_buf_simple_tailroom(buf), stored_buf.len - offset));
2593 
2594 	LOG_DBG("metadata read %d", buf->len);
2595 
2596 	if (buf->len == original_len) {
2597 		return -ENOENT;
2598 	}
2599 
2600 	return 0;
2601 }
2602 #endif
2603 
models_metadata_clear(void)2604 static void models_metadata_clear(void)
2605 {
2606 	int err;
2607 
2608 	err = settings_delete("bt/mesh/metadata");
2609 	if (err) {
2610 		LOG_ERR("Failed to clear models metadata: %d", err);
2611 	} else {
2612 		LOG_DBG("Cleared models metadata");
2613 	}
2614 
2615 	atomic_clear_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY);
2616 }
2617 
bt_mesh_comp_data_pending_clear(void)2618 void bt_mesh_comp_data_pending_clear(void)
2619 {
2620 	comp_data_clear();
2621 	models_metadata_clear();
2622 }
2623 
bt_mesh_comp_data_clear(void)2624 void bt_mesh_comp_data_clear(void)
2625 {
2626 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_COMP_PENDING);
2627 }
2628 
bt_mesh_models_metadata_change_prepare(void)2629 int bt_mesh_models_metadata_change_prepare(void)
2630 {
2631 #if IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
2632 	return bt_mesh_models_metadata_store();
2633 #else
2634 	return -ENOTSUP;
2635 #endif
2636 }
2637 
commit_mod(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)2638 static void commit_mod(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem,
2639 		       bool vnd, bool primary, void *user_data)
2640 {
2641 	if (mod->pub && mod->pub->update &&
2642 	    mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
2643 		int32_t ms = bt_mesh_model_pub_period_get(mod);
2644 
2645 		if (ms > 0) {
2646 			/* Delay the first publication after power-up for longer time (section
2647 			 * 3.7.3.1):
2648 			 *
2649 			 * When the publication of a message is the result of a power-up, a state
2650 			 * transition progress update, or completion of a state transition, multiple
2651 			 * nodes may be reporting the state change at the same time. To reduce the
2652 			 * probability of a message collision, these messages should be sent with a
2653 			 * random delay between 20 and 500 milliseconds.
2654 			 */
2655 			uint16_t random;
2656 
2657 			random = !!mod->pub->delayable ? pub_delay_get(RANDOM_DELAY_LONG) : 0;
2658 
2659 			LOG_DBG("Starting publish timer (period %u ms, delay %u ms)", ms, random);
2660 			k_work_schedule(&mod->pub->timer, K_MSEC(ms + random));
2661 		}
2662 	}
2663 
2664 	if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
2665 		return;
2666 	}
2667 
2668 	for (int i = 0; i < mod->groups_cnt; i++) {
2669 		if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
2670 			bt_mesh_lpn_group_add(mod->groups[i]);
2671 		}
2672 	}
2673 }
2674 
bt_mesh_model_settings_commit(void)2675 void bt_mesh_model_settings_commit(void)
2676 {
2677 	bt_mesh_model_foreach(commit_mod, NULL);
2678 }
2679 
bt_mesh_model_data_store_schedule(const struct bt_mesh_model * mod)2680 void bt_mesh_model_data_store_schedule(const struct bt_mesh_model *mod)
2681 {
2682 	mod->rt->flags |= BT_MESH_MOD_DATA_PENDING;
2683 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
2684 }
2685 
bt_mesh_comp_parse_page(struct net_buf_simple * buf)2686 uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf)
2687 {
2688 	uint8_t page = net_buf_simple_pull_u8(buf);
2689 
2690 	if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) &&
2691 	    (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
2692 	     IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
2693 		page = 130U;
2694 	} else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) &&
2695 		   (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
2696 		    IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
2697 		page = 129U;
2698 	} else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
2699 				    IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
2700 		page = 128U;
2701 	} else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) {
2702 		page = 2U;
2703 	} else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
2704 		page = 1U;
2705 	} else if (page != 0U) {
2706 		LOG_DBG("Composition page %u not available", page);
2707 		page = 0U;
2708 	}
2709 
2710 	return page;
2711 }
2712 
bt_mesh_access_init(void)2713 void bt_mesh_access_init(void)
2714 {
2715 #if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
2716 	bt_mesh_delayable_msg_init();
2717 #endif
2718 }
2719 
bt_mesh_access_suspend(void)2720 void bt_mesh_access_suspend(void)
2721 {
2722 #if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
2723 	bt_mesh_delayable_msg_stop();
2724 #endif
2725 }
2726 
bt_mesh_access_reset(void)2727 void bt_mesh_access_reset(void)
2728 {
2729 #if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
2730 	bt_mesh_delayable_msg_stop();
2731 #endif
2732 }
2733