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