1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <sys/util.h>
11 #include <sys/byteorder.h>
12
13 #include <net/buf.h>
14 #include <bluetooth/bluetooth.h>
15 #include <bluetooth/mesh.h>
16
17 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_ACCESS)
18 #define LOG_MODULE_NAME bt_mesh_access
19 #include "common/log.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 "settings.h"
29
30 /* bt_mesh_model.flags */
31 enum {
32 BT_MESH_MOD_BIND_PENDING = BIT(0),
33 BT_MESH_MOD_SUB_PENDING = BIT(1),
34 BT_MESH_MOD_PUB_PENDING = BIT(2),
35 BT_MESH_MOD_EXTENDED = BIT(3),
36 };
37
38 /* Model publication information for persistent storage. */
39 struct mod_pub_val {
40 uint16_t addr;
41 uint16_t key;
42 uint8_t ttl;
43 uint8_t retransmit;
44 uint8_t period;
45 uint8_t period_div:4,
46 cred:1;
47 };
48
49 static const struct bt_mesh_comp *dev_comp;
50 static uint16_t dev_primary_addr;
51 static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
52
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)53 void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
54 struct bt_mesh_elem *elem,
55 bool vnd, bool primary,
56 void *user_data),
57 void *user_data)
58 {
59 int i, j;
60
61 for (i = 0; i < dev_comp->elem_count; i++) {
62 struct bt_mesh_elem *elem = &dev_comp->elem[i];
63
64 for (j = 0; j < elem->model_count; j++) {
65 struct bt_mesh_model *model = &elem->models[j];
66
67 func(model, elem, false, i == 0, user_data);
68 }
69
70 for (j = 0; j < elem->vnd_model_count; j++) {
71 struct bt_mesh_model *model = &elem->vnd_models[j];
72
73 func(model, elem, true, i == 0, user_data);
74 }
75 }
76 }
77
bt_mesh_model_pub_period_get(struct bt_mesh_model * mod)78 int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod)
79 {
80 int32_t period;
81
82 if (!mod->pub) {
83 return 0;
84 }
85
86 switch (mod->pub->period >> 6) {
87 case 0x00:
88 /* 1 step is 100 ms */
89 period = (mod->pub->period & BIT_MASK(6)) * 100U;
90 break;
91 case 0x01:
92 /* 1 step is 1 second */
93 period = (mod->pub->period & BIT_MASK(6)) * MSEC_PER_SEC;
94 break;
95 case 0x02:
96 /* 1 step is 10 seconds */
97 period = (mod->pub->period & BIT_MASK(6)) * 10U * MSEC_PER_SEC;
98 break;
99 case 0x03:
100 /* 1 step is 10 minutes */
101 period = (mod->pub->period & BIT_MASK(6)) * 600U * MSEC_PER_SEC;
102 break;
103 default:
104 CODE_UNREACHABLE;
105 }
106
107 if (mod->pub->fast_period) {
108 return period >> mod->pub->period_div;
109 } else {
110 return period;
111 }
112 }
113
next_period(struct bt_mesh_model * mod)114 static int32_t next_period(struct bt_mesh_model *mod)
115 {
116 struct bt_mesh_model_pub *pub = mod->pub;
117 uint32_t elapsed, period;
118
119 period = bt_mesh_model_pub_period_get(mod);
120 if (!period) {
121 return 0;
122 }
123
124 elapsed = k_uptime_get_32() - pub->period_start;
125
126 BT_DBG("Publishing took %ums", elapsed);
127
128 if (elapsed >= period) {
129 BT_WARN("Publication sending took longer than the period");
130 /* Return smallest positive number since 0 means disabled */
131 return 1;
132 }
133
134 return period - elapsed;
135 }
136
publish_sent(int err,void * user_data)137 static void publish_sent(int err, void *user_data)
138 {
139 struct bt_mesh_model *mod = user_data;
140 int32_t delay;
141
142 BT_DBG("err %d", err);
143
144 if (mod->pub->count) {
145 delay = BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit);
146 } else {
147 delay = next_period(mod);
148 }
149
150 if (delay) {
151 BT_DBG("Publishing next time in %dms", delay);
152 /* Using schedule() in case the application has already called
153 * bt_mesh_publish, and a publication is pending.
154 */
155 k_work_schedule(&mod->pub->timer, K_MSEC(delay));
156 }
157 }
158
publish_start(uint16_t duration,int err,void * user_data)159 static void publish_start(uint16_t duration, int err, void *user_data)
160 {
161 struct bt_mesh_model *mod = user_data;
162 struct bt_mesh_model_pub *pub = mod->pub;
163
164 if (err) {
165 BT_ERR("Failed to publish: err %d", err);
166 publish_sent(err, user_data);
167 return;
168 }
169
170 /* Initialize the timestamp for the beginning of a new period */
171 if (pub->count == BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit)) {
172 pub->period_start = k_uptime_get_32();
173 }
174 }
175
176 static const struct bt_mesh_send_cb pub_sent_cb = {
177 .start = publish_start,
178 .end = publish_sent,
179 };
180
publish_transmit(struct bt_mesh_model * mod)181 static int publish_transmit(struct bt_mesh_model *mod)
182 {
183 NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
184 struct bt_mesh_model_pub *pub = mod->pub;
185 struct bt_mesh_msg_ctx ctx = {
186 .addr = pub->addr,
187 .send_ttl = pub->ttl,
188 .app_idx = pub->key,
189 };
190 struct bt_mesh_net_tx tx = {
191 .ctx = &ctx,
192 .src = bt_mesh_model_elem(mod)->addr,
193 .friend_cred = pub->cred,
194 };
195
196 net_buf_simple_add_mem(&sdu, pub->msg->data, pub->msg->len);
197
198 return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, mod);
199 }
200
pub_period_start(struct bt_mesh_model_pub * pub)201 static int pub_period_start(struct bt_mesh_model_pub *pub)
202 {
203 int err;
204
205 pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit);
206
207 if (!pub->update) {
208 return 0;
209 }
210
211 err = pub->update(pub->mod);
212 if (err) {
213 /* Skip this publish attempt. */
214 BT_DBG("Update failed, skipping publish (err: %d)", err);
215 pub->count = 0;
216 pub->period_start = k_uptime_get_32();
217 publish_sent(err, pub->mod);
218 return err;
219 }
220
221 return 0;
222 }
223
mod_publish(struct k_work * work)224 static void mod_publish(struct k_work *work)
225 {
226 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
227 struct bt_mesh_model_pub *pub = CONTAINER_OF(dwork,
228 struct bt_mesh_model_pub,
229 timer);
230 int err;
231
232 if (pub->addr == BT_MESH_ADDR_UNASSIGNED ||
233 atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
234 /* Publication is no longer active, but the cancellation of the
235 * delayed work failed. Abandon recurring timer.
236 */
237 return;
238 }
239
240 BT_DBG("");
241
242 if (pub->count) {
243 pub->count--;
244 } else {
245 /* First publication in this period */
246 err = pub_period_start(pub);
247 if (err) {
248 return;
249 }
250 }
251
252 err = publish_transmit(pub->mod);
253 if (err) {
254 BT_ERR("Failed to publish (err %d)", err);
255 if (pub->count == BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit)) {
256 pub->period_start = k_uptime_get_32();
257 }
258
259 publish_sent(err, pub->mod);
260 }
261 }
262
bt_mesh_model_elem(struct bt_mesh_model * mod)263 struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod)
264 {
265 return &dev_comp->elem[mod->elem_idx];
266 }
267
bt_mesh_model_get(bool vnd,uint8_t elem_idx,uint8_t mod_idx)268 struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx)
269 {
270 struct bt_mesh_elem *elem;
271
272 if (elem_idx >= dev_comp->elem_count) {
273 BT_ERR("Invalid element index %u", elem_idx);
274 return NULL;
275 }
276
277 elem = &dev_comp->elem[elem_idx];
278
279 if (vnd) {
280 if (mod_idx >= elem->vnd_model_count) {
281 BT_ERR("Invalid vendor model index %u", mod_idx);
282 return NULL;
283 }
284
285 return &elem->vnd_models[mod_idx];
286 } else {
287 if (mod_idx >= elem->model_count) {
288 BT_ERR("Invalid SIG model index %u", mod_idx);
289 return NULL;
290 }
291
292 return &elem->models[mod_idx];
293 }
294 }
295
296 #if defined(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)
bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model * mod)297 static int bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model *mod)
298 {
299 uint16_t cid;
300 const struct bt_mesh_model_op *op;
301
302 for (op = mod->op; op->func; op++) {
303 cid = (uint16_t)(op->opcode & 0xffff);
304
305 if (cid == mod->vnd.company) {
306 continue;
307 }
308
309 BT_ERR("Invalid vendor model(company:0x%04x"
310 " id:0x%04x) message opcode 0x%08x",
311 mod->vnd.company, mod->vnd.id, op->opcode);
312
313 return -EINVAL;
314 }
315
316 return 0;
317 }
318 #endif
319
mod_init(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)320 static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
321 bool vnd, bool primary, void *user_data)
322 {
323 int i;
324 int *err = user_data;
325
326 if (*err) {
327 return;
328 }
329
330 if (mod->pub) {
331 mod->pub->mod = mod;
332 k_work_init_delayable(&mod->pub->timer, mod_publish);
333 }
334
335 for (i = 0; i < ARRAY_SIZE(mod->keys); i++) {
336 mod->keys[i] = BT_MESH_KEY_UNUSED;
337 }
338
339 mod->elem_idx = elem - dev_comp->elem;
340 if (vnd) {
341 mod->mod_idx = mod - elem->vnd_models;
342
343 if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE)) {
344 *err = bt_mesh_vnd_mod_msg_cid_check(mod);
345 if (*err) {
346 return;
347 }
348 }
349
350 } else {
351 mod->mod_idx = mod - elem->models;
352 }
353
354 if (mod->cb && mod->cb->init) {
355 *err = mod->cb->init(mod);
356 }
357 }
358
bt_mesh_comp_register(const struct bt_mesh_comp * comp)359 int bt_mesh_comp_register(const struct bt_mesh_comp *comp)
360 {
361 int err;
362
363 /* There must be at least one element */
364 if (!comp || !comp->elem_count) {
365 return -EINVAL;
366 }
367
368 dev_comp = comp;
369
370 err = 0;
371 bt_mesh_model_foreach(mod_init, &err);
372
373 return err;
374 }
375
bt_mesh_comp_provision(uint16_t addr)376 void bt_mesh_comp_provision(uint16_t addr)
377 {
378 int i;
379
380 dev_primary_addr = addr;
381
382 BT_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count);
383
384 for (i = 0; i < dev_comp->elem_count; i++) {
385 struct bt_mesh_elem *elem = &dev_comp->elem[i];
386
387 elem->addr = addr++;
388
389 BT_DBG("addr 0x%04x mod_count %u vnd_mod_count %u",
390 elem->addr, elem->model_count, elem->vnd_model_count);
391 }
392 }
393
bt_mesh_comp_unprovision(void)394 void bt_mesh_comp_unprovision(void)
395 {
396 BT_DBG("");
397
398 dev_primary_addr = BT_MESH_ADDR_UNASSIGNED;
399 }
400
bt_mesh_primary_addr(void)401 uint16_t bt_mesh_primary_addr(void)
402 {
403 return dev_primary_addr;
404 }
405
model_group_get(struct bt_mesh_model * mod,uint16_t addr)406 static uint16_t *model_group_get(struct bt_mesh_model *mod, uint16_t addr)
407 {
408 int i;
409
410 for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
411 if (mod->groups[i] == addr) {
412 return &mod->groups[i];
413 }
414 }
415
416 return NULL;
417 }
418
419 struct find_group_visitor_ctx {
420 uint16_t *entry;
421 struct bt_mesh_model *mod;
422 uint16_t addr;
423 };
424
find_group_mod_visitor(struct bt_mesh_model * mod,void * user_data)425 static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, void *user_data)
426 {
427 struct find_group_visitor_ctx *ctx = user_data;
428
429 if (mod->elem_idx != ctx->mod->elem_idx) {
430 return BT_MESH_WALK_CONTINUE;
431 }
432
433 ctx->entry = model_group_get(mod, ctx->addr);
434 if (ctx->entry) {
435 ctx->mod = mod;
436 return BT_MESH_WALK_STOP;
437 }
438
439 return BT_MESH_WALK_CONTINUE;
440 }
441
bt_mesh_model_find_group(struct bt_mesh_model ** mod,uint16_t addr)442 uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr)
443 {
444 struct find_group_visitor_ctx ctx = {
445 .mod = *mod,
446 .entry = NULL,
447 .addr = addr,
448 };
449
450 bt_mesh_model_extensions_walk(*mod, find_group_mod_visitor, &ctx);
451
452 *mod = ctx.mod;
453 return ctx.entry;
454 }
455
bt_mesh_elem_find_group(struct bt_mesh_elem * elem,uint16_t group_addr)456 static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem,
457 uint16_t group_addr)
458 {
459 struct bt_mesh_model *model;
460 uint16_t *match;
461 int i;
462
463 for (i = 0; i < elem->model_count; i++) {
464 model = &elem->models[i];
465
466 match = model_group_get(model, group_addr);
467 if (match) {
468 return model;
469 }
470 }
471
472 for (i = 0; i < elem->vnd_model_count; i++) {
473 model = &elem->vnd_models[i];
474
475 match = model_group_get(model, group_addr);
476 if (match) {
477 return model;
478 }
479 }
480
481 return NULL;
482 }
483
bt_mesh_elem_find(uint16_t addr)484 struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr)
485 {
486 uint16_t index;
487
488 if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
489 return NULL;
490 }
491
492 index = addr - dev_comp->elem[0].addr;
493 if (index >= dev_comp->elem_count) {
494 return NULL;
495 }
496
497 return &dev_comp->elem[index];
498 }
499
bt_mesh_has_addr(uint16_t addr)500 bool bt_mesh_has_addr(uint16_t addr)
501 {
502 uint16_t index;
503
504 if (BT_MESH_ADDR_IS_UNICAST(addr)) {
505 return bt_mesh_elem_find(addr) != NULL;
506 }
507
508 if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
509 return true;
510 }
511
512 for (index = 0; index < dev_comp->elem_count; index++) {
513 struct bt_mesh_elem *elem = &dev_comp->elem[index];
514
515 if (bt_mesh_elem_find_group(elem, addr)) {
516 return true;
517 }
518 }
519
520 return false;
521 }
522
523 #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))524 void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx,
525 struct net_buf_simple *buf))
526 {
527 msg_cb = cb;
528 }
529 #endif
530
bt_mesh_msg_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)531 int bt_mesh_msg_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr,
532 const struct bt_mesh_send_cb *cb, void *cb_data)
533 {
534 struct bt_mesh_net_tx tx = {
535 .ctx = ctx,
536 .src = src_addr,
537 };
538
539 BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx,
540 tx.ctx->app_idx, tx.ctx->addr);
541 BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
542
543 if (!bt_mesh_is_provisioned()) {
544 BT_ERR("Local node is not yet provisioned");
545 return -EAGAIN;
546 }
547
548 return bt_mesh_trans_send(&tx, buf, cb, cb_data);
549 }
550
bt_mesh_elem_count(void)551 uint8_t bt_mesh_elem_count(void)
552 {
553 return dev_comp->elem_count;
554 }
555
bt_mesh_model_has_key(struct bt_mesh_model * mod,uint16_t key)556 bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key)
557 {
558 int i;
559
560 for (i = 0; i < ARRAY_SIZE(mod->keys); i++) {
561 if (mod->keys[i] == key ||
562 (mod->keys[i] == BT_MESH_KEY_DEV_ANY &&
563 BT_MESH_IS_DEV_KEY(key))) {
564 return true;
565 }
566 }
567
568 return false;
569 }
570
model_has_dst(struct bt_mesh_model * mod,uint16_t dst)571 static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst)
572 {
573 if (BT_MESH_ADDR_IS_UNICAST(dst)) {
574 return (dev_comp->elem[mod->elem_idx].addr == dst);
575 } else if (BT_MESH_ADDR_IS_GROUP(dst) || BT_MESH_ADDR_IS_VIRTUAL(dst)) {
576 return !!bt_mesh_model_find_group(&mod, dst);
577 }
578
579 /* If a message with a fixed group address is sent to the access layer,
580 * the lower layers have already confirmed that we are subscribing to
581 * it. All models on the primary element should receive the message.
582 */
583 return mod->elem_idx == 0;
584 }
585
find_op(struct bt_mesh_elem * elem,uint32_t opcode,struct bt_mesh_model ** model)586 static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem,
587 uint32_t opcode, struct bt_mesh_model **model)
588 {
589 uint8_t i;
590 uint8_t count;
591 /* This value shall not be used in shipping end products. */
592 uint32_t cid = UINT32_MAX;
593 struct bt_mesh_model *models;
594
595 /* SIG models cannot contain 3-byte (vendor) OpCodes, and
596 * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so
597 * we only need to do the lookup in one of the model lists.
598 */
599 if (BT_MESH_MODEL_OP_LEN(opcode) < 3) {
600 models = elem->models;
601 count = elem->model_count;
602 } else {
603 models = elem->vnd_models;
604 count = elem->vnd_model_count;
605
606 cid = (uint16_t)(opcode & 0xffff);
607 }
608
609 for (i = 0U; i < count; i++) {
610
611 const struct bt_mesh_model_op *op;
612
613 if (IS_ENABLED(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) &&
614 cid != UINT32_MAX &&
615 cid != models[i].vnd.company) {
616 continue;
617 }
618
619 *model = &models[i];
620
621 for (op = (*model)->op; op->func; op++) {
622 if (op->opcode == opcode) {
623 return op;
624 }
625 }
626 }
627
628 *model = NULL;
629 return NULL;
630 }
631
get_opcode(struct net_buf_simple * buf,uint32_t * opcode)632 static int get_opcode(struct net_buf_simple *buf, uint32_t *opcode)
633 {
634 switch (buf->data[0] >> 6) {
635 case 0x00:
636 case 0x01:
637 if (buf->data[0] == 0x7f) {
638 BT_ERR("Ignoring RFU OpCode");
639 return -EINVAL;
640 }
641
642 *opcode = net_buf_simple_pull_u8(buf);
643 return 0;
644 case 0x02:
645 if (buf->len < 2) {
646 BT_ERR("Too short payload for 2-octet OpCode");
647 return -EINVAL;
648 }
649
650 *opcode = net_buf_simple_pull_be16(buf);
651 return 0;
652 case 0x03:
653 if (buf->len < 3) {
654 BT_ERR("Too short payload for 3-octet OpCode");
655 return -EINVAL;
656 }
657
658 *opcode = net_buf_simple_pull_u8(buf) << 16;
659 /* Using LE for the CID since the model layer is defined as
660 * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
661 * will declare the opcode in this way.
662 */
663 *opcode |= net_buf_simple_pull_le16(buf);
664 return 0;
665 }
666
667 CODE_UNREACHABLE;
668 }
669
bt_mesh_model_recv(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)670 void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
671 {
672 struct bt_mesh_model *model;
673 const struct bt_mesh_model_op *op;
674 uint32_t opcode;
675 int i;
676
677 BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx,
678 rx->ctx.addr, rx->ctx.recv_dst);
679 BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len));
680
681 if (get_opcode(buf, &opcode) < 0) {
682 BT_WARN("Unable to decode OpCode");
683 return;
684 }
685
686 BT_DBG("OpCode 0x%08x", opcode);
687
688 for (i = 0; i < dev_comp->elem_count; i++) {
689 struct net_buf_simple_state state;
690
691 op = find_op(&dev_comp->elem[i], opcode, &model);
692 if (!op) {
693 BT_DBG("No OpCode 0x%08x for elem %d", opcode, i);
694 continue;
695 }
696
697 if (!bt_mesh_model_has_key(model, rx->ctx.app_idx)) {
698 continue;
699 }
700
701 if (!model_has_dst(model, rx->ctx.recv_dst)) {
702 continue;
703 }
704
705 if ((op->len >= 0) && (buf->len < (size_t)op->len)) {
706 BT_ERR("Too short message for OpCode 0x%08x", opcode);
707 continue;
708 } else if ((op->len < 0) && (buf->len != (size_t)(-op->len))) {
709 BT_ERR("Invalid message size for OpCode 0x%08x",
710 opcode);
711 continue;
712 }
713
714 /* The callback will likely parse the buffer, so
715 * store the parsing state in case multiple models
716 * receive the message.
717 */
718 net_buf_simple_save(buf, &state);
719 (void)op->func(model, &rx->ctx, buf);
720 net_buf_simple_restore(buf, &state);
721 }
722
723 if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
724 msg_cb(opcode, &rx->ctx, buf);
725 }
726 }
727
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)728 int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
729 struct net_buf_simple *msg,
730 const struct bt_mesh_send_cb *cb, void *cb_data)
731 {
732 if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
733 BT_ERR("Model not bound to AppKey 0x%04x", ctx->app_idx);
734 return -EINVAL;
735 }
736
737 return bt_mesh_msg_send(ctx, msg, bt_mesh_model_elem(model)->addr, cb, cb_data);
738 }
739
bt_mesh_model_publish(struct bt_mesh_model * model)740 int bt_mesh_model_publish(struct bt_mesh_model *model)
741 {
742 struct bt_mesh_model_pub *pub = model->pub;
743
744 if (!pub) {
745 return -ENOTSUP;
746 }
747
748 BT_DBG("");
749
750 if (pub->addr == BT_MESH_ADDR_UNASSIGNED) {
751 return -EADDRNOTAVAIL;
752 }
753
754 if (!pub->msg || !pub->msg->len) {
755 BT_ERR("No publication message");
756 return -EINVAL;
757 }
758
759 if (pub->msg->len + BT_MESH_MIC_SHORT > BT_MESH_TX_SDU_MAX) {
760 BT_ERR("Message does not fit maximum SDU size");
761 return -EMSGSIZE;
762 }
763
764 if (pub->count) {
765 BT_WARN("Clearing publish retransmit timer");
766 }
767
768 /* Account for initial transmission */
769 pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit) + 1;
770
771 BT_DBG("Publish Retransmit Count %u Interval %ums", pub->count,
772 BT_MESH_PUB_TRANSMIT_INT(pub->retransmit));
773
774 k_work_reschedule(&pub->timer, K_NO_WAIT);
775
776 return 0;
777 }
778
bt_mesh_model_find_vnd(const struct bt_mesh_elem * elem,uint16_t company,uint16_t id)779 struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
780 uint16_t company, uint16_t id)
781 {
782 uint8_t i;
783
784 for (i = 0U; i < elem->vnd_model_count; i++) {
785 if (elem->vnd_models[i].vnd.company == company &&
786 elem->vnd_models[i].vnd.id == id) {
787 return &elem->vnd_models[i];
788 }
789 }
790
791 return NULL;
792 }
793
bt_mesh_model_find(const struct bt_mesh_elem * elem,uint16_t id)794 struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
795 uint16_t id)
796 {
797 uint8_t i;
798
799 for (i = 0U; i < elem->model_count; i++) {
800 if (elem->models[i].id == id) {
801 return &elem->models[i];
802 }
803 }
804
805 return NULL;
806 }
807
bt_mesh_comp_get(void)808 const struct bt_mesh_comp *bt_mesh_comp_get(void)
809 {
810 return dev_comp;
811 }
812
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)813 void bt_mesh_model_extensions_walk(struct bt_mesh_model *model,
814 enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod,
815 void *user_data),
816 void *user_data)
817 {
818 #ifndef CONFIG_BT_MESH_MODEL_EXTENSIONS
819 (void)cb(model, user_data);
820 return;
821 #else
822 struct bt_mesh_model *it;
823
824 if (model->next == NULL) {
825 (void)cb(model, user_data);
826 return;
827 }
828
829 for (it = model; (it != NULL) && (it->next != model); it = it->next) {
830 if (cb(it, user_data) == BT_MESH_WALK_STOP) {
831 return;
832 }
833 }
834 #endif
835 }
836
837 #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS
bt_mesh_model_extend(struct bt_mesh_model * extending_mod,struct bt_mesh_model * base_mod)838 int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_model *base_mod)
839 {
840 struct bt_mesh_model *a = extending_mod;
841 struct bt_mesh_model *b = base_mod;
842 struct bt_mesh_model *a_next = a->next;
843 struct bt_mesh_model *b_next = b->next;
844 struct bt_mesh_model *it;
845
846 base_mod->flags |= BT_MESH_MOD_EXTENDED;
847
848 if (a == b) {
849 return 0;
850 }
851
852 /* Check if a's list contains b */
853 for (it = a; (it != NULL) && (it->next != a); it = it->next) {
854 if (it == b) {
855 return 0;
856 }
857 }
858
859 /* Merge lists */
860 if (a_next) {
861 b->next = a_next;
862 } else {
863 b->next = a;
864 }
865
866 if (b_next) {
867 a->next = b_next;
868 } else {
869 a->next = b;
870 }
871
872 return 0;
873 }
874 #endif
875
bt_mesh_model_is_extended(struct bt_mesh_model * model)876 bool bt_mesh_model_is_extended(struct bt_mesh_model *model)
877 {
878 return model->flags & BT_MESH_MOD_EXTENDED;
879 }
880
mod_set_bind(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)881 static int mod_set_bind(struct bt_mesh_model *mod, size_t len_rd,
882 settings_read_cb read_cb, void *cb_arg)
883 {
884 ssize_t len;
885 int i;
886
887 /* Start with empty array regardless of cleared or set value */
888 for (i = 0; i < ARRAY_SIZE(mod->keys); i++) {
889 mod->keys[i] = BT_MESH_KEY_UNUSED;
890 }
891
892 if (len_rd == 0) {
893 BT_DBG("Cleared bindings for model");
894 return 0;
895 }
896
897 len = read_cb(cb_arg, mod->keys, sizeof(mod->keys));
898 if (len < 0) {
899 BT_ERR("Failed to read value (err %zd)", len);
900 return len;
901 }
902
903 BT_HEXDUMP_DBG(mod->keys, len, "val");
904
905 BT_DBG("Decoded %zu bound keys for model", len / sizeof(mod->keys[0]));
906 return 0;
907 }
908
mod_set_sub(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)909 static int mod_set_sub(struct bt_mesh_model *mod, size_t len_rd,
910 settings_read_cb read_cb, void *cb_arg)
911 {
912 ssize_t len;
913
914 /* Start with empty array regardless of cleared or set value */
915 (void)memset(mod->groups, 0, sizeof(mod->groups));
916
917 if (len_rd == 0) {
918 BT_DBG("Cleared subscriptions for model");
919 return 0;
920 }
921
922 len = read_cb(cb_arg, mod->groups, sizeof(mod->groups));
923 if (len < 0) {
924 BT_ERR("Failed to read value (err %zd)", len);
925 return len;
926 }
927
928 BT_HEXDUMP_DBG(mod->groups, len, "val");
929
930 BT_DBG("Decoded %zu subscribed group addresses for model",
931 len / sizeof(mod->groups[0]));
932 return 0;
933 }
934
mod_set_pub(struct bt_mesh_model * mod,size_t len_rd,settings_read_cb read_cb,void * cb_arg)935 static int mod_set_pub(struct bt_mesh_model *mod, size_t len_rd,
936 settings_read_cb read_cb, void *cb_arg)
937 {
938 struct mod_pub_val pub;
939 int err;
940
941 if (!mod->pub) {
942 BT_WARN("Model has no publication context!");
943 return -EINVAL;
944 }
945
946 if (len_rd == 0) {
947 mod->pub->addr = BT_MESH_ADDR_UNASSIGNED;
948 mod->pub->key = 0U;
949 mod->pub->cred = 0U;
950 mod->pub->ttl = 0U;
951 mod->pub->period = 0U;
952 mod->pub->retransmit = 0U;
953 mod->pub->count = 0U;
954
955 BT_DBG("Cleared publication for model");
956 return 0;
957 }
958
959 if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
960 return 0;
961 }
962
963 err = bt_mesh_settings_set(read_cb, cb_arg, &pub, sizeof(pub));
964 if (err) {
965 BT_ERR("Failed to set \'model-pub\'");
966 return err;
967 }
968
969 mod->pub->addr = pub.addr;
970 mod->pub->key = pub.key;
971 mod->pub->cred = pub.cred;
972 mod->pub->ttl = pub.ttl;
973 mod->pub->period = pub.period;
974 mod->pub->retransmit = pub.retransmit;
975 mod->pub->period_div = pub.period_div;
976 mod->pub->count = 0U;
977
978 BT_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x",
979 pub.addr, pub.key);
980
981 return 0;
982 }
983
mod_data_set(struct bt_mesh_model * mod,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)984 static int mod_data_set(struct bt_mesh_model *mod,
985 const char *name, size_t len_rd,
986 settings_read_cb read_cb, void *cb_arg)
987 {
988 const char *next;
989
990 settings_name_next(name, &next);
991
992 if (mod->cb && mod->cb->settings_set) {
993 return mod->cb->settings_set(mod, next, len_rd,
994 read_cb, cb_arg);
995 }
996
997 return 0;
998 }
999
mod_set(bool vnd,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1000 static int mod_set(bool vnd, const char *name, size_t len_rd,
1001 settings_read_cb read_cb, void *cb_arg)
1002 {
1003 struct bt_mesh_model *mod;
1004 uint8_t elem_idx, mod_idx;
1005 uint16_t mod_key;
1006 int len;
1007 const char *next;
1008
1009 if (!name) {
1010 BT_ERR("Insufficient number of arguments");
1011 return -ENOENT;
1012 }
1013
1014 mod_key = strtol(name, NULL, 16);
1015 elem_idx = mod_key >> 8;
1016 mod_idx = mod_key;
1017
1018 BT_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u",
1019 mod_key, elem_idx, mod_idx);
1020
1021 mod = bt_mesh_model_get(vnd, elem_idx, mod_idx);
1022 if (!mod) {
1023 BT_ERR("Failed to get model for elem_idx %u mod_idx %u",
1024 elem_idx, mod_idx);
1025 return -ENOENT;
1026 }
1027
1028 len = settings_name_next(name, &next);
1029
1030 if (!next) {
1031 BT_ERR("Insufficient number of arguments");
1032 return -ENOENT;
1033 }
1034
1035 if (!strncmp(next, "bind", len)) {
1036 return mod_set_bind(mod, len_rd, read_cb, cb_arg);
1037 }
1038
1039 if (!strncmp(next, "sub", len)) {
1040 return mod_set_sub(mod, len_rd, read_cb, cb_arg);
1041 }
1042
1043 if (!strncmp(next, "pub", len)) {
1044 return mod_set_pub(mod, len_rd, read_cb, cb_arg);
1045 }
1046
1047 if (!strncmp(next, "data", len)) {
1048 return mod_data_set(mod, next, len_rd, read_cb, cb_arg);
1049 }
1050
1051 BT_WARN("Unknown module key %s", next);
1052 return -ENOENT;
1053 }
1054
sig_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1055 static int sig_mod_set(const char *name, size_t len_rd,
1056 settings_read_cb read_cb, void *cb_arg)
1057 {
1058 return mod_set(false, name, len_rd, read_cb, cb_arg);
1059 }
1060
1061 BT_MESH_SETTINGS_DEFINE(sig_mod, "s", sig_mod_set);
1062
vnd_mod_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1063 static int vnd_mod_set(const char *name, size_t len_rd,
1064 settings_read_cb read_cb, void *cb_arg)
1065 {
1066 return mod_set(true, name, len_rd, read_cb, cb_arg);
1067 }
1068
1069 BT_MESH_SETTINGS_DEFINE(vnd_mod, "v", vnd_mod_set);
1070
encode_mod_path(struct bt_mesh_model * mod,bool vnd,const char * key,char * path,size_t path_len)1071 static void encode_mod_path(struct bt_mesh_model *mod, bool vnd,
1072 const char *key, char *path, size_t path_len)
1073 {
1074 uint16_t mod_key = (((uint16_t)mod->elem_idx << 8) | mod->mod_idx);
1075
1076 if (vnd) {
1077 snprintk(path, path_len, "bt/mesh/v/%x/%s", mod_key, key);
1078 } else {
1079 snprintk(path, path_len, "bt/mesh/s/%x/%s", mod_key, key);
1080 }
1081 }
1082
store_pending_mod_bind(struct bt_mesh_model * mod,bool vnd)1083 static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd)
1084 {
1085 uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
1086 char path[20];
1087 int i, count, err;
1088
1089 for (i = 0, count = 0; i < ARRAY_SIZE(mod->keys); i++) {
1090 if (mod->keys[i] != BT_MESH_KEY_UNUSED) {
1091 keys[count++] = mod->keys[i];
1092 BT_DBG("model key 0x%04x", mod->keys[i]);
1093 }
1094 }
1095
1096 encode_mod_path(mod, vnd, "bind", path, sizeof(path));
1097
1098 if (count) {
1099 err = settings_save_one(path, keys, count * sizeof(keys[0]));
1100 } else {
1101 err = settings_delete(path);
1102 }
1103
1104 if (err) {
1105 BT_ERR("Failed to store %s value", log_strdup(path));
1106 } else {
1107 BT_DBG("Stored %s value", log_strdup(path));
1108 }
1109 }
1110
store_pending_mod_sub(struct bt_mesh_model * mod,bool vnd)1111 static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd)
1112 {
1113 uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
1114 char path[20];
1115 int i, count, err;
1116
1117 for (i = 0, count = 0; i < CONFIG_BT_MESH_MODEL_GROUP_COUNT; i++) {
1118 if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
1119 groups[count++] = mod->groups[i];
1120 }
1121 }
1122
1123 encode_mod_path(mod, vnd, "sub", path, sizeof(path));
1124
1125 if (count) {
1126 err = settings_save_one(path, groups,
1127 count * sizeof(groups[0]));
1128 } else {
1129 err = settings_delete(path);
1130 }
1131
1132 if (err) {
1133 BT_ERR("Failed to store %s value", log_strdup(path));
1134 } else {
1135 BT_DBG("Stored %s value", log_strdup(path));
1136 }
1137 }
1138
store_pending_mod_pub(struct bt_mesh_model * mod,bool vnd)1139 static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd)
1140 {
1141 struct mod_pub_val pub;
1142 char path[20];
1143 int err;
1144
1145 encode_mod_path(mod, vnd, "pub", path, sizeof(path));
1146
1147 if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
1148 err = settings_delete(path);
1149 } else {
1150 pub.addr = mod->pub->addr;
1151 pub.key = mod->pub->key;
1152 pub.ttl = mod->pub->ttl;
1153 pub.retransmit = mod->pub->retransmit;
1154 pub.period = mod->pub->period;
1155 pub.period_div = mod->pub->period_div;
1156 pub.cred = mod->pub->cred;
1157
1158 err = settings_save_one(path, &pub, sizeof(pub));
1159 }
1160
1161 if (err) {
1162 BT_ERR("Failed to store %s value", log_strdup(path));
1163 } else {
1164 BT_DBG("Stored %s value", log_strdup(path));
1165 }
1166 }
1167
store_pending_mod(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)1168 static void store_pending_mod(struct bt_mesh_model *mod,
1169 struct bt_mesh_elem *elem, bool vnd,
1170 bool primary, void *user_data)
1171 {
1172 if (!mod->flags) {
1173 return;
1174 }
1175
1176 if (mod->flags & BT_MESH_MOD_BIND_PENDING) {
1177 mod->flags &= ~BT_MESH_MOD_BIND_PENDING;
1178 store_pending_mod_bind(mod, vnd);
1179 }
1180
1181 if (mod->flags & BT_MESH_MOD_SUB_PENDING) {
1182 mod->flags &= ~BT_MESH_MOD_SUB_PENDING;
1183 store_pending_mod_sub(mod, vnd);
1184 }
1185
1186 if (mod->flags & BT_MESH_MOD_PUB_PENDING) {
1187 mod->flags &= ~BT_MESH_MOD_PUB_PENDING;
1188 store_pending_mod_pub(mod, vnd);
1189 }
1190 }
1191
bt_mesh_model_pending_store(void)1192 void bt_mesh_model_pending_store(void)
1193 {
1194 bt_mesh_model_foreach(store_pending_mod, NULL);
1195 }
1196
bt_mesh_model_bind_store(struct bt_mesh_model * mod)1197 void bt_mesh_model_bind_store(struct bt_mesh_model *mod)
1198 {
1199 mod->flags |= BT_MESH_MOD_BIND_PENDING;
1200 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1201 }
1202
bt_mesh_model_sub_store(struct bt_mesh_model * mod)1203 void bt_mesh_model_sub_store(struct bt_mesh_model *mod)
1204 {
1205 mod->flags |= BT_MESH_MOD_SUB_PENDING;
1206 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1207 }
1208
bt_mesh_model_pub_store(struct bt_mesh_model * mod)1209 void bt_mesh_model_pub_store(struct bt_mesh_model *mod)
1210 {
1211 mod->flags |= BT_MESH_MOD_PUB_PENDING;
1212 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
1213 }
1214
bt_mesh_model_data_store(struct bt_mesh_model * mod,bool vnd,const char * name,const void * data,size_t data_len)1215 int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
1216 const char *name, const void *data,
1217 size_t data_len)
1218 {
1219 char path[30];
1220 int err;
1221
1222 encode_mod_path(mod, vnd, "data", path, sizeof(path));
1223 if (name) {
1224 strcat(path, "/");
1225 strncat(path, name, SETTINGS_MAX_DIR_DEPTH);
1226 }
1227
1228 if (data_len) {
1229 err = settings_save_one(path, data, data_len);
1230 } else {
1231 err = settings_delete(path);
1232 }
1233
1234 if (err) {
1235 BT_ERR("Failed to store %s value", log_strdup(path));
1236 } else {
1237 BT_DBG("Stored %s value", log_strdup(path));
1238 }
1239 return err;
1240 }
1241
commit_mod(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)1242 static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
1243 bool vnd, bool primary, void *user_data)
1244 {
1245 if (mod->pub && mod->pub->update &&
1246 mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
1247 int32_t ms = bt_mesh_model_pub_period_get(mod);
1248
1249 if (ms > 0) {
1250 BT_DBG("Starting publish timer (period %u ms)", ms);
1251 k_work_schedule(&mod->pub->timer, K_MSEC(ms));
1252 }
1253 }
1254
1255 if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
1256 return;
1257 }
1258
1259 for (int i = 0; i < ARRAY_SIZE(mod->groups); i++) {
1260 if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
1261 bt_mesh_lpn_group_add(mod->groups[i]);
1262 }
1263 }
1264 }
1265
bt_mesh_model_settings_commit(void)1266 void bt_mesh_model_settings_commit(void)
1267 {
1268 bt_mesh_model_foreach(commit_mod, NULL);
1269 }
1270