1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <zephyr/types.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/byteorder.h>
14
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/bluetooth/mesh.h>
18
19 #include "common/bt_str.h"
20
21 #include "host/testing.h"
22
23 #include "mesh.h"
24 #include "net.h"
25 #include "rpl.h"
26 #include "lpn.h"
27 #include "transport.h"
28 #include "heartbeat.h"
29 #include "crypto.h"
30 #include "access.h"
31 #include "beacon.h"
32 #include "proxy.h"
33 #include "foundation.h"
34 #include "friend.h"
35 #include "settings.h"
36 #include "cfg.h"
37 #include "va.h"
38
39 #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
40 #include <zephyr/logging/log.h>
41 LOG_MODULE_REGISTER(bt_mesh_cfg_srv);
42
node_reset_pending_handler(struct k_work * work)43 static void node_reset_pending_handler(struct k_work *work)
44 {
45 bt_mesh_reset();
46 }
47
48 static K_WORK_DEFINE(node_reset_pending, node_reset_pending_handler);
49
dev_comp_data_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)50 static int dev_comp_data_get(const struct bt_mesh_model *model,
51 struct bt_mesh_msg_ctx *ctx,
52 struct net_buf_simple *buf)
53 {
54 NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
55 uint8_t page;
56 int err;
57
58 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
59 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
60
61 page = bt_mesh_comp_parse_page(buf);
62 LOG_DBG("Preparing Composition data page %d", page);
63
64 bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS);
65
66 net_buf_simple_add_u8(&sdu, page);
67
68 if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && page < 128) {
69 sdu.size -= BT_MESH_MIC_SHORT;
70 err = bt_mesh_comp_read(&sdu, page);
71 sdu.size += BT_MESH_MIC_SHORT;
72 } else {
73 err = bt_mesh_comp_data_get_page(&sdu, page, 0);
74 }
75
76 if (err) {
77 LOG_ERR("Failed to get CDP%d, err:%d", page, err);
78 return err;
79 }
80
81 if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {
82 LOG_ERR("Unable to send Device Composition Status response");
83 }
84
85 return err;
86 }
87
get_model(const struct bt_mesh_elem * elem,struct net_buf_simple * buf,bool * vnd)88 static const struct bt_mesh_model *get_model(const struct bt_mesh_elem *elem,
89 struct net_buf_simple *buf, bool *vnd)
90 {
91 if (buf->len < 4) {
92 uint16_t id;
93
94 id = net_buf_simple_pull_le16(buf);
95
96 LOG_DBG("ID 0x%04x addr 0x%04x", id, elem->rt->addr);
97
98 *vnd = false;
99
100 return bt_mesh_model_find(elem, id);
101 } else {
102 uint16_t company, id;
103
104 company = net_buf_simple_pull_le16(buf);
105 id = net_buf_simple_pull_le16(buf);
106
107 LOG_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, elem->rt->addr);
108
109 *vnd = true;
110
111 return bt_mesh_model_find_vnd(elem, company, id);
112 }
113 }
114
_mod_pub_set(const struct bt_mesh_model * model,uint16_t pub_addr,const uint8_t * uuid,uint16_t app_idx,uint8_t cred_flag,uint8_t ttl,uint8_t period,uint8_t retransmit,bool store)115 static uint8_t _mod_pub_set(const struct bt_mesh_model *model, uint16_t pub_addr,
116 const uint8_t *uuid, uint16_t app_idx, uint8_t cred_flag,
117 uint8_t ttl, uint8_t period, uint8_t retransmit, bool store)
118 {
119 if (!model->pub) {
120 return STATUS_NVAL_PUB_PARAM;
121 }
122
123 if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && cred_flag) {
124 return STATUS_FEAT_NOT_SUPP;
125 }
126
127 if (!model->pub->update && period) {
128 return STATUS_NVAL_PUB_PARAM;
129 }
130
131 if (pub_addr == BT_MESH_ADDR_UNASSIGNED) {
132 if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
133 return STATUS_SUCCESS;
134 }
135
136 model->pub->addr = BT_MESH_ADDR_UNASSIGNED;
137 model->pub->key = 0U;
138 model->pub->cred = 0U;
139 model->pub->ttl = 0U;
140 model->pub->period = 0U;
141 model->pub->retransmit = 0U;
142 model->pub->count = 0U;
143 model->pub->uuid = NULL;
144
145 if (model->pub->update) {
146 /* If this fails, the timer will check pub->addr and
147 * exit without transmitting.
148 */
149 (void)k_work_cancel_delayable(&model->pub->timer);
150 }
151
152 if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
153 bt_mesh_model_pub_store(model);
154 }
155
156 return STATUS_SUCCESS;
157 }
158
159 if (!bt_mesh_app_key_exists(app_idx) || !bt_mesh_model_has_key(model, app_idx)) {
160 return STATUS_INVALID_APPKEY;
161 }
162
163 #if CONFIG_BT_MESH_LABEL_COUNT > 0
164 if (BT_MESH_ADDR_IS_VIRTUAL(model->pub->addr)) {
165 (void)bt_mesh_va_del(model->pub->uuid);
166 }
167 #endif
168
169 model->pub->addr = pub_addr;
170 model->pub->key = app_idx;
171 model->pub->cred = cred_flag;
172 model->pub->ttl = ttl;
173 model->pub->period = period;
174 model->pub->retransmit = retransmit;
175 model->pub->uuid = uuid;
176
177 if (model->pub->update) {
178 int32_t period_ms;
179
180 period_ms = bt_mesh_model_pub_period_get(model);
181 LOG_DBG("period %u ms", period_ms);
182
183 if (period_ms > 0) {
184 k_work_reschedule(&model->pub->timer,
185 K_MSEC(period_ms));
186 } else {
187 /* If this fails, publication will stop after the
188 * ongoing set of retransmits.
189 */
190 (void)k_work_cancel_delayable(&model->pub->timer);
191 }
192 }
193
194 if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
195 bt_mesh_model_pub_store(model);
196 }
197
198 return STATUS_SUCCESS;
199 }
200
mod_bind(const struct bt_mesh_model * model,uint16_t key_idx)201 static uint8_t mod_bind(const struct bt_mesh_model *model, uint16_t key_idx)
202 {
203 int i;
204
205 LOG_DBG("model %p key_idx 0x%03x", model, key_idx);
206
207 if (!bt_mesh_app_key_exists(key_idx)) {
208 return STATUS_INVALID_APPKEY;
209 }
210
211 for (i = 0; i < model->keys_cnt; i++) {
212 LOG_DBG("model %p id 0x%04x i %d key 0x%03x", model, model->id, i, model->keys[i]);
213 /* Treat existing binding as success */
214 if (model->keys[i] == key_idx) {
215 return STATUS_SUCCESS;
216 }
217 }
218
219 for (i = 0; i < model->keys_cnt; i++) {
220 if (model->keys[i] == BT_MESH_KEY_UNUSED) {
221 model->keys[i] = key_idx;
222
223 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
224 bt_mesh_model_bind_store(model);
225 }
226
227 return STATUS_SUCCESS;
228 }
229 }
230
231 return STATUS_INSUFF_RESOURCES;
232 }
233
mod_unbind(const struct bt_mesh_model * model,uint16_t key_idx,bool store)234 static uint8_t mod_unbind(const struct bt_mesh_model *model, uint16_t key_idx, bool store)
235 {
236 int i;
237
238 LOG_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store);
239
240 if (!bt_mesh_app_key_exists(key_idx)) {
241 return STATUS_INVALID_APPKEY;
242 }
243
244 for (i = 0; i < model->keys_cnt; i++) {
245 if (model->keys[i] != key_idx) {
246 continue;
247 }
248
249 model->keys[i] = BT_MESH_KEY_UNUSED;
250
251 if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
252 bt_mesh_model_bind_store(model);
253 }
254
255 if (model->pub && model->pub->key == key_idx) {
256 _mod_pub_set(model, BT_MESH_ADDR_UNASSIGNED, NULL,
257 0, 0, 0, 0, 0, store);
258 }
259 }
260
261 return STATUS_SUCCESS;
262 }
263
key_idx_pack_list(struct net_buf_simple * buf,uint16_t * arr,size_t cnt)264 static void key_idx_pack_list(struct net_buf_simple *buf, uint16_t *arr, size_t cnt)
265 {
266 uint16_t *idx = NULL;
267
268 for (int i = 0; i < cnt; i++) {
269 if (arr[i] != BT_MESH_KEY_UNUSED) {
270 if (!idx) {
271 idx = &arr[i];
272 continue;
273 }
274
275 key_idx_pack_pair(buf, *idx, arr[i]);
276 idx = NULL;
277 }
278 }
279
280 if (idx) {
281 net_buf_simple_add_le16(buf, *idx);
282 }
283
284 }
285
send_app_key_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status,uint16_t app_idx,uint16_t net_idx)286 static int send_app_key_status(const struct bt_mesh_model *model,
287 struct bt_mesh_msg_ctx *ctx,
288 uint8_t status,
289 uint16_t app_idx, uint16_t net_idx)
290 {
291 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
292
293 bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS);
294 net_buf_simple_add_u8(&msg, status);
295 key_idx_pack_pair(&msg, net_idx, app_idx);
296
297 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
298 LOG_ERR("Unable to send App Key Status response");
299 }
300
301 return 0;
302 }
303
app_key_add(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)304 static int app_key_add(const struct bt_mesh_model *model,
305 struct bt_mesh_msg_ctx *ctx,
306 struct net_buf_simple *buf)
307 {
308 uint16_t key_net_idx, key_app_idx;
309 uint8_t status;
310
311 key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
312
313 LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
314
315 status = bt_mesh_app_key_add(key_app_idx, key_net_idx, buf->data);
316
317 return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
318 }
319
app_key_update(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)320 static int app_key_update(const struct bt_mesh_model *model,
321 struct bt_mesh_msg_ctx *ctx,
322 struct net_buf_simple *buf)
323 {
324 uint16_t key_net_idx, key_app_idx;
325 uint8_t status;
326
327 key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
328
329 LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
330
331 status = bt_mesh_app_key_update(key_app_idx, key_net_idx, buf->data);
332 LOG_DBG("status 0x%02x", status);
333
334 return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
335 }
336
mod_app_key_del(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)337 static void mod_app_key_del(const struct bt_mesh_model *mod,
338 const struct bt_mesh_elem *elem, bool vnd, bool primary,
339 void *user_data)
340 {
341 uint16_t *app_idx = user_data;
342
343 mod_unbind(mod, *app_idx, true);
344 }
345
app_key_evt(uint16_t app_idx,uint16_t net_idx,enum bt_mesh_key_evt evt)346 static void app_key_evt(uint16_t app_idx, uint16_t net_idx,
347 enum bt_mesh_key_evt evt)
348 {
349 if (evt == BT_MESH_KEY_DELETED) {
350 bt_mesh_model_foreach(&mod_app_key_del, &app_idx);
351 }
352 }
353
354 BT_MESH_APP_KEY_CB_DEFINE(app_key_evt);
355
app_key_del(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)356 static int app_key_del(const struct bt_mesh_model *model,
357 struct bt_mesh_msg_ctx *ctx,
358 struct net_buf_simple *buf)
359 {
360 uint16_t key_net_idx, key_app_idx;
361 uint8_t status;
362
363 key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
364
365 LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
366
367 status = bt_mesh_app_key_del(key_app_idx, key_net_idx);
368
369 return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
370 }
371
372 /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */
373 #define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2)
374
app_key_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)375 static int app_key_get(const struct bt_mesh_model *model,
376 struct bt_mesh_msg_ctx *ctx,
377 struct net_buf_simple *buf)
378 {
379 BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST,
380 3 + IDX_LEN(CONFIG_BT_MESH_APP_KEY_COUNT));
381 uint16_t app_idx[CONFIG_BT_MESH_APP_KEY_COUNT];
382 uint16_t get_idx;
383 uint8_t status;
384 ssize_t count;
385
386 get_idx = net_buf_simple_pull_le16(buf);
387 if (get_idx > 0xfff) {
388 LOG_ERR("Invalid NetKeyIndex 0x%04x", get_idx);
389 return -EINVAL;
390 }
391
392 LOG_DBG("idx 0x%04x", get_idx);
393
394 bt_mesh_model_msg_init(&msg, OP_APP_KEY_LIST);
395
396 if (!bt_mesh_subnet_exists(get_idx)) {
397 status = STATUS_INVALID_NETKEY;
398 } else {
399 status = STATUS_SUCCESS;
400 }
401
402 net_buf_simple_add_u8(&msg, status);
403 net_buf_simple_add_le16(&msg, get_idx);
404
405 if (status != STATUS_SUCCESS) {
406 goto send_status;
407 }
408
409 count = bt_mesh_app_keys_get(get_idx, app_idx, ARRAY_SIZE(app_idx), 0);
410 if (count < 0 || count > ARRAY_SIZE(app_idx)) {
411 count = ARRAY_SIZE(app_idx);
412 }
413
414 key_idx_pack_list(&msg, app_idx, count);
415
416 send_status:
417 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
418 LOG_ERR("Unable to send AppKey List");
419 }
420
421 return 0;
422 }
423
beacon_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)424 static int beacon_get(const struct bt_mesh_model *model,
425 struct bt_mesh_msg_ctx *ctx,
426 struct net_buf_simple *buf)
427 {
428 BT_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
429
430 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
431 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
432
433 bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
434 net_buf_simple_add_u8(&msg, bt_mesh_beacon_enabled());
435
436 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
437 LOG_ERR("Unable to send Config Beacon Status response");
438 }
439
440 return 0;
441 }
442
beacon_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)443 static int beacon_set(const struct bt_mesh_model *model,
444 struct bt_mesh_msg_ctx *ctx,
445 struct net_buf_simple *buf)
446 {
447 BT_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
448
449 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
450 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
451
452 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
453 LOG_WRN("Invalid Config Beacon value 0x%02x", buf->data[0]);
454 return -EINVAL;
455 }
456
457 bt_mesh_beacon_set(buf->data[0]);
458
459 bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
460 net_buf_simple_add_u8(&msg, buf->data[0]);
461
462 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
463 LOG_ERR("Unable to send Config Beacon Status response");
464 }
465
466 return 0;
467 }
468
default_ttl_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)469 static int default_ttl_get(const struct bt_mesh_model *model,
470 struct bt_mesh_msg_ctx *ctx,
471 struct net_buf_simple *buf)
472 {
473 BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
474
475 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
476 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
477
478 bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
479 net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get());
480
481 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
482 LOG_ERR("Unable to send Default TTL Status response");
483 }
484
485 return 0;
486 }
487
default_ttl_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)488 static int default_ttl_set(const struct bt_mesh_model *model,
489 struct bt_mesh_msg_ctx *ctx,
490 struct net_buf_simple *buf)
491 {
492 BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
493 int err;
494
495 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
496 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
497
498 err = bt_mesh_default_ttl_set(buf->data[0]);
499 if (err) {
500 LOG_WRN("Prohibited Default TTL value 0x%02x", buf->data[0]);
501 return err;
502 }
503
504 bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
505 net_buf_simple_add_u8(&msg, buf->data[0]);
506
507 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
508 LOG_ERR("Unable to send Default TTL Status response");
509 }
510
511 return 0;
512 }
513
send_gatt_proxy_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)514 static int send_gatt_proxy_status(const struct bt_mesh_model *model,
515 struct bt_mesh_msg_ctx *ctx)
516 {
517 BT_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1);
518
519 bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
520 net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get());
521
522 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
523 LOG_ERR("Unable to send GATT Proxy Status");
524 }
525
526 return 0;
527 }
528
gatt_proxy_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)529 static int gatt_proxy_get(const struct bt_mesh_model *model,
530 struct bt_mesh_msg_ctx *ctx,
531 struct net_buf_simple *buf)
532 {
533 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
534 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
535
536 return send_gatt_proxy_status(model, ctx);
537 }
538
gatt_proxy_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)539 static int gatt_proxy_set(const struct bt_mesh_model *model,
540 struct bt_mesh_msg_ctx *ctx,
541 struct net_buf_simple *buf)
542 {
543 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
544 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
545
546 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
547 LOG_WRN("Invalid GATT Proxy value 0x%02x", buf->data[0]);
548 return -EINVAL;
549 }
550
551 (void)bt_mesh_gatt_proxy_set(buf->data[0]);
552
553 /** 4.2.46.1: If the value of the Node Identity state of the node for any subnet is 0x01,
554 * then the value of the Private Node Identity state shall be Disable (0x00).
555 */
556 if (IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS) && buf->data[0]) {
557 (void)bt_mesh_priv_gatt_proxy_set(BT_MESH_FEATURE_DISABLED);
558 }
559
560 return send_gatt_proxy_status(model, ctx);
561 }
562
net_transmit_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)563 static int net_transmit_get(const struct bt_mesh_model *model,
564 struct bt_mesh_msg_ctx *ctx,
565 struct net_buf_simple *buf)
566 {
567 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
568
569 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
570 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
571
572 bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
573 net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get());
574
575 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
576 LOG_ERR("Unable to send Config Network Transmit Status");
577 }
578
579 return 0;
580 }
581
net_transmit_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)582 static int net_transmit_set(const struct bt_mesh_model *model,
583 struct bt_mesh_msg_ctx *ctx,
584 struct net_buf_simple *buf)
585 {
586 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
587
588 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
589 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
590
591 LOG_DBG("Transmit 0x%02x (count %u interval %ums)", buf->data[0],
592 BT_MESH_TRANSMIT_COUNT(buf->data[0]), BT_MESH_TRANSMIT_INT(buf->data[0]));
593
594 bt_mesh_net_transmit_set(buf->data[0]);
595
596 bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
597 net_buf_simple_add_u8(&msg, buf->data[0]);
598
599 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
600 LOG_ERR("Unable to send Network Transmit Status");
601 }
602
603 return 0;
604 }
605
relay_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)606 static int relay_get(const struct bt_mesh_model *model,
607 struct bt_mesh_msg_ctx *ctx,
608 struct net_buf_simple *buf)
609 {
610 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
611
612 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
613 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
614
615 bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
616 net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
617 net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
618
619 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
620 LOG_ERR("Unable to send Config Relay Status response");
621 }
622
623 return 0;
624 }
625
relay_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)626 static int relay_set(const struct bt_mesh_model *model,
627 struct bt_mesh_msg_ctx *ctx,
628 struct net_buf_simple *buf)
629 {
630 BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
631
632 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
633 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
634
635 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
636 LOG_WRN("Invalid Relay value 0x%02x", buf->data[0]);
637 return -EINVAL;
638 }
639
640 (void)bt_mesh_relay_set(buf->data[0], buf->data[1]);
641
642 bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
643 net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
644 net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
645
646 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
647 LOG_ERR("Unable to send Relay Status response");
648 }
649
650 return 0;
651 }
652
send_mod_pub_status(const struct bt_mesh_model * cfg_mod,struct bt_mesh_msg_ctx * ctx,uint16_t elem_addr,uint16_t pub_addr,bool vnd,const struct bt_mesh_model * mod,uint8_t status,uint8_t * mod_id)653 static int send_mod_pub_status(const struct bt_mesh_model *cfg_mod,
654 struct bt_mesh_msg_ctx *ctx, uint16_t elem_addr,
655 uint16_t pub_addr, bool vnd,
656 const struct bt_mesh_model *mod, uint8_t status,
657 uint8_t *mod_id)
658 {
659 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14);
660
661 bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
662
663 net_buf_simple_add_u8(&msg, status);
664 net_buf_simple_add_le16(&msg, elem_addr);
665
666 if (status != STATUS_SUCCESS) {
667 (void)memset(net_buf_simple_add(&msg, 7), 0, 7);
668 } else {
669 uint16_t idx_cred;
670
671 net_buf_simple_add_le16(&msg, pub_addr);
672
673 idx_cred = mod->pub->key | (uint16_t)mod->pub->cred << 12;
674 net_buf_simple_add_le16(&msg, idx_cred);
675 net_buf_simple_add_u8(&msg, mod->pub->ttl);
676 net_buf_simple_add_u8(&msg, mod->pub->period);
677 net_buf_simple_add_u8(&msg, mod->pub->retransmit);
678 }
679
680 if (vnd) {
681 memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
682 } else {
683 memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
684 }
685
686 if (bt_mesh_model_send(cfg_mod, ctx, &msg, NULL, NULL)) {
687 LOG_ERR("Unable to send Model Publication Status");
688 }
689
690 return 0;
691 }
692
mod_pub_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)693 static int mod_pub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
694 struct net_buf_simple *buf)
695 {
696 uint16_t elem_addr, pub_addr = 0U;
697 const struct bt_mesh_model *mod;
698 const struct bt_mesh_elem *elem;
699 uint8_t *mod_id, status;
700 bool vnd;
701
702 if ((buf->len != 4U) && (buf->len != 6U)) {
703 LOG_ERR("The message size for the application opcode is incorrect.");
704 return -EMSGSIZE;
705 }
706
707 elem_addr = net_buf_simple_pull_le16(buf);
708 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
709 LOG_WRN("Prohibited element address");
710 return -EINVAL;
711 }
712
713 mod_id = buf->data;
714
715 LOG_DBG("elem_addr 0x%04x", elem_addr);
716
717 elem = bt_mesh_elem_find(elem_addr);
718 if (!elem) {
719 mod = NULL;
720 vnd = (buf->len == 4U);
721 status = STATUS_INVALID_ADDRESS;
722 goto send_status;
723 }
724
725 mod = get_model(elem, buf, &vnd);
726 if (!mod) {
727 status = STATUS_INVALID_MODEL;
728 goto send_status;
729 }
730
731 if (!mod->pub) {
732 status = STATUS_NVAL_PUB_PARAM;
733 goto send_status;
734 }
735
736 pub_addr = mod->pub->addr;
737 status = STATUS_SUCCESS;
738
739 send_status:
740 return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
741 status, mod_id);
742 }
743
mod_pub_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)744 static int mod_pub_set(const struct bt_mesh_model *model,
745 struct bt_mesh_msg_ctx *ctx,
746 struct net_buf_simple *buf)
747 {
748 uint8_t retransmit, status, pub_ttl, pub_period, cred_flag;
749 uint16_t elem_addr, pub_addr, pub_app_idx;
750 const struct bt_mesh_model *mod;
751 const struct bt_mesh_elem *elem;
752 uint8_t *mod_id;
753 bool vnd;
754
755 if ((buf->len != 11U) && (buf->len != 13U)) {
756 LOG_ERR("The message size for the application opcode is incorrect.");
757 return -EMSGSIZE;
758 }
759
760 elem_addr = net_buf_simple_pull_le16(buf);
761 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
762 LOG_WRN("Prohibited element address");
763 return -EINVAL;
764 }
765
766 pub_addr = net_buf_simple_pull_le16(buf);
767 pub_app_idx = net_buf_simple_pull_le16(buf);
768 cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
769 pub_app_idx &= BIT_MASK(12);
770
771 pub_ttl = net_buf_simple_pull_u8(buf);
772 if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) {
773 LOG_ERR("Invalid TTL value 0x%02x", pub_ttl);
774 return -EINVAL;
775 }
776
777 pub_period = net_buf_simple_pull_u8(buf);
778 retransmit = net_buf_simple_pull_u8(buf);
779 mod_id = buf->data;
780
781 LOG_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", elem_addr, pub_addr, cred_flag);
782 LOG_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", pub_app_idx, pub_ttl,
783 pub_period);
784 LOG_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
785 BT_MESH_PUB_TRANSMIT_COUNT(retransmit), BT_MESH_PUB_TRANSMIT_INT(retransmit));
786
787 elem = bt_mesh_elem_find(elem_addr);
788 if (!elem) {
789 mod = NULL;
790 vnd = (buf->len == 4U);
791 status = STATUS_INVALID_ADDRESS;
792 goto send_status;
793 }
794
795 mod = get_model(elem, buf, &vnd);
796 if (!mod) {
797 status = STATUS_INVALID_MODEL;
798 goto send_status;
799 }
800
801 status = _mod_pub_set(mod, pub_addr, NULL, pub_app_idx, cred_flag, pub_ttl,
802 pub_period, retransmit, true);
803
804 send_status:
805 return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
806 status, mod_id);
807 }
808
mod_sub_list_clear(const struct bt_mesh_model * mod)809 static size_t mod_sub_list_clear(const struct bt_mesh_model *mod)
810 {
811 size_t clear_count;
812 int i;
813
814 for (i = 0, clear_count = 0; i < mod->groups_cnt; i++) {
815 /* mod->groups contains both, group and virtual addrs. Virtual addrs deletion will
816 * be handled separately.
817 */
818 if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
819 mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
820 clear_count++;
821 }
822 }
823
824 #if CONFIG_BT_MESH_LABEL_COUNT > 0
825 /* Unref stored labels related to this model */
826 for (i = 0; i < CONFIG_BT_MESH_LABEL_COUNT; i++) {
827 if (mod->uuids[i] == NULL) {
828 continue;
829 }
830
831 (void)bt_mesh_va_del(mod->uuids[i]);
832 mod->uuids[i] = NULL;
833 /* No need to increment `clear_count` as `groups` contains virtual addresses. */
834 }
835 #endif
836
837 return clear_count;
838 }
839
mod_pub_va_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)840 static int mod_pub_va_set(const struct bt_mesh_model *model,
841 struct bt_mesh_msg_ctx *ctx,
842 struct net_buf_simple *buf)
843 {
844 const struct bt_mesh_va *va;
845 uint8_t retransmit, status, pub_ttl, pub_period, cred_flag;
846 uint16_t elem_addr, pub_app_idx;
847 uint16_t pub_addr = 0U;
848 const struct bt_mesh_model *mod;
849 const struct bt_mesh_elem *elem;
850 const uint8_t *uuid;
851 uint8_t *mod_id;
852 bool vnd;
853
854 if ((buf->len != 25U) && (buf->len != 27U)) {
855 LOG_ERR("The message size for the application opcode is incorrect.");
856 return -EMSGSIZE;
857 }
858
859 elem_addr = net_buf_simple_pull_le16(buf);
860 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
861 LOG_WRN("Prohibited element address");
862 return -EINVAL;
863 }
864
865 uuid = net_buf_simple_pull_mem(buf, 16);
866 pub_app_idx = net_buf_simple_pull_le16(buf);
867 cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
868 pub_app_idx &= BIT_MASK(12);
869 pub_ttl = net_buf_simple_pull_u8(buf);
870 if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) {
871 LOG_ERR("Invalid TTL value 0x%02x", pub_ttl);
872 return -EINVAL;
873 }
874
875 pub_period = net_buf_simple_pull_u8(buf);
876 retransmit = net_buf_simple_pull_u8(buf);
877 mod_id = buf->data;
878
879 LOG_DBG("elem_addr 0x%04x cred_flag %u", elem_addr, cred_flag);
880 LOG_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", pub_app_idx, pub_ttl,
881 pub_period);
882 LOG_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
883 BT_MESH_PUB_TRANSMIT_COUNT(retransmit), BT_MESH_PUB_TRANSMIT_INT(retransmit));
884
885 elem = bt_mesh_elem_find(elem_addr);
886 if (!elem) {
887 mod = NULL;
888 vnd = (buf->len == 4U);
889 status = STATUS_INVALID_ADDRESS;
890 goto send_status;
891 }
892
893 mod = get_model(elem, buf, &vnd);
894 if (!mod) {
895 status = STATUS_INVALID_MODEL;
896 goto send_status;
897 }
898
899 status = bt_mesh_va_add(uuid, &va);
900 if (status != STATUS_SUCCESS) {
901 goto send_status;
902 }
903
904 pub_addr = va->addr;
905
906 status = _mod_pub_set(mod, pub_addr, va->uuid, pub_app_idx, cred_flag, pub_ttl,
907 pub_period, retransmit, true);
908 if (status != STATUS_SUCCESS) {
909 (void)bt_mesh_va_del(va->uuid);
910 }
911
912 send_status:
913 return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
914 status, mod_id);
915 }
916
send_mod_sub_status(const 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)917 static int send_mod_sub_status(const struct bt_mesh_model *model,
918 struct bt_mesh_msg_ctx *ctx, uint8_t status,
919 uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id,
920 bool vnd)
921 {
922 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9);
923
924 LOG_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, elem_addr, sub_addr);
925
926 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_STATUS);
927
928 net_buf_simple_add_u8(&msg, status);
929 net_buf_simple_add_le16(&msg, elem_addr);
930 net_buf_simple_add_le16(&msg, sub_addr);
931
932 if (vnd) {
933 memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
934 } else {
935 memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
936 }
937
938 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
939 LOG_ERR("Unable to send Model Subscription Status");
940 }
941
942 return 0;
943 }
944
mod_sub_add(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)945 static int mod_sub_add(const struct bt_mesh_model *model,
946 struct bt_mesh_msg_ctx *ctx,
947 struct net_buf_simple *buf)
948 {
949 uint16_t elem_addr, sub_addr;
950 const struct bt_mesh_model *mod;
951 const struct bt_mesh_elem *elem;
952 uint8_t *mod_id;
953 uint8_t status;
954 uint16_t *entry;
955 bool vnd;
956
957 if ((buf->len != 6U) && (buf->len != 8U)) {
958 LOG_ERR("The message size for the application opcode is incorrect.");
959 return -EMSGSIZE;
960 }
961
962 elem_addr = net_buf_simple_pull_le16(buf);
963 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
964 LOG_WRN("Prohibited element address");
965 return -EINVAL;
966 }
967
968 sub_addr = net_buf_simple_pull_le16(buf);
969
970 LOG_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr);
971
972 mod_id = buf->data;
973
974 elem = bt_mesh_elem_find(elem_addr);
975 if (!elem) {
976 mod = NULL;
977 vnd = (buf->len == 4U);
978 status = STATUS_INVALID_ADDRESS;
979 goto send_status;
980 }
981
982 mod = get_model(elem, buf, &vnd);
983 if (!mod) {
984 status = STATUS_INVALID_MODEL;
985 goto send_status;
986 }
987
988 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
989 status = STATUS_INVALID_ADDRESS;
990 goto send_status;
991 }
992
993 if (bt_mesh_model_find_group(&mod, sub_addr)) {
994 /* Tried to add existing subscription */
995 LOG_DBG("found existing subscription");
996 status = STATUS_SUCCESS;
997 goto send_status;
998 }
999
1000 entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED);
1001 if (!entry) {
1002 status = STATUS_INSUFF_RESOURCES;
1003 goto send_status;
1004 }
1005
1006 *entry = sub_addr;
1007 status = STATUS_SUCCESS;
1008
1009 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1010 bt_mesh_model_sub_store(mod);
1011 }
1012
1013 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
1014 bt_mesh_lpn_group_add(sub_addr);
1015 }
1016
1017
1018 send_status:
1019 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1020 mod_id, vnd);
1021 }
1022
mod_sub_del(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1023 static int mod_sub_del(const struct bt_mesh_model *model,
1024 struct bt_mesh_msg_ctx *ctx,
1025 struct net_buf_simple *buf)
1026 {
1027 uint16_t elem_addr, sub_addr;
1028 const struct bt_mesh_model *mod;
1029 const struct bt_mesh_elem *elem;
1030 uint8_t *mod_id;
1031 uint16_t *match;
1032 uint8_t status;
1033 bool vnd;
1034
1035 if ((buf->len != 6U) && (buf->len != 8U)) {
1036 LOG_ERR("The message size for the application opcode is incorrect.");
1037 return -EMSGSIZE;
1038 }
1039
1040 elem_addr = net_buf_simple_pull_le16(buf);
1041 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1042 LOG_WRN("Prohibited element address");
1043 return -EINVAL;
1044 }
1045
1046 sub_addr = net_buf_simple_pull_le16(buf);
1047
1048 LOG_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
1049
1050 mod_id = buf->data;
1051
1052 elem = bt_mesh_elem_find(elem_addr);
1053 if (!elem) {
1054 mod = NULL;
1055 vnd = (buf->len == 4U);
1056 status = STATUS_INVALID_ADDRESS;
1057 goto send_status;
1058 }
1059
1060 mod = get_model(elem, buf, &vnd);
1061 if (!mod) {
1062 status = STATUS_INVALID_MODEL;
1063 goto send_status;
1064 }
1065
1066 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1067 status = STATUS_INVALID_ADDRESS;
1068 goto send_status;
1069 }
1070
1071 /* An attempt to remove a non-existing address shall be treated
1072 * as a success.
1073 */
1074 status = STATUS_SUCCESS;
1075
1076 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
1077 bt_mesh_lpn_group_del(&sub_addr, 1);
1078 }
1079
1080 match = bt_mesh_model_find_group(&mod, sub_addr);
1081 if (match) {
1082 *match = BT_MESH_ADDR_UNASSIGNED;
1083
1084 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1085 bt_mesh_model_sub_store(mod);
1086 }
1087 }
1088
1089 send_status:
1090 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1091 mod_id, vnd);
1092 }
1093
mod_sub_clear_visitor(const struct bt_mesh_model * mod,void * user_data)1094 static enum bt_mesh_walk mod_sub_clear_visitor(const struct bt_mesh_model *mod, void *user_data)
1095 {
1096 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
1097 bt_mesh_lpn_group_del(mod->groups, mod->groups_cnt);
1098 }
1099
1100 mod_sub_list_clear(mod);
1101
1102 return BT_MESH_WALK_CONTINUE;
1103 }
1104
mod_sub_overwrite(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1105 static int mod_sub_overwrite(const struct bt_mesh_model *model,
1106 struct bt_mesh_msg_ctx *ctx,
1107 struct net_buf_simple *buf)
1108 {
1109 uint16_t elem_addr, sub_addr;
1110 const struct bt_mesh_model *mod;
1111 const struct bt_mesh_elem *elem;
1112 uint8_t *mod_id;
1113 uint8_t status;
1114 bool vnd;
1115
1116 if ((buf->len != 6U) && (buf->len != 8U)) {
1117 LOG_ERR("The message size for the application opcode is incorrect.");
1118 return -EMSGSIZE;
1119 }
1120
1121 elem_addr = net_buf_simple_pull_le16(buf);
1122 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1123 LOG_WRN("Prohibited element address");
1124 return -EINVAL;
1125 }
1126
1127 sub_addr = net_buf_simple_pull_le16(buf);
1128
1129 LOG_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
1130
1131 mod_id = buf->data;
1132
1133 elem = bt_mesh_elem_find(elem_addr);
1134 if (!elem) {
1135 mod = NULL;
1136 vnd = (buf->len == 4U);
1137 status = STATUS_INVALID_ADDRESS;
1138 goto send_status;
1139 }
1140
1141 mod = get_model(elem, buf, &vnd);
1142 if (!mod) {
1143 status = STATUS_INVALID_MODEL;
1144 goto send_status;
1145 }
1146
1147 if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
1148 status = STATUS_INVALID_ADDRESS;
1149 goto send_status;
1150 }
1151
1152
1153 if (mod->groups_cnt > 0) {
1154 bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
1155
1156 mod->groups[0] = sub_addr;
1157 status = STATUS_SUCCESS;
1158
1159 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1160 bt_mesh_model_sub_store(mod);
1161 }
1162
1163 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
1164 bt_mesh_lpn_group_add(sub_addr);
1165 }
1166 } else {
1167 status = STATUS_INSUFF_RESOURCES;
1168 }
1169
1170
1171 send_status:
1172 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1173 mod_id, vnd);
1174 }
1175
mod_sub_del_all(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1176 static int mod_sub_del_all(const struct bt_mesh_model *model,
1177 struct bt_mesh_msg_ctx *ctx,
1178 struct net_buf_simple *buf)
1179 {
1180 const struct bt_mesh_model *mod;
1181 const struct bt_mesh_elem *elem;
1182 uint16_t elem_addr;
1183 uint8_t *mod_id;
1184 uint8_t status;
1185 bool vnd;
1186
1187 if ((buf->len != 4U) && (buf->len != 6U)) {
1188 LOG_ERR("The message size for the application opcode is incorrect.");
1189 return -EMSGSIZE;
1190 }
1191
1192 elem_addr = net_buf_simple_pull_le16(buf);
1193 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1194 LOG_WRN("Prohibited element address");
1195 return -EINVAL;
1196 }
1197
1198 LOG_DBG("elem_addr 0x%04x", elem_addr);
1199
1200 mod_id = buf->data;
1201
1202 elem = bt_mesh_elem_find(elem_addr);
1203 if (!elem) {
1204 mod = NULL;
1205 vnd = (buf->len == 4U);
1206 status = STATUS_INVALID_ADDRESS;
1207 goto send_status;
1208 }
1209
1210 mod = get_model(elem, buf, &vnd);
1211 if (!mod) {
1212 status = STATUS_INVALID_MODEL;
1213 goto send_status;
1214 }
1215
1216 bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
1217
1218 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1219 bt_mesh_model_sub_store(mod);
1220 }
1221
1222 status = STATUS_SUCCESS;
1223
1224 send_status:
1225 return send_mod_sub_status(model, ctx, status, elem_addr,
1226 BT_MESH_ADDR_UNASSIGNED, mod_id, vnd);
1227 }
1228
1229 struct mod_sub_list_ctx {
1230 uint16_t elem_idx;
1231 struct net_buf_simple *msg;
1232 };
1233
mod_sub_list_visitor(const struct bt_mesh_model * mod,void * ctx)1234 static enum bt_mesh_walk mod_sub_list_visitor(const struct bt_mesh_model *mod, void *ctx)
1235 {
1236 struct mod_sub_list_ctx *visit = ctx;
1237 int count = 0;
1238 int i;
1239
1240 if (mod->rt->elem_idx != visit->elem_idx) {
1241 return BT_MESH_WALK_CONTINUE;
1242 }
1243
1244 for (i = 0; i < mod->groups_cnt; i++) {
1245 if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
1246 continue;
1247 }
1248
1249 if (net_buf_simple_tailroom(visit->msg) <
1250 2 + BT_MESH_MIC_SHORT) {
1251 LOG_WRN("No room for all groups");
1252 return BT_MESH_WALK_STOP;
1253 }
1254
1255 net_buf_simple_add_le16(visit->msg, mod->groups[i]);
1256 count++;
1257 }
1258
1259 LOG_DBG("sublist: model %u:%x: %u groups", mod->rt->elem_idx, mod->id, count);
1260
1261 return BT_MESH_WALK_CONTINUE;
1262 }
1263
mod_sub_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1264 static int mod_sub_get(const struct bt_mesh_model *model,
1265 struct bt_mesh_msg_ctx *ctx,
1266 struct net_buf_simple *buf)
1267 {
1268 NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX);
1269 struct mod_sub_list_ctx visit_ctx;
1270 const struct bt_mesh_model *mod;
1271 const struct bt_mesh_elem *elem;
1272 uint16_t addr, id;
1273
1274 addr = net_buf_simple_pull_le16(buf);
1275 if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
1276 LOG_WRN("Prohibited element address");
1277 return -EINVAL;
1278 }
1279
1280 id = net_buf_simple_pull_le16(buf);
1281
1282 LOG_DBG("addr 0x%04x id 0x%04x", addr, id);
1283
1284 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST);
1285
1286 elem = bt_mesh_elem_find(addr);
1287 if (!elem) {
1288 net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
1289 net_buf_simple_add_le16(&msg, addr);
1290 net_buf_simple_add_le16(&msg, id);
1291 goto send_list;
1292 }
1293
1294 mod = bt_mesh_model_find(elem, id);
1295 if (!mod) {
1296 net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
1297 net_buf_simple_add_le16(&msg, addr);
1298 net_buf_simple_add_le16(&msg, id);
1299 goto send_list;
1300 }
1301
1302 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
1303
1304 net_buf_simple_add_le16(&msg, addr);
1305 net_buf_simple_add_le16(&msg, id);
1306
1307 visit_ctx.msg = &msg;
1308 visit_ctx.elem_idx = mod->rt->elem_idx;
1309 bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
1310
1311 send_list:
1312 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1313 LOG_ERR("Unable to send Model Subscription List");
1314 }
1315
1316 return 0;
1317 }
1318
mod_sub_get_vnd(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1319 static int mod_sub_get_vnd(const struct bt_mesh_model *model,
1320 struct bt_mesh_msg_ctx *ctx,
1321 struct net_buf_simple *buf)
1322 {
1323 NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX);
1324 struct mod_sub_list_ctx visit_ctx;
1325 const struct bt_mesh_model *mod;
1326 const struct bt_mesh_elem *elem;
1327 uint16_t company, addr, id;
1328
1329 addr = net_buf_simple_pull_le16(buf);
1330 if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
1331 LOG_WRN("Prohibited element address");
1332 return -EINVAL;
1333 }
1334
1335 company = net_buf_simple_pull_le16(buf);
1336 id = net_buf_simple_pull_le16(buf);
1337
1338 LOG_DBG("addr 0x%04x company 0x%04x id 0x%04x", addr, company, id);
1339
1340 bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST_VND);
1341
1342 elem = bt_mesh_elem_find(addr);
1343 if (!elem) {
1344 net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
1345 net_buf_simple_add_le16(&msg, addr);
1346 net_buf_simple_add_le16(&msg, company);
1347 net_buf_simple_add_le16(&msg, id);
1348 goto send_list;
1349 }
1350
1351 mod = bt_mesh_model_find_vnd(elem, company, id);
1352 if (!mod) {
1353 net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
1354 net_buf_simple_add_le16(&msg, addr);
1355 net_buf_simple_add_le16(&msg, company);
1356 net_buf_simple_add_le16(&msg, id);
1357 goto send_list;
1358 }
1359
1360 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
1361
1362 net_buf_simple_add_le16(&msg, addr);
1363 net_buf_simple_add_le16(&msg, company);
1364 net_buf_simple_add_le16(&msg, id);
1365
1366 visit_ctx.msg = &msg;
1367 visit_ctx.elem_idx = mod->rt->elem_idx;
1368 bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
1369
1370 send_list:
1371 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1372 LOG_ERR("Unable to send Vendor Model Subscription List");
1373 }
1374
1375 return 0;
1376 }
1377
mod_sub_va_add(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1378 static int mod_sub_va_add(const struct bt_mesh_model *model,
1379 struct bt_mesh_msg_ctx *ctx,
1380 struct net_buf_simple *buf)
1381 {
1382 const struct bt_mesh_va *va;
1383 uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
1384 const struct bt_mesh_model *mod;
1385 const struct bt_mesh_elem *elem;
1386 const uint8_t *uuid;
1387 uint8_t *mod_id;
1388 uint16_t *group_entry;
1389 const uint8_t **label_entry;
1390 uint8_t status;
1391 bool vnd;
1392
1393 if ((buf->len != 20U) && (buf->len != 22U)) {
1394 LOG_ERR("The message size for the application opcode is incorrect.");
1395 return -EMSGSIZE;
1396 }
1397
1398 elem_addr = net_buf_simple_pull_le16(buf);
1399 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1400 LOG_WRN("Prohibited element address");
1401 return -EINVAL;
1402 }
1403
1404 uuid = net_buf_simple_pull_mem(buf, 16);
1405
1406 LOG_DBG("elem_addr 0x%04x", elem_addr);
1407
1408 mod_id = buf->data;
1409 elem = bt_mesh_elem_find(elem_addr);
1410 if (!elem) {
1411 mod = NULL;
1412 vnd = (buf->len == 4U);
1413 status = STATUS_INVALID_ADDRESS;
1414 goto send_status;
1415 }
1416
1417 mod = get_model(elem, buf, &vnd);
1418 if (!mod) {
1419 status = STATUS_INVALID_MODEL;
1420 goto send_status;
1421 }
1422
1423 status = bt_mesh_va_add(uuid, &va);
1424 if (status != STATUS_SUCCESS) {
1425 goto send_status;
1426 }
1427
1428 if (bt_mesh_model_find_uuid(&mod, va->uuid)) {
1429 /* Tried to add existing subscription */
1430 status = STATUS_SUCCESS;
1431 (void)bt_mesh_va_del(va->uuid);
1432 goto send_status;
1433 }
1434
1435 label_entry = bt_mesh_model_find_uuid(&mod, NULL);
1436 if (!label_entry) {
1437 status = STATUS_INSUFF_RESOURCES;
1438 (void)bt_mesh_va_del(va->uuid);
1439 goto send_status;
1440 }
1441
1442 group_entry = NULL;
1443
1444 for (int i = 0; i < mod->groups_cnt; i++) {
1445 if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
1446 group_entry = &mod->groups[i];
1447 break;
1448 }
1449 }
1450
1451 /* bt_mesh_model_find_uuid() should find a model where both, uuids and groups lists have
1452 * empty entry.
1453 */
1454 if (!group_entry) {
1455 status = STATUS_INSUFF_RESOURCES;
1456 (void)bt_mesh_va_del(va->uuid);
1457 goto send_status;
1458 }
1459
1460 *group_entry = va->addr;
1461 *label_entry = va->uuid;
1462
1463 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
1464 !bt_mesh_va_collision_check(va->addr)) {
1465 bt_mesh_lpn_group_add(va->addr);
1466 }
1467
1468 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1469 bt_mesh_model_sub_store(mod);
1470 }
1471
1472 status = STATUS_SUCCESS;
1473 sub_addr = va->addr;
1474
1475 send_status:
1476 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1477 mod_id, vnd);
1478 }
1479
mod_sub_va_del(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1480 static int mod_sub_va_del(const struct bt_mesh_model *model,
1481 struct bt_mesh_msg_ctx *ctx,
1482 struct net_buf_simple *buf)
1483 {
1484 const struct bt_mesh_va *va;
1485 uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
1486 const struct bt_mesh_model *mod;
1487 const struct bt_mesh_elem *elem;
1488 const uint8_t *uuid;
1489 uint8_t *mod_id;
1490 const uint8_t **label_match;
1491 uint8_t status;
1492 bool vnd;
1493
1494 if ((buf->len != 20U) && (buf->len != 22U)) {
1495 LOG_ERR("The message size for the application opcode is incorrect.");
1496 return -EMSGSIZE;
1497 }
1498
1499 elem_addr = net_buf_simple_pull_le16(buf);
1500 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1501 LOG_WRN("Prohibited element address");
1502 return -EINVAL;
1503 }
1504
1505 uuid = net_buf_simple_pull_mem(buf, 16);
1506
1507 LOG_DBG("elem_addr 0x%04x", elem_addr);
1508
1509 mod_id = buf->data;
1510
1511 elem = bt_mesh_elem_find(elem_addr);
1512 if (!elem) {
1513 mod = NULL;
1514 vnd = (buf->len == 4U);
1515 status = STATUS_INVALID_ADDRESS;
1516 goto send_status;
1517 }
1518
1519 mod = get_model(elem, buf, &vnd);
1520 if (!mod) {
1521 status = STATUS_INVALID_MODEL;
1522 goto send_status;
1523 }
1524
1525 va = bt_mesh_va_find(uuid);
1526 if (!va) {
1527 status = STATUS_CANNOT_REMOVE;
1528 goto send_status;
1529 }
1530
1531 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
1532 !bt_mesh_va_collision_check(va->addr)) {
1533 bt_mesh_lpn_group_del(&va->addr, 1);
1534 }
1535
1536 label_match = bt_mesh_model_find_uuid(&mod, va->uuid);
1537 if (!label_match) {
1538 status = STATUS_CANNOT_REMOVE;
1539 goto send_status;
1540 }
1541
1542 for (int i = 0; i < mod->groups_cnt; i++) {
1543 if (mod->groups[i] == va->addr) {
1544 mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
1545 break;
1546 }
1547 }
1548
1549 *label_match = NULL;
1550
1551 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1552 bt_mesh_model_sub_store(mod);
1553 }
1554
1555 sub_addr = va->addr;
1556 (void)bt_mesh_va_del(va->uuid);
1557 status = STATUS_SUCCESS;
1558
1559 send_status:
1560 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1561 mod_id, vnd);
1562 }
1563
mod_sub_va_overwrite(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1564 static int mod_sub_va_overwrite(const struct bt_mesh_model *model,
1565 struct bt_mesh_msg_ctx *ctx,
1566 struct net_buf_simple *buf)
1567 {
1568 const struct bt_mesh_va *va;
1569 uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
1570 const struct bt_mesh_model *mod;
1571 const struct bt_mesh_elem *elem;
1572 const uint8_t *uuid;
1573 uint8_t *mod_id;
1574 uint8_t status;
1575 bool vnd;
1576
1577 if ((buf->len != 20U) && (buf->len != 22U)) {
1578 LOG_ERR("The message size for the application opcode is incorrect.");
1579 return -EMSGSIZE;
1580 }
1581
1582 elem_addr = net_buf_simple_pull_le16(buf);
1583 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1584 LOG_WRN("Prohibited element address");
1585 return -EINVAL;
1586 }
1587
1588 uuid = net_buf_simple_pull_mem(buf, 16);
1589
1590 LOG_DBG("elem_addr 0x%04x", elem_addr);
1591
1592 mod_id = buf->data;
1593
1594 elem = bt_mesh_elem_find(elem_addr);
1595 if (!elem) {
1596 mod = NULL;
1597 vnd = (buf->len == 4U);
1598 status = STATUS_INVALID_ADDRESS;
1599 goto send_status;
1600 }
1601
1602 mod = get_model(elem, buf, &vnd);
1603 if (!mod) {
1604 status = STATUS_INVALID_MODEL;
1605 goto send_status;
1606 }
1607
1608 if (CONFIG_BT_MESH_LABEL_COUNT == 0 || mod->groups_cnt == 0) {
1609 (void)va;
1610 status = STATUS_INSUFF_RESOURCES;
1611 goto send_status;
1612 }
1613
1614 #if CONFIG_BT_MESH_LABEL_COUNT > 0
1615 status = bt_mesh_va_add(uuid, &va);
1616 if (status != STATUS_SUCCESS) {
1617 goto send_status;
1618 }
1619
1620 bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
1621 mod->groups[0] = va->addr;
1622 mod->uuids[0] = va->uuid;
1623
1624 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1625 bt_mesh_model_sub_store(mod);
1626 }
1627
1628 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
1629 !bt_mesh_va_collision_check(va->addr)) {
1630 bt_mesh_lpn_group_add(va->addr);
1631 }
1632
1633 sub_addr = va->addr;
1634 #endif
1635 send_status:
1636 return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
1637 mod_id, vnd);
1638 }
1639
send_net_key_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t idx,uint8_t status)1640 static int send_net_key_status(const struct bt_mesh_model *model,
1641 struct bt_mesh_msg_ctx *ctx, uint16_t idx,
1642 uint8_t status)
1643 {
1644 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3);
1645
1646 bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS);
1647
1648 net_buf_simple_add_u8(&msg, status);
1649 net_buf_simple_add_le16(&msg, idx);
1650
1651 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1652 LOG_ERR("Unable to send NetKey Status");
1653 }
1654
1655 return 0;
1656 }
1657
net_key_add(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1658 static int net_key_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
1659 struct net_buf_simple *buf)
1660 {
1661 uint8_t status;
1662 uint16_t idx;
1663
1664 idx = net_buf_simple_pull_le16(buf);
1665 if (idx > 0xfff) {
1666 LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
1667 return -EINVAL;
1668 }
1669
1670 LOG_DBG("idx 0x%04x", idx);
1671
1672 status = bt_mesh_subnet_add(idx, buf->data);
1673
1674 return send_net_key_status(model, ctx, idx, status);
1675 }
1676
net_key_update(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1677 static int net_key_update(const struct bt_mesh_model *model,
1678 struct bt_mesh_msg_ctx *ctx,
1679 struct net_buf_simple *buf)
1680 {
1681 uint8_t status;
1682 uint16_t idx;
1683
1684 idx = net_buf_simple_pull_le16(buf);
1685 if (idx > 0xfff) {
1686 LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
1687 return -EINVAL;
1688 }
1689
1690 status = bt_mesh_subnet_update(idx, buf->data);
1691
1692 return send_net_key_status(model, ctx, idx, status);
1693 }
1694
net_key_del(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1695 static int net_key_del(const struct bt_mesh_model *model,
1696 struct bt_mesh_msg_ctx *ctx,
1697 struct net_buf_simple *buf)
1698 {
1699 uint16_t del_idx;
1700
1701 del_idx = net_buf_simple_pull_le16(buf);
1702 if (del_idx > 0xfff) {
1703 LOG_ERR("Invalid NetKeyIndex 0x%04x", del_idx);
1704 return -EINVAL;
1705 }
1706
1707 LOG_DBG("idx 0x%04x", del_idx);
1708
1709 /* The key that the message was encrypted with cannot be removed.
1710 * The NetKey List must contain a minimum of one NetKey.
1711 */
1712 if (ctx->net_idx == del_idx) {
1713 return send_net_key_status(model, ctx, del_idx,
1714 STATUS_CANNOT_REMOVE);
1715 }
1716
1717 (void)bt_mesh_subnet_del(del_idx);
1718
1719 return send_net_key_status(model, ctx, del_idx, STATUS_SUCCESS);
1720 }
1721
net_key_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1722 static int net_key_get(const struct bt_mesh_model *model,
1723 struct bt_mesh_msg_ctx *ctx,
1724 struct net_buf_simple *buf)
1725 {
1726 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST,
1727 IDX_LEN(CONFIG_BT_MESH_SUBNET_COUNT));
1728 uint16_t net_idx[CONFIG_BT_MESH_SUBNET_COUNT];
1729 ssize_t count;
1730
1731 bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST);
1732
1733 count = bt_mesh_subnets_get(net_idx, ARRAY_SIZE(net_idx), 0);
1734 if (count < 0 || count > ARRAY_SIZE(net_idx)) {
1735 count = ARRAY_SIZE(net_idx);
1736 }
1737
1738 key_idx_pack_list(&msg, net_idx, count);
1739
1740 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1741 LOG_ERR("Unable to send NetKey List");
1742 }
1743
1744 return 0;
1745 }
1746
send_node_id_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status,uint16_t net_idx,uint8_t node_id)1747 static int send_node_id_status(const struct bt_mesh_model *model,
1748 struct bt_mesh_msg_ctx *ctx,
1749 uint8_t status,
1750 uint16_t net_idx, uint8_t node_id)
1751 {
1752 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
1753
1754 bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_STATUS);
1755 net_buf_simple_add_u8(&msg, status);
1756 net_buf_simple_add_le16(&msg, net_idx);
1757 net_buf_simple_add_u8(&msg, node_id);
1758
1759 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1760 LOG_ERR("Unable to send Node Identity Status");
1761 }
1762
1763 return 0;
1764 }
1765
node_identity_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1766 static int node_identity_get(const struct bt_mesh_model *model,
1767 struct bt_mesh_msg_ctx *ctx,
1768 struct net_buf_simple *buf)
1769 {
1770 enum bt_mesh_feat_state node_id;
1771 uint8_t status;
1772 uint16_t idx;
1773
1774 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
1775 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
1776
1777 idx = net_buf_simple_pull_le16(buf);
1778 if (idx > 0xfff) {
1779 LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
1780 return -EINVAL;
1781 }
1782
1783 status = bt_mesh_subnet_node_id_get(idx, &node_id);
1784
1785 return send_node_id_status(model, ctx, status, idx, node_id);
1786 }
1787
node_identity_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1788 static int node_identity_set(const struct bt_mesh_model *model,
1789 struct bt_mesh_msg_ctx *ctx,
1790 struct net_buf_simple *buf)
1791 {
1792 uint8_t node_id, status;
1793 uint16_t idx;
1794
1795 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
1796 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
1797
1798 idx = net_buf_simple_pull_le16(buf);
1799 if (idx > 0xfff) {
1800 LOG_WRN("Invalid NetKeyIndex 0x%04x", idx);
1801 return -EINVAL;
1802 }
1803
1804 node_id = net_buf_simple_pull_u8(buf);
1805 if (node_id != 0x00 && node_id != 0x01) {
1806 LOG_WRN("Invalid Node ID value 0x%02x", node_id);
1807 return -EINVAL;
1808 }
1809
1810 status = bt_mesh_subnet_node_id_set(idx, node_id);
1811 if (status == STATUS_INVALID_NETKEY) {
1812 return send_node_id_status(model, ctx, status, idx,
1813 BT_MESH_NODE_IDENTITY_STOPPED);
1814 }
1815
1816 if (status == STATUS_FEAT_NOT_SUPP) {
1817 /* Should return success, even if feature isn't supported: */
1818 return send_node_id_status(model, ctx, STATUS_SUCCESS, idx,
1819 BT_MESH_NODE_IDENTITY_NOT_SUPPORTED);
1820 }
1821
1822 return send_node_id_status(model, ctx, status, idx, node_id);
1823 }
1824
create_mod_app_status(struct net_buf_simple * msg,const struct bt_mesh_model * mod,bool vnd,uint16_t elem_addr,uint16_t app_idx,uint8_t status,uint8_t * mod_id)1825 static void create_mod_app_status(struct net_buf_simple *msg,
1826 const struct bt_mesh_model *mod, bool vnd,
1827 uint16_t elem_addr, uint16_t app_idx,
1828 uint8_t status, uint8_t *mod_id)
1829 {
1830 bt_mesh_model_msg_init(msg, OP_MOD_APP_STATUS);
1831
1832 net_buf_simple_add_u8(msg, status);
1833 net_buf_simple_add_le16(msg, elem_addr);
1834 net_buf_simple_add_le16(msg, app_idx);
1835
1836 if (vnd) {
1837 memcpy(net_buf_simple_add(msg, 4), mod_id, 4);
1838 } else {
1839 memcpy(net_buf_simple_add(msg, 2), mod_id, 2);
1840 }
1841 }
1842
mod_app_bind(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1843 static int mod_app_bind(const struct bt_mesh_model *model,
1844 struct bt_mesh_msg_ctx *ctx,
1845 struct net_buf_simple *buf)
1846 {
1847 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
1848 uint16_t elem_addr, key_app_idx;
1849 const struct bt_mesh_model *mod;
1850 const struct bt_mesh_elem *elem;
1851 uint8_t *mod_id, status;
1852 bool vnd;
1853
1854 if ((buf->len != 6U) && (buf->len != 8U)) {
1855 LOG_ERR("The message size for the application opcode is incorrect.");
1856 return -EMSGSIZE;
1857 }
1858
1859 elem_addr = net_buf_simple_pull_le16(buf);
1860 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1861 LOG_WRN("Prohibited element address");
1862 return -EINVAL;
1863 }
1864
1865 key_app_idx = net_buf_simple_pull_le16(buf);
1866 mod_id = buf->data;
1867
1868 elem = bt_mesh_elem_find(elem_addr);
1869 if (!elem) {
1870 mod = NULL;
1871 vnd = (buf->len == 4U);
1872 status = STATUS_INVALID_ADDRESS;
1873 goto send_status;
1874 }
1875
1876 mod = get_model(elem, buf, &vnd);
1877 if (!mod) {
1878 status = STATUS_INVALID_MODEL;
1879 goto send_status;
1880 }
1881
1882 /* Some models only allow device key based access */
1883 if (mod->rt->flags & BT_MESH_MOD_DEVKEY_ONLY) {
1884 LOG_ERR("Client tried to bind AppKey to DevKey based model");
1885 status = STATUS_CANNOT_BIND;
1886 goto send_status;
1887 }
1888
1889 status = mod_bind(mod, key_app_idx);
1890
1891 if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) {
1892 bt_test_mesh_model_bound(ctx->addr, mod, key_app_idx);
1893 }
1894
1895 send_status:
1896 LOG_DBG("status 0x%02x", status);
1897 create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
1898 mod_id);
1899
1900 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1901 LOG_ERR("Unable to send Model App Bind Status response");
1902 }
1903
1904 return 0;
1905 }
1906
mod_app_unbind(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1907 static int mod_app_unbind(const struct bt_mesh_model *model,
1908 struct bt_mesh_msg_ctx *ctx,
1909 struct net_buf_simple *buf)
1910 {
1911 BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
1912 uint16_t elem_addr, key_app_idx;
1913 const struct bt_mesh_model *mod;
1914 const struct bt_mesh_elem *elem;
1915 uint8_t *mod_id, status;
1916 bool vnd;
1917
1918 if ((buf->len != 6U) && (buf->len != 8U)) {
1919 LOG_ERR("The message size for the application opcode is incorrect.");
1920 return -EMSGSIZE;
1921 }
1922
1923 elem_addr = net_buf_simple_pull_le16(buf);
1924 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1925 LOG_WRN("Prohibited element address");
1926 return -EINVAL;
1927 }
1928
1929 key_app_idx = net_buf_simple_pull_le16(buf);
1930 mod_id = buf->data;
1931
1932 elem = bt_mesh_elem_find(elem_addr);
1933 if (!elem) {
1934 mod = NULL;
1935 vnd = (buf->len == 4U);
1936 status = STATUS_INVALID_ADDRESS;
1937 goto send_status;
1938 }
1939
1940 mod = get_model(elem, buf, &vnd);
1941 if (!mod) {
1942 status = STATUS_INVALID_MODEL;
1943 goto send_status;
1944 }
1945
1946 status = mod_unbind(mod, key_app_idx, true);
1947
1948 if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) {
1949 bt_test_mesh_model_unbound(ctx->addr, mod, key_app_idx);
1950 }
1951
1952 send_status:
1953 LOG_DBG("status 0x%02x", status);
1954 create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
1955 mod_id);
1956
1957 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
1958 LOG_ERR("Unable to send Model App Unbind Status response");
1959 }
1960
1961 return 0;
1962 }
1963
1964 #define KEY_LIST_LEN (CONFIG_BT_MESH_MODEL_KEY_COUNT * 2)
1965
mod_app_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1966 static int mod_app_get(const struct bt_mesh_model *model,
1967 struct bt_mesh_msg_ctx *ctx,
1968 struct net_buf_simple *buf)
1969 {
1970 NET_BUF_SIMPLE_DEFINE(msg,
1971 MAX(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST,
1972 9 + KEY_LIST_LEN),
1973 BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST,
1974 9 + KEY_LIST_LEN)));
1975 const struct bt_mesh_model *mod;
1976 const struct bt_mesh_elem *elem;
1977 uint8_t *mod_id, status;
1978 uint16_t elem_addr;
1979 bool vnd;
1980
1981 if ((buf->len != 4U) && (buf->len != 6U)) {
1982 LOG_ERR("The message size for the application opcode is incorrect.");
1983 return -EMSGSIZE;
1984 }
1985
1986 elem_addr = net_buf_simple_pull_le16(buf);
1987 if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
1988 LOG_WRN("Prohibited element address");
1989 return -EINVAL;
1990 }
1991
1992 mod_id = buf->data;
1993
1994 LOG_DBG("elem_addr 0x%04x", elem_addr);
1995
1996 elem = bt_mesh_elem_find(elem_addr);
1997 if (!elem) {
1998 mod = NULL;
1999 vnd = (buf->len == 4U);
2000 status = STATUS_INVALID_ADDRESS;
2001 goto send_list;
2002 }
2003
2004 mod = get_model(elem, buf, &vnd);
2005 if (!mod) {
2006 status = STATUS_INVALID_MODEL;
2007 goto send_list;
2008 }
2009
2010 status = STATUS_SUCCESS;
2011
2012 send_list:
2013 if (vnd) {
2014 bt_mesh_model_msg_init(&msg, OP_VND_MOD_APP_LIST);
2015 } else {
2016 bt_mesh_model_msg_init(&msg, OP_SIG_MOD_APP_LIST);
2017 }
2018
2019 net_buf_simple_add_u8(&msg, status);
2020 net_buf_simple_add_le16(&msg, elem_addr);
2021
2022 if (vnd) {
2023 net_buf_simple_add_mem(&msg, mod_id, 4);
2024 } else {
2025 net_buf_simple_add_mem(&msg, mod_id, 2);
2026 }
2027
2028 if (mod) {
2029 key_idx_pack_list(&msg, mod->keys, mod->keys_cnt);
2030 }
2031
2032 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2033 LOG_ERR("Unable to send Model Application List message");
2034 }
2035
2036 return 0;
2037 }
2038
reset_send_start(uint16_t duration,int err,void * cb_data)2039 static void reset_send_start(uint16_t duration, int err, void *cb_data)
2040 {
2041 if (err) {
2042 LOG_ERR("Sending Node Reset Status failed (err %d)", err);
2043 k_work_submit(&node_reset_pending);
2044 }
2045 }
2046
reset_send_end(int err,void * cb_data)2047 static void reset_send_end(int err, void *cb_data)
2048 {
2049 k_work_submit(&node_reset_pending);
2050 }
2051
node_reset(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2052 static int node_reset(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
2053 struct net_buf_simple *buf)
2054 {
2055 static const struct bt_mesh_send_cb reset_cb = {
2056 .start = reset_send_start,
2057 .end = reset_send_end,
2058 };
2059
2060 BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
2061
2062 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
2063 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
2064
2065 bt_mesh_model_msg_init(&msg, OP_NODE_RESET_STATUS);
2066
2067 if (bt_mesh_model_send(model, ctx, &msg, &reset_cb, NULL)) {
2068 LOG_ERR("Unable to send Node Reset Status");
2069 }
2070
2071 return 0;
2072 }
2073
send_friend_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)2074 static int send_friend_status(const struct bt_mesh_model *model,
2075 struct bt_mesh_msg_ctx *ctx)
2076 {
2077 BT_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
2078
2079 bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
2080 net_buf_simple_add_u8(&msg, bt_mesh_friend_get());
2081
2082 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2083 LOG_ERR("Unable to send Friend Status");
2084 }
2085
2086 return 0;
2087 }
2088
friend_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2089 static int friend_get(const struct bt_mesh_model *model,
2090 struct bt_mesh_msg_ctx *ctx,
2091 struct net_buf_simple *buf)
2092 {
2093 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
2094 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
2095
2096 return send_friend_status(model, ctx);
2097 }
2098
friend_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2099 static int friend_set(const struct bt_mesh_model *model,
2100 struct bt_mesh_msg_ctx *ctx,
2101 struct net_buf_simple *buf)
2102 {
2103 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
2104 ctx->addr, buf->len, bt_hex(buf->data, buf->len));
2105
2106 if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
2107 LOG_WRN("Invalid Friend value 0x%02x", buf->data[0]);
2108 return -EINVAL;
2109 }
2110
2111 (void)bt_mesh_friend_set(buf->data[0]);
2112
2113 return send_friend_status(model, ctx);
2114 }
2115
lpn_timeout_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2116 static int lpn_timeout_get(const struct bt_mesh_model *model,
2117 struct bt_mesh_msg_ctx *ctx,
2118 struct net_buf_simple *buf)
2119 {
2120 BT_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5);
2121 struct bt_mesh_friend *frnd;
2122 int32_t timeout_steps;
2123 uint16_t lpn_addr;
2124
2125 lpn_addr = net_buf_simple_pull_le16(buf);
2126
2127 LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x", ctx->net_idx,
2128 ctx->app_idx, ctx->addr, lpn_addr);
2129
2130 if (!BT_MESH_ADDR_IS_UNICAST(lpn_addr)) {
2131 LOG_WRN("Invalid LPNAddress; ignoring msg");
2132 return -EINVAL;
2133 }
2134
2135 bt_mesh_model_msg_init(&msg, OP_LPN_TIMEOUT_STATUS);
2136 net_buf_simple_add_le16(&msg, lpn_addr);
2137
2138 if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
2139 timeout_steps = 0;
2140 goto send_rsp;
2141 }
2142
2143 frnd = bt_mesh_friend_find(BT_MESH_KEY_ANY, lpn_addr, true, true);
2144 if (!frnd) {
2145 timeout_steps = 0;
2146 goto send_rsp;
2147 }
2148
2149 /* PollTimeout should be reported in steps of 100ms. */
2150 timeout_steps = frnd->poll_to / 100;
2151
2152 send_rsp:
2153 net_buf_simple_add_le24(&msg, timeout_steps);
2154
2155 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2156 LOG_ERR("Unable to send LPN PollTimeout Status");
2157 }
2158
2159 return 0;
2160 }
2161
send_krp_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t idx,uint8_t phase,uint8_t status)2162 static int send_krp_status(const struct bt_mesh_model *model,
2163 struct bt_mesh_msg_ctx *ctx, uint16_t idx,
2164 uint8_t phase, uint8_t status)
2165 {
2166 BT_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4);
2167
2168 bt_mesh_model_msg_init(&msg, OP_KRP_STATUS);
2169
2170 net_buf_simple_add_u8(&msg, status);
2171 net_buf_simple_add_le16(&msg, idx);
2172 net_buf_simple_add_u8(&msg, phase);
2173
2174 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2175 LOG_ERR("Unable to send Key Refresh State Status");
2176 }
2177
2178 return 0;
2179 }
2180
krp_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2181 static int krp_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
2182 struct net_buf_simple *buf)
2183 {
2184 uint8_t kr_phase, status;
2185 uint16_t idx;
2186
2187 idx = net_buf_simple_pull_le16(buf);
2188 if (idx > 0xfff) {
2189 LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
2190 return -EINVAL;
2191 }
2192
2193 LOG_DBG("idx 0x%04x", idx);
2194
2195 status = bt_mesh_subnet_kr_phase_get(idx, &kr_phase);
2196
2197 return send_krp_status(model, ctx, idx, kr_phase, status);
2198 }
2199
krp_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2200 static int krp_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
2201 struct net_buf_simple *buf)
2202 {
2203 uint8_t phase, status;
2204 uint16_t idx;
2205
2206 idx = net_buf_simple_pull_le16(buf);
2207 phase = net_buf_simple_pull_u8(buf);
2208
2209 if (idx > 0xfff) {
2210 LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
2211 return -EINVAL;
2212 }
2213
2214 status = bt_mesh_subnet_kr_phase_set(idx, &phase);
2215 if (status == STATUS_CANNOT_UPDATE) {
2216 LOG_ERR("Invalid kr phase transition 0x%02x", phase);
2217 return -EINVAL;
2218 }
2219
2220 return send_krp_status(model, ctx, idx, phase, status);
2221 }
2222
hb_sub_count_log(uint32_t val)2223 static uint8_t hb_sub_count_log(uint32_t val)
2224 {
2225 if (val == 0xffff) {
2226 return 0xff;
2227 } else {
2228 return bt_mesh_hb_log(val);
2229 }
2230 }
2231
hb_pub_count_log(uint16_t val)2232 static uint8_t hb_pub_count_log(uint16_t val)
2233 {
2234 if (!val) {
2235 return 0x00;
2236 } else if (val == 0x01) {
2237 return 0x01;
2238 } else if (val == 0xfffe) {
2239 return 0x11;
2240 } else if (val == 0xffff) {
2241 return 0xff;
2242 } else {
2243 return 32 - __builtin_clz(val - 1) + 1;
2244 }
2245 }
2246
2247 struct hb_pub_param {
2248 uint16_t dst;
2249 uint8_t count_log;
2250 uint8_t period_log;
2251 uint8_t ttl;
2252 uint16_t feat;
2253 uint16_t net_idx;
2254 } __packed;
2255
hb_pub_send_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint8_t status,const struct bt_mesh_hb_pub * pub)2256 static int hb_pub_send_status(const struct bt_mesh_model *model,
2257 struct bt_mesh_msg_ctx *ctx, uint8_t status,
2258 const struct bt_mesh_hb_pub *pub)
2259 {
2260 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10);
2261
2262 LOG_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
2263
2264 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_STATUS);
2265
2266 net_buf_simple_add_u8(&msg, status);
2267
2268 net_buf_simple_add_le16(&msg, pub->dst);
2269 if (pub->dst == BT_MESH_ADDR_UNASSIGNED) {
2270 (void)memset(net_buf_simple_add(&msg, 7), 0, 7);
2271 } else {
2272 net_buf_simple_add_u8(&msg, hb_pub_count_log(pub->count));
2273 net_buf_simple_add_u8(&msg, bt_mesh_hb_log(pub->period));
2274 net_buf_simple_add_u8(&msg, pub->ttl);
2275 net_buf_simple_add_le16(&msg, pub->feat);
2276 net_buf_simple_add_le16(&msg, pub->net_idx & 0xfff);
2277 }
2278
2279 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2280 LOG_ERR("Unable to send Heartbeat Publication Status");
2281 }
2282
2283 return 0;
2284 }
2285
heartbeat_pub_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2286 static int heartbeat_pub_get(const struct bt_mesh_model *model,
2287 struct bt_mesh_msg_ctx *ctx,
2288 struct net_buf_simple *buf)
2289 {
2290 struct bt_mesh_hb_pub pub;
2291
2292 LOG_DBG("src 0x%04x", ctx->addr);
2293
2294 bt_mesh_hb_pub_get(&pub);
2295
2296 return hb_pub_send_status(model, ctx, STATUS_SUCCESS, &pub);
2297 }
2298
heartbeat_pub_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2299 static int heartbeat_pub_set(const struct bt_mesh_model *model,
2300 struct bt_mesh_msg_ctx *ctx,
2301 struct net_buf_simple *buf)
2302 {
2303 struct hb_pub_param *param = (void *)buf->data;
2304 struct bt_mesh_hb_pub pub;
2305 uint8_t status;
2306
2307 LOG_DBG("src 0x%04x", ctx->addr);
2308
2309 pub.dst = sys_le16_to_cpu(param->dst);
2310 if (param->count_log == 0x11) {
2311 /* Special case defined in MshPRFv1.1 Errata 11737 */
2312 pub.count = 0xfffe;
2313 } else {
2314 pub.count = bt_mesh_hb_pwr2(param->count_log);
2315 }
2316
2317 if (param->period_log == 0x11) {
2318 pub.period = 0x10000;
2319 } else {
2320 pub.period = bt_mesh_hb_pwr2(param->period_log);
2321 }
2322
2323 pub.ttl = param->ttl;
2324 pub.feat = sys_le16_to_cpu(param->feat);
2325 pub.net_idx = sys_le16_to_cpu(param->net_idx);
2326
2327 /* All other address types but virtual are valid */
2328 if (BT_MESH_ADDR_IS_VIRTUAL(pub.dst)) {
2329 status = STATUS_INVALID_ADDRESS;
2330 goto rsp;
2331 }
2332
2333 if (param->count_log > 0x11 && param->count_log != 0xff) {
2334 status = STATUS_CANNOT_SET;
2335 goto rsp;
2336 }
2337
2338 if (param->period_log > 0x11) {
2339 status = STATUS_CANNOT_SET;
2340 goto rsp;
2341 }
2342
2343 if (param->ttl > BT_MESH_TTL_MAX && param->ttl != BT_MESH_TTL_DEFAULT) {
2344 LOG_ERR("Invalid TTL value 0x%02x", param->ttl);
2345 return -EINVAL;
2346 }
2347
2348 if (pub.net_idx > 0xfff) {
2349 LOG_ERR("Invalid NetKeyIndex 0x%04x", pub.net_idx);
2350 return -EINVAL;
2351 }
2352
2353 status = bt_mesh_hb_pub_set(&pub);
2354
2355 rsp:
2356 return hb_pub_send_status(model, ctx, status, &pub);
2357 }
2358
hb_sub_send_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,const struct bt_mesh_hb_sub * sub)2359 static int hb_sub_send_status(const struct bt_mesh_model *model,
2360 struct bt_mesh_msg_ctx *ctx,
2361 const struct bt_mesh_hb_sub *sub)
2362 {
2363 BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9);
2364
2365 LOG_DBG("src 0x%04x ", ctx->addr);
2366
2367 bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_STATUS);
2368
2369 net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
2370 net_buf_simple_add_le16(&msg, sub->src);
2371 net_buf_simple_add_le16(&msg, sub->dst);
2372 net_buf_simple_add_u8(&msg, bt_mesh_hb_log(sub->remaining));
2373 net_buf_simple_add_u8(&msg, hb_sub_count_log(sub->count));
2374 net_buf_simple_add_u8(&msg, sub->min_hops);
2375 net_buf_simple_add_u8(&msg, sub->max_hops);
2376
2377 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
2378 LOG_ERR("Unable to send Heartbeat Subscription Status");
2379 }
2380
2381 return 0;
2382 }
2383
heartbeat_sub_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2384 static int heartbeat_sub_get(const struct bt_mesh_model *model,
2385 struct bt_mesh_msg_ctx *ctx,
2386 struct net_buf_simple *buf)
2387 {
2388 struct bt_mesh_hb_sub sub;
2389
2390 LOG_DBG("src 0x%04x", ctx->addr);
2391
2392 bt_mesh_hb_sub_get(&sub);
2393
2394 return hb_sub_send_status(model, ctx, &sub);
2395 }
2396
heartbeat_sub_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2397 static int heartbeat_sub_set(const struct bt_mesh_model *model,
2398 struct bt_mesh_msg_ctx *ctx,
2399 struct net_buf_simple *buf)
2400 {
2401 uint8_t period_log, status;
2402 struct bt_mesh_hb_sub sub;
2403 uint16_t sub_src, sub_dst;
2404 uint32_t period;
2405 int err;
2406
2407 LOG_DBG("src 0x%04x", ctx->addr);
2408
2409 sub_src = net_buf_simple_pull_le16(buf);
2410 sub_dst = net_buf_simple_pull_le16(buf);
2411 period_log = net_buf_simple_pull_u8(buf);
2412
2413 LOG_DBG("sub_src 0x%04x sub_dst 0x%04x period 0x%02x", sub_src, sub_dst, period_log);
2414
2415 if (period_log > 0x11) {
2416 LOG_WRN("Prohibited subscription period 0x%02x", period_log);
2417 return -EINVAL;
2418 }
2419
2420 if (period_log == 0x11) {
2421 period = 0x10000;
2422 } else {
2423 period = bt_mesh_hb_pwr2(period_log);
2424 }
2425
2426 status = bt_mesh_hb_sub_set(sub_src, sub_dst, period);
2427 if (status != STATUS_SUCCESS) {
2428 /* All errors are caused by invalid packets, which should be
2429 * ignored.
2430 */
2431 return -EINVAL;
2432 }
2433
2434 bt_mesh_hb_sub_get(&sub);
2435
2436 /* MESH/NODE/CFG/HBS/BV-01-C expects the MinHops to be 0x7f after
2437 * disabling subscription, but 0x00 for subsequent Get requests.
2438 */
2439 if (sub.src == BT_MESH_ADDR_UNASSIGNED || !period_log) {
2440 sub.min_hops = BT_MESH_TTL_MAX;
2441 }
2442
2443 err = hb_sub_send_status(model, ctx, &sub);
2444 if (err) {
2445 return err;
2446 }
2447
2448 /* MESH/NODE/CFG/HBS/BV-02-C expects us to return previous
2449 * count value and then reset it to 0.
2450 */
2451 if (sub.src != BT_MESH_ADDR_UNASSIGNED &&
2452 sub.dst != BT_MESH_ADDR_UNASSIGNED && !period) {
2453 bt_mesh_hb_sub_reset_count();
2454 }
2455
2456 return 0;
2457 }
2458
2459 const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = {
2460 { OP_DEV_COMP_DATA_GET, BT_MESH_LEN_EXACT(1), dev_comp_data_get },
2461 { OP_APP_KEY_ADD, BT_MESH_LEN_EXACT(19), app_key_add },
2462 { OP_APP_KEY_UPDATE, BT_MESH_LEN_EXACT(19), app_key_update },
2463 { OP_APP_KEY_DEL, BT_MESH_LEN_EXACT(3), app_key_del },
2464 { OP_APP_KEY_GET, BT_MESH_LEN_EXACT(2), app_key_get },
2465 { OP_BEACON_GET, BT_MESH_LEN_EXACT(0), beacon_get },
2466 { OP_BEACON_SET, BT_MESH_LEN_EXACT(1), beacon_set },
2467 { OP_DEFAULT_TTL_GET, BT_MESH_LEN_EXACT(0), default_ttl_get },
2468 { OP_DEFAULT_TTL_SET, BT_MESH_LEN_EXACT(1), default_ttl_set },
2469 { OP_GATT_PROXY_GET, BT_MESH_LEN_EXACT(0), gatt_proxy_get },
2470 { OP_GATT_PROXY_SET, BT_MESH_LEN_EXACT(1), gatt_proxy_set },
2471 { OP_NET_TRANSMIT_GET, BT_MESH_LEN_EXACT(0), net_transmit_get },
2472 { OP_NET_TRANSMIT_SET, BT_MESH_LEN_EXACT(1), net_transmit_set },
2473 { OP_RELAY_GET, BT_MESH_LEN_EXACT(0), relay_get },
2474 { OP_RELAY_SET, BT_MESH_LEN_EXACT(2), relay_set },
2475 { OP_MOD_PUB_GET, BT_MESH_LEN_MIN(4), mod_pub_get },
2476 { OP_MOD_PUB_SET, BT_MESH_LEN_MIN(11), mod_pub_set },
2477 { OP_MOD_PUB_VA_SET, BT_MESH_LEN_MIN(25), mod_pub_va_set },
2478 { OP_MOD_SUB_ADD, BT_MESH_LEN_MIN(6), mod_sub_add },
2479 { OP_MOD_SUB_VA_ADD, BT_MESH_LEN_MIN(20), mod_sub_va_add },
2480 { OP_MOD_SUB_DEL, BT_MESH_LEN_MIN(6), mod_sub_del },
2481 { OP_MOD_SUB_VA_DEL, BT_MESH_LEN_MIN(20), mod_sub_va_del },
2482 { OP_MOD_SUB_OVERWRITE, BT_MESH_LEN_MIN(6), mod_sub_overwrite },
2483 { OP_MOD_SUB_VA_OVERWRITE, BT_MESH_LEN_MIN(20), mod_sub_va_overwrite },
2484 { OP_MOD_SUB_DEL_ALL, BT_MESH_LEN_MIN(4), mod_sub_del_all },
2485 { OP_MOD_SUB_GET, BT_MESH_LEN_EXACT(4), mod_sub_get },
2486 { OP_MOD_SUB_GET_VND, BT_MESH_LEN_EXACT(6), mod_sub_get_vnd },
2487 { OP_NET_KEY_ADD, BT_MESH_LEN_EXACT(18), net_key_add },
2488 { OP_NET_KEY_UPDATE, BT_MESH_LEN_EXACT(18), net_key_update },
2489 { OP_NET_KEY_DEL, BT_MESH_LEN_EXACT(2), net_key_del },
2490 { OP_NET_KEY_GET, BT_MESH_LEN_EXACT(0), net_key_get },
2491 { OP_NODE_IDENTITY_GET, BT_MESH_LEN_EXACT(2), node_identity_get },
2492 { OP_NODE_IDENTITY_SET, BT_MESH_LEN_EXACT(3), node_identity_set },
2493 { OP_MOD_APP_BIND, BT_MESH_LEN_MIN(6), mod_app_bind },
2494 { OP_MOD_APP_UNBIND, BT_MESH_LEN_MIN(6), mod_app_unbind },
2495 { OP_SIG_MOD_APP_GET, BT_MESH_LEN_MIN(4), mod_app_get },
2496 { OP_VND_MOD_APP_GET, BT_MESH_LEN_MIN(6), mod_app_get },
2497 { OP_NODE_RESET, BT_MESH_LEN_EXACT(0), node_reset },
2498 { OP_FRIEND_GET, BT_MESH_LEN_EXACT(0), friend_get },
2499 { OP_FRIEND_SET, BT_MESH_LEN_EXACT(1), friend_set },
2500 { OP_LPN_TIMEOUT_GET, BT_MESH_LEN_EXACT(2), lpn_timeout_get },
2501 { OP_KRP_GET, BT_MESH_LEN_EXACT(2), krp_get },
2502 { OP_KRP_SET, BT_MESH_LEN_EXACT(3), krp_set },
2503 { OP_HEARTBEAT_PUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_pub_get },
2504 { OP_HEARTBEAT_PUB_SET, BT_MESH_LEN_EXACT(9), heartbeat_pub_set },
2505 { OP_HEARTBEAT_SUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_sub_get },
2506 { OP_HEARTBEAT_SUB_SET, BT_MESH_LEN_EXACT(5), heartbeat_sub_set },
2507 BT_MESH_MODEL_OP_END,
2508 };
2509
cfg_srv_init(const struct bt_mesh_model * model)2510 static int cfg_srv_init(const struct bt_mesh_model *model)
2511 {
2512 if (!bt_mesh_model_in_primary(model)) {
2513 LOG_ERR("Configuration Server only allowed in primary element");
2514 return -EINVAL;
2515 }
2516
2517 /*
2518 * Configuration Model security is device-key based and only the local
2519 * device-key is allowed to access this model.
2520 */
2521 model->keys[0] = BT_MESH_KEY_DEV_LOCAL;
2522 model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
2523
2524 return 0;
2525 }
2526
2527 const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = {
2528 .init = cfg_srv_init,
2529 };
2530
mod_reset(const struct bt_mesh_model * mod,const struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)2531 static void mod_reset(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem,
2532 bool vnd, bool primary, void *user_data)
2533 {
2534 size_t clear_count;
2535
2536 /* Clear model state that isn't otherwise cleared. E.g. AppKey
2537 * binding and model publication is cleared as a consequence
2538 * of removing all app keys, however model subscription and user data
2539 * clearing must be taken care of here.
2540 */
2541
2542 clear_count = mod_sub_list_clear(mod);
2543
2544 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
2545 if (clear_count) {
2546 bt_mesh_model_sub_store(mod);
2547 }
2548 }
2549
2550 if (mod->cb && mod->cb->reset) {
2551 mod->cb->reset(mod);
2552 }
2553 }
2554
bt_mesh_model_reset(void)2555 void bt_mesh_model_reset(void)
2556 {
2557 bt_mesh_model_foreach(mod_reset, NULL);
2558 }
2559