xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/mesh/src/cfg_cli.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 #if MYNEWT_VAL(BLE_MESH_CFG_CLI)
11 
12 #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL))
13 #include "mesh/mesh.h"
14 
15 #include <string.h>
16 #include <errno.h>
17 #include <stdbool.h>
18 
19 #include "net.h"
20 #include "foundation.h"
21 
22 #define CID_NVAL 0xffff
23 
24 struct comp_data {
25 	u8_t *status;
26 	struct os_mbuf *comp;
27 };
28 
29 static s32_t msg_timeout = K_SECONDS(5);
30 
31 static struct bt_mesh_cfg_cli *cli;
32 
comp_data_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)33 static void comp_data_status(struct bt_mesh_model *model,
34 			     struct bt_mesh_msg_ctx *ctx,
35 			     struct os_mbuf *buf)
36 {
37 	struct comp_data *param;
38 	size_t to_copy;
39 
40 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
41 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
42 	       bt_hex(buf->om_data, buf->om_len));
43 
44 	if (cli->op_pending != OP_DEV_COMP_DATA_STATUS) {
45 		BT_WARN("Unexpected Composition Data Status");
46 		return;
47 	}
48 
49 	param = cli->op_param;
50 
51 	*(param->status) = net_buf_simple_pull_u8(buf);
52 	to_copy  = min(net_buf_simple_tailroom(param->comp), buf->om_len);
53 	net_buf_simple_add_mem(param->comp, buf->om_data, to_copy);
54 
55 	k_sem_give(&cli->op_sync);
56 }
57 
state_status_u8(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf,u32_t expect_status)58 static void state_status_u8(struct bt_mesh_model *model,
59 			    struct bt_mesh_msg_ctx *ctx,
60 			    struct os_mbuf*buf,
61 			    u32_t expect_status)
62 {
63 	u8_t *status;
64 
65 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
66 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
67 	       bt_hex(buf->om_data, buf->om_len));
68 
69 	if (cli->op_pending != expect_status) {
70 		BT_WARN("Unexpected Status (0x%08x != 0x%08x)",
71 			cli->op_pending, expect_status);
72 		return;
73 	}
74 
75 	status = cli->op_param;
76 	*status = net_buf_simple_pull_u8(buf);
77 
78 	k_sem_give(&cli->op_sync);
79 }
80 
beacon_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)81 static void beacon_status(struct bt_mesh_model *model,
82 			  struct bt_mesh_msg_ctx *ctx,
83 			  struct os_mbuf *buf)
84 {
85 	state_status_u8(model, ctx, buf, OP_BEACON_STATUS);
86 }
87 
ttl_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)88 static void ttl_status(struct bt_mesh_model *model,
89 			  struct bt_mesh_msg_ctx *ctx,
90 			  struct os_mbuf*buf)
91 {
92 	state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS);
93 }
94 
friend_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)95 static void friend_status(struct bt_mesh_model *model,
96 			  struct bt_mesh_msg_ctx *ctx,
97 			  struct os_mbuf*buf)
98 {
99 	state_status_u8(model, ctx, buf, OP_FRIEND_STATUS);
100 }
101 
gatt_proxy_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)102 static void gatt_proxy_status(struct bt_mesh_model *model,
103 			      struct bt_mesh_msg_ctx *ctx,
104 			      struct os_mbuf*buf)
105 {
106 	state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS);
107 }
108 
109 struct relay_param {
110 	u8_t *status;
111 	u8_t *transmit;
112 };
113 
relay_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)114 static void relay_status(struct bt_mesh_model *model,
115 			 struct bt_mesh_msg_ctx *ctx,
116 			 struct os_mbuf*buf)
117 {
118 	struct relay_param *param;
119 
120 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
121 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
122 	       bt_hex(buf->om_data, buf->om_len));
123 
124 	if (cli->op_pending != OP_RELAY_STATUS) {
125 		BT_WARN("Unexpected Relay Status message");
126 		return;
127 	}
128 
129 	param = cli->op_param;
130 	*param->status = net_buf_simple_pull_u8(buf);
131 	*param->transmit = net_buf_simple_pull_u8(buf);
132 
133 	k_sem_give(&cli->op_sync);
134 }
135 
136 struct net_key_param {
137 	u8_t *status;
138 	u16_t net_idx;
139 };
140 
net_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)141 static void net_key_status(struct bt_mesh_model *model,
142 			   struct bt_mesh_msg_ctx *ctx,
143 			   struct os_mbuf *buf)
144 {
145 	struct net_key_param *param;
146 	u16_t net_idx, app_idx;
147 	u8_t status;
148 
149 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
150 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
151 	       bt_hex(buf->om_data, buf->om_len));
152 
153 	if (cli->op_pending != OP_NET_KEY_STATUS) {
154 		BT_WARN("Unexpected Net Key Status message");
155 		return;
156 	}
157 
158 	status = net_buf_simple_pull_u8(buf);
159 	key_idx_unpack(buf, &net_idx, &app_idx);
160 
161 	param = cli->op_param;
162 	if (param->net_idx != net_idx) {
163 		BT_WARN("Net Key Status key index does not match");
164 		return;
165 	}
166 
167 	if (param->status) {
168 		*param->status = status;
169 	}
170 
171 	k_sem_give(&cli->op_sync);
172 }
173 
174 struct app_key_param {
175 	u8_t *status;
176 	u16_t net_idx;
177 	u16_t app_idx;
178 };
179 
app_key_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)180 static void app_key_status(struct bt_mesh_model *model,
181 			   struct bt_mesh_msg_ctx *ctx,
182 			   struct os_mbuf*buf)
183 {
184 	struct app_key_param *param;
185 	u16_t net_idx, app_idx;
186 	u8_t status;
187 
188 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
189 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
190 	       bt_hex(buf->om_data, buf->om_len));
191 
192 	if (cli->op_pending != OP_APP_KEY_STATUS) {
193 		BT_WARN("Unexpected App Key Status message");
194 		return;
195 	}
196 
197 	status = net_buf_simple_pull_u8(buf);
198 	key_idx_unpack(buf, &net_idx, &app_idx);
199 
200 	param = cli->op_param;
201 	if (param->net_idx != net_idx || param->app_idx != app_idx) {
202 		BT_WARN("App Key Status key indices did not match");
203 		return;
204 	}
205 
206 	if (param->status) {
207 		*param->status = status;
208 	}
209 
210 	k_sem_give(&cli->op_sync);
211 }
212 
213 struct mod_app_param {
214 	u8_t *status;
215 	u16_t elem_addr;
216 	u16_t mod_app_idx;
217 	u16_t mod_id;
218 	u16_t cid;
219 };
220 
mod_app_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)221 static void mod_app_status(struct bt_mesh_model *model,
222 			   struct bt_mesh_msg_ctx *ctx,
223 			   struct os_mbuf*buf)
224 {
225 	u16_t elem_addr, mod_app_idx, mod_id, cid;
226 	struct mod_app_param *param;
227 	u8_t status;
228 
229 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
230 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
231 	       bt_hex(buf->om_data, buf->om_len));
232 
233 	if (cli->op_pending != OP_MOD_APP_STATUS) {
234 		BT_WARN("Unexpected Model App Status message");
235 		return;
236 	}
237 
238 	status = net_buf_simple_pull_u8(buf);
239 	elem_addr = net_buf_simple_pull_le16(buf);
240 	mod_app_idx = net_buf_simple_pull_le16(buf);
241 
242 	if (buf->om_len >= 4) {
243 		cid = net_buf_simple_pull_le16(buf);
244 	} else {
245 		cid = CID_NVAL;
246 	}
247 
248 	mod_id = net_buf_simple_pull_le16(buf);
249 
250 	param = cli->op_param;
251 	if (param->elem_addr != elem_addr ||
252 	    param->mod_app_idx != mod_app_idx || param->mod_id != mod_id ||
253 	    param->cid != cid) {
254 		BT_WARN("Model App Status parameters did not match");
255 		return;
256 	}
257 
258 	if (param->status) {
259 		*param->status = status;
260 	}
261 
262 	k_sem_give(&cli->op_sync);
263 }
264 
265 struct mod_pub_param {
266 	u16_t                       mod_id;
267 	u16_t                       cid;
268 	u16_t                       elem_addr;
269 	u8_t                       *status;
270 	struct bt_mesh_cfg_mod_pub *pub;
271 };
272 
mod_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)273 static void mod_pub_status(struct bt_mesh_model *model,
274 			   struct bt_mesh_msg_ctx *ctx,
275 			   struct os_mbuf*buf)
276 {
277 	u16_t mod_id, cid, elem_addr;
278 	struct mod_pub_param *param;
279 	u8_t status;
280 
281 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
282 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
283 	       bt_hex(buf->om_data, buf->om_len));
284 
285 	if (cli->op_pending != OP_MOD_PUB_STATUS) {
286 		BT_WARN("Unexpected Model Pub Status message");
287 		return;
288 	}
289 
290 	param = cli->op_param;
291 	if (param->cid != CID_NVAL) {
292 		if (buf->om_len < 14) {
293 			BT_WARN("Unexpected Mod Pub Status with SIG Model");
294 			return;
295 		}
296 
297 		cid = sys_get_le16(&buf->om_data[10]);
298 		mod_id = sys_get_le16(&buf->om_data[12]);
299 	} else {
300 		if (buf->om_len > 12) {
301 			BT_WARN("Unexpected Mod Pub Status with Vendor Model");
302 			return;
303 		}
304 
305 		cid = CID_NVAL;
306 		mod_id = sys_get_le16(&buf->om_data[10]);
307 	}
308 
309 	if (mod_id != param->mod_id || cid != param->cid) {
310 		BT_WARN("Mod Pub Model ID or Company ID mismatch");
311 		return;
312 	}
313 
314 	status = net_buf_simple_pull_u8(buf);
315 
316 	elem_addr = net_buf_simple_pull_le16(buf);
317 	if (elem_addr != param->elem_addr) {
318 		BT_WARN("Model Pub Status for unexpected element (0x%04x)",
319 			elem_addr);
320 		return;
321 	}
322 
323 	if (param->status) {
324 		*param->status = status;
325 	}
326 
327 	if (param->pub) {
328 		param->pub->addr = net_buf_simple_pull_le16(buf);
329 		param->pub->app_idx = net_buf_simple_pull_le16(buf);
330 		param->pub->cred_flag = (param->pub->app_idx & BIT(12));
331 		param->pub->app_idx &= BIT_MASK(12);
332 		param->pub->ttl = net_buf_simple_pull_u8(buf);
333 		param->pub->period = net_buf_simple_pull_u8(buf);
334 		param->pub->transmit = net_buf_simple_pull_u8(buf);
335 	}
336 
337 	k_sem_give(&cli->op_sync);
338 }
339 
340 struct mod_sub_param {
341 	u8_t *status;
342 	u16_t elem_addr;
343 	u16_t *sub_addr;
344 	u16_t *expect_sub;
345 	u16_t mod_id;
346 	u16_t cid;
347 };
348 
mod_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)349 static void mod_sub_status(struct bt_mesh_model *model,
350 			   struct bt_mesh_msg_ctx *ctx,
351 			   struct os_mbuf*buf)
352 {
353 	u16_t elem_addr, sub_addr, mod_id, cid;
354 	struct mod_sub_param *param;
355 	u8_t status;
356 
357 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
358 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
359 	       bt_hex(buf->om_data, buf->om_len));
360 
361 	if (cli->op_pending != OP_MOD_SUB_STATUS) {
362 		BT_WARN("Unexpected Model Subscription Status message");
363 		return;
364 	}
365 
366 	status = net_buf_simple_pull_u8(buf);
367 	elem_addr = net_buf_simple_pull_le16(buf);
368 	sub_addr = net_buf_simple_pull_le16(buf);
369 
370 	if (buf->om_len >= 4) {
371 		cid = net_buf_simple_pull_le16(buf);
372 	} else {
373 		cid = CID_NVAL;
374 	}
375 
376 	mod_id = net_buf_simple_pull_le16(buf);
377 
378 	param = cli->op_param;
379 	if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
380 	    (param->expect_sub && *param->expect_sub != sub_addr) ||
381 	    param->cid != cid) {
382 		BT_WARN("Model Subscription Status parameters did not match");
383 		return;
384 	}
385 
386 	if (param->sub_addr) {
387 		*param->sub_addr = sub_addr;
388 	}
389 
390 	if (param->status) {
391 		*param->status = status;
392 	}
393 
394 	k_sem_give(&cli->op_sync);
395 }
396 
397 struct hb_sub_param {
398 	u8_t *status;
399 	struct bt_mesh_cfg_hb_sub *sub;
400 };
401 
hb_sub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)402 static void hb_sub_status(struct bt_mesh_model *model,
403 			  struct bt_mesh_msg_ctx *ctx,
404 			  struct os_mbuf*buf)
405 {
406 	struct hb_sub_param *param;
407 
408 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
409 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
410 	       bt_hex(buf->om_data, buf->om_len));
411 
412 	if (cli->op_pending != OP_HEARTBEAT_SUB_STATUS) {
413 		BT_WARN("Unexpected Heartbeat Subscription Status message");
414 		return;
415 	}
416 
417 	param = cli->op_param;
418 
419 	*param->status = net_buf_simple_pull_u8(buf);
420 
421 	param->sub->src = net_buf_simple_pull_le16(buf);
422 	param->sub->dst = net_buf_simple_pull_le16(buf);
423 	param->sub->period = net_buf_simple_pull_u8(buf);
424 	param->sub->count = net_buf_simple_pull_u8(buf);
425 	param->sub->min = net_buf_simple_pull_u8(buf);
426 	param->sub->max = net_buf_simple_pull_u8(buf);
427 
428 	k_sem_give(&cli->op_sync);
429 }
430 
431 struct hb_pub_param {
432 	u8_t *status;
433 	struct bt_mesh_cfg_hb_pub *pub;
434 };
435 
hb_pub_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)436 static void hb_pub_status(struct bt_mesh_model *model,
437 			  struct bt_mesh_msg_ctx *ctx,
438 			  struct os_mbuf *buf)
439 {
440 	struct hb_pub_param *param;
441 
442 	BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
443 	       ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len,
444 	       bt_hex(buf->om_data, buf->om_len));
445 
446 	if (cli->op_pending != OP_HEARTBEAT_PUB_STATUS) {
447 		BT_WARN("Unexpected Heartbeat Publication Status message");
448 		return;
449 	}
450 
451 	param = cli->op_param;
452 
453 	*param->status = net_buf_simple_pull_u8(buf);
454 
455 	if (param->pub) {
456 		param->pub->dst = net_buf_simple_pull_le16(buf);
457 		param->pub->count = net_buf_simple_pull_u8(buf);
458 		param->pub->period = net_buf_simple_pull_u8(buf);
459 		param->pub->ttl = net_buf_simple_pull_u8(buf);
460 		param->pub->feat = net_buf_simple_pull_u8(buf);
461 		param->pub->net_idx = net_buf_simple_pull_u8(buf);
462 	}
463 
464 	k_sem_give(&cli->op_sync);
465 }
466 
467 const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
468 	{ OP_DEV_COMP_DATA_STATUS,   15,  comp_data_status },
469 	{ OP_BEACON_STATUS,          1,   beacon_status },
470 	{ OP_DEFAULT_TTL_STATUS,     1,   ttl_status },
471 	{ OP_FRIEND_STATUS,          1,   friend_status },
472 	{ OP_GATT_PROXY_STATUS,      1,   gatt_proxy_status },
473 	{ OP_RELAY_STATUS,           2,   relay_status },
474 	{ OP_NET_KEY_STATUS,         3,   net_key_status },
475 	{ OP_APP_KEY_STATUS,         4,   app_key_status },
476 	{ OP_MOD_APP_STATUS,         7,   mod_app_status },
477 	{ OP_MOD_PUB_STATUS,         12,  mod_pub_status },
478 	{ OP_MOD_SUB_STATUS,         7,   mod_sub_status },
479 	{ OP_HEARTBEAT_SUB_STATUS,   9,   hb_sub_status },
480 	{ OP_HEARTBEAT_PUB_STATUS,   10,  hb_pub_status },
481 	BT_MESH_MODEL_OP_END,
482 };
483 
cli_prepare(void * param,u32_t op)484 static int cli_prepare(void *param, u32_t op)
485 {
486 	if (!cli) {
487 		BT_ERR("No available Configuration Client context!");
488 		return -EINVAL;
489 	}
490 
491 	if (cli->op_pending) {
492 		BT_WARN("Another synchronous operation pending");
493 		return -EBUSY;
494 	}
495 
496 	cli->op_param = param;
497 	cli->op_pending = op;
498 
499 	return 0;
500 }
501 
cli_reset(void)502 static void cli_reset(void)
503 {
504 	cli->op_pending = 0;
505 	cli->op_param = NULL;
506 }
507 
cli_wait(void)508 static int cli_wait(void)
509 {
510 	int err;
511 
512 	err = k_sem_take(&cli->op_sync, msg_timeout);
513 
514 	cli_reset();
515 
516 	return err;
517 }
518 
bt_mesh_cfg_comp_data_get(u16_t net_idx,u16_t addr,u8_t page,u8_t * status,struct os_mbuf * comp)519 int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page,
520 			      u8_t *status, struct os_mbuf *comp)
521 {
522 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4);
523 	struct bt_mesh_msg_ctx ctx = {
524 		.net_idx = net_idx,
525 		.app_idx = BT_MESH_KEY_DEV,
526 		.addr = addr,
527 		.send_ttl = BT_MESH_TTL_DEFAULT,
528 	};
529 	struct comp_data param = {
530 		.status = status,
531 		.comp = comp,
532 	};
533 	int err;
534 
535 	err = cli_prepare(&param, OP_DEV_COMP_DATA_STATUS);
536 	if (err) {
537 		goto done;
538 	}
539 
540 	bt_mesh_model_msg_init(msg, OP_DEV_COMP_DATA_GET);
541 	net_buf_simple_add_u8(msg, page);
542 
543 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
544 	if (err) {
545 		BT_ERR("model_send() failed (err %d)", err);
546 		cli_reset();
547 		goto done;
548 	}
549 
550 	err = cli_wait();
551 done:
552 	os_mbuf_free_chain(msg);
553 	return err;
554 }
555 
get_state_u8(u16_t net_idx,u16_t addr,u32_t op,u32_t rsp,u8_t * val)556 static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
557 			u8_t *val)
558 {
559 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4);
560 	struct bt_mesh_msg_ctx ctx = {
561 		.net_idx = net_idx,
562 		.app_idx = BT_MESH_KEY_DEV,
563 		.addr = addr,
564 		.send_ttl = BT_MESH_TTL_DEFAULT,
565 	};
566 	int err;
567 
568 	err = cli_prepare(val, rsp);
569 	if (err) {
570 		goto done;
571 	}
572 
573 	bt_mesh_model_msg_init(msg, op);
574 
575 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
576 	if (err) {
577 		BT_ERR("model_send() failed (err %d)", err);
578 		cli_reset();
579 		goto done;
580 	}
581 
582 	err = cli_wait();
583 done:
584 	os_mbuf_free_chain(msg);
585 	return err;
586 }
587 
set_state_u8(u16_t net_idx,u16_t addr,u32_t op,u32_t rsp,u8_t new_val,u8_t * val)588 static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
589 			u8_t new_val, u8_t *val)
590 {
591 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4);
592 	struct bt_mesh_msg_ctx ctx = {
593 		.net_idx = net_idx,
594 		.app_idx = BT_MESH_KEY_DEV,
595 		.addr = addr,
596 		.send_ttl = BT_MESH_TTL_DEFAULT,
597 	};
598 	int err;
599 
600 	err = cli_prepare(val, rsp);
601 	if (err) {
602 		goto done;
603 	}
604 
605 	bt_mesh_model_msg_init(msg, op);
606 	net_buf_simple_add_u8(msg, new_val);
607 
608 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
609 	if (err) {
610 		BT_ERR("model_send() failed (err %d)", err);
611 		cli_reset();
612 		goto done;
613 	}
614 
615 	err = cli_wait();
616 done:
617 	os_mbuf_free_chain(msg);
618 	return err;
619 }
620 
bt_mesh_cfg_beacon_get(u16_t net_idx,u16_t addr,u8_t * status)621 int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status)
622 {
623 	return get_state_u8(net_idx, addr, OP_BEACON_GET, OP_BEACON_STATUS,
624 			    status);
625 }
626 
bt_mesh_cfg_beacon_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)627 int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
628 {
629 	return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS,
630 			    val, status);
631 }
632 
bt_mesh_cfg_ttl_get(u16_t net_idx,u16_t addr,u8_t * ttl)633 int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl)
634 {
635 	return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET,
636 			    OP_DEFAULT_TTL_STATUS, ttl);
637 }
638 
bt_mesh_cfg_ttl_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * ttl)639 int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl)
640 {
641 	return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET,
642 			    OP_DEFAULT_TTL_STATUS, val, ttl);
643 }
644 
bt_mesh_cfg_friend_get(u16_t net_idx,u16_t addr,u8_t * status)645 int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status)
646 {
647 	return get_state_u8(net_idx, addr, OP_FRIEND_GET,
648 			    OP_FRIEND_STATUS, status);
649 }
650 
bt_mesh_cfg_friend_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)651 int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status)
652 {
653 	return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS,
654 			    val, status);
655 }
656 
bt_mesh_cfg_gatt_proxy_get(u16_t net_idx,u16_t addr,u8_t * status)657 int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status)
658 {
659 	return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET,
660 			    OP_GATT_PROXY_STATUS, status);
661 }
662 
bt_mesh_cfg_gatt_proxy_set(u16_t net_idx,u16_t addr,u8_t val,u8_t * status)663 int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val,
664 			       u8_t *status)
665 {
666 	return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET,
667 			    OP_GATT_PROXY_STATUS, val, status);
668 }
669 
bt_mesh_cfg_relay_get(u16_t net_idx,u16_t addr,u8_t * status,u8_t * transmit)670 int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status,
671 			  u8_t *transmit)
672 {
673 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4);
674 	struct bt_mesh_msg_ctx ctx = {
675 		.net_idx = net_idx,
676 		.app_idx = BT_MESH_KEY_DEV,
677 		.addr = addr,
678 		.send_ttl = BT_MESH_TTL_DEFAULT,
679 	};
680 	struct relay_param param = {
681 		.status = status,
682 		.transmit = transmit,
683 	};
684 	int err;
685 
686 	err = cli_prepare(&param, OP_RELAY_STATUS);
687 	if (err) {
688 		goto done;
689 	}
690 
691 	bt_mesh_model_msg_init(msg, OP_RELAY_GET);
692 
693 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
694 	if (err) {
695 		BT_ERR("model_send() failed (err %d)", err);
696 		cli_reset();
697 		goto done;
698 	}
699 
700 	err = cli_wait();
701 done:
702 	os_mbuf_free_chain(msg);
703 	return err;
704 }
705 
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)706 int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay,
707 			  u8_t new_transmit, u8_t *status, u8_t *transmit)
708 {
709 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4);
710 	struct bt_mesh_msg_ctx ctx = {
711 		.net_idx = net_idx,
712 		.app_idx = BT_MESH_KEY_DEV,
713 		.addr = addr,
714 		.send_ttl = BT_MESH_TTL_DEFAULT,
715 	};
716 	struct relay_param param = {
717 		.status = status,
718 		.transmit = transmit,
719 	};
720 	int err;
721 
722 	err = cli_prepare(&param, OP_RELAY_STATUS);
723 	if (err) {
724 		goto done;
725 	}
726 
727 	bt_mesh_model_msg_init(msg, OP_RELAY_SET);
728 	net_buf_simple_add_u8(msg, new_relay);
729 	net_buf_simple_add_u8(msg, new_transmit);
730 
731 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
732 	if (err) {
733 		BT_ERR("model_send() failed (err %d)", err);
734 		cli_reset();
735 		goto done;
736 	}
737 
738 	err = cli_wait();
739 done:
740 	os_mbuf_free_chain(msg);
741 	return err;
742 }
743 
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)744 int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
745 			    const u8_t net_key[16], u8_t *status)
746 {
747 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 18 + 4);
748 	struct bt_mesh_msg_ctx ctx = {
749 		.net_idx = net_idx,
750 		.app_idx = BT_MESH_KEY_DEV,
751 		.addr = addr,
752 		.send_ttl = BT_MESH_TTL_DEFAULT,
753 	};
754 	struct net_key_param param = {
755 		.status = status,
756 		.net_idx = key_net_idx,
757 	};
758 	int err;
759 
760 	err = cli_prepare(&param, OP_NET_KEY_STATUS);
761 	if (err) {
762 		goto done;
763 	}
764 
765 	bt_mesh_model_msg_init(msg, OP_NET_KEY_ADD);
766 	net_buf_simple_add_le16(msg, key_net_idx);
767 	net_buf_simple_add_mem(msg, net_key, 16);
768 
769 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
770 	if (err) {
771 		BT_ERR("model_send() failed (err %d)", err);
772 		cli_reset();
773 		goto done;
774 	}
775 
776 	if (!status) {
777 		cli_reset();
778 		goto done;
779 	}
780 
781 	err = cli_wait();
782 done:
783 	os_mbuf_free_chain(msg);
784 	return err;
785 }
786 
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)787 int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
788 			    u16_t key_app_idx, const u8_t app_key[16],
789 			    u8_t *status)
790 {
791 	struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 19 + 4);
792 	struct bt_mesh_msg_ctx ctx = {
793 		.net_idx = net_idx,
794 		.app_idx = BT_MESH_KEY_DEV,
795 		.addr = addr,
796 		.send_ttl = BT_MESH_TTL_DEFAULT,
797 	};
798 	struct app_key_param param = {
799 		.status = status,
800 		.net_idx = key_net_idx,
801 		.app_idx = key_app_idx,
802 	};
803 	int err;
804 
805 	err = cli_prepare(&param, OP_APP_KEY_STATUS);
806 	if (err) {
807 		goto done;
808 	}
809 
810 	bt_mesh_model_msg_init(msg, OP_APP_KEY_ADD);
811 	key_idx_pack(msg, key_net_idx, key_app_idx);
812 	net_buf_simple_add_mem(msg, app_key, 16);
813 
814 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
815 	if (err) {
816 		BT_ERR("model_send() failed (err %d)", err);
817 		cli_reset();
818 		goto done;
819 	}
820 
821 	if (!status) {
822 		cli_reset();
823 		goto done;
824 	}
825 
826 	err = cli_wait();
827 done:
828 	os_mbuf_free_chain(msg);
829 	return err;
830 }
831 
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)832 static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
833 			u16_t mod_app_idx, u16_t mod_id, u16_t cid,
834 			u8_t *status)
835 {
836 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4);
837 	struct bt_mesh_msg_ctx ctx = {
838 		.net_idx = net_idx,
839 		.app_idx = BT_MESH_KEY_DEV,
840 		.addr = addr,
841 		.send_ttl = BT_MESH_TTL_DEFAULT,
842 	};
843 	struct mod_app_param param = {
844 		.status = status,
845 		.elem_addr = elem_addr,
846 		.mod_app_idx = mod_app_idx,
847 		.mod_id = mod_id,
848 		.cid = cid,
849 	};
850 	int err;
851 
852 	err = cli_prepare(&param, OP_MOD_APP_STATUS);
853 	if (err) {
854 		goto done;
855 	}
856 
857 	bt_mesh_model_msg_init(msg, OP_MOD_APP_BIND);
858 	net_buf_simple_add_le16(msg, elem_addr);
859 	net_buf_simple_add_le16(msg, mod_app_idx);
860 
861 	if (cid != CID_NVAL) {
862 		net_buf_simple_add_le16(msg, cid);
863 	}
864 
865 	net_buf_simple_add_le16(msg, mod_id);
866 
867 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
868 	if (err) {
869 		BT_ERR("model_send() failed (err %d)", err);
870 		cli_reset();
871 		goto done;
872 	}
873 
874 	if (!status) {
875 		cli_reset();
876 		goto done;
877 	}
878 
879 	err = cli_wait();
880 done:
881 	os_mbuf_free_chain(msg);
882 	return err;
883 }
884 
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)885 int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
886 			     u16_t mod_app_idx, u16_t mod_id, u8_t *status)
887 {
888 	return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id,
889 			    CID_NVAL, status);
890 }
891 
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)892 int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
893 				 u16_t mod_app_idx, u16_t mod_id, u16_t cid,
894 				 u8_t *status)
895 {
896 	if (cid == CID_NVAL) {
897 		return -EINVAL;
898 	}
899 
900 	return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid,
901 			    status);
902 }
903 
mod_sub(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)904 static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
905 		   u16_t sub_addr, u16_t mod_id, u16_t cid, u8_t *status)
906 {
907 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4);
908 	struct bt_mesh_msg_ctx ctx = {
909 		.net_idx = net_idx,
910 		.app_idx = BT_MESH_KEY_DEV,
911 		.addr = addr,
912 		.send_ttl = BT_MESH_TTL_DEFAULT,
913 	};
914 	struct mod_sub_param param = {
915 		.status = status,
916 		.elem_addr = elem_addr,
917 		.expect_sub = &sub_addr,
918 		.mod_id = mod_id,
919 		.cid = cid,
920 	};
921 	int err;
922 
923 	err = cli_prepare(&param, OP_MOD_SUB_STATUS);
924 	if (err) {
925 		goto done;
926 	}
927 
928 	bt_mesh_model_msg_init(msg, op);
929 	net_buf_simple_add_le16(msg, elem_addr);
930 	net_buf_simple_add_le16(msg, sub_addr);
931 
932 	if (cid != CID_NVAL) {
933 		net_buf_simple_add_le16(msg, cid);
934 	}
935 
936 	net_buf_simple_add_le16(msg, mod_id);
937 
938 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
939 	if (err) {
940 		BT_ERR("model_send() failed (err %d)", err);
941 		cli_reset();
942 		goto done;
943 	}
944 
945 	if (!status) {
946 		cli_reset();
947 		goto done;
948 	}
949 
950 	err = cli_wait();
951 done:
952 	os_mbuf_free_chain(msg);
953 	return err;
954 }
955 
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)956 int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
957 			    u16_t sub_addr, u16_t mod_id, u8_t *status)
958 {
959 	return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr,
960 		       mod_id, CID_NVAL, status);
961 }
962 
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)963 int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
964 				 u16_t sub_addr, u16_t mod_id, u16_t cid,
965 				 u8_t *status)
966 {
967 	if (cid == CID_NVAL) {
968 		return -EINVAL;
969 	}
970 
971 	return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr,
972 		       mod_id, cid, status);
973 }
974 
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)975 int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
976 			    u16_t sub_addr, u16_t mod_id, u8_t *status)
977 {
978 	return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr,
979 		       mod_id, CID_NVAL, status);
980 }
981 
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)982 int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
983 				 u16_t sub_addr, u16_t mod_id, u16_t cid,
984 				 u8_t *status)
985 {
986 	if (cid == CID_NVAL) {
987 		return -EINVAL;
988 	}
989 
990 	return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr,
991 		       mod_id, cid, status);
992 }
993 
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)994 int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr,
995 				  u16_t sub_addr, u16_t mod_id, u8_t *status)
996 {
997 	return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr,
998 		       sub_addr, mod_id, CID_NVAL, status);
999 }
1000 
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)1001 int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr,
1002 				      u16_t elem_addr, u16_t sub_addr,
1003 				      u16_t mod_id, u16_t cid, u8_t *status)
1004 {
1005 	if (cid == CID_NVAL) {
1006 		return -EINVAL;
1007 	}
1008 
1009 	return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr,
1010 		       sub_addr, mod_id, cid, status);
1011 }
1012 
mod_sub_va(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)1013 static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
1014 		      const u8_t label[16], u16_t mod_id, u16_t cid,
1015 		      u16_t *virt_addr, u8_t *status)
1016 {
1017 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 22 + 4);
1018 	struct bt_mesh_msg_ctx ctx = {
1019 		.net_idx = net_idx,
1020 		.app_idx = BT_MESH_KEY_DEV,
1021 		.addr = addr,
1022 		.send_ttl = BT_MESH_TTL_DEFAULT,
1023 	};
1024 	struct mod_sub_param param = {
1025 		.status = status,
1026 		.elem_addr = elem_addr,
1027 		.sub_addr = virt_addr,
1028 		.mod_id = mod_id,
1029 		.cid = cid,
1030 	};
1031 	int err;
1032 
1033 	err = cli_prepare(&param, OP_MOD_SUB_STATUS);
1034 	if (err) {
1035 		goto done;
1036 	}
1037 
1038 	BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s",
1039 	       net_idx, addr, elem_addr, label);
1040 	BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);
1041 
1042 	bt_mesh_model_msg_init(msg, op);
1043 	net_buf_simple_add_le16(msg, elem_addr);
1044 	net_buf_simple_add_mem(msg, label, 16);
1045 
1046 	if (cid != CID_NVAL) {
1047 		net_buf_simple_add_le16(msg, cid);
1048 	}
1049 
1050 	net_buf_simple_add_le16(msg, mod_id);
1051 
1052 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1053 	if (err) {
1054 		BT_ERR("model_send() failed (err %d)", err);
1055 		cli_reset();
1056 		goto done;
1057 	}
1058 
1059 	if (!status) {
1060 		cli_reset();
1061 		goto done;
1062 	}
1063 
1064 	err = cli_wait();
1065 done:
1066 	os_mbuf_free_chain(msg);
1067 	return err;
1068 }
1069 
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)1070 int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
1071 			       const u8_t label[16], u16_t mod_id,
1072 			       u16_t *virt_addr, u8_t *status)
1073 {
1074 	return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
1075 			  mod_id, CID_NVAL, virt_addr, status);
1076 }
1077 
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)1078 int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1079 				   const u8_t label[16], u16_t mod_id,
1080 				   u16_t cid, u16_t *virt_addr, u8_t *status)
1081 {
1082 	if (cid == CID_NVAL) {
1083 		return -EINVAL;
1084 	}
1085 
1086 	return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
1087 			  mod_id, cid, virt_addr, status);
1088 }
1089 
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)1090 int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
1091 			       const u8_t label[16], u16_t mod_id,
1092 			       u16_t *virt_addr, u8_t *status)
1093 {
1094 	return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
1095 			  mod_id, CID_NVAL, virt_addr, status);
1096 }
1097 
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)1098 int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1099 				   const u8_t label[16], u16_t mod_id,
1100 				   u16_t cid, u16_t *virt_addr, u8_t *status)
1101 {
1102 	if (cid == CID_NVAL) {
1103 		return -EINVAL;
1104 	}
1105 
1106 	return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
1107 			  mod_id, cid, virt_addr, status);
1108 }
1109 
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)1110 int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr,
1111 				     u16_t elem_addr, const u8_t label[16],
1112 				     u16_t mod_id, u16_t *virt_addr,
1113 				     u8_t *status)
1114 {
1115 	return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
1116 			  label, mod_id, CID_NVAL, virt_addr, status);
1117 }
1118 
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)1119 int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr,
1120 					 u16_t elem_addr, const u8_t label[16],
1121 					 u16_t mod_id, u16_t cid,
1122 					 u16_t *virt_addr, u8_t *status)
1123 {
1124 	if (cid == CID_NVAL) {
1125 		return -EINVAL;
1126 	}
1127 
1128 	return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
1129 			  label, mod_id, cid, virt_addr, status);
1130 }
1131 
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)1132 static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
1133 		       u16_t mod_id, u16_t cid,
1134 		       struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1135 {
1136 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 6 + 4);
1137 	struct bt_mesh_msg_ctx ctx = {
1138 		.net_idx = net_idx,
1139 		.app_idx = BT_MESH_KEY_DEV,
1140 		.addr = addr,
1141 		.send_ttl = BT_MESH_TTL_DEFAULT,
1142 	};
1143 	struct mod_pub_param param = {
1144 		.mod_id = mod_id,
1145 		.cid = cid,
1146 		.elem_addr = elem_addr,
1147 		.status = status,
1148 		.pub = pub,
1149 	};
1150 	int err;
1151 
1152 	err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1153 	if (err) {
1154 		goto done;
1155 	}
1156 
1157 	bt_mesh_model_msg_init(msg, OP_MOD_PUB_GET);
1158 
1159 	net_buf_simple_add_le16(msg, elem_addr);
1160 
1161 	if (cid != CID_NVAL) {
1162 		net_buf_simple_add_le16(msg, cid);
1163 	}
1164 
1165 	net_buf_simple_add_le16(msg, mod_id);
1166 
1167 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1168 	if (err) {
1169 		BT_ERR("model_send() failed (err %d)", err);
1170 		cli_reset();
1171 		goto done;
1172 	}
1173 
1174 	if (!status) {
1175 		cli_reset();
1176 		goto done;
1177 	}
1178 
1179 	err = cli_wait();
1180 done:
1181 	os_mbuf_free_chain(msg);
1182 	return err;
1183 }
1184 
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)1185 int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
1186 			    u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1187 			    u8_t *status)
1188 {
1189 	return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL,
1190 			   pub, status);
1191 }
1192 
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)1193 int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1194 				u16_t mod_id, u16_t cid,
1195 				struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1196 {
1197 	if (cid == CID_NVAL) {
1198 		return -EINVAL;
1199 	}
1200 
1201 	return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1202 }
1203 
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)1204 static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
1205 		       u16_t mod_id, u16_t cid,
1206 		       struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1207 {
1208 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 13 + 4);
1209 	struct bt_mesh_msg_ctx ctx = {
1210 		.net_idx = net_idx,
1211 		.app_idx = BT_MESH_KEY_DEV,
1212 		.addr = addr,
1213 		.send_ttl = BT_MESH_TTL_DEFAULT,
1214 	};
1215 	struct mod_pub_param param = {
1216 		.mod_id = mod_id,
1217 		.cid = cid,
1218 		.elem_addr = elem_addr,
1219 		.status = status,
1220 		.pub = pub,
1221 	};
1222 	int err;
1223 
1224 	err = cli_prepare(&param, OP_MOD_PUB_STATUS);
1225 	if (err) {
1226 		goto done;
1227 	}
1228 
1229 	bt_mesh_model_msg_init(msg, OP_MOD_PUB_SET);
1230 
1231 	net_buf_simple_add_le16(msg, elem_addr);
1232 	net_buf_simple_add_le16(msg, pub->addr);
1233 	net_buf_simple_add_le16(msg, (pub->app_idx & (pub->cred_flag << 12)));
1234 	net_buf_simple_add_u8(msg, pub->ttl);
1235 	net_buf_simple_add_u8(msg, pub->period);
1236 	net_buf_simple_add_u8(msg, pub->transmit);
1237 
1238 	if (cid != CID_NVAL) {
1239 		net_buf_simple_add_le16(msg, cid);
1240 	}
1241 
1242 	net_buf_simple_add_le16(msg, mod_id);
1243 
1244 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1245 	if (err) {
1246 		BT_ERR("model_send() failed (err %d)", err);
1247 		cli_reset();
1248 		goto done;
1249 	}
1250 
1251 	if (!status) {
1252 		cli_reset();
1253 		goto done;
1254 	}
1255 
1256 	err = cli_wait();
1257 done:
1258 	os_mbuf_free_chain(msg);
1259 	return err;
1260 }
1261 
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)1262 int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
1263 			    u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
1264 			    u8_t *status)
1265 {
1266 	return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL,
1267 			   pub, status);
1268 }
1269 
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)1270 int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
1271 				u16_t mod_id, u16_t cid,
1272 				struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
1273 {
1274 	if (cid == CID_NVAL) {
1275 		return -EINVAL;
1276 	}
1277 
1278 	return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status);
1279 }
1280 
bt_mesh_cfg_hb_sub_set(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1281 int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
1282 			   struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1283 {
1284 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4);
1285 	struct bt_mesh_msg_ctx ctx = {
1286 		.net_idx = net_idx,
1287 		.app_idx = BT_MESH_KEY_DEV,
1288 		.addr = addr,
1289 		.send_ttl = BT_MESH_TTL_DEFAULT,
1290 	};
1291 	struct hb_sub_param param = {
1292 		.status = status,
1293 		.sub = sub,
1294 	};
1295 	int err;
1296 
1297 	err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1298 	if (err) {
1299 		goto done;
1300 	}
1301 
1302 	bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_SET);
1303 	net_buf_simple_add_le16(msg, sub->src);
1304 	net_buf_simple_add_le16(msg, sub->dst);
1305 	net_buf_simple_add_u8(msg, sub->period);
1306 
1307 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1308 	if (err) {
1309 		BT_ERR("model_send() failed (err %d)", err);
1310 		cli_reset();
1311 		goto done;
1312 	}
1313 
1314 	if (!status) {
1315 		cli_reset();
1316 		goto done;
1317 	}
1318 
1319 	err = cli_wait();
1320 done:
1321 	os_mbuf_free_chain(msg);
1322 	return err;
1323 }
1324 
bt_mesh_cfg_hb_sub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_sub * sub,u8_t * status)1325 int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr,
1326 			   struct bt_mesh_cfg_hb_sub *sub, u8_t *status)
1327 {
1328 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4);
1329 	struct bt_mesh_msg_ctx ctx = {
1330 		.net_idx = net_idx,
1331 		.app_idx = BT_MESH_KEY_DEV,
1332 		.addr = addr,
1333 		.send_ttl = BT_MESH_TTL_DEFAULT,
1334 	};
1335 	struct hb_sub_param param = {
1336 		.status = status,
1337 		.sub = sub,
1338 	};
1339 	int err;
1340 
1341 	err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
1342 	if (err) {
1343 		goto done;
1344 	}
1345 
1346 	bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_GET);
1347 
1348 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1349 	if (err) {
1350 		BT_ERR("model_send() failed (err %d)", err);
1351 		cli_reset();
1352 		goto done;
1353 	}
1354 
1355 	if (!status) {
1356 		cli_reset();
1357 		goto done;
1358 	}
1359 
1360 	err = cli_wait();
1361 done:
1362 	os_mbuf_free_chain(msg);
1363 	return err;
1364 }
1365 
bt_mesh_cfg_hb_pub_set(u16_t net_idx,u16_t addr,const struct bt_mesh_cfg_hb_pub * pub,u8_t * status)1366 int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr,
1367 			   const struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
1368 {
1369 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4);
1370 	struct bt_mesh_msg_ctx ctx = {
1371 		.net_idx = net_idx,
1372 		.app_idx = BT_MESH_KEY_DEV,
1373 		.addr = addr,
1374 		.send_ttl = BT_MESH_TTL_DEFAULT,
1375 	};
1376 	struct hb_pub_param param = {
1377 		.status = status,
1378 	};
1379 	int err;
1380 
1381 	err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
1382 	if (err) {
1383 		goto done;
1384 	}
1385 
1386 	bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_SET);
1387 	net_buf_simple_add_le16(msg, pub->dst);
1388 	net_buf_simple_add_u8(msg, pub->count);
1389 	net_buf_simple_add_u8(msg, pub->period);
1390 	net_buf_simple_add_u8(msg, pub->ttl);
1391 	net_buf_simple_add_le16(msg, pub->feat);
1392 	net_buf_simple_add_le16(msg, pub->net_idx);
1393 
1394 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1395 	if (err) {
1396 		BT_ERR("model_send() failed (err %d)", err);
1397 		cli_reset();
1398 		goto done;
1399 	}
1400 
1401 	if (!status) {
1402 		cli_reset();
1403 		goto done;
1404 	}
1405 
1406 	err = cli_wait();
1407 done:
1408 	os_mbuf_free_chain(msg);
1409 	return err;
1410 }
1411 
bt_mesh_cfg_hb_pub_get(u16_t net_idx,u16_t addr,struct bt_mesh_cfg_hb_pub * pub,u8_t * status)1412 int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr,
1413 			   struct bt_mesh_cfg_hb_pub *pub, u8_t *status)
1414 {
1415 	struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4);
1416 	struct bt_mesh_msg_ctx ctx = {
1417 		.net_idx = net_idx,
1418 		.app_idx = BT_MESH_KEY_DEV,
1419 		.addr = addr,
1420 		.send_ttl = BT_MESH_TTL_DEFAULT,
1421 	};
1422 	struct hb_pub_param param = {
1423 		.status = status,
1424 		.pub = pub,
1425 	};
1426 	int err;
1427 
1428 	err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
1429 	if (err) {
1430 		goto done;
1431 	}
1432 
1433 	bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_GET);
1434 
1435 	err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
1436 	if (err) {
1437 		BT_ERR("model_send() failed (err %d)", err);
1438 		cli_reset();
1439 		goto done;
1440 	}
1441 
1442 	if (!status) {
1443 		cli_reset();
1444 		goto done;
1445 	}
1446 
1447 	err = cli_wait();
1448 done:
1449 	os_mbuf_free_chain(msg);
1450 	return err;
1451 }
1452 
bt_mesh_cfg_cli_timeout_get(void)1453 s32_t bt_mesh_cfg_cli_timeout_get(void)
1454 {
1455 	return msg_timeout;
1456 }
1457 
bt_mesh_cfg_cli_timeout_set(s32_t timeout)1458 void bt_mesh_cfg_cli_timeout_set(s32_t timeout)
1459 {
1460 	msg_timeout = timeout;
1461 }
1462 
bt_mesh_cfg_cli_init(struct bt_mesh_model * model,bool primary)1463 int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary)
1464 {
1465 	BT_DBG("primary %u", primary);
1466 
1467 	if (!primary) {
1468 		BT_ERR("Configuration Client only allowed in primary element");
1469 		return -EINVAL;
1470 	}
1471 
1472 	if (!model->user_data) {
1473 		BT_ERR("No Configuration Client context provided");
1474 		return -EINVAL;
1475 	}
1476 
1477 	cli = model->user_data;
1478 	cli->model = model;
1479 
1480 	/* Configuration Model security is device-key based */
1481 	model->keys[0] = BT_MESH_KEY_DEV;
1482 
1483 	k_sem_init(&cli->op_sync, 0, 1);
1484 
1485 	return 0;
1486 }
1487 
1488 #endif
1489