1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <ble_os.h>
10 #include <string.h>
11 #include <bt_errno.h>
12 #include <stdbool.h>
13 #include <ble_types/types.h>
14 #include <misc/util.h>
15 #include <misc/byteorder.h>
16 
17 #include <bluetooth/bluetooth.h>
18 #include <bluetooth/conn.h>
19 #include <api/mesh.h>
20 
21 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)
22 #include "common/log.h"
23 
24 #include "net.h"
25 #include "foundation.h"
26 
27 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
28 #include "mesh_event_port.h"
29 #endif
30 
31 #if defined(CONFIG_BT_MESH_CFG_CLI)
32 
33 #define CID_NVAL 0xffff
34 
35 struct comp_data {
36     u8_t *status;
37     struct net_buf_simple *comp;
38 };
39 
40 static bt_s32_t msg_timeout = K_SECONDS(2);
41 
42 static struct bt_mesh_cfg_cli *cli;
43 
44 struct bt_mesh_cfg_cli g_cfg_cli = {};
45 
comp_data_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)46 static void comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
47 {
48     struct comp_data *param;
49     size_t to_copy;
50     u8_t status;
51     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
52            bt_hex(buf->data, buf->len));
53 
54 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
55     bt_mesh_model_evt_t evt_data;
56     evt_data.source_addr = ctx->addr;
57     evt_data.user_data = buf;
58     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
59     if (event_cb) {
60         event_cb(BT_MESH_MODEL_EVT_COMP_DATA_STATUS, &evt_data);
61     }
62 #endif
63 
64     if (cli->op_pending != OP_DEV_COMP_DATA_STATUS) {
65         BT_WARN("Unexpected Composition Data Status");
66         return;
67     }
68 
69     param = cli->op_param;
70 
71     status = net_buf_simple_pull_u8(buf);
72     if (param) {
73         to_copy = MIN(net_buf_simple_tailroom(param->comp), buf->len);
74         net_buf_simple_add_mem(param->comp, buf->data, to_copy);
75         if (param && param->status) {
76             *param->status = status;
77         }
78         k_sem_give(&cli->op_sync);
79     }
80 }
81 
state_status_u8(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf,bt_u32_t expect_status)82 static void state_status_u8(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf,
83                             bt_u32_t expect_status)
84 {
85     u8_t status;
86 
87     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
88            bt_hex(buf->data, buf->len));
89 
90     if (cli->op_pending != expect_status) {
91         BT_WARN("Unexpected Status (0x%08x != 0x%08x)", cli->op_pending, expect_status);
92         return;
93     }
94 
95     status = net_buf_simple_pull_u8(buf);
96     if (cli->op_param) {
97         *((u8_t *)cli->op_param) = status;
98         k_sem_give(&cli->op_sync);
99     }
100 }
101 
beacon_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)102 static void beacon_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
103 {
104 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
105     bt_mesh_model_evt_t evt_data;
106     evt_data.source_addr = ctx->addr;
107     evt_data.user_data = buf;
108     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
109     if (event_cb) {
110         event_cb(BT_MESH_MODEL_EVT_BEACON_STATUS, &evt_data);
111     }
112 #endif
113 
114     state_status_u8(model, ctx, buf, OP_BEACON_STATUS);
115 }
116 
ttl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)117 static void ttl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
118 {
119 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
120     bt_mesh_model_evt_t evt_data;
121     evt_data.source_addr = ctx->addr;
122     evt_data.user_data = buf;
123     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
124     if (event_cb) {
125         event_cb(BT_MESH_MODEL_EVT_TTL_STATUS, &evt_data);
126     }
127 #endif
128 
129     state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS);
130 }
131 
friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)132 static void friend_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
133 {
134 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
135     bt_mesh_model_evt_t evt_data;
136     evt_data.source_addr = ctx->addr;
137     evt_data.user_data = buf;
138     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
139     if (event_cb) {
140         event_cb(BT_MESH_MODEL_EVT_FRIEND_STATUS, &evt_data);
141     }
142 #endif
143 
144     state_status_u8(model, ctx, buf, OP_FRIEND_STATUS);
145 }
146 
gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)147 static void gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
148 {
149 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
150     bt_mesh_model_evt_t evt_data;
151     evt_data.source_addr = ctx->addr;
152     evt_data.user_data = buf;
153     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
154     if (event_cb) {
155         event_cb(BT_MESH_MODEL_EVT_PROXY_STATUS, &evt_data);
156     }
157 #endif
158 
159     state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS);
160 }
161 
162 struct relay_param {
163     u8_t *status;
164     u8_t *transmit;
165 };
166 
relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)167 static void relay_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
168 {
169     struct relay_param *param;
170     uint8_t status;
171     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
172            bt_hex(buf->data, buf->len));
173 
174 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
175     bt_mesh_model_evt_t evt_data;
176     evt_data.source_addr = ctx->addr;
177     evt_data.user_data = buf;
178     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
179     if (event_cb) {
180         event_cb(BT_MESH_MODEL_EVT_RELAY_STATUS, &evt_data);
181     }
182 #endif
183 
184     if (cli->op_pending != OP_RELAY_STATUS) {
185         BT_WARN("Unexpected Relay Status message");
186         return;
187     }
188 
189     param = cli->op_param;
190     status = net_buf_simple_pull_u8(buf);
191 
192     if (param) {
193         *param->transmit = net_buf_simple_pull_u8(buf);
194         if (param->status) {
195             *param->status = status;
196         }
197 
198         k_sem_give(&cli->op_sync);
199     }
200 }
201 
202 struct net_key_param {
203     u8_t *status;
204     u16_t net_idx;
205 };
206 
net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)207 static void net_key_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
208 {
209     struct net_key_param *param;
210     u16_t net_idx;
211     u8_t status;
212 
213     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
214            bt_hex(buf->data, buf->len));
215 
216 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
217     bt_mesh_model_evt_t evt_data;
218     evt_data.source_addr = ctx->addr;
219     evt_data.user_data = buf;
220     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
221     if (event_cb) {
222         event_cb(BT_MESH_MODEL_EVT_NETKEY_STATUS, &evt_data);
223     }
224 #endif
225 
226     if (cli->op_pending != OP_NET_KEY_STATUS) {
227         BT_WARN("Unexpected Net Key Status message");
228         return;
229     }
230 
231     status = net_buf_simple_pull_u8(buf);
232     net_idx = net_buf_simple_pull_le16(buf);
233     param = cli->op_param;
234 
235     if (param && param->net_idx != net_idx) {
236         BT_WARN("Net Key Status key index does not match");
237         return;
238     }
239 
240     if (param && param->status) {
241         *param->status = status;
242     }
243 
244     if (param) {
245         k_sem_give(&cli->op_sync);
246     }
247 }
248 
249 struct krp_param {
250     uint8_t *status;
251     uint16_t net_idx;
252     uint8_t *phase;
253 };
254 
net_krp_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)255 static void net_krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
256 {
257     struct krp_param *param;
258     u16_t net_idx;
259     u8_t status, phase;
260 
261     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s\n", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
262            bt_hex(buf->data, buf->len));
263 
264 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
265     bt_mesh_model_evt_t evt_data;
266     evt_data.source_addr = ctx->addr;
267     evt_data.user_data = buf;
268     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
269     if (event_cb) {
270         event_cb(BT_MESH_MODEL_EVT_NET_KRP_STATUS, &evt_data);
271     }
272 #endif
273 
274     if (cli->op_pending != OP_KRP_STATUS) {
275         BT_WARN("Unexpected KRP Status message");
276         return;
277     }
278 
279     status = net_buf_simple_pull_u8(buf);
280     net_idx = net_buf_simple_pull_le16(buf);
281     phase = net_buf_simple_pull_u8(buf);
282     param = cli->op_param;
283     if (param) {
284         if (param->net_idx != net_idx) {
285             BT_WARN("krp Status key index does not match");
286             return;
287         }
288 
289         if (param->status) {
290             *param->status = status;
291         }
292 
293         if (param->phase) {
294             *param->phase = phase;
295         }
296 
297         k_sem_give(&cli->op_sync);
298     }
299 }
300 
301 struct app_key_param {
302     u8_t *status;
303     u16_t net_idx;
304     u16_t app_idx;
305 };
306 
app_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)307 static void app_key_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
308 {
309     struct app_key_param *param;
310     u16_t net_idx, app_idx;
311     u8_t status;
312 
313     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
314            bt_hex(buf->data, buf->len));
315 
316 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
317     bt_mesh_model_evt_t evt_data;
318     evt_data.source_addr = ctx->addr;
319     evt_data.user_data = buf;
320     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
321     if (event_cb) {
322         event_cb(BT_MESH_MODEL_EVT_APPKEY_STATUS, &evt_data);
323     }
324 #endif
325 
326     if (cli->op_pending != OP_APP_KEY_STATUS) {
327         BT_WARN("Unexpected App Key Status message");
328         return;
329     }
330 
331     status = net_buf_simple_pull_u8(buf);
332     key_idx_unpack(buf, &net_idx, &app_idx);
333 
334     param = cli->op_param;
335     if (param && (param->net_idx != net_idx || param->app_idx != app_idx)) {
336         BT_WARN("App Key Status key indices did not match");
337         return;
338     }
339 
340     if (param && param->status) {
341         *param->status = status;
342     }
343 
344     if (param) {
345         k_sem_give(&cli->op_sync);
346     }
347 }
348 
349 struct mod_app_param {
350     u8_t *status;
351     u16_t elem_addr;
352     u16_t mod_app_idx;
353     u16_t mod_id;
354     u16_t cid;
355 };
356 
mod_app_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)357 static void mod_app_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
358 {
359     u16_t elem_addr, mod_app_idx, mod_id, cid;
360     struct mod_app_param *param;
361     u8_t status;
362 
363     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
364            bt_hex(buf->data, buf->len));
365 
366 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
367     bt_mesh_model_evt_t evt_data;
368     evt_data.source_addr = ctx->addr;
369     evt_data.user_data = buf;
370     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
371     if (event_cb) {
372         event_cb(BT_MESH_MODEL_EVT_APPKEY_BIND_STATUS, &evt_data);
373     }
374 #endif
375 
376     if (cli->op_pending != OP_MOD_APP_STATUS) {
377         BT_WARN("Unexpected Model App Status message");
378         return;
379     }
380     status = net_buf_simple_pull_u8(buf);
381     elem_addr = net_buf_simple_pull_le16(buf);
382     mod_app_idx = net_buf_simple_pull_le16(buf);
383 
384     if (buf->len >= 4) {
385         cid = net_buf_simple_pull_le16(buf);
386     } else {
387         cid = CID_NVAL;
388     }
389 
390     mod_id = net_buf_simple_pull_le16(buf);
391 
392     param = cli->op_param;
393     if (param) {
394         if (param->elem_addr != elem_addr || param->mod_app_idx != mod_app_idx || param->mod_id != mod_id ||
395             param->cid != cid) {
396             BT_WARN("Model App Status parameters did not match");
397             return;
398         }
399 
400         if (param->status) {
401             *param->status = status;
402         }
403 
404         k_sem_give(&cli->op_sync);
405     }
406 }
407 
408 struct mod_pub_param {
409     u16_t mod_id;
410     u16_t cid;
411     u16_t elem_addr;
412     u8_t *status;
413     struct bt_mesh_cfg_mod_pub *pub;
414 };
415 
mod_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)416 static void mod_pub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
417 {
418     u16_t mod_id, cid, elem_addr;
419     struct mod_pub_param *param;
420     u8_t status;
421 
422     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
423            bt_hex(buf->data, buf->len));
424 
425 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
426     bt_mesh_model_evt_t evt_data;
427     evt_data.source_addr = ctx->addr;
428     evt_data.user_data = buf;
429     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
430     if (event_cb) {
431         event_cb(BT_MESH_MODEL_EVT_PUB_STATUS, &evt_data);
432     }
433 #endif
434 
435     if (cli->op_pending != OP_MOD_PUB_STATUS) {
436         BT_WARN("Unexpected Model Pub Status message");
437         return;
438     }
439 
440     param = cli->op_param;
441 
442     if (param) {
443         if (param->cid != CID_NVAL) {
444             if (buf->len < 14) {
445                 BT_WARN("Unexpected Mod Pub Status with SIG Model");
446                 return;
447             }
448 
449             cid = sys_get_le16(&buf->data[10]);
450             mod_id = sys_get_le16(&buf->data[12]);
451         } else {
452             if (buf->len > 12) {
453                 BT_WARN("Unexpected Mod Pub Status with Vendor Model");
454                 return;
455             }
456 
457             cid = CID_NVAL;
458             mod_id = sys_get_le16(&buf->data[10]);
459         }
460 
461         if (mod_id != param->mod_id || cid != param->cid) {
462             BT_WARN("Mod Pub Model ID or Company ID mismatch");
463             return;
464         }
465 
466         status = net_buf_simple_pull_u8(buf);
467 
468         elem_addr = net_buf_simple_pull_le16(buf);
469 
470         if (elem_addr != param->elem_addr) {
471             BT_WARN("Model Pub Status for unexpected element (0x%04x)", elem_addr);
472             return;
473         }
474 
475         if (param->status) {
476             *param->status = status;
477         }
478 
479         if (param->pub) {
480             param->pub->addr = net_buf_simple_pull_le16(buf);
481             param->pub->app_idx = net_buf_simple_pull_le16(buf);
482             param->pub->cred_flag = (param->pub->app_idx & BIT(12));
483             param->pub->app_idx &= BIT_MASK(12);
484             param->pub->ttl = net_buf_simple_pull_u8(buf);
485             param->pub->period = net_buf_simple_pull_u8(buf);
486             param->pub->transmit = net_buf_simple_pull_u8(buf);
487         }
488 
489         k_sem_give(&cli->op_sync);
490     }
491 }
492 
493 struct mod_sub_param {
494     u8_t *status;
495     u16_t elem_addr;
496     u16_t *sub_addr;
497     u16_t *expect_sub;
498     u16_t mod_id;
499     u16_t cid;
500 };
501 
mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)502 static void mod_sub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
503 {
504     u16_t elem_addr, sub_addr, mod_id, cid;
505     struct mod_sub_param *param;
506     u8_t status;
507 
508     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
509            bt_hex(buf->data, buf->len));
510 
511 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
512     bt_mesh_model_evt_t evt_data;
513     evt_data.source_addr = ctx->addr;
514     evt_data.user_data = buf;
515     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
516     if (event_cb) {
517         event_cb(BT_MESH_MODEL_EVT_SUB_STATUS, &evt_data);
518     }
519 #endif
520 
521     if (cli->op_pending != OP_MOD_SUB_STATUS) {
522         BT_WARN("Unexpected Model Subscription Status message");
523         return;
524     }
525 
526     status = net_buf_simple_pull_u8(buf);
527     elem_addr = net_buf_simple_pull_le16(buf);
528     sub_addr = net_buf_simple_pull_le16(buf);
529 
530     if (buf->len >= 4) {
531         cid = net_buf_simple_pull_le16(buf);
532     } else {
533         cid = CID_NVAL;
534     }
535 
536     mod_id = net_buf_simple_pull_le16(buf);
537 
538     param = cli->op_param;
539     if (param) {
540         if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
541             (param->expect_sub && *param->expect_sub != sub_addr) || param->cid != cid) {
542             BT_WARN("Model Subscription Status parameters did not match");
543             return;
544         }
545 
546         if (param->sub_addr) {
547             *param->sub_addr = sub_addr;
548         }
549 
550         if (param->status) {
551             *param->status = status;
552         }
553 
554         k_sem_give(&cli->op_sync);
555     }
556 }
557 
mod_sub_list_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)558 static void mod_sub_list_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
559 {
560     u16_t elem_addr;
561     struct mod_sub_param *param;
562     u8_t status;
563     u16_t mod_id;
564 
565     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
566            bt_hex(buf->data, buf->len));
567 
568 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
569     bt_mesh_model_evt_t evt_data;
570     evt_data.source_addr = ctx->addr;
571     evt_data.user_data = buf;
572     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
573     if (event_cb) {
574         event_cb(BT_MESH_MODEL_EVT_SUB_LIST, &evt_data);
575     }
576 #endif
577 
578     if (cli->op_pending != OP_MOD_SUB_LIST) {
579         BT_WARN("Unexpected Model App Status message");
580         return;
581     }
582 
583     status = net_buf_simple_pull_u8(buf);
584     elem_addr = net_buf_simple_pull_le16(buf);
585     mod_id = net_buf_simple_pull_le16(buf);
586 
587     param = (struct mod_sub_param *)cli->op_param;
588     if (param) {
589         if (param->elem_addr != elem_addr) {
590             BT_WARN("Model App Status parameters did not match");
591             return;
592         }
593         if (param->status) {
594             *param->status = status;
595         }
596         if (param->sub_addr) {
597             uint8_t index = 0;
598             while (buf->len >= 2) {
599                 param->sub_addr[index++] = net_buf_simple_pull_le16(buf);
600             }
601         }
602 
603         k_sem_give(&cli->op_sync);
604     }
605     (void)mod_id;
606 }
607 
mod_sub_list_vnd_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)608 static void mod_sub_list_vnd_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
609                                     struct net_buf_simple *buf)
610 {
611     u16_t elem_addr;
612     u16_t company_id;
613     struct mod_sub_param *param;
614     u8_t status;
615     u16_t mod_id;
616 
617     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
618            bt_hex(buf->data, buf->len));
619 
620 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
621     bt_mesh_model_evt_t evt_data;
622     evt_data.source_addr = ctx->addr;
623     evt_data.user_data = buf;
624     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
625     if (event_cb) {
626         event_cb(BT_MESH_MODEL_EVT_SUB_LIST_VND, &evt_data);
627     }
628 #endif
629 
630     if (cli->op_pending != OP_MOD_SUB_LIST_VND) {
631         BT_WARN("Unexpected Model App Status message");
632         return;
633     }
634 
635     status = net_buf_simple_pull_u8(buf);
636     elem_addr = net_buf_simple_pull_le16(buf);
637     company_id = net_buf_simple_pull_le16(buf);
638     mod_id = net_buf_simple_pull_le16(buf);
639 
640     param = (struct mod_sub_param *)cli->op_param;
641     if (param) {
642         if (param->elem_addr != elem_addr) {
643             BT_WARN("Model App Status parameters did not match");
644             return;
645         }
646         if (param->status) {
647             *param->status = status;
648         }
649         if (param->sub_addr) {
650             uint8_t index = 0;
651             while (buf->len >= 2) {
652                 param->sub_addr[index++] = net_buf_simple_pull_le16(buf);
653             }
654         }
655 
656         k_sem_give(&cli->op_sync);
657     }
658     (void)mod_id;
659     (void)company_id;
660 }
661 
662 struct hb_sub_param {
663     u8_t *status;
664     struct bt_mesh_cfg_hb_sub *sub;
665 };
666 
hb_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)667 static void hb_sub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
668 {
669     struct hb_sub_param *param;
670     uint8_t status;
671     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
672            bt_hex(buf->data, buf->len));
673 
674 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
675     bt_mesh_model_evt_t evt_data;
676     evt_data.source_addr = ctx->addr;
677     evt_data.user_data = buf;
678     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
679     if (event_cb) {
680         event_cb(BT_MESH_MODEL_EVT_HB_SUB_STATUS, &evt_data);
681     }
682 #endif
683 
684     if (cli->op_pending != OP_HEARTBEAT_SUB_STATUS) {
685         BT_WARN("Unexpected Heartbeat Subscription Status message");
686         return;
687     }
688 
689     param = cli->op_param;
690 
691     status = net_buf_simple_pull_u8(buf);
692 
693     if (param) {
694         param->sub->src = net_buf_simple_pull_le16(buf);
695         param->sub->dst = net_buf_simple_pull_le16(buf);
696         param->sub->period = net_buf_simple_pull_u8(buf);
697         param->sub->count = net_buf_simple_pull_u8(buf);
698         param->sub->min = net_buf_simple_pull_u8(buf);
699         param->sub->max = net_buf_simple_pull_u8(buf);
700         if (param->status) {
701             *param->status = status;
702         }
703 
704         k_sem_give(&cli->op_sync);
705     }
706 }
707 
708 struct hb_pub_param {
709     u8_t *status;
710     struct bt_mesh_cfg_hb_pub *pub;
711 };
712 
hb_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)713 static void hb_pub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
714 {
715     struct hb_pub_param *param;
716     uint8_t status;
717     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
718            bt_hex(buf->data, buf->len));
719 
720 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
721     bt_mesh_model_evt_t evt_data;
722     evt_data.source_addr = ctx->addr;
723     evt_data.user_data = buf;
724     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
725     if (event_cb) {
726         event_cb(BT_MESH_MODEL_EVT_HB_PUB_STATUS, &evt_data);
727     }
728 #endif
729 
730     if (cli->op_pending != OP_HEARTBEAT_PUB_STATUS) {
731         BT_WARN("Unexpected Heartbeat Publication Status message");
732         return;
733     }
734 
735     param = cli->op_param;
736 
737     status = net_buf_simple_pull_u8(buf);
738 
739     if (param && param->pub) {
740         param->pub->dst = net_buf_simple_pull_le16(buf);
741         param->pub->count = net_buf_simple_pull_u8(buf);
742         param->pub->period = net_buf_simple_pull_u8(buf);
743         param->pub->ttl = net_buf_simple_pull_u8(buf);
744         param->pub->feat = net_buf_simple_pull_u8(buf);
745         param->pub->net_idx = net_buf_simple_pull_u8(buf);
746     }
747     if (param && param->status) {
748         *param->status = status;
749     }
750     if (param) {
751         k_sem_give(&cli->op_sync);
752     }
753 }
754 
node_reset_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)755 static void node_reset_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
756 {
757     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
758            bt_hex(buf->data, buf->len));
759 
760 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
761     bt_mesh_model_evt_t evt_data;
762     evt_data.source_addr = ctx->addr;
763     evt_data.user_data = buf;
764     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
765     if (event_cb) {
766         event_cb(BT_MESH_MODEL_EVT_NODE_RESET_STATUS, &evt_data);
767     }
768 #endif
769     if (cli->op_pending != OP_NODE_RESET_STATUS) {
770         BT_WARN("Unexpected Node Reset Status message");
771         return;
772     }
773 
774     k_sem_give(&cli->op_sync);
775 }
776 
777 /*[Genie begin] add by wenbing.cwb at 2021-01-21*/
778 #ifdef CONFIG_BT_MESH_CTRL_RELAY
779 struct cli_cr_param {
780     u8_t *status;
781     struct ctrl_relay_param *cr_p;
782 };
783 
cli_ctrl_relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)784 static void cli_ctrl_relay_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
785 {
786     struct cli_cr_param *param;
787 
788     BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
789            bt_hex(buf->data, buf->len));
790 
791 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
792     bt_mesh_model_evt_t evt_data;
793     evt_data.source_addr = ctx->addr;
794     evt_data.user_data = buf;
795     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
796     if (event_cb) {
797         event_cb(BT_MESH_MODEL_EVT_CTRL_RELAY_STATUS, &evt_data);
798     }
799 #endif
800 
801     if (cli->op_pending != OP_CTRL_RELAY_CONF_STATUS) {
802         BT_WARN("Unexpected Ctrl Relay Status message");
803         return;
804     }
805 
806     param = cli->op_param;
807 
808     *param->status = net_buf_simple_pull_u8(buf);
809 
810     if (param->cr_p) {
811         param->cr_p->enable = net_buf_simple_pull_u8(buf);
812         param->cr_p->trd_n = net_buf_simple_pull_u8(buf);
813         param->cr_p->rssi = net_buf_simple_pull_u8(buf);
814         param->cr_p->sta_period = net_buf_simple_pull_u8(buf);
815         param->cr_p->chk_period = net_buf_simple_pull_u8(buf);
816         param->cr_p->req_period = net_buf_simple_pull_u8(buf);
817     }
818 
819     k_sem_give(&cli->op_sync);
820 }
821 #endif
822 /*[Genie end] add by wenbing.cwb at 2021-01-21*/
823 
824 const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
825     { OP_DEV_COMP_DATA_STATUS, 15, comp_data_status },
826     { OP_BEACON_STATUS, 1, beacon_status },
827     { OP_DEFAULT_TTL_STATUS, 1, ttl_status },
828     { OP_FRIEND_STATUS, 1, friend_status },
829     { OP_GATT_PROXY_STATUS, 1, gatt_proxy_status },
830     { OP_RELAY_STATUS, 2, relay_status },
831     { OP_NET_KEY_STATUS, 3, net_key_status },
832     { OP_APP_KEY_STATUS, 4, app_key_status },
833     { OP_MOD_APP_STATUS, 7, mod_app_status },
834     { OP_MOD_PUB_STATUS, 12, mod_pub_status },
835     { OP_MOD_SUB_STATUS, 7, mod_sub_status },
836     { OP_HEARTBEAT_SUB_STATUS, 9, hb_sub_status },
837     { OP_HEARTBEAT_PUB_STATUS, 10, hb_pub_status },
838     { OP_NODE_RESET_STATUS, 0, node_reset_status },
839     { OP_KRP_STATUS, 4, net_krp_status },
840     { OP_MOD_SUB_LIST, 5, mod_sub_list_status },
841     { OP_MOD_SUB_LIST_VND, 7, mod_sub_list_vnd_status },
842 /*[Genie begin] add by wenbing.cwb at 2021-01-21*/
843 #ifdef CONFIG_BT_MESH_CTRL_RELAY
844     { OP_CTRL_RELAY_CONF_STATUS, 7, cli_ctrl_relay_status },
845 #endif
846     /*[Genie end] add by wenbing.cwb at 2021-01-21*/
847     BT_MESH_MODEL_OP_END,
848 };
849 
cli_prepare(void * param,bt_u32_t op)850 static int cli_prepare(void *param, bt_u32_t op)
851 {
852     if (!cli) {
853         BT_ERR("No available Configuration Client context!");
854         return -EINVAL;
855     }
856 
857     if (cli->op_pending) {
858         BT_WARN("Another synchronous operation pending");
859         return -EBUSY;
860     }
861 
862     cli->op_param = param;
863     cli->op_pending = op;
864 
865     return 0;
866 }
867 
cli_reset(void)868 static void cli_reset(void)
869 {
870     cli->op_pending = 0;
871     cli->op_param = NULL;
872 }
873 
cli_wait(void)874 static int cli_wait(void)
875 {
876     int err;
877 
878     err = k_sem_take(&cli->op_sync, msg_timeout);
879 
880     cli_reset();
881 
882     return err;
883 }
884 
bt_mesh_cfg_comp_data_get(u16_t net_idx,u16_t addr,u8_t page,u8_t * status,struct net_buf_simple * comp)885 int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, u8_t *status, struct net_buf_simple *comp)
886 {
887     if (status && comp == NULL) {
888         return -EINVAL;
889     }
890 
891     NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
892     struct bt_mesh_msg_ctx ctx = {
893         .net_idx = net_idx,
894         .app_idx = BT_MESH_KEY_DEV,
895         .addr = addr,
896         .send_ttl = BT_MESH_TTL_DEFAULT,
897     };
898     struct comp_data param = {
899         .status = status,
900         .comp = comp,
901     };
902     int err;
903 
904     err = cli_prepare(&param, OP_DEV_COMP_DATA_STATUS);
905     if (err) {
906         return err;
907     }
908 
909     bt_mesh_model_msg_init(&msg, OP_DEV_COMP_DATA_GET);
910     net_buf_simple_add_u8(&msg, page);
911 
912     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
913     if (err) {
914         BT_ERR("model_send() failed (err %d)", err);
915         cli_reset();
916         return err;
917     }
918     if (!status) {
919         cli_reset();
920         return 0;
921     }
922     return cli_wait();
923 }
924 
get_state_u8(u16_t net_idx,u16_t addr,bt_u32_t op,bt_u32_t rsp,u8_t * val)925 static int get_state_u8(u16_t net_idx, u16_t addr, bt_u32_t op, bt_u32_t rsp, u8_t *val)
926 {
927     NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
928     struct bt_mesh_msg_ctx ctx = {
929         .net_idx = net_idx,
930         .app_idx = BT_MESH_KEY_DEV,
931         .addr = addr,
932         .send_ttl = BT_MESH_TTL_DEFAULT,
933     };
934     int err;
935 
936     err = cli_prepare(val, rsp);
937     if (err) {
938         return err;
939     }
940 
941     bt_mesh_model_msg_init(&msg, op);
942 
943     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
944     if (err) {
945         BT_ERR("model_send() failed (err %d)", err);
946         cli_reset();
947         return err;
948     }
949     if (!val) {
950         cli_reset();
951         return 0;
952     }
953     return cli_wait();
954 }
955 
set_state_u8(u16_t net_idx,u16_t addr,bt_u32_t op,bt_u32_t rsp,u8_t new_val,u8_t * val)956 static int set_state_u8(u16_t net_idx, u16_t addr, bt_u32_t op, bt_u32_t rsp, u8_t new_val, u8_t *val)
957 {
958     NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
959     struct bt_mesh_msg_ctx ctx = {
960         .net_idx = net_idx,
961         .app_idx = BT_MESH_KEY_DEV,
962         .addr = addr,
963         .send_ttl = BT_MESH_TTL_DEFAULT,
964     };
965     int err;
966 
967     err = cli_prepare(val, rsp);
968     if (err) {
969         return err;
970     }
971 
972     bt_mesh_model_msg_init(&msg, op);
973     net_buf_simple_add_u8(&msg, new_val);
974 
975     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
976     if (err) {
977         BT_ERR("model_send() failed (err %d)", err);
978         cli_reset();
979         return err;
980     }
981     if (!val) {
982         cli_reset();
983         return 0;
984     }
985     return cli_wait();
986 }
987 
bt_mesh_cfg_beacon_get(u16_t net_idx,u16_t addr,u8_t * status)988 int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status)
989 {
990     return get_state_u8(net_idx, addr, OP_BEACON_GET, OP_BEACON_STATUS, status);
991 }
992 
bt_mesh_cfg_beacon_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)993 int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
994 {
995     if (val > BT_MESH_BEACON_ENABLED) {
996         return -EINVAL;
997     }
998     return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS, val, status);
999 }
1000 
bt_mesh_cfg_ttl_get(u16_t net_idx,u16_t addr,u8_t * ttl)1001 int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl)
1002 {
1003     if (ttl == NULL) {
1004         return -EINVAL;
1005     }
1006     return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET, OP_DEFAULT_TTL_STATUS, ttl);
1007 }
1008 
bt_mesh_cfg_ttl_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * ttl)1009 int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl)
1010 {
1011     if (ttl == NULL || val == 0x01 || val > BT_MESH_TTL_MAX) {
1012         return -EINVAL;
1013     }
1014     return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET, OP_DEFAULT_TTL_STATUS, val, ttl);
1015 }
1016 
bt_mesh_cfg_friend_get(u16_t net_idx,u16_t addr,u8_t * status)1017 int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status)
1018 {
1019     return get_state_u8(net_idx, addr, OP_FRIEND_GET, OP_FRIEND_STATUS, status);
1020 }
1021 
bt_mesh_cfg_friend_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)1022 int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
1023 {
1024     if (val > BT_MESH_FRIEND_ENABLED) {
1025         return -EINVAL;
1026     }
1027     return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS, val, status);
1028 }
1029 
bt_mesh_cfg_gatt_proxy_get(u16_t net_idx,u16_t addr,u8_t * status)1030 int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status)
1031 {
1032     return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET, OP_GATT_PROXY_STATUS, status);
1033 }
1034 
bt_mesh_cfg_gatt_proxy_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)1035 int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
1036 {
1037     if (val > BT_MESH_GATT_PROXY_ENABLED) {
1038         return -EINVAL;
1039     }
1040     return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET, OP_GATT_PROXY_STATUS, val, status);
1041 }
1042 
bt_mesh_cfg_relay_get(u16_t net_idx,u16_t addr,u8_t * status,u8_t * transmit)1043 int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status, u8_t *transmit)
1044 {
1045     if (transmit == NULL) {
1046         return -EINVAL;
1047     }
1048 
1049     NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
1050     struct bt_mesh_msg_ctx ctx = {
1051         .net_idx = net_idx,
1052         .app_idx = BT_MESH_KEY_DEV,
1053         .addr = addr,
1054         .send_ttl = BT_MESH_TTL_DEFAULT,
1055     };
1056     struct relay_param param = {
1057         .status = status,
1058         .transmit = transmit,
1059     };
1060     int err;
1061 
1062     err = cli_prepare(&param, OP_RELAY_STATUS);
1063     if (err) {
1064         return err;
1065     }
1066 
1067     bt_mesh_model_msg_init(&msg, OP_RELAY_GET);
1068 
1069     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1070     if (err) {
1071         BT_ERR("model_send() failed (err %d)", err);
1072         cli_reset();
1073         return err;
1074     }
1075     if (!status) {
1076         cli_reset();
1077         return 0;
1078     }
1079     return cli_wait();
1080 }
1081 
bt_mesh_cfg_relay_set(u16_t net_idx,u16_t addr,u8_t new_relay,u8_t new_transmit,u8_t * status,u8_t * transmit)1082 int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay, u8_t new_transmit, u8_t *status, u8_t *transmit)
1083 {
1084     if (transmit == NULL) {
1085         return -EINVAL;
1086     }
1087 
1088     if (new_relay > BT_MESH_RELAY_ENABLED) {
1089         return -EINVAL;
1090     }
1091 
1092     NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
1093     struct bt_mesh_msg_ctx ctx = {
1094         .net_idx = net_idx,
1095         .app_idx = BT_MESH_KEY_DEV,
1096         .addr = addr,
1097         .send_ttl = BT_MESH_TTL_DEFAULT,
1098     };
1099     struct relay_param param = {
1100         .status = status,
1101         .transmit = transmit,
1102     };
1103     int err;
1104 
1105     err = cli_prepare(&param, OP_RELAY_STATUS);
1106     if (err) {
1107         return err;
1108     }
1109 
1110     bt_mesh_model_msg_init(&msg, OP_RELAY_SET);
1111     net_buf_simple_add_u8(&msg, new_relay);
1112     net_buf_simple_add_u8(&msg, new_transmit);
1113 
1114     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1115     if (err) {
1116         BT_ERR("model_send() failed (err %d)", err);
1117         cli_reset();
1118         return err;
1119     }
1120     if (!status) {
1121         cli_reset();
1122         return 0;
1123     }
1124     return cli_wait();
1125 }
1126 
bt_mesh_cfg_net_key_add(u16_t net_idx,u16_t addr,u16_t key_net_idx,const u8_t net_key[16],u8_t * status)1127 int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, const u8_t net_key[16], u8_t *status)
1128 {
1129     NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4);
1130     struct bt_mesh_msg_ctx ctx = {
1131         .net_idx = net_idx,
1132         .app_idx = BT_MESH_KEY_DEV,
1133         .addr = addr,
1134         .send_ttl = BT_MESH_TTL_DEFAULT,
1135     };
1136     struct net_key_param param = {
1137         .status = status,
1138         .net_idx = key_net_idx,
1139     };
1140     int err;
1141 
1142     err = cli_prepare(&param, OP_NET_KEY_STATUS);
1143     if (err) {
1144         return err;
1145     }
1146 
1147     bt_mesh_model_msg_init(&msg, OP_NET_KEY_ADD);
1148     net_buf_simple_add_le16(&msg, key_net_idx);
1149     net_buf_simple_add_mem(&msg, net_key, 16);
1150 
1151     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1152     if (err) {
1153         BT_ERR("model_send() failed (err %d)", err);
1154         cli_reset();
1155         return err;
1156     }
1157     if (!status) {
1158         cli_reset();
1159         return 0;
1160     }
1161 
1162     return cli_wait();
1163 }
1164 
bt_mesh_cfg_net_key_update(u16_t net_idx,u16_t addr,u16_t key_net_idx,const u8_t net_key[16],u8_t * status)1165 int bt_mesh_cfg_net_key_update(u16_t net_idx, u16_t addr, u16_t key_net_idx, const u8_t net_key[16], u8_t *status)
1166 {
1167     NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4);
1168     struct bt_mesh_msg_ctx ctx = {
1169         .net_idx = net_idx,
1170         .app_idx = BT_MESH_KEY_DEV,
1171         .addr = addr,
1172         .send_ttl = BT_MESH_TTL_DEFAULT,
1173     };
1174     struct net_key_param param = {
1175         .status = status,
1176         .net_idx = key_net_idx,
1177     };
1178     int err;
1179 
1180     err = cli_prepare(&param, OP_NET_KEY_STATUS);
1181     if (err) {
1182         return err;
1183     }
1184 
1185     bt_mesh_model_msg_init(&msg, OP_NET_KEY_UPDATE);
1186     net_buf_simple_add_le16(&msg, key_net_idx);
1187     net_buf_simple_add_mem(&msg, net_key, 16);
1188 
1189     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1190     if (err) {
1191         BT_ERR("model_send() failed (err %d)", err);
1192         cli_reset();
1193         return err;
1194     }
1195 
1196     if (!status) {
1197         cli_reset();
1198         return 0;
1199     }
1200 
1201     return cli_wait();
1202 }
1203 
bt_mesh_cfg_krp_set(u16_t net_idx,u16_t addr,u16_t key_net_idx,u8_t * phase,u8_t * status)1204 int bt_mesh_cfg_krp_set(u16_t net_idx, u16_t addr, u16_t key_net_idx, u8_t *phase, u8_t *status)
1205 {
1206     NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
1207     struct bt_mesh_msg_ctx ctx = {
1208         .net_idx = net_idx,
1209         .app_idx = BT_MESH_KEY_DEV,
1210         .addr = addr,
1211         .send_ttl = BT_MESH_TTL_DEFAULT,
1212     };
1213     struct krp_param param = {
1214         .status = status,
1215         .net_idx = key_net_idx,
1216         .phase = phase,
1217     };
1218     int err;
1219 
1220     err = cli_prepare(&param, OP_KRP_STATUS);
1221     if (err) {
1222         return err;
1223     }
1224 
1225     bt_mesh_model_msg_init(&msg, OP_KRP_SET);
1226     net_buf_simple_add_le16(&msg, key_net_idx);
1227     net_buf_simple_add_u8(&msg, *phase);
1228 
1229     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1230     if (err) {
1231         BT_ERR("model_send() failed (err %d)", err);
1232         cli_reset();
1233         return err;
1234     }
1235 
1236     if (!status) {
1237         cli_reset();
1238         return 0;
1239     }
1240 
1241     return cli_wait();
1242 }
1243 
bt_mesh_cfg_krp_get(u16_t net_idx,u16_t addr,u16_t key_net_idx,u8_t * phase,u8_t * status)1244 int bt_mesh_cfg_krp_get(u16_t net_idx, u16_t addr, u16_t key_net_idx, u8_t *phase, u8_t *status)
1245 {
1246     NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
1247     struct bt_mesh_msg_ctx ctx = {
1248         .net_idx = net_idx,
1249         .app_idx = BT_MESH_KEY_DEV,
1250         .addr = addr,
1251         .send_ttl = BT_MESH_TTL_DEFAULT,
1252     };
1253     struct krp_param param = {
1254         .status = status,
1255         .net_idx = key_net_idx,
1256         .phase = phase,
1257     };
1258     int err;
1259     err = cli_prepare(&param, OP_KRP_STATUS);
1260     if (err) {
1261         return err;
1262     }
1263 
1264     bt_mesh_model_msg_init(&msg, OP_KRP_GET);
1265     net_buf_simple_add_le16(&msg, key_net_idx);
1266 
1267     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1268     if (err) {
1269         BT_ERR("model_send() failed (err %d)", err);
1270         cli_reset();
1271         return err;
1272     }
1273 
1274     if (!status) {
1275         cli_reset();
1276         return 0;
1277     }
1278 
1279     return cli_wait();
1280 }
1281 
bt_mesh_cfg_app_key_add(u16_t net_idx,u16_t addr,u16_t key_net_idx,u16_t key_app_idx,const u8_t app_key[16],u8_t * status)1282 int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16],
1283                             u8_t *status)
1284 {
1285     NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4);
1286     struct bt_mesh_msg_ctx ctx = {
1287         .net_idx = net_idx,
1288         .app_idx = BT_MESH_KEY_DEV,
1289         .addr = addr,
1290         .send_ttl = BT_MESH_TTL_DEFAULT,
1291     };
1292 
1293     struct app_key_param param = {
1294         .status = status,
1295         .net_idx = key_net_idx,
1296         .app_idx = key_app_idx,
1297     };
1298 
1299     int err;
1300 
1301     err = cli_prepare(&param, OP_APP_KEY_STATUS);
1302     if (err) {
1303         return err;
1304     }
1305 
1306     bt_mesh_model_msg_init(&msg, OP_APP_KEY_ADD);
1307     key_idx_pack(&msg, key_net_idx, key_app_idx);
1308     net_buf_simple_add_mem(&msg, app_key, 16);
1309 
1310     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1311     if (err) {
1312         BT_ERR("model_send() failed (err %d)", err);
1313         cli_reset();
1314         return err;
1315     }
1316     if (!status) {
1317         cli_reset();
1318         return 0;
1319     }
1320     return cli_wait();
1321 }
1322 
bt_mesh_cfg_app_key_update(u16_t net_idx,u16_t addr,u16_t key_net_idx,u16_t key_app_idx,const u8_t app_key[16],u8_t * status)1323 int bt_mesh_cfg_app_key_update(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16],
1324                                u8_t *status)
1325 {
1326     NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4);
1327     struct bt_mesh_msg_ctx ctx = {
1328         .net_idx = net_idx,
1329         .app_idx = BT_MESH_KEY_DEV,
1330         .addr = addr,
1331         .send_ttl = BT_MESH_TTL_DEFAULT,
1332     };
1333     struct app_key_param param = {
1334         .status = status,
1335         .net_idx = key_net_idx,
1336         .app_idx = key_app_idx,
1337     };
1338     int err;
1339 
1340     err = cli_prepare(&param, OP_APP_KEY_STATUS);
1341     if (err) {
1342         return err;
1343     }
1344 
1345     bt_mesh_model_msg_init(&msg, OP_APP_KEY_UPDATE);
1346     key_idx_pack(&msg, key_net_idx, key_app_idx);
1347     net_buf_simple_add_mem(&msg, app_key, 16);
1348 
1349     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1350     if (err) {
1351         BT_ERR("model_send() failed (err %d)", err);
1352         cli_reset();
1353         return err;
1354     }
1355 
1356     if (!status) {
1357         cli_reset();
1358         return 0;
1359     }
1360 
1361     return cli_wait();
1362 }
1363 
mod_app_bind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)1364 static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid,
1365                         u8_t *status)
1366 {
1367     NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
1368     struct bt_mesh_msg_ctx ctx = {
1369         .net_idx = net_idx,
1370         .app_idx = BT_MESH_KEY_DEV,
1371         .addr = addr,
1372         .send_ttl = BT_MESH_TTL_DEFAULT,
1373     };
1374 
1375     struct mod_app_param param = {
1376         .status = status,
1377         .elem_addr = elem_addr,
1378         .mod_app_idx = mod_app_idx,
1379         .mod_id = mod_id,
1380         .cid = cid,
1381     };
1382 
1383     int err;
1384 
1385     err = cli_prepare(&param, OP_MOD_APP_STATUS);
1386     if (err) {
1387         return err;
1388     }
1389 
1390     bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND);
1391     net_buf_simple_add_le16(&msg, elem_addr);
1392     net_buf_simple_add_le16(&msg, mod_app_idx);
1393 
1394     if (cid != CID_NVAL) {
1395         net_buf_simple_add_le16(&msg, cid);
1396     }
1397 
1398     net_buf_simple_add_le16(&msg, mod_id);
1399 
1400     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1401     if (err) {
1402         BT_ERR("model_send() failed (err %d)", err);
1403         cli_reset();
1404         return err;
1405     }
1406 
1407     if (!status) {
1408         cli_reset();
1409         return 0;
1410     }
1411 
1412     return cli_wait();
1413 }
1414 
mod_app_unbind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)1415 static int mod_app_unbind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid,
1416                           u8_t *status)
1417 {
1418     NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
1419     struct bt_mesh_msg_ctx ctx = {
1420         .net_idx = net_idx,
1421         .app_idx = BT_MESH_KEY_DEV,
1422         .addr = addr,
1423         .send_ttl = BT_MESH_TTL_DEFAULT,
1424     };
1425 
1426     struct mod_app_param param = {
1427         .status = status,
1428         .elem_addr = elem_addr,
1429         .mod_app_idx = mod_app_idx,
1430         .mod_id = mod_id,
1431         .cid = cid,
1432     };
1433 
1434     int err;
1435 
1436     err = cli_prepare(&param, OP_MOD_APP_STATUS);
1437     if (err) {
1438         return err;
1439     }
1440 
1441     bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND);
1442     net_buf_simple_add_le16(&msg, elem_addr);
1443     net_buf_simple_add_le16(&msg, mod_app_idx);
1444 
1445     if (cid != CID_NVAL) {
1446         net_buf_simple_add_le16(&msg, cid);
1447     }
1448 
1449     net_buf_simple_add_le16(&msg, mod_id);
1450 
1451     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1452     if (err) {
1453         BT_ERR("model_send() failed (err %d)", err);
1454         cli_reset();
1455         return err;
1456     }
1457 
1458     if (!status) {
1459         cli_reset();
1460         return 0;
1461     }
1462 
1463     return cli_wait();
1464 }
1465 
bt_mesh_cfg_mod_app_unbind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u8_t * status)1466 int bt_mesh_cfg_mod_app_unbind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id,
1467                                u8_t *status)
1468 {
1469     return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1470 }
1471 
bt_mesh_cfg_mod_app_unbind_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)1472 int bt_mesh_cfg_mod_app_unbind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id,
1473                                    u16_t cid, u8_t *status)
1474 {
1475     if (cid == CID_NVAL) {
1476         return -EINVAL;
1477     }
1478 
1479     return mod_app_unbind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1480 }
1481 
bt_mesh_cfg_mod_app_bind(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u8_t * status)1482 int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u8_t *status)
1483 {
1484     return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, CID_NVAL, status);
1485 }
1486 
bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_app_idx,u16_t mod_id,u16_t cid,u8_t * status)1487 int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid,
1488                                  u8_t *status)
1489 {
1490     if (cid == CID_NVAL) {
1491         return -EINVAL;
1492     }
1493 
1494     return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, status);
1495 }
1496 
mod_sub(bt_u32_t op,u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)1497 static int mod_sub(bt_u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid,
1498                    u8_t *status)
1499 {
1500     NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
1501     struct bt_mesh_msg_ctx ctx = {
1502         .net_idx = net_idx,
1503         .app_idx = BT_MESH_KEY_DEV,
1504         .addr = addr,
1505         .send_ttl = BT_MESH_TTL_DEFAULT,
1506     };
1507     struct mod_sub_param param = {
1508         .status = status,
1509         .elem_addr = elem_addr,
1510         .expect_sub = &sub_addr,
1511         .mod_id = mod_id,
1512         .cid = cid,
1513     };
1514     int err;
1515 
1516     err = cli_prepare(&param, OP_MOD_SUB_STATUS);
1517     if (err) {
1518         return err;
1519     }
1520 
1521     bt_mesh_model_msg_init(&msg, op);
1522     net_buf_simple_add_le16(&msg, elem_addr);
1523     net_buf_simple_add_le16(&msg, sub_addr);
1524 
1525     if (cid != CID_NVAL) {
1526         net_buf_simple_add_le16(&msg, cid);
1527     }
1528 
1529     net_buf_simple_add_le16(&msg, mod_id);
1530 
1531     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1532     if (err) {
1533         BT_ERR("model_send() failed (err %d)", err);
1534         cli_reset();
1535         return err;
1536     }
1537 
1538     if (!status) {
1539         cli_reset();
1540         return 0;
1541     }
1542 
1543     return cli_wait();
1544 }
1545 
bt_mesh_cfg_mod_sub_add(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)1546 int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u8_t *status)
1547 {
1548     return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status);
1549 }
1550 
bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)1551 int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid,
1552                                 u8_t *status)
1553 {
1554     if (cid == CID_NVAL) {
1555         return -EINVAL;
1556     }
1557 
1558     return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1559 }
1560 
bt_mesh_cfg_mod_sub_del(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)1561 int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u8_t *status)
1562 {
1563     return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status);
1564 }
1565 
bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)1566 int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid,
1567                                 u8_t *status)
1568 {
1569     if (cid == CID_NVAL) {
1570         return -EINVAL;
1571     }
1572 
1573     return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1574 }
1575 
bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u8_t * status)1576 int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id,
1577                                   u8_t *status)
1578 {
1579     return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status);
1580 }
1581 
bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t sub_addr,u16_t mod_id,u16_t cid,u8_t * status)1582 int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id,
1583                                       u16_t cid, u8_t *status)
1584 {
1585     if (cid == CID_NVAL) {
1586         return -EINVAL;
1587     }
1588 
1589     return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, cid, status);
1590 }
1591 
mod_sub_va(bt_u32_t op,u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1592 static int mod_sub_va(bt_u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1593                       u16_t cid, u16_t *virt_addr, u8_t *status)
1594 {
1595     NET_BUF_SIMPLE_DEFINE(msg, 2 + 22 + 4);
1596     struct bt_mesh_msg_ctx ctx = {
1597         .net_idx = net_idx,
1598         .app_idx = BT_MESH_KEY_DEV,
1599         .addr = addr,
1600         .send_ttl = BT_MESH_TTL_DEFAULT,
1601     };
1602     struct mod_sub_param param = {
1603         .status = status,
1604         .elem_addr = elem_addr,
1605         .sub_addr = virt_addr,
1606         .mod_id = mod_id,
1607         .cid = cid,
1608     };
1609     int err;
1610 
1611     err = cli_prepare(&param, OP_MOD_SUB_STATUS);
1612     if (err) {
1613         return err;
1614     }
1615 
1616     BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", net_idx, addr, elem_addr, label);
1617     BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
1618 
1619     bt_mesh_model_msg_init(&msg, op);
1620     net_buf_simple_add_le16(&msg, elem_addr);
1621     net_buf_simple_add_mem(&msg, label, 16);
1622 
1623     if (cid != CID_NVAL) {
1624         net_buf_simple_add_le16(&msg, cid);
1625     }
1626 
1627     net_buf_simple_add_le16(&msg, mod_id);
1628 
1629     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1630     if (err) {
1631         BT_ERR("model_send() failed (err %d)", err);
1632         cli_reset();
1633         return err;
1634     }
1635 
1636     if (!status) {
1637         cli_reset();
1638         return 0;
1639     }
1640 
1641     return cli_wait();
1642 }
1643 
bt_mesh_cfg_mod_sub_va_add(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1644 int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1645                                u16_t *virt_addr, u8_t *status)
1646 {
1647     if (virt_addr == NULL) {
1648         return -EINVAL;
1649     }
1650     return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, CID_NVAL, virt_addr, status);
1651 }
1652 
bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1653 int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1654                                    u16_t cid, u16_t *virt_addr, u8_t *status)
1655 {
1656     if (cid == CID_NVAL || virt_addr == NULL) {
1657         return -EINVAL;
1658     }
1659 
1660     return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, mod_id, cid, virt_addr, status);
1661 }
1662 
bt_mesh_cfg_mod_sub_va_del(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1663 int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1664                                u16_t *virt_addr, u8_t *status)
1665 {
1666     if (virt_addr == NULL) {
1667         return -EINVAL;
1668     }
1669     return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, CID_NVAL, virt_addr, status);
1670 }
1671 
bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1672 int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1673                                    u16_t cid, u16_t *virt_addr, u8_t *status)
1674 {
1675     if (cid == CID_NVAL || virt_addr == NULL) {
1676         return -EINVAL;
1677     }
1678 
1679     return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, mod_id, cid, virt_addr, status);
1680 }
1681 
bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t * virt_addr,u8_t * status)1682 int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1683                                      u16_t *virt_addr, u8_t *status)
1684 {
1685     if (virt_addr == NULL) {
1686         return -EINVAL;
1687     }
1688     return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id, CID_NVAL, virt_addr, status);
1689 }
1690 
bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,const u8_t label[16],u16_t mod_id,u16_t cid,u16_t * virt_addr,u8_t * status)1691 int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
1692                                          u16_t cid, u16_t *virt_addr, u8_t *status)
1693 {
1694     if (cid == CID_NVAL || virt_addr == NULL) {
1695         return -EINVAL;
1696     }
1697 
1698     return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, label, mod_id, cid, virt_addr, status);
1699 }
1700 
mod_pub_get(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1701 static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
1702                        struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1703 {
1704     NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
1705     struct bt_mesh_msg_ctx ctx = {
1706         .net_idx = net_idx,
1707         .app_idx = BT_MESH_KEY_DEV,
1708         .addr = addr,
1709         .send_ttl = BT_MESH_TTL_DEFAULT,
1710     };
1711     struct mod_pub_param param = {
1712         .mod_id = mod_id,
1713         .cid = cid,
1714         .elem_addr = elem_addr,
1715         .status = status,
1716         .pub = pub,
1717     };
1718     int err;
1719 
1720     err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1721     if (err) {
1722         return err;
1723     }
1724 
1725     bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET);
1726 
1727     net_buf_simple_add_le16(&msg, elem_addr);
1728 
1729     if (cid != CID_NVAL) {
1730         net_buf_simple_add_le16(&msg, cid);
1731     }
1732 
1733     net_buf_simple_add_le16(&msg, mod_id);
1734 
1735     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1736     if (err) {
1737         BT_ERR("model_send() failed (err %d)", err);
1738         cli_reset();
1739         return err;
1740     }
1741 
1742     if (!status) {
1743         cli_reset();
1744         return 0;
1745     }
1746 
1747     return cli_wait();
1748 }
1749 
bt_mesh_cfg_mod_pub_get(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1750 int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1751                             u8_t *status)
1752 {
1753     if ((pub == NULL && status) || (pub && status == NULL)) {
1754         return -EINVAL;
1755     }
1756     return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1757 }
1758 
bt_mesh_cfg_mod_sub_get(u16_t net_idx,u16_t addr,u16_t mod_id,uint16_t * sub,u8_t * status)1759 int bt_mesh_cfg_mod_sub_get(u16_t net_idx, u16_t addr, u16_t mod_id, uint16_t *sub, u8_t *status)
1760 {
1761     if ((sub == NULL && status) || (sub && status == NULL)) {
1762         return -EINVAL;
1763     }
1764 
1765     NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
1766     struct bt_mesh_msg_ctx ctx = {
1767         .net_idx = net_idx,
1768         .app_idx = BT_MESH_KEY_DEV,
1769         .addr = addr,
1770         .send_ttl = BT_MESH_TTL_DEFAULT,
1771     };
1772 
1773     struct mod_sub_param param = {
1774         .status = status,
1775         .elem_addr = addr,
1776         .sub_addr = sub,
1777     };
1778     int err;
1779 
1780     err = cli_prepare(&param, OP_MOD_SUB_LIST);
1781     if (err) {
1782         return err;
1783     }
1784 
1785     bt_mesh_model_msg_init(&msg, OP_MOD_SUB_GET);
1786     net_buf_simple_add_le16(&msg, addr);
1787     net_buf_simple_add_le16(&msg, mod_id);
1788 
1789     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1790     if (err) {
1791         BT_ERR("model_send() failed (err %d)", err);
1792         cli_reset();
1793         return err;
1794     }
1795 
1796     if (!status) {
1797         cli_reset();
1798         return 0;
1799     }
1800 
1801     return cli_wait();
1802 }
1803 
bt_mesh_cfg_mod_sub_get_vnd(u16_t net_idx,u16_t addr,u16_t mod_id,u16_t cid,uint16_t * sub,u8_t * status)1804 int bt_mesh_cfg_mod_sub_get_vnd(u16_t net_idx, u16_t addr, u16_t mod_id, u16_t cid, uint16_t *sub, u8_t *status)
1805 {
1806     if ((sub == NULL && status) || (sub && status == NULL)) {
1807         return -EINVAL;
1808     }
1809 
1810     NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
1811     struct bt_mesh_msg_ctx ctx = {
1812         .net_idx = net_idx,
1813         .app_idx = BT_MESH_KEY_DEV,
1814         .addr = addr,
1815         .send_ttl = BT_MESH_TTL_DEFAULT,
1816     };
1817 
1818     struct mod_sub_param param = {
1819         .status = status,
1820         .elem_addr = addr,
1821         .sub_addr = sub,
1822     };
1823     int err;
1824 
1825     err = cli_prepare(&param, OP_MOD_SUB_LIST_VND);
1826     if (err) {
1827         return err;
1828     }
1829 
1830     bt_mesh_model_msg_init(&msg, OP_MOD_SUB_GET_VND);
1831     net_buf_simple_add_le16(&msg, addr);
1832     net_buf_simple_add_le16(&msg, cid);
1833     net_buf_simple_add_le16(&msg, mod_id);
1834     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1835     if (err) {
1836         BT_ERR("model_send() failed (err %d)", err);
1837         cli_reset();
1838         return err;
1839     }
1840 
1841     if (!status) {
1842         cli_reset();
1843         return 0;
1844     }
1845 
1846     return cli_wait();
1847 }
1848 
bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1849 int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
1850                                 struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1851 {
1852     if (cid == CID_NVAL || (pub == NULL && status) || (pub && status == NULL)) {
1853         return -EINVAL;
1854     }
1855 
1856     return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1857 }
1858 
mod_pub_set(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1859 static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
1860                        struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1861 {
1862     NET_BUF_SIMPLE_DEFINE(msg, 2 + 13 + 4);
1863     struct bt_mesh_msg_ctx ctx = {
1864         .net_idx = net_idx,
1865         .app_idx = BT_MESH_KEY_DEV,
1866         .addr = addr,
1867         .send_ttl = BT_MESH_TTL_DEFAULT,
1868     };
1869     struct mod_pub_param param = {
1870         .mod_id = mod_id,
1871         .cid = cid,
1872         .elem_addr = elem_addr,
1873         .status = status,
1874         .pub = pub,
1875     };
1876     int err;
1877 
1878     err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1879     if (err) {
1880         return err;
1881     }
1882 
1883     bt_mesh_model_msg_init(&msg, OP_MOD_PUB_SET);
1884 
1885     net_buf_simple_add_le16(&msg, elem_addr);
1886     net_buf_simple_add_le16(&msg, pub->addr);
1887     net_buf_simple_add_le16(&msg, (pub->app_idx & (pub->cred_flag << 12)));
1888     net_buf_simple_add_u8(&msg, pub->ttl);
1889     net_buf_simple_add_u8(&msg, pub->period);
1890     net_buf_simple_add_u8(&msg, pub->transmit);
1891 
1892     if (cid != CID_NVAL) {
1893         net_buf_simple_add_le16(&msg, cid);
1894     }
1895 
1896     net_buf_simple_add_le16(&msg, mod_id);
1897 
1898     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1899     if (err) {
1900         BT_ERR("model_send() failed (err %d)", err);
1901         cli_reset();
1902         return err;
1903     }
1904 
1905     if (!status) {
1906         cli_reset();
1907         return 0;
1908     }
1909 
1910     return cli_wait();
1911 }
1912 
bt_mesh_cfg_mod_pub_set(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1913 int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1914                             u8_t *status)
1915 {
1916     if (pub == NULL) {
1917         return -EINVAL;
1918     }
1919 
1920     return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status);
1921 }
1922 
bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx,u16_t addr,u16_t elem_addr,u16_t mod_id,u16_t cid,struct bt_mesh_cfg_mod_pub * pub,u8_t * status)1923 int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
1924                                 struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1925 {
1926     if (cid == CID_NVAL || pub == NULL) {
1927         return -EINVAL;
1928     }
1929 
1930     return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1931 }
1932 
bt_mesh_cfg_hb_sub_set(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1933 int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1934 {
1935     if (sub == NULL) {
1936         return -EINVAL;
1937     }
1938 
1939     NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4);
1940     struct bt_mesh_msg_ctx ctx = {
1941         .net_idx = net_idx,
1942         .app_idx = BT_MESH_KEY_DEV,
1943         .addr = addr,
1944         .send_ttl = BT_MESH_TTL_DEFAULT,
1945     };
1946     struct hb_sub_param param = {
1947         .status = status,
1948         .sub = sub,
1949     };
1950     int err;
1951 
1952     err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1953     if (err) {
1954         return err;
1955     }
1956 
1957     bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_SET);
1958     net_buf_simple_add_le16(&msg, sub->src);
1959     net_buf_simple_add_le16(&msg, sub->dst);
1960     net_buf_simple_add_u8(&msg, sub->period);
1961 
1962     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
1963     if (err) {
1964         BT_ERR("model_send() failed (err %d)", err);
1965         cli_reset();
1966         return err;
1967     }
1968     if (!status) {
1969         cli_reset();
1970         return 0;
1971     }
1972     return cli_wait();
1973 }
1974 
bt_mesh_cfg_hb_sub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1975 int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1976 {
1977     if (sub == NULL) {
1978         return -EINVAL;
1979     }
1980 
1981     NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
1982     struct bt_mesh_msg_ctx ctx = {
1983         .net_idx = net_idx,
1984         .app_idx = BT_MESH_KEY_DEV,
1985         .addr = addr,
1986         .send_ttl = BT_MESH_TTL_DEFAULT,
1987     };
1988     struct hb_sub_param param = {
1989         .status = status,
1990         .sub = sub,
1991     };
1992     int err;
1993 
1994     err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1995     if (err) {
1996         return err;
1997     }
1998 
1999     bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_GET);
2000 
2001     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
2002     if (err) {
2003         BT_ERR("model_send() failed (err %d)", err);
2004         cli_reset();
2005         return err;
2006     }
2007     if (!status) {
2008         cli_reset();
2009         return 0;
2010     }
2011     return cli_wait();
2012 }
2013 
bt_mesh_cfg_hb_pub_set(u16_t net_idx,u16_t addr,const struct bt_mesh_cfg_hb_pub * pub,u8_t * status)2014 int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr, const struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
2015 {
2016     if (pub == NULL) {
2017         return -EINVAL;
2018     }
2019 
2020     NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
2021     struct bt_mesh_msg_ctx ctx = {
2022         .net_idx = net_idx,
2023         .app_idx = BT_MESH_KEY_DEV,
2024         .addr = addr,
2025         .send_ttl = BT_MESH_TTL_DEFAULT,
2026     };
2027     struct hb_pub_param param = {
2028         .status = status,
2029     };
2030     int err;
2031 
2032     err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
2033     if (err) {
2034         return err;
2035     }
2036 
2037     bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_SET);
2038     net_buf_simple_add_le16(&msg, pub->dst);
2039     net_buf_simple_add_u8(&msg, pub->count);
2040     net_buf_simple_add_u8(&msg, pub->period);
2041     net_buf_simple_add_u8(&msg, pub->ttl);
2042     net_buf_simple_add_le16(&msg, pub->feat);
2043     net_buf_simple_add_le16(&msg, pub->net_idx);
2044 
2045     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
2046     if (err) {
2047         BT_ERR("model_send() failed (err %d)", err);
2048         cli_reset();
2049         return err;
2050     }
2051     if (!status) {
2052         cli_reset();
2053         return 0;
2054     }
2055     return cli_wait();
2056 }
2057 
bt_mesh_cfg_hb_pub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_pub * pub,u8_t * status)2058 int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
2059 {
2060     if (pub == NULL) {
2061         return -EINVAL;
2062     }
2063 
2064     NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
2065     struct bt_mesh_msg_ctx ctx = {
2066         .net_idx = net_idx,
2067         .app_idx = BT_MESH_KEY_DEV,
2068         .addr = addr,
2069         .send_ttl = BT_MESH_TTL_DEFAULT,
2070     };
2071     struct hb_pub_param param = {
2072         .status = status,
2073         .pub = pub,
2074     };
2075     int err;
2076 
2077     err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
2078     if (err) {
2079         return err;
2080     }
2081 
2082     bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_GET);
2083 
2084     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
2085     if (err) {
2086         BT_ERR("model_send() failed (err %d)", err);
2087         cli_reset();
2088         return err;
2089     }
2090     if (!status) {
2091         cli_reset();
2092         return 0;
2093     }
2094     return cli_wait();
2095 }
2096 
2097 /*[Genie begin] add by wenbing.cwb at 2021-01-21*/
2098 #ifdef CONFIG_BT_MESH_CTRL_RELAY
bt_mesh_cfg_ctrl_relay_get(u16_t net_idx,u16_t addr,struct ctrl_relay_param * cr,u8_t * status)2099 int bt_mesh_cfg_ctrl_relay_get(u16_t net_idx, u16_t addr, struct ctrl_relay_param *cr, u8_t *status)
2100 {
2101     struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 0 + 4);
2102     struct bt_mesh_msg_ctx ctx = {
2103         .net_idx = net_idx,
2104         .app_idx = BT_MESH_KEY_DEV,
2105         .addr = addr,
2106         .send_ttl = BT_MESH_TTL_DEFAULT,
2107     };
2108     struct cli_cr_param param = {
2109         .status = status,
2110         .cr_p = cr,
2111     };
2112     int err;
2113 
2114     err = cli_prepare(&param, OP_CTRL_RELAY_CONF_STATUS);
2115     if (err) {
2116         return err;
2117     }
2118 
2119     bt_mesh_model_msg_init(msg, OP_CTRL_RELAY_CONF_GET);
2120 
2121     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
2122     if (err) {
2123         BT_ERR("model_send() failed (err %d)", err);
2124         cli_reset();
2125         return err;
2126     }
2127 
2128     if (!status) {
2129         cli_reset();
2130         return 0;
2131     }
2132 
2133     return cli_wait();
2134 }
2135 
bt_mesh_cfg_ctrl_relay_set(u16_t net_idx,u16_t addr,const struct ctrl_relay_param * cr,u8_t * status)2136 int bt_mesh_cfg_ctrl_relay_set(u16_t net_idx, u16_t addr, const struct ctrl_relay_param *cr, u8_t *status)
2137 {
2138     struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 6 + 4);
2139     struct bt_mesh_msg_ctx ctx = {
2140         .net_idx = net_idx,
2141         .app_idx = BT_MESH_KEY_DEV,
2142         .addr = addr,
2143         .send_ttl = BT_MESH_TTL_DEFAULT,
2144     };
2145     struct cli_cr_param param = {
2146         .status = status,
2147     };
2148     int err;
2149 
2150     err = cli_prepare(&param, OP_CTRL_RELAY_CONF_STATUS);
2151     if (err) {
2152         return err;
2153     }
2154 
2155     bt_mesh_model_msg_init(msg, OP_CTRL_RELAY_CONF_SET);
2156     net_buf_simple_add_u8(msg, cr->enable);
2157     net_buf_simple_add_u8(msg, cr->trd_n);
2158     net_buf_simple_add_u8(msg, cr->rssi);
2159     net_buf_simple_add_u8(msg, cr->sta_period);
2160     net_buf_simple_add_u8(msg, cr->chk_period);
2161     net_buf_simple_add_u8(msg, cr->req_period);
2162 
2163     err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
2164     if (err) {
2165         BT_ERR("model_send() failed (err %d)", err);
2166         cli_reset();
2167         return err;
2168     }
2169 
2170     if (!status) {
2171         cli_reset();
2172         return 0;
2173     }
2174 
2175     return cli_wait();
2176 }
2177 #endif
2178 /*[Genie end] add by wenbing.cwb at 2021-01-21*/
2179 
bt_mesh_cfg_node_reset(u16_t net_idx,u16_t addr)2180 int bt_mesh_cfg_node_reset(u16_t net_idx, u16_t addr)
2181 {
2182     NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
2183     struct bt_mesh_msg_ctx ctx = {
2184         .net_idx = net_idx,
2185         .app_idx = BT_MESH_KEY_DEV,
2186         .addr = addr,
2187         .send_ttl = BT_MESH_TTL_DEFAULT,
2188     };
2189     int err;
2190 
2191     err = cli_prepare(NULL, OP_NODE_RESET_STATUS);
2192     if (err) {
2193         return err;
2194     }
2195 
2196     bt_mesh_model_msg_init(&msg, OP_NODE_RESET);
2197     err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
2198     if (err) {
2199         BT_ERR("model_send() failed (err %d)", err);
2200         cli_reset();
2201         return err;
2202     }
2203 
2204     return cli_wait();
2205 }
2206 
bt_mesh_cfg_cli_timeout_get(void)2207 bt_s32_t bt_mesh_cfg_cli_timeout_get(void)
2208 {
2209     return msg_timeout / MSEC_PER_SEC;
2210 }
2211 
bt_mesh_cfg_cli_timeout_set(bt_s32_t timeout)2212 void bt_mesh_cfg_cli_timeout_set(bt_s32_t timeout)
2213 {
2214     msg_timeout = K_SECONDS(timeout);
2215 }
2216 
bt_mesh_cfg_cli_init(struct bt_mesh_model * model,bool primary)2217 int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary)
2218 {
2219     BT_DBG("primary %u", primary);
2220 
2221     if (!primary) {
2222         BT_ERR("Configuration Client only allowed in primary element");
2223         return -EINVAL;
2224     }
2225 
2226     if (!model || !model->user_data) {
2227         BT_ERR("No Configuration Client context provided");
2228         return -EINVAL;
2229     }
2230 
2231     cli = model->user_data;
2232     cli->model = model;
2233 
2234     /* Configuration Model security is device-key based */
2235     model->keys[0] = BT_MESH_KEY_DEV;
2236     k_sem_init(&cli->op_sync, 0, 1);
2237 
2238     return 0;
2239 }
2240 
2241 #endif
2242