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