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 "adv.h"
23 #include "net.h"
24 #include "lpn.h"
25 #include "transport.h"
26 #include "access.h"
27 #include "foundation.h"
28 #include "op_agg.h"
29 #include "settings.h"
30 
31 #define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL
32 #include <zephyr/logging/log.h>
33 LOG_MODULE_REGISTER(bt_mesh_access);
34 
35 /* Model publication information for persistent storage. */
36 struct mod_pub_val {
37 	uint16_t addr;
38 	uint16_t key;
39 	uint8_t  ttl;
40 	uint8_t  retransmit;
41 	uint8_t  period;
42 	uint8_t  period_div:4,
43 		 cred:1;
44 };
45 
46 struct comp_foreach_model_arg {
47 	struct net_buf_simple *buf;
48 	size_t *offset;
49 };
50 
51 static const struct bt_mesh_comp *dev_comp;
52 static uint16_t dev_primary_addr;
53 static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
54 
55 /* Structure containing information about model extension */
56 struct mod_relation {
57 	/** Element that composition data base model belongs to. */
58 	uint8_t elem_base;
59 	/** Index of composition data base model in its element. */
60 	uint8_t idx_base;
61 	/** Element that composition data extension model belongs to. */
62 	uint8_t elem_ext;
63 	/** Index of composition data extension model in its element. */
64 	uint8_t idx_ext;
65 	/** Type of relation; value in range 0x00-0xFE marks correspondence
66 	 * and equals to Correspondence ID; value 0xFF marks extension
67 	 */
68 	uint8_t type;
69 };
70 
71 #ifdef CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE
72 #define MOD_REL_LIST_SIZE CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE
73 #else
74 #define MOD_REL_LIST_SIZE 0
75 #endif
76 
77 /* List of all existing extension relations between models */
78 static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE];
79 
80 #define MOD_REL_LIST_FOR_EACH(idx) \
81 	for ((idx) = 0; \
82 		(idx) < ARRAY_SIZE(mod_rel_list) && \
83 		!(mod_rel_list[(idx)].elem_base == 0 && \
84 		  mod_rel_list[(idx)].idx_base == 0 && \
85 		  mod_rel_list[(idx)].elem_ext == 0 && \
86 		  mod_rel_list[(idx)].idx_ext == 0); \
87 		 (idx)++)
88 
89 #define IS_MOD_BASE(mod, idx) \
90 	(mod_rel_list[(idx)].elem_base == (mod)->elem_idx && \
91 	 mod_rel_list[(idx)].idx_base == (mod)->mod_idx &&   \
92 	 !(mod_rel_list[(idx)].elem_ext != (mod)->elem_idx && \
93 	   mod_rel_list[(idx)].idx_ext != (mod)->mod_idx))
94 
95 #define IS_MOD_EXTENSION(mod, idx) \
96 	 (mod_rel_list[(idx)].elem_ext == (mod)->elem_idx && \
97 	  mod_rel_list[(idx)].idx_ext == (mod)->mod_idx &&   \
98 	  !(mod_rel_list[(idx)].elem_base != (mod)->elem_idx && \
99 	    mod_rel_list[(idx)].idx_base != (mod)->mod_idx))
100 
101 #define RELATION_TYPE_EXT 0xFF
102 
bt_mesh_model_foreach(void (* func)(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data),void * user_data)103 void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
104 					struct bt_mesh_elem *elem,
105 					bool vnd, bool primary,
106 					void *user_data),
107 			   void *user_data)
108 {
109 	int i, j;
110 
111 	for (i = 0; i < dev_comp->elem_count; i++) {
112 		struct bt_mesh_elem *elem = &dev_comp->elem[i];
113 
114 		for (j = 0; j < elem->model_count; j++) {
115 			struct bt_mesh_model *model = &elem->models[j];
116 
117 			func(model, elem, false, i == 0, user_data);
118 		}
119 
120 		for (j = 0; j < elem->vnd_model_count; j++) {
121 			struct bt_mesh_model *model = &elem->vnd_models[j];
122 
123 			func(model, elem, true, i == 0, user_data);
124 		}
125 	}
126 }
127 
bt_mesh_comp_elem_size(const struct bt_mesh_elem * elem)128 static size_t bt_mesh_comp_elem_size(const struct bt_mesh_elem *elem)
129 {
130 	return (4 + (elem->model_count * 2U) + (elem->vnd_model_count * 4U));
131 }
132 
data_buf_add_u8_offset(struct net_buf_simple * buf,uint8_t val,size_t * offset)133 static uint8_t *data_buf_add_u8_offset(struct net_buf_simple *buf,
134 				       uint8_t val, size_t *offset)
135 {
136 	if (*offset >= 1) {
137 		*offset -= 1;
138 		return NULL;
139 	}
140 
141 	return net_buf_simple_add_u8(buf, val);
142 }
143 
data_buf_add_le16_offset(struct net_buf_simple * buf,uint16_t val,size_t * offset)144 static void data_buf_add_le16_offset(struct net_buf_simple *buf,
145 				     uint16_t val, size_t *offset)
146 {
147 	if (*offset >= 2) {
148 		*offset -= 2;
149 		return;
150 	} else if (*offset == 1) {
151 		*offset -= 1;
152 		net_buf_simple_add_u8(buf, (val >> 8));
153 	} else {
154 		net_buf_simple_add_le16(buf, val);
155 	}
156 }
157 
comp_add_model(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,void * user_data)158 static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
159 			   bool vnd, void *user_data)
160 {
161 	struct comp_foreach_model_arg *arg = user_data;
162 
163 	if (vnd) {
164 		data_buf_add_le16_offset(arg->buf, mod->vnd.company, arg->offset);
165 		data_buf_add_le16_offset(arg->buf, mod->vnd.id, arg->offset);
166 	} else {
167 		data_buf_add_le16_offset(arg->buf, mod->id, arg->offset);
168 	}
169 }
170 
171 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
data_buf_add_mem_offset(struct net_buf_simple * buf,const void * mem,size_t len,size_t * offset)172 static void data_buf_add_mem_offset(struct net_buf_simple *buf,
173 				    const void *mem, size_t len,
174 				    size_t *offset)
175 {
176 	if (*offset >= len) {
177 		*offset -= len;
178 		return;
179 	} else if (*offset > 0) {
180 		net_buf_simple_add_mem(buf, ((uint8_t *)mem), (len - *offset));
181 
182 	} else {
183 		net_buf_simple_add_mem(buf, mem, len);
184 	}
185 }
186 
metadata_model_size(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd)187 static size_t metadata_model_size(struct bt_mesh_model *mod,
188 				  struct bt_mesh_elem *elem, bool vnd)
189 {
190 	const struct bt_mesh_models_metadata_entry *entry;
191 	size_t size = 0;
192 
193 	if (!mod->metadata) {
194 		return size;
195 	}
196 
197 	if (vnd) {
198 		size += sizeof(mod->vnd.company);
199 		size += sizeof(mod->vnd.id);
200 	} else {
201 		size += sizeof(mod->id);
202 	}
203 
204 	size += sizeof(uint8_t);
205 
206 	for (entry = *mod->metadata; entry && entry->len; ++entry) {
207 		size += sizeof(entry->len) + sizeof(entry->id) + entry->len;
208 	}
209 
210 	return size;
211 }
212 
bt_mesh_metadata_page_0_size(void)213 size_t bt_mesh_metadata_page_0_size(void)
214 {
215 	const struct bt_mesh_comp *comp;
216 	size_t size = 0;
217 	int i, j;
218 
219 	comp = bt_mesh_comp_get();
220 
221 	for (i = 0; i < dev_comp->elem_count; i++) {
222 		struct bt_mesh_elem *elem = &dev_comp->elem[i];
223 
224 		size += sizeof(elem->model_count) +
225 			sizeof(elem->vnd_model_count);
226 
227 		for (j = 0; j < elem->model_count; j++) {
228 			struct bt_mesh_model *model = &elem->models[j];
229 
230 			size += metadata_model_size(model, elem, false);
231 		}
232 
233 		for (j = 0; j < elem->vnd_model_count; j++) {
234 			struct bt_mesh_model *model = &elem->vnd_models[j];
235 
236 			size += metadata_model_size(model, elem, true);
237 		}
238 	}
239 
240 	return size;
241 }
242 
metadata_add_model(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,void * user_data)243 static int metadata_add_model(struct bt_mesh_model *mod,
244 			      struct bt_mesh_elem *elem, bool vnd,
245 			      void *user_data)
246 {
247 	const struct bt_mesh_models_metadata_entry *entry;
248 	struct comp_foreach_model_arg *arg = user_data;
249 	struct net_buf_simple *buf = arg->buf;
250 	size_t *offset = arg->offset;
251 	size_t model_size;
252 	uint8_t count = 0;
253 	uint8_t *count_ptr;
254 
255 	model_size = metadata_model_size(mod, elem, vnd);
256 
257 	if (*offset >= model_size) {
258 		*offset -= model_size;
259 		return 0;
260 	}
261 
262 	if (net_buf_simple_tailroom(buf) < (model_size + BT_MESH_MIC_SHORT)) {
263 		LOG_DBG("Model metadata didn't fit in the buffer");
264 		return -E2BIG;
265 	}
266 
267 	comp_add_model(mod, elem, vnd, user_data);
268 
269 	count_ptr = data_buf_add_u8_offset(buf, 0, offset);
270 
271 	if (mod->metadata) {
272 		for (entry = *mod->metadata; entry && entry->data != NULL; ++entry) {
273 			data_buf_add_le16_offset(buf, entry->len, offset);
274 			data_buf_add_le16_offset(buf, entry->id, offset);
275 			data_buf_add_mem_offset(buf, entry->data, entry->len, offset);
276 			count++;
277 		}
278 	}
279 
280 	if (count_ptr) {
281 		*count_ptr = count;
282 	}
283 
284 	return 0;
285 }
286 
bt_mesh_metadata_get_page_0(struct net_buf_simple * buf,size_t offset)287 int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset)
288 {
289 	const struct bt_mesh_comp *comp;
290 	struct comp_foreach_model_arg arg = {
291 		.buf = buf,
292 		.offset = &offset,
293 	};
294 	uint8_t *mod_count_ptr;
295 	uint8_t *vnd_count_ptr;
296 	int i, j, err;
297 
298 	comp = bt_mesh_comp_get();
299 
300 	for (i = 0; i < comp->elem_count; i++) {
301 		struct bt_mesh_elem *elem = &dev_comp->elem[i];
302 
303 		/* Check that the buffer has available tailroom for metadata item counts */
304 		if (net_buf_simple_tailroom(buf) < (((offset == 0) ? 2 : (offset == 1) ? 1 : 0)
305 				+ BT_MESH_MIC_SHORT)) {
306 			LOG_DBG("Model metadata didn't fit in the buffer");
307 			return -E2BIG;
308 		}
309 		mod_count_ptr = data_buf_add_u8_offset(buf, 0, &offset);
310 		vnd_count_ptr = data_buf_add_u8_offset(buf, 0, &offset);
311 
312 		for (j = 0; j < elem->model_count; j++) {
313 			struct bt_mesh_model *model = &elem->models[j];
314 
315 			if (!model->metadata) {
316 				continue;
317 			}
318 
319 			err = metadata_add_model(model, elem, false, &arg);
320 			if (err) {
321 				return err;
322 			}
323 
324 			if (mod_count_ptr) {
325 				(*mod_count_ptr) += 1;
326 			}
327 		}
328 
329 		for (j = 0; j < elem->vnd_model_count; j++) {
330 			struct bt_mesh_model *model = &elem->vnd_models[j];
331 
332 			if (!model->metadata) {
333 				continue;
334 			}
335 
336 			err = metadata_add_model(model, elem, true, &arg);
337 			if (err) {
338 				return err;
339 			}
340 
341 			if (vnd_count_ptr) {
342 				(*vnd_count_ptr) += 1;
343 			}
344 		}
345 	}
346 
347 	return 0;
348 }
349 #endif
350 
bt_mesh_comp_page_0_size(void)351 size_t bt_mesh_comp_page_0_size(void)
352 {
353 	const struct bt_mesh_comp *comp;
354 	const struct bt_mesh_elem *elem;
355 	size_t size = 10;
356 	int i;
357 
358 	comp = bt_mesh_comp_get();
359 
360 	for (i = 0; i < comp->elem_count; i++) {
361 		elem = &comp->elem[i];
362 		size += bt_mesh_comp_elem_size(elem);
363 	}
364 
365 	return size;
366 }
367 
comp_add_elem(struct net_buf_simple * buf,struct bt_mesh_elem * elem,size_t * offset)368 static int comp_add_elem(struct net_buf_simple *buf, 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 + BT_MESH_MIC_SHORT)) {
384 		if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) {
385 			/* Mesh Profile 1.1 Section 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->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 		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 		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(struct bt_mesh_model * mod,uint8_t * max_offset)460 static uint8_t count_mod_ext(struct bt_mesh_model *mod, uint8_t *max_offset)
461 {
462 	int i;
463 	uint8_t extensions = 0;
464 	int8_t offset, offset_record = 0;
465 
466 	MOD_REL_LIST_FOR_EACH(i) {
467 		if (IS_MOD_EXTENSION(mod, i) &&
468 		    mod_rel_list[i].type == RELATION_TYPE_EXT) {
469 			extensions++;
470 			offset = mod_rel_list[i].elem_ext -
471 				mod_rel_list[i].elem_base;
472 			if (abs(offset) > abs(offset_record)) {
473 				offset_record = offset;
474 			}
475 		}
476 	}
477 	memcpy(max_offset, &offset_record, sizeof(uint8_t));
478 	return extensions;
479 }
480 
is_cor_present(struct bt_mesh_model * mod,uint8_t * cor_id)481 static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id)
482 {
483 	int i;
484 
485 	MOD_REL_LIST_FOR_EACH(i) {
486 		if ((IS_MOD_BASE(mod, i) ||
487 		     IS_MOD_EXTENSION(mod, i)) &&
488 		     mod_rel_list[i].type < RELATION_TYPE_EXT) {
489 			memcpy(cor_id, &mod_rel_list[i].type, sizeof(uint8_t));
490 			return true;
491 		}
492 	}
493 	return false;
494 }
495 
prep_model_item_header(struct bt_mesh_model * mod,uint8_t * cor_id,uint8_t * mod_cnt,struct net_buf_simple * buf)496 static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id,
497 			    uint8_t *mod_cnt, struct net_buf_simple *buf)
498 {
499 	uint8_t ext_mod_cnt;
500 	bool cor_present;
501 	uint8_t mod_elem_info = 0;
502 	int8_t max_offset;
503 
504 	ext_mod_cnt = count_mod_ext(mod, &max_offset);
505 	cor_present = is_cor_present(mod, cor_id);
506 
507 	mod_elem_info = ext_mod_cnt << 2;
508 	if (ext_mod_cnt > 31 ||
509 		max_offset > 3 ||
510 		max_offset < -4) {
511 		mod_elem_info |= BIT(1);
512 	}
513 	if (cor_present) {
514 		mod_elem_info |= BIT(0);
515 	}
516 	net_buf_simple_add_u8(buf, mod_elem_info);
517 
518 	if (cor_present) {
519 		net_buf_simple_add_u8(buf, *cor_id);
520 	}
521 	memset(mod_cnt, ext_mod_cnt, sizeof(uint8_t));
522 }
523 
add_items_to_page(struct net_buf_simple * buf,struct bt_mesh_model * mod,uint8_t ext_mod_cnt)524 static void add_items_to_page(struct net_buf_simple *buf, struct bt_mesh_model *mod,
525 		       uint8_t ext_mod_cnt)
526 {
527 	int i, offset;
528 	uint8_t mod_idx;
529 
530 	MOD_REL_LIST_FOR_EACH(i) {
531 		if (IS_MOD_EXTENSION(mod, i)) {
532 			offset = mod->elem_idx - mod_rel_list[i].elem_base;
533 			mod_idx = mod_rel_list[i].idx_base;
534 			if (ext_mod_cnt < 32 &&
535 				offset < 4 &&
536 				offset > -5) {
537 				/* short format */
538 				if (offset < 0) {
539 					offset += 8;
540 				}
541 
542 				offset |= mod_idx << 3;
543 				net_buf_simple_add_u8(buf, offset);
544 			} else {
545 				/* long format */
546 				if (offset < 0) {
547 					offset += 256;
548 				}
549 				net_buf_simple_add_u8(buf, offset);
550 				net_buf_simple_add_u8(buf, mod_idx);
551 			}
552 		}
553 	}
554 }
555 
bt_mesh_comp_data_get_page_1(struct net_buf_simple * buf)556 int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
557 {
558 	const struct bt_mesh_comp *comp;
559 	uint8_t cor_id = 0;
560 	uint8_t ext_mod_cnt = 0;
561 	int i, j;
562 
563 	comp = bt_mesh_comp_get();
564 
565 	for (i = 0; i < comp->elem_count; i++) {
566 		net_buf_simple_add_u8(buf, comp->elem[i].model_count);
567 		net_buf_simple_add_u8(buf, comp->elem[i].vnd_model_count);
568 		for (j = 0; j < comp->elem[i].model_count; j++) {
569 			prep_model_item_header(&comp->elem[i].models[j],
570 					       &cor_id, &ext_mod_cnt, buf);
571 			if (ext_mod_cnt != 0) {
572 				add_items_to_page(buf,
573 						  &comp->elem[i].models[j],
574 						  ext_mod_cnt);
575 			}
576 		}
577 
578 		for (j = 0; j < comp->elem[i].vnd_model_count; j++) {
579 			prep_model_item_header(&comp->elem[i].vnd_models[j],
580 					       &cor_id, &ext_mod_cnt, buf);
581 			if (ext_mod_cnt != 0) {
582 				add_items_to_page(buf,
583 						  &comp->elem[i].vnd_models[j],
584 						  ext_mod_cnt);
585 			}
586 		}
587 	}
588 	return 0;
589 }
590 
bt_mesh_model_pub_period_get(struct bt_mesh_model * mod)591 int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod)
592 {
593 	int32_t period;
594 
595 	if (!mod->pub) {
596 		return 0;
597 	}
598 
599 	switch (mod->pub->period >> 6) {
600 	case 0x00:
601 		/* 1 step is 100 ms */
602 		period = (mod->pub->period & BIT_MASK(6)) * 100U;
603 		break;
604 	case 0x01:
605 		/* 1 step is 1 second */
606 		period = (mod->pub->period & BIT_MASK(6)) * MSEC_PER_SEC;
607 		break;
608 	case 0x02:
609 		/* 1 step is 10 seconds */
610 		period = (mod->pub->period & BIT_MASK(6)) * 10U * MSEC_PER_SEC;
611 		break;
612 	case 0x03:
613 		/* 1 step is 10 minutes */
614 		period = (mod->pub->period & BIT_MASK(6)) * 600U * MSEC_PER_SEC;
615 		break;
616 	default:
617 		CODE_UNREACHABLE;
618 	}
619 
620 	if (mod->pub->fast_period) {
621 		if (!period) {
622 			return 0;
623 		}
624 
625 		return MAX(period >> mod->pub->period_div, 100);
626 	} else {
627 		return period;
628 	}
629 }
630 
next_period(struct bt_mesh_model * mod)631 static int32_t next_period(struct bt_mesh_model *mod)
632 {
633 	struct bt_mesh_model_pub *pub = mod->pub;
634 	uint32_t period = 0;
635 	uint32_t elapsed;
636 
637 	elapsed = k_uptime_get_32() - pub->period_start;
638 	LOG_DBG("Publishing took %ums", elapsed);
639 
640 	if (mod->pub->count) {
641 		/* If a message is to be retransmitted, period should include time since the first
642 		 * publication until the last publication.
643 		 */
644 		period = BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit);
645 		period *= BT_MESH_PUB_MSG_NUM(mod->pub);
646 
647 		if (period && elapsed >= period) {
648 			LOG_WRN("Retransmission interval is too short");
649 			/* Return smallest positive number since 0 means disabled */
650 			return 1;
651 		}
652 	}
653 
654 	if (!period) {
655 		period = bt_mesh_model_pub_period_get(mod);
656 		if (!period) {
657 			return 0;
658 		}
659 	}
660 
661 	if (elapsed >= period) {
662 		LOG_WRN("Publication sending took longer than the period");
663 		/* Return smallest positive number since 0 means disabled */
664 		return 1;
665 	}
666 
667 	return period - elapsed;
668 }
669 
publish_sent(int err,void * user_data)670 static void publish_sent(int err, void *user_data)
671 {
672 	struct bt_mesh_model *mod = user_data;
673 	int32_t delay;
674 
675 	LOG_DBG("err %d, time %u", err, k_uptime_get_32());
676 
677 	delay = next_period(mod);
678 
679 	if (delay) {
680 		LOG_DBG("Publishing next time in %dms", delay);
681 		/* Using schedule() in case the application has already called
682 		 * bt_mesh_publish, and a publication is pending.
683 		 */
684 		k_work_schedule(&mod->pub->timer, K_MSEC(delay));
685 	}
686 }
687 
publish_start(uint16_t duration,int err,void * user_data)688 static void publish_start(uint16_t duration, int err, void *user_data)
689 {
690 	if (err) {
691 		LOG_ERR("Failed to publish: err %d", err);
692 		publish_sent(err, user_data);
693 		return;
694 	}
695 }
696 
697 static const struct bt_mesh_send_cb pub_sent_cb = {
698 	.start = publish_start,
699 	.end = publish_sent,
700 };
701 
publish_transmit(struct bt_mesh_model * mod)702 static int publish_transmit(struct bt_mesh_model *mod)
703 {
704 	NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
705 	struct bt_mesh_model_pub *pub = mod->pub;
706 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_PUB(pub);
707 	struct bt_mesh_net_tx tx = {
708 		.ctx = &ctx,
709 		.src = bt_mesh_model_elem(mod)->addr,
710 		.friend_cred = pub->cred,
711 	};
712 
713 	net_buf_simple_add_mem(&sdu, pub->msg->data, pub->msg->len);
714 
715 	return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, mod);
716 }
717 
pub_period_start(struct bt_mesh_model_pub * pub)718 static int pub_period_start(struct bt_mesh_model_pub *pub)
719 {
720 	int err;
721 
722 	pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit);
723 
724 	if (!pub->update) {
725 		return 0;
726 	}
727 
728 	err = pub->update(pub->mod);
729 
730 	pub->period_start = k_uptime_get_32();
731 
732 	if (err) {
733 		/* Skip this publish attempt. */
734 		LOG_DBG("Update failed, skipping publish (err: %d)", err);
735 		pub->count = 0;
736 		publish_sent(err, pub->mod);
737 		return err;
738 	}
739 
740 	return 0;
741 }
742 
mod_publish(struct k_work * work)743 static void mod_publish(struct k_work *work)
744 {
745 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
746 	struct bt_mesh_model_pub *pub = CONTAINER_OF(dwork,
747 						     struct bt_mesh_model_pub,
748 						     timer);
749 	int err;
750 
751 	if (pub->addr == BT_MESH_ADDR_UNASSIGNED ||
752 	    atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
753 		/* Publication is no longer active, but the cancellation of the
754 		 * delayed work failed. Abandon recurring timer.
755 		 */
756 		return;
757 	}
758 
759 	LOG_DBG("%u", k_uptime_get_32());
760 
761 	if (pub->count) {
762 		pub->count--;
763 
764 		if (pub->retr_update && pub->update &&
765 		    bt_mesh_model_pub_is_retransmission(pub->mod)) {
766 			err = pub->update(pub->mod);
767 			if (err) {
768 				publish_sent(err, pub->mod);
769 				return;
770 			}
771 		}
772 	} else {
773 		/* First publication in this period */
774 		err = pub_period_start(pub);
775 		if (err) {
776 			return;
777 		}
778 	}
779 
780 	err = publish_transmit(pub->mod);
781 	if (err) {
782 		LOG_ERR("Failed to publish (err %d)", err);
783 		publish_sent(err, pub->mod);
784 	}
785 }
786 
bt_mesh_model_elem(struct bt_mesh_model * mod)787 struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod)
788 {
789 	return &dev_comp->elem[mod->elem_idx];
790 }
791 
bt_mesh_model_get(bool vnd,uint8_t elem_idx,uint8_t mod_idx)792 struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx)
793 {
794 	struct bt_mesh_elem *elem;
795 
796 	if (elem_idx >= dev_comp->elem_count) {
797 		LOG_ERR("Invalid element index %u", elem_idx);
798 		return NULL;
799 	}
800 
801 	elem = &dev_comp->elem[elem_idx];
802 
803 	if (vnd) {
804 		if (mod_idx >= elem->vnd_model_count) {
805 			LOG_ERR("Invalid vendor model index %u", mod_idx);
806 			return NULL;
807 		}
808 
809 		return &elem->vnd_models[mod_idx];
810 	} else {
811 		if (mod_idx >= elem->model_count) {
812 			LOG_ERR("Invalid SIG model index %u", mod_idx);
813 			return NULL;
814 		}
815 
816 		return &elem->models[mod_idx];
817 	}
818 }
819 
820 #if defined(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)
bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model * mod)821 static int bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model *mod)
822 {
823 	uint16_t cid;
824 	const struct bt_mesh_model_op *op;
825 
826 	for (op = mod->op; op->func; op++) {
827 		cid = (uint16_t)(op->opcode & 0xffff);
828 
829 		if (cid == mod->vnd.company) {
830 			continue;
831 		}
832 
833 		LOG_ERR("Invalid vendor model(company:0x%04x"
834 		       " id:0x%04x) message opcode 0x%08x",
835 		       mod->vnd.company, mod->vnd.id, op->opcode);
836 
837 		return -EINVAL;
838 	}
839 
840 	return 0;
841 }
842 #endif
843 
mod_init(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)844 static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
845 		     bool vnd, bool primary, void *user_data)
846 {
847 	int i;
848 	int *err = user_data;
849 
850 	if (*err) {
851 		return;
852 	}
853 
854 	if (mod->pub) {
855 		mod->pub->mod = mod;
856 		k_work_init_delayable(&mod->pub->timer, mod_publish);
857 	}
858 
859 	for (i = 0; i < mod->keys_cnt; i++) {
860 		mod->keys[i] = BT_MESH_KEY_UNUSED;
861 	}
862 
863 	mod->elem_idx = elem - dev_comp->elem;
864 	if (vnd) {
865 		mod->mod_idx = mod - elem->vnd_models;
866 
867 		if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)) {
868 			*err = bt_mesh_vnd_mod_msg_cid_check(mod);
869 			if (*err) {
870 				return;
871 			}
872 		}
873 
874 	} else {
875 		mod->mod_idx = mod - elem->models;
876 	}
877 
878 	if (mod->cb && mod->cb->init) {
879 		*err = mod->cb->init(mod);
880 	}
881 }
882 
bt_mesh_comp_register(const struct bt_mesh_comp * comp)883 int bt_mesh_comp_register(const struct bt_mesh_comp *comp)
884 {
885 	int err;
886 
887 	/* There must be at least one element */
888 	if (!comp || !comp->elem_count) {
889 		return -EINVAL;
890 	}
891 
892 	dev_comp = comp;
893 
894 	err = 0;
895 
896 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
897 		memset(mod_rel_list, 0, sizeof(mod_rel_list));
898 	}
899 
900 	bt_mesh_model_foreach(mod_init, &err);
901 
902 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
903 		int i;
904 
905 		MOD_REL_LIST_FOR_EACH(i) {
906 			LOG_DBG("registered %s",
907 				mod_rel_list[i].type < RELATION_TYPE_EXT ?
908 				"correspondence" : "extension");
909 			LOG_DBG("\tbase: elem %u idx %u",
910 				mod_rel_list[i].elem_base,
911 				mod_rel_list[i].idx_base);
912 			LOG_DBG("\text: elem %u idx %u",
913 				mod_rel_list[i].elem_ext,
914 				mod_rel_list[i].idx_ext);
915 		}
916 		if (i < MOD_REL_LIST_SIZE) {
917 			LOG_WRN("Unused space in relation list: %d",
918 				MOD_REL_LIST_SIZE - i);
919 		}
920 	}
921 
922 	return err;
923 }
924 
bt_mesh_comp_provision(uint16_t addr)925 void bt_mesh_comp_provision(uint16_t addr)
926 {
927 	int i;
928 
929 	dev_primary_addr = addr;
930 
931 	LOG_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count);
932 
933 	for (i = 0; i < dev_comp->elem_count; i++) {
934 		struct bt_mesh_elem *elem = &dev_comp->elem[i];
935 
936 		elem->addr = addr++;
937 
938 		LOG_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", elem->addr, elem->model_count,
939 			elem->vnd_model_count);
940 	}
941 }
942 
bt_mesh_comp_unprovision(void)943 void bt_mesh_comp_unprovision(void)
944 {
945 	LOG_DBG("");
946 
947 	dev_primary_addr = BT_MESH_ADDR_UNASSIGNED;
948 }
949 
bt_mesh_primary_addr(void)950 uint16_t bt_mesh_primary_addr(void)
951 {
952 	return dev_primary_addr;
953 }
954 
model_group_get(struct bt_mesh_model * mod,uint16_t addr)955 static uint16_t *model_group_get(struct bt_mesh_model *mod, uint16_t addr)
956 {
957 	int i;
958 
959 	for (i = 0; i < mod->groups_cnt; i++) {
960 		if (mod->groups[i] == addr) {
961 			return &mod->groups[i];
962 		}
963 	}
964 
965 	return NULL;
966 }
967 
968 struct find_group_visitor_ctx {
969 	uint16_t *entry;
970 	struct bt_mesh_model *mod;
971 	uint16_t addr;
972 };
973 
find_group_mod_visitor(struct bt_mesh_model * mod,void * user_data)974 static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, void *user_data)
975 {
976 	struct find_group_visitor_ctx *ctx = user_data;
977 
978 	if (mod->elem_idx != ctx->mod->elem_idx) {
979 		return BT_MESH_WALK_CONTINUE;
980 	}
981 
982 	ctx->entry = model_group_get(mod, ctx->addr);
983 	if (ctx->entry) {
984 		ctx->mod = mod;
985 		return BT_MESH_WALK_STOP;
986 	}
987 
988 	return BT_MESH_WALK_CONTINUE;
989 }
990 
bt_mesh_model_find_group(struct bt_mesh_model ** mod,uint16_t addr)991 uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr)
992 {
993 	struct find_group_visitor_ctx ctx = {
994 		.mod = *mod,
995 		.entry = NULL,
996 		.addr = addr,
997 	};
998 
999 	bt_mesh_model_extensions_walk(*mod, find_group_mod_visitor, &ctx);
1000 
1001 	*mod = ctx.mod;
1002 	return ctx.entry;
1003 }
1004 
bt_mesh_elem_find_group(struct bt_mesh_elem * elem,uint16_t group_addr)1005 static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem,
1006 						     uint16_t group_addr)
1007 {
1008 	struct bt_mesh_model *model;
1009 	uint16_t *match;
1010 	int i;
1011 
1012 	for (i = 0; i < elem->model_count; i++) {
1013 		model = &elem->models[i];
1014 
1015 		match = model_group_get(model, group_addr);
1016 		if (match) {
1017 			return model;
1018 		}
1019 	}
1020 
1021 	for (i = 0; i < elem->vnd_model_count; i++) {
1022 		model = &elem->vnd_models[i];
1023 
1024 		match = model_group_get(model, group_addr);
1025 		if (match) {
1026 			return model;
1027 		}
1028 	}
1029 
1030 	return NULL;
1031 }
1032 
bt_mesh_elem_find(uint16_t addr)1033 struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
1034 {
1035 	uint16_t index;
1036 
1037 	if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
1038 		return NULL;
1039 	}
1040 
1041 	index = addr - dev_comp->elem[0].addr;
1042 	if (index >= dev_comp->elem_count) {
1043 		return NULL;
1044 	}
1045 
1046 	return &dev_comp->elem[index];
1047 }
1048 
bt_mesh_has_addr(uint16_t addr)1049 bool bt_mesh_has_addr(uint16_t addr)
1050 {
1051 	uint16_t index;
1052 
1053 	if (BT_MESH_ADDR_IS_UNICAST(addr)) {
1054 		return bt_mesh_elem_find(addr) != NULL;
1055 	}
1056 
1057 	if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
1058 		return true;
1059 	}
1060 
1061 	for (index = 0; index < dev_comp->elem_count; index++) {
1062 		struct bt_mesh_elem *elem = &dev_comp->elem[index];
1063 
1064 		if (bt_mesh_elem_find_group(elem, addr)) {
1065 			return true;
1066 		}
1067 	}
1068 
1069 	return false;
1070 }
1071 
1072 #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))1073 void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx,
1074 			struct net_buf_simple *buf))
1075 {
1076 	msg_cb = cb;
1077 }
1078 #endif
1079 
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)1080 int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr,
1081 			const struct bt_mesh_send_cb *cb, void *cb_data)
1082 {
1083 	struct bt_mesh_net_tx tx = {
1084 		.ctx = ctx,
1085 		.src = src_addr,
1086 	};
1087 
1088 	LOG_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx, tx.ctx->app_idx,
1089 		tx.ctx->addr);
1090 	LOG_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
1091 
1092 	if (!bt_mesh_is_provisioned()) {
1093 		LOG_ERR("Local node is not yet provisioned");
1094 		return -EAGAIN;
1095 	}
1096 
1097 	return bt_mesh_trans_send(&tx, buf, cb, cb_data);
1098 }
1099 
bt_mesh_elem_count(void)1100 uint8_t bt_mesh_elem_count(void)
1101 {
1102 	return dev_comp->elem_count;
1103 }
1104 
bt_mesh_model_has_key(struct bt_mesh_model * mod,uint16_t key)1105 bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key)
1106 {
1107 	int i;
1108 
1109 	for (i = 0; i < mod->keys_cnt; i++) {
1110 		if (mod->keys[i] == key ||
1111 		    (mod->keys[i] == BT_MESH_KEY_DEV_ANY &&
1112 		     BT_MESH_IS_DEV_KEY(key))) {
1113 			return true;
1114 		}
1115 	}
1116 
1117 	return false;
1118 }
1119 
model_has_dst(struct bt_mesh_model * mod,uint16_t dst)1120 static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst)
1121 {
1122 	if (BT_MESH_ADDR_IS_UNICAST(dst)) {
1123 		return (dev_comp->elem[mod->elem_idx].addr == dst);
1124 	} else if (BT_MESH_ADDR_IS_GROUP(dst) || BT_MESH_ADDR_IS_VIRTUAL(dst) ||
1125 		  (BT_MESH_ADDR_IS_FIXED_GROUP(dst) &&  mod->elem_idx != 0)) {
1126 		return !!bt_mesh_model_find_group(&mod, dst);
1127 	}
1128 
1129 	/* If a message with a fixed group address is sent to the access layer,
1130 	 * the lower layers have already confirmed that we are subscribing to
1131 	 * it. All models on the primary element should receive the message.
1132 	 */
1133 	return mod->elem_idx == 0;
1134 }
1135 
find_op(struct bt_mesh_elem * elem,uint32_t opcode,struct bt_mesh_model ** model)1136 static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem,
1137 					      uint32_t opcode, struct bt_mesh_model **model)
1138 {
1139 	uint8_t i;
1140 	uint8_t count;
1141 	/* This value shall not be used in shipping end products. */
1142 	uint32_t cid = UINT32_MAX;
1143 	struct bt_mesh_model *models;
1144 
1145 	/* SIG models cannot contain 3-byte (vendor) OpCodes, and
1146 	 * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so
1147 	 * we only need to do the lookup in one of the model lists.
1148 	 */
1149 	if (BT_MESH_MODEL_OP_LEN(opcode) < 3) {
1150 		models = elem->models;
1151 		count = elem->model_count;
1152 	} else {
1153 		models = elem->vnd_models;
1154 		count = elem->vnd_model_count;
1155 
1156 		cid = (uint16_t)(opcode & 0xffff);
1157 	}
1158 
1159 	for (i = 0U; i < count; i++) {
1160 
1161 		const struct bt_mesh_model_op *op;
1162 
1163 		if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) &&
1164 		     cid != UINT32_MAX &&
1165 		     cid != models[i].vnd.company) {
1166 			continue;
1167 		}
1168 
1169 		*model = &models[i];
1170 
1171 		for (op = (*model)->op; op->func; op++) {
1172 			if (op->opcode == opcode) {
1173 				return op;
1174 			}
1175 		}
1176 	}
1177 
1178 	*model = NULL;
1179 	return NULL;
1180 }
1181 
get_opcode(struct net_buf_simple * buf,uint32_t * opcode)1182 static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode)
1183 {
1184 	switch (buf->data[0] >> 6) {
1185 	case 0x00:
1186 	case 0x01:
1187 		if (buf->data[0] == 0x7f) {
1188 			LOG_ERR("Ignoring RFU OpCode");
1189 			return -EINVAL;
1190 		}
1191 
1192 		*opcode = net_buf_simple_pull_u8(buf);
1193 		return 0;
1194 	case 0x02:
1195 		if (buf->len < 2) {
1196 			LOG_ERR("Too short payload for 2-octet OpCode");
1197 			return -EINVAL;
1198 		}
1199 
1200 		*opcode = net_buf_simple_pull_be16(buf);
1201 		return 0;
1202 	case 0x03:
1203 		if (buf->len < 3) {
1204 			LOG_ERR("Too short payload for 3-octet OpCode");
1205 			return -EINVAL;
1206 		}
1207 
1208 		*opcode = net_buf_simple_pull_u8(buf) << 16;
1209 		/* Using LE for the CID since the model layer is defined as
1210 		 * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
1211 		 * will declare the opcode in this way.
1212 		 */
1213 		*opcode |= net_buf_simple_pull_le16(buf);
1214 		return 0;
1215 	}
1216 
1217 	CODE_UNREACHABLE;
1218 }
1219 
element_model_recv(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,uint16_t addr,struct bt_mesh_elem * elem,uint32_t opcode)1220 static int element_model_recv(struct bt_mesh_msg_ctx *ctx,
1221 			      struct net_buf_simple *buf, uint16_t addr,
1222 			      struct bt_mesh_elem *elem, uint32_t opcode)
1223 {
1224 	const struct bt_mesh_model_op *op;
1225 	struct bt_mesh_model *model;
1226 	struct net_buf_simple_state state;
1227 	int err;
1228 
1229 	op = find_op(elem, opcode, &model);
1230 	if (!op) {
1231 		LOG_ERR("No OpCode 0x%08x for elem 0x%02x", opcode, elem->addr);
1232 		return ACCESS_STATUS_WRONG_OPCODE;
1233 	}
1234 
1235 	if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
1236 		LOG_ERR("Wrong key");
1237 		return ACCESS_STATUS_WRONG_KEY;
1238 	}
1239 
1240 	if (!model_has_dst(model, addr)) {
1241 		LOG_ERR("Invalid address 0x%02x", addr);
1242 		return ACCESS_STATUS_INVALID_ADDRESS;
1243 	}
1244 
1245 	if ((op->len >= 0) && (buf->len < (size_t)op->len)) {
1246 		LOG_ERR("Too short message for OpCode 0x%08x", opcode);
1247 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1248 	} else if ((op->len < 0) && (buf->len != (size_t)(-op->len))) {
1249 		LOG_ERR("Invalid message size for OpCode 0x%08x", opcode);
1250 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1251 	}
1252 
1253 	net_buf_simple_save(buf, &state);
1254 	err = op->func(model, ctx, buf);
1255 	net_buf_simple_restore(buf, &state);
1256 
1257 	if (err) {
1258 		return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
1259 	}
1260 	return ACCESS_STATUS_SUCCESS;
1261 }
1262 
bt_mesh_model_recv(struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1263 int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
1264 {
1265 	int err = ACCESS_STATUS_SUCCESS;
1266 	uint32_t opcode;
1267 	uint16_t index;
1268 
1269 	LOG_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", ctx->app_idx, ctx->addr,
1270 		ctx->recv_dst);
1271 	LOG_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
1272 
1273 	if (IS_ENABLED(CONFIG_BT_TESTING)) {
1274 		bt_test_mesh_model_recv(ctx->addr, ctx->recv_dst, buf->data,
1275 					buf->len);
1276 	}
1277 
1278 	if (get_opcode(buf, &opcode) < 0) {
1279 		LOG_WRN("Unable to decode OpCode");
1280 		return ACCESS_STATUS_WRONG_OPCODE;
1281 	}
1282 
1283 	LOG_DBG("OpCode 0x%08x", opcode);
1284 
1285 	if (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
1286 		index = ctx->recv_dst - dev_comp->elem[0].addr;
1287 
1288 		if (index >= dev_comp->elem_count) {
1289 			LOG_ERR("Invalid address 0x%02x", ctx->recv_dst);
1290 			err = ACCESS_STATUS_INVALID_ADDRESS;
1291 		} else {
1292 			struct bt_mesh_elem *elem = &dev_comp->elem[index];
1293 
1294 			err = element_model_recv(ctx, buf, ctx->recv_dst, elem, opcode);
1295 		}
1296 	} else {
1297 		for (index = 0; index < dev_comp->elem_count; index++) {
1298 			struct bt_mesh_elem *elem = &dev_comp->elem[index];
1299 
1300 			(void)element_model_recv(ctx, buf, ctx->recv_dst, elem, opcode);
1301 		}
1302 	}
1303 
1304 	if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
1305 		msg_cb(opcode, ctx, buf);
1306 	}
1307 
1308 	return err;
1309 }
1310 
bt_mesh_model_send(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)1311 int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
1312 		       struct net_buf_simple *msg,
1313 		       const struct bt_mesh_send_cb *cb, void *cb_data)
1314 {
1315 	if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG) && bt_mesh_op_agg_accept(ctx)) {
1316 		return bt_mesh_op_agg_send(model, ctx, msg, cb);
1317 	}
1318 
1319 	if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
1320 		LOG_ERR("Model not bound to AppKey 0x%04x", ctx->app_idx);
1321 		return -EINVAL;
1322 	}
1323 
1324 	return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->addr, cb, cb_data);
1325 }
1326 
bt_mesh_model_publish(struct bt_mesh_model * model)1327 int bt_mesh_model_publish(struct bt_mesh_model *model)
1328 {
1329 	struct bt_mesh_model_pub *pub = model->pub;
1330 
1331 	if (!pub) {
1332 		return -ENOTSUP;
1333 	}
1334 
1335 	LOG_DBG("");
1336 
1337 	if (pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1338 		return -EADDRNOTAVAIL;
1339 	}
1340 
1341 	if (!pub->msg || !pub->msg->len) {
1342 		LOG_ERR("No publication message");
1343 		return -EINVAL;
1344 	}
1345 
1346 	if (pub->msg->len + BT_MESH_MIC_SHORT > BT_MESH_TX_SDU_MAX) {
1347 		LOG_ERR("Message does not fit maximum SDU size");
1348 		return -EMSGSIZE;
1349 	}
1350 
1351 	if (pub->count) {
1352 		LOG_WRN("Clearing publish retransmit timer");
1353 	}
1354 
1355 	/* Account for initial transmission */
1356 	pub->count = BT_MESH_PUB_MSG_TOTAL(pub);
1357 	pub->period_start = k_uptime_get_32();
1358 
1359 	LOG_DBG("Publish Retransmit Count %u Interval %ums", pub->count,
1360 		BT_MESH_PUB_TRANSMIT_INT(pub->retransmit));
1361 
1362 	k_work_reschedule(&pub->timer, K_NO_WAIT);
1363 
1364 	return 0;
1365 }
1366 
bt_mesh_model_find_vnd(const struct bt_mesh_elem * elem,uint16_t company,uint16_t id)1367 struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
1368 					     uint16_t company, uint16_t id)
1369 {
1370 	uint8_t i;
1371 
1372 	for (i = 0U; i < elem->vnd_model_count; i++) {
1373 		if (elem->vnd_models[i].vnd.company == company &&
1374 		    elem->vnd_models[i].vnd.id == id) {
1375 			return &elem->vnd_models[i];
1376 		}
1377 	}
1378 
1379 	return NULL;
1380 }
1381 
bt_mesh_model_find(const struct bt_mesh_elem * elem,uint16_t id)1382 struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
1383 					 uint16_t id)
1384 {
1385 	uint8_t i;
1386 
1387 	for (i = 0U; i < elem->model_count; i++) {
1388 		if (elem->models[i].id == id) {
1389 			return &elem->models[i];
1390 		}
1391 	}
1392 
1393 	return NULL;
1394 }
1395 
bt_mesh_comp_get(void)1396 const struct bt_mesh_comp *bt_mesh_comp_get(void)
1397 {
1398 	return dev_comp;
1399 }
1400 
bt_mesh_model_extensions_walk(struct bt_mesh_model * model,enum bt_mesh_walk (* cb)(struct bt_mesh_model * mod,void * user_data),void * user_data)1401 void bt_mesh_model_extensions_walk(struct bt_mesh_model *model,
1402 				   enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod,
1403 							   void *user_data),
1404 				   void *user_data)
1405 {
1406 #ifndef CONFIG_BT_MESH_MODEL_EXTENSIONS
1407 	(void)cb(model, user_data);
1408 	return;
1409 #else
1410 	struct bt_mesh_model *it;
1411 
1412 	if (cb(model, user_data) == BT_MESH_WALK_STOP || !model->next) {
1413 		return;
1414 	}
1415 
1416 	/* List is circular. Step through all models until we reach the start: */
1417 	for (it = model->next; it != model; it = it->next) {
1418 		if (cb(it, user_data) == BT_MESH_WALK_STOP) {
1419 			return;
1420 		}
1421 	}
1422 #endif
1423 }
1424 
1425 #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS
mod_rel_register(struct bt_mesh_model * base,struct bt_mesh_model * ext,uint8_t type)1426 static int mod_rel_register(struct bt_mesh_model *base,
1427 				 struct bt_mesh_model *ext,
1428 				 uint8_t type)
1429 {
1430 	LOG_DBG("");
1431 	struct mod_relation extension = {
1432 		base->elem_idx,
1433 		base->mod_idx,
1434 		ext->elem_idx,
1435 		ext->mod_idx,
1436 		type,
1437 	};
1438 	int i;
1439 
1440 	for (i = 0; i < ARRAY_SIZE(mod_rel_list); i++) {
1441 		if (mod_rel_list[i].elem_base == 0 &&
1442 			mod_rel_list[i].idx_base == 0 &&
1443 			mod_rel_list[i].elem_ext == 0 &&
1444 			mod_rel_list[i].idx_ext == 0) {
1445 			memcpy(&mod_rel_list[i], &extension,
1446 			       sizeof(extension));
1447 			return 0;
1448 		}
1449 	}
1450 	LOG_ERR("Failed to extend");
1451 	return -ENOMEM;
1452 }
1453 
bt_mesh_model_extend(struct bt_mesh_model * extending_mod,struct bt_mesh_model * base_mod)1454 int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_model *base_mod)
1455 {
1456 	struct bt_mesh_model *a = extending_mod;
1457 	struct bt_mesh_model *b = base_mod;
1458 	struct bt_mesh_model *a_next = a->next;
1459 	struct bt_mesh_model *b_next = b->next;
1460 	struct bt_mesh_model *it;
1461 
1462 	base_mod->flags |= BT_MESH_MOD_EXTENDED;
1463 
1464 	if (a == b) {
1465 		return 0;
1466 	}
1467 
1468 	/* Check if a's list contains b */
1469 	for (it = a; (it != NULL) && (it->next != a); it = it->next) {
1470 		if (it == b) {
1471 			return 0;
1472 		}
1473 	}
1474 
1475 	/* Merge lists */
1476 	if (a_next) {
1477 		b->next = a_next;
1478 	} else {
1479 		b->next = a;
1480 	}
1481 
1482 	if (b_next) {
1483 		a->next = b_next;
1484 	} else {
1485 		a->next = b;
1486 	}
1487 
1488 
1489 	if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1490 		return mod_rel_register(base_mod, extending_mod, RELATION_TYPE_EXT);
1491 	}
1492 
1493 	return 0;
1494 }
1495 
bt_mesh_model_correspond(struct bt_mesh_model * corresponding_mod,struct bt_mesh_model * base_mod)1496 int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod,
1497 			     struct bt_mesh_model *base_mod)
1498 {
1499 	int i, err;
1500 	uint8_t cor_id = 0;
1501 
1502 	if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
1503 		return -ENOTSUP;
1504 	}
1505 
1506 	MOD_REL_LIST_FOR_EACH(i) {
1507 		if (mod_rel_list[i].type < RELATION_TYPE_EXT &&
1508 		    mod_rel_list[i].type > cor_id) {
1509 			cor_id = mod_rel_list[i].type;
1510 		}
1511 
1512 		if ((IS_MOD_BASE(base_mod, i) ||
1513 		     IS_MOD_EXTENSION(base_mod, i) ||
1514 		     IS_MOD_BASE(corresponding_mod, i) ||
1515 		     IS_MOD_EXTENSION(corresponding_mod, i)) &&
1516 		    mod_rel_list[i].type < RELATION_TYPE_EXT) {
1517 			return mod_rel_register(base_mod, corresponding_mod, mod_rel_list[i].type);
1518 		}
1519 	}
1520 	err = mod_rel_register(base_mod, corresponding_mod, cor_id);
1521 	if (err) {
1522 		return err;
1523 	}
1524 	return 0;
1525 }
1526 #endif /* CONFIG_BT_MESH_MODEL_EXTENSIONS */
1527 
bt_mesh_model_is_extended(struct bt_mesh_model * model)1528 bool bt_mesh_model_is_extended(struct bt_mesh_model *model)
1529 {
1530 	return model->flags & BT_MESH_MOD_EXTENDED;
1531 }
1532 
mod_set_bind(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1533 static int mod_set_bind(struct bt_mesh_model *mod, size_t len_rd,
1534 			settings_read_cb read_cb, void *cb_arg)
1535 {
1536 	ssize_t len;
1537 	int i;
1538 
1539 	/* Start with empty array regardless of cleared or set value */
1540 	for (i = 0; i < mod->keys_cnt; i++) {
1541 		mod->keys[i] = BT_MESH_KEY_UNUSED;
1542 	}
1543 
1544 	if (len_rd == 0) {
1545 		LOG_DBG("Cleared bindings for model");
1546 		return 0;
1547 	}
1548 
1549 	len = read_cb(cb_arg, mod->keys, mod->keys_cnt * sizeof(mod->keys[0]));
1550 	if (len < 0) {
1551 		LOG_ERR("Failed to read value (err %zd)", len);
1552 		return len;
1553 	}
1554 
1555 	LOG_HEXDUMP_DBG(mod->keys, len, "val");
1556 
1557 	LOG_DBG("Decoded %zu bound keys for model", len / sizeof(mod->keys[0]));
1558 	return 0;
1559 }
1560 
mod_set_sub(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1561 static int mod_set_sub(struct bt_mesh_model *mod, size_t len_rd,
1562 		       settings_read_cb read_cb, void *cb_arg)
1563 {
1564 	size_t size = mod->groups_cnt * sizeof(mod->groups[0]);
1565 	ssize_t len;
1566 
1567 	/* Start with empty array regardless of cleared or set value */
1568 	(void)memset(mod->groups, 0, size);
1569 
1570 	if (len_rd == 0) {
1571 		LOG_DBG("Cleared subscriptions for model");
1572 		return 0;
1573 	}
1574 
1575 	len = read_cb(cb_arg, mod->groups, size);
1576 	if (len < 0) {
1577 		LOG_ERR("Failed to read value (err %zd)", len);
1578 		return len;
1579 	}
1580 
1581 	LOG_HEXDUMP_DBG(mod->groups, len, "val");
1582 
1583 	LOG_DBG("Decoded %zu subscribed group addresses for model", len / sizeof(mod->groups[0]));
1584 	return 0;
1585 }
1586 
mod_set_pub(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1587 static int mod_set_pub(struct bt_mesh_model *mod, size_t len_rd,
1588 		       settings_read_cb read_cb, void *cb_arg)
1589 {
1590 	struct mod_pub_val pub;
1591 	int err;
1592 
1593 	if (!mod->pub) {
1594 		LOG_WRN("Model has no publication context!");
1595 		return -EINVAL;
1596 	}
1597 
1598 	if (len_rd == 0) {
1599 		mod->pub->addr = BT_MESH_ADDR_UNASSIGNED;
1600 		mod->pub->key = 0U;
1601 		mod->pub->cred = 0U;
1602 		mod->pub->ttl = 0U;
1603 		mod->pub->period = 0U;
1604 		mod->pub->retransmit = 0U;
1605 		mod->pub->count = 0U;
1606 
1607 		LOG_DBG("Cleared publication for model");
1608 		return 0;
1609 	}
1610 
1611 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
1612 		return 0;
1613 	}
1614 
1615 	err = bt_mesh_settings_set(read_cb, cb_arg, &pub, sizeof(pub));
1616 	if (err) {
1617 		LOG_ERR("Failed to set \'model-pub\'");
1618 		return err;
1619 	}
1620 
1621 	mod->pub->addr = pub.addr;
1622 	mod->pub->key = pub.key;
1623 	mod->pub->cred = pub.cred;
1624 	mod->pub->ttl = pub.ttl;
1625 	mod->pub->period = pub.period;
1626 	mod->pub->retransmit = pub.retransmit;
1627 	mod->pub->period_div = pub.period_div;
1628 	mod->pub->count = 0U;
1629 
1630 	LOG_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", pub.addr, pub.key);
1631 
1632 	return 0;
1633 }
1634 
mod_data_set(struct bt_mesh_model * mod,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1635 static int mod_data_set(struct bt_mesh_model *mod,
1636 			const char *name, size_t len_rd,
1637 			settings_read_cb read_cb, void *cb_arg)
1638 {
1639 	const char *next;
1640 
1641 	settings_name_next(name, &next);
1642 
1643 	if (mod->cb && mod->cb->settings_set) {
1644 		return mod->cb->settings_set(mod, next, len_rd,
1645 			read_cb, cb_arg);
1646 	}
1647 
1648 	return 0;
1649 }
1650 
mod_set(bool vnd,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1651 static int mod_set(bool vnd, const char *name, size_t len_rd,
1652 		   settings_read_cb read_cb, void *cb_arg)
1653 {
1654 	struct bt_mesh_model *mod;
1655 	uint8_t elem_idx, mod_idx;
1656 	uint16_t mod_key;
1657 	int len;
1658 	const char *next;
1659 
1660 	if (!name) {
1661 		LOG_ERR("Insufficient number of arguments");
1662 		return -ENOENT;
1663 	}
1664 
1665 	mod_key = strtol(name, NULL, 16);
1666 	elem_idx = mod_key >> 8;
1667 	mod_idx = mod_key;
1668 
1669 	LOG_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u", mod_key, elem_idx, mod_idx);
1670 
1671 	mod = bt_mesh_model_get(vnd, elem_idx, mod_idx);
1672 	if (!mod) {
1673 		LOG_ERR("Failed to get model for elem_idx %u mod_idx %u", elem_idx, mod_idx);
1674 		return -ENOENT;
1675 	}
1676 
1677 	len = settings_name_next(name, &next);
1678 
1679 	if (!next) {
1680 		LOG_ERR("Insufficient number of arguments");
1681 		return -ENOENT;
1682 	}
1683 
1684 	if (!strncmp(next, "bind", len)) {
1685 		return mod_set_bind(mod, len_rd, read_cb, cb_arg);
1686 	}
1687 
1688 	if (!strncmp(next, "sub", len)) {
1689 		return mod_set_sub(mod, len_rd, read_cb, cb_arg);
1690 	}
1691 
1692 	if (!strncmp(next, "pub", len)) {
1693 		return mod_set_pub(mod, len_rd, read_cb, cb_arg);
1694 	}
1695 
1696 	if (!strncmp(next, "data", len)) {
1697 		return mod_data_set(mod, next, len_rd, read_cb, cb_arg);
1698 	}
1699 
1700 	LOG_WRN("Unknown module key %s", next);
1701 	return -ENOENT;
1702 }
1703 
sig_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1704 static int sig_mod_set(const char *name, size_t len_rd,
1705 		       settings_read_cb read_cb, void *cb_arg)
1706 {
1707 	return mod_set(false, name, len_rd, read_cb, cb_arg);
1708 }
1709 
1710 BT_MESH_SETTINGS_DEFINE(sig_mod, "s", sig_mod_set);
1711 
vnd_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1712 static int vnd_mod_set(const char *name, size_t len_rd,
1713 		       settings_read_cb read_cb, void *cb_arg)
1714 {
1715 	return mod_set(true, name, len_rd, read_cb, cb_arg);
1716 }
1717 
1718 BT_MESH_SETTINGS_DEFINE(vnd_mod, "v", vnd_mod_set);
1719 
comp_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1720 static int comp_set(const char *name, size_t len_rd, settings_read_cb read_cb,
1721 		    void *cb_arg)
1722 {
1723 	/* Only need to know that the entry exists. Will load the contents on
1724 	 * demand.
1725 	 */
1726 	if (len_rd > 0) {
1727 		atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
1728 	}
1729 
1730 	return 0;
1731 }
1732 BT_MESH_SETTINGS_DEFINE(comp, "cmp", comp_set);
1733 
encode_mod_path(struct bt_mesh_model * mod,bool vnd,const char * key,char * path,size_t path_len)1734 static void encode_mod_path(struct bt_mesh_model *mod, bool vnd,
1735 			    const char *key, char *path, size_t path_len)
1736 {
1737 	uint16_t mod_key = (((uint16_t)mod->elem_idx << 8) | mod->mod_idx);
1738 
1739 	if (vnd) {
1740 		snprintk(path, path_len, "bt/mesh/v/%x/%s", mod_key, key);
1741 	} else {
1742 		snprintk(path, path_len, "bt/mesh/s/%x/%s", mod_key, key);
1743 	}
1744 }
1745 
store_pending_mod_bind(struct bt_mesh_model * mod,bool vnd)1746 static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd)
1747 {
1748 	uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
1749 	char path[20];
1750 	int i, count, err;
1751 
1752 	for (i = 0, count = 0; i < mod->keys_cnt; i++) {
1753 		if (mod->keys[i] != BT_MESH_KEY_UNUSED) {
1754 			keys[count++] = mod->keys[i];
1755 			LOG_DBG("model key 0x%04x", mod->keys[i]);
1756 		}
1757 	}
1758 
1759 	encode_mod_path(mod, vnd, "bind", path, sizeof(path));
1760 
1761 	if (count) {
1762 		err = settings_save_one(path, keys, count * sizeof(keys[0]));
1763 	} else {
1764 		err = settings_delete(path);
1765 	}
1766 
1767 	if (err) {
1768 		LOG_ERR("Failed to store %s value", path);
1769 	} else {
1770 		LOG_DBG("Stored %s value", path);
1771 	}
1772 }
1773 
store_pending_mod_sub(struct bt_mesh_model * mod,bool vnd)1774 static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd)
1775 {
1776 	uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
1777 	char path[20];
1778 	int i, count, err;
1779 
1780 	for (i = 0, count = 0; i < mod->groups_cnt; i++) {
1781 		if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
1782 			groups[count++] = mod->groups[i];
1783 		}
1784 	}
1785 
1786 	encode_mod_path(mod, vnd, "sub", path, sizeof(path));
1787 
1788 	if (count) {
1789 		err = settings_save_one(path, groups,
1790 					count * sizeof(groups[0]));
1791 	} else {
1792 		err = settings_delete(path);
1793 	}
1794 
1795 	if (err) {
1796 		LOG_ERR("Failed to store %s value", path);
1797 	} else {
1798 		LOG_DBG("Stored %s value", path);
1799 	}
1800 }
1801 
store_pending_mod_pub(struct bt_mesh_model * mod,bool vnd)1802 static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd)
1803 {
1804 	struct mod_pub_val pub = {0};
1805 	char path[20];
1806 	int err;
1807 
1808 	encode_mod_path(mod, vnd, "pub", path, sizeof(path));
1809 
1810 	if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1811 		err = settings_delete(path);
1812 	} else {
1813 		pub.addr = mod->pub->addr;
1814 		pub.key = mod->pub->key;
1815 		pub.ttl = mod->pub->ttl;
1816 		pub.retransmit = mod->pub->retransmit;
1817 		pub.period = mod->pub->period;
1818 		pub.period_div = mod->pub->period_div;
1819 		pub.cred = mod->pub->cred;
1820 
1821 		err = settings_save_one(path, &pub, sizeof(pub));
1822 	}
1823 
1824 	if (err) {
1825 		LOG_ERR("Failed to store %s value", path);
1826 	} else {
1827 		LOG_DBG("Stored %s value", path);
1828 	}
1829 }
1830 
store_pending_mod(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)1831 static void store_pending_mod(struct bt_mesh_model *mod,
1832 			      struct bt_mesh_elem *elem, bool vnd,
1833 			      bool primary, void *user_data)
1834 {
1835 	if (!mod->flags) {
1836 		return;
1837 	}
1838 
1839 	if (mod->flags & BT_MESH_MOD_BIND_PENDING) {
1840 		mod->flags &= ~BT_MESH_MOD_BIND_PENDING;
1841 		store_pending_mod_bind(mod, vnd);
1842 	}
1843 
1844 	if (mod->flags & BT_MESH_MOD_SUB_PENDING) {
1845 		mod->flags &= ~BT_MESH_MOD_SUB_PENDING;
1846 		store_pending_mod_sub(mod, vnd);
1847 	}
1848 
1849 	if (mod->flags & BT_MESH_MOD_PUB_PENDING) {
1850 		mod->flags &= ~BT_MESH_MOD_PUB_PENDING;
1851 		store_pending_mod_pub(mod, vnd);
1852 	}
1853 
1854 	if (mod->flags & BT_MESH_MOD_DATA_PENDING) {
1855 		mod->flags &= ~BT_MESH_MOD_DATA_PENDING;
1856 		mod->cb->pending_store(mod);
1857 	}
1858 }
1859 
bt_mesh_model_pending_store(void)1860 void bt_mesh_model_pending_store(void)
1861 {
1862 	bt_mesh_model_foreach(store_pending_mod, NULL);
1863 }
1864 
bt_mesh_model_bind_store(struct bt_mesh_model * mod)1865 void bt_mesh_model_bind_store(struct bt_mesh_model *mod)
1866 {
1867 	mod->flags |= BT_MESH_MOD_BIND_PENDING;
1868 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1869 }
1870 
bt_mesh_model_sub_store(struct bt_mesh_model * mod)1871 void bt_mesh_model_sub_store(struct bt_mesh_model *mod)
1872 {
1873 	mod->flags |= BT_MESH_MOD_SUB_PENDING;
1874 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1875 }
1876 
bt_mesh_model_pub_store(struct bt_mesh_model * mod)1877 void bt_mesh_model_pub_store(struct bt_mesh_model *mod)
1878 {
1879 	mod->flags |= BT_MESH_MOD_PUB_PENDING;
1880 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1881 }
1882 
bt_mesh_comp_store(void)1883 int bt_mesh_comp_store(void)
1884 {
1885 	NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
1886 	int err;
1887 
1888 	err = bt_mesh_comp_data_get_page_0(&buf, 0);
1889 	if (err) {
1890 		LOG_ERR("Failed to read composition data: %d", err);
1891 		return err;
1892 	}
1893 
1894 	err = settings_save_one("bt/mesh/cmp", buf.data, buf.len);
1895 	if (err) {
1896 		LOG_ERR("Failed to store composition data: %d", err);
1897 	} else {
1898 		LOG_DBG("Stored composition data");
1899 	}
1900 
1901 	return err;
1902 }
1903 
bt_mesh_comp_change_prepare(void)1904 int bt_mesh_comp_change_prepare(void)
1905 {
1906 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
1907 		return -ENOTSUP;
1908 	}
1909 
1910 	return bt_mesh_comp_store();
1911 }
1912 
comp_data_clear(void)1913 static void comp_data_clear(void)
1914 {
1915 	int err;
1916 
1917 	err = settings_delete("bt/mesh/cmp");
1918 	if (err) {
1919 		LOG_ERR("Failed to clear composition data: %d", err);
1920 	} else {
1921 		LOG_DBG("Cleared composition data page 128");
1922 	}
1923 
1924 	atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
1925 }
1926 
read_comp_cb(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)1927 static int read_comp_cb(const char *key, size_t len, settings_read_cb read_cb,
1928 			void *cb_arg, void *param)
1929 {
1930 	struct net_buf_simple *buf = param;
1931 
1932 	if (len > net_buf_simple_tailroom(buf)) {
1933 		return -ENOBUFS;
1934 	}
1935 
1936 	len = read_cb(cb_arg, net_buf_simple_tail(buf), len);
1937 	if (len > 0) {
1938 		net_buf_simple_add(buf, len);
1939 	}
1940 
1941 	return -EALREADY;
1942 }
1943 
bt_mesh_comp_read(struct net_buf_simple * buf)1944 int bt_mesh_comp_read(struct net_buf_simple *buf)
1945 {
1946 	size_t original_len = buf->len;
1947 	int err;
1948 
1949 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
1950 		return -ENOTSUP;
1951 	}
1952 
1953 	err = settings_load_subtree_direct("bt/mesh/cmp", read_comp_cb, buf);
1954 	if (err) {
1955 		LOG_ERR("Failed reading composition data: %d", err);
1956 		return err;
1957 	}
1958 
1959 	if (buf->len == original_len) {
1960 		return -ENOENT;
1961 	}
1962 
1963 	return 0;
1964 }
1965 
bt_mesh_model_data_store(struct bt_mesh_model * mod,bool vnd,const char * name,const void * data,size_t data_len)1966 int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
1967 			     const char *name, const void *data,
1968 			     size_t data_len)
1969 {
1970 	char path[30];
1971 	int err;
1972 
1973 	encode_mod_path(mod, vnd, "data", path, sizeof(path));
1974 	if (name) {
1975 		strcat(path, "/");
1976 		strncat(path, name, SETTINGS_MAX_DIR_DEPTH);
1977 	}
1978 
1979 	if (data_len) {
1980 		err = settings_save_one(path, data, data_len);
1981 	} else {
1982 		err = settings_delete(path);
1983 	}
1984 
1985 	if (err) {
1986 		LOG_ERR("Failed to store %s value", path);
1987 	} else {
1988 		LOG_DBG("Stored %s value", path);
1989 	}
1990 	return err;
1991 }
1992 
1993 #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)1994 static int metadata_set(const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg)
1995 {
1996 	/* Only need to know that the entry exists. Will load the contents on
1997 	 * demand.
1998 	 */
1999 	if (len_rd > 0) {
2000 		atomic_set_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY);
2001 	}
2002 
2003 	return 0;
2004 }
2005 BT_MESH_SETTINGS_DEFINE(metadata, "metadata", metadata_set);
2006 
bt_mesh_models_metadata_store(void)2007 int bt_mesh_models_metadata_store(void)
2008 {
2009 	NET_BUF_SIMPLE_DEFINE(buf, CONFIG_BT_MESH_MODELS_METADATA_PAGE_LEN);
2010 	size_t total_size;
2011 	int err;
2012 
2013 	total_size = bt_mesh_metadata_page_0_size();
2014 	LOG_DBG("bt/mesh/metadata total %d", total_size);
2015 
2016 	net_buf_simple_init(&buf, 0);
2017 	net_buf_simple_add_le16(&buf, total_size);
2018 
2019 	err = bt_mesh_metadata_get_page_0(&buf, 0);
2020 	if (err == -E2BIG) {
2021 		LOG_ERR("Metadata too large");
2022 		return err;
2023 	}
2024 	if (err) {
2025 		LOG_ERR("Failed to read models metadata: %d", err);
2026 		return err;
2027 	}
2028 
2029 	LOG_DBG("bt/mesh/metadata len %d", buf.len);
2030 
2031 	err = settings_save_one("bt/mesh/metadata", buf.data, buf.len);
2032 	if (err) {
2033 		LOG_ERR("Failed to store models metadata: %d", err);
2034 	} else {
2035 		LOG_DBG("Stored models metadata");
2036 	}
2037 
2038 	return err;
2039 }
2040 
bt_mesh_models_metadata_read(struct net_buf_simple * buf,size_t offset)2041 int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset)
2042 {
2043 	NET_BUF_SIMPLE_DEFINE(stored_buf, CONFIG_BT_MESH_MODELS_METADATA_PAGE_LEN);
2044 	size_t original_len = buf->len;
2045 	int err;
2046 
2047 	if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
2048 		return -ENOTSUP;
2049 	}
2050 
2051 	net_buf_simple_init(&stored_buf, 0);
2052 
2053 	err = settings_load_subtree_direct("bt/mesh/metadata", read_comp_cb, &stored_buf);
2054 	if (err) {
2055 		LOG_ERR("Failed reading models metadata: %d", err);
2056 		return err;
2057 	}
2058 
2059 	/* First two bytes are total length */
2060 	offset += 2;
2061 
2062 	net_buf_simple_add_mem(buf, &stored_buf.data, MIN(net_buf_simple_tailroom(buf), 2));
2063 
2064 	if (offset >= stored_buf.len) {
2065 		return 0;
2066 	}
2067 
2068 	net_buf_simple_add_mem(buf, &stored_buf.data[offset],
2069 			       MIN(net_buf_simple_tailroom(buf), stored_buf.len - offset));
2070 
2071 	LOG_DBG("metadata read %d", buf->len);
2072 
2073 	if (buf->len == original_len) {
2074 		return -ENOENT;
2075 	}
2076 
2077 	return 0;
2078 }
2079 #endif
2080 
models_metadata_clear(void)2081 static void models_metadata_clear(void)
2082 {
2083 	int err;
2084 
2085 	err = settings_delete("bt/mesh/metadata");
2086 	if (err) {
2087 		LOG_ERR("Failed to clear models metadata: %d", err);
2088 	} else {
2089 		LOG_DBG("Cleared models metadata");
2090 	}
2091 
2092 	atomic_clear_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY);
2093 }
2094 
bt_mesh_comp_data_pending_clear(void)2095 void bt_mesh_comp_data_pending_clear(void)
2096 {
2097 	comp_data_clear();
2098 	models_metadata_clear();
2099 }
2100 
bt_mesh_comp_data_clear(void)2101 void bt_mesh_comp_data_clear(void)
2102 {
2103 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_COMP_PENDING);
2104 }
2105 
bt_mesh_models_metadata_change_prepare(void)2106 int bt_mesh_models_metadata_change_prepare(void)
2107 {
2108 #if IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
2109 	return bt_mesh_models_metadata_store();
2110 #else
2111 	return -ENOTSUP;
2112 #endif
2113 }
2114 
commit_mod(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)2115 static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
2116 		       bool vnd, bool primary, void *user_data)
2117 {
2118 	if (mod->pub && mod->pub->update &&
2119 	    mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
2120 		int32_t ms = bt_mesh_model_pub_period_get(mod);
2121 
2122 		if (ms > 0) {
2123 			LOG_DBG("Starting publish timer (period %u ms)", ms);
2124 			k_work_schedule(&mod->pub->timer, K_MSEC(ms));
2125 		}
2126 	}
2127 
2128 	if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
2129 		return;
2130 	}
2131 
2132 	for (int i = 0; i < mod->groups_cnt; i++) {
2133 		if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
2134 			bt_mesh_lpn_group_add(mod->groups[i]);
2135 		}
2136 	}
2137 }
2138 
bt_mesh_model_settings_commit(void)2139 void bt_mesh_model_settings_commit(void)
2140 {
2141 	bt_mesh_model_foreach(commit_mod, NULL);
2142 }
2143 
bt_mesh_model_data_store_schedule(struct bt_mesh_model * mod)2144 void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod)
2145 {
2146 	mod->flags |= BT_MESH_MOD_DATA_PENDING;
2147 	bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
2148 }
2149