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