1 /*  Bluetooth Mesh */
2 
3 /*
4  * SPDX-FileCopyrightText: 2017 Intel Corporation
5  * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <string.h>
11 #include <errno.h>
12 #include <stdbool.h>
13 
14 #include "btc_ble_mesh_config_model.h"
15 
16 #include "mesh.h"
17 #include "adv.h"
18 #include "lpn.h"
19 #include "transport.h"
20 #include "crypto.h"
21 #include "access.h"
22 #include "beacon.h"
23 #include "foundation.h"
24 #include "friend.h"
25 #include "settings.h"
26 #include "cfg_srv.h"
27 #include "proxy_server.h"
28 #include "mesh_main.h"
29 #include "mesh_common.h"
30 
31 #define DEFAULT_TTL 7
32 
33 /* Maximum message length is 384 in BLE Mesh. Here for composition data,
34  * due to 1 octet opcode and 4 octets TransMIC, 379 octets can be used to
35  * store device composition data.
36  */
37 #define COMP_DATA_MAX_LEN   379
38 
39 static struct bt_mesh_cfg_srv *conf;
40 
41 static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT];
42 
comp_add_elem(struct net_buf_simple * buf,struct bt_mesh_elem * elem,bool primary)43 static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
44                          bool primary)
45 {
46     struct bt_mesh_model *mod = NULL;
47     int i;
48 
49     if (net_buf_simple_tailroom(buf) <
50             4 + (elem->model_count * 2U) + (elem->vnd_model_count * 4U)) {
51         BT_ERR("Too large device composition");
52         return -E2BIG;
53     }
54 
55     net_buf_simple_add_le16(buf, elem->loc);
56 
57     net_buf_simple_add_u8(buf, elem->model_count);
58     net_buf_simple_add_u8(buf, elem->vnd_model_count);
59 
60     for (i = 0; i < elem->model_count; i++) {
61         mod = &elem->models[i];
62         net_buf_simple_add_le16(buf, mod->id);
63     }
64 
65     for (i = 0; i < elem->vnd_model_count; i++) {
66         mod = &elem->vnd_models[i];
67         net_buf_simple_add_le16(buf, mod->vnd.company);
68         net_buf_simple_add_le16(buf, mod->vnd.id);
69     }
70 
71     return 0;
72 }
73 
comp_get_page_0(struct net_buf_simple * buf)74 static int comp_get_page_0(struct net_buf_simple *buf)
75 {
76     const struct bt_mesh_comp *comp = NULL;
77     uint16_t feat = 0U;
78     int i;
79 
80     comp = bt_mesh_comp_get();
81 
82     if (IS_ENABLED(CONFIG_BLE_MESH_RELAY)) {
83         feat |= BLE_MESH_FEAT_RELAY;
84     }
85 
86     if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
87         feat |= BLE_MESH_FEAT_PROXY;
88     }
89 
90     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
91         feat |= BLE_MESH_FEAT_FRIEND;
92     }
93 
94     if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
95         feat |= BLE_MESH_FEAT_LOW_POWER;
96     }
97 
98     net_buf_simple_add_le16(buf, comp->cid);
99     net_buf_simple_add_le16(buf, comp->pid);
100     net_buf_simple_add_le16(buf, comp->vid);
101     net_buf_simple_add_le16(buf, CONFIG_BLE_MESH_CRPL);
102     net_buf_simple_add_le16(buf, feat);
103 
104     for (i = 0; i < comp->elem_count; i++) {
105         int err;
106 
107         err = comp_add_elem(buf, &comp->elem[i], i == 0);
108         if (err) {
109             return err;
110         }
111     }
112 
113     return 0;
114 }
115 
dev_comp_data_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)116 static void dev_comp_data_get(struct bt_mesh_model *model,
117                               struct bt_mesh_msg_ctx *ctx,
118                               struct net_buf_simple *buf)
119 {
120     struct net_buf_simple *sdu = NULL;
121     uint8_t page = 0U;
122 
123     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
124            ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
125            bt_hex(buf->data, buf->len));
126 
127     page = net_buf_simple_pull_u8(buf);
128     if (page != 0U) {
129         BT_WARN("Composition page %u not available", page);
130         page = 0U;
131     }
132 
133     sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, COMP_DATA_MAX_LEN));
134     if (!sdu) {
135         BT_ERR("%s, Out of memory", __func__);
136         return;
137     }
138 
139     bt_mesh_model_msg_init(sdu, OP_DEV_COMP_DATA_STATUS);
140 
141     net_buf_simple_add_u8(sdu, page);
142     if (comp_get_page_0(sdu) < 0) {
143         BT_ERR("Unable to get composition page 0");
144         bt_mesh_free_buf(sdu);
145         return;
146     }
147 
148     if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
149         BT_ERR("Unable to send Config Composition Data Status");
150     }
151 
152     bt_mesh_free_buf(sdu);
153     return;
154 }
155 
get_model(struct bt_mesh_elem * elem,struct net_buf_simple * buf,bool * vnd)156 static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem,
157                                        struct net_buf_simple *buf, bool *vnd)
158 {
159     if (buf->len < 4) {
160         uint16_t id = 0U;
161 
162         id = net_buf_simple_pull_le16(buf);
163 
164         BT_DBG("ID 0x%04x addr 0x%04x", id, elem->addr);
165 
166         *vnd = false;
167 
168         return bt_mesh_model_find(elem, id);
169     } else {
170         uint16_t company = 0U, id = 0U;
171 
172         company = net_buf_simple_pull_le16(buf);
173         id = net_buf_simple_pull_le16(buf);
174 
175         BT_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id,
176                elem->addr);
177 
178         *vnd = true;
179 
180         return bt_mesh_model_find_vnd(elem, company, id);
181     }
182 }
183 
app_key_is_valid(uint16_t app_idx)184 static bool app_key_is_valid(uint16_t app_idx)
185 {
186     int i;
187 
188     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
189         struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
190 
191         if (key->net_idx != BLE_MESH_KEY_UNUSED &&
192                 key->app_idx == app_idx) {
193             return true;
194         }
195     }
196 
197     return false;
198 }
199 
_mod_pub_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 ? sub->net_idx : BLE_MESH_KEY_UNUSED;
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