• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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