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