1 /* Bluetooth Mesh */
2
3 /*
4 * SPDX-FileCopyrightText: 2017 Intel Corporation
5 * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <string.h>
11 #include <errno.h>
12 #include <stdbool.h>
13
14 #include "btc_ble_mesh_config_model.h"
15
16 #include "mesh.h"
17 #include "adv.h"
18 #include "lpn.h"
19 #include "transport.h"
20 #include "crypto.h"
21 #include "access.h"
22 #include "beacon.h"
23 #include "foundation.h"
24 #include "friend.h"
25 #include "settings.h"
26 #include "cfg_srv.h"
27 #include "proxy_server.h"
28 #include "mesh_main.h"
29 #include "mesh_common.h"
30
31 #define DEFAULT_TTL 7
32
33 /* Maximum message length is 384 in BLE Mesh. Here for composition data,
34 * due to 1 octet opcode and 4 octets TransMIC, 379 octets can be used to
35 * store device composition data.
36 */
37 #define COMP_DATA_MAX_LEN 379
38
39 static struct bt_mesh_cfg_srv *conf;
40
41 static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT];
42
comp_add_elem(struct net_buf_simple * buf,struct bt_mesh_elem * elem,bool primary)43 static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
44 bool primary)
45 {
46 struct bt_mesh_model *mod = NULL;
47 int i;
48
49 if (net_buf_simple_tailroom(buf) <
50 4 + (elem->model_count * 2U) + (elem->vnd_model_count * 4U)) {
51 BT_ERR("Too large device composition");
52 return -E2BIG;
53 }
54
55 net_buf_simple_add_le16(buf, elem->loc);
56
57 net_buf_simple_add_u8(buf, elem->model_count);
58 net_buf_simple_add_u8(buf, elem->vnd_model_count);
59
60 for (i = 0; i < elem->model_count; i++) {
61 mod = &elem->models[i];
62 net_buf_simple_add_le16(buf, mod->id);
63 }
64
65 for (i = 0; i < elem->vnd_model_count; i++) {
66 mod = &elem->vnd_models[i];
67 net_buf_simple_add_le16(buf, mod->vnd.company);
68 net_buf_simple_add_le16(buf, mod->vnd.id);
69 }
70
71 return 0;
72 }
73
comp_get_page_0(struct net_buf_simple * buf)74 static int comp_get_page_0(struct net_buf_simple *buf)
75 {
76 const struct bt_mesh_comp *comp = NULL;
77 uint16_t feat = 0U;
78 int i;
79
80 comp = bt_mesh_comp_get();
81
82 if (IS_ENABLED(CONFIG_BLE_MESH_RELAY)) {
83 feat |= BLE_MESH_FEAT_RELAY;
84 }
85
86 if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
87 feat |= BLE_MESH_FEAT_PROXY;
88 }
89
90 if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
91 feat |= BLE_MESH_FEAT_FRIEND;
92 }
93
94 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
95 feat |= BLE_MESH_FEAT_LOW_POWER;
96 }
97
98 net_buf_simple_add_le16(buf, comp->cid);
99 net_buf_simple_add_le16(buf, comp->pid);
100 net_buf_simple_add_le16(buf, comp->vid);
101 net_buf_simple_add_le16(buf, CONFIG_BLE_MESH_CRPL);
102 net_buf_simple_add_le16(buf, feat);
103
104 for (i = 0; i < comp->elem_count; i++) {
105 int err;
106
107 err = comp_add_elem(buf, &comp->elem[i], i == 0);
108 if (err) {
109 return err;
110 }
111 }
112
113 return 0;
114 }
115
dev_comp_data_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)116 static void dev_comp_data_get(struct bt_mesh_model *model,
117 struct bt_mesh_msg_ctx *ctx,
118 struct net_buf_simple *buf)
119 {
120 struct net_buf_simple *sdu = NULL;
121 uint8_t page = 0U;
122
123 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
124 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
125 bt_hex(buf->data, buf->len));
126
127 page = net_buf_simple_pull_u8(buf);
128 if (page != 0U) {
129 BT_WARN("Composition page %u not available", page);
130 page = 0U;
131 }
132
133 sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, COMP_DATA_MAX_LEN));
134 if (!sdu) {
135 BT_ERR("%s, Out of memory", __func__);
136 return;
137 }
138
139 bt_mesh_model_msg_init(sdu, OP_DEV_COMP_DATA_STATUS);
140
141 net_buf_simple_add_u8(sdu, page);
142 if (comp_get_page_0(sdu) < 0) {
143 BT_ERR("Unable to get composition page 0");
144 bt_mesh_free_buf(sdu);
145 return;
146 }
147
148 if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
149 BT_ERR("Unable to send Config Composition Data Status");
150 }
151
152 bt_mesh_free_buf(sdu);
153 return;
154 }
155
get_model(struct bt_mesh_elem * elem,struct net_buf_simple * buf,bool * vnd)156 static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem,
157 struct net_buf_simple *buf, bool *vnd)
158 {
159 if (buf->len < 4) {
160 uint16_t id = 0U;
161
162 id = net_buf_simple_pull_le16(buf);
163
164 BT_DBG("ID 0x%04x addr 0x%04x", id, elem->addr);
165
166 *vnd = false;
167
168 return bt_mesh_model_find(elem, id);
169 } else {
170 uint16_t company = 0U, id = 0U;
171
172 company = net_buf_simple_pull_le16(buf);
173 id = net_buf_simple_pull_le16(buf);
174
175 BT_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id,
176 elem->addr);
177
178 *vnd = true;
179
180 return bt_mesh_model_find_vnd(elem, company, id);
181 }
182 }
183
app_key_is_valid(uint16_t app_idx)184 static bool app_key_is_valid(uint16_t app_idx)
185 {
186 int i;
187
188 for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
189 struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
190
191 if (key->net_idx != BLE_MESH_KEY_UNUSED &&
192 key->app_idx == app_idx) {
193 return true;
194 }
195 }
196
197 return false;
198 }
199
mod_pub_app_key_bound(struct bt_mesh_model * model,uint16_t app_idx)200 static bool mod_pub_app_key_bound(struct bt_mesh_model *model,
201 uint16_t app_idx)
202 {
203 int i;
204
205 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
206 if (model->keys[i] == app_idx) {
207 return true;
208 }
209 }
210
211 BT_ERR("Appkey(0x%02x) not bound to this model.", app_idx);
212 return false;
213 }
214
_mod_pub_set(struct bt_mesh_model * model,uint16_t pub_addr,uint16_t app_idx,uint8_t cred_flag,uint8_t ttl,uint8_t period,uint8_t retransmit,bool store)215 static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr,
216 uint16_t app_idx, uint8_t cred_flag, uint8_t ttl, uint8_t period,
217 uint8_t retransmit, bool store)
218 {
219 if (!model->pub) {
220 return STATUS_NVAL_PUB_PARAM;
221 }
222
223 if (!IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && cred_flag) {
224 return STATUS_FEAT_NOT_SUPP;
225 }
226
227 if (!model->pub->update && period) {
228 return STATUS_NVAL_PUB_PARAM;
229 }
230
231 if (pub_addr == BLE_MESH_ADDR_UNASSIGNED) {
232 if (model->pub->addr == BLE_MESH_ADDR_UNASSIGNED) {
233 return STATUS_SUCCESS;
234 }
235
236 model->pub->addr = BLE_MESH_ADDR_UNASSIGNED;
237 model->pub->key = 0U;
238 model->pub->cred = 0U;
239 model->pub->ttl = 0U;
240 model->pub->period = 0U;
241 model->pub->retransmit = 0U;
242 model->pub->count = 0U;
243
244 if (model->pub->update) {
245 k_delayed_work_cancel(&model->pub->timer);
246 }
247
248 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
249 bt_mesh_store_mod_pub(model);
250 }
251
252 return STATUS_SUCCESS;
253 }
254
255 /* For case MESH/NODE/CFG/MP/BI-03-C, need to check if appkey
256 * is bound to model identified by the ModelIdentifier.
257 */
258 if (!bt_mesh_app_key_find(app_idx) ||
259 !mod_pub_app_key_bound(model, app_idx)) {
260 return STATUS_INVALID_APPKEY;
261 }
262
263 model->pub->addr = pub_addr;
264 model->pub->key = app_idx;
265 model->pub->cred = cred_flag;
266 model->pub->ttl = ttl;
267 model->pub->period = period;
268 model->pub->retransmit = retransmit;
269
270 if (model->pub->update) {
271 int32_t period_ms;
272
273 period_ms = bt_mesh_model_pub_period_get(model);
274 BT_DBG("period %u ms", period_ms);
275
276 if (period_ms) {
277 k_delayed_work_submit(&model->pub->timer, period_ms);
278 } else {
279 k_delayed_work_cancel(&model->pub->timer);
280 }
281 }
282
283 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
284 bt_mesh_store_mod_pub(model);
285 }
286
287 return STATUS_SUCCESS;
288 }
289
mod_bind(struct bt_mesh_model * model,uint16_t key_idx)290 static uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx)
291 {
292 int i;
293
294 BT_DBG("model %p key_idx 0x%03x", model, key_idx);
295
296 if (!app_key_is_valid(key_idx)) {
297 return STATUS_INVALID_APPKEY;
298 }
299
300 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
301 /* Treat existing binding as success */
302 if (model->keys[i] == key_idx) {
303 return STATUS_SUCCESS;
304 }
305 }
306
307 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
308 if (model->keys[i] == BLE_MESH_KEY_UNUSED) {
309 model->keys[i] = key_idx;
310
311 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
312 bt_mesh_store_mod_bind(model);
313 }
314
315 return STATUS_SUCCESS;
316 }
317 }
318
319 return STATUS_INSUFF_RESOURCES;
320 }
321
mod_unbind(struct bt_mesh_model * model,uint16_t key_idx,bool store)322 static uint8_t mod_unbind(struct bt_mesh_model *model, uint16_t key_idx, bool store)
323 {
324 int i;
325
326 BT_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store);
327
328 if (!app_key_is_valid(key_idx)) {
329 return STATUS_INVALID_APPKEY;
330 }
331
332 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
333 if (model->keys[i] != key_idx) {
334 continue;
335 }
336
337 model->keys[i] = BLE_MESH_KEY_UNUSED;
338
339 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
340 bt_mesh_store_mod_bind(model);
341 }
342
343 if (model->pub && model->pub->key == key_idx) {
344 _mod_pub_set(model, BLE_MESH_ADDR_UNASSIGNED,
345 0, 0, 0, 0, 0, store);
346 }
347 }
348
349 return STATUS_SUCCESS;
350 }
351
bt_mesh_app_key_alloc(uint16_t app_idx)352 struct bt_mesh_app_key *bt_mesh_app_key_alloc(uint16_t app_idx)
353 {
354 int i;
355
356 for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
357 struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
358
359 if (key->net_idx == BLE_MESH_KEY_UNUSED) {
360 return key;
361 }
362 }
363
364 return NULL;
365 }
366
app_key_set(uint16_t net_idx,uint16_t app_idx,const uint8_t val[16],bool update)367 static uint8_t app_key_set(uint16_t net_idx, uint16_t app_idx, const uint8_t val[16],
368 bool update)
369 {
370 struct bt_mesh_app_keys *keys = NULL;
371 struct bt_mesh_app_key *key = NULL;
372 struct bt_mesh_subnet *sub = NULL;
373
374 BT_DBG("net_idx 0x%04x app_idx %04x update %u val %s",
375 net_idx, app_idx, update, bt_hex(val, 16));
376
377 sub = bt_mesh_subnet_get(net_idx);
378 if (!sub) {
379 return STATUS_INVALID_NETKEY;
380 }
381
382 key = bt_mesh_app_key_find(app_idx);
383 if (update) {
384 if (!key) {
385 return STATUS_INVALID_APPKEY;
386 }
387
388 if (key->net_idx != net_idx) {
389 return STATUS_INVALID_BINDING;
390 }
391
392 keys = &key->keys[1];
393
394 /* The AppKey Update message shall generate an error when node
395 * is in normal operation, Phase 2, or Phase 3 or in Phase 1
396 * when the AppKey Update message on a valid AppKeyIndex when
397 * the AppKey value is different.
398 */
399 if (sub->kr_phase != BLE_MESH_KR_PHASE_1) {
400 return STATUS_CANNOT_UPDATE;
401 }
402
403 if (key->updated) {
404 if (memcmp(keys->val, val, 16)) {
405 return STATUS_CANNOT_UPDATE;
406 } else {
407 return STATUS_SUCCESS;
408 }
409 }
410
411 key->updated = true;
412 } else {
413 if (key) {
414 if (key->net_idx == net_idx &&
415 !memcmp(key->keys[0].val, val, 16)) {
416 return STATUS_SUCCESS;
417 }
418
419 if (key->net_idx == net_idx) {
420 return STATUS_IDX_ALREADY_STORED;
421 } else {
422 return STATUS_INVALID_NETKEY;
423 }
424 }
425
426 key = bt_mesh_app_key_alloc(app_idx);
427 if (!key) {
428 return STATUS_INSUFF_RESOURCES;
429 }
430
431 keys = &key->keys[0];
432 }
433
434 if (bt_mesh_app_id(val, &keys->id)) {
435 if (update) {
436 key->updated = false;
437 }
438
439 return STATUS_STORAGE_FAIL;
440 }
441
442 BT_DBG("app_idx 0x%04x AID 0x%02x", app_idx, keys->id);
443
444 key->net_idx = net_idx;
445 key->app_idx = app_idx;
446 memcpy(keys->val, val, 16);
447
448 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
449 BT_DBG("Storing AppKey persistently");
450 bt_mesh_store_app_key(key);
451 }
452
453 return STATUS_SUCCESS;
454 }
455
app_key_add(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)456 static void app_key_add(struct bt_mesh_model *model,
457 struct bt_mesh_msg_ctx *ctx,
458 struct net_buf_simple *buf)
459 {
460 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
461 uint16_t key_net_idx = 0U, key_app_idx = 0U;
462 uint8_t status = 0U;
463
464 key_idx_unpack(buf, &key_net_idx, &key_app_idx);
465
466 BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
467
468 bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS);
469
470 status = app_key_set(key_net_idx, key_app_idx, buf->data, false);
471 BT_DBG("status 0x%02x", status);
472 net_buf_simple_add_u8(&msg, status);
473
474 key_idx_pack(&msg, key_net_idx, key_app_idx);
475
476 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
477 BT_ERR("Unable to send Config AppKey Status");
478 return;
479 }
480
481 if (status == STATUS_SUCCESS) {
482 bt_mesh_cfg_server_state_change_t change = {0};
483 change.cfg_appkey_add.net_idx = key_net_idx;
484 change.cfg_appkey_add.app_idx = key_app_idx;
485 memcpy(change.cfg_appkey_add.app_key, buf->data, 16);
486 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
487 model, ctx, (const uint8_t *)&change, sizeof(change));
488 }
489 }
490
app_key_update(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)491 static void app_key_update(struct bt_mesh_model *model,
492 struct bt_mesh_msg_ctx *ctx,
493 struct net_buf_simple *buf)
494 {
495 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
496 uint16_t key_net_idx = 0U, key_app_idx = 0U;
497 uint8_t status = 0U;
498
499 key_idx_unpack(buf, &key_net_idx, &key_app_idx);
500
501 BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
502
503 bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS);
504
505 status = app_key_set(key_net_idx, key_app_idx, buf->data, true);
506 BT_DBG("status 0x%02x", status);
507 net_buf_simple_add_u8(&msg, status);
508
509 key_idx_pack(&msg, key_net_idx, key_app_idx);
510
511 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
512 BT_ERR("Unable to send Config AppKey Status");
513 }
514
515 if (status == STATUS_SUCCESS) {
516 bt_mesh_cfg_server_state_change_t change = {0};
517 change.cfg_appkey_update.net_idx = key_net_idx;
518 change.cfg_appkey_update.app_idx = key_app_idx;
519 memcpy(change.cfg_appkey_update.app_key, buf->data, 16);
520 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
521 model, ctx, (const uint8_t *)&change, sizeof(change));
522 }
523 }
524
525 struct unbind_data {
526 uint16_t app_idx;
527 bool store;
528 };
529
_mod_unbind(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)530 static void _mod_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
531 bool vnd, bool primary, void *user_data)
532 {
533 struct unbind_data *data = user_data;
534
535 mod_unbind(mod, data->app_idx, data->store);
536 }
537
bt_mesh_app_key_del(struct bt_mesh_app_key * key,bool store)538 void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store)
539 {
540 struct unbind_data data = { .app_idx = key->app_idx, .store = store };
541
542 BT_DBG("AppIdx 0x%03x store %u", key->app_idx, store);
543
544 bt_mesh_model_foreach(_mod_unbind, &data);
545
546 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
547 bt_mesh_clear_app_key(key);
548 }
549
550 key->net_idx = BLE_MESH_KEY_UNUSED;
551 (void)memset(key->keys, 0, sizeof(key->keys));
552 }
553
app_key_del(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)554 static void app_key_del(struct bt_mesh_model *model,
555 struct bt_mesh_msg_ctx *ctx,
556 struct net_buf_simple *buf)
557 {
558 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
559 uint16_t key_net_idx = 0U, key_app_idx = 0U;
560 struct bt_mesh_app_key *key = NULL;
561 uint8_t status = 0U;
562
563 key_idx_unpack(buf, &key_net_idx, &key_app_idx);
564
565 BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
566
567 if (!bt_mesh_subnet_get(key_net_idx)) {
568 status = STATUS_INVALID_NETKEY;
569 goto send_status;
570 }
571
572 key = bt_mesh_app_key_find(key_app_idx);
573 if (!key) {
574 /* Treat as success since the client might have missed a
575 * previous response and is resending the request.
576 */
577 status = STATUS_SUCCESS;
578 goto send_status;
579 }
580
581 if (key->net_idx != key_net_idx) {
582 status = STATUS_INVALID_BINDING;
583 goto send_status;
584 }
585
586 bt_mesh_app_key_del(key, true);
587 status = STATUS_SUCCESS;
588
589 send_status:
590 bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS);
591
592 net_buf_simple_add_u8(&msg, status);
593
594 key_idx_pack(&msg, key_net_idx, key_app_idx);
595
596 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
597 BT_ERR("Unable to send Config AppKey Status");
598 }
599
600 if (status == STATUS_SUCCESS) {
601 bt_mesh_cfg_server_state_change_t change = {0};
602 change.cfg_appkey_delete.net_idx = key_net_idx;
603 change.cfg_appkey_delete.app_idx = key_app_idx;
604 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
605 model, ctx, (const uint8_t *)&change, sizeof(change));
606 }
607 }
608
609 /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */
610 #define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2)
611
app_key_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)612 static void app_key_get(struct bt_mesh_model *model,
613 struct bt_mesh_msg_ctx *ctx,
614 struct net_buf_simple *buf)
615 {
616 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST,
617 3 + IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT));
618 uint16_t get_idx = 0U, i = 0U, prev = 0U;
619 uint8_t status = 0U;
620
621 get_idx = net_buf_simple_pull_le16(buf);
622 if (get_idx > 0xfff) {
623 BT_ERR("Invalid NetKeyIndex 0x%04x", get_idx);
624 return;
625 }
626
627 BT_DBG("idx 0x%04x", get_idx);
628
629 bt_mesh_model_msg_init(&msg, OP_APP_KEY_LIST);
630
631 if (!bt_mesh_subnet_get(get_idx)) {
632 status = STATUS_INVALID_NETKEY;
633 } else {
634 status = STATUS_SUCCESS;
635 }
636
637 net_buf_simple_add_u8(&msg, status);
638 net_buf_simple_add_le16(&msg, get_idx);
639
640 if (status != STATUS_SUCCESS) {
641 goto send_status;
642 }
643
644 prev = BLE_MESH_KEY_UNUSED;
645 for (i = 0U; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
646 struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
647
648 if (key->net_idx != get_idx) {
649 continue;
650 }
651
652 if (prev == BLE_MESH_KEY_UNUSED) {
653 prev = key->app_idx;
654 continue;
655 }
656
657 key_idx_pack(&msg, prev, key->app_idx);
658 prev = BLE_MESH_KEY_UNUSED;
659 }
660
661 if (prev != BLE_MESH_KEY_UNUSED) {
662 net_buf_simple_add_le16(&msg, prev);
663 }
664
665 send_status:
666 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
667 BT_ERR("Unable to send Config AppKey List");
668 }
669 }
670
beacon_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)671 static void beacon_get(struct bt_mesh_model *model,
672 struct bt_mesh_msg_ctx *ctx,
673 struct net_buf_simple *buf)
674 {
675 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
676
677 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
678 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
679 bt_hex(buf->data, buf->len));
680
681 bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
682 net_buf_simple_add_u8(&msg, bt_mesh_beacon_get());
683
684 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
685 BT_ERR("Unable to send Config Beacon Status");
686 }
687 }
688
beacon_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)689 static void beacon_set(struct bt_mesh_model *model,
690 struct bt_mesh_msg_ctx *ctx,
691 struct net_buf_simple *buf)
692 {
693 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
694 struct bt_mesh_cfg_srv *cfg = model->user_data;
695
696 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
697 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
698 bt_hex(buf->data, buf->len));
699
700 if (!cfg) {
701 BT_WARN("No Configuration Server context available");
702 } else if (buf->data[0] == 0x00 || buf->data[0] == 0x01) {
703 if (buf->data[0] != cfg->beacon) {
704 cfg->beacon = buf->data[0];
705
706 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
707 bt_mesh_store_cfg();
708 }
709
710 if (cfg->beacon) {
711 bt_mesh_beacon_enable();
712 } else {
713 bt_mesh_beacon_disable();
714 }
715 }
716 } else {
717 BT_WARN("Invalid Config Beacon value 0x%02x", buf->data[0]);
718 return;
719 }
720
721 bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
722 net_buf_simple_add_u8(&msg, bt_mesh_beacon_get());
723
724 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
725 BT_ERR("Unable to send Config Beacon Status");
726 }
727 }
728
default_ttl_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)729 static void default_ttl_get(struct bt_mesh_model *model,
730 struct bt_mesh_msg_ctx *ctx,
731 struct net_buf_simple *buf)
732 {
733 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
734
735 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
736 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
737 bt_hex(buf->data, buf->len));
738
739 bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
740 net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get());
741
742 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
743 BT_ERR("Unable to send Config Default TTL Status");
744 }
745 }
746
default_ttl_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)747 static void default_ttl_set(struct bt_mesh_model *model,
748 struct bt_mesh_msg_ctx *ctx,
749 struct net_buf_simple *buf)
750 {
751 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
752 struct bt_mesh_cfg_srv *cfg = model->user_data;
753
754 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
755 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
756 bt_hex(buf->data, buf->len));
757
758 if (!cfg) {
759 BT_WARN("No Configuration Server context available");
760 } else if (buf->data[0] <= BLE_MESH_TTL_MAX && buf->data[0] != 0x01) {
761 if (cfg->default_ttl != buf->data[0]) {
762 cfg->default_ttl = buf->data[0];
763
764 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
765 bt_mesh_store_cfg();
766 }
767 }
768 } else {
769 BT_WARN("Prohibited Default TTL value 0x%02x", buf->data[0]);
770 return;
771 }
772
773 bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
774 net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get());
775
776 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
777 BT_ERR("Unable to send Config Default TTL Status");
778 }
779 }
780
send_gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)781 static void send_gatt_proxy_status(struct bt_mesh_model *model,
782 struct bt_mesh_msg_ctx *ctx)
783 {
784 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1);
785
786 bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
787 net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get());
788
789 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
790 BT_ERR("Unable to send Config GATT Proxy Status");
791 }
792 }
793
gatt_proxy_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)794 static void gatt_proxy_get(struct bt_mesh_model *model,
795 struct bt_mesh_msg_ctx *ctx,
796 struct net_buf_simple *buf)
797 {
798 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
799 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
800 bt_hex(buf->data, buf->len));
801
802 send_gatt_proxy_status(model, ctx);
803 }
804
gatt_proxy_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)805 static void gatt_proxy_set(struct bt_mesh_model *model,
806 struct bt_mesh_msg_ctx *ctx,
807 struct net_buf_simple *buf)
808 {
809 struct bt_mesh_cfg_srv *cfg = model->user_data;
810
811 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
812 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
813 bt_hex(buf->data, buf->len));
814
815 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
816 BT_WARN("Invalid GATT Proxy value 0x%02x", buf->data[0]);
817 return;
818 }
819
820 if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) ||
821 bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_NOT_SUPPORTED) {
822 goto send_status;
823 }
824
825 if (!cfg) {
826 BT_WARN("No Configuration Server context available");
827 goto send_status;
828 }
829
830 BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->data[0]);
831
832 if (cfg->gatt_proxy == buf->data[0]) {
833 goto send_status;
834 }
835
836 cfg->gatt_proxy = buf->data[0];
837
838 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
839 bt_mesh_store_cfg();
840 }
841
842 if (cfg->hb_pub.feat & BLE_MESH_FEAT_PROXY) {
843 bt_mesh_heartbeat_send();
844 }
845
846 send_status:
847 send_gatt_proxy_status(model, ctx);
848 }
849
net_transmit_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)850 static void net_transmit_get(struct bt_mesh_model *model,
851 struct bt_mesh_msg_ctx *ctx,
852 struct net_buf_simple *buf)
853 {
854 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
855
856 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
857 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
858 bt_hex(buf->data, buf->len));
859
860 bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
861 net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get());
862
863 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
864 BT_ERR("Unable to send Config Network Transmit Status");
865 }
866 }
867
net_transmit_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)868 static void net_transmit_set(struct bt_mesh_model *model,
869 struct bt_mesh_msg_ctx *ctx,
870 struct net_buf_simple *buf)
871 {
872 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
873 struct bt_mesh_cfg_srv *cfg = model->user_data;
874
875 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
876 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
877 bt_hex(buf->data, buf->len));
878
879 BT_DBG("Transmit 0x%02x (count %u interval %ums)", buf->data[0],
880 BLE_MESH_TRANSMIT_COUNT(buf->data[0]),
881 BLE_MESH_TRANSMIT_INT(buf->data[0]));
882
883 if (!cfg) {
884 BT_WARN("No Configuration Server context available");
885 } else {
886 cfg->net_transmit = buf->data[0];
887
888 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
889 bt_mesh_store_cfg();
890 }
891 }
892
893 bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
894 net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get());
895
896 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
897 BT_ERR("Unable to send Config Network Transmit Status");
898 }
899 }
900
relay_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)901 static void relay_get(struct bt_mesh_model *model,
902 struct bt_mesh_msg_ctx *ctx,
903 struct net_buf_simple *buf)
904 {
905 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
906
907 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
908 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
909 bt_hex(buf->data, buf->len));
910
911 bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
912 net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
913 net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
914
915 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
916 BT_ERR("Unable to send Config Relay Status");
917 }
918 }
919
relay_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)920 static void relay_set(struct bt_mesh_model *model,
921 struct bt_mesh_msg_ctx *ctx,
922 struct net_buf_simple *buf)
923 {
924 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
925 struct bt_mesh_cfg_srv *cfg = model->user_data;
926
927 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
928 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
929 bt_hex(buf->data, buf->len));
930
931 if (!cfg) {
932 BT_WARN("No Configuration Server context available");
933 } else if (buf->data[0] == 0x00 || buf->data[0] == 0x01) {
934 bool change;
935
936 if (cfg->relay == BLE_MESH_RELAY_NOT_SUPPORTED) {
937 change = false;
938 } else {
939 change = (cfg->relay != buf->data[0]);
940 cfg->relay = buf->data[0];
941 cfg->relay_retransmit = buf->data[1];
942
943 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
944 bt_mesh_store_cfg();
945 }
946 }
947
948 BT_DBG("Relay 0x%02x (%s) xmit 0x%02x (count %u interval %u)",
949 cfg->relay, change ? "changed" : "not changed",
950 cfg->relay_retransmit,
951 BLE_MESH_TRANSMIT_COUNT(cfg->relay_retransmit),
952 BLE_MESH_TRANSMIT_INT(cfg->relay_retransmit));
953
954 if ((cfg->hb_pub.feat & BLE_MESH_FEAT_RELAY) && change) {
955 bt_mesh_heartbeat_send();
956 }
957 } else {
958 BT_WARN("Invalid Relay value 0x%02x", buf->data[0]);
959 return;
960 }
961
962 bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
963 net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
964 net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
965
966 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
967 BT_ERR("Unable to send Config Relay Status");
968 }
969 }
970
send_mod_pub_status(struct bt_mesh_model * cfg_mod,struct bt_mesh_msg_ctx * ctx,uint16_t elem_addr,uint16_t pub_addr,bool vnd,struct bt_mesh_model * mod,uint8_t status,uint8_t * mod_id)971 static void send_mod_pub_status(struct bt_mesh_model *cfg_mod,
972 struct bt_mesh_msg_ctx *ctx,
973 uint16_t elem_addr, uint16_t pub_addr,
974 bool vnd, struct bt_mesh_model *mod,
975 uint8_t status, uint8_t *mod_id)
976 {
977 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14);
978
979 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
980
981 net_buf_simple_add_u8(&msg, status);
982 net_buf_simple_add_le16(&msg, elem_addr);
983
984 if (status != STATUS_SUCCESS) {
985 (void)memset(net_buf_simple_add(&msg, 7), 0, 7);
986 } else {
987 uint16_t idx_cred;
988
989 net_buf_simple_add_le16(&msg, pub_addr);
990
991 idx_cred = mod->pub->key | (uint16_t)mod->pub->cred << 12;
992 net_buf_simple_add_le16(&msg, idx_cred);
993 net_buf_simple_add_u8(&msg, mod->pub->ttl);
994 net_buf_simple_add_u8(&msg, mod->pub->period);
995 net_buf_simple_add_u8(&msg, mod->pub->retransmit);
996 }
997
998 if (vnd) {
999 memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
1000 } else {
1001 memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
1002 }
1003
1004 if (bt_mesh_model_send(cfg_mod, ctx, &msg, NULL, NULL)) {
1005 BT_ERR("Unable to send Config Model Publication Status");
1006 }
1007 }
1008
mod_pub_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1009 static void mod_pub_get(struct bt_mesh_model *model,
1010 struct bt_mesh_msg_ctx *ctx,
1011 struct net_buf_simple *buf)
1012 {
1013 uint16_t elem_addr = 0U, pub_addr = 0U;
1014 struct bt_mesh_model *mod = NULL;
1015 struct bt_mesh_elem *elem = NULL;
1016 uint8_t *mod_id = NULL, status = 0U;
1017 bool vnd = false;
1018
1019 elem_addr = net_buf_simple_pull_le16(buf);
1020 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1021 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1022 return;
1023 }
1024
1025 mod_id = buf->data;
1026
1027 BT_DBG("elem_addr 0x%04x", elem_addr);
1028
1029 elem = bt_mesh_elem_find(elem_addr);
1030 if (!elem) {
1031 mod = NULL;
1032 vnd = (buf->len == 4U);
1033 status = STATUS_INVALID_ADDRESS;
1034 goto send_status;
1035 }
1036
1037 mod = get_model(elem, buf, &vnd);
1038 if (!mod) {
1039 status = STATUS_INVALID_MODEL;
1040 goto send_status;
1041 }
1042
1043 if (!mod->pub) {
1044 status = STATUS_NVAL_PUB_PARAM;
1045 goto send_status;
1046 }
1047
1048 pub_addr = mod->pub->addr;
1049 status = STATUS_SUCCESS;
1050
1051 send_status:
1052 send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
1053 status, mod_id);
1054 }
1055
mod_pub_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1056 static void mod_pub_set(struct bt_mesh_model *model,
1057 struct bt_mesh_msg_ctx *ctx,
1058 struct net_buf_simple *buf)
1059 {
1060 uint8_t retransmit = 0U, status = 0U, pub_ttl = 0U, pub_period = 0U, cred_flag = 0U;
1061 uint16_t elem_addr = 0U, pub_addr = 0U, pub_app_idx = 0U;
1062 struct bt_mesh_model *mod = NULL;
1063 struct bt_mesh_elem *elem = NULL;
1064 uint8_t *mod_id = NULL;
1065 bool vnd = false;
1066
1067 elem_addr = net_buf_simple_pull_le16(buf);
1068 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1069 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1070 return;
1071 }
1072
1073 pub_addr = net_buf_simple_pull_le16(buf);
1074 pub_app_idx = net_buf_simple_pull_le16(buf);
1075 cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
1076 pub_app_idx &= BIT_MASK(12);
1077
1078 pub_ttl = net_buf_simple_pull_u8(buf);
1079 if (pub_ttl > BLE_MESH_TTL_MAX && pub_ttl != BLE_MESH_TTL_DEFAULT) {
1080 BT_ERR("Invalid TTL value 0x%02x", pub_ttl);
1081 return;
1082 }
1083
1084 pub_period = net_buf_simple_pull_u8(buf);
1085 retransmit = net_buf_simple_pull_u8(buf);
1086 mod_id = buf->data;
1087
1088 BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u",
1089 elem_addr, pub_addr, cred_flag);
1090 BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x",
1091 pub_app_idx, pub_ttl, pub_period);
1092 BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
1093 BLE_MESH_PUB_TRANSMIT_COUNT(retransmit),
1094 BLE_MESH_PUB_TRANSMIT_INT(retransmit));
1095
1096 elem = bt_mesh_elem_find(elem_addr);
1097 if (!elem) {
1098 mod = NULL;
1099 vnd = (buf->len == 4U);
1100 status = STATUS_INVALID_ADDRESS;
1101 goto send_status;
1102 }
1103
1104 mod = get_model(elem, buf, &vnd);
1105 if (!mod) {
1106 status = STATUS_INVALID_MODEL;
1107 goto send_status;
1108 }
1109
1110 status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl,
1111 pub_period, retransmit, true);
1112
1113 send_status:
1114 send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
1115 status, mod_id);
1116
1117 if (status == STATUS_SUCCESS && mod->pub) {
1118 bt_mesh_cfg_server_state_change_t change = {0};
1119 change.cfg_mod_pub_set.elem_addr = elem_addr;
1120 change.cfg_mod_pub_set.pub_addr = mod->pub->addr;
1121 change.cfg_mod_pub_set.app_idx = mod->pub->key;
1122 change.cfg_mod_pub_set.cred_flag = mod->pub->cred;
1123 change.cfg_mod_pub_set.ttl = mod->pub->ttl;
1124 change.cfg_mod_pub_set.period = mod->pub->period;
1125 change.cfg_mod_pub_set.transmit = mod->pub->retransmit;
1126 change.cfg_mod_pub_set.cid = vnd ? mod->vnd.company : 0xFFFF;
1127 change.cfg_mod_pub_set.mod_id = vnd ? mod->vnd.id : mod->id;
1128 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
1129 model, ctx, (const uint8_t *)&change, sizeof(change));
1130 }
1131 }
1132
get_label(uint16_t index)1133 struct label *get_label(uint16_t index)
1134 {
1135 if (index >= ARRAY_SIZE(labels)) {
1136 return NULL;
1137 }
1138
1139 return &labels[index];
1140 }
1141
1142 #if CONFIG_BLE_MESH_LABEL_COUNT > 0
va_store(struct label * store)1143 static inline void va_store(struct label *store)
1144 {
1145 bt_mesh_atomic_set_bit(store->flags, BLE_MESH_VA_CHANGED);
1146 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1147 bt_mesh_store_label();
1148 }
1149 }
1150
va_find(const uint8_t * label_uuid,struct label ** free_slot)1151 static struct label *va_find(const uint8_t *label_uuid,
1152 struct label **free_slot)
1153 {
1154 struct label *match = NULL;
1155 int i;
1156
1157 if (free_slot != NULL) {
1158 *free_slot = NULL;
1159 }
1160
1161 for (i = 0; i < ARRAY_SIZE(labels); i++) {
1162 if (labels[i].ref == 0) {
1163 if (free_slot != NULL) {
1164 *free_slot = &labels[i];
1165 }
1166 continue;
1167 }
1168
1169 if (!memcmp(labels[i].uuid, label_uuid, 16)) {
1170 match = &labels[i];
1171 }
1172 }
1173
1174 return match;
1175 }
1176
va_add(uint8_t * label_uuid,uint16_t * addr)1177 uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
1178 {
1179 struct label *update = NULL, *free_slot = NULL;
1180
1181 update = va_find(label_uuid, &free_slot);
1182 if (update) {
1183 update->ref++;
1184 va_store(update);
1185 if (addr) {
1186 *addr = update->addr;
1187 }
1188 return STATUS_SUCCESS;
1189 }
1190
1191 if (!free_slot) {
1192 return STATUS_INSUFF_RESOURCES;
1193 }
1194
1195 if (bt_mesh_virtual_addr(label_uuid, addr) < 0) {
1196 return STATUS_UNSPECIFIED;
1197 }
1198
1199 free_slot->ref = 1U;
1200 free_slot->addr = *addr;
1201 memcpy(free_slot->uuid, label_uuid, 16);
1202 va_store(free_slot);
1203
1204 return STATUS_SUCCESS;
1205 }
1206
va_del(uint8_t * label_uuid,uint16_t * addr)1207 uint8_t va_del(uint8_t *label_uuid, uint16_t *addr)
1208 {
1209 struct label *update = NULL;
1210
1211 update = va_find(label_uuid, NULL);
1212 if (update) {
1213 update->ref--;
1214
1215 if (addr) {
1216 *addr = update->addr;
1217 }
1218
1219 va_store(update);
1220 return STATUS_SUCCESS;
1221 }
1222
1223 if (addr) {
1224 *addr = BLE_MESH_ADDR_UNASSIGNED;
1225 }
1226
1227 return STATUS_CANNOT_REMOVE;
1228 }
1229
mod_sub_list_clear(struct bt_mesh_model * mod)1230 static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
1231 {
1232 uint8_t *label_uuid = NULL;
1233 size_t clear_count = 0U;
1234 int i;
1235
1236 /* Unref stored labels related to this model */
1237 for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) {
1238 if (!BLE_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) {
1239 if (mod->groups[i] != BLE_MESH_ADDR_UNASSIGNED) {
1240 mod->groups[i] = BLE_MESH_ADDR_UNASSIGNED;
1241 clear_count++;
1242 }
1243
1244 continue;
1245 }
1246
1247 label_uuid = bt_mesh_label_uuid_get(mod->groups[i]);
1248
1249 mod->groups[i] = BLE_MESH_ADDR_UNASSIGNED;
1250 clear_count++;
1251
1252 if (label_uuid) {
1253 va_del(label_uuid, NULL);
1254 } else {
1255 BT_ERR("Label UUID not found");
1256 }
1257 }
1258
1259 return clear_count;
1260 }
1261
mod_pub_va_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1262 static void mod_pub_va_set(struct bt_mesh_model *model,
1263 struct bt_mesh_msg_ctx *ctx,
1264 struct net_buf_simple *buf)
1265 {
1266 uint8_t retransmit = 0U, status = 0U, pub_ttl = 0U, pub_period = 0U, cred_flag = 0U;
1267 uint16_t elem_addr = 0U, pub_addr = 0U, pub_app_idx = 0U;
1268 struct bt_mesh_model *mod = NULL;
1269 struct bt_mesh_elem *elem = NULL;
1270 uint8_t *label_uuid = NULL;
1271 uint8_t *mod_id = NULL;
1272 bool vnd = false;
1273
1274 elem_addr = net_buf_simple_pull_le16(buf);
1275 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1276 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1277 return;
1278 }
1279
1280 label_uuid = net_buf_simple_pull_mem(buf, 16);
1281 pub_app_idx = net_buf_simple_pull_le16(buf);
1282 cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
1283 pub_app_idx &= BIT_MASK(12);
1284 pub_ttl = net_buf_simple_pull_u8(buf);
1285 if (pub_ttl > BLE_MESH_TTL_MAX && pub_ttl != BLE_MESH_TTL_DEFAULT) {
1286 BT_ERR("Invalid TTL value 0x%02x", pub_ttl);
1287 return;
1288 }
1289
1290 pub_period = net_buf_simple_pull_u8(buf);
1291 retransmit = net_buf_simple_pull_u8(buf);
1292 mod_id = buf->data;
1293
1294 BT_DBG("elem_addr 0x%04x cred_flag %u", elem_addr, cred_flag);
1295 BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x",
1296 pub_app_idx, pub_ttl, pub_period);
1297 BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
1298 BLE_MESH_PUB_TRANSMIT_COUNT(retransmit),
1299 BLE_MESH_PUB_TRANSMIT_INT(retransmit));
1300
1301 elem = bt_mesh_elem_find(elem_addr);
1302 if (!elem) {
1303 mod = NULL;
1304 vnd = (buf->len == 4U);
1305 pub_addr = 0U;
1306 status = STATUS_INVALID_ADDRESS;
1307 goto send_status;
1308 }
1309
1310 mod = get_model(elem, buf, &vnd);
1311 if (!mod) {
1312 pub_addr = 0U;
1313 status = STATUS_INVALID_MODEL;
1314 goto send_status;
1315 }
1316
1317 status = va_add(label_uuid, &pub_addr);
1318 if (status == STATUS_SUCCESS) {
1319 status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag,
1320 pub_ttl, pub_period, retransmit, true);
1321 }
1322
1323 send_status:
1324 send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
1325 status, mod_id);
1326 }
1327 #else
mod_sub_list_clear(struct bt_mesh_model * mod)1328 static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
1329 {
1330 size_t clear_count = 0U;
1331 int i;
1332
1333 /* Unref stored labels related to this model */
1334 for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) {
1335 if (mod->groups[i] != BLE_MESH_ADDR_UNASSIGNED) {
1336 mod->groups[i] = BLE_MESH_ADDR_UNASSIGNED;
1337 clear_count++;
1338 }
1339 }
1340
1341 return clear_count;
1342 }
1343
mod_pub_va_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1344 static void mod_pub_va_set(struct bt_mesh_model *model,
1345 struct bt_mesh_msg_ctx *ctx,
1346 struct net_buf_simple *buf)
1347 {
1348 uint8_t *mod_id = NULL, status = 0U;
1349 struct bt_mesh_model *mod = NULL;
1350 struct bt_mesh_elem *elem = NULL;
1351 uint16_t elem_addr = 0U, pub_addr = 0U;
1352 bool vnd = false;
1353
1354 elem_addr = net_buf_simple_pull_le16(buf);
1355 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1356 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1357 return;
1358 }
1359
1360 net_buf_simple_pull(buf, 16);
1361 mod_id = net_buf_simple_pull(buf, 4);
1362
1363 BT_DBG("elem_addr 0x%04x", elem_addr);
1364
1365 elem = bt_mesh_elem_find(elem_addr);
1366 if (!elem) {
1367 mod = NULL;
1368 vnd = (buf->len == 4U);
1369 status = STATUS_INVALID_ADDRESS;
1370 goto send_status;
1371 }
1372
1373 mod = get_model(elem, buf, &vnd);
1374 if (!mod) {
1375 status = STATUS_INVALID_MODEL;
1376 goto send_status;
1377 }
1378
1379 if (!mod->pub) {
1380 status = STATUS_NVAL_PUB_PARAM;
1381 goto send_status;
1382 }
1383
1384 pub_addr = mod->pub->addr;
1385 status = STATUS_INSUFF_RESOURCES;
1386
1387 send_status:
1388 send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
1389 status, mod_id);
1390 }
1391 #endif /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */
1392
send_mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status,uint16_t elem_addr,uint16_t sub_addr,uint8_t * mod_id,bool vnd)1393 static void send_mod_sub_status(struct bt_mesh_model *model,
1394 struct bt_mesh_msg_ctx *ctx, uint8_t status,
1395 uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id,
1396 bool vnd)
1397 {
1398 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9);
1399
1400 BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status,
1401 elem_addr, sub_addr);
1402
1403 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_STATUS);
1404
1405 net_buf_simple_add_u8(&msg, status);
1406 net_buf_simple_add_le16(&msg, elem_addr);
1407 net_buf_simple_add_le16(&msg, sub_addr);
1408
1409 if (vnd) {
1410 memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
1411 } else {
1412 memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
1413 }
1414
1415 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1416 BT_ERR("Unable to send Config Model Subscription Status");
1417 }
1418 }
1419
mod_sub_add(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1420 static void mod_sub_add(struct bt_mesh_model *model,
1421 struct bt_mesh_msg_ctx *ctx,
1422 struct net_buf_simple *buf)
1423 {
1424 uint16_t elem_addr = 0U, sub_addr = 0U;
1425 struct bt_mesh_model *mod = NULL;
1426 struct bt_mesh_elem *elem = NULL;
1427 uint8_t *mod_id = NULL;
1428 uint8_t status = 0U;
1429 bool vnd = false;
1430 int i;
1431
1432 elem_addr = net_buf_simple_pull_le16(buf);
1433 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1434 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1435 return;
1436 }
1437
1438 sub_addr = net_buf_simple_pull_le16(buf);
1439
1440 BT_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr);
1441
1442 mod_id = buf->data;
1443
1444 elem = bt_mesh_elem_find(elem_addr);
1445 if (!elem) {
1446 mod = NULL;
1447 vnd = (buf->len == 4U);
1448 status = STATUS_INVALID_ADDRESS;
1449 goto send_status;
1450 }
1451
1452 mod = get_model(elem, buf, &vnd);
1453 if (!mod) {
1454 status = STATUS_INVALID_MODEL;
1455 goto send_status;
1456 }
1457
1458 if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) {
1459 status = STATUS_INVALID_ADDRESS;
1460 goto send_status;
1461 }
1462
1463 if (bt_mesh_model_find_group(mod, sub_addr)) {
1464 /* Tried to add existing subscription */
1465 BT_DBG("found existing subscription");
1466 status = STATUS_SUCCESS;
1467 goto send_status;
1468 }
1469
1470 BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT,
1471 "SubGroupAddr: 0x%x", sub_addr);
1472
1473 for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
1474 if (mod->groups[i] == BLE_MESH_ADDR_UNASSIGNED) {
1475 mod->groups[i] = sub_addr;
1476 break;
1477 }
1478 }
1479
1480 if (i == ARRAY_SIZE(mod->groups)) {
1481 status = STATUS_INSUFF_RESOURCES;
1482 } else {
1483 status = STATUS_SUCCESS;
1484
1485 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1486 bt_mesh_store_mod_sub(mod);
1487 }
1488
1489 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1490 bt_mesh_lpn_group_add(sub_addr);
1491 }
1492 }
1493
1494 send_status:
1495 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1496 mod_id, vnd);
1497
1498 if (status == STATUS_SUCCESS) {
1499 bt_mesh_cfg_server_state_change_t change = {0};
1500 change.cfg_mod_sub_add.elem_addr = elem_addr;
1501 change.cfg_mod_sub_add.sub_addr = sub_addr;
1502 change.cfg_mod_sub_add.cid = vnd ? mod->vnd.company : 0xFFFF;
1503 change.cfg_mod_sub_add.mod_id = vnd ? mod->vnd.id : mod->id;
1504 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
1505 model, ctx, (const uint8_t *)&change, sizeof(change));
1506 }
1507 }
1508
mod_sub_del(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1509 static void mod_sub_del(struct bt_mesh_model *model,
1510 struct bt_mesh_msg_ctx *ctx,
1511 struct net_buf_simple *buf)
1512 {
1513 uint16_t elem_addr = 0U, sub_addr = 0U;
1514 struct bt_mesh_model *mod = NULL;
1515 struct bt_mesh_elem *elem = NULL;
1516 uint8_t *mod_id = NULL;
1517 uint16_t *match = NULL;
1518 uint8_t status = 0U;
1519 bool vnd = false;
1520
1521 elem_addr = net_buf_simple_pull_le16(buf);
1522 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1523 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1524 return;
1525 }
1526
1527 sub_addr = net_buf_simple_pull_le16(buf);
1528
1529 BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
1530
1531 mod_id = buf->data;
1532
1533 elem = bt_mesh_elem_find(elem_addr);
1534 if (!elem) {
1535 mod = NULL;
1536 vnd = (buf->len == 4U);
1537 status = STATUS_INVALID_ADDRESS;
1538 goto send_status;
1539 }
1540
1541 mod = get_model(elem, buf, &vnd);
1542 if (!mod) {
1543 status = STATUS_INVALID_MODEL;
1544 goto send_status;
1545 }
1546
1547 if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) {
1548 status = STATUS_INVALID_ADDRESS;
1549 goto send_status;
1550 }
1551
1552 /* An attempt to remove a non-existing address shall be treated
1553 * as a success.
1554 */
1555 status = STATUS_SUCCESS;
1556
1557 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1558 bt_mesh_lpn_group_del(&sub_addr, 1);
1559 }
1560
1561 match = bt_mesh_model_find_group(mod, sub_addr);
1562 if (match) {
1563 *match = BLE_MESH_ADDR_UNASSIGNED;
1564
1565 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1566 bt_mesh_store_mod_sub(mod);
1567 }
1568 }
1569
1570 send_status:
1571 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1572 mod_id, vnd);
1573
1574 if (status == STATUS_SUCCESS) {
1575 bt_mesh_cfg_server_state_change_t change = {0};
1576 change.cfg_mod_sub_delete.elem_addr = elem_addr;
1577 change.cfg_mod_sub_delete.sub_addr = sub_addr;
1578 change.cfg_mod_sub_delete.cid = vnd ? mod->vnd.company : 0xFFFF;
1579 change.cfg_mod_sub_delete.mod_id = vnd ? mod->vnd.id : mod->id;
1580 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
1581 model, ctx, (const uint8_t *)&change, sizeof(change));
1582 }
1583 }
1584
mod_sub_overwrite(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1585 static void mod_sub_overwrite(struct bt_mesh_model *model,
1586 struct bt_mesh_msg_ctx *ctx,
1587 struct net_buf_simple *buf)
1588 {
1589 uint16_t elem_addr = 0U, sub_addr = 0U;
1590 struct bt_mesh_model *mod = NULL;
1591 struct bt_mesh_elem *elem = NULL;
1592 uint8_t *mod_id = NULL;
1593 uint8_t status = 0U;
1594 bool vnd = false;
1595
1596 elem_addr = net_buf_simple_pull_le16(buf);
1597 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1598 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1599 return;
1600 }
1601
1602 sub_addr = net_buf_simple_pull_le16(buf);
1603
1604 BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
1605
1606 mod_id = buf->data;
1607
1608 elem = bt_mesh_elem_find(elem_addr);
1609 if (!elem) {
1610 mod = NULL;
1611 vnd = (buf->len == 4U);
1612 status = STATUS_INVALID_ADDRESS;
1613 goto send_status;
1614 }
1615
1616 mod = get_model(elem, buf, &vnd);
1617 if (!mod) {
1618 status = STATUS_INVALID_MODEL;
1619 goto send_status;
1620 }
1621
1622 if (!BLE_MESH_ADDR_IS_GROUP(sub_addr)) {
1623 status = STATUS_INVALID_ADDRESS;
1624 goto send_status;
1625 }
1626
1627 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1628 bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups));
1629 }
1630
1631 mod_sub_list_clear(mod);
1632
1633 if (ARRAY_SIZE(mod->groups) > 0) {
1634 mod->groups[0] = sub_addr;
1635 status = STATUS_SUCCESS;
1636
1637 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1638 bt_mesh_store_mod_sub(mod);
1639 }
1640
1641 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1642 bt_mesh_lpn_group_add(sub_addr);
1643 }
1644 } else {
1645 status = STATUS_INSUFF_RESOURCES;
1646 }
1647
1648
1649 send_status:
1650 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1651 mod_id, vnd);
1652 }
1653
mod_sub_del_all(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1654 static void mod_sub_del_all(struct bt_mesh_model *model,
1655 struct bt_mesh_msg_ctx *ctx,
1656 struct net_buf_simple *buf)
1657 {
1658 struct bt_mesh_model *mod = NULL;
1659 struct bt_mesh_elem *elem = NULL;
1660 uint16_t elem_addr = 0U;
1661 uint8_t *mod_id = NULL;
1662 uint8_t status = 0U;
1663 bool vnd = false;
1664
1665 elem_addr = net_buf_simple_pull_le16(buf);
1666 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1667 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1668 return;
1669 }
1670
1671 BT_DBG("elem_addr 0x%04x", elem_addr);
1672
1673 mod_id = buf->data;
1674
1675 elem = bt_mesh_elem_find(elem_addr);
1676 if (!elem) {
1677 mod = NULL;
1678 vnd = (buf->len == 4U);
1679 status = STATUS_INVALID_ADDRESS;
1680 goto send_status;
1681 }
1682
1683 mod = get_model(elem, buf, &vnd);
1684 if (!mod) {
1685 status = STATUS_INVALID_MODEL;
1686 goto send_status;
1687 }
1688
1689 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1690 bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups));
1691 }
1692
1693 mod_sub_list_clear(mod);
1694
1695 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1696 bt_mesh_store_mod_sub(mod);
1697 }
1698
1699 status = STATUS_SUCCESS;
1700
1701 send_status:
1702 send_mod_sub_status(model, ctx, status, elem_addr,
1703 BLE_MESH_ADDR_UNASSIGNED, mod_id, vnd);
1704 }
1705
mod_sub_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1706 static void mod_sub_get(struct bt_mesh_model *model,
1707 struct bt_mesh_msg_ctx *ctx,
1708 struct net_buf_simple *buf)
1709 {
1710 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST,
1711 5 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
1712 struct bt_mesh_model *mod = NULL;
1713 struct bt_mesh_elem *elem = NULL;
1714 uint16_t addr = 0U, id = 0U;
1715 int i;
1716
1717 addr = net_buf_simple_pull_le16(buf);
1718 if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
1719 BT_ERR("Prohibited element address 0x%04x", addr);
1720 return;
1721 }
1722
1723 id = net_buf_simple_pull_le16(buf);
1724
1725 BT_DBG("addr 0x%04x id 0x%04x", addr, id);
1726
1727 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST);
1728
1729 elem = bt_mesh_elem_find(addr);
1730 if (!elem) {
1731 net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
1732 net_buf_simple_add_le16(&msg, addr);
1733 net_buf_simple_add_le16(&msg, id);
1734 goto send_list;
1735 }
1736
1737 mod = bt_mesh_model_find(elem, id);
1738 if (!mod) {
1739 net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
1740 net_buf_simple_add_le16(&msg, addr);
1741 net_buf_simple_add_le16(&msg, id);
1742 goto send_list;
1743 }
1744
1745 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
1746
1747 net_buf_simple_add_le16(&msg, addr);
1748 net_buf_simple_add_le16(&msg, id);
1749
1750 for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
1751 if (mod->groups[i] != BLE_MESH_ADDR_UNASSIGNED) {
1752 net_buf_simple_add_le16(&msg, mod->groups[i]);
1753 }
1754 }
1755
1756 send_list:
1757 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1758 BT_ERR("Unable to send Config Model Subscription List");
1759 }
1760 }
1761
mod_sub_get_vnd(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1762 static void mod_sub_get_vnd(struct bt_mesh_model *model,
1763 struct bt_mesh_msg_ctx *ctx,
1764 struct net_buf_simple *buf)
1765 {
1766 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST_VND,
1767 7 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
1768 struct bt_mesh_model *mod = NULL;
1769 struct bt_mesh_elem *elem = NULL;
1770 uint16_t company = 0U, addr = 0U, id = 0U;
1771 int i;
1772
1773 addr = net_buf_simple_pull_le16(buf);
1774 if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
1775 BT_ERR("Prohibited element address 0x%04x", addr);
1776 return;
1777 }
1778
1779 company = net_buf_simple_pull_le16(buf);
1780 id = net_buf_simple_pull_le16(buf);
1781
1782 BT_DBG("addr 0x%04x company 0x%04x id 0x%04x", addr, company, id);
1783
1784 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST_VND);
1785
1786 elem = bt_mesh_elem_find(addr);
1787 if (!elem) {
1788 net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
1789 net_buf_simple_add_le16(&msg, addr);
1790 net_buf_simple_add_le16(&msg, company);
1791 net_buf_simple_add_le16(&msg, id);
1792 goto send_list;
1793 }
1794
1795 mod = bt_mesh_model_find_vnd(elem, company, id);
1796 if (!mod) {
1797 net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
1798 net_buf_simple_add_le16(&msg, addr);
1799 net_buf_simple_add_le16(&msg, company);
1800 net_buf_simple_add_le16(&msg, id);
1801 goto send_list;
1802 }
1803
1804 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
1805
1806 net_buf_simple_add_le16(&msg, addr);
1807 net_buf_simple_add_le16(&msg, company);
1808 net_buf_simple_add_le16(&msg, id);
1809
1810 for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
1811 if (mod->groups[i] != BLE_MESH_ADDR_UNASSIGNED) {
1812 net_buf_simple_add_le16(&msg, mod->groups[i]);
1813 }
1814 }
1815
1816 send_list:
1817 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1818 BT_ERR("Unable to send Config Vendor Model Subscription List");
1819 }
1820 }
1821
1822 #if CONFIG_BLE_MESH_LABEL_COUNT > 0
mod_sub_va_add(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1823 static void mod_sub_va_add(struct bt_mesh_model *model,
1824 struct bt_mesh_msg_ctx *ctx,
1825 struct net_buf_simple *buf)
1826 {
1827 uint16_t elem_addr = 0U, sub_addr = 0U;
1828 struct bt_mesh_model *mod = NULL;
1829 struct bt_mesh_elem *elem = NULL;
1830 uint8_t *label_uuid = NULL;
1831 uint8_t *mod_id = NULL;
1832 uint8_t status = 0U;
1833 bool vnd = false;
1834 int i;
1835
1836 elem_addr = net_buf_simple_pull_le16(buf);
1837 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1838 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1839 return;
1840 }
1841
1842 label_uuid = net_buf_simple_pull_mem(buf, 16);
1843
1844 BT_DBG("elem_addr 0x%04x", elem_addr);
1845
1846 mod_id = buf->data;
1847 elem = bt_mesh_elem_find(elem_addr);
1848 if (!elem) {
1849 mod = NULL;
1850 vnd = (buf->len == 4U);
1851 sub_addr = BLE_MESH_ADDR_UNASSIGNED;
1852 status = STATUS_INVALID_ADDRESS;
1853 goto send_status;
1854 }
1855
1856 mod = get_model(elem, buf, &vnd);
1857 if (!mod) {
1858 sub_addr = BLE_MESH_ADDR_UNASSIGNED;
1859 status = STATUS_INVALID_MODEL;
1860 goto send_status;
1861 }
1862
1863 status = va_add(label_uuid, &sub_addr);
1864 if (status != STATUS_SUCCESS) {
1865 goto send_status;
1866 }
1867
1868 if (bt_mesh_model_find_group(mod, sub_addr)) {
1869 /* Tried to add existing subscription */
1870 status = STATUS_SUCCESS;
1871 goto send_status;
1872 }
1873
1874 BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_TNPT,
1875 "SubVirtualAddr: 0x%x", sub_addr);
1876
1877 for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
1878 if (mod->groups[i] == BLE_MESH_ADDR_UNASSIGNED) {
1879 mod->groups[i] = sub_addr;
1880 break;
1881 }
1882 }
1883
1884 if (i == ARRAY_SIZE(mod->groups)) {
1885 status = STATUS_INSUFF_RESOURCES;
1886 } else {
1887 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1888 bt_mesh_lpn_group_add(sub_addr);
1889 }
1890
1891 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1892 bt_mesh_store_mod_sub(mod);
1893 }
1894
1895 status = STATUS_SUCCESS;
1896 }
1897
1898 send_status:
1899 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1900 mod_id, vnd);
1901 }
1902
mod_sub_va_del(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1903 static void mod_sub_va_del(struct bt_mesh_model *model,
1904 struct bt_mesh_msg_ctx *ctx,
1905 struct net_buf_simple *buf)
1906 {
1907 uint16_t elem_addr = 0U, sub_addr = 0U;
1908 struct bt_mesh_model *mod = NULL;
1909 struct bt_mesh_elem *elem = NULL;
1910 uint8_t *label_uuid = NULL;
1911 uint8_t *mod_id = NULL;
1912 uint16_t *match = NULL;
1913 uint8_t status = 0U;
1914 bool vnd = false;
1915
1916 elem_addr = net_buf_simple_pull_le16(buf);
1917 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1918 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1919 return;
1920 }
1921
1922 label_uuid = net_buf_simple_pull_mem(buf, 16);
1923
1924 BT_DBG("elem_addr 0x%04x", elem_addr);
1925
1926 mod_id = buf->data;
1927
1928 elem = bt_mesh_elem_find(elem_addr);
1929 if (!elem) {
1930 mod = NULL;
1931 vnd = (buf->len == 4U);
1932 sub_addr = BLE_MESH_ADDR_UNASSIGNED;
1933 status = STATUS_INVALID_ADDRESS;
1934 goto send_status;
1935 }
1936
1937 mod = get_model(elem, buf, &vnd);
1938 if (!mod) {
1939 sub_addr = BLE_MESH_ADDR_UNASSIGNED;
1940 status = STATUS_INVALID_MODEL;
1941 goto send_status;
1942 }
1943
1944 status = va_del(label_uuid, &sub_addr);
1945 if (sub_addr == BLE_MESH_ADDR_UNASSIGNED) {
1946 goto send_status;
1947 }
1948
1949 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
1950 bt_mesh_lpn_group_del(&sub_addr, 1);
1951 }
1952
1953 match = bt_mesh_model_find_group(mod, sub_addr);
1954 if (match) {
1955 *match = BLE_MESH_ADDR_UNASSIGNED;
1956
1957 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1958 bt_mesh_store_mod_sub(mod);
1959 }
1960
1961 status = STATUS_SUCCESS;
1962 } else {
1963 status = STATUS_CANNOT_REMOVE;
1964 }
1965
1966 send_status:
1967 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1968 mod_id, vnd);
1969 }
1970
mod_sub_va_overwrite(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1971 static void mod_sub_va_overwrite(struct bt_mesh_model *model,
1972 struct bt_mesh_msg_ctx *ctx,
1973 struct net_buf_simple *buf)
1974 {
1975 uint16_t elem_addr = 0U, sub_addr = BLE_MESH_ADDR_UNASSIGNED;
1976 struct bt_mesh_model *mod = NULL;
1977 struct bt_mesh_elem *elem = NULL;
1978 uint8_t *label_uuid = NULL;
1979 uint8_t *mod_id = NULL;
1980 uint8_t status = 0U;
1981 bool vnd = false;
1982
1983 elem_addr = net_buf_simple_pull_le16(buf);
1984 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
1985 BT_ERR("Prohibited element address 0x%04x", elem_addr);
1986 return;
1987 }
1988
1989 label_uuid = net_buf_simple_pull_mem(buf, 16);
1990
1991 BT_DBG("elem_addr 0x%04x", elem_addr);
1992
1993 mod_id = buf->data;
1994
1995 elem = bt_mesh_elem_find(elem_addr);
1996 if (!elem) {
1997 mod = NULL;
1998 vnd = (buf->len == 4U);
1999 status = STATUS_INVALID_ADDRESS;
2000 goto send_status;
2001 }
2002
2003 mod = get_model(elem, buf, &vnd);
2004 if (!mod) {
2005 status = STATUS_INVALID_MODEL;
2006 goto send_status;
2007 }
2008
2009 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
2010 bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups));
2011 }
2012
2013 mod_sub_list_clear(mod);
2014
2015 if (ARRAY_SIZE(mod->groups) > 0) {
2016 status = va_add(label_uuid, &sub_addr);
2017 if (status == STATUS_SUCCESS) {
2018 mod->groups[0] = sub_addr;
2019
2020 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
2021 bt_mesh_store_mod_sub(mod);
2022 }
2023
2024 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
2025 bt_mesh_lpn_group_add(sub_addr);
2026 }
2027 }
2028 } else {
2029 status = STATUS_INSUFF_RESOURCES;
2030 }
2031
2032 send_status:
2033 send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
2034 mod_id, vnd);
2035 }
2036 #else
mod_sub_va_add(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2037 static void mod_sub_va_add(struct bt_mesh_model *model,
2038 struct bt_mesh_msg_ctx *ctx,
2039 struct net_buf_simple *buf)
2040 {
2041 struct bt_mesh_model *mod = NULL;
2042 struct bt_mesh_elem *elem = NULL;
2043 uint16_t elem_addr = 0U;
2044 uint8_t *mod_id = NULL;
2045 uint8_t status = 0U;
2046 bool vnd = false;
2047
2048 elem_addr = net_buf_simple_pull_le16(buf);
2049 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2050 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2051 return;
2052 }
2053
2054 net_buf_simple_pull(buf, 16);
2055
2056 mod_id = buf->data;
2057
2058 elem = bt_mesh_elem_find(elem_addr);
2059 if (!elem) {
2060 mod = NULL;
2061 vnd = (buf->len == 4U);
2062 status = STATUS_INVALID_ADDRESS;
2063 goto send_status;
2064 }
2065
2066 mod = get_model(elem, buf, &vnd);
2067 if (!mod) {
2068 status = STATUS_INVALID_MODEL;
2069 goto send_status;
2070 }
2071
2072 status = STATUS_INSUFF_RESOURCES;
2073
2074 send_status:
2075 send_mod_sub_status(model, ctx, status, elem_addr,
2076 BLE_MESH_ADDR_UNASSIGNED, mod_id, vnd);
2077 }
2078
mod_sub_va_del(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2079 static void mod_sub_va_del(struct bt_mesh_model *model,
2080 struct bt_mesh_msg_ctx *ctx,
2081 struct net_buf_simple *buf)
2082 {
2083 struct bt_mesh_elem *elem = NULL;
2084 uint16_t elem_addr = 0U;
2085 uint8_t *mod_id = NULL;
2086 uint8_t status = 0U;
2087 bool vnd = false;
2088
2089 elem_addr = net_buf_simple_pull_le16(buf);
2090 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2091 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2092 return;
2093 }
2094
2095 net_buf_simple_pull(buf, 16);
2096
2097 mod_id = buf->data;
2098
2099 elem = bt_mesh_elem_find(elem_addr);
2100 if (!elem) {
2101 vnd = (buf->len == 4U);
2102 status = STATUS_INVALID_ADDRESS;
2103 goto send_status;
2104 }
2105
2106 if (!get_model(elem, buf, &vnd)) {
2107 status = STATUS_INVALID_MODEL;
2108 goto send_status;
2109 }
2110
2111 status = STATUS_INSUFF_RESOURCES;
2112
2113 send_status:
2114 send_mod_sub_status(model, ctx, status, elem_addr,
2115 BLE_MESH_ADDR_UNASSIGNED, mod_id, vnd);
2116 }
2117
mod_sub_va_overwrite(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2118 static void mod_sub_va_overwrite(struct bt_mesh_model *model,
2119 struct bt_mesh_msg_ctx *ctx,
2120 struct net_buf_simple *buf)
2121 {
2122 struct bt_mesh_elem *elem = NULL;
2123 uint16_t elem_addr = 0U;
2124 uint8_t *mod_id = NULL;
2125 uint8_t status = 0U;
2126 bool vnd = false;
2127
2128 elem_addr = net_buf_simple_pull_le16(buf);
2129 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2130 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2131 return;
2132 }
2133
2134 net_buf_simple_pull(buf, 18);
2135
2136 mod_id = buf->data;
2137
2138 elem = bt_mesh_elem_find(elem_addr);
2139 if (!elem) {
2140 vnd = (buf->len == 4U);
2141 status = STATUS_INVALID_ADDRESS;
2142 goto send_status;
2143 }
2144
2145 if (!get_model(elem, buf, &vnd)) {
2146 status = STATUS_INVALID_MODEL;
2147 goto send_status;
2148 }
2149
2150 status = STATUS_INSUFF_RESOURCES;
2151
2152 send_status:
2153 send_mod_sub_status(model, ctx, status, elem_addr,
2154 BLE_MESH_ADDR_UNASSIGNED, mod_id, vnd);
2155 }
2156 #endif /* CONFIG_BLE_MESH_LABEL_COUNT > 0 */
2157
send_net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t idx,uint8_t status)2158 static void send_net_key_status(struct bt_mesh_model *model,
2159 struct bt_mesh_msg_ctx *ctx,
2160 uint16_t idx, uint8_t status)
2161 {
2162 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3);
2163
2164 bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS);
2165
2166 net_buf_simple_add_u8(&msg, status);
2167 net_buf_simple_add_le16(&msg, idx);
2168
2169 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2170 BT_ERR("Unable to send Config NetKey Status");
2171 }
2172 }
2173
net_key_add(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2174 static void net_key_add(struct bt_mesh_model *model,
2175 struct bt_mesh_msg_ctx *ctx,
2176 struct net_buf_simple *buf)
2177 {
2178 struct bt_mesh_subnet *sub = NULL;
2179 uint16_t idx = 0U;
2180 int err = 0;
2181
2182 idx = net_buf_simple_pull_le16(buf);
2183 if (idx > 0xfff) {
2184 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
2185 return;
2186 }
2187
2188 BT_DBG("idx 0x%04x", idx);
2189
2190 sub = bt_mesh_subnet_get(idx);
2191 if (!sub) {
2192 int i;
2193
2194 for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
2195 if (bt_mesh.sub[i].net_idx == BLE_MESH_KEY_UNUSED) {
2196 sub = &bt_mesh.sub[i];
2197 break;
2198 }
2199 }
2200
2201 if (!sub) {
2202 send_net_key_status(model, ctx, idx,
2203 STATUS_INSUFF_RESOURCES);
2204 return;
2205 }
2206 }
2207
2208 /* Check for already existing subnet */
2209 if (sub->net_idx == idx) {
2210 uint8_t status = 0U;
2211
2212 if (memcmp(buf->data, sub->keys[0].net, 16)) {
2213 status = STATUS_IDX_ALREADY_STORED;
2214 } else {
2215 status = STATUS_SUCCESS;
2216 }
2217
2218 send_net_key_status(model, ctx, idx, status);
2219 return;
2220 }
2221
2222 err = bt_mesh_net_keys_create(&sub->keys[0], buf->data);
2223 if (err) {
2224 send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED);
2225 return;
2226 }
2227
2228 sub->net_idx = idx;
2229
2230 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
2231 BT_DBG("Storing NetKey persistently");
2232 bt_mesh_store_subnet(sub);
2233 }
2234
2235 /* Make sure we have valid beacon data to be sent */
2236 bt_mesh_net_beacon_update(sub);
2237
2238 if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
2239 sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
2240 bt_mesh_proxy_server_beacon_send(sub);
2241 bt_mesh_adv_update();
2242 } else {
2243 sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
2244 }
2245
2246 send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
2247
2248 bt_mesh_cfg_server_state_change_t change = {0};
2249 change.cfg_netkey_add.net_idx = sub->net_idx;
2250 memcpy(change.cfg_netkey_add.net_key, sub->keys[0].net, 16);
2251 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2252 model, ctx, (const uint8_t *)&change, sizeof(change));
2253 }
2254
net_key_update(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2255 static void net_key_update(struct bt_mesh_model *model,
2256 struct bt_mesh_msg_ctx *ctx,
2257 struct net_buf_simple *buf)
2258 {
2259 struct bt_mesh_subnet *sub = NULL;
2260 uint16_t idx = 0U;
2261 int err = 0;
2262
2263 idx = net_buf_simple_pull_le16(buf);
2264 if (idx > 0xfff) {
2265 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
2266 return;
2267 }
2268
2269 BT_DBG("idx 0x%04x", idx);
2270
2271 sub = bt_mesh_subnet_get(idx);
2272 if (!sub) {
2273 send_net_key_status(model, ctx, idx, STATUS_INVALID_NETKEY);
2274 return;
2275 }
2276
2277 /* The node shall successfully process a NetKey Update message on a
2278 * valid NetKeyIndex when the NetKey value is different and the Key
2279 * Refresh procedure has not been started, or when the NetKey value is
2280 * the same in Phase 1. The NetKey Update message shall generate an
2281 * error when the node is in Phase 2, or Phase 3.
2282 */
2283 switch (sub->kr_phase) {
2284 case BLE_MESH_KR_NORMAL:
2285 if (!memcmp(buf->data, sub->keys[0].net, 16)) {
2286 return;
2287 }
2288 break;
2289 case BLE_MESH_KR_PHASE_1:
2290 if (!memcmp(buf->data, sub->keys[1].net, 16)) {
2291 send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
2292 return;
2293 }
2294 /* fall through */
2295 case BLE_MESH_KR_PHASE_2:
2296 case BLE_MESH_KR_PHASE_3:
2297 send_net_key_status(model, ctx, idx, STATUS_CANNOT_UPDATE);
2298 return;
2299 }
2300
2301 err = bt_mesh_net_keys_create(&sub->keys[1], buf->data);
2302 if (!err && (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) ||
2303 IS_ENABLED(CONFIG_BLE_MESH_FRIEND))) {
2304 err = friend_cred_update(sub);
2305 }
2306
2307 if (err) {
2308 send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED);
2309 return;
2310 }
2311
2312 sub->kr_phase = BLE_MESH_KR_PHASE_1;
2313
2314 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
2315 BT_DBG("Storing NetKey persistently");
2316 bt_mesh_store_subnet(sub);
2317 }
2318
2319 bt_mesh_net_beacon_update(sub);
2320
2321 send_net_key_status(model, ctx, idx, STATUS_SUCCESS);
2322
2323 bt_mesh_cfg_server_state_change_t change = {0};
2324 change.cfg_netkey_update.net_idx = sub->net_idx;
2325 memcpy(change.cfg_netkey_update.net_key, sub->keys[1].net, 16);
2326 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2327 model, ctx, (const uint8_t *)&change, sizeof(change));
2328 }
2329
hb_pub_disable(struct bt_mesh_cfg_srv * cfg)2330 static void hb_pub_disable(struct bt_mesh_cfg_srv *cfg)
2331 {
2332 BT_DBG("%s", __func__);
2333
2334 cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED;
2335 cfg->hb_pub.count = 0U;
2336 cfg->hb_pub.ttl = 0U;
2337 cfg->hb_pub.period = 0U;
2338
2339 k_delayed_work_cancel(&cfg->hb_pub.timer);
2340 }
2341
net_key_del(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2342 static void net_key_del(struct bt_mesh_model *model,
2343 struct bt_mesh_msg_ctx *ctx,
2344 struct net_buf_simple *buf)
2345 {
2346 struct bt_mesh_subnet *sub = NULL;
2347 uint16_t del_idx = 0U;
2348 uint8_t status = 0U;
2349
2350 del_idx = net_buf_simple_pull_le16(buf);
2351 if (del_idx > 0xfff) {
2352 BT_ERR("Invalid NetKeyIndex 0x%04x", del_idx);
2353 return;
2354 }
2355
2356 BT_DBG("idx 0x%04x", del_idx);
2357
2358 sub = bt_mesh_subnet_get(del_idx);
2359 if (!sub) {
2360 /* This could be a retry of a previous attempt that had its
2361 * response lost, so pretend that it was a success.
2362 */
2363 status = STATUS_SUCCESS;
2364 goto send_status;
2365 }
2366
2367 /* The key that the message was encrypted with cannot be removed.
2368 * The NetKey List must contain a minimum of one NetKey.
2369 */
2370 if (ctx->net_idx == del_idx) {
2371 status = STATUS_CANNOT_REMOVE;
2372 goto send_status;
2373 }
2374
2375 bt_mesh_subnet_del(sub, true);
2376 status = STATUS_SUCCESS;
2377
2378 send_status:
2379 send_net_key_status(model, ctx, del_idx, status);
2380
2381 if (status == STATUS_SUCCESS) {
2382 bt_mesh_cfg_server_state_change_t change = {0};
2383 change.cfg_netkey_delete.net_idx = sub ? sub->net_idx : BLE_MESH_KEY_UNUSED;
2384 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2385 model, ctx, (const uint8_t *)&change, sizeof(change));
2386 }
2387 }
2388
net_key_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2389 static void net_key_get(struct bt_mesh_model *model,
2390 struct bt_mesh_msg_ctx *ctx,
2391 struct net_buf_simple *buf)
2392 {
2393 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST,
2394 IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT));
2395 uint16_t prev = 0U, i = 0U;
2396
2397 bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST);
2398
2399 prev = BLE_MESH_KEY_UNUSED;
2400 for (i = 0U; i < ARRAY_SIZE(bt_mesh.sub); i++) {
2401 struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
2402
2403 if (sub->net_idx == BLE_MESH_KEY_UNUSED) {
2404 continue;
2405 }
2406
2407 if (prev == BLE_MESH_KEY_UNUSED) {
2408 prev = sub->net_idx;
2409 continue;
2410 }
2411
2412 key_idx_pack(&msg, prev, sub->net_idx);
2413 prev = BLE_MESH_KEY_UNUSED;
2414 }
2415
2416 if (prev != BLE_MESH_KEY_UNUSED) {
2417 net_buf_simple_add_le16(&msg, prev);
2418 }
2419
2420 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2421 BT_ERR("Unable to send Config NetKey List");
2422 }
2423 }
2424
node_identity_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2425 static void node_identity_get(struct bt_mesh_model *model,
2426 struct bt_mesh_msg_ctx *ctx,
2427 struct net_buf_simple *buf)
2428 {
2429 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
2430 struct bt_mesh_subnet *sub = NULL;
2431 uint8_t node_id = 0U;
2432 uint16_t idx = 0U;
2433
2434 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
2435 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
2436 bt_hex(buf->data, buf->len));
2437
2438 idx = net_buf_simple_pull_le16(buf);
2439 if (idx > 0xfff) {
2440 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
2441 return;
2442 }
2443
2444 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_STATUS);
2445
2446 sub = bt_mesh_subnet_get(idx);
2447 if (!sub) {
2448 net_buf_simple_add_u8(&msg, STATUS_INVALID_NETKEY);
2449 node_id = 0x00;
2450 } else {
2451 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
2452 node_id = sub->node_id;
2453 }
2454
2455 net_buf_simple_add_le16(&msg, idx);
2456 net_buf_simple_add_u8(&msg, node_id);
2457
2458 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2459 BT_ERR("Unable to send Config Node Identity Status");
2460 }
2461 }
2462
node_identity_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2463 static void node_identity_set(struct bt_mesh_model *model,
2464 struct bt_mesh_msg_ctx *ctx,
2465 struct net_buf_simple *buf)
2466 {
2467 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
2468 struct bt_mesh_subnet *sub = NULL;
2469 uint8_t node_id = 0U;
2470 uint16_t idx = 0U;
2471
2472 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
2473 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
2474 bt_hex(buf->data, buf->len));
2475
2476 idx = net_buf_simple_pull_le16(buf);
2477 if (idx > 0xfff) {
2478 BT_WARN("Invalid NetKeyIndex 0x%04x", idx);
2479 return;
2480 }
2481
2482 node_id = net_buf_simple_pull_u8(buf);
2483 if (node_id != 0x00 && node_id != 0x01) {
2484 BT_WARN("Invalid Node ID value 0x%02x", node_id);
2485 return;
2486 }
2487
2488 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_STATUS);
2489
2490 sub = bt_mesh_subnet_get(idx);
2491 if (!sub) {
2492 net_buf_simple_add_u8(&msg, STATUS_INVALID_NETKEY);
2493 net_buf_simple_add_le16(&msg, idx);
2494 net_buf_simple_add_u8(&msg, node_id);
2495 } else {
2496 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
2497 net_buf_simple_add_le16(&msg, idx);
2498
2499 if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
2500 if (node_id) {
2501 bt_mesh_proxy_server_identity_start(sub);
2502 } else {
2503 bt_mesh_proxy_server_identity_stop(sub);
2504 }
2505 bt_mesh_adv_update();
2506 }
2507 net_buf_simple_add_u8(&msg, sub->node_id);
2508 }
2509
2510 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2511 BT_ERR("Unable to send Config Node Identity Status");
2512 }
2513 }
2514
create_mod_app_status(struct net_buf_simple * msg,struct bt_mesh_model * mod,bool vnd,uint16_t elem_addr,uint16_t app_idx,uint8_t status,uint8_t * mod_id)2515 static void create_mod_app_status(struct net_buf_simple *msg,
2516 struct bt_mesh_model *mod, bool vnd,
2517 uint16_t elem_addr, uint16_t app_idx,
2518 uint8_t status, uint8_t *mod_id)
2519 {
2520 bt_mesh_model_msg_init(msg, OP_MOD_APP_STATUS);
2521
2522 net_buf_simple_add_u8(msg, status);
2523 net_buf_simple_add_le16(msg, elem_addr);
2524 net_buf_simple_add_le16(msg, app_idx);
2525
2526 if (vnd) {
2527 memcpy(net_buf_simple_add(msg, 4), mod_id, 4);
2528 } else {
2529 memcpy(net_buf_simple_add(msg, 2), mod_id, 2);
2530 }
2531 }
2532
mod_app_bind(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2533 static void mod_app_bind(struct bt_mesh_model *model,
2534 struct bt_mesh_msg_ctx *ctx,
2535 struct net_buf_simple *buf)
2536 {
2537 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
2538 uint16_t elem_addr = 0U, key_app_idx = 0U;
2539 struct bt_mesh_model *mod = NULL;
2540 struct bt_mesh_elem *elem = NULL;
2541 uint8_t *mod_id = NULL, status = 0U;
2542 bool vnd = false;
2543
2544 elem_addr = net_buf_simple_pull_le16(buf);
2545 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2546 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2547 return;
2548 }
2549
2550 key_app_idx = net_buf_simple_pull_le16(buf);
2551 mod_id = buf->data;
2552
2553 elem = bt_mesh_elem_find(elem_addr);
2554 if (!elem) {
2555 mod = NULL;
2556 vnd = (buf->len == 4U);
2557 status = STATUS_INVALID_ADDRESS;
2558 goto send_status;
2559 }
2560
2561 mod = get_model(elem, buf, &vnd);
2562 if (!mod) {
2563 status = STATUS_INVALID_MODEL;
2564 goto send_status;
2565 }
2566
2567 /* Configuration Server only allows device key based access */
2568 if (model == mod) {
2569 BT_ERR("Client tried to bind AppKey to Configuration Model");
2570 status = STATUS_CANNOT_BIND;
2571 goto send_status;
2572 }
2573
2574 status = mod_bind(mod, key_app_idx);
2575
2576 send_status:
2577 BT_DBG("status 0x%02x", status);
2578 create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
2579 mod_id);
2580
2581 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2582 BT_ERR("Unable to send Config Model App Bind Status");
2583 }
2584
2585 if (status == STATUS_SUCCESS) {
2586 bt_mesh_cfg_server_state_change_t change = {0};
2587 change.cfg_mod_app_bind.elem_addr = elem_addr;
2588 change.cfg_mod_app_bind.app_idx = key_app_idx;
2589 change.cfg_mod_app_bind.cid = vnd ? mod->vnd.company : 0xFFFF;
2590 change.cfg_mod_app_bind.mod_id = vnd ? mod->vnd.id : mod->id;
2591 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2592 model, ctx, (const uint8_t *)&change, sizeof(change));
2593 }
2594 }
2595
mod_app_unbind(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2596 static void mod_app_unbind(struct bt_mesh_model *model,
2597 struct bt_mesh_msg_ctx *ctx,
2598 struct net_buf_simple *buf)
2599 {
2600 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
2601 uint16_t elem_addr = 0U, key_app_idx = 0U;
2602 struct bt_mesh_model *mod = NULL;
2603 struct bt_mesh_elem *elem = NULL;
2604 uint8_t *mod_id = NULL, status = 0U;
2605 bool vnd = false;
2606
2607 elem_addr = net_buf_simple_pull_le16(buf);
2608 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2609 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2610 return;
2611 }
2612
2613 key_app_idx = net_buf_simple_pull_le16(buf);
2614 mod_id = buf->data;
2615
2616 elem = bt_mesh_elem_find(elem_addr);
2617 if (!elem) {
2618 mod = NULL;
2619 vnd = (buf->len == 4U);
2620 status = STATUS_INVALID_ADDRESS;
2621 goto send_status;
2622 }
2623
2624 mod = get_model(elem, buf, &vnd);
2625 if (!mod) {
2626 status = STATUS_INVALID_MODEL;
2627 goto send_status;
2628 }
2629
2630 status = mod_unbind(mod, key_app_idx, true);
2631
2632 send_status:
2633 BT_DBG("status 0x%02x", status);
2634 create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
2635 mod_id);
2636
2637 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2638 BT_ERR("Unable to send Config Model App Unbind Status");
2639 }
2640
2641 if (status == STATUS_SUCCESS) {
2642 bt_mesh_cfg_server_state_change_t change = {0};
2643 change.cfg_mod_app_unbind.elem_addr = elem_addr;
2644 change.cfg_mod_app_unbind.app_idx = key_app_idx;
2645 change.cfg_mod_app_unbind.cid = vnd ? mod->vnd.company : 0xFFFF;
2646 change.cfg_mod_app_unbind.mod_id = vnd ? mod->vnd.id : mod->id;
2647 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2648 model, ctx, (const uint8_t *)&change, sizeof(change));
2649 }
2650 }
2651
2652 #define KEY_LIST_LEN (CONFIG_BLE_MESH_MODEL_KEY_COUNT * 2)
2653
mod_app_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2654 static void mod_app_get(struct bt_mesh_model *model,
2655 struct bt_mesh_msg_ctx *ctx,
2656 struct net_buf_simple *buf)
2657 {
2658 NET_BUF_SIMPLE_DEFINE(msg,
2659 MAX(BLE_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST,
2660 9 + KEY_LIST_LEN),
2661 BLE_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST,
2662 9 + KEY_LIST_LEN)));
2663 struct bt_mesh_model *mod = NULL;
2664 struct bt_mesh_elem *elem = NULL;
2665 uint8_t *mod_id = NULL, status = 0U;
2666 uint16_t elem_addr = 0U;
2667 bool vnd = false;
2668
2669 elem_addr = net_buf_simple_pull_le16(buf);
2670 if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
2671 BT_ERR("Prohibited element address 0x%04x", elem_addr);
2672 return;
2673 }
2674
2675 mod_id = buf->data;
2676
2677 BT_DBG("elem_addr 0x%04x", elem_addr);
2678
2679 elem = bt_mesh_elem_find(elem_addr);
2680 if (!elem) {
2681 mod = NULL;
2682 vnd = (buf->len == 4U);
2683 status = STATUS_INVALID_ADDRESS;
2684 goto send_list;
2685 }
2686
2687 mod = get_model(elem, buf, &vnd);
2688 if (!mod) {
2689 status = STATUS_INVALID_MODEL;
2690 goto send_list;
2691 }
2692
2693 status = STATUS_SUCCESS;
2694
2695 send_list:
2696 if (vnd) {
2697 bt_mesh_model_msg_init(&msg, OP_VND_MOD_APP_LIST);
2698 } else {
2699 bt_mesh_model_msg_init(&msg, OP_SIG_MOD_APP_LIST);
2700 }
2701
2702 net_buf_simple_add_u8(&msg, status);
2703 net_buf_simple_add_le16(&msg, elem_addr);
2704
2705 if (vnd) {
2706 net_buf_simple_add_mem(&msg, mod_id, 4);
2707 } else {
2708 net_buf_simple_add_mem(&msg, mod_id, 2);
2709 }
2710
2711 if (mod) {
2712 int i;
2713
2714 for (i = 0; i < ARRAY_SIZE(mod->keys); i++) {
2715 if (mod->keys[i] != BLE_MESH_KEY_UNUSED) {
2716 net_buf_simple_add_le16(&msg, mod->keys[i]);
2717 }
2718 }
2719 }
2720
2721 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2722 BT_ERR("Unable to send Config Model Application List");
2723 }
2724 }
2725
node_reset(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2726 static void node_reset(struct bt_mesh_model *model,
2727 struct bt_mesh_msg_ctx *ctx,
2728 struct net_buf_simple *buf)
2729 {
2730 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
2731
2732 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
2733 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
2734 bt_hex(buf->data, buf->len));
2735
2736
2737 bt_mesh_model_msg_init(&msg, OP_NODE_RESET_STATUS);
2738
2739 /* Send the response first since we wont have any keys left to
2740 * send it later.
2741 */
2742 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2743 BT_ERR("Unable to send Config Node Reset Status");
2744 }
2745
2746 if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) {
2747 bt_mesh_node_reset();
2748 }
2749 }
2750
send_friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)2751 static void send_friend_status(struct bt_mesh_model *model,
2752 struct bt_mesh_msg_ctx *ctx)
2753 {
2754 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
2755 struct bt_mesh_cfg_srv *cfg = model->user_data;
2756
2757 bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
2758 net_buf_simple_add_u8(&msg, cfg->frnd);
2759
2760 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2761 BT_ERR("Unable to send Config Friend Status");
2762 }
2763 }
2764
friend_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2765 static void friend_get(struct bt_mesh_model *model,
2766 struct bt_mesh_msg_ctx *ctx,
2767 struct net_buf_simple *buf)
2768 {
2769 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
2770 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
2771 bt_hex(buf->data, buf->len));
2772
2773 send_friend_status(model, ctx);
2774 }
2775
friend_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2776 static void friend_set(struct bt_mesh_model *model,
2777 struct bt_mesh_msg_ctx *ctx,
2778 struct net_buf_simple *buf)
2779 {
2780 struct bt_mesh_cfg_srv *cfg = model->user_data;
2781
2782 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
2783 ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
2784 bt_hex(buf->data, buf->len));
2785
2786 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
2787 BT_WARN("Invalid Friend value 0x%02x", buf->data[0]);
2788 return;
2789 }
2790
2791 if (!cfg) {
2792 BT_WARN("No Configuration Server context available");
2793 goto send_status;
2794 }
2795
2796 BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->data[0]);
2797
2798 if (cfg->frnd == buf->data[0]) {
2799 goto send_status;
2800 }
2801
2802 if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
2803 cfg->frnd = buf->data[0];
2804
2805 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
2806 bt_mesh_store_cfg();
2807 }
2808
2809 if (cfg->frnd == BLE_MESH_FRIEND_DISABLED) {
2810 bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
2811 }
2812 }
2813
2814 if (cfg->hb_pub.feat & BLE_MESH_FEAT_FRIEND) {
2815 bt_mesh_heartbeat_send();
2816 }
2817
2818 send_status:
2819 send_friend_status(model, ctx);
2820 }
2821
lpn_timeout_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2822 static void lpn_timeout_get(struct bt_mesh_model *model,
2823 struct bt_mesh_msg_ctx *ctx,
2824 struct net_buf_simple *buf)
2825 {
2826 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5);
2827 struct bt_mesh_friend *frnd = NULL;
2828 uint16_t lpn_addr = 0U;
2829 int32_t timeout = 0;
2830
2831 lpn_addr = net_buf_simple_pull_le16(buf);
2832
2833 BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x",
2834 ctx->net_idx, ctx->app_idx, ctx->addr, lpn_addr);
2835
2836 if (!BLE_MESH_ADDR_IS_UNICAST(lpn_addr)) {
2837 BT_WARN("Invalid LPNAddress; ignoring msg");
2838 return;
2839 }
2840
2841 bt_mesh_model_msg_init(&msg, OP_LPN_TIMEOUT_STATUS);
2842 net_buf_simple_add_le16(&msg, lpn_addr);
2843
2844 if (!IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
2845 timeout = 0;
2846 goto send_rsp;
2847 }
2848
2849 frnd = bt_mesh_friend_find(BLE_MESH_KEY_ANY, lpn_addr, true, true);
2850 if (!frnd) {
2851 timeout = 0;
2852 goto send_rsp;
2853 }
2854
2855 timeout = k_delayed_work_remaining_get(&frnd->timer) / 100;
2856
2857 send_rsp:
2858 net_buf_simple_add_le24(&msg, timeout);
2859
2860 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2861 BT_ERR("Unable to send Config LPN PollTimeout Status");
2862 }
2863 }
2864
send_krp_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t idx,uint8_t phase,uint8_t status)2865 static void send_krp_status(struct bt_mesh_model *model,
2866 struct bt_mesh_msg_ctx *ctx,
2867 uint16_t idx, uint8_t phase, uint8_t status)
2868 {
2869 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4);
2870
2871 bt_mesh_model_msg_init(&msg, OP_KRP_STATUS);
2872
2873 net_buf_simple_add_u8(&msg, status);
2874 net_buf_simple_add_le16(&msg, idx);
2875 net_buf_simple_add_u8(&msg, phase);
2876
2877 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2878 BT_ERR("Unable to send Config Key Refresh Phase Status");
2879 }
2880 }
2881
krp_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2882 static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
2883 struct net_buf_simple *buf)
2884 {
2885 struct bt_mesh_subnet *sub = NULL;
2886 uint16_t idx = 0U;
2887
2888 idx = net_buf_simple_pull_le16(buf);
2889 if (idx > 0xfff) {
2890 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
2891 return;
2892 }
2893
2894 BT_DBG("idx 0x%04x", idx);
2895
2896 sub = bt_mesh_subnet_get(idx);
2897 if (!sub) {
2898 send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY);
2899 } else {
2900 send_krp_status(model, ctx, idx, sub->kr_phase,
2901 STATUS_SUCCESS);
2902 }
2903 }
2904
krp_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2905 static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
2906 struct net_buf_simple *buf)
2907 {
2908 struct bt_mesh_subnet *sub = NULL;
2909 uint8_t phase = 0U;
2910 uint16_t idx = 0U;
2911
2912 idx = net_buf_simple_pull_le16(buf);
2913 phase = net_buf_simple_pull_u8(buf);
2914
2915 if (idx > 0xfff) {
2916 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
2917 return;
2918 }
2919
2920 BT_DBG("idx 0x%04x transition 0x%02x", idx, phase);
2921
2922 sub = bt_mesh_subnet_get(idx);
2923 if (!sub) {
2924 send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY);
2925 return;
2926 }
2927
2928 BT_DBG("%u -> %u", sub->kr_phase, phase);
2929
2930 if (phase < BLE_MESH_KR_PHASE_2 || phase > BLE_MESH_KR_PHASE_3 ||
2931 (sub->kr_phase == BLE_MESH_KR_NORMAL &&
2932 phase == BLE_MESH_KR_PHASE_2)) {
2933 BT_WARN("Prohibited transition %u -> %u", sub->kr_phase, phase);
2934 return;
2935 }
2936
2937 if (sub->kr_phase == BLE_MESH_KR_PHASE_1 &&
2938 phase == BLE_MESH_KR_PHASE_2) {
2939 sub->kr_phase = BLE_MESH_KR_PHASE_2;
2940 sub->kr_flag = 1;
2941
2942 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
2943 BT_DBG("Storing kr phase persistently");
2944 bt_mesh_store_subnet(sub);
2945 }
2946
2947 bt_mesh_net_beacon_update(sub);
2948 } else if ((sub->kr_phase == BLE_MESH_KR_PHASE_1 ||
2949 sub->kr_phase == BLE_MESH_KR_PHASE_2) &&
2950 phase == BLE_MESH_KR_PHASE_3) {
2951 sub->kr_phase = BLE_MESH_KR_NORMAL;
2952 sub->kr_flag = 0;
2953 bt_mesh_net_revoke_keys(sub);
2954
2955 if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) ||
2956 IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
2957 friend_cred_refresh(ctx->net_idx);
2958 }
2959
2960 bt_mesh_net_beacon_update(sub);
2961 }
2962
2963 send_krp_status(model, ctx, idx, sub->kr_phase, STATUS_SUCCESS);
2964
2965 bt_mesh_cfg_server_state_change_t change = {0};
2966 change.cfg_kr_phase_set.net_idx = idx;
2967 change.cfg_kr_phase_set.kr_phase = phase;
2968 bt_mesh_config_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_CONFIG_SERVER_STATE_CHANGE,
2969 model, ctx, (const uint8_t *)&change, sizeof(change));
2970 }
2971
hb_log(uint16_t val)2972 static uint8_t hb_log(uint16_t val)
2973 {
2974 if (!val) {
2975 return 0x00;
2976 } else if (val == 0xffff) {
2977 return 0xff;
2978 } else {
2979 return 32 - __builtin_clz(val);
2980 }
2981 }
2982
hb_pub_count_log(uint16_t val)2983 static uint8_t hb_pub_count_log(uint16_t val)
2984 {
2985 if (!val) {
2986 return 0x00;
2987 } else if (val == 0x01) {
2988 return 0x01;
2989 } else if (val == 0xffff) {
2990 return 0xff;
2991 } else {
2992 return 32 - __builtin_clz(val - 1) + 1;
2993 }
2994 }
2995
hb_pwr2(uint8_t val,uint8_t sub)2996 static uint16_t hb_pwr2(uint8_t val, uint8_t sub)
2997 {
2998 if (!val) {
2999 return 0x0000;
3000 } else if (val == 0xff || val == 0x11) {
3001 return 0xffff;
3002 } else {
3003 return (1 << (val - sub));
3004 }
3005 }
3006
3007 struct hb_pub_param {
3008 uint16_t dst;
3009 uint8_t count_log;
3010 uint8_t period_log;
3011 uint8_t ttl;
3012 uint16_t feat;
3013 uint16_t net_idx;
3014 } __packed;
3015
hb_pub_send_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status,struct hb_pub_param * orig_msg)3016 static void hb_pub_send_status(struct bt_mesh_model *model,
3017 struct bt_mesh_msg_ctx *ctx, uint8_t status,
3018 struct hb_pub_param *orig_msg)
3019 {
3020 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10);
3021 struct bt_mesh_cfg_srv *cfg = model->user_data;
3022
3023 BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
3024
3025 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_STATUS);
3026
3027 net_buf_simple_add_u8(&msg, status);
3028
3029 if (orig_msg) {
3030 memcpy(net_buf_simple_add(&msg, sizeof(*orig_msg)), orig_msg,
3031 sizeof(*orig_msg));
3032 goto send;
3033 }
3034
3035 net_buf_simple_add_le16(&msg, cfg->hb_pub.dst);
3036 net_buf_simple_add_u8(&msg, hb_pub_count_log(cfg->hb_pub.count));
3037 net_buf_simple_add_u8(&msg, cfg->hb_pub.period);
3038 net_buf_simple_add_u8(&msg, cfg->hb_pub.ttl);
3039 net_buf_simple_add_le16(&msg, cfg->hb_pub.feat);
3040 net_buf_simple_add_le16(&msg, cfg->hb_pub.net_idx);
3041
3042 send:
3043 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
3044 BT_ERR("Unable to send Config Heartbeat Publication Status");
3045 }
3046 }
3047
heartbeat_pub_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)3048 static void heartbeat_pub_get(struct bt_mesh_model *model,
3049 struct bt_mesh_msg_ctx *ctx,
3050 struct net_buf_simple *buf)
3051 {
3052 BT_DBG("src 0x%04x", ctx->addr);
3053
3054 hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL);
3055 }
3056
heartbeat_pub_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)3057 static void heartbeat_pub_set(struct bt_mesh_model *model,
3058 struct bt_mesh_msg_ctx *ctx,
3059 struct net_buf_simple *buf)
3060 {
3061 struct hb_pub_param *param = (void *)buf->data;
3062 struct bt_mesh_cfg_srv *cfg = model->user_data;
3063 uint16_t dst = 0U, feat = 0U, idx = 0U;
3064 uint8_t status = 0U;
3065
3066 BT_DBG("src 0x%04x", ctx->addr);
3067
3068 dst = sys_le16_to_cpu(param->dst);
3069 /* All other address types but virtual are valid */
3070 if (BLE_MESH_ADDR_IS_VIRTUAL(dst)) {
3071 status = STATUS_INVALID_ADDRESS;
3072 goto failed;
3073 }
3074
3075 if (param->count_log > 0x11 && param->count_log != 0xff) {
3076 status = STATUS_CANNOT_SET;
3077 goto failed;
3078 }
3079
3080 if (param->period_log > 0x11) {
3081 status = STATUS_CANNOT_SET;
3082 goto failed;
3083 }
3084
3085 if (param->ttl > BLE_MESH_TTL_MAX && param->ttl != BLE_MESH_TTL_DEFAULT) {
3086 BT_ERR("Invalid TTL value 0x%02x", param->ttl);
3087 return;
3088 }
3089
3090 feat = sys_le16_to_cpu(param->feat);
3091
3092 idx = sys_le16_to_cpu(param->net_idx);
3093 if (idx > 0xfff) {
3094 BT_ERR("Invalid NetKeyIndex 0x%04x", idx);
3095 return;
3096 }
3097
3098 if (!bt_mesh_subnet_get(idx)) {
3099 status = STATUS_INVALID_NETKEY;
3100 goto failed;
3101 }
3102
3103 cfg->hb_pub.dst = dst;
3104 cfg->hb_pub.period = param->period_log;
3105 cfg->hb_pub.feat = feat & BLE_MESH_FEAT_SUPPORTED;
3106 cfg->hb_pub.net_idx = idx;
3107
3108 if (dst == BLE_MESH_ADDR_UNASSIGNED) {
3109 hb_pub_disable(cfg);
3110 } else {
3111 /* 2^(n-1) */
3112 cfg->hb_pub.count = hb_pwr2(param->count_log, 1);
3113 cfg->hb_pub.ttl = param->ttl;
3114
3115 BT_DBG("period %u ms", hb_pwr2(param->period_log, 1) * 1000U);
3116
3117 /* Note: Send heartbeat message here will cause wrong heartbeat status message */
3118 #if 0
3119 /* The first Heartbeat message shall be published as soon
3120 * as possible after the Heartbeat Publication Period state
3121 * has been configured for periodic publishing.
3122 */
3123 if (param->period_log && param->count_log) {
3124 k_work_submit(&cfg->hb_pub.timer.work);
3125 } else {
3126 k_delayed_work_cancel(&cfg->hb_pub.timer);
3127 }
3128 #endif
3129 }
3130
3131 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
3132 bt_mesh_store_hb_pub();
3133 }
3134
3135 hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL);
3136
3137 /* The first Heartbeat message shall be published as soon
3138 * as possible after the Heartbeat Publication Period state
3139 * has been configured for periodic publishing.
3140 */
3141 if (dst != BLE_MESH_ADDR_UNASSIGNED) {
3142 if (param->period_log && param->count_log) {
3143 k_work_submit(&cfg->hb_pub.timer.work);
3144 } else {
3145 k_delayed_work_cancel(&cfg->hb_pub.timer);
3146 }
3147 }
3148
3149 return;
3150
3151 failed:
3152 hb_pub_send_status(model, ctx, status, param);
3153 }
3154
hb_sub_send_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status)3155 static void hb_sub_send_status(struct bt_mesh_model *model,
3156 struct bt_mesh_msg_ctx *ctx, uint8_t status)
3157 {
3158 BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9);
3159 struct bt_mesh_cfg_srv *cfg = model->user_data;
3160 uint16_t period = 0U;
3161 int64_t uptime = 0;
3162
3163 BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
3164
3165 uptime = k_uptime_get();
3166 if (uptime > cfg->hb_sub.expiry) {
3167 period = 0U;
3168 } else {
3169 period = (cfg->hb_sub.expiry - uptime) / 1000;
3170 }
3171
3172 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_STATUS);
3173
3174 net_buf_simple_add_u8(&msg, status);
3175 net_buf_simple_add_le16(&msg, cfg->hb_sub.src);
3176 net_buf_simple_add_le16(&msg, cfg->hb_sub.dst);
3177 net_buf_simple_add_u8(&msg, hb_log(period));
3178 net_buf_simple_add_u8(&msg, hb_log(cfg->hb_sub.count));
3179 net_buf_simple_add_u8(&msg, cfg->hb_sub.min_hops);
3180 net_buf_simple_add_u8(&msg, cfg->hb_sub.max_hops);
3181
3182 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
3183 BT_ERR("Unable to send Config Heartbeat Subscription Status");
3184 }
3185 }
3186
heartbeat_sub_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)3187 static void heartbeat_sub_get(struct bt_mesh_model *model,
3188 struct bt_mesh_msg_ctx *ctx,
3189 struct net_buf_simple *buf)
3190 {
3191 BT_DBG("src 0x%04x", ctx->addr);
3192
3193 hb_sub_send_status(model, ctx, STATUS_SUCCESS);
3194 }
3195
heartbeat_sub_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)3196 static void heartbeat_sub_set(struct bt_mesh_model *model,
3197 struct bt_mesh_msg_ctx *ctx,
3198 struct net_buf_simple *buf)
3199 {
3200 struct bt_mesh_cfg_srv *cfg = model->user_data;
3201 uint16_t sub_src = 0U, sub_dst = 0U;
3202 uint8_t sub_period = 0U;
3203 int32_t period_ms = 0;
3204
3205 BT_DBG("src 0x%04x", ctx->addr);
3206
3207 sub_src = net_buf_simple_pull_le16(buf);
3208 sub_dst = net_buf_simple_pull_le16(buf);
3209 sub_period = net_buf_simple_pull_u8(buf);
3210
3211 BT_DBG("sub_src 0x%04x sub_dst 0x%04x period 0x%02x",
3212 sub_src, sub_dst, sub_period);
3213
3214 if (sub_src != BLE_MESH_ADDR_UNASSIGNED &&
3215 !BLE_MESH_ADDR_IS_UNICAST(sub_src)) {
3216 BT_WARN("Prohibited source address");
3217 return;
3218 }
3219
3220 if (BLE_MESH_ADDR_IS_VIRTUAL(sub_dst) || BLE_MESH_ADDR_IS_RFU(sub_dst) ||
3221 (BLE_MESH_ADDR_IS_UNICAST(sub_dst) &&
3222 sub_dst != bt_mesh_primary_addr())) {
3223 BT_WARN("Prohibited destination address");
3224 return;
3225 }
3226
3227 if (sub_period > 0x11) {
3228 BT_WARN("Prohibited subscription period 0x%02x", sub_period);
3229 return;
3230 }
3231
3232 if (sub_src == BLE_MESH_ADDR_UNASSIGNED ||
3233 sub_dst == BLE_MESH_ADDR_UNASSIGNED ||
3234 sub_period == 0x00) {
3235 /* Only an explicit address change to unassigned should
3236 * trigger clearing of the values according to
3237 * MESH/NODE/CFG/HBS/BV-02-C.
3238 */
3239 if (sub_src == BLE_MESH_ADDR_UNASSIGNED ||
3240 sub_dst == BLE_MESH_ADDR_UNASSIGNED) {
3241 cfg->hb_sub.src = BLE_MESH_ADDR_UNASSIGNED;
3242 cfg->hb_sub.dst = BLE_MESH_ADDR_UNASSIGNED;
3243 cfg->hb_sub.min_hops = BLE_MESH_TTL_MAX;
3244 cfg->hb_sub.max_hops = 0U;
3245 }
3246
3247 period_ms = 0;
3248 } else {
3249 cfg->hb_sub.src = sub_src;
3250 cfg->hb_sub.dst = sub_dst;
3251 cfg->hb_sub.min_hops = BLE_MESH_TTL_MAX;
3252 cfg->hb_sub.max_hops = 0U;
3253 cfg->hb_sub.count = 0U;
3254 period_ms = hb_pwr2(sub_period, 1) * 1000U;
3255 }
3256
3257 /* Let the transport layer know it needs to handle this address */
3258 bt_mesh_set_hb_sub_dst(cfg->hb_sub.dst);
3259
3260 BT_DBG("period_ms %u", period_ms);
3261
3262 if (period_ms) {
3263 cfg->hb_sub.expiry = k_uptime_get() + period_ms;
3264 } else {
3265 cfg->hb_sub.expiry = 0;
3266 }
3267
3268 hb_sub_send_status(model, ctx, STATUS_SUCCESS);
3269
3270 /* For case MESH/NODE/CFG/HBS/BV-02-C, set count_log to 0
3271 * when Heartbeat Subscription Status message is sent.
3272 */
3273 cfg->hb_sub.count = 0U;
3274
3275 /* MESH/NODE/CFG/HBS/BV-01-C expects the MinHops to be 0x7f after
3276 * disabling subscription, but 0x00 for subsequent Get requests.
3277 */
3278 if (!period_ms) {
3279 cfg->hb_sub.min_hops = 0U;
3280 }
3281 }
3282
3283 const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = {
3284 { OP_DEV_COMP_DATA_GET, 1, dev_comp_data_get },
3285 { OP_APP_KEY_ADD, 19, app_key_add },
3286 { OP_APP_KEY_UPDATE, 19, app_key_update },
3287 { OP_APP_KEY_DEL, 3, app_key_del },
3288 { OP_APP_KEY_GET, 2, app_key_get },
3289 { OP_BEACON_GET, 0, beacon_get },
3290 { OP_BEACON_SET, 1, beacon_set },
3291 { OP_DEFAULT_TTL_GET, 0, default_ttl_get },
3292 { OP_DEFAULT_TTL_SET, 1, default_ttl_set },
3293 { OP_GATT_PROXY_GET, 0, gatt_proxy_get },
3294 { OP_GATT_PROXY_SET, 1, gatt_proxy_set },
3295 { OP_NET_TRANSMIT_GET, 0, net_transmit_get },
3296 { OP_NET_TRANSMIT_SET, 1, net_transmit_set },
3297 { OP_RELAY_GET, 0, relay_get },
3298 { OP_RELAY_SET, 2, relay_set },
3299 { OP_MOD_PUB_GET, 4, mod_pub_get },
3300 { OP_MOD_PUB_SET, 11, mod_pub_set },
3301 { OP_MOD_PUB_VA_SET, 24, mod_pub_va_set },
3302 { OP_MOD_SUB_ADD, 6, mod_sub_add },
3303 { OP_MOD_SUB_VA_ADD, 20, mod_sub_va_add },
3304 { OP_MOD_SUB_DEL, 6, mod_sub_del },
3305 { OP_MOD_SUB_VA_DEL, 20, mod_sub_va_del },
3306 { OP_MOD_SUB_OVERWRITE, 6, mod_sub_overwrite },
3307 { OP_MOD_SUB_VA_OVERWRITE, 20, mod_sub_va_overwrite },
3308 { OP_MOD_SUB_DEL_ALL, 4, mod_sub_del_all },
3309 { OP_MOD_SUB_GET, 4, mod_sub_get },
3310 { OP_MOD_SUB_GET_VND, 6, mod_sub_get_vnd },
3311 { OP_NET_KEY_ADD, 18, net_key_add },
3312 { OP_NET_KEY_UPDATE, 18, net_key_update },
3313 { OP_NET_KEY_DEL, 2, net_key_del },
3314 { OP_NET_KEY_GET, 0, net_key_get },
3315 { OP_NODE_IDENTITY_GET, 2, node_identity_get },
3316 { OP_NODE_IDENTITY_SET, 3, node_identity_set },
3317 { OP_MOD_APP_BIND, 6, mod_app_bind },
3318 { OP_MOD_APP_UNBIND, 6, mod_app_unbind },
3319 { OP_SIG_MOD_APP_GET, 4, mod_app_get },
3320 { OP_VND_MOD_APP_GET, 6, mod_app_get },
3321 { OP_NODE_RESET, 0, node_reset },
3322 { OP_FRIEND_GET, 0, friend_get },
3323 { OP_FRIEND_SET, 1, friend_set },
3324 { OP_LPN_TIMEOUT_GET, 2, lpn_timeout_get },
3325 { OP_KRP_GET, 2, krp_get },
3326 { OP_KRP_SET, 3, krp_set },
3327 { OP_HEARTBEAT_PUB_GET, 0, heartbeat_pub_get },
3328 { OP_HEARTBEAT_PUB_SET, 9, heartbeat_pub_set },
3329 { OP_HEARTBEAT_SUB_GET, 0, heartbeat_sub_get },
3330 { OP_HEARTBEAT_SUB_SET, 5, heartbeat_sub_set },
3331 BLE_MESH_MODEL_OP_END,
3332 };
3333
hb_publish(struct k_work * work)3334 static void hb_publish(struct k_work *work)
3335 {
3336 struct bt_mesh_cfg_srv *cfg = CONTAINER_OF(work,
3337 struct bt_mesh_cfg_srv,
3338 hb_pub.timer.work);
3339 struct bt_mesh_subnet *sub = NULL;
3340 uint16_t period_ms = 0U;
3341
3342 BT_DBG("hb_pub.count: %u", cfg->hb_pub.count);
3343
3344 sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx);
3345 if (!sub) {
3346 BT_ERR("No matching subnet for idx 0x%04x",
3347 cfg->hb_pub.net_idx);
3348 cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED;
3349 return;
3350 }
3351
3352 if (cfg->hb_pub.count == 0U) {
3353 return;
3354 }
3355
3356 period_ms = hb_pwr2(cfg->hb_pub.period, 1) * 1000U;
3357 if (period_ms && cfg->hb_pub.count > 1) {
3358 k_delayed_work_submit(&cfg->hb_pub.timer, period_ms);
3359 }
3360
3361 bt_mesh_heartbeat_send();
3362
3363 if (cfg->hb_pub.count != 0xffff) {
3364 cfg->hb_pub.count--;
3365 }
3366 }
3367
conf_is_valid(struct bt_mesh_cfg_srv * cfg)3368 static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg)
3369 {
3370 if (cfg->relay > 0x02) {
3371 return false;
3372 }
3373
3374 if (cfg->beacon > 0x01) {
3375 return false;
3376 }
3377
3378 if (cfg->default_ttl > BLE_MESH_TTL_MAX) {
3379 return false;
3380 }
3381
3382 return true;
3383 }
3384
cfg_srv_init(struct bt_mesh_model * model)3385 static int cfg_srv_init(struct bt_mesh_model *model)
3386 {
3387 struct bt_mesh_cfg_srv *cfg = model->user_data;
3388
3389 if (!bt_mesh_model_in_primary(model)) {
3390 BT_ERR("Configuration Server only allowed in primary element");
3391 return -EINVAL;
3392 }
3393
3394 if (!cfg) {
3395 BT_ERR("No Configuration Server context provided");
3396 return -EINVAL;
3397 }
3398
3399 if (!conf_is_valid(cfg)) {
3400 BT_ERR("Invalid values in configuration");
3401 return -EINVAL;
3402 }
3403
3404 /* Configuration Model security is device-key based */
3405 model->keys[0] = BLE_MESH_KEY_DEV;
3406
3407 if (!IS_ENABLED(CONFIG_BLE_MESH_RELAY)) {
3408 cfg->relay = BLE_MESH_RELAY_NOT_SUPPORTED;
3409 }
3410
3411 if (!IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
3412 cfg->frnd = BLE_MESH_FRIEND_NOT_SUPPORTED;
3413 }
3414
3415 if (!IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
3416 cfg->gatt_proxy = BLE_MESH_GATT_PROXY_NOT_SUPPORTED;
3417 }
3418
3419 k_delayed_work_init(&cfg->hb_pub.timer, hb_publish);
3420 cfg->hb_pub.net_idx = BLE_MESH_KEY_UNUSED;
3421 cfg->hb_sub.expiry = 0;
3422
3423 cfg->model = model;
3424
3425 conf = cfg;
3426
3427 return 0;
3428 }
3429
3430 #if CONFIG_BLE_MESH_DEINIT
cfg_srv_deinit(struct bt_mesh_model * model)3431 static int cfg_srv_deinit(struct bt_mesh_model *model)
3432 {
3433 struct bt_mesh_cfg_srv *cfg = model->user_data;
3434
3435 if (!bt_mesh_model_in_primary(model)) {
3436 BT_ERR("Configuration Server only allowed in primary element");
3437 return -EINVAL;
3438 }
3439
3440 if (!cfg) {
3441 BT_ERR("No Configuration Server context provided");
3442 return -EINVAL;
3443 }
3444
3445 /* Use "false" here because if cfg needs to be erased,
3446 * it will already be erased in the ble_mesh_deinit().
3447 */
3448 bt_mesh_cfg_reset(false);
3449
3450 k_delayed_work_free(&cfg->hb_pub.timer);
3451 cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED;
3452
3453 conf = NULL;
3454
3455 return 0;
3456 }
3457 #endif /* CONFIG_BLE_MESH_DEINIT */
3458
3459 const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = {
3460 .init = cfg_srv_init,
3461 #if CONFIG_BLE_MESH_DEINIT
3462 .deinit = cfg_srv_deinit,
3463 #endif /* CONFIG_BLE_MESH_DEINIT */
3464 };
3465
mod_reset(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)3466 static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
3467 bool vnd, bool primary, void *user_data)
3468 {
3469 bool store = *(bool *)user_data;
3470 size_t clear_count = 0U;
3471
3472 /* Clear model state that isn't otherwise cleared. E.g. AppKey
3473 * binding and model publication is cleared as a consequence
3474 * of removing all app keys, however model subscription clearing
3475 * must be taken care of here.
3476 */
3477
3478 clear_count = mod_sub_list_clear(mod);
3479
3480 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && clear_count && store) {
3481 bt_mesh_store_mod_sub(mod);
3482 }
3483 }
3484
bt_mesh_mod_sub_reset(bool store)3485 void bt_mesh_mod_sub_reset(bool store)
3486 {
3487 bt_mesh_model_foreach(mod_reset, &store);
3488 }
3489
bt_mesh_cfg_reset(bool store)3490 void bt_mesh_cfg_reset(bool store)
3491 {
3492 struct bt_mesh_cfg_srv *cfg = conf;
3493 int i;
3494
3495 BT_DBG("%s", __func__);
3496
3497 if (!cfg) {
3498 return;
3499 }
3500
3501 bt_mesh_set_hb_sub_dst(BLE_MESH_ADDR_UNASSIGNED);
3502
3503 cfg->hb_sub.src = BLE_MESH_ADDR_UNASSIGNED;
3504 cfg->hb_sub.dst = BLE_MESH_ADDR_UNASSIGNED;
3505 cfg->hb_sub.expiry = 0;
3506
3507 /* Delete all net keys, which also takes care of all app keys which
3508 * are associated with each net key.
3509 */
3510 for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
3511 struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
3512
3513 if (sub->net_idx != BLE_MESH_KEY_UNUSED) {
3514 bt_mesh_subnet_del(sub, store);
3515 }
3516 }
3517
3518 bt_mesh_mod_sub_reset(store);
3519
3520 (void)memset(labels, 0, sizeof(labels));
3521 }
3522
bt_mesh_heartbeat(uint16_t src,uint16_t dst,uint8_t hops,uint16_t feat)3523 void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat)
3524 {
3525 struct bt_mesh_cfg_srv *cfg = conf;
3526
3527 if (!cfg) {
3528 BT_WARN("No configuration server context available");
3529 return;
3530 }
3531
3532 if (src != cfg->hb_sub.src || dst != cfg->hb_sub.dst) {
3533 BT_WARN("No subscription for received heartbeat");
3534 return;
3535 }
3536
3537 if (k_uptime_get() > cfg->hb_sub.expiry) {
3538 BT_WARN("Heartbeat subscription period expired");
3539 return;
3540 }
3541
3542 cfg->hb_sub.min_hops = MIN(cfg->hb_sub.min_hops, hops);
3543 cfg->hb_sub.max_hops = MAX(cfg->hb_sub.max_hops, hops);
3544
3545 if (cfg->hb_sub.count < 0xffff) {
3546 cfg->hb_sub.count++;
3547 }
3548
3549 BT_DBG("src 0x%04x dst 0x%04x hops %u min %u max %u count %u", src,
3550 dst, hops, cfg->hb_sub.min_hops, cfg->hb_sub.max_hops,
3551 cfg->hb_sub.count);
3552
3553 if (cfg->hb_sub.func) {
3554 cfg->hb_sub.func(hops, feat);
3555 }
3556 }
3557
bt_mesh_net_transmit_get(void)3558 uint8_t bt_mesh_net_transmit_get(void)
3559 {
3560 if (conf) {
3561 return conf->net_transmit;
3562 }
3563
3564 return 0;
3565 }
3566
bt_mesh_relay_get(void)3567 uint8_t bt_mesh_relay_get(void)
3568 {
3569 if (conf) {
3570 return conf->relay;
3571 }
3572
3573 return BLE_MESH_RELAY_NOT_SUPPORTED;
3574 }
3575
bt_mesh_friend_get(void)3576 uint8_t bt_mesh_friend_get(void)
3577 {
3578 if (conf) {
3579 BT_DBG("conf %p conf->frnd 0x%02x", conf, conf->frnd);
3580 return conf->frnd;
3581 }
3582
3583 return BLE_MESH_FRIEND_NOT_SUPPORTED;
3584 }
3585
bt_mesh_relay_retransmit_get(void)3586 uint8_t bt_mesh_relay_retransmit_get(void)
3587 {
3588 if (conf) {
3589 return conf->relay_retransmit;
3590 }
3591
3592 return 0;
3593 }
3594
bt_mesh_beacon_get(void)3595 uint8_t bt_mesh_beacon_get(void)
3596 {
3597 if (conf) {
3598 return conf->beacon;
3599 }
3600
3601 return BLE_MESH_BEACON_DISABLED;
3602 }
3603
bt_mesh_gatt_proxy_get(void)3604 uint8_t bt_mesh_gatt_proxy_get(void)
3605 {
3606 if (conf) {
3607 return conf->gatt_proxy;
3608 }
3609
3610 return BLE_MESH_GATT_PROXY_NOT_SUPPORTED;
3611 }
3612
bt_mesh_default_ttl_get(void)3613 uint8_t bt_mesh_default_ttl_get(void)
3614 {
3615 if (conf) {
3616 return conf->default_ttl;
3617 }
3618
3619 return DEFAULT_TTL;
3620 }
3621
bt_mesh_label_uuid_get(uint16_t addr)3622 uint8_t *bt_mesh_label_uuid_get(uint16_t addr)
3623 {
3624 int i;
3625
3626 BT_DBG("addr 0x%04x", addr);
3627
3628 for (i = 0; i < ARRAY_SIZE(labels); i++) {
3629 if (labels[i].addr == addr) {
3630 BT_DBG("Found Label UUID for 0x%04x: %s", addr,
3631 bt_hex(labels[i].uuid, 16));
3632 return labels[i].uuid;
3633 }
3634 }
3635
3636 BT_WARN("No matching Label UUID for 0x%04x", addr);
3637
3638 return NULL;
3639 }
3640
bt_mesh_hb_pub_get(void)3641 struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
3642 {
3643 if (!conf) {
3644 return NULL;
3645 }
3646
3647 return &conf->hb_pub;
3648 }
3649
bt_mesh_hb_pub_disable(void)3650 void bt_mesh_hb_pub_disable(void)
3651 {
3652 if (conf) {
3653 hb_pub_disable(conf);
3654 }
3655 }
3656
bt_mesh_cfg_get(void)3657 struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void)
3658 {
3659 return conf;
3660 }
3661
bt_mesh_subnet_del(struct bt_mesh_subnet * sub,bool store)3662 void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store)
3663 {
3664 int i;
3665
3666 BT_DBG("NetIdx 0x%03x store %u", sub->net_idx, store);
3667
3668 if (conf && conf->hb_pub.net_idx == sub->net_idx) {
3669 hb_pub_disable(conf);
3670
3671 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
3672 bt_mesh_store_hb_pub();
3673 }
3674 }
3675
3676 /* Delete any app keys bound to this NetKey index */
3677 for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
3678 struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
3679
3680 if (key->net_idx == sub->net_idx) {
3681 bt_mesh_app_key_del(key, store);
3682 }
3683 }
3684
3685 if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
3686 bt_mesh_friend_clear_net_idx(sub->net_idx);
3687 }
3688
3689 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
3690 bt_mesh_clear_subnet(sub);
3691 }
3692
3693 (void)memset(sub, 0, sizeof(*sub));
3694 sub->net_idx = BLE_MESH_KEY_UNUSED;
3695 }
3696