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