1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/bluetooth/bluetooth.h>
8 
9 #include <assert.h>
10 #include <errno.h>
11 #include <zephyr/bluetooth/mesh.h>
12 #include <zephyr/bluetooth/mesh/cfg.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/settings/settings.h>
15 #include <app_keys.h>
16 #include <va.h>
17 #include <sar_cfg_internal.h>
18 #include <string.h>
19 #include "mesh/access.h"
20 #include "mesh/testing.h"
21 
22 #include <zephyr/logging/log.h>
23 #define LOG_MODULE_NAME bttester_mesh
24 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
25 
26 #include "btp/btp.h"
27 #include "dfu_slot.h"
28 
29 #define CID_LOCAL 0x05F1
30 #define COMPANY_ID_LF 0x05F1
31 #define COMPANY_ID_NORDIC_SEMI 0x05F9
32 
33 /* Health server data */
34 #define CUR_FAULTS_MAX 4
35 #define HEALTH_TEST_ID 0x00
36 
37 static uint8_t cur_faults[CUR_FAULTS_MAX];
38 static uint8_t reg_faults[CUR_FAULTS_MAX * 2];
39 
40 /* Provision node data */
41 static uint8_t net_key[16];
42 static uint16_t net_key_idx;
43 static uint8_t flags;
44 static uint32_t iv_index;
45 static uint16_t addr;
46 static uint8_t dev_key[16];
47 static uint8_t input_size;
48 static uint8_t pub_key[64];
49 static uint8_t priv_key[32];
50 
51 /* Configured provisioning data */
52 static uint8_t dev_uuid[16];
53 static uint8_t static_auth[BTP_MESH_PROV_AUTH_MAX_LEN];
54 static uint8_t static_auth_size;
55 
56 /* Vendor Model data */
57 #define VND_MODEL_ID_1 0x1234
58 static uint8_t vnd_app_key[16];
59 static uint16_t vnd_app_key_idx = 0x000f;
60 
61 /* Model send data */
62 #define MODEL_BOUNDS_MAX 100
63 
64 #if defined(CONFIG_BT_MESH_BLOB_SRV) || defined(CONFIG_BT_MESH_BLOB_CLI)
65 /* BLOB Model data*/
66 static uint8_t blob_rx_sum;
67 static bool blob_valid;
68 static const char *blob_data = "11111111111111111111111111111111";
69 
blob_io_open(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,enum bt_mesh_blob_io_mode mode)70 static int blob_io_open(const struct bt_mesh_blob_io *io,
71 			const struct bt_mesh_blob_xfer *xfer,
72 			enum bt_mesh_blob_io_mode mode)
73 {
74 	blob_rx_sum = 0;
75 	blob_valid = true;
76 	return 0;
77 }
78 
blob_chunk_wr(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,const struct bt_mesh_blob_block * block,const struct bt_mesh_blob_chunk * chunk)79 static int blob_chunk_wr(const struct bt_mesh_blob_io *io,
80 			 const struct bt_mesh_blob_xfer *xfer,
81 			 const struct bt_mesh_blob_block *block,
82 			 const struct bt_mesh_blob_chunk *chunk)
83 {
84 	for (int i = 0; i < chunk->size; ++i) {
85 		blob_rx_sum += chunk->data[i];
86 		if (chunk->data[i] !=
87 		    blob_data[(i + chunk->offset) % strlen(blob_data)]) {
88 			blob_valid = false;
89 		}
90 	}
91 
92 	return 0;
93 }
94 
blob_chunk_rd(const struct bt_mesh_blob_io * io,const struct bt_mesh_blob_xfer * xfer,const struct bt_mesh_blob_block * block,const struct bt_mesh_blob_chunk * chunk)95 static int blob_chunk_rd(const struct bt_mesh_blob_io *io,
96 			 const struct bt_mesh_blob_xfer *xfer,
97 			 const struct bt_mesh_blob_block *block,
98 			 const struct bt_mesh_blob_chunk *chunk)
99 {
100 	for (int i = 0; i < chunk->size; ++i) {
101 		chunk->data[i] =
102 			blob_data[(i + chunk->offset) % strlen(blob_data)];
103 	}
104 
105 	return 0;
106 }
107 
108 static const struct bt_mesh_blob_io dummy_blob_io = {
109 	.open = blob_io_open,
110 	.rd = blob_chunk_rd,
111 	.wr = blob_chunk_wr,
112 };
113 #endif
114 
115 #if defined(CONFIG_BT_MESH_DFD_SRV)
116 static const struct bt_mesh_dfu_slot *dfu_self_update_slot;
117 
is_self_update(struct bt_mesh_dfd_srv * srv)118 static bool is_self_update(struct bt_mesh_dfd_srv *srv)
119 {
120 	for (int i = 0; i < ARRAY_SIZE(srv->targets); i++) {
121 		if (bt_mesh_has_addr(srv->targets[i].blob.addr)) {
122 			return true;
123 		}
124 	}
125 
126 	return false;
127 }
128 
129 /* DFD Model data*/
dfd_srv_recv(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const struct bt_mesh_blob_io ** io)130 static int dfd_srv_recv(struct bt_mesh_dfd_srv *srv,
131 			const struct bt_mesh_dfu_slot *slot,
132 			const struct bt_mesh_blob_io **io)
133 {
134 	LOG_DBG("Uploading new firmware image to the distributor.");
135 
136 	*io = &dummy_blob_io;
137 
138 	return 0;
139 }
140 
dfd_srv_del(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)141 static void dfd_srv_del(struct bt_mesh_dfd_srv *srv,
142 			const struct bt_mesh_dfu_slot *slot)
143 {
144 	LOG_DBG("Deleting the firmware image from the distributor.");
145 }
146 
dfd_srv_send(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const struct bt_mesh_blob_io ** io)147 static int dfd_srv_send(struct bt_mesh_dfd_srv *srv,
148 			const struct bt_mesh_dfu_slot *slot,
149 			const struct bt_mesh_blob_io **io)
150 {
151 	LOG_DBG("Starting the firmware distribution.");
152 
153 	*io = &dummy_blob_io;
154 
155 	dfu_self_update_slot = NULL;
156 
157 	if (is_self_update(srv)) {
158 		LOG_DBG("DFD server starts self-update...");
159 		dfu_self_update_slot = slot;
160 	}
161 
162 	return 0;
163 }
164 
165 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
166 static struct {
167 	uint8_t uri[CONFIG_BT_MESH_DFU_URI_MAXLEN];
168 	uint8_t uri_len;
169 	uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
170 	uint8_t fwid_len;
171 	const struct bt_mesh_dfu_slot *slot;
172 	uint8_t progress;
173 	bool started;
174 } dfd_srv_oob_ctx;
175 
176 static void oob_check_handler(struct k_work *work);
177 static K_WORK_DEFINE(oob_check, oob_check_handler);
178 static void oob_store_handler(struct k_work *work);
179 static K_WORK_DEFINE(oob_store, oob_store_handler);
180 
dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot,const char * uri,uint8_t uri_len,const uint8_t * fwid,uint16_t fwid_len)181 static int dfd_srv_start_oob_upload(struct bt_mesh_dfd_srv *srv,
182 				    const struct bt_mesh_dfu_slot *slot,
183 				    const char *uri, uint8_t uri_len,
184 				    const uint8_t *fwid, uint16_t fwid_len)
185 {
186 	LOG_DBG("Start OOB Upload");
187 
188 	memcpy(dfd_srv_oob_ctx.uri, uri, uri_len);
189 	dfd_srv_oob_ctx.uri_len = uri_len;
190 	memcpy(dfd_srv_oob_ctx.fwid, fwid, fwid_len);
191 	dfd_srv_oob_ctx.fwid_len = fwid_len;
192 	dfd_srv_oob_ctx.slot = slot;
193 	dfd_srv_oob_ctx.progress = 0;
194 	dfd_srv_oob_ctx.started = true;
195 
196 	k_work_submit(&oob_check);
197 
198 	return BT_MESH_DFD_SUCCESS;
199 }
200 
dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)201 static void dfd_srv_cancel_oob_upload(struct bt_mesh_dfd_srv *srv,
202 				      const struct bt_mesh_dfu_slot *slot)
203 {
204 	LOG_DBG("Cancel OOB Upload");
205 
206 	dfd_srv_oob_ctx.started = false;
207 }
208 
dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv * srv,const struct bt_mesh_dfu_slot * slot)209 static uint8_t dfd_srv_oob_progress_get(struct bt_mesh_dfd_srv *srv,
210 					const struct bt_mesh_dfu_slot *slot)
211 {
212 	uint8_t progress;
213 
214 	if (dfd_srv_oob_ctx.started) {
215 		progress = dfd_srv_oob_ctx.progress;
216 
217 		dfd_srv_oob_ctx.progress = MIN(dfd_srv_oob_ctx.progress + 25, 99);
218 
219 		if (dfd_srv_oob_ctx.progress == 99) {
220 			k_work_submit(&oob_store);
221 		}
222 	} else {
223 		progress = 0;
224 	}
225 
226 	LOG_DBG("OOB Progress Get (%sstarted: %d %%)", dfd_srv_oob_ctx.started ? "" : "not ",
227 		progress);
228 	return progress;
229 }
230 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
231 
232 static struct bt_mesh_dfd_srv_cb dfd_srv_cb = {
233 	.recv = dfd_srv_recv,
234 	.del = dfd_srv_del,
235 	.send = dfd_srv_send,
236 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
237 	.start_oob_upload = dfd_srv_start_oob_upload,
238 	.cancel_oob_upload = dfd_srv_cancel_oob_upload,
239 	.oob_progress_get = dfd_srv_oob_progress_get,
240 #endif
241 };
242 
243 static struct bt_mesh_dfd_srv dfd_srv = BT_MESH_DFD_SRV_INIT(&dfd_srv_cb);
244 
245 #ifdef CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD
246 #define SUPPORTED_SCHEME "http"
247 
oob_check_handler(struct k_work * work)248 static void oob_check_handler(struct k_work *work)
249 {
250 	uint8_t scheme[10];
251 	int i;
252 	int status;
253 	int err;
254 
255 	for (i = 0; i < MIN(dfd_srv_oob_ctx.uri_len, sizeof(scheme)); i++) {
256 		if (IN_RANGE(dfd_srv_oob_ctx.uri[i], 48, 57) || /* DIGIT */
257 		    IN_RANGE(dfd_srv_oob_ctx.uri[i], 65, 90) || /* ALPHA UPPER CASE */
258 		    IN_RANGE(dfd_srv_oob_ctx.uri[i], 97, 122) || /* ALPHA LOWER CASE */
259 		    dfd_srv_oob_ctx.uri[i] == '.' ||
260 		    dfd_srv_oob_ctx.uri[i] == '+' ||
261 		    dfd_srv_oob_ctx.uri[i] == '-') {
262 			scheme[i] = dfd_srv_oob_ctx.uri[i];
263 		} else {
264 			break;
265 		}
266 	}
267 
268 	if (i == dfd_srv_oob_ctx.uri_len || dfd_srv_oob_ctx.uri[i] != ':') {
269 		status = BT_MESH_DFD_ERR_URI_MALFORMED;
270 	} else if (i != strlen(SUPPORTED_SCHEME) ||
271 		   memcmp(scheme, SUPPORTED_SCHEME, strlen(SUPPORTED_SCHEME))) {
272 		status = BT_MESH_DFD_ERR_URI_NOT_SUPPORTED;
273 	} else {
274 		status = BT_MESH_DFD_SUCCESS;
275 	}
276 
277 	err = bt_mesh_dfd_srv_oob_check_complete(&dfd_srv, dfd_srv_oob_ctx.slot, status,
278 						 dfd_srv_oob_ctx.fwid, dfd_srv_oob_ctx.fwid_len);
279 	LOG_DBG("OOB check completed (err %d)", err);
280 }
281 
oob_store_handler(struct k_work * work)282 static void oob_store_handler(struct k_work *work)
283 {
284 	int err;
285 
286 	err = bt_mesh_dfd_srv_oob_store_complete(&dfd_srv, dfd_srv_oob_ctx.slot, true,
287 						 10000, "metadata", 8);
288 	LOG_DBG("OOB store completed (err %d)", err);
289 }
290 #endif /* CONFIG_BT_MESH_DFD_SRV_OOB_UPLOAD */
291 #endif
292 
293 #if defined(CONFIG_BT_MESH_BLOB_CLI)
294 static struct {
295 	struct bt_mesh_blob_cli_inputs inputs;
296 	struct bt_mesh_blob_target targets[32];
297 	struct bt_mesh_blob_target_pull pull[32];
298 	uint8_t target_count;
299 	struct bt_mesh_blob_xfer xfer;
300 } blob_cli_xfer;
301 
blob_cli_lost_target(struct bt_mesh_blob_cli * cli,struct bt_mesh_blob_target * target,enum bt_mesh_blob_status reason)302 static void blob_cli_lost_target(struct bt_mesh_blob_cli *cli,
303 				 struct bt_mesh_blob_target *target,
304 				 enum bt_mesh_blob_status reason)
305 {
306 	LOG_DBG("Mesh Blob: Lost target 0x%04x (reason: %u)", target->addr,
307 		reason);
308 	tester_event(BTP_SERVICE_ID_MESH, MESH_EV_BLOB_LOST_TARGET, NULL, 0);
309 }
310 
blob_cli_caps(struct bt_mesh_blob_cli * cli,const struct bt_mesh_blob_cli_caps * caps)311 static void blob_cli_caps(struct bt_mesh_blob_cli *cli,
312 			  const struct bt_mesh_blob_cli_caps *caps)
313 {
314 	const char *const modes[] = {
315 		"none",
316 		"push",
317 		"pull",
318 		"all",
319 	};
320 
321 	if (!caps) {
322 		LOG_DBG("None of the targets can be used for BLOB transfer");
323 		return;
324 	}
325 
326 	LOG_DBG("Mesh BLOB: capabilities:");
327 	LOG_DBG("\tMax BLOB size: %u bytes", caps->max_size);
328 	LOG_DBG("\tBlock size: %u-%u (%u-%u bytes)", caps->min_block_size_log,
329 		caps->max_block_size_log, 1 << caps->min_block_size_log,
330 		1 << caps->max_block_size_log);
331 	LOG_DBG("\tMax chunks: %u", caps->max_chunks);
332 	LOG_DBG("\tChunk size: %u", caps->max_chunk_size);
333 	LOG_DBG("\tMTU size: %u", caps->mtu_size);
334 	LOG_DBG("\tModes: %s", modes[caps->modes]);
335 }
336 
blob_cli_end(struct bt_mesh_blob_cli * cli,const struct bt_mesh_blob_xfer * xfer,bool success)337 static void blob_cli_end(struct bt_mesh_blob_cli *cli,
338 			 const struct bt_mesh_blob_xfer *xfer, bool success)
339 {
340 	if (success) {
341 		LOG_DBG("Mesh BLOB transfer complete.");
342 	} else {
343 		LOG_DBG("Mesh BLOB transfer failed.");
344 	}
345 }
346 
347 static const struct bt_mesh_blob_cli_cb blob_cli_handlers = {
348 	.lost_target = blob_cli_lost_target,
349 	.caps = blob_cli_caps,
350 	.end = blob_cli_end,
351 };
352 
353 static struct bt_mesh_blob_cli blob_cli = { .cb = &blob_cli_handlers };
354 #endif
355 
356 #if defined(CONFIG_BT_MESH_DFU_SRV)
357 const char *metadata_data = "1100000000000011";
358 
359 static uint8_t dfu_fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN] = {
360 	0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
361 };
362 
363 static struct bt_mesh_dfu_img dfu_imgs[] = { {
364 	.fwid = &dfu_fwid,
365 	.fwid_len = sizeof(dfu_fwid),
366 } };
367 
dfu_meta_check(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,struct net_buf_simple * metadata,enum bt_mesh_dfu_effect * effect)368 static int dfu_meta_check(struct bt_mesh_dfu_srv *srv,
369 			  const struct bt_mesh_dfu_img *img,
370 			  struct net_buf_simple *metadata,
371 			  enum bt_mesh_dfu_effect *effect)
372 {
373 	char string[2 * CONFIG_BT_MESH_DFU_METADATA_MAXLEN + 1];
374 	int i;
375 	size_t len;
376 
377 	len = bin2hex(metadata->data, metadata->len, string, sizeof(string));
378 	string[len] = '\0';
379 
380 	for (i = 0; i <= len; i++) {
381 		if (string[i] != metadata_data[i]) {
382 			LOG_ERR("Wrong Firmware Metadata");
383 			return -EINVAL;
384 		}
385 	}
386 
387 	return 0;
388 }
389 
dfu_start(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,struct net_buf_simple * metadata,const struct bt_mesh_blob_io ** io)390 static int dfu_start(struct bt_mesh_dfu_srv *srv,
391 		     const struct bt_mesh_dfu_img *img,
392 		     struct net_buf_simple *metadata,
393 		     const struct bt_mesh_blob_io **io)
394 {
395 	LOG_DBG("DFU setup");
396 
397 	*io = &dummy_blob_io;
398 
399 	return 0;
400 }
401 
dfu_end(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img,bool success)402 static void dfu_end(struct bt_mesh_dfu_srv *srv,
403 		    const struct bt_mesh_dfu_img *img, bool success)
404 {
405 	if (!success) {
406 		LOG_ERR("DFU failed");
407 		return;
408 	}
409 
410 	if (!blob_valid) {
411 		bt_mesh_dfu_srv_rejected(srv);
412 		return;
413 	}
414 
415 	bt_mesh_dfu_srv_verified(srv);
416 }
417 
dfu_apply(struct bt_mesh_dfu_srv * srv,const struct bt_mesh_dfu_img * img)418 static int dfu_apply(struct bt_mesh_dfu_srv *srv,
419 		     const struct bt_mesh_dfu_img *img)
420 {
421 	if (!blob_valid) {
422 		return -EINVAL;
423 	}
424 
425 	LOG_DBG("Applying DFU transfer...");
426 
427 #if defined(CONFIG_BT_MESH_DFD_SRV)
428 	if (is_self_update(&dfd_srv) && dfu_self_update_slot != NULL) {
429 		LOG_DBG("Swapping fwid for self-update");
430 		/* Simulate self-update by swapping fwid. */
431 		memcpy(&dfu_fwid[0], dfu_self_update_slot->fwid, dfu_self_update_slot->fwid_len);
432 		dfu_imgs[0].fwid_len = dfu_self_update_slot->fwid_len;
433 	}
434 
435 #endif
436 
437 	return 0;
438 }
439 
440 static const struct bt_mesh_dfu_srv_cb dfu_handlers = {
441 	.check = dfu_meta_check,
442 	.start = dfu_start,
443 	.end = dfu_end,
444 	.apply = dfu_apply,
445 };
446 
447 static struct bt_mesh_dfu_srv dfu_srv =
448 	BT_MESH_DFU_SRV_INIT(&dfu_handlers, dfu_imgs, ARRAY_SIZE(dfu_imgs));
449 #endif /* CONFIG_BT_MESH_DFU_SRV */
450 
451 /* Model Authentication Method */
452 #define AUTH_METHOD_STATIC 0x01
453 #define AUTH_METHOD_OUTPUT 0x02
454 #define AUTH_METHOD_INPUT 0x03
455 
456 static struct model_data {
457 	const struct bt_mesh_model *model;
458 	uint16_t addr;
459 	uint16_t appkey_idx;
460 } model_bound[MODEL_BOUNDS_MAX];
461 
462 static struct {
463 	uint16_t local;
464 	uint16_t dst;
465 	uint16_t net_idx;
466 } net = {
467 	.local = BT_MESH_ADDR_UNASSIGNED,
468 	.dst = BT_MESH_ADDR_UNASSIGNED,
469 };
470 
supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)471 static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
472 				  void *rsp, uint16_t *rsp_len)
473 {
474 	struct btp_mesh_read_supported_commands_rp *rp = rsp;
475 
476 	/* octet 0 */
477 	tester_set_bit(rp->data, BTP_MESH_READ_SUPPORTED_COMMANDS);
478 	tester_set_bit(rp->data, BTP_MESH_CONFIG_PROVISIONING);
479 	tester_set_bit(rp->data, BTP_MESH_PROVISION_NODE);
480 	tester_set_bit(rp->data, BTP_MESH_INIT);
481 	tester_set_bit(rp->data, BTP_MESH_RESET);
482 	tester_set_bit(rp->data, BTP_MESH_INPUT_NUMBER);
483 	tester_set_bit(rp->data, BTP_MESH_INPUT_STRING);
484 
485 	/* octet 1 */
486 	tester_set_bit(rp->data, BTP_MESH_IVU_TEST_MODE);
487 	tester_set_bit(rp->data, BTP_MESH_IVU_TOGGLE_STATE);
488 	tester_set_bit(rp->data, BTP_MESH_NET_SEND);
489 	tester_set_bit(rp->data, BTP_MESH_HEALTH_GENERATE_FAULTS);
490 	tester_set_bit(rp->data, BTP_MESH_HEALTH_CLEAR_FAULTS);
491 	tester_set_bit(rp->data, BTP_MESH_LPN);
492 	tester_set_bit(rp->data, BTP_MESH_LPN_POLL);
493 	tester_set_bit(rp->data, BTP_MESH_MODEL_SEND);
494 
495 	/* octet 2 */
496 #if defined(CONFIG_BT_TESTING)
497 	tester_set_bit(rp->data, BTP_MESH_LPN_SUBSCRIBE);
498 	tester_set_bit(rp->data, BTP_MESH_LPN_UNSUBSCRIBE);
499 	tester_set_bit(rp->data, BTP_MESH_RPL_CLEAR);
500 #endif /* CONFIG_BT_TESTING */
501 	tester_set_bit(rp->data, BTP_MESH_PROXY_IDENTITY);
502 	tester_set_bit(rp->data, BTP_MESH_COMP_DATA_GET);
503 	tester_set_bit(rp->data, BTP_MESH_CFG_BEACON_GET);
504 	tester_set_bit(rp->data, BTP_MESH_CFG_BEACON_SET);
505 
506 	/* octet 3 */
507 	tester_set_bit(rp->data, BTP_MESH_CFG_DEFAULT_TTL_GET);
508 	tester_set_bit(rp->data, BTP_MESH_CFG_DEFAULT_TTL_SET);
509 	tester_set_bit(rp->data, BTP_MESH_CFG_GATT_PROXY_GET);
510 	tester_set_bit(rp->data, BTP_MESH_CFG_GATT_PROXY_SET);
511 	tester_set_bit(rp->data, BTP_MESH_CFG_FRIEND_GET);
512 	tester_set_bit(rp->data, BTP_MESH_CFG_FRIEND_SET);
513 	tester_set_bit(rp->data, BTP_MESH_CFG_RELAY_GET);
514 	tester_set_bit(rp->data, BTP_MESH_CFG_RELAY_SET);
515 
516 	/* octet 4 */
517 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_PUB_GET);
518 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_PUB_SET);
519 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_ADD);
520 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_DEL);
521 	tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_ADD);
522 	tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_GET);
523 	tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_DEL);
524 	tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_ADD);
525 
526 	/* octet 5 */
527 	tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_DEL);
528 	tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_GET);
529 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_BIND);
530 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_UNBIND);
531 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_GET);
532 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_VND_GET);
533 	tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_PUB_SET);
534 	tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_PUB_GET);
535 
536 	/* octet 6 */
537 	tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_SUB_SET);
538 	tester_set_bit(rp->data, BTP_MESH_CFG_HEARTBEAT_SUB_GET);
539 	tester_set_bit(rp->data, BTP_MESH_CFG_NET_TRANS_GET);
540 	tester_set_bit(rp->data, BTP_MESH_CFG_NET_TRANS_SET);
541 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_OVW);
542 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_DEL_ALL);
543 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_GET);
544 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_GET_VND);
545 
546 	/* octet 7 */
547 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_ADD);
548 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_DEL);
549 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_SUB_VA_OVW);
550 	tester_set_bit(rp->data, BTP_MESH_CFG_NETKEY_UPDATE);
551 	tester_set_bit(rp->data, BTP_MESH_CFG_APPKEY_UPDATE);
552 	tester_set_bit(rp->data, BTP_MESH_CFG_NODE_IDT_SET);
553 	tester_set_bit(rp->data, BTP_MESH_CFG_NODE_IDT_GET);
554 	tester_set_bit(rp->data, BTP_MESH_CFG_NODE_RESET);
555 
556 	/* octet 8 */
557 	tester_set_bit(rp->data, BTP_MESH_CFG_LPN_TIMEOUT_GET);
558 	tester_set_bit(rp->data, BTP_MESH_CFG_MODEL_APP_BIND_VND);
559 	tester_set_bit(rp->data, BTP_MESH_HEALTH_FAULT_GET);
560 	tester_set_bit(rp->data, BTP_MESH_HEALTH_FAULT_CLEAR);
561 	tester_set_bit(rp->data, BTP_MESH_HEALTH_PERIOD_GET);
562 	tester_set_bit(rp->data, BTP_MESH_HEALTH_PERIOD_SET);
563 
564 	/* octet 9 */
565 	tester_set_bit(rp->data, BTP_MESH_HEALTH_ATTENTION_GET);
566 	tester_set_bit(rp->data, BTP_MESH_HEALTH_ATTENTION_SET);
567 	tester_set_bit(rp->data, BTP_MESH_PROVISION_ADV);
568 	tester_set_bit(rp->data, BTP_MESH_CFG_KRP_GET);
569 	tester_set_bit(rp->data, BTP_MESH_CFG_KRP_SET);
570 	tester_set_bit(rp->data, BTP_MESH_VA_ADD);
571 	tester_set_bit(rp->data, BTP_MESH_VA_DEL);
572 
573 	*rsp_len = sizeof(*rp) + 10;
574 
575 	return BTP_STATUS_SUCCESS;
576 }
577 
get_faults(uint8_t * faults,uint8_t faults_size,uint8_t * dst,uint8_t * count)578 static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
579 {
580 	uint8_t i, limit = *count;
581 
582 	for (i = 0U, *count = 0U; i < faults_size && *count < limit; i++) {
583 		if (faults[i]) {
584 			*dst++ = faults[i];
585 			(*count)++;
586 		}
587 	}
588 }
589 
fault_get_cur(const struct bt_mesh_model * model,uint8_t * test_id,uint16_t * company_id,uint8_t * faults,uint8_t * fault_count)590 static int fault_get_cur(const struct bt_mesh_model *model, uint8_t *test_id,
591 			 uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
592 {
593 	LOG_DBG("");
594 
595 	*test_id = HEALTH_TEST_ID;
596 	*company_id = CID_LOCAL;
597 
598 	get_faults(cur_faults, sizeof(cur_faults), faults, fault_count);
599 
600 	return 0;
601 }
602 
fault_get_reg(const struct bt_mesh_model * model,uint16_t company_id,uint8_t * test_id,uint8_t * faults,uint8_t * fault_count)603 static int fault_get_reg(const struct bt_mesh_model *model, uint16_t company_id,
604 			 uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
605 {
606 	LOG_DBG("company_id 0x%04x", company_id);
607 
608 	if (company_id != CID_LOCAL) {
609 		return -EINVAL;
610 	}
611 
612 	*test_id = HEALTH_TEST_ID;
613 
614 	get_faults(reg_faults, sizeof(reg_faults), faults, fault_count);
615 
616 	return 0;
617 }
618 
fault_clear(const struct bt_mesh_model * model,uint16_t company_id)619 static int fault_clear(const struct bt_mesh_model *model, uint16_t company_id)
620 {
621 	LOG_DBG("company_id 0x%04x", company_id);
622 
623 	if (company_id != CID_LOCAL) {
624 		return -EINVAL;
625 	}
626 
627 	(void)memset(reg_faults, 0, sizeof(reg_faults));
628 
629 	return 0;
630 }
631 
fault_test(const struct bt_mesh_model * model,uint8_t test_id,uint16_t company_id)632 static int fault_test(const struct bt_mesh_model *model, uint8_t test_id,
633 		      uint16_t company_id)
634 {
635 	LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id);
636 
637 	if (company_id != CID_LOCAL || test_id != HEALTH_TEST_ID) {
638 		return -EINVAL;
639 	}
640 
641 	return 0;
642 }
643 
644 static const struct bt_mesh_health_srv_cb health_srv_cb = {
645 	.fault_get_cur = fault_get_cur,
646 	.fault_get_reg = fault_get_reg,
647 	.fault_clear = fault_clear,
648 	.fault_test = fault_test,
649 };
650 
show_faults(uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)651 static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
652 {
653 	size_t i;
654 
655 	if (!fault_count) {
656 		LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x: no faults",
657 			test_id, cid);
658 		return;
659 	}
660 
661 	LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu: ",
662 		test_id, cid, fault_count);
663 
664 	for (i = 0; i < fault_count; i++) {
665 		LOG_DBG("0x%02x", faults[i]);
666 	}
667 }
668 
health_current_status(struct bt_mesh_health_cli * cli,uint16_t addr,uint8_t test_id,uint16_t cid,uint8_t * faults,size_t fault_count)669 static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
670 				  uint8_t test_id, uint16_t cid, uint8_t *faults,
671 				  size_t fault_count)
672 {
673 	LOG_DBG("Health Current Status from 0x%04x", addr);
674 	show_faults(test_id, cid, faults, fault_count);
675 }
676 
677 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
678 static struct bt_mesh_large_comp_data_cli lcd_cli = {
679 };
680 #endif
681 
682 static struct bt_mesh_health_cli health_cli = {
683 	.current_status = health_current_status,
684 };
685 
686 
687 static uint8_t health_tests[] = {
688 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34,
689 				 0x15),
690 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03),
691 };
692 
693 static const uint8_t zero_metadata[100];
694 
695 static const struct bt_mesh_models_metadata_entry health_srv_meta[] = {
696 	BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests),
697 	{
698 		.len = ARRAY_SIZE(zero_metadata),
699 		.id = 0xABCD,
700 		.data = zero_metadata,
701 	},
702 	BT_MESH_MODELS_METADATA_END,
703 };
704 
705 static const uint8_t health_tests_alt[] = {
706 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x11, 0x22, 0x33, 0x44, 0x55,
707 				 0x66),
708 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x11, 0x22, 0x33),
709 };
710 
711 static const struct bt_mesh_models_metadata_entry health_srv_meta_alt[] = {
712 	BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests_alt),
713 	{
714 		.len = ARRAY_SIZE(zero_metadata),
715 		.id = 0xFEED,
716 		.data = zero_metadata,
717 	},
718 	BT_MESH_MODELS_METADATA_END,
719 };
720 
721 static struct bt_mesh_health_srv health_srv = {
722 	.cb = &health_srv_cb,
723 };
724 
725 BT_MESH_HEALTH_PUB_DEFINE(health_pub, CUR_FAULTS_MAX);
726 
727 static struct bt_mesh_cfg_cli cfg_cli = {
728 };
729 
730 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
731 static struct bt_mesh_sar_cfg_cli sar_cfg_cli;
732 #endif
733 
734 #if defined(CONFIG_BT_MESH_RPR_CLI)
rpr_scan_report(struct bt_mesh_rpr_cli * cli,const struct bt_mesh_rpr_node * srv,struct bt_mesh_rpr_unprov * unprov,struct net_buf_simple * adv_data)735 static void rpr_scan_report(struct bt_mesh_rpr_cli *cli,
736 			    const struct bt_mesh_rpr_node *srv,
737 			    struct bt_mesh_rpr_unprov *unprov,
738 			    struct net_buf_simple *adv_data)
739 {
740 	char uuid_hex_str[32 + 1];
741 
742 	bin2hex(unprov->uuid, 16, uuid_hex_str, sizeof(uuid_hex_str));
743 
744 	LOG_DBG("Server 0x%04x:\n"
745 		    "\tuuid:   %s\n"
746 		    "\tOOB:    0x%04x",
747 		    srv->addr, uuid_hex_str, unprov->oob);
748 
749 	while (adv_data && adv_data->len > 2) {
750 		uint8_t len, type;
751 		uint8_t data[31];
752 
753 		len = net_buf_simple_pull_u8(adv_data) - 1;
754 		type = net_buf_simple_pull_u8(adv_data);
755 		memcpy(data, net_buf_simple_pull_mem(adv_data, len), len);
756 		data[len] = '\0';
757 
758 		if (type == BT_DATA_URI) {
759 			LOG_DBG("\tURI:    \"\\x%02x%s\"",
760 				data[0], &data[1]);
761 		} else if (type == BT_DATA_NAME_COMPLETE) {
762 			LOG_DBG("\tName:   \"%s\"", data);
763 		} else {
764 			char string[64 + 1];
765 
766 			bin2hex(data, len, string, sizeof(string));
767 			LOG_DBG("\t0x%02x:  %s", type, string);
768 		}
769 	}
770 }
771 
772 static struct bt_mesh_rpr_cli rpr_cli = {
773 	.scan_report = rpr_scan_report,
774 };
775 #endif
776 
777 #if defined(CONFIG_BT_MESH_DFU_SRV)
dfu_srv_apply(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)778 static uint8_t dfu_srv_apply(const void *cmd, uint16_t cmd_len,
779 			     void *rsp, uint16_t *rsp_len)
780 {
781 	LOG_DBG("Applying image on server");
782 	bt_mesh_dfu_srv_applied(&dfu_srv);
783 	return BTP_STATUS_SUCCESS;
784 }
785 #endif
786 
787 #ifdef CONFIG_BT_MESH_PRIV_BEACON_CLI
788 static struct bt_mesh_priv_beacon_cli priv_beacon_cli;
789 
priv_beacon_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)790 static uint8_t priv_beacon_get(const void *cmd, uint16_t cmd_len,
791 			       void *rsp, uint16_t *rsp_len)
792 {
793 	const struct btp_priv_beacon_get_cmd *cp = cmd;
794 
795 	struct bt_mesh_priv_beacon val;
796 	int err;
797 
798 	err = bt_mesh_priv_beacon_cli_get(net.net_idx, cp->dst, &val);
799 	if (err) {
800 		LOG_ERR("Failed to send Private Beacon Get (err %d)", err);
801 		return BTP_STATUS_FAILED;
802 	}
803 
804 	LOG_DBG("Private Beacon state: %u, %u", val.enabled, val.rand_interval);
805 	return BTP_STATUS_SUCCESS;
806 }
807 
priv_beacon_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)808 static uint8_t priv_beacon_set(const void *cmd, uint16_t cmd_len,
809 			       void *rsp, uint16_t *rsp_len)
810 {
811 	const struct btp_priv_beacon_set_cmd *cp = cmd;
812 	struct bt_mesh_priv_beacon val;
813 	int err;
814 
815 	val.enabled = cp->enabled;
816 	val.rand_interval = cp->rand_interval;
817 
818 	err = bt_mesh_priv_beacon_cli_set(net.net_idx, cp->dst, &val, &val);
819 	if (err) {
820 		LOG_ERR("Failed to send Private Beacon Set (err %d)", err);
821 		return BTP_STATUS_FAILED;
822 	}
823 
824 	return BTP_STATUS_SUCCESS;
825 }
826 
priv_gatt_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)827 static uint8_t priv_gatt_proxy_get(const void *cmd, uint16_t cmd_len,
828 				   void *rsp, uint16_t *rsp_len)
829 {
830 	const struct btp_priv_gatt_proxy_get_cmd *cp = cmd;
831 
832 	uint8_t state;
833 	int err;
834 
835 	err = bt_mesh_priv_beacon_cli_gatt_proxy_get(net.net_idx, cp->dst, &state);
836 	if (err) {
837 		LOG_ERR("Failed to send Private GATT Proxy Get (err %d)", err);
838 		return BTP_STATUS_FAILED;
839 	}
840 
841 	LOG_DBG("Private GATT Proxy state: %u", state);
842 	return BTP_STATUS_SUCCESS;
843 }
844 
priv_gatt_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)845 static uint8_t priv_gatt_proxy_set(const void *cmd, uint16_t cmd_len,
846 				   void *rsp, uint16_t *rsp_len)
847 {
848 	const struct btp_priv_gatt_proxy_set_cmd *cp = cmd;
849 
850 	uint8_t state;
851 	int err;
852 
853 	state = cp->state;
854 
855 	err = bt_mesh_priv_beacon_cli_gatt_proxy_set(net.net_idx, cp->dst, state, &state);
856 	if (err) {
857 		LOG_ERR("Failed to send Private GATT Proxy Set (err %d)", err);
858 		return BTP_STATUS_FAILED;
859 	}
860 
861 	return BTP_STATUS_SUCCESS;
862 }
863 
priv_node_id_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)864 static uint8_t priv_node_id_get(const void *cmd, uint16_t cmd_len,
865 				void *rsp, uint16_t *rsp_len)
866 {
867 	const struct btp_priv_node_id_get_cmd *cp = cmd;
868 	struct bt_mesh_priv_node_id val;
869 	uint16_t key_net_idx;
870 	int err;
871 
872 	key_net_idx = cp->key_net_idx;
873 
874 	err = bt_mesh_priv_beacon_cli_node_id_get(net.net_idx, cp->dst, key_net_idx, &val);
875 	if (err) {
876 		LOG_ERR("Failed to send Private Node Identity Get (err %d)", err);
877 		return BTP_STATUS_FAILED;
878 	}
879 
880 	LOG_DBG("Private Node Identity state: %u %u %u", val.net_idx, val.state, val.status);
881 	return BTP_STATUS_SUCCESS;
882 }
883 
priv_node_id_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)884 static uint8_t priv_node_id_set(const void *cmd, uint16_t cmd_len,
885 				void *rsp, uint16_t *rsp_len)
886 {
887 	const struct btp_priv_node_id_set_cmd *cp = cmd;
888 	struct bt_mesh_priv_node_id val;
889 	int err;
890 
891 	val.net_idx = cp->net_idx;
892 	val.state = cp->state;
893 
894 	err = bt_mesh_priv_beacon_cli_node_id_set(net.net_idx, cp->dst, &val, &val);
895 	if (err) {
896 		LOG_ERR("Failed to send Private Node Identity Set (err %d)", err);
897 		return BTP_STATUS_FAILED;
898 	}
899 
900 	return BTP_STATUS_SUCCESS;
901 }
902 
proxy_private_identity_enable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)903 static uint8_t proxy_private_identity_enable(const void *cmd, uint16_t cmd_len,
904 					     void *rsp, uint16_t *rsp_len)
905 {
906 	int err;
907 
908 	LOG_DBG("");
909 
910 	err = bt_mesh_proxy_private_identity_enable();
911 	if (err) {
912 		LOG_ERR("Failed to enable proxy private identity (err %d)", err);
913 		return BTP_STATUS_FAILED;
914 	}
915 
916 	return BTP_STATUS_SUCCESS;
917 }
918 #endif
919 
920 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
921 static struct bt_mesh_sol_pdu_rpl_cli srpl_cli;
922 #endif
923 
924 
925 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
926 static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli;
927 
od_priv_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)928 static uint8_t od_priv_proxy_get(const void *cmd, uint16_t cmd_len,
929 				 void *rsp, uint16_t *rsp_len)
930 {
931 	const struct btp_od_priv_proxy_get_cmd *cp = cmd;
932 	uint8_t val_rsp;
933 	int err;
934 
935 	LOG_DBG("");
936 
937 	err = bt_mesh_od_priv_proxy_cli_get(net.net_idx, cp->dst, &val_rsp);
938 	if (err) {
939 		LOG_ERR("Failed to get On-Demand Private Proxy state (err %d)", err);
940 		return BTP_STATUS_FAILED;
941 	}
942 
943 	LOG_DBG("On-Demand Private Proxy state: %u", val_rsp);
944 
945 	return BTP_STATUS_SUCCESS;
946 }
947 
od_priv_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)948 static uint8_t od_priv_proxy_set(const void *cmd, uint16_t cmd_len,
949 				 void *rsp, uint16_t *rsp_len)
950 {
951 	const struct btp_od_priv_proxy_set_cmd *cp = cmd;
952 	uint8_t val_rsp;
953 	int err;
954 
955 	LOG_DBG("");
956 
957 	err = bt_mesh_od_priv_proxy_cli_set(net.net_idx, cp->dst, cp->val, &val_rsp);
958 	if (err) {
959 		LOG_ERR("Failed to set On-Demand Private Proxy state (err %d)", err);
960 		return BTP_STATUS_FAILED;
961 	}
962 
963 	LOG_DBG("On-Demand Private Proxy set state: %u", val_rsp);
964 
965 	return BTP_STATUS_SUCCESS;
966 }
967 
968 #endif
969 
970 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
srpl_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)971 static uint8_t srpl_clear(const void *cmd, uint16_t cmd_len,
972 			  void *rsp, uint16_t *rsp_len)
973 {
974 	const struct btp_srpl_clear_cmd *cp = cmd;
975 	uint16_t app_idx = BT_MESH_KEY_UNUSED;
976 	uint16_t start_rsp;
977 	uint8_t len_rsp;
978 	int err;
979 
980 	/* Lookup source address */
981 	for (int i = 0; i < ARRAY_SIZE(model_bound); i++) {
982 		if (model_bound[i].model->id == BT_MESH_MODEL_ID_SOL_PDU_RPL_CLI) {
983 			app_idx = model_bound[i].appkey_idx;
984 			break;
985 		}
986 	}
987 
988 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_APP(app_idx, cp->dst);
989 
990 	if (cp->acked) {
991 		err = bt_mesh_sol_pdu_rpl_clear(&ctx, cp->range_start, cp->range_len, &start_rsp,
992 						&len_rsp);
993 	} else {
994 		err = bt_mesh_sol_pdu_rpl_clear_unack(&ctx, cp->range_start, cp->range_len);
995 	}
996 	if (err) {
997 		LOG_ERR("Failed to clear SRPL (err %d)", err);
998 		return BTP_STATUS_FAILED;
999 	}
1000 
1001 	return BTP_STATUS_SUCCESS;
1002 }
1003 #endif
1004 
1005 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
proxy_solicit(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1006 static uint8_t proxy_solicit(const void *cmd, uint16_t cmd_len,
1007 			     void *rsp, uint16_t *rsp_len)
1008 {
1009 	const struct btp_proxy_solicit_cmd *cp = cmd;
1010 	int err;
1011 
1012 	err = bt_mesh_proxy_solicit(cp->net_idx);
1013 	if (err) {
1014 		LOG_ERR("Failed to advertise solicitation PDU (err %d)", err);
1015 		return BTP_STATUS_FAILED;
1016 	}
1017 
1018 	return BTP_STATUS_SUCCESS;
1019 }
1020 #endif /* CONFIG_BT_MESH_PROXY_SOLICITATION */
1021 
1022 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1023 static struct bt_mesh_brg_cfg_cli brg_cfg_cli;
1024 #endif /* CONFIG_BT_MESH_BRG_CFG_CLI */
1025 
1026 static const struct bt_mesh_model primary_models[] = {
1027 	BT_MESH_MODEL_CFG_SRV,
1028 	BT_MESH_MODEL_CFG_CLI(&cfg_cli),
1029 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub, health_srv_meta),
1030 	BT_MESH_MODEL_HEALTH_CLI(&health_cli),
1031 #if defined(CONFIG_BT_MESH_SAR_CFG_SRV)
1032 	BT_MESH_MODEL_SAR_CFG_SRV,
1033 #endif
1034 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
1035 	BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
1036 #endif
1037 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
1038 	BT_MESH_MODEL_LARGE_COMP_DATA_SRV,
1039 #endif
1040 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
1041 	BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli),
1042 #endif
1043 #if defined(CONFIG_BT_MESH_OP_AGG_SRV)
1044 	BT_MESH_MODEL_OP_AGG_SRV,
1045 #endif
1046 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
1047 	BT_MESH_MODEL_OP_AGG_CLI,
1048 #endif
1049 #if defined(CONFIG_BT_MESH_RPR_CLI)
1050 	BT_MESH_MODEL_RPR_CLI(&rpr_cli),
1051 #endif
1052 #if defined(CONFIG_BT_MESH_RPR_SRV)
1053 	BT_MESH_MODEL_RPR_SRV,
1054 #endif
1055 #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV)
1056 	BT_MESH_MODEL_PRIV_BEACON_SRV,
1057 #endif
1058 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
1059 	BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
1060 #endif
1061 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
1062 	BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli),
1063 #endif
1064 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
1065 	BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli),
1066 #endif
1067 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
1068 	BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
1069 #endif
1070 #if defined(CONFIG_BT_MESH_BRG_CFG_SRV)
1071 	BT_MESH_MODEL_BRG_CFG_SRV,
1072 #endif
1073 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1074 	BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
1075 #endif
1076 
1077 };
1078 
1079 #if defined(CONFIG_BT_MESH_DFD_SRV)
1080 static const struct bt_mesh_model dfu_distributor_models[] = {BT_MESH_MODEL_DFD_SRV(&dfd_srv)};
1081 #endif
1082 
1083 #if defined(CONFIG_BT_MESH_DFU_SRV)
1084 static const struct bt_mesh_model dfu_target_models[] = {
1085 	BT_MESH_MODEL_DFU_SRV(&dfu_srv),
1086 };
1087 #endif
1088 
1089 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1090 static const struct bt_mesh_model blob_client_models[] = {
1091 	BT_MESH_MODEL_BLOB_CLI(&blob_cli),
1092 };
1093 #endif
1094 
1095 static const struct bt_mesh_model primary_models_alt[] = {
1096 	BT_MESH_MODEL_CFG_SRV,
1097 	BT_MESH_MODEL_CFG_CLI(&cfg_cli),
1098 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub, health_srv_meta_alt),
1099 	BT_MESH_MODEL_HEALTH_CLI(&health_cli),
1100 #if defined(CONFIG_BT_MESH_SAR_CFG_SRV)
1101 	BT_MESH_MODEL_SAR_CFG_SRV,
1102 #endif
1103 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
1104 	BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
1105 #endif
1106 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
1107 	BT_MESH_MODEL_LARGE_COMP_DATA_SRV,
1108 #endif
1109 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
1110 	BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli),
1111 #endif
1112 #if defined(CONFIG_BT_MESH_OP_AGG_SRV)
1113 	BT_MESH_MODEL_OP_AGG_SRV,
1114 #endif
1115 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
1116 	BT_MESH_MODEL_OP_AGG_CLI,
1117 #endif
1118 #if defined(CONFIG_BT_MESH_RPR_CLI)
1119 	BT_MESH_MODEL_RPR_CLI(&rpr_cli),
1120 #endif
1121 #if defined(CONFIG_BT_MESH_RPR_SRV)
1122 	BT_MESH_MODEL_RPR_SRV,
1123 #endif
1124 #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV)
1125 	BT_MESH_MODEL_PRIV_BEACON_SRV,
1126 #endif
1127 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
1128 	BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
1129 #endif
1130 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
1131 	BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&od_priv_proxy_cli),
1132 #endif
1133 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
1134 	BT_MESH_MODEL_SOL_PDU_RPL_CLI(&srpl_cli),
1135 #endif
1136 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
1137 	BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
1138 #endif
1139 #if defined(CONFIG_BT_MESH_BRG_CFG_SRV)
1140 	BT_MESH_MODEL_BRG_CFG_SRV,
1141 #endif
1142 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
1143 	BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
1144 #endif
1145 
1146 };
1147 
lookup_model_bound(uint16_t id)1148 struct model_data *lookup_model_bound(uint16_t id)
1149 {
1150 	int i;
1151 
1152 	for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
1153 		if (model_bound[i].model && model_bound[i].model->id == id) {
1154 			return &model_bound[i];
1155 		}
1156 	}
1157 
1158 	return NULL;
1159 }
1160 static const struct bt_mesh_model vnd_models[] = {
1161 	BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL,
1162 			  NULL),
1163 };
1164 
1165 static const struct bt_mesh_elem elements[] = {
1166 	BT_MESH_ELEM(0, primary_models, vnd_models),
1167 #if defined(CONFIG_BT_MESH_DFD_SRV)
1168 	BT_MESH_ELEM(0, dfu_distributor_models, BT_MESH_MODEL_NONE),
1169 #endif
1170 #if defined(CONFIG_BT_MESH_DFU_SRV)
1171 	BT_MESH_ELEM(0, dfu_target_models, BT_MESH_MODEL_NONE),
1172 #endif
1173 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1174 	BT_MESH_ELEM(0, blob_client_models, BT_MESH_MODEL_NONE),
1175 #endif
1176 };
1177 
1178 static const struct bt_mesh_elem elements_alt[] = {
1179 	BT_MESH_ELEM(0, primary_models_alt, vnd_models),
1180 #if defined(CONFIG_BT_MESH_DFD_SRV)
1181 	BT_MESH_ELEM(0, dfu_distributor_models, BT_MESH_MODEL_NONE),
1182 #endif
1183 #if defined(CONFIG_BT_MESH_DFU_SRV)
1184 	BT_MESH_ELEM(0, dfu_target_models, BT_MESH_MODEL_NONE),
1185 #endif
1186 #if defined(CONFIG_BT_MESH_BLOB_CLI)
1187 	BT_MESH_ELEM(0, blob_client_models, BT_MESH_MODEL_NONE),
1188 #endif
1189 };
1190 
link_open(bt_mesh_prov_bearer_t bearer)1191 static void link_open(bt_mesh_prov_bearer_t bearer)
1192 {
1193 	struct btp_mesh_prov_link_open_ev ev;
1194 
1195 	LOG_DBG("bearer 0x%02x", bearer);
1196 
1197 	switch (bearer) {
1198 	case BT_MESH_PROV_ADV:
1199 		ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV;
1200 		break;
1201 	case BT_MESH_PROV_GATT:
1202 		ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT;
1203 		break;
1204 	case BT_MESH_PROV_REMOTE:
1205 		ev.bearer = BTP_MESH_PROV_BEARER_REMOTE;
1206 		break;
1207 	default:
1208 		LOG_ERR("Invalid bearer");
1209 
1210 		return;
1211 	}
1212 
1213 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, &ev, sizeof(ev));
1214 }
1215 
link_close(bt_mesh_prov_bearer_t bearer)1216 static void link_close(bt_mesh_prov_bearer_t bearer)
1217 {
1218 	struct btp_mesh_prov_link_closed_ev ev;
1219 
1220 	LOG_DBG("bearer 0x%02x", bearer);
1221 
1222 	switch (bearer) {
1223 	case BT_MESH_PROV_ADV:
1224 		ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV;
1225 		break;
1226 	case BT_MESH_PROV_GATT:
1227 		ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT;
1228 		break;
1229 	case BT_MESH_PROV_REMOTE:
1230 		ev.bearer = BTP_MESH_PROV_BEARER_REMOTE;
1231 		break;
1232 	default:
1233 		LOG_ERR("Invalid bearer");
1234 
1235 		return;
1236 	}
1237 
1238 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, &ev, sizeof(ev));
1239 }
1240 
output_number(bt_mesh_output_action_t action,uint32_t number)1241 static int output_number(bt_mesh_output_action_t action, uint32_t number)
1242 {
1243 	struct btp_mesh_out_number_action_ev ev;
1244 
1245 	LOG_DBG("action 0x%04x number 0x%08x", action, number);
1246 
1247 	ev.action = sys_cpu_to_le16(action);
1248 	ev.number = sys_cpu_to_le32(number);
1249 
1250 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, &ev, sizeof(ev));
1251 
1252 	return 0;
1253 }
1254 
output_string(const char * str)1255 static int output_string(const char *str)
1256 {
1257 	struct btp_mesh_out_string_action_ev *ev;
1258 	struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
1259 
1260 	LOG_DBG("str %s", str);
1261 
1262 	net_buf_simple_init(buf, 0);
1263 
1264 	ev = net_buf_simple_add(buf, sizeof(*ev));
1265 	ev->string_len = strlen(str);
1266 
1267 	net_buf_simple_add_mem(buf, str, ev->string_len);
1268 
1269 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_STRING_ACTION,
1270 		    buf->data, buf->len);
1271 
1272 	return 0;
1273 }
1274 
input(bt_mesh_input_action_t action,uint8_t size)1275 static int input(bt_mesh_input_action_t action, uint8_t size)
1276 {
1277 	struct btp_mesh_in_action_ev ev;
1278 
1279 	LOG_DBG("action 0x%04x number 0x%02x", action, size);
1280 
1281 	input_size = size;
1282 
1283 	ev.action = sys_cpu_to_le16(action);
1284 	ev.size = size;
1285 
1286 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, &ev, sizeof(ev));
1287 
1288 	return 0;
1289 }
1290 
prov_complete(uint16_t net_idx,uint16_t addr)1291 static void prov_complete(uint16_t net_idx, uint16_t addr)
1292 {
1293 	LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr);
1294 
1295 	net.net_idx = net_idx,
1296 	net.local = addr;
1297 	net.dst = addr;
1298 
1299 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, NULL, 0);
1300 }
1301 
prov_node_added(uint16_t net_idx,uint8_t uuid[16],uint16_t addr,uint8_t num_elem)1302 static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
1303 			    uint8_t num_elem)
1304 {
1305 	struct btp_mesh_prov_node_added_ev ev;
1306 
1307 	LOG_DBG("net_idx 0x%04x addr 0x%04x num_elem %d", net_idx, addr,
1308 		num_elem);
1309 
1310 	ev.net_idx = net_idx;
1311 	ev.addr = addr;
1312 	ev.num_elems = num_elem;
1313 	memcpy(&ev.uuid, uuid, sizeof(ev.uuid));
1314 
1315 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_NODE_ADDED, &ev, sizeof(ev));
1316 }
1317 
prov_reset(void)1318 static void prov_reset(void)
1319 {
1320 	LOG_DBG("");
1321 
1322 	bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
1323 
1324 	if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
1325 		bt_mesh_prov_enable(BT_MESH_PROV_REMOTE);
1326 	}
1327 }
1328 
1329 static const struct bt_mesh_comp comp = {
1330 	.cid = CID_LOCAL,
1331 	.elem = elements,
1332 	.elem_count = ARRAY_SIZE(elements),
1333 	.vid = 1,
1334 };
1335 
1336 static const struct bt_mesh_comp comp_alt = {
1337 	.cid = CID_LOCAL,
1338 	.elem = elements_alt,
1339 	.elem_count = ARRAY_SIZE(elements_alt),
1340 	.vid = 2,
1341 };
1342 
1343 #if defined(CONFIG_BT_MESH_COMP_PAGE_2)
1344 static const uint8_t cmp2_elem_offset[1] = {0};
1345 
1346 static const struct bt_mesh_comp2_record comp_rec = {
1347 	.id = 0x1600,
1348 	.version.x = 1,
1349 	.version.y = 0,
1350 	.version.z = 0,
1351 	.elem_offset_cnt = 1,
1352 	.elem_offset = cmp2_elem_offset,
1353 	.data_len = 0
1354 };
1355 
1356 static const struct bt_mesh_comp2 comp_p2 = {.record_cnt = 1, .record = &comp_rec};
1357 #endif
1358 
1359 static struct bt_mesh_prov prov = {
1360 	.uuid = dev_uuid,
1361 	.static_val = static_auth,
1362 	.static_val_len = sizeof(static_auth),
1363 	.output_number = output_number,
1364 	.output_string = output_string,
1365 	.input = input,
1366 	.link_open = link_open,
1367 	.link_close = link_close,
1368 	.complete = prov_complete,
1369 	.node_added = prov_node_added,
1370 	.reset = prov_reset,
1371 	.uri = "Tester",
1372 };
1373 
config_prov(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1374 static uint8_t config_prov(const void *cmd, uint16_t cmd_len,
1375 			   void *rsp, uint16_t *rsp_len)
1376 {
1377 	const struct btp_mesh_config_provisioning_cmd *cp = cmd;
1378 	const struct btp_mesh_config_provisioning_cmd_v2 *cp2 = cmd;
1379 	int err = 0;
1380 
1381 	/* TODO consider fix BTP commands to avoid this */
1382 	if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) {
1383 		LOG_DBG("wrong cmd size");
1384 		return BTP_STATUS_FAILED;
1385 	}
1386 
1387 	LOG_DBG("");
1388 
1389 	static_auth_size = cp->static_auth_size;
1390 
1391 	if (static_auth_size > BTP_MESH_PROV_AUTH_MAX_LEN || static_auth_size == 0) {
1392 		LOG_DBG("wrong static auth length");
1393 		return BTP_STATUS_FAILED;
1394 	}
1395 
1396 	memcpy(dev_uuid, cp->uuid, sizeof(dev_uuid));
1397 	memcpy(static_auth, cp->static_auth, cp->static_auth_size);
1398 
1399 	prov.output_size = cp->out_size;
1400 	prov.output_actions = sys_le16_to_cpu(cp->out_actions);
1401 	prov.input_size = cp->in_size;
1402 	prov.input_actions = sys_le16_to_cpu(cp->in_actions);
1403 
1404 	if (cmd_len == sizeof(*cp2)) {
1405 		memcpy(pub_key, cp2->set_pub_key, sizeof(cp2->set_pub_key));
1406 		memcpy(priv_key, cp2->set_priv_key, sizeof(cp2->set_priv_key));
1407 		prov.public_key_be = pub_key;
1408 		prov.private_key_be = priv_key;
1409 	}
1410 
1411 	if (cp->auth_method == AUTH_METHOD_OUTPUT) {
1412 		err = bt_mesh_auth_method_set_output(prov.output_actions, prov.output_size);
1413 	} else if (cp->auth_method == AUTH_METHOD_INPUT) {
1414 		err = bt_mesh_auth_method_set_input(prov.input_actions, prov.input_size);
1415 	} else if (cp->auth_method == AUTH_METHOD_STATIC) {
1416 		err = bt_mesh_auth_method_set_static(static_auth, static_auth_size);
1417 	}
1418 
1419 	if (err) {
1420 		LOG_ERR("err %d", err);
1421 		return BTP_STATUS_FAILED;
1422 	}
1423 
1424 	return BTP_STATUS_SUCCESS;
1425 }
1426 
provision_node(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1427 static uint8_t provision_node(const void *cmd, uint16_t cmd_len,
1428 			      void *rsp, uint16_t *rsp_len)
1429 {
1430 	const struct btp_mesh_provision_node_cmd *cp = cmd;
1431 	const struct btp_mesh_provision_node_cmd_v2 *cp2 = cmd;
1432 	int err;
1433 
1434 	/* TODO consider fix BTP commands to avoid this */
1435 	if (cmd_len != sizeof(*cp) && cmd_len != (sizeof(*cp2))) {
1436 		return BTP_STATUS_FAILED;
1437 	}
1438 
1439 	LOG_DBG("");
1440 
1441 	memcpy(dev_key, cp->dev_key, sizeof(dev_key));
1442 	memcpy(net_key, cp->net_key, sizeof(net_key));
1443 
1444 	addr = sys_le16_to_cpu(cp->addr);
1445 	flags = cp->flags;
1446 	iv_index = sys_le32_to_cpu(cp->iv_index);
1447 	net_key_idx = sys_le16_to_cpu(cp->net_key_idx);
1448 
1449 	if (cmd_len == sizeof(*cp2)) {
1450 		memcpy(pub_key, cp2->pub_key, sizeof(pub_key));
1451 
1452 		err = bt_mesh_prov_remote_pub_key_set(pub_key);
1453 		if (err) {
1454 			LOG_ERR("err %d", err);
1455 			return BTP_STATUS_FAILED;
1456 		}
1457 	}
1458 #if defined(CONFIG_BT_MESH_PROVISIONER)
1459 	err = bt_mesh_cdb_create(net_key);
1460 	if (err) {
1461 		LOG_ERR("err %d", err);
1462 		return BTP_STATUS_FAILED;
1463 	}
1464 #endif
1465 	err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, addr,
1466 				dev_key);
1467 	if (err) {
1468 		LOG_ERR("err %d", err);
1469 		return BTP_STATUS_FAILED;
1470 	}
1471 
1472 	return BTP_STATUS_SUCCESS;
1473 }
1474 
provision_adv(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1475 static uint8_t provision_adv(const void *cmd, uint16_t cmd_len,
1476 			     void *rsp, uint16_t *rsp_len)
1477 {
1478 	const struct btp_mesh_provision_adv_cmd *cp = cmd;
1479 	int err;
1480 
1481 	LOG_DBG("");
1482 
1483 	err = bt_mesh_provision_adv(cp->uuid, sys_le16_to_cpu(cp->net_idx),
1484 				    sys_le16_to_cpu(cp->address),
1485 				    cp->attention_duration);
1486 	if (err) {
1487 		LOG_ERR("err %d", err);
1488 		return BTP_STATUS_FAILED;
1489 	}
1490 
1491 	return BTP_STATUS_SUCCESS;
1492 }
1493 
init(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1494 static uint8_t init(const void *cmd, uint16_t cmd_len,
1495 		    void *rsp, uint16_t *rsp_len)
1496 {
1497 	const struct btp_mesh_init_cmd *cp = cmd;
1498 	int err;
1499 
1500 	if (cp->comp == 0) {
1501 		LOG_WRN("Loading default comp data");
1502 		err = bt_mesh_init(&prov, &comp);
1503 	} else {
1504 		LOG_WRN("Loading alternative comp data");
1505 		err = bt_mesh_init(&prov, &comp_alt);
1506 	}
1507 
1508 	if (err) {
1509 		return BTP_STATUS_FAILED;
1510 	}
1511 
1512 	return BTP_STATUS_SUCCESS;
1513 }
1514 
start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1515 static uint8_t start(const void *cmd, uint16_t cmd_len,
1516 		     void *rsp, uint16_t *rsp_len)
1517 {
1518 	int err;
1519 
1520 	LOG_DBG("");
1521 
1522 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1523 		printk("Loading stored settings\n");
1524 		settings_load();
1525 	}
1526 
1527 	if (addr) {
1528 		err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index,
1529 					addr, dev_key);
1530 		if (err && err != -EALREADY) {
1531 			return BTP_STATUS_FAILED;
1532 		}
1533 	} else {
1534 		err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
1535 		if (err && err != -EALREADY) {
1536 			return BTP_STATUS_FAILED;
1537 		}
1538 	}
1539 
1540 	if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
1541 		err = bt_mesh_prov_enable(BT_MESH_PROV_REMOTE);
1542 		if (err) {
1543 			return BTP_STATUS_FAILED;
1544 		}
1545 	}
1546 
1547 	return BTP_STATUS_SUCCESS;
1548 }
1549 
reset(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1550 static uint8_t reset(const void *cmd, uint16_t cmd_len,
1551 		     void *rsp, uint16_t *rsp_len)
1552 {
1553 	LOG_DBG("");
1554 
1555 	bt_mesh_reset();
1556 
1557 	return BTP_STATUS_SUCCESS;
1558 }
1559 
input_number(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1560 static uint8_t input_number(const void *cmd, uint16_t cmd_len,
1561 			    void *rsp, uint16_t *rsp_len)
1562 {
1563 	const struct btp_mesh_input_number_cmd *cp = cmd;
1564 	uint32_t number;
1565 	int err;
1566 
1567 	number = sys_le32_to_cpu(cp->number);
1568 
1569 	LOG_DBG("number 0x%04x", number);
1570 
1571 	err = bt_mesh_input_number(number);
1572 	if (err) {
1573 		return BTP_STATUS_FAILED;
1574 	}
1575 
1576 	return BTP_STATUS_SUCCESS;
1577 }
1578 
input_string(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1579 static uint8_t input_string(const void *cmd, uint16_t cmd_len,
1580 			    void *rsp, uint16_t *rsp_len)
1581 {
1582 	const struct btp_mesh_input_string_cmd *cp = cmd;
1583 	uint8_t status = BTP_STATUS_SUCCESS;
1584 	int err;
1585 
1586 	LOG_DBG("");
1587 
1588 	if (cmd_len < sizeof(*cp) &&
1589 	    cmd_len != (sizeof(*cp) + cp->string_len)) {
1590 		return BTP_STATUS_FAILED;
1591 	}
1592 
1593 	/* for historical reasons this commands must send NULL terminated
1594 	 * string
1595 	 */
1596 	if (cp->string[cp->string_len] != '\0') {
1597 		return BTP_STATUS_FAILED;
1598 	}
1599 
1600 	if (strlen(cp->string) < input_size) {
1601 		LOG_ERR("Too short input (%u chars required)", input_size);
1602 		return BTP_STATUS_FAILED;
1603 	}
1604 
1605 	err = bt_mesh_input_string(cp->string);
1606 	if (err) {
1607 		status = BTP_STATUS_FAILED;
1608 	}
1609 
1610 	return BTP_STATUS_SUCCESS;
1611 }
1612 
ivu_test_mode(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1613 static uint8_t ivu_test_mode(const void *cmd, uint16_t cmd_len,
1614 			     void *rsp, uint16_t *rsp_len)
1615 {
1616 	const struct btp_mesh_ivu_test_mode_cmd *cp = cmd;
1617 
1618 	LOG_DBG("enable 0x%02x", cp->enable);
1619 
1620 	bt_mesh_iv_update_test(cp->enable ? true : false);
1621 
1622 	return BTP_STATUS_SUCCESS;
1623 }
1624 
ivu_toggle_state(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1625 static uint8_t ivu_toggle_state(const void *cmd, uint16_t cmd_len,
1626 				void *rsp, uint16_t *rsp_len)
1627 {
1628 	bool result;
1629 
1630 	LOG_DBG("");
1631 
1632 	result = bt_mesh_iv_update();
1633 	if (!result) {
1634 		LOG_ERR("Failed to toggle the IV Update state");
1635 		return BTP_STATUS_FAILED;
1636 	}
1637 
1638 	return BTP_STATUS_SUCCESS;
1639 }
1640 
1641 #if defined(CONFIG_BT_MESH_LOW_POWER)
lpn(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1642 static uint8_t lpn(const void *cmd, uint16_t cmd_len,
1643 		   void *rsp, uint16_t *rsp_len)
1644 {
1645 	const struct btp_mesh_lpn_set_cmd *cp = cmd;
1646 	int err;
1647 
1648 	LOG_DBG("enable 0x%02x", cp->enable);
1649 
1650 	err = bt_mesh_lpn_set(cp->enable ? true : false);
1651 	if (err) {
1652 		LOG_ERR("Failed to toggle LPN (err %d)", err);
1653 		return BTP_STATUS_FAILED;
1654 	}
1655 
1656 	return BTP_STATUS_SUCCESS;
1657 }
1658 
lpn_poll(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1659 static uint8_t lpn_poll(const void *cmd, uint16_t cmd_len,
1660 			void *rsp, uint16_t *rsp_len)
1661 {
1662 	int err;
1663 
1664 	LOG_DBG("");
1665 
1666 	err = bt_mesh_lpn_poll();
1667 	if (err) {
1668 		LOG_ERR("Failed to send poll msg (err %d)", err);
1669 	}
1670 
1671 	return BTP_STATUS_SUCCESS;
1672 }
1673 #endif /* CONFIG_BT_MESH_LOW_POWER */
1674 
net_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1675 static uint8_t net_send(const void *cmd, uint16_t cmd_len,
1676 			void *rsp, uint16_t *rsp_len)
1677 {
1678 	const struct btp_mesh_net_send_cmd *cp = cmd;
1679 	NET_BUF_SIMPLE_DEFINE(msg, UINT8_MAX);
1680 	int err;
1681 
1682 	if (cmd_len < sizeof(*cp) &&
1683 	    cmd_len != (sizeof(*cp) + cp->payload_len)) {
1684 		return BTP_STATUS_FAILED;
1685 	}
1686 
1687 	struct bt_mesh_msg_ctx ctx = {
1688 		.net_idx = net.net_idx,
1689 		.app_idx = vnd_app_key_idx,
1690 		.addr = sys_le16_to_cpu(cp->dst),
1691 		.send_ttl = cp->ttl,
1692 	};
1693 
1694 	if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) {
1695 		ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL);
1696 	}
1697 
1698 	LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl,
1699 		ctx.addr, cp->payload_len);
1700 
1701 	if (!bt_mesh_app_key_exists(vnd_app_key_idx)) {
1702 		(void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx,
1703 					  vnd_app_key);
1704 		vnd_models[0].keys[0] = vnd_app_key_idx;
1705 	}
1706 
1707 	net_buf_simple_add_mem(&msg, cp->payload, cp->payload_len);
1708 
1709 	err = bt_mesh_model_send(&vnd_models[0], &ctx, &msg, NULL, NULL);
1710 	if (err) {
1711 		LOG_ERR("Failed to send (err %d)", err);
1712 		return BTP_STATUS_FAILED;
1713 	}
1714 
1715 	return BTP_STATUS_SUCCESS;
1716 }
1717 
va_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1718 static uint8_t va_add(const void *cmd, uint16_t cmd_len,
1719 		      void *rsp, uint16_t *rsp_len)
1720 {
1721 	const struct btp_mesh_va_add_cmd *cp = cmd;
1722 	struct btp_mesh_va_add_rp *rp = rsp;
1723 	const struct bt_mesh_va *va;
1724 	int err;
1725 
1726 	err = bt_mesh_va_add(cp->label_uuid, &va);
1727 	if (err) {
1728 		LOG_ERR("Failed to add Label UUID (err %d)", err);
1729 		return BTP_STATUS_FAILED;
1730 	}
1731 
1732 	rp->addr = sys_cpu_to_le16(va->addr);
1733 	*rsp_len = sizeof(*rp);
1734 
1735 	return BTP_STATUS_SUCCESS;
1736 }
1737 
va_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1738 static uint8_t va_del(const void *cmd, uint16_t cmd_len,
1739 		      void *rsp, uint16_t *rsp_len)
1740 {
1741 	const struct btp_mesh_va_del_cmd *cp = cmd;
1742 	const struct bt_mesh_va *va;
1743 	int err;
1744 
1745 	va = bt_mesh_va_find(cp->label_uuid);
1746 	if (!va) {
1747 		LOG_ERR("Failed to find Label UUID");
1748 		return BTP_STATUS_FAILED;
1749 	}
1750 
1751 	err = bt_mesh_va_del(va->uuid);
1752 	if (err) {
1753 		LOG_ERR("Failed to delete Label UUID (err %d)", err);
1754 		return BTP_STATUS_FAILED;
1755 	}
1756 
1757 	return BTP_STATUS_SUCCESS;
1758 }
1759 
health_generate_faults(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1760 static uint8_t health_generate_faults(const void *cmd, uint16_t cmd_len,
1761 				      void *rsp, uint16_t *rsp_len)
1762 {
1763 	struct btp_mesh_health_generate_faults_rp *rp = rsp;
1764 	uint8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 };
1765 	uint8_t cur_faults_count;
1766 	uint8_t reg_faults_count;
1767 
1768 	cur_faults_count = MIN(sizeof(cur_faults), sizeof(some_faults));
1769 	memcpy(cur_faults, some_faults, cur_faults_count);
1770 	memcpy(rp->faults, cur_faults, cur_faults_count);
1771 	rp->cur_faults_count = cur_faults_count;
1772 
1773 	reg_faults_count = MIN(sizeof(reg_faults), sizeof(some_faults));
1774 	memcpy(reg_faults, some_faults, reg_faults_count);
1775 	memcpy(rp->faults + cur_faults_count, reg_faults, reg_faults_count);
1776 	rp->reg_faults_count = reg_faults_count;
1777 
1778 	bt_mesh_health_srv_fault_update(&elements[0]);
1779 
1780 	*rsp_len = sizeof(*rp) + cur_faults_count + reg_faults_count;
1781 
1782 	return BTP_STATUS_SUCCESS;
1783 }
1784 
health_clear_faults(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1785 static uint8_t health_clear_faults(const void *cmd, uint16_t cmd_len,
1786 				   void *rsp, uint16_t *rsp_len)
1787 {
1788 	LOG_DBG("");
1789 
1790 	(void)memset(cur_faults, 0, sizeof(cur_faults));
1791 	(void)memset(reg_faults, 0, sizeof(reg_faults));
1792 
1793 	bt_mesh_health_srv_fault_update(&elements[0]);
1794 
1795 	return BTP_STATUS_SUCCESS;
1796 }
1797 
model_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1798 static uint8_t model_send(const void *cmd, uint16_t cmd_len,
1799 			  void *rsp, uint16_t *rsp_len)
1800 {
1801 	const struct btp_mesh_model_send_cmd *cp = cmd;
1802 	NET_BUF_SIMPLE_DEFINE(msg, UINT8_MAX);
1803 	const struct bt_mesh_model *model = NULL;
1804 	uint16_t src;
1805 	int err;
1806 
1807 	if (cmd_len < sizeof(*cp) &&
1808 	    cmd_len != (sizeof(*cp) + cp->payload_len)) {
1809 		return BTP_STATUS_FAILED;
1810 	}
1811 
1812 	struct bt_mesh_msg_ctx ctx = {
1813 		.net_idx = net.net_idx,
1814 		.app_idx = BT_MESH_KEY_DEV,
1815 		.addr = sys_le16_to_cpu(cp->dst),
1816 		.send_ttl = cp->ttl,
1817 	};
1818 
1819 	if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) {
1820 		ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL);
1821 	}
1822 
1823 	src = sys_le16_to_cpu(cp->src);
1824 
1825 	/* Lookup source address */
1826 	for (int i = 0; i < ARRAY_SIZE(model_bound); i++) {
1827 		if (bt_mesh_model_elem(model_bound[i].model)->rt->addr == src) {
1828 			model = model_bound[i].model;
1829 			ctx.app_idx = model_bound[i].appkey_idx;
1830 
1831 			break;
1832 		}
1833 	}
1834 
1835 	if (!model) {
1836 		LOG_ERR("Model not found");
1837 		return BTP_STATUS_FAILED;
1838 	}
1839 
1840 	LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src,
1841 		ctx.addr, model, cp->payload_len);
1842 
1843 	net_buf_simple_add_mem(&msg, cp->payload, cp->payload_len);
1844 
1845 	err = bt_mesh_model_send(model, &ctx, &msg, NULL, NULL);
1846 	if (err) {
1847 		LOG_ERR("Failed to send (err %d)", err);
1848 		return BTP_STATUS_FAILED;
1849 	}
1850 
1851 	return BTP_STATUS_SUCCESS;
1852 }
1853 
1854 #if defined(CONFIG_BT_TESTING)
1855 #if defined(CONFIG_BT_MESH_LOW_POWER)
lpn_subscribe(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1856 static uint8_t lpn_subscribe(const void *cmd, uint16_t cmd_len,
1857 			     void *rsp, uint16_t *rsp_len)
1858 {
1859 	const struct btp_mesh_lpn_subscribe_cmd *cp = cmd;
1860 	uint16_t address = sys_le16_to_cpu(cp->address);
1861 	int err;
1862 
1863 	LOG_DBG("address 0x%04x", address);
1864 
1865 	err = bt_mesh_test_lpn_group_add(address);
1866 	if (err) {
1867 		LOG_ERR("Failed to subscribe (err %d)", err);
1868 		return BTP_STATUS_FAILED;
1869 	}
1870 
1871 	return BTP_STATUS_SUCCESS;
1872 }
1873 
lpn_unsubscribe(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1874 static uint8_t lpn_unsubscribe(const void *cmd, uint16_t cmd_len,
1875 			       void *rsp, uint16_t *rsp_len)
1876 {
1877 	const struct btp_mesh_lpn_unsubscribe_cmd *cp = cmd;
1878 	uint16_t address = sys_le16_to_cpu(cp->address);
1879 	int err;
1880 
1881 	LOG_DBG("address 0x%04x", address);
1882 
1883 	err = bt_mesh_test_lpn_group_remove(&address, 1);
1884 	if (err) {
1885 		LOG_ERR("Failed to unsubscribe (err %d)", err);
1886 		return BTP_STATUS_FAILED;
1887 	}
1888 
1889 	return BTP_STATUS_SUCCESS;
1890 }
1891 #endif /* CONFIG_BT_MESH_LOW_POWER */
1892 
rpl_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1893 static uint8_t rpl_clear(const void *cmd, uint16_t cmd_len,
1894 			 void *rsp, uint16_t *rsp_len)
1895 {
1896 	int err;
1897 
1898 	LOG_DBG("");
1899 
1900 	err = bt_mesh_test_rpl_clear();
1901 	if (err) {
1902 		LOG_ERR("Failed to clear RPL (err %d)", err);
1903 		return BTP_STATUS_FAILED;
1904 	}
1905 
1906 	return BTP_STATUS_SUCCESS;
1907 }
1908 #endif /* CONFIG_BT_TESTING */
1909 
proxy_identity_enable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1910 static uint8_t proxy_identity_enable(const void *cmd, uint16_t cmd_len,
1911 				     void *rsp, uint16_t *rsp_len)
1912 {
1913 	int err;
1914 
1915 	LOG_DBG("");
1916 
1917 	err = bt_mesh_proxy_identity_enable();
1918 	if (err) {
1919 		LOG_ERR("Failed to enable proxy identity (err %d)", err);
1920 		return BTP_STATUS_FAILED;
1921 	}
1922 
1923 	return BTP_STATUS_SUCCESS;
1924 }
1925 
1926 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
proxy_connect(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1927 static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len,
1928 			     void *rsp, uint16_t *rsp_len)
1929 {
1930 	const struct btp_proxy_connect_cmd *cp = cmd;
1931 	int err;
1932 
1933 	err = bt_mesh_proxy_connect(cp->net_idx);
1934 	if (err) {
1935 		LOG_ERR("Failed to connect to GATT Proxy (err %d)", err);
1936 		return BTP_STATUS_FAILED;
1937 	}
1938 
1939 	return BTP_STATUS_SUCCESS;
1940 }
1941 #endif
1942 
1943 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
sar_transmitter_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1944 static uint8_t sar_transmitter_get(const void *cmd, uint16_t cmd_len,
1945 				   void *rsp, uint16_t *rsp_len)
1946 {
1947 	const struct btp_mesh_sar_transmitter_get_cmd *cp = cmd;
1948 	struct bt_mesh_sar_tx tx_rsp;
1949 	int err;
1950 
1951 	LOG_DBG("");
1952 
1953 	bt_mesh_sar_cfg_cli_timeout_set(5000);
1954 
1955 	err = bt_mesh_sar_cfg_cli_transmitter_get(
1956 		net_key_idx, sys_le16_to_cpu(cp->dst), &tx_rsp);
1957 	if (err) {
1958 		LOG_ERR("err=%d", err);
1959 		return BTP_STATUS_FAILED;
1960 	}
1961 
1962 	return BTP_STATUS_SUCCESS;
1963 }
1964 
sar_transmitter_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1965 static uint8_t sar_transmitter_set(const void *cmd, uint16_t cmd_len,
1966 				   void *rsp, uint16_t *rsp_len)
1967 {
1968 	const struct btp_mesh_sar_transmitter_set_cmd *cp = cmd;
1969 	struct bt_mesh_sar_tx set, tx_rsp;
1970 	int err;
1971 
1972 	LOG_DBG("");
1973 
1974 	bt_mesh_sar_cfg_cli_timeout_set(5000);
1975 
1976 	set.seg_int_step = cp->tx.seg_int_step;
1977 	set.unicast_retrans_count = cp->tx.unicast_retrans_count;
1978 	set.unicast_retrans_int_inc = cp->tx.unicast_retrans_int_inc;
1979 	set.unicast_retrans_int_step = cp->tx.unicast_retrans_int_step;
1980 	set.unicast_retrans_without_prog_count =
1981 		cp->tx.unicast_retrans_without_prog_count;
1982 	set.multicast_retrans_count = cp->tx.multicast_retrans_count;
1983 	set.multicast_retrans_int = cp->tx.multicast_retrans_int;
1984 
1985 	err = bt_mesh_sar_cfg_cli_transmitter_set(net_key_idx,
1986 						  sys_le16_to_cpu(cp->dst),
1987 						  &set, &tx_rsp);
1988 	if (err) {
1989 		LOG_ERR("err=%d", err);
1990 		return BTP_STATUS_FAILED;
1991 	}
1992 
1993 	return BTP_STATUS_SUCCESS;
1994 }
1995 
sar_receiver_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1996 static uint8_t sar_receiver_get(const void *cmd, uint16_t cmd_len,
1997 				void *rsp, uint16_t *rsp_len)
1998 {
1999 	const struct btp_mesh_sar_receiver_get_cmd *cp = cmd;
2000 	struct bt_mesh_sar_rx rx_rsp;
2001 	int err;
2002 
2003 	LOG_DBG("");
2004 
2005 	err = bt_mesh_sar_cfg_cli_receiver_get(net_key_idx,
2006 					       sys_le16_to_cpu(cp->dst), &rx_rsp);
2007 	if (err) {
2008 		LOG_ERR("err=%d", err);
2009 		return BTP_STATUS_FAILED;
2010 	}
2011 
2012 	return BTP_STATUS_SUCCESS;
2013 }
2014 
sar_receiver_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2015 static uint8_t sar_receiver_set(const void *cmd, uint16_t cmd_len,
2016 				void *rsp, uint16_t *rsp_len)
2017 {
2018 	const struct btp_mesh_sar_receiver_set_cmd *cp = cmd;
2019 	struct bt_mesh_sar_rx set, rx_rsp;
2020 	int err;
2021 
2022 	LOG_DBG("");
2023 
2024 	set.ack_delay_inc = cp->rx.ack_delay_inc;
2025 	set.ack_retrans_count = cp->rx.ack_retrans_count;
2026 	set.discard_timeout = cp->rx.discard_timeout;
2027 	set.seg_thresh = cp->rx.seg_thresh;
2028 	set.rx_seg_int_step = cp->rx.rx_seg_int_step;
2029 
2030 	err = bt_mesh_sar_cfg_cli_receiver_set(net_key_idx,
2031 					       sys_le16_to_cpu(cp->dst), &set,
2032 					       &rx_rsp);
2033 	if (err) {
2034 		LOG_ERR("err=%d", err);
2035 		return BTP_STATUS_FAILED;
2036 	}
2037 
2038 	return BTP_STATUS_SUCCESS;
2039 }
2040 #endif
2041 
2042 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
large_comp_data_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2043 static uint8_t large_comp_data_get(const void *cmd, uint16_t cmd_len,
2044 				   void *rsp, uint16_t *rsp_len)
2045 {
2046 	const struct btp_mesh_large_comp_data_get_cmd *cp = cmd;
2047 	struct btp_mesh_large_comp_data_get_rp *rp = rsp;
2048 	int err;
2049 
2050 	NET_BUF_SIMPLE_DEFINE(data, 500);
2051 	net_buf_simple_init(&data, 0);
2052 
2053 	struct bt_mesh_large_comp_data_rsp comp = {
2054 		.data = &data,
2055 	};
2056 
2057 	err = bt_mesh_large_comp_data_get(sys_le16_to_cpu(cp->net_idx),
2058 				    sys_le16_to_cpu(cp->addr), cp->page,
2059 				    sys_le16_to_cpu(cp->offset), &comp);
2060 	if (err) {
2061 		LOG_ERR("Large Composition Data Get failed (err %d)", err);
2062 
2063 		return BTP_STATUS_FAILED;
2064 	}
2065 
2066 	memcpy(rp->data, comp.data->data, comp.data->len);
2067 	*rsp_len = comp.data->len;
2068 
2069 	return BTP_STATUS_SUCCESS;
2070 }
2071 
models_metadata_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2072 static uint8_t models_metadata_get(const void *cmd, uint16_t cmd_len,
2073 				   void *rsp, uint16_t *rsp_len)
2074 {
2075 	const struct btp_mesh_models_metadata_get_cmd *cp = cmd;
2076 	struct btp_mesh_models_metadata_get_rp *rp = rsp;
2077 	int err;
2078 
2079 	NET_BUF_SIMPLE_DEFINE(data, 500);
2080 	net_buf_simple_init(&data, 0);
2081 
2082 	struct bt_mesh_large_comp_data_rsp metadata = {
2083 		.data = &data,
2084 	};
2085 
2086 	err = bt_mesh_models_metadata_get(sys_le16_to_cpu(cp->net_idx),
2087 					  sys_le16_to_cpu(cp->addr), cp->page,
2088 					  sys_le16_to_cpu(cp->offset), &metadata);
2089 
2090 	if (err) {
2091 		LOG_ERR("Models Metadata Get failed (err %d)", err);
2092 		return BTP_STATUS_FAILED;
2093 	}
2094 
2095 	memcpy(rp->data, metadata.data->data, metadata.data->len);
2096 	*rsp_len = metadata.data->len;
2097 
2098 	return BTP_STATUS_SUCCESS;
2099 }
2100 #endif
2101 
2102 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
subnet_bridge_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2103 static uint8_t subnet_bridge_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2104 {
2105 	const struct btp_mesh_subnet_bridge_get_cmd *cp = cmd;
2106 	enum bt_mesh_brg_cfg_state state;
2107 	int err;
2108 
2109 	err = bt_mesh_brg_cfg_cli_get(net.net_idx, sys_le16_to_cpu(cp->addr), &state);
2110 	if (err) {
2111 		LOG_ERR("err=%d", err);
2112 		return BTP_STATUS_FAILED;
2113 	}
2114 
2115 	LOG_DBG("Subnet Bridge state: %u", state);
2116 
2117 	return BTP_STATUS_SUCCESS;
2118 }
2119 
subnet_bridge_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2120 static uint8_t subnet_bridge_set(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2121 {
2122 	const struct btp_mesh_subnet_bridge_set_cmd *cp = cmd;
2123 	enum bt_mesh_brg_cfg_state state;
2124 	int err;
2125 
2126 	state = cp->val;
2127 
2128 	err = bt_mesh_brg_cfg_cli_set(net.net_idx, sys_le16_to_cpu(cp->addr), state, &state);
2129 	if (err) {
2130 		LOG_ERR("err=%d", err);
2131 		return BTP_STATUS_FAILED;
2132 	}
2133 
2134 	LOG_DBG("Subnet Bridge state: %u", state);
2135 
2136 	return BTP_STATUS_SUCCESS;
2137 }
2138 
bridging_table_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2139 static uint8_t bridging_table_add(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2140 {
2141 	const struct btp_mesh_bridging_table_add_cmd *cp = cmd;
2142 	struct bt_mesh_brg_cfg_table_entry entry;
2143 	struct bt_mesh_brg_cfg_table_status rp;
2144 	int err;
2145 
2146 	LOG_DBG("");
2147 
2148 	entry.directions = cp->directions;
2149 	entry.net_idx1 = sys_le16_to_cpu(cp->net_idx1);
2150 	entry.net_idx2 = sys_le16_to_cpu(cp->net_idx2);
2151 	entry.addr1 = sys_le16_to_cpu(cp->addr1);
2152 	entry.addr2 = sys_le16_to_cpu(cp->addr2);
2153 
2154 	err = bt_mesh_brg_cfg_cli_table_add(net_key_idx, sys_le16_to_cpu(cp->addr), &entry, &rp);
2155 	if (err) {
2156 		LOG_ERR("err=%d", err);
2157 		return BTP_STATUS_FAILED;
2158 	}
2159 
2160 	return BTP_STATUS_SUCCESS;
2161 }
2162 
bridging_table_remove(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2163 static uint8_t bridging_table_remove(const void *cmd, uint16_t cmd_len, void *rsp,
2164 				     uint16_t *rsp_len)
2165 {
2166 	const struct btp_mesh_bridging_table_remove_cmd *cp = cmd;
2167 	struct bt_mesh_brg_cfg_table_status rp;
2168 	int err;
2169 
2170 	LOG_DBG("");
2171 
2172 	err = bt_mesh_brg_cfg_cli_table_remove(
2173 		net_key_idx, sys_le16_to_cpu(cp->addr), sys_le16_to_cpu(cp->net_idx1),
2174 		sys_le16_to_cpu(cp->net_idx2), sys_le16_to_cpu(cp->addr1),
2175 		sys_le16_to_cpu(cp->addr2), &rp);
2176 
2177 	if (err) {
2178 		LOG_ERR("err=%d", err);
2179 		return BTP_STATUS_FAILED;
2180 	}
2181 
2182 	return BTP_STATUS_SUCCESS;
2183 }
2184 
bridged_subnets_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2185 static uint8_t bridged_subnets_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2186 {
2187 	const struct btp_mesh_bridged_subnets_get_cmd *cp = cmd;
2188 	struct bt_mesh_brg_cfg_filter_netkey filter_net_idx;
2189 	struct bt_mesh_brg_cfg_subnets_list rp;
2190 	int err;
2191 
2192 	LOG_DBG("");
2193 
2194 	/* Initialize list ptr to NULL to prevent the client copying response to whatever was
2195 	 * on the stack where `rp` was allocated.
2196 	 */
2197 	rp.list = NULL;
2198 
2199 	filter_net_idx.filter = cp->filter;
2200 	filter_net_idx.net_idx = sys_le16_to_cpu(cp->net_idx);
2201 
2202 	err = bt_mesh_brg_cfg_cli_subnets_get(net_key_idx, sys_le16_to_cpu(cp->addr),
2203 					      filter_net_idx, cp->start_idx, &rp);
2204 	if (err) {
2205 		LOG_ERR("err=%d", err);
2206 		return BTP_STATUS_FAILED;
2207 	}
2208 
2209 	return BTP_STATUS_SUCCESS;
2210 }
2211 
bridging_table_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2212 static uint8_t bridging_table_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2213 {
2214 	const struct btp_mesh_bridging_table_get_cmd *cp = cmd;
2215 	struct bt_mesh_brg_cfg_table_list rp;
2216 	int err;
2217 
2218 	LOG_DBG("");
2219 
2220 	/* Initialize list ptr to NULL to prevent the client copying response to whatever was
2221 	 * on the stack where `rp` was allocated.
2222 	 */
2223 	rp.list = NULL;
2224 
2225 	err = bt_mesh_brg_cfg_cli_table_get(
2226 		net_key_idx, sys_le16_to_cpu(cp->addr), sys_le16_to_cpu(cp->net_idx1),
2227 		sys_le16_to_cpu(cp->net_idx2), sys_le16_to_cpu(cp->start_idx), &rp);
2228 	if (err) {
2229 		LOG_ERR("err=%d", err);
2230 		return BTP_STATUS_FAILED;
2231 	}
2232 
2233 	return BTP_STATUS_SUCCESS;
2234 }
2235 
bridging_table_size_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2236 static uint8_t bridging_table_size_get(const void *cmd, uint16_t cmd_len, void *rsp,
2237 				       uint16_t *rsp_len)
2238 {
2239 	const struct btp_mesh_bridging_table_size_get_cmd *cp = cmd;
2240 	uint16_t size;
2241 	int err;
2242 
2243 	LOG_DBG("");
2244 
2245 	err = bt_mesh_brg_cfg_cli_table_size_get(net_key_idx, sys_le16_to_cpu(cp->addr), &size);
2246 	if (err) {
2247 		LOG_ERR("err=%d", err);
2248 		return BTP_STATUS_FAILED;
2249 	}
2250 
2251 	return BTP_STATUS_SUCCESS;
2252 }
2253 
2254 #endif
2255 
composition_data_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2256 static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
2257 {
2258 	const struct btp_mesh_comp_data_get_cmd *cp = cmd;
2259 	struct btp_mesh_comp_data_get_rp *rp = rsp;
2260 	uint8_t page;
2261 	struct net_buf_simple *comp = NET_BUF_SIMPLE(128);
2262 	int err;
2263 
2264 	LOG_DBG("");
2265 
2266 	bt_mesh_cfg_cli_timeout_set(10 * MSEC_PER_SEC);
2267 
2268 	net_buf_simple_init(comp, 0);
2269 
2270 	err = bt_mesh_cfg_cli_comp_data_get(sys_le16_to_cpu(cp->net_idx),
2271 					    sys_le16_to_cpu(cp->address),
2272 					    cp->page, &page, comp);
2273 	if (err) {
2274 		LOG_ERR("err %d", err);
2275 		return BTP_STATUS_FAILED;
2276 	}
2277 
2278 	rp->data[0] = page;
2279 	memcpy(rp->data + 1, comp->data, comp->len);
2280 	*rsp_len = comp->len + 1;
2281 
2282 	return BTP_STATUS_SUCCESS;
2283 }
2284 
change_prepare(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2285 static uint8_t change_prepare(const void *cmd, uint16_t cmd_len,
2286 			      void *rsp, uint16_t *rsp_len)
2287 {
2288 	int err;
2289 
2290 	LOG_DBG("");
2291 
2292 	err = bt_mesh_comp_change_prepare();
2293 	if (err < 0) {
2294 		return BTP_STATUS_FAILED;
2295 	}
2296 
2297 #if CONFIG_BT_MESH_LARGE_COMP_DATA_SRV
2298 	err = bt_mesh_models_metadata_change_prepare();
2299 	if (err < 0) {
2300 		return BTP_STATUS_FAILED;
2301 	}
2302 #endif
2303 
2304 	return BTP_STATUS_SUCCESS;
2305 }
2306 
config_krp_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2307 static uint8_t config_krp_get(const void *cmd, uint16_t cmd_len,
2308 			      void *rsp, uint16_t *rsp_len)
2309 {
2310 	const struct btp_mesh_cfg_krp_get_cmd *cp = cmd;
2311 	struct btp_mesh_cfg_krp_get_rp *rp = rsp;
2312 	uint8_t status;
2313 	uint8_t phase;
2314 	int err;
2315 
2316 	LOG_DBG("");
2317 
2318 	err = bt_mesh_cfg_cli_krp_get(sys_le16_to_cpu(cp->net_idx),
2319 				      sys_le16_to_cpu(cp->address),
2320 				      sys_le16_to_cpu(cp->key_net_idx),
2321 				      &status, &phase);
2322 
2323 	if (err) {
2324 		LOG_ERR("err %d", err);
2325 		return BTP_STATUS_FAILED;
2326 	}
2327 
2328 	rp->status = status;
2329 	rp->phase = phase;
2330 
2331 	*rsp_len = sizeof(*rp);
2332 
2333 	return BTP_STATUS_SUCCESS;
2334 }
2335 
config_krp_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2336 static uint8_t config_krp_set(const void *cmd, uint16_t cmd_len,
2337 			      void *rsp, uint16_t *rsp_len)
2338 {
2339 	const struct btp_mesh_cfg_krp_set_cmd *cp = cmd;
2340 	struct btp_mesh_cfg_krp_set_rp *rp = rsp;
2341 	uint8_t status;
2342 	uint8_t phase;
2343 	int err;
2344 
2345 	LOG_DBG("");
2346 
2347 	err = bt_mesh_cfg_cli_krp_set(sys_le16_to_cpu(cp->net_idx),
2348 				      sys_le16_to_cpu(cp->address),
2349 				      sys_le16_to_cpu(cp->key_net_idx),
2350 				      cp->transition, &status, &phase);
2351 	if (err) {
2352 		LOG_ERR("err %d", err);
2353 		return BTP_STATUS_FAILED;
2354 	}
2355 
2356 	rp->status = status;
2357 	rp->phase = phase;
2358 
2359 	*rsp_len = sizeof(*rp);
2360 
2361 	return BTP_STATUS_SUCCESS;
2362 }
2363 
config_beacon_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2364 static uint8_t config_beacon_get(const void *cmd, uint16_t cmd_len,
2365 				 void *rsp, uint16_t *rsp_len)
2366 {
2367 	const struct btp_mesh_cfg_beacon_get_cmd *cp = cmd;
2368 	struct btp_mesh_cfg_beacon_get_rp *rp = rsp;
2369 	uint8_t status;
2370 	int err;
2371 
2372 	LOG_DBG("");
2373 
2374 	err = bt_mesh_cfg_cli_beacon_get(sys_le16_to_cpu(cp->net_idx),
2375 					 sys_le16_to_cpu(cp->address), &status);
2376 	if (err) {
2377 		LOG_ERR("err %d", err);
2378 		return BTP_STATUS_FAILED;
2379 	}
2380 
2381 	rp->status = status;
2382 	*rsp_len = sizeof(*rp);
2383 
2384 	return BTP_STATUS_SUCCESS;
2385 }
2386 
config_beacon_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2387 static uint8_t config_beacon_set(const void *cmd, uint16_t cmd_len,
2388 				 void *rsp, uint16_t *rsp_len)
2389 {
2390 	const struct btp_mesh_cfg_beacon_set_cmd *cp = cmd;
2391 	struct btp_mesh_cfg_beacon_set_rp *rp = rsp;
2392 	uint8_t status;
2393 	int err;
2394 
2395 	LOG_DBG("");
2396 
2397 	err = bt_mesh_cfg_cli_beacon_set(sys_le16_to_cpu(cp->net_idx),
2398 					 sys_le16_to_cpu(cp->address), cp->val,
2399 					 &status);
2400 	if (err) {
2401 		LOG_ERR("err %d", err);
2402 		return BTP_STATUS_FAILED;
2403 	}
2404 
2405 	rp->status = status;
2406 	*rsp_len = sizeof(*rp);
2407 
2408 	return BTP_STATUS_SUCCESS;
2409 }
2410 
config_default_ttl_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2411 static uint8_t config_default_ttl_get(const void *cmd, uint16_t cmd_len,
2412 				      void *rsp, uint16_t *rsp_len)
2413 {
2414 	const struct btp_mesh_cfg_default_ttl_get_cmd *cp = cmd;
2415 	struct btp_mesh_cfg_default_ttl_get_rp *rp = rsp;
2416 	uint8_t status;
2417 	int err;
2418 
2419 	LOG_DBG("");
2420 
2421 	err = bt_mesh_cfg_cli_ttl_get(sys_le16_to_cpu(cp->net_idx),
2422 				      sys_le16_to_cpu(cp->address), &status);
2423 
2424 	if (err) {
2425 		LOG_ERR("err %d", err);
2426 		return BTP_STATUS_FAILED;
2427 	}
2428 
2429 	rp->status = status;
2430 	*rsp_len = sizeof(*rp);
2431 
2432 	return BTP_STATUS_SUCCESS;
2433 }
2434 
config_default_ttl_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2435 static uint8_t config_default_ttl_set(const void *cmd, uint16_t cmd_len,
2436 				      void *rsp, uint16_t *rsp_len)
2437 {
2438 	const struct btp_mesh_cfg_default_ttl_set_cmd *cp = cmd;
2439 	struct btp_mesh_cfg_default_ttl_set_rp *rp = rsp;
2440 	uint8_t status;
2441 	int err;
2442 
2443 	LOG_DBG("");
2444 
2445 	err = bt_mesh_cfg_cli_ttl_set(sys_le16_to_cpu(cp->net_idx),
2446 				      sys_le16_to_cpu(cp->address), cp->val,
2447 				      &status);
2448 
2449 	if (err) {
2450 		LOG_ERR("err %d", err);
2451 		return BTP_STATUS_FAILED;
2452 	}
2453 
2454 	rp->status = status;
2455 	*rsp_len = sizeof(*rp);
2456 
2457 	return BTP_STATUS_SUCCESS;
2458 }
2459 
config_gatt_proxy_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2460 static uint8_t config_gatt_proxy_get(const void *cmd, uint16_t cmd_len,
2461 				     void *rsp, uint16_t *rsp_len)
2462 {
2463 	const struct btp_mesh_cfg_gatt_proxy_get_cmd *cp = cmd;
2464 	struct btp_mesh_cfg_gatt_proxy_get_rp *rp = rsp;
2465 	uint8_t status;
2466 	int err;
2467 
2468 	LOG_DBG("");
2469 
2470 	err = bt_mesh_cfg_cli_gatt_proxy_get(sys_le16_to_cpu(cp->net_idx),
2471 					     sys_le16_to_cpu(cp->address),
2472 					     &status);
2473 	if (err) {
2474 		LOG_ERR("err %d", err);
2475 		return BTP_STATUS_FAILED;
2476 	}
2477 
2478 	rp->status = status;
2479 	*rsp_len = sizeof(*rp);
2480 
2481 	return BTP_STATUS_SUCCESS;
2482 }
2483 
config_gatt_proxy_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2484 static uint8_t config_gatt_proxy_set(const void *cmd, uint16_t cmd_len,
2485 				     void *rsp, uint16_t *rsp_len)
2486 {
2487 	const struct btp_mesh_cfg_gatt_proxy_set_cmd *cp = cmd;
2488 	struct btp_mesh_cfg_gatt_proxy_set_rp *rp = rsp;
2489 	uint8_t status;
2490 	int err;
2491 
2492 	LOG_DBG("");
2493 
2494 	err = bt_mesh_cfg_cli_gatt_proxy_set(sys_le16_to_cpu(cp->net_idx),
2495 					     sys_le16_to_cpu(cp->address),
2496 					     cp->val, &status);
2497 	if (err) {
2498 		LOG_ERR("err %d", err);
2499 		return BTP_STATUS_FAILED;
2500 	}
2501 
2502 	rp->status = status;
2503 	*rsp_len = sizeof(*rp);
2504 
2505 	return BTP_STATUS_SUCCESS;
2506 }
2507 
config_friend_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2508 static uint8_t config_friend_get(const void *cmd, uint16_t cmd_len,
2509 				 void *rsp, uint16_t *rsp_len)
2510 {
2511 	const struct btp_mesh_cfg_friend_get_cmd *cp = cmd;
2512 	struct btp_mesh_cfg_friend_get_rp *rp = rsp;
2513 	uint8_t status;
2514 	int err;
2515 
2516 	LOG_DBG("");
2517 
2518 	err = bt_mesh_cfg_cli_friend_get(sys_le16_to_cpu(cp->net_idx),
2519 					 sys_le16_to_cpu(cp->address),
2520 					 &status);
2521 
2522 	if (err) {
2523 		LOG_ERR("err %d", err);
2524 		return BTP_STATUS_FAILED;
2525 	}
2526 
2527 	rp->status = status;
2528 	*rsp_len = sizeof(*rp);
2529 
2530 	return BTP_STATUS_SUCCESS;
2531 }
2532 
config_friend_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2533 static uint8_t config_friend_set(const void *cmd, uint16_t cmd_len,
2534 				 void *rsp, uint16_t *rsp_len)
2535 {
2536 	const struct btp_mesh_cfg_friend_set_cmd *cp = cmd;
2537 	struct btp_mesh_cfg_friend_set_rp *rp = rsp;
2538 	uint8_t status;
2539 	int err;
2540 
2541 	LOG_DBG("");
2542 
2543 	err = bt_mesh_cfg_cli_friend_set(sys_le16_to_cpu(cp->net_idx),
2544 					 sys_le16_to_cpu(cp->address),
2545 					 cp->val, &status);
2546 
2547 	if (err) {
2548 		LOG_ERR("err %d", err);
2549 		return BTP_STATUS_FAILED;
2550 	}
2551 
2552 	rp->status = status;
2553 	*rsp_len = sizeof(*rp);
2554 
2555 	return BTP_STATUS_SUCCESS;
2556 }
2557 
config_relay_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2558 static uint8_t config_relay_get(const void *cmd, uint16_t cmd_len,
2559 				void *rsp, uint16_t *rsp_len)
2560 {
2561 	const struct btp_mesh_cfg_relay_get_cmd *cp = cmd;
2562 	struct btp_mesh_cfg_relay_get_rp *rp = rsp;
2563 	uint8_t status;
2564 	uint8_t transmit;
2565 	int err;
2566 
2567 	LOG_DBG("");
2568 
2569 	err = bt_mesh_cfg_cli_relay_get(sys_le16_to_cpu(cp->net_idx),
2570 					sys_le16_to_cpu(cp->address), &status,
2571 					&transmit);
2572 
2573 	if (err) {
2574 		LOG_ERR("err %d", err);
2575 		return BTP_STATUS_FAILED;
2576 	}
2577 
2578 	rp->status = status;
2579 	*rsp_len = sizeof(*rp);
2580 
2581 	return BTP_STATUS_SUCCESS;
2582 }
2583 
config_relay_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2584 static uint8_t config_relay_set(const void *cmd, uint16_t cmd_len,
2585 				void *rsp, uint16_t *rsp_len)
2586 {
2587 	const struct btp_mesh_cfg_relay_set_cmd *cp = cmd;
2588 	struct btp_mesh_cfg_relay_set_rp *rp = rsp;
2589 	uint8_t status;
2590 	uint8_t transmit;
2591 	int err;
2592 
2593 	LOG_DBG("");
2594 
2595 	err = bt_mesh_cfg_cli_relay_set(sys_le16_to_cpu(cp->net_idx),
2596 					sys_le16_to_cpu(cp->address),
2597 					cp->new_relay, cp->new_transmit,
2598 					&status, &transmit);
2599 
2600 	if (err) {
2601 		LOG_ERR("err %d", err);
2602 		return BTP_STATUS_FAILED;
2603 	}
2604 
2605 	rp->status = status;
2606 	*rsp_len = sizeof(*rp);
2607 
2608 	return BTP_STATUS_SUCCESS;
2609 }
2610 
config_mod_pub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2611 static uint8_t config_mod_pub_get(const void *cmd, uint16_t cmd_len,
2612 				  void *rsp, uint16_t *rsp_len)
2613 {
2614 	const struct btp_mesh_cfg_model_pub_get_cmd *cp = cmd;
2615 	struct btp_mesh_cfg_model_pub_get_rp *rp = rsp;
2616 	struct bt_mesh_cfg_cli_mod_pub pub;
2617 	uint8_t status;
2618 	int err;
2619 
2620 	LOG_DBG("");
2621 
2622 	err = bt_mesh_cfg_cli_mod_pub_get(sys_le16_to_cpu(cp->net_idx),
2623 					  sys_le16_to_cpu(cp->address),
2624 					  sys_le16_to_cpu(cp->elem_address),
2625 					  sys_le16_to_cpu(cp->model_id),
2626 					  &pub, &status);
2627 
2628 	if (err) {
2629 		LOG_ERR("err %d", err);
2630 		return BTP_STATUS_FAILED;
2631 	}
2632 
2633 	rp->status = status;
2634 	*rsp_len = sizeof(*rp);
2635 
2636 	return BTP_STATUS_SUCCESS;
2637 }
2638 
config_mod_pub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2639 static uint8_t config_mod_pub_set(const void *cmd, uint16_t cmd_len,
2640 				  void *rsp, uint16_t *rsp_len)
2641 {
2642 	const struct btp_mesh_cfg_model_pub_set_cmd *cp = cmd;
2643 	struct btp_mesh_cfg_model_pub_set_rp *rp = rsp;
2644 	struct bt_mesh_cfg_cli_mod_pub pub;
2645 	uint8_t status;
2646 	int err;
2647 
2648 	LOG_DBG("");
2649 
2650 	pub.addr = sys_le16_to_cpu(cp->pub_addr);
2651 	pub.uuid = NULL;
2652 	pub.app_idx = sys_le16_to_cpu(cp->app_idx);
2653 	pub.cred_flag = cp->cred_flag;
2654 	pub.ttl = cp->ttl;
2655 	pub.period = cp->period;
2656 	pub.transmit = cp->transmit;
2657 
2658 	err = bt_mesh_cfg_cli_mod_pub_set(sys_le16_to_cpu(cp->net_idx),
2659 					  sys_le16_to_cpu(cp->address),
2660 					  sys_le16_to_cpu(cp->elem_address),
2661 					  sys_le16_to_cpu(cp->model_id),
2662 					  &pub, &status);
2663 
2664 	if (err) {
2665 		LOG_ERR("err %d", err);
2666 		return BTP_STATUS_FAILED;
2667 	}
2668 
2669 	rp->status = status;
2670 	*rsp_len = sizeof(*rp);
2671 
2672 	return BTP_STATUS_SUCCESS;
2673 }
2674 
config_mod_pub_va_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2675 static uint8_t config_mod_pub_va_set(const void *cmd, uint16_t cmd_len,
2676 				     void *rsp, uint16_t *rsp_len)
2677 {
2678 	const struct btp_mesh_cfg_model_pub_va_set_cmd *cp = cmd;
2679 	struct btp_mesh_cfg_model_pub_va_set_rp *rp = rsp;
2680 	uint8_t status;
2681 	struct bt_mesh_cfg_cli_mod_pub pub;
2682 	int err;
2683 
2684 	LOG_DBG("");
2685 
2686 	pub.uuid = cp->uuid;
2687 	pub.app_idx = sys_le16_to_cpu(cp->app_idx);
2688 	pub.cred_flag = cp->cred_flag;
2689 	pub.ttl = cp->ttl;
2690 	pub.period = cp->period;
2691 	pub.transmit = cp->transmit;
2692 
2693 	err = bt_mesh_cfg_cli_mod_pub_set(sys_le16_to_cpu(cp->net_idx),
2694 					  sys_le16_to_cpu(cp->address),
2695 					  sys_le16_to_cpu(cp->elem_address),
2696 					  sys_le16_to_cpu(cp->model_id),
2697 					  &pub, &status);
2698 
2699 	if (err) {
2700 		LOG_ERR("err %d", err);
2701 		return BTP_STATUS_FAILED;
2702 	}
2703 
2704 	rp->status = status;
2705 	*rsp_len = sizeof(*rp);
2706 
2707 	return BTP_STATUS_SUCCESS;
2708 }
2709 
config_mod_sub_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2710 static uint8_t config_mod_sub_add(const void *cmd, uint16_t cmd_len,
2711 				  void *rsp, uint16_t *rsp_len)
2712 {
2713 	const struct btp_mesh_cfg_model_sub_add_cmd *cp = cmd;
2714 	struct btp_mesh_cfg_model_sub_add_rp *rp = rsp;
2715 	uint8_t status;
2716 	int err;
2717 
2718 	LOG_DBG("");
2719 
2720 	err = bt_mesh_cfg_cli_mod_sub_add(sys_le16_to_cpu(cp->net_idx),
2721 					  sys_le16_to_cpu(cp->address),
2722 					  sys_le16_to_cpu(cp->elem_address),
2723 					  sys_le16_to_cpu(cp->sub_addr),
2724 					  sys_le16_to_cpu(cp->model_id),
2725 					  &status);
2726 
2727 	if (err) {
2728 		LOG_ERR("err %d", err);
2729 		return BTP_STATUS_FAILED;
2730 	}
2731 
2732 	rp->status = status;
2733 	*rsp_len = sizeof(*rp);
2734 
2735 	return BTP_STATUS_SUCCESS;
2736 }
2737 
config_mod_sub_ovw(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2738 static uint8_t config_mod_sub_ovw(const void *cmd, uint16_t cmd_len,
2739 				  void *rsp, uint16_t *rsp_len)
2740 {
2741 	const struct btp_mesh_cfg_model_sub_ovw_cmd *cp = cmd;
2742 	struct btp_mesh_cfg_model_sub_add_rp *rp = rsp;
2743 	uint8_t status;
2744 	int err;
2745 
2746 	LOG_DBG("");
2747 
2748 	err = bt_mesh_cfg_cli_mod_sub_overwrite(sys_le16_to_cpu(cp->net_idx),
2749 						sys_le16_to_cpu(cp->address),
2750 						sys_le16_to_cpu(cp->elem_address),
2751 						sys_le16_to_cpu(cp->sub_addr),
2752 						sys_le16_to_cpu(cp->model_id),
2753 						&status);
2754 	if (err) {
2755 		LOG_ERR("err %d", err);
2756 		return BTP_STATUS_FAILED;
2757 	}
2758 
2759 	rp->status = status;
2760 	*rsp_len = sizeof(*rp);
2761 
2762 	return BTP_STATUS_SUCCESS;
2763 }
2764 
config_mod_sub_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2765 static uint8_t config_mod_sub_del(const void *cmd, uint16_t cmd_len,
2766 				  void *rsp, uint16_t *rsp_len)
2767 {
2768 	const struct btp_mesh_cfg_model_sub_del_cmd *cp = cmd;
2769 	struct btp_mesh_cfg_model_sub_del_rp *rp = rsp;
2770 	uint8_t status;
2771 	int err;
2772 
2773 	LOG_DBG("");
2774 
2775 	err = bt_mesh_cfg_cli_mod_sub_del(sys_le16_to_cpu(cp->net_idx),
2776 					  sys_le16_to_cpu(cp->address),
2777 					  sys_le16_to_cpu(cp->elem_address),
2778 					  sys_le16_to_cpu(cp->sub_addr),
2779 					  sys_le16_to_cpu(cp->model_id),
2780 					  &status);
2781 	if (err) {
2782 		LOG_ERR("err %d", err);
2783 		return BTP_STATUS_FAILED;
2784 	}
2785 
2786 	rp->status = status;
2787 	*rsp_len = sizeof(*rp);
2788 
2789 	return BTP_STATUS_SUCCESS;
2790 }
2791 
config_mod_sub_del_all(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2792 static uint8_t config_mod_sub_del_all(const void *cmd, uint16_t cmd_len,
2793 				      void *rsp, uint16_t *rsp_len)
2794 {
2795 	const struct btp_mesh_cfg_model_sub_del_all_cmd *cp = cmd;
2796 	struct btp_mesh_cfg_model_sub_del_all_rp *rp = rsp;
2797 	uint8_t status;
2798 	int err;
2799 
2800 	LOG_DBG("");
2801 
2802 	err = bt_mesh_cfg_cli_mod_sub_del_all(sys_le16_to_cpu(cp->net_idx),
2803 					      sys_le16_to_cpu(cp->address),
2804 					      sys_le16_to_cpu(cp->elem_address),
2805 					      sys_le16_to_cpu(cp->model_id),
2806 					      &status);
2807 
2808 	if (err) {
2809 		LOG_ERR("err %d", err);
2810 		return BTP_STATUS_FAILED;
2811 	}
2812 
2813 	rp->status = status;
2814 	*rsp_len = sizeof(*rp);
2815 
2816 	return BTP_STATUS_SUCCESS;
2817 }
2818 
config_mod_sub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2819 static uint8_t config_mod_sub_get(const void *cmd, uint16_t cmd_len,
2820 				  void *rsp, uint16_t *rsp_len)
2821 {
2822 	const struct btp_mesh_cfg_model_sub_get_cmd *cp = cmd;
2823 	struct btp_mesh_cfg_model_sub_get_rp *rp = rsp;
2824 	uint8_t status;
2825 	int16_t subs;
2826 	size_t sub_cn;
2827 	int err;
2828 
2829 	LOG_DBG("");
2830 
2831 	err = bt_mesh_cfg_cli_mod_sub_get(sys_le16_to_cpu(cp->net_idx),
2832 					  sys_le16_to_cpu(cp->address),
2833 					  sys_le16_to_cpu(cp->elem_address),
2834 					  sys_le16_to_cpu(cp->model_id),
2835 					  &status, &subs, &sub_cn);
2836 	if (err) {
2837 		LOG_ERR("err %d", err);
2838 		return BTP_STATUS_FAILED;
2839 	}
2840 
2841 	rp->status = status;
2842 	*rsp_len = sizeof(*rp);
2843 
2844 	return BTP_STATUS_SUCCESS;
2845 }
2846 
config_mod_sub_get_vnd(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2847 static uint8_t config_mod_sub_get_vnd(const void *cmd, uint16_t cmd_len,
2848 				      void *rsp, uint16_t *rsp_len)
2849 {
2850 	const struct btp_mesh_cfg_model_sub_get_vnd_cmd *cp = cmd;
2851 	struct btp_mesh_cfg_model_sub_get_vnd_rp *rp = rsp;
2852 	uint8_t status;
2853 	uint16_t subs;
2854 	size_t sub_cn;
2855 	int err;
2856 
2857 	LOG_DBG("");
2858 
2859 	err = bt_mesh_cfg_cli_mod_sub_get_vnd(sys_le16_to_cpu(cp->net_idx),
2860 					      sys_le16_to_cpu(cp->address),
2861 					      sys_le16_to_cpu(cp->elem_address),
2862 					      sys_le16_to_cpu(cp->model_id),
2863 					      sys_le16_to_cpu(cp->cid),
2864 					      &status, &subs, &sub_cn);
2865 	if (err) {
2866 		LOG_ERR("err %d", err);
2867 		return BTP_STATUS_FAILED;
2868 	}
2869 
2870 	rp->status = status;
2871 	*rsp_len = sizeof(*rp);
2872 
2873 	return BTP_STATUS_SUCCESS;
2874 }
2875 
config_mod_sub_va_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2876 static uint8_t config_mod_sub_va_add(const void *cmd, uint16_t cmd_len,
2877 				     void *rsp, uint16_t *rsp_len)
2878 {
2879 	const struct btp_mesh_cfg_model_sub_va_add_cmd *cp = cmd;
2880 	struct btp_mesh_cfg_model_sub_va_add_rp *rp = rsp;
2881 	uint8_t status;
2882 	uint16_t virt_addr_rcv;
2883 	int err;
2884 
2885 	LOG_DBG("");
2886 
2887 	err = bt_mesh_cfg_cli_mod_sub_va_add(sys_le16_to_cpu(cp->net_idx),
2888 					     sys_le16_to_cpu(cp->address),
2889 					     sys_le16_to_cpu(cp->elem_address),
2890 					     sys_le16_to_cpu(cp->uuid),
2891 					     sys_le16_to_cpu(cp->model_id),
2892 					     &virt_addr_rcv, &status);
2893 
2894 	if (err) {
2895 		LOG_ERR("err %d", err);
2896 		return BTP_STATUS_FAILED;
2897 	}
2898 
2899 	rp->status = status;
2900 	*rsp_len = sizeof(*rp);
2901 
2902 	return BTP_STATUS_SUCCESS;
2903 }
2904 
config_mod_sub_va_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2905 static uint8_t config_mod_sub_va_del(const void *cmd, uint16_t cmd_len,
2906 				     void *rsp, uint16_t *rsp_len)
2907 {
2908 	const struct btp_mesh_cfg_model_sub_va_del_cmd *cp = cmd;
2909 	struct btp_mesh_cfg_model_sub_va_del_rp *rp = rsp;
2910 	uint8_t status;
2911 	uint16_t virt_addr_rcv;
2912 	int err;
2913 
2914 	LOG_DBG("");
2915 
2916 	err = bt_mesh_cfg_cli_mod_sub_va_del(sys_le16_to_cpu(cp->net_idx),
2917 					     sys_le16_to_cpu(cp->address),
2918 					     sys_le16_to_cpu(cp->elem_address),
2919 					     sys_le16_to_cpu(cp->uuid),
2920 					     sys_le16_to_cpu(cp->model_id),
2921 					     &virt_addr_rcv, &status);
2922 
2923 	if (err) {
2924 		LOG_ERR("err %d", err);
2925 		return BTP_STATUS_FAILED;
2926 	}
2927 
2928 	rp->status = status;
2929 	*rsp_len = sizeof(*rp);
2930 
2931 	return BTP_STATUS_SUCCESS;
2932 }
2933 
config_mod_sub_va_ovw(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2934 static uint8_t config_mod_sub_va_ovw(const void *cmd, uint16_t cmd_len,
2935 				     void *rsp, uint16_t *rsp_len)
2936 {
2937 	const struct btp_mesh_cfg_model_sub_va_ovw_cmd *cp = cmd;
2938 	struct btp_mesh_cfg_model_sub_va_ovw_rp *rp = rsp;
2939 	uint8_t status;
2940 	uint16_t virt_addr_rcv;
2941 	int err;
2942 
2943 	LOG_DBG("");
2944 
2945 	err = bt_mesh_cfg_cli_mod_sub_va_overwrite(sys_le16_to_cpu(cp->net_idx),
2946 						   sys_le16_to_cpu(cp->address),
2947 						   sys_le16_to_cpu(cp->elem_address),
2948 						   sys_le16_to_cpu(cp->uuid),
2949 						   sys_le16_to_cpu(cp->model_id),
2950 						   &virt_addr_rcv, &status);
2951 
2952 	if (err) {
2953 		LOG_ERR("err %d", err);
2954 		return BTP_STATUS_FAILED;
2955 	}
2956 
2957 	rp->status = status;
2958 	*rsp_len = sizeof(*rp);
2959 
2960 	return BTP_STATUS_SUCCESS;
2961 }
2962 
config_netkey_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2963 static uint8_t config_netkey_add(const void *cmd, uint16_t cmd_len,
2964 				 void *rsp, uint16_t *rsp_len)
2965 {
2966 	const struct btp_mesh_cfg_netkey_add_cmd *cp = cmd;
2967 	struct btp_mesh_cfg_netkey_add_rp *rp = rsp;
2968 	uint8_t status;
2969 	int err;
2970 
2971 	LOG_DBG("");
2972 
2973 	err = bt_mesh_cfg_cli_net_key_add(sys_le16_to_cpu(cp->net_idx),
2974 					  sys_le16_to_cpu(cp->address),
2975 					  sys_le16_to_cpu(cp->net_key_idx),
2976 					  cp->net_key, &status);
2977 
2978 	if (err) {
2979 		LOG_ERR("err %d", err);
2980 		return BTP_STATUS_FAILED;
2981 	}
2982 
2983 	rp->status = status;
2984 	*rsp_len = sizeof(*rp);
2985 
2986 	return BTP_STATUS_SUCCESS;
2987 }
2988 
config_netkey_update(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2989 static uint8_t config_netkey_update(const void *cmd, uint16_t cmd_len,
2990 				    void *rsp, uint16_t *rsp_len)
2991 {
2992 	const struct btp_mesh_cfg_netkey_update_cmd *cp = cmd;
2993 	struct btp_mesh_cfg_netkey_update_rp *rp = rsp;
2994 	uint8_t status;
2995 	int err;
2996 
2997 	LOG_DBG("");
2998 
2999 	err = bt_mesh_cfg_cli_net_key_update(sys_le16_to_cpu(cp->net_idx),
3000 					     sys_le16_to_cpu(cp->address),
3001 					     sys_le16_to_cpu(cp->net_key_idx),
3002 					     cp->net_key,
3003 					     &status);
3004 
3005 	if (err) {
3006 		LOG_ERR("err %d", err);
3007 		return BTP_STATUS_FAILED;
3008 	}
3009 
3010 	rp->status = status;
3011 	*rsp_len = sizeof(*rp);
3012 
3013 	return BTP_STATUS_SUCCESS;
3014 }
3015 
config_netkey_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3016 static uint8_t config_netkey_get(const void *cmd, uint16_t cmd_len,
3017 				 void *rsp, uint16_t *rsp_len)
3018 {
3019 	const struct btp_mesh_cfg_netkey_get_cmd *cp = cmd;
3020 	struct btp_mesh_cfg_netkey_get_rp *rp = rsp;
3021 	size_t key_cnt = 1;
3022 	uint16_t keys;
3023 	int err;
3024 
3025 	LOG_DBG("");
3026 
3027 	err = bt_mesh_cfg_cli_net_key_get(sys_le16_to_cpu(cp->net_idx),
3028 					  sys_le16_to_cpu(cp->address),
3029 					  &keys, &key_cnt);
3030 	if (err) {
3031 		LOG_ERR("err %d", err);
3032 		return BTP_STATUS_FAILED;
3033 	}
3034 
3035 	/* for historical reasons this command has status in response */
3036 	rp->status = 0;
3037 	*rsp_len = sizeof(*rp);
3038 
3039 	return BTP_STATUS_SUCCESS;
3040 }
3041 
config_netkey_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3042 static uint8_t config_netkey_del(const void *cmd, uint16_t cmd_len,
3043 				 void *rsp, uint16_t *rsp_len)
3044 {
3045 	const struct btp_mesh_cfg_netkey_del_cmd *cp = cmd;
3046 	struct btp_mesh_cfg_netkey_del_rp *rp = rsp;
3047 	uint8_t status;
3048 	int err;
3049 
3050 	LOG_DBG("");
3051 
3052 	err = bt_mesh_cfg_cli_net_key_del(sys_le16_to_cpu(cp->net_idx),
3053 					  sys_le16_to_cpu(cp->address),
3054 					  sys_le16_to_cpu(cp->net_key_idx),
3055 					  &status);
3056 
3057 	if (err) {
3058 		LOG_ERR("err %d", err);
3059 		return BTP_STATUS_FAILED;
3060 	}
3061 
3062 	rp->status = status;
3063 	*rsp_len = sizeof(*rp);
3064 
3065 	return BTP_STATUS_SUCCESS;
3066 }
3067 
config_appkey_add(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3068 static uint8_t config_appkey_add(const void *cmd, uint16_t cmd_len,
3069 				 void *rsp, uint16_t *rsp_len)
3070 {
3071 	const struct btp_mesh_cfg_appkey_add_cmd *cp = cmd;
3072 	struct btp_mesh_cfg_appkey_add_rp *rp = rsp;
3073 	uint8_t status;
3074 	int err;
3075 
3076 	LOG_DBG("");
3077 
3078 	err = bt_mesh_cfg_cli_app_key_add(sys_le16_to_cpu(cp->net_idx),
3079 					  sys_le16_to_cpu(cp->address),
3080 					  sys_le16_to_cpu(cp->net_key_idx),
3081 					  sys_le16_to_cpu(cp->app_key_idx),
3082 					  sys_le16_to_cpu(cp->app_key),
3083 					  &status);
3084 
3085 	if (err) {
3086 		LOG_ERR("err %d", err);
3087 		return BTP_STATUS_FAILED;
3088 	}
3089 
3090 	rp->status = status;
3091 	*rsp_len = sizeof(*rp);
3092 
3093 	return BTP_STATUS_SUCCESS;
3094 }
3095 
config_appkey_update(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3096 static uint8_t config_appkey_update(const void *cmd, uint16_t cmd_len,
3097 				    void *rsp, uint16_t *rsp_len)
3098 {
3099 	const struct btp_mesh_cfg_appkey_update_cmd *cp = cmd;
3100 	struct btp_mesh_cfg_appkey_update_rp *rp = rsp;
3101 	uint8_t status;
3102 	int err;
3103 
3104 	LOG_DBG("");
3105 
3106 	err = bt_mesh_cfg_cli_app_key_update(sys_le16_to_cpu(cp->net_idx),
3107 					     sys_le16_to_cpu(cp->address),
3108 					     sys_le16_to_cpu(cp->net_key_idx),
3109 					     sys_le16_to_cpu(cp->app_key_idx),
3110 					     sys_le16_to_cpu(cp->app_key),
3111 					     &status);
3112 
3113 	if (err) {
3114 		LOG_ERR("err %d", err);
3115 		return BTP_STATUS_FAILED;
3116 	}
3117 
3118 	rp->status = status;
3119 	*rsp_len = sizeof(*rp);
3120 
3121 	return BTP_STATUS_SUCCESS;
3122 }
3123 
config_appkey_del(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3124 static uint8_t config_appkey_del(const void *cmd, uint16_t cmd_len,
3125 				 void *rsp, uint16_t *rsp_len)
3126 {
3127 	const struct btp_mesh_cfg_appkey_del_cmd *cp = cmd;
3128 	struct btp_mesh_cfg_appkey_del_rp *rp = rsp;
3129 	uint8_t status;
3130 	int err;
3131 
3132 	LOG_DBG("");
3133 
3134 	err = bt_mesh_cfg_cli_app_key_del(sys_le16_to_cpu(cp->net_idx),
3135 					  sys_le16_to_cpu(cp->address),
3136 					  sys_le16_to_cpu(cp->net_key_idx),
3137 					  sys_le16_to_cpu(cp->app_key_idx),
3138 					  &status);
3139 
3140 	if (err) {
3141 		LOG_ERR("err %d", err);
3142 		return BTP_STATUS_FAILED;
3143 	}
3144 
3145 	rp->status = status;
3146 	*rsp_len = sizeof(*rp);
3147 
3148 	return BTP_STATUS_SUCCESS;
3149 }
3150 
config_appkey_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3151 static uint8_t config_appkey_get(const void *cmd, uint16_t cmd_len,
3152 				 void *rsp, uint16_t *rsp_len)
3153 {
3154 	const struct btp_mesh_cfg_appkey_get_cmd *cp = cmd;
3155 	struct btp_mesh_cfg_appkey_get_rp *rp = rsp;
3156 	uint8_t status;
3157 	uint16_t keys;
3158 	size_t key_cnt = 1;
3159 	int err;
3160 
3161 	LOG_DBG("");
3162 
3163 	err = bt_mesh_cfg_cli_app_key_get(sys_le16_to_cpu(cp->net_idx),
3164 					  sys_le16_to_cpu(cp->address),
3165 					  sys_le16_to_cpu(cp->net_key_idx),
3166 					  &status, &keys, &key_cnt);
3167 
3168 	if (err) {
3169 		LOG_ERR("err %d", err);
3170 		return BTP_STATUS_FAILED;
3171 	}
3172 
3173 	rp->status = status;
3174 	*rsp_len = sizeof(*rp);
3175 
3176 	return BTP_STATUS_SUCCESS;
3177 }
3178 
3179 
config_model_app_bind(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3180 static uint8_t config_model_app_bind(const void *cmd, uint16_t cmd_len,
3181 				 void *rsp, uint16_t *rsp_len)
3182 {
3183 	const struct btp_mesh_cfg_model_app_bind_cmd *cp = cmd;
3184 	struct btp_mesh_cfg_model_app_bind_rp *rp = rsp;
3185 	uint8_t status;
3186 	int err;
3187 
3188 	LOG_DBG("");
3189 
3190 	bt_mesh_cfg_cli_timeout_set(5000);
3191 
3192 	err = bt_mesh_cfg_cli_mod_app_bind(sys_le16_to_cpu(cp->net_idx),
3193 					   sys_le16_to_cpu(cp->address),
3194 					   sys_le16_to_cpu(cp->elem_address),
3195 					   sys_le16_to_cpu(cp->app_key_idx),
3196 					   sys_le16_to_cpu(cp->mod_id),
3197 					   &status);
3198 
3199 	if (err) {
3200 		LOG_ERR("err %d", err);
3201 		return BTP_STATUS_FAILED;
3202 	}
3203 
3204 	rp->status = status;
3205 	*rsp_len = sizeof(*rp);
3206 
3207 	return BTP_STATUS_SUCCESS;
3208 }
3209 
config_model_app_bind_vnd(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3210 static uint8_t config_model_app_bind_vnd(const void *cmd, uint16_t cmd_len,
3211 					 void *rsp, uint16_t *rsp_len)
3212 {
3213 	const struct btp_mesh_cfg_model_app_bind_vnd_cmd *cp = cmd;
3214 	struct btp_mesh_cfg_model_app_bind_vnd_rp *rp = rsp;
3215 	uint8_t status;
3216 	int err;
3217 
3218 	LOG_DBG("");
3219 
3220 	err = bt_mesh_cfg_cli_mod_app_bind_vnd(sys_le16_to_cpu(cp->net_idx),
3221 					       sys_le16_to_cpu(cp->address),
3222 					       sys_le16_to_cpu(cp->elem_address),
3223 					       sys_le16_to_cpu(cp->app_key_idx),
3224 					       sys_le16_to_cpu(cp->mod_id),
3225 					       sys_le16_to_cpu(cp->cid),
3226 					       &status);
3227 
3228 	if (err) {
3229 		LOG_ERR("err %d", err);
3230 		return BTP_STATUS_FAILED;
3231 	}
3232 
3233 	rp->status = status;
3234 	*rsp_len = sizeof(*rp);
3235 
3236 	return BTP_STATUS_SUCCESS;
3237 }
3238 
config_model_app_unbind(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3239 static uint8_t config_model_app_unbind(const void *cmd, uint16_t cmd_len,
3240 				       void *rsp, uint16_t *rsp_len)
3241 {
3242 	const struct btp_mesh_cfg_model_app_unbind_cmd *cp = cmd;
3243 	struct btp_mesh_cfg_model_app_unbind_rp *rp = rsp;
3244 	uint8_t status;
3245 	int err;
3246 
3247 	LOG_DBG("");
3248 
3249 	err = bt_mesh_cfg_cli_mod_app_unbind(sys_le16_to_cpu(cp->net_idx),
3250 					     sys_le16_to_cpu(cp->address),
3251 					     sys_le16_to_cpu(cp->elem_address),
3252 					     sys_le16_to_cpu(cp->app_key_idx),
3253 					     sys_le16_to_cpu(cp->mod_id),
3254 					     &status);
3255 	if (err) {
3256 		LOG_ERR("err %d", err);
3257 		return BTP_STATUS_FAILED;
3258 	}
3259 
3260 	rp->status = status;
3261 	*rsp_len = sizeof(*rp);
3262 
3263 	return BTP_STATUS_SUCCESS;
3264 }
3265 
3266 
config_model_app_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3267 static uint8_t config_model_app_get(const void *cmd, uint16_t cmd_len,
3268 				    void *rsp, uint16_t *rsp_len)
3269 {
3270 	const struct btp_mesh_cfg_model_app_get_cmd *cp = cmd;
3271 	struct btp_mesh_cfg_model_app_get_rp *rp = rsp;
3272 	uint8_t status;
3273 	uint16_t apps;
3274 	size_t app_cnt;
3275 	int err;
3276 
3277 	LOG_DBG("");
3278 
3279 	err = bt_mesh_cfg_cli_mod_app_get(sys_le16_to_cpu(cp->net_idx),
3280 					  sys_le16_to_cpu(cp->address),
3281 					  sys_le16_to_cpu(cp->elem_address),
3282 					  sys_le16_to_cpu(cp->mod_id),
3283 					  &status, &apps, &app_cnt);
3284 
3285 	if (err) {
3286 		LOG_ERR("err %d", err);
3287 		return BTP_STATUS_FAILED;
3288 	}
3289 
3290 	rp->status = status;
3291 	*rsp_len = sizeof(*rp);
3292 
3293 	return BTP_STATUS_SUCCESS;
3294 }
3295 
config_model_app_vnd_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3296 static uint8_t config_model_app_vnd_get(const void *cmd, uint16_t cmd_len,
3297 				    void *rsp, uint16_t *rsp_len)
3298 {
3299 	const struct btp_mesh_cfg_model_app_vnd_get_cmd *cp = cmd;
3300 	struct btp_mesh_cfg_model_app_vnd_get_rp *rp = rsp;
3301 	uint8_t status;
3302 	uint16_t apps;
3303 	size_t app_cnt;
3304 	int err;
3305 
3306 	LOG_DBG("");
3307 
3308 	err = bt_mesh_cfg_cli_mod_app_get_vnd(sys_le16_to_cpu(cp->net_idx),
3309 					      sys_le16_to_cpu(cp->address),
3310 					      sys_le16_to_cpu(cp->elem_address),
3311 					      sys_le16_to_cpu(cp->mod_id),
3312 					      sys_le16_to_cpu(cp->cid),
3313 					      &status, &apps, &app_cnt);
3314 	if (err) {
3315 		LOG_ERR("err %d", err);
3316 		return BTP_STATUS_FAILED;
3317 	}
3318 
3319 	rp->status = status;
3320 	*rsp_len = sizeof(*rp);
3321 
3322 	return BTP_STATUS_SUCCESS;
3323 }
3324 
config_hb_pub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3325 static uint8_t config_hb_pub_set(const void *cmd, uint16_t cmd_len,
3326 				 void *rsp, uint16_t *rsp_len)
3327 {
3328 	const struct btp_mesh_cfg_heartbeat_pub_set_cmd *cp = cmd;
3329 	struct btp_mesh_cfg_heartbeat_pub_set_rp *rp = rsp;
3330 	uint8_t status;
3331 	struct bt_mesh_cfg_cli_hb_pub pub;
3332 	int err;
3333 
3334 	LOG_DBG("");
3335 
3336 	pub.net_idx = sys_le16_to_cpu(cp->net_key_idx);
3337 	pub.dst = sys_le16_to_cpu(cp->destination);
3338 	pub.count = cp->count_log;
3339 	pub.period = cp->period_log;
3340 	pub.ttl = cp->ttl;
3341 	pub.feat = sys_le16_to_cpu(cp->features);
3342 
3343 	err = bt_mesh_cfg_cli_hb_pub_set(sys_le16_to_cpu(cp->net_idx),
3344 					 sys_le16_to_cpu(cp->address),
3345 					 &pub, &status);
3346 
3347 	if (err) {
3348 		LOG_ERR("err %d", err);
3349 		return BTP_STATUS_FAILED;
3350 	}
3351 
3352 	rp->status = status;
3353 	*rsp_len = sizeof(*rp);
3354 
3355 	return BTP_STATUS_SUCCESS;
3356 }
3357 
config_hb_pub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3358 static uint8_t config_hb_pub_get(const void *cmd, uint16_t cmd_len,
3359 				 void *rsp, uint16_t *rsp_len)
3360 {
3361 	const struct btp_mesh_cfg_heartbeat_pub_get_cmd *cp = cmd;
3362 	struct btp_mesh_cfg_heartbeat_pub_get_rp *rp = rsp;
3363 	uint8_t status;
3364 	struct bt_mesh_cfg_cli_hb_pub pub;
3365 	int err;
3366 
3367 	LOG_DBG("");
3368 
3369 	err = bt_mesh_cfg_cli_hb_pub_get(sys_le16_to_cpu(cp->net_idx),
3370 					 sys_le16_to_cpu(cp->address),
3371 					 &pub, &status);
3372 
3373 	if (err) {
3374 		LOG_ERR("err %d", err);
3375 		return BTP_STATUS_FAILED;
3376 	}
3377 
3378 	rp->status = status;
3379 	*rsp_len = sizeof(*rp);
3380 
3381 	return BTP_STATUS_SUCCESS;
3382 }
3383 
config_hb_sub_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3384 static uint8_t config_hb_sub_set(const void *cmd, uint16_t cmd_len,
3385 				 void *rsp, uint16_t *rsp_len)
3386 {
3387 	const struct btp_mesh_cfg_heartbeat_sub_set_cmd *cp = cmd;
3388 	struct btp_mesh_cfg_heartbeat_sub_set_rp *rp = rsp;
3389 	uint8_t status;
3390 	struct bt_mesh_cfg_cli_hb_sub sub;
3391 	int err;
3392 
3393 	LOG_DBG("");
3394 
3395 	sub.src = sys_le16_to_cpu(cp->source);
3396 	sub.dst = sys_le16_to_cpu(cp->destination);
3397 	sub.period = cp->period_log;
3398 
3399 	err = bt_mesh_cfg_cli_hb_sub_set(sys_le16_to_cpu(cp->net_idx),
3400 					 sys_le16_to_cpu(cp->address),
3401 					 &sub, &status);
3402 
3403 	if (err) {
3404 		LOG_ERR("err %d", err);
3405 		return BTP_STATUS_FAILED;
3406 	}
3407 
3408 	rp->status = status;
3409 	*rsp_len = sizeof(*rp);
3410 
3411 	return BTP_STATUS_SUCCESS;
3412 }
3413 
config_hb_sub_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3414 static uint8_t config_hb_sub_get(const void *cmd, uint16_t cmd_len,
3415 				 void *rsp, uint16_t *rsp_len)
3416 {
3417 	const struct btp_mesh_cfg_heartbeat_sub_get_cmd *cp = cmd;
3418 	struct btp_mesh_cfg_heartbeat_sub_get_rp *rp = rsp;
3419 	uint8_t status;
3420 	struct bt_mesh_cfg_cli_hb_sub sub;
3421 	int err;
3422 
3423 	LOG_DBG("");
3424 
3425 	err = bt_mesh_cfg_cli_hb_sub_get(sys_le16_to_cpu(cp->net_idx),
3426 					 sys_le16_to_cpu(cp->address),
3427 					 &sub, &status);
3428 
3429 	if (err) {
3430 		LOG_ERR("err %d", err);
3431 		return BTP_STATUS_FAILED;
3432 	}
3433 
3434 	rp->status = status;
3435 	*rsp_len = sizeof(*rp);
3436 
3437 	return BTP_STATUS_SUCCESS;
3438 }
3439 
config_net_trans_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3440 static uint8_t config_net_trans_get(const void *cmd, uint16_t cmd_len,
3441 				    void *rsp, uint16_t *rsp_len)
3442 {
3443 	const struct btp_mesh_cfg_net_trans_get_cmd *cp = cmd;
3444 	struct btp_mesh_cfg_net_trans_get_rp *rp = rsp;
3445 	uint8_t transmit;
3446 	int err;
3447 
3448 	LOG_DBG("");
3449 
3450 	err = bt_mesh_cfg_cli_net_transmit_get(sys_le16_to_cpu(cp->net_idx),
3451 					       sys_le16_to_cpu(cp->address),
3452 					       &transmit);
3453 
3454 	if (err) {
3455 		LOG_ERR("err %d", err);
3456 		return BTP_STATUS_FAILED;
3457 	}
3458 
3459 	rp->transmit = transmit;
3460 	*rsp_len = sizeof(*rp);
3461 
3462 	return BTP_STATUS_SUCCESS;
3463 }
3464 
config_net_trans_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3465 static uint8_t config_net_trans_set(const void *cmd, uint16_t cmd_len,
3466 				    void *rsp, uint16_t *rsp_len)
3467 {
3468 	const struct btp_mesh_cfg_net_trans_set_cmd *cp = cmd;
3469 	struct btp_mesh_cfg_net_trans_set_rp *rp = rsp;
3470 	uint8_t transmit;
3471 	int err;
3472 
3473 	LOG_DBG("");
3474 
3475 	err = bt_mesh_cfg_cli_net_transmit_set(sys_le16_to_cpu(cp->net_idx),
3476 					       sys_le16_to_cpu(cp->address),
3477 					       cp->transmit, &transmit);
3478 
3479 	if (err) {
3480 		LOG_ERR("err %d", err);
3481 		return BTP_STATUS_FAILED;
3482 	}
3483 
3484 	rp->transmit = transmit;
3485 	*rsp_len = sizeof(*rp);
3486 
3487 	return BTP_STATUS_SUCCESS;
3488 }
3489 
config_node_identity_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3490 static uint8_t config_node_identity_set(const void *cmd, uint16_t cmd_len,
3491 				    void *rsp, uint16_t *rsp_len)
3492 {
3493 	const struct btp_mesh_cfg_node_idt_set_cmd *cp = cmd;
3494 	struct btp_mesh_cfg_node_idt_set_rp *rp = rsp;
3495 	uint8_t identity;
3496 	uint8_t status;
3497 	int err;
3498 
3499 	LOG_DBG("");
3500 
3501 	err = bt_mesh_cfg_cli_node_identity_set(sys_le16_to_cpu(cp->net_idx),
3502 						sys_le16_to_cpu(cp->address),
3503 						sys_le16_to_cpu(cp->net_key_idx),
3504 						cp->new_identity,
3505 						&status, &identity);
3506 
3507 	if (err) {
3508 		LOG_ERR("err %d", err);
3509 		return BTP_STATUS_FAILED;
3510 	}
3511 
3512 	rp->status = status;
3513 	rp->identity = identity;
3514 
3515 	*rsp_len = sizeof(*rp);
3516 	return BTP_STATUS_SUCCESS;
3517 }
3518 
config_node_identity_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3519 static uint8_t config_node_identity_get(const void *cmd, uint16_t cmd_len,
3520 				    void *rsp, uint16_t *rsp_len)
3521 {
3522 	const struct btp_mesh_cfg_node_idt_get_cmd *cp = cmd;
3523 	struct btp_mesh_cfg_node_idt_get_rp *rp = rsp;
3524 	uint8_t identity;
3525 	uint8_t status;
3526 	int err;
3527 
3528 	LOG_DBG("");
3529 
3530 	err = bt_mesh_cfg_cli_node_identity_get(sys_le16_to_cpu(cp->net_idx),
3531 						sys_le16_to_cpu(cp->address),
3532 						sys_le16_to_cpu(cp->net_key_idx),
3533 						&status, &identity);
3534 
3535 	if (err) {
3536 		LOG_ERR("err %d", err);
3537 		return BTP_STATUS_FAILED;
3538 	}
3539 
3540 	rp->status = status;
3541 	rp->identity = identity;
3542 
3543 	*rsp_len = sizeof(*rp);
3544 	return BTP_STATUS_SUCCESS;
3545 }
3546 
config_node_reset(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3547 static uint8_t config_node_reset(const void *cmd, uint16_t cmd_len,
3548 				 void *rsp, uint16_t *rsp_len)
3549 {
3550 	const struct btp_mesh_cfg_node_reset_cmd *cp = cmd;
3551 	struct btp_mesh_cfg_node_reset_rp *rp = rsp;
3552 	bool status;
3553 	int err;
3554 
3555 	LOG_DBG("");
3556 
3557 	err = bt_mesh_cfg_cli_node_reset(sys_le16_to_cpu(cp->net_idx),
3558 					 sys_le16_to_cpu(cp->address),
3559 					 &status);
3560 
3561 	if (err) {
3562 		LOG_ERR("err %d", err);
3563 		return BTP_STATUS_FAILED;
3564 	}
3565 
3566 	rp->status = status;
3567 
3568 	*rsp_len = sizeof(*rp);
3569 	return BTP_STATUS_SUCCESS;
3570 }
3571 
config_lpn_timeout_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3572 static uint8_t config_lpn_timeout_get(const void *cmd, uint16_t cmd_len,
3573 				      void *rsp, uint16_t *rsp_len)
3574 {
3575 	const struct btp_mesh_cfg_lpn_timeout_cmd *cp = cmd;
3576 	struct btp_mesh_cfg_lpn_timeout_rp *rp = rsp;
3577 	int32_t polltimeout;
3578 	int err;
3579 
3580 	LOG_DBG("");
3581 
3582 	err = bt_mesh_cfg_cli_lpn_timeout_get(sys_le16_to_cpu(cp->net_idx),
3583 					      sys_le16_to_cpu(cp->address),
3584 					      sys_le16_to_cpu(cp->unicast_addr),
3585 					      &polltimeout);
3586 
3587 	if (err) {
3588 		LOG_ERR("err %d", err);
3589 		return BTP_STATUS_FAILED;
3590 	}
3591 
3592 	rp->timeout = sys_cpu_to_le32(polltimeout);
3593 
3594 	*rsp_len = sizeof(*rp);
3595 	return BTP_STATUS_SUCCESS;
3596 }
3597 
health_fault_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3598 static uint8_t health_fault_get(const void *cmd, uint16_t cmd_len,
3599 				void *rsp, uint16_t *rsp_len)
3600 {
3601 	const struct btp_mesh_health_fault_get_cmd *cp = cmd;
3602 	struct bt_mesh_msg_ctx ctx = {
3603 		.net_idx = net.net_idx,
3604 		.addr = sys_le16_to_cpu(cp->address),
3605 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3606 	};
3607 	uint8_t test_id;
3608 	size_t fault_count = 16;
3609 	uint8_t faults[fault_count];
3610 	int err;
3611 
3612 	LOG_DBG("");
3613 
3614 	err = bt_mesh_health_cli_fault_get(&health_cli, &ctx,
3615 					   sys_le16_to_cpu(cp->cid), &test_id,
3616 					   faults, &fault_count);
3617 
3618 	if (err) {
3619 		LOG_ERR("err %d", err);
3620 		return BTP_STATUS_FAILED;
3621 	}
3622 
3623 	return BTP_STATUS_SUCCESS;
3624 }
3625 
health_fault_clear(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3626 static uint8_t health_fault_clear(const void *cmd, uint16_t cmd_len,
3627 				  void *rsp, uint16_t *rsp_len)
3628 {
3629 	const struct btp_mesh_health_fault_clear_cmd *cp = cmd;
3630 	struct bt_mesh_msg_ctx ctx = {
3631 		.net_idx = net.net_idx,
3632 		.addr = sys_le16_to_cpu(cp->address),
3633 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3634 	};
3635 	uint8_t test_id = 0;
3636 	size_t fault_count = 16;
3637 	uint8_t faults[fault_count];
3638 	int err;
3639 
3640 	LOG_DBG("");
3641 
3642 	if (cp->ack) {
3643 		err = bt_mesh_health_cli_fault_clear(&health_cli, &ctx,
3644 						     sys_le16_to_cpu(cp->cid),
3645 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3646 						     bt_mesh_op_agg_cli_seq_is_started() ?
3647 						     NULL :
3648 #endif
3649 						     &test_id,
3650 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3651 						     bt_mesh_op_agg_cli_seq_is_started() ?
3652 						     NULL :
3653 #endif
3654 						     faults,
3655 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3656 						     bt_mesh_op_agg_cli_seq_is_started() ?
3657 						     NULL :
3658 #endif
3659 						     &fault_count);
3660 	} else {
3661 		err = bt_mesh_health_cli_fault_clear_unack(&health_cli, &ctx,
3662 							   sys_le16_to_cpu(cp->cid));
3663 	}
3664 
3665 	if (err) {
3666 		LOG_ERR("err %d", err);
3667 		return BTP_STATUS_FAILED;
3668 	}
3669 
3670 	if (cp->ack) {
3671 		struct btp_mesh_health_fault_clear_rp *rp = rsp;
3672 
3673 		rp->test_id = test_id;
3674 		*rsp_len = sizeof(*rp);
3675 	}
3676 
3677 	return BTP_STATUS_SUCCESS;
3678 }
3679 
health_fault_test(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3680 static uint8_t health_fault_test(const void *cmd, uint16_t cmd_len,
3681 				 void *rsp, uint16_t *rsp_len)
3682 {
3683 	const struct btp_mesh_health_fault_test_cmd *cp = cmd;
3684 	struct bt_mesh_msg_ctx ctx = {
3685 		.net_idx = net.net_idx,
3686 		.addr = sys_le16_to_cpu(cp->address),
3687 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3688 	};
3689 	size_t fault_count = 16;
3690 	uint8_t faults[fault_count];
3691 	int err;
3692 
3693 	LOG_DBG("");
3694 
3695 	if (cp->ack) {
3696 		err = bt_mesh_health_cli_fault_test(&health_cli, &ctx,
3697 						    sys_le16_to_cpu(cp->cid),
3698 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3699 						    bt_mesh_op_agg_cli_seq_is_started() ?
3700 						    0 :
3701 #endif
3702 						    cp->test_id,
3703 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3704 						    bt_mesh_op_agg_cli_seq_is_started() ?
3705 						    NULL :
3706 #endif
3707 						    faults,
3708 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3709 						    bt_mesh_op_agg_cli_seq_is_started() ?
3710 						    NULL :
3711 #endif
3712 						    &fault_count);
3713 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3714 		if (bt_mesh_op_agg_cli_seq_is_started()) {
3715 			fault_count = 0;
3716 		}
3717 #endif
3718 	} else {
3719 		err = bt_mesh_health_cli_fault_test_unack(&health_cli, &ctx,
3720 							  sys_le16_to_cpu(cp->cid),
3721 							  cp->test_id);
3722 	}
3723 
3724 	if (err) {
3725 		LOG_ERR("err %d", err);
3726 		return BTP_STATUS_FAILED;
3727 	}
3728 
3729 	if (cp->ack) {
3730 		struct btp_mesh_health_fault_test_rp *rp = rsp;
3731 
3732 		rp->test_id = cp->test_id;
3733 		rp->cid = cp->cid;
3734 		(void)memcpy(rp->faults, faults, fault_count);
3735 
3736 		*rsp_len = sizeof(*rp) + fault_count;
3737 	}
3738 
3739 	return BTP_STATUS_SUCCESS;
3740 }
3741 
health_period_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3742 static uint8_t health_period_get(const void *cmd, uint16_t cmd_len,
3743 				 void *rsp, uint16_t *rsp_len)
3744 {
3745 	const struct btp_mesh_health_period_get_cmd *cp = cmd;
3746 	struct bt_mesh_msg_ctx ctx = {
3747 		.net_idx = net.net_idx,
3748 		.addr = sys_le16_to_cpu(cp->address),
3749 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3750 	};
3751 	uint8_t divisor;
3752 	int err;
3753 
3754 	LOG_DBG("");
3755 
3756 	err = bt_mesh_health_cli_period_get(&health_cli, &ctx, &divisor);
3757 
3758 	if (err) {
3759 		LOG_ERR("err %d", err);
3760 		return BTP_STATUS_FAILED;
3761 	}
3762 
3763 	return BTP_STATUS_SUCCESS;
3764 }
3765 
health_period_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3766 static uint8_t health_period_set(const void *cmd, uint16_t cmd_len,
3767 				 void *rsp, uint16_t *rsp_len)
3768 {
3769 	const struct btp_mesh_health_period_set_cmd *cp = cmd;
3770 	struct bt_mesh_msg_ctx ctx = {
3771 		.net_idx = net.net_idx,
3772 		.addr = sys_le16_to_cpu(cp->address),
3773 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3774 	};
3775 	uint8_t updated_divisor;
3776 	int err;
3777 
3778 	LOG_DBG("");
3779 
3780 	if (cp->ack) {
3781 		err = bt_mesh_health_cli_period_set(&health_cli, &ctx, cp->divisor,
3782 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3783 						    bt_mesh_op_agg_cli_seq_is_started() ?
3784 						    NULL :
3785 #endif
3786 						    &updated_divisor);
3787 	} else {
3788 		err = bt_mesh_health_cli_period_set_unack(&health_cli, &ctx, cp->divisor);
3789 	}
3790 
3791 	if (err) {
3792 		LOG_ERR("err %d", err);
3793 		return BTP_STATUS_FAILED;
3794 	}
3795 
3796 	if (cp->ack) {
3797 		struct btp_mesh_health_period_set_rp *rp = rsp;
3798 
3799 		rp->divisor = updated_divisor;
3800 
3801 		*rsp_len = sizeof(*rp);
3802 	}
3803 
3804 	return BTP_STATUS_SUCCESS;
3805 }
3806 
health_attention_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3807 static uint8_t health_attention_get(const void *cmd, uint16_t cmd_len,
3808 				    void *rsp, uint16_t *rsp_len)
3809 {
3810 	const struct btp_mesh_health_attention_get_cmd *cp = cmd;
3811 	struct bt_mesh_msg_ctx ctx = {
3812 		.net_idx = net.net_idx,
3813 		.addr = sys_le16_to_cpu(cp->address),
3814 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3815 	};
3816 	uint8_t attention;
3817 	int err;
3818 
3819 	LOG_DBG("");
3820 
3821 	err = bt_mesh_health_cli_attention_get(&health_cli, &ctx, &attention);
3822 
3823 	if (err) {
3824 		LOG_ERR("err %d", err);
3825 		return BTP_STATUS_FAILED;
3826 	}
3827 
3828 	return BTP_STATUS_SUCCESS;
3829 }
3830 
health_attention_set(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3831 static uint8_t health_attention_set(const void *cmd, uint16_t cmd_len,
3832 				    void *rsp, uint16_t *rsp_len)
3833 {
3834 	const struct btp_mesh_health_attention_set_cmd *cp = cmd;
3835 	struct bt_mesh_msg_ctx ctx = {
3836 		.net_idx = net.net_idx,
3837 		.addr = sys_le16_to_cpu(cp->address),
3838 		.app_idx = sys_le16_to_cpu(cp->app_idx),
3839 	};
3840 	uint8_t updated_attention;
3841 	int err;
3842 
3843 	LOG_DBG("");
3844 
3845 	if (cp->ack) {
3846 		err = bt_mesh_health_cli_attention_set(&health_cli, &ctx, cp->attention,
3847 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
3848 						       bt_mesh_op_agg_cli_seq_is_started() ?
3849 						       NULL :
3850 #endif
3851 						       &updated_attention);
3852 	} else {
3853 		err = bt_mesh_health_cli_attention_set_unack(&health_cli, &ctx, cp->attention);
3854 	}
3855 
3856 	if (err) {
3857 		LOG_ERR("err %d", err);
3858 		return BTP_STATUS_FAILED;
3859 	}
3860 
3861 	if (cp->ack) {
3862 		struct btp_mesh_health_attention_set_rp *rp = rsp;
3863 
3864 		rp->attention = updated_attention;
3865 
3866 		*rsp_len = sizeof(*rp);
3867 	}
3868 
3869 	return BTP_STATUS_SUCCESS;
3870 }
3871 
3872 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
opcodes_aggregator_init(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3873 static uint8_t opcodes_aggregator_init(const void *cmd, uint16_t cmd_len,
3874 				       void *rsp, uint16_t *rsp_len)
3875 {
3876 	const struct btp_mesh_opcodes_aggregator_init_cmd *cp = cmd;
3877 	int err;
3878 
3879 	LOG_DBG("");
3880 
3881 	err = bt_mesh_op_agg_cli_seq_start(cp->net_idx, cp->app_idx, cp->dst, cp->elem_addr);
3882 	if (err) {
3883 		LOG_ERR("Failed to init Opcodes Aggregator Context (err %d)", err);
3884 		return BTP_STATUS_FAILED;
3885 	}
3886 
3887 	return BTP_STATUS_SUCCESS;
3888 }
3889 
opcodes_aggregator_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3890 static uint8_t opcodes_aggregator_send(const void *cmd, uint16_t cmd_len,
3891 				       void *rsp, uint16_t *rsp_len)
3892 {
3893 	int err;
3894 
3895 	LOG_DBG("");
3896 
3897 	err = bt_mesh_op_agg_cli_seq_send();
3898 	if (err) {
3899 		LOG_ERR("Failed to send Opcodes Aggregator message (err %d)", err);
3900 		return BTP_STATUS_FAILED;
3901 	}
3902 
3903 	return BTP_STATUS_SUCCESS;
3904 }
3905 #endif
3906 
3907 #if defined(CONFIG_BT_MESH_RPR_CLI)
rpr_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3908 static uint8_t rpr_scan_start(const void *cmd, uint16_t cmd_len,
3909 			      void *rsp, uint16_t *rsp_len)
3910 {
3911 	const struct btp_rpr_scan_start_cmd *cp = cmd;
3912 
3913 	struct bt_mesh_rpr_scan_status status;
3914 	const struct bt_mesh_rpr_node srv = {
3915 		.addr = cp->dst,
3916 		.net_idx = net.net_idx,
3917 		.ttl = BT_MESH_TTL_DEFAULT,
3918 	};
3919 	uint8_t uuid[16] = {0};
3920 	int err;
3921 
3922 	err = bt_mesh_rpr_scan_start(&rpr_cli, &srv,
3923 				     memcmp(uuid, cp->uuid, 16) ? cp->uuid : NULL,
3924 				     cp->timeout,
3925 				     BT_MESH_RPR_SCAN_MAX_DEVS_ANY, &status);
3926 
3927 	if (err) {
3928 		LOG_ERR("Scan start failed: %d", err);
3929 		return BTP_STATUS_FAILED;
3930 	}
3931 
3932 	return BTP_STATUS_SUCCESS;
3933 }
3934 
rpr_ext_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3935 static uint8_t rpr_ext_scan_start(const void *cmd, uint16_t cmd_len,
3936 				  void *rsp, uint16_t *rsp_len)
3937 {
3938 	const struct btp_rpr_ext_scan_start_cmd *cp = cmd;
3939 	const struct bt_mesh_rpr_node srv = {
3940 		.addr = cp->dst,
3941 		.net_idx = net.net_idx,
3942 		.ttl = BT_MESH_TTL_DEFAULT,
3943 	};
3944 	int err;
3945 
3946 	err = bt_mesh_rpr_scan_start_ext(&rpr_cli, &srv, cp->uuid,
3947 					 cp->timeout, cp->ad_types,
3948 					 cp->ad_count);
3949 	if (err) {
3950 		LOG_ERR("Scan start failed: %d", err);
3951 		return BTP_STATUS_FAILED;
3952 	}
3953 
3954 	return BTP_STATUS_SUCCESS;
3955 }
3956 
rpr_scan_caps_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3957 static uint8_t rpr_scan_caps_get(const void *cmd, uint16_t cmd_len,
3958 				 void *rsp, uint16_t *rsp_len)
3959 {
3960 	const struct btp_rpr_scan_caps_get_cmd *cp = cmd;
3961 	struct bt_mesh_rpr_caps caps;
3962 	const struct bt_mesh_rpr_node srv = {
3963 		.addr = cp->dst,
3964 		.net_idx = net.net_idx,
3965 		.ttl = BT_MESH_TTL_DEFAULT,
3966 	};
3967 	int err;
3968 
3969 	err = bt_mesh_rpr_scan_caps_get(&rpr_cli, &srv, &caps);
3970 	if (err) {
3971 		LOG_ERR("Scan capabilities get failed: %d", err);
3972 		return BTP_STATUS_FAILED;
3973 	}
3974 
3975 	LOG_DBG("Remote Provisioning scan capabilities of 0x%04x:",
3976 		net.dst);
3977 	LOG_DBG("\tMax devices:     %u", caps.max_devs);
3978 	LOG_DBG("\tActive scanning: %s",
3979 		    caps.active_scan ? "true" : "false");
3980 
3981 	return BTP_STATUS_SUCCESS;
3982 }
3983 
rpr_scan_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)3984 static uint8_t rpr_scan_get(const void *cmd, uint16_t cmd_len,
3985 			    void *rsp, uint16_t *rsp_len)
3986 {
3987 	const struct btp_rpr_scan_get_cmd *cp = cmd;
3988 	struct bt_mesh_rpr_scan_status status;
3989 	const struct bt_mesh_rpr_node srv = {
3990 		.addr = cp->dst,
3991 		.net_idx = net.net_idx,
3992 		.ttl = BT_MESH_TTL_DEFAULT,
3993 	};
3994 	int err;
3995 
3996 	err = bt_mesh_rpr_scan_get(&rpr_cli, &srv, &status);
3997 	if (err) {
3998 		LOG_ERR("Scan get failed: %d", err);
3999 		return BTP_STATUS_FAILED;
4000 	}
4001 
4002 	LOG_DBG("Remote Provisioning scan on 0x%04x:", cp->dst);
4003 	LOG_DBG("\tStatus:         %u", status.status);
4004 	LOG_DBG("\tScan type:      %u", status.scan);
4005 	LOG_DBG("\tMax devices:    %u", status.max_devs);
4006 	LOG_DBG("\tRemaining time: %u", status.timeout);
4007 
4008 	return BTP_STATUS_SUCCESS;
4009 }
4010 
rpr_scan_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4011 static uint8_t rpr_scan_stop(const void *cmd, uint16_t cmd_len,
4012 			     void *rsp, uint16_t *rsp_len)
4013 {
4014 	const struct btp_rpr_scan_stop_cmd *cp = cmd;
4015 	struct bt_mesh_rpr_scan_status status;
4016 	const struct bt_mesh_rpr_node srv = {
4017 		.addr = cp->dst,
4018 		.net_idx = net.net_idx,
4019 		.ttl = BT_MESH_TTL_DEFAULT,
4020 	};
4021 	int err;
4022 
4023 	err = bt_mesh_rpr_scan_stop(&rpr_cli, &srv, &status);
4024 	if (err || status.status) {
4025 		LOG_DBG("Scan stop failed: %d %u", err, status.status);
4026 		return BTP_STATUS_FAILED;
4027 	}
4028 
4029 	LOG_DBG("Remote Provisioning scan on 0x%04x stopped.",
4030 		    net.dst);
4031 
4032 	return BTP_STATUS_SUCCESS;
4033 }
4034 
rpr_link_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4035 static uint8_t rpr_link_get(const void *cmd, uint16_t cmd_len,
4036 			    void *rsp, uint16_t *rsp_len)
4037 {
4038 	const struct btp_rpr_link_get_cmd *cp = cmd;
4039 	struct bt_mesh_rpr_link link;
4040 	const struct bt_mesh_rpr_node srv = {
4041 		.addr = cp->dst,
4042 		.net_idx = net.net_idx,
4043 		.ttl = BT_MESH_TTL_DEFAULT,
4044 	};
4045 	int err;
4046 
4047 	err = bt_mesh_rpr_link_get(&rpr_cli, &srv, &link);
4048 	if (err) {
4049 		LOG_ERR("Link get failed: %d %u", err, link.status);
4050 		return BTP_STATUS_FAILED;
4051 	}
4052 
4053 	LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst);
4054 	LOG_DBG("\tStatus: %u", link.status);
4055 	LOG_DBG("\tState:  %u", link.state);
4056 
4057 	return BTP_STATUS_SUCCESS;
4058 }
4059 
rpr_link_close(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4060 static uint8_t rpr_link_close(const void *cmd, uint16_t cmd_len,
4061 			      void *rsp, uint16_t *rsp_len)
4062 {
4063 	const struct btp_rpr_link_close_cmd *cp = cmd;
4064 	struct bt_mesh_rpr_link link;
4065 	const struct bt_mesh_rpr_node srv = {
4066 		.addr = cp->dst,
4067 		.net_idx = net.net_idx,
4068 		.ttl = BT_MESH_TTL_DEFAULT,
4069 	};
4070 	int err;
4071 
4072 	err = bt_mesh_rpr_link_close(&rpr_cli, &srv, &link);
4073 	if (err) {
4074 		LOG_ERR("Link close failed: %d %u", err, link.status);
4075 		return BTP_STATUS_FAILED;
4076 	}
4077 
4078 	LOG_DBG("Remote Provisioning Link on 0x%04x:", cp->dst);
4079 	LOG_DBG("\tStatus: %u", link.status);
4080 	LOG_DBG("\tState:  %u", link.state);
4081 
4082 	return BTP_STATUS_SUCCESS;
4083 }
4084 
rpr_prov_remote(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4085 static uint8_t rpr_prov_remote(const void *cmd, uint16_t cmd_len,
4086 			       void *rsp, uint16_t *rsp_len)
4087 {
4088 	const struct btp_rpr_prov_remote_cmd *cp = cmd;
4089 	struct bt_mesh_rpr_node srv = {
4090 		.addr = cp->dst,
4091 		.net_idx = net.net_idx,
4092 		.ttl = BT_MESH_TTL_DEFAULT,
4093 	};
4094 	int err;
4095 
4096 	err = bt_mesh_provision_remote(&rpr_cli, &srv, cp->uuid,
4097 				       cp->net_idx, cp->addr);
4098 	if (err) {
4099 		LOG_ERR("Prov remote start failed: %d", err);
4100 		return BTP_STATUS_FAILED;
4101 	}
4102 
4103 	return BTP_STATUS_SUCCESS;
4104 }
4105 
rpr_reprov_remote(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4106 static uint8_t rpr_reprov_remote(const void *cmd, uint16_t cmd_len,
4107 				 void *rsp, uint16_t *rsp_len)
4108 {
4109 	const struct btp_rpr_reprov_remote_cmd *cp = cmd;
4110 	struct bt_mesh_rpr_node srv = {
4111 		.addr = cp->dst,
4112 		.net_idx = net.net_idx,
4113 		.ttl = BT_MESH_TTL_DEFAULT,
4114 	};
4115 	int err;
4116 
4117 	if (!BT_MESH_ADDR_IS_UNICAST(cp->addr)) {
4118 		LOG_ERR("Must be a valid unicast address");
4119 		err = -EINVAL;
4120 		return BTP_STATUS_FAILED;
4121 	}
4122 
4123 	err = bt_mesh_reprovision_remote(&rpr_cli, &srv, cp->addr,
4124 					 cp->comp_change);
4125 	if (err) {
4126 		LOG_ERR("Reprovisioning failed: %d", err);
4127 		return BTP_STATUS_FAILED;
4128 	}
4129 
4130 	return BTP_STATUS_SUCCESS;
4131 }
4132 #endif
4133 
4134 #if defined(CONFIG_BT_MESH_DFD_SRV)
4135 static struct {
4136 	struct bt_mesh_dfu_target targets[32];
4137 	struct bt_mesh_blob_target_pull pull[32];
4138 	size_t target_cnt;
4139 	struct bt_mesh_blob_cli_inputs inputs;
4140 } dfu_tx;
4141 
dfu_tx_prepare(void)4142 static void dfu_tx_prepare(void)
4143 {
4144 	sys_slist_init(&dfu_tx.inputs.targets);
4145 
4146 	for (int i = 0; i < dfu_tx.target_cnt; i++) {
4147 		/* Reset target context. */
4148 		uint16_t addr = dfu_tx.targets[i].blob.addr;
4149 
4150 		memset(&dfu_tx.targets[i].blob, 0,
4151 		       sizeof(struct bt_mesh_blob_target));
4152 		memset(&dfu_tx.pull[i], 0,
4153 		       sizeof(struct bt_mesh_blob_target_pull));
4154 		dfu_tx.targets[i].blob.addr = addr;
4155 		dfu_tx.targets[i].blob.pull = &dfu_tx.pull[i];
4156 
4157 		sys_slist_append(&dfu_tx.inputs.targets,
4158 				 &dfu_tx.targets[i].blob.n);
4159 	}
4160 }
4161 
dfu_target(uint8_t img_idx,uint16_t addr)4162 static void dfu_target(uint8_t img_idx, uint16_t addr)
4163 {
4164 	if (dfu_tx.target_cnt == ARRAY_SIZE(dfu_tx.targets)) {
4165 		LOG_ERR("No room.");
4166 		return;
4167 	}
4168 
4169 	for (int i = 0; i < dfu_tx.target_cnt; i++) {
4170 		if (dfu_tx.targets[i].blob.addr == addr) {
4171 			LOG_ERR("Target 0x%04x already exists", addr);
4172 			return;
4173 		}
4174 	}
4175 
4176 	dfu_tx.targets[dfu_tx.target_cnt].blob.addr = addr;
4177 	dfu_tx.targets[dfu_tx.target_cnt].img_idx = img_idx;
4178 	sys_slist_append(&dfu_tx.inputs.targets,
4179 			 &dfu_tx.targets[dfu_tx.target_cnt].blob.n);
4180 	dfu_tx.target_cnt++;
4181 
4182 	LOG_DBG("Added target 0x%04x", addr);
4183 }
dfu_slot_add(size_t size,uint8_t * fwid,size_t fwid_len,uint8_t * metadata,size_t metadata_len)4184 static void dfu_slot_add(size_t size, uint8_t *fwid, size_t fwid_len,
4185 			 uint8_t *metadata, size_t metadata_len)
4186 {
4187 	struct bt_mesh_dfu_slot *slot;
4188 	int err;
4189 
4190 	slot = bt_mesh_dfu_slot_reserve();
4191 	err = bt_mesh_dfu_slot_info_set(slot, size, metadata, metadata_len);
4192 	if (err) {
4193 		LOG_ERR("Failed to set slot info: %d", err);
4194 		return;
4195 	}
4196 
4197 	err = bt_mesh_dfu_slot_fwid_set(slot, fwid, fwid_len);
4198 	if (err) {
4199 		LOG_ERR("Failed to set slot fwid: %d", err);
4200 		return;
4201 	}
4202 
4203 	err = bt_mesh_dfu_slot_commit(slot);
4204 	if (err) {
4205 		LOG_ERR("Failed to commit slot: %d", err);
4206 		return;
4207 	}
4208 
4209 	LOG_DBG("Slot added.");
4210 }
dfu_img_cb(struct bt_mesh_dfu_cli * cli,struct bt_mesh_msg_ctx * ctx,uint8_t idx,uint8_t total,const struct bt_mesh_dfu_img * img,void * cb_data)4211 static enum bt_mesh_dfu_iter dfu_img_cb(struct bt_mesh_dfu_cli *cli,
4212 					struct bt_mesh_msg_ctx *ctx,
4213 					uint8_t idx, uint8_t total,
4214 					const struct bt_mesh_dfu_img *img,
4215 					void *cb_data)
4216 {
4217 	char fwid[2 * CONFIG_BT_MESH_DFU_FWID_MAXLEN + 1];
4218 	size_t len;
4219 
4220 	idx = 0xff;
4221 
4222 	if (img->fwid_len <= sizeof(fwid)) {
4223 		len = bin2hex(img->fwid, img->fwid_len, fwid, sizeof(fwid));
4224 	} else {
4225 		LOG_ERR("FWID is too big");
4226 		return BT_MESH_DFU_ITER_STOP;
4227 	}
4228 
4229 	fwid[len] = '\0';
4230 
4231 	LOG_DBG("Image %u:", idx);
4232 	LOG_DBG("\tFWID: ");
4233 	if (img->uri) {
4234 		LOG_DBG("\tURI:  ");
4235 	}
4236 
4237 	return BT_MESH_DFU_ITER_CONTINUE;
4238 }
4239 
dfu_info_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4240 static uint8_t dfu_info_get(const void *cmd, uint16_t cmd_len,
4241 			    void *rsp, uint16_t *rsp_len)
4242 {
4243 	const struct btp_mmdl_dfu_info_get_cmd *cp = cmd;
4244 	struct model_data *model_bound;
4245 	struct bt_mesh_msg_ctx ctx = {
4246 		.net_idx = net.net_idx,
4247 		.send_ttl = BT_MESH_TTL_DEFAULT,
4248 	};
4249 	uint8_t max_count;
4250 	int err = 0;
4251 
4252 	LOG_DBG("");
4253 
4254 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4255 	if (!model_bound) {
4256 		LOG_ERR("Model not found");
4257 		return BTP_STATUS_FAILED;
4258 	}
4259 	ctx.addr = model_bound->addr;
4260 	ctx.app_idx = model_bound->appkey_idx;
4261 
4262 	max_count = cp->limit;
4263 
4264 	err = bt_mesh_dfu_cli_imgs_get(&dfd_srv.dfu, &ctx, dfu_img_cb, NULL,
4265 				       max_count);
4266 	if (err) {
4267 		return BTP_STATUS_FAILED;
4268 	}
4269 
4270 	return BTP_STATUS_SUCCESS;
4271 }
4272 
dfu_update_metadata_check(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4273 static uint8_t dfu_update_metadata_check(const void *cmd, uint16_t cmd_len,
4274 					 void *rsp, uint16_t *rsp_len)
4275 {
4276 	const struct btp_mmdl_dfu_metadata_check_cmd *cp = cmd;
4277 	struct btp_mmdl_dfu_metadata_check_rp *rp = rsp;
4278 	const struct bt_mesh_dfu_slot *slot;
4279 	struct model_data *model_bound;
4280 	struct bt_mesh_msg_ctx ctx = {
4281 		.net_idx = net.net_idx,
4282 		.send_ttl = BT_MESH_TTL_DEFAULT,
4283 	};
4284 	struct bt_mesh_dfu_metadata_status rsp_data;
4285 	uint8_t img_idx, slot_idx;
4286 	size_t size;
4287 	size_t fwid_len;
4288 	size_t metadata_len;
4289 	uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
4290 	uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
4291 	int err;
4292 
4293 	LOG_DBG("");
4294 
4295 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4296 	if (!model_bound) {
4297 		LOG_ERR("Model not found");
4298 		return BTP_STATUS_FAILED;
4299 	}
4300 
4301 	ctx.addr = model_bound->addr;
4302 	ctx.app_idx = model_bound->appkey_idx;
4303 	img_idx = cp->index;
4304 	slot_idx = cp->slot_idx;
4305 	size = cp->slot_size;
4306 	fwid_len = cp->fwid_len;
4307 	metadata_len = cp->metadata_len;
4308 
4309 	if ((metadata_len > 0) &&
4310 		(metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) {
4311 		memcpy(&metadata, cp->data, metadata_len);
4312 	}
4313 
4314 	dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len);
4315 
4316 	slot = bt_mesh_dfu_slot_at(slot_idx);
4317 	if (!slot) {
4318 		LOG_ERR("No image in slot %u", slot_idx);
4319 		return BTP_STATUS_FAILED;
4320 	}
4321 
4322 	err = bt_mesh_dfu_cli_metadata_check(&dfd_srv.dfu, &ctx, img_idx, slot,
4323 					     &rsp_data);
4324 
4325 	if (err) {
4326 		LOG_ERR("ERR %d", err);
4327 		return BTP_STATUS_FAILED;
4328 	}
4329 
4330 	rp->idx = rsp_data.idx;
4331 	rp->status = rsp_data.status;
4332 	rp->effect = rsp_data.effect;
4333 
4334 	*rsp_len = sizeof(struct btp_mmdl_dfu_metadata_check_rp);
4335 
4336 	return BTP_STATUS_SUCCESS;
4337 }
4338 
dfu_firmware_update_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4339 static uint8_t dfu_firmware_update_get(const void *cmd, uint16_t cmd_len,
4340 				       void *rsp, uint16_t *rsp_len)
4341 {
4342 	struct model_data *model_bound;
4343 	struct bt_mesh_msg_ctx ctx = {
4344 		.net_idx = net.net_idx,
4345 		.send_ttl = BT_MESH_TTL_DEFAULT,
4346 	};
4347 	struct bt_mesh_dfu_target_status rsp_data;
4348 	struct btp_mmdl_dfu_firmware_update_rp *rp = rsp;
4349 	int err;
4350 
4351 	LOG_DBG("");
4352 
4353 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4354 	if (!model_bound) {
4355 		LOG_ERR("Model not found");
4356 		return BTP_STATUS_FAILED;
4357 	}
4358 
4359 	ctx.addr = model_bound->addr;
4360 	ctx.app_idx = model_bound->appkey_idx;
4361 
4362 	err = bt_mesh_dfu_cli_status_get(&dfd_srv.dfu, &ctx, &rsp_data);
4363 	if (err) {
4364 		LOG_ERR("err %d", err);
4365 		return BTP_STATUS_FAILED;
4366 	}
4367 
4368 	rp->status = rsp_data.status;
4369 	*rsp_len = sizeof(struct btp_mmdl_dfu_firmware_update_rp);
4370 	return BTP_STATUS_SUCCESS;
4371 }
4372 
dfu_firmware_update_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4373 static uint8_t dfu_firmware_update_cancel(const void *cmd, uint16_t cmd_len,
4374 					  void *rsp, uint16_t *rsp_len)
4375 {
4376 	struct model_data *model_bound;
4377 	struct bt_mesh_msg_ctx ctx = {
4378 		.net_idx = net.net_idx,
4379 		.send_ttl = BT_MESH_TTL_DEFAULT,
4380 	};
4381 	int err;
4382 
4383 	LOG_DBG("");
4384 
4385 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4386 	if (!model_bound) {
4387 		LOG_ERR("Model not found");
4388 		return BTP_STATUS_FAILED;
4389 	}
4390 
4391 	ctx.addr = model_bound->addr;
4392 	ctx.app_idx = model_bound->appkey_idx;
4393 
4394 	err = bt_mesh_dfu_cli_cancel(&dfd_srv.dfu, &ctx);
4395 	if (err) {
4396 		LOG_ERR("err %d", err);
4397 		return BTP_STATUS_FAILED;
4398 	}
4399 
4400 	return BTP_STATUS_SUCCESS;
4401 }
4402 
dfu_firmware_update_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4403 static uint8_t dfu_firmware_update_start(const void *cmd, uint16_t cmd_len,
4404 					 void *rsp, uint16_t *rsp_len)
4405 {
4406 	const struct btp_mmdl_dfu_firmware_update_cmd *cp = cmd;
4407 	struct model_data *model_bound;
4408 	struct bt_mesh_dfu_cli_xfer xfer;
4409 	uint8_t addr_cnt;
4410 	uint16_t addr = BT_MESH_ADDR_UNASSIGNED;
4411 	uint8_t slot_idx;
4412 	size_t size;
4413 	size_t fwid_len;
4414 	size_t metadata_len;
4415 	uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
4416 	uint8_t metadata[CONFIG_BT_MESH_DFU_METADATA_MAXLEN];
4417 	int err = 0;
4418 	int i = 0;
4419 
4420 	LOG_DBG("");
4421 
4422 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4423 	if (!model_bound) {
4424 		LOG_ERR("Model not found");
4425 		return BTP_STATUS_FAILED;
4426 	}
4427 
4428 	struct bt_mesh_dfu_cli_xfer_blob_params blob = {
4429 		.block_size_log = cp->block_size,
4430 		.chunk_size = cp->chunk_size,
4431 	};
4432 
4433 	addr_cnt = cp->addr_cnt;
4434 	slot_idx = cp->slot_idx;
4435 	size = cp->slot_size;
4436 	fwid_len = cp->fwid_len;
4437 	metadata_len = cp->metadata_len;
4438 	xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH;
4439 	xfer.blob_params = &blob;
4440 
4441 	if ((metadata_len > 0) &&
4442 		(metadata_len < CONFIG_BT_MESH_DFU_METADATA_MAXLEN)) {
4443 		memcpy(&metadata, cp->data, metadata_len);
4444 	}
4445 
4446 	bt_mesh_dfu_slot_del_all();
4447 
4448 	dfu_slot_add(size, fwid, fwid_len, metadata, metadata_len);
4449 
4450 	xfer.slot = bt_mesh_dfu_slot_at(slot_idx);
4451 	if (!xfer.slot) {
4452 		LOG_ERR("No image in slot %u", slot_idx);
4453 		return BTP_STATUS_FAILED;
4454 	}
4455 
4456 	for (i = 0; i < addr_cnt; i++) {
4457 		addr = cp->data[metadata_len + 1 + i * sizeof(uint16_t)] |
4458 			(cp->data[metadata_len + i * sizeof(uint16_t)] << 8);
4459 		dfu_target(slot_idx, addr);
4460 	}
4461 
4462 	dfu_tx_prepare();
4463 
4464 	if (!dfu_tx.target_cnt) {
4465 		LOG_ERR("No targets.");
4466 		return BTP_STATUS_FAILED;
4467 	}
4468 
4469 	if (addr_cnt > 1) {
4470 		dfu_tx.inputs.group = BT_MESH_ADDR_UNASSIGNED;
4471 	} else {
4472 		dfu_tx.inputs.group = addr;
4473 	}
4474 
4475 	dfu_tx.inputs.app_idx = model_bound->appkey_idx;
4476 	dfu_tx.inputs.ttl = BT_MESH_TTL_DEFAULT;
4477 
4478 	err = bt_mesh_dfu_cli_send(&dfd_srv.dfu, &dfu_tx.inputs, &dummy_blob_io, &xfer);
4479 
4480 	if (err) {
4481 		LOG_ERR("err %d", err);
4482 		return BTP_STATUS_FAILED;
4483 	}
4484 
4485 	return BTP_STATUS_SUCCESS;
4486 }
4487 
dfu_firmware_update_apply(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4488 static uint8_t dfu_firmware_update_apply(const void *cmd, uint16_t cmd_len,
4489 					 void *rsp, uint16_t *rsp_len)
4490 {
4491 	struct model_data *model_bound;
4492 	int err;
4493 
4494 	LOG_DBG("");
4495 
4496 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_DFU_CLI);
4497 	if (!model_bound) {
4498 		LOG_ERR("Model not found");
4499 		return BTP_STATUS_FAILED;
4500 	}
4501 
4502 	err = bt_mesh_dfu_cli_apply(&dfd_srv.dfu);
4503 	if (err) {
4504 		LOG_ERR("err %d", err);
4505 		return BTP_STATUS_FAILED;
4506 	}
4507 
4508 	return BTP_STATUS_SUCCESS;
4509 }
4510 #endif
4511 
4512 #if defined(CONFIG_BT_MESH_BLOB_CLI)
blob_cli_inputs_prepare(uint16_t group,uint16_t app_idx)4513 static void blob_cli_inputs_prepare(uint16_t group, uint16_t app_idx)
4514 {
4515 	int i;
4516 
4517 	blob_cli_xfer.inputs.ttl = BT_MESH_TTL_DEFAULT;
4518 	blob_cli_xfer.inputs.group = group;
4519 	blob_cli_xfer.inputs.app_idx = app_idx;
4520 	sys_slist_init(&blob_cli_xfer.inputs.targets);
4521 
4522 	for (i = 0; i < blob_cli_xfer.target_count; ++i) {
4523 		/* Reset target context. */
4524 		uint16_t addr = blob_cli_xfer.targets[i].addr;
4525 
4526 		memset(&blob_cli_xfer.targets[i], 0,
4527 		       sizeof(struct bt_mesh_blob_target));
4528 		memset(&blob_cli_xfer.pull[i], 0,
4529 		       sizeof(struct bt_mesh_blob_target_pull));
4530 		blob_cli_xfer.targets[i].addr = addr;
4531 		blob_cli_xfer.targets[i].pull = &blob_cli_xfer.pull[i];
4532 
4533 		sys_slist_append(&blob_cli_xfer.inputs.targets,
4534 				 &blob_cli_xfer.targets[i].n);
4535 	}
4536 }
4537 
cmd_blob_target(uint16_t addr)4538 static int cmd_blob_target(uint16_t addr)
4539 {
4540 	struct bt_mesh_blob_target *t;
4541 
4542 	if (blob_cli_xfer.target_count == ARRAY_SIZE(blob_cli_xfer.targets)) {
4543 		LOG_ERR("No more room");
4544 		return 0;
4545 	}
4546 
4547 	t = &blob_cli_xfer.targets[blob_cli_xfer.target_count];
4548 
4549 	t->addr = addr;
4550 
4551 	LOG_DBG("Added target 0x%04x", t->addr);
4552 
4553 	blob_cli_xfer.target_count++;
4554 	return 0;
4555 }
4556 
blob_info_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4557 static uint8_t blob_info_get(const void *cmd, uint16_t cmd_len,
4558 			     void *rsp, uint16_t *rsp_len)
4559 {
4560 	const struct btp_mmdl_blob_info_get_cmd *cp = cmd;
4561 	struct model_data *model_bound;
4562 	uint16_t addr = BT_MESH_ADDR_UNASSIGNED;
4563 	uint16_t group = BT_MESH_ADDR_UNASSIGNED;
4564 	int err;
4565 
4566 	LOG_DBG("");
4567 
4568 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4569 	if (!model_bound) {
4570 		LOG_ERR("Model not found");
4571 		return BTP_STATUS_FAILED;
4572 	}
4573 
4574 	for (int i = 0; i < cp->addr_cnt; i++) {
4575 		addr = cp->addr[1 + i * sizeof(uint16_t)] |
4576 			(cp->addr[i * sizeof(uint16_t)] << 8);
4577 		err = cmd_blob_target(addr);
4578 		if (err) {
4579 			LOG_ERR("err target %d", err);
4580 			return BTP_STATUS_FAILED;
4581 		}
4582 	}
4583 
4584 	if (cp->addr_cnt > 1) {
4585 		group = BT_MESH_ADDR_UNASSIGNED;
4586 	} else {
4587 		group = addr;
4588 	}
4589 
4590 	if (!blob_cli_xfer.target_count) {
4591 		LOG_ERR("Failed: No targets");
4592 		return BTP_STATUS_FAILED;
4593 	}
4594 
4595 	blob_cli_inputs_prepare(group, model_bound->appkey_idx);
4596 
4597 	err = bt_mesh_blob_cli_caps_get(&blob_cli, &blob_cli_xfer.inputs);
4598 
4599 	if (err) {
4600 		return BTP_STATUS_FAILED;
4601 	}
4602 
4603 	return BTP_STATUS_SUCCESS;
4604 }
4605 
blob_transfer_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4606 static uint8_t blob_transfer_start(const void *cmd, uint16_t cmd_len,
4607 				   void *rsp, uint16_t *rsp_len)
4608 {
4609 	const struct btp_mmdl_blob_transfer_start_cmd *cp = cmd;
4610 	struct model_data *model_bound;
4611 	int err = 0;
4612 
4613 	LOG_DBG("");
4614 
4615 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4616 	if (!model_bound) {
4617 		LOG_ERR("Model not found");
4618 		return BTP_STATUS_FAILED;
4619 	}
4620 
4621 	if (!blob_cli_xfer.target_count) {
4622 		LOG_ERR("Failed: No targets");
4623 		return BTP_STATUS_FAILED;
4624 	}
4625 	blob_cli_xfer.xfer.id = cp->id;
4626 	blob_cli_xfer.xfer.size = cp->size;
4627 	blob_cli_xfer.xfer.block_size_log = cp->block_size;
4628 	blob_cli_xfer.xfer.chunk_size = cp->chunk_size;
4629 
4630 	if (blob_cli.caps.modes) {
4631 		blob_cli_xfer.xfer.mode = blob_cli.caps.modes;
4632 	} else {
4633 		blob_cli_xfer.xfer.mode = BT_MESH_BLOB_XFER_MODE_PUSH;
4634 	}
4635 
4636 	if (cp->timeout) {
4637 		blob_cli_xfer.inputs.timeout_base = cp->timeout;
4638 	}
4639 
4640 	if (cp->ttl) {
4641 		blob_cli_xfer.inputs.ttl = cp->ttl;
4642 	}
4643 
4644 	err = bt_mesh_blob_cli_send(&blob_cli, &blob_cli_xfer.inputs,
4645 				    &blob_cli_xfer.xfer, &dummy_blob_io);
4646 
4647 	if (err) {
4648 		return BTP_STATUS_FAILED;
4649 	}
4650 
4651 	return BTP_STATUS_SUCCESS;
4652 }
4653 
blob_transfer_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4654 static uint8_t blob_transfer_cancel(const void *cmd, uint16_t cmd_len,
4655 				    void *rsp, uint16_t *rsp_len)
4656 {
4657 	LOG_DBG("");
4658 
4659 	bt_mesh_blob_cli_cancel(&blob_cli);
4660 
4661 	return BTP_STATUS_SUCCESS;
4662 }
4663 
blob_transfer_get(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4664 static uint8_t blob_transfer_get(const void *cmd, uint16_t cmd_len,
4665 				 void *rsp, uint16_t *rsp_len)
4666 {
4667 	struct model_data *model_bound;
4668 	uint16_t group;
4669 	int err;
4670 
4671 	LOG_DBG("");
4672 
4673 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_CLI);
4674 	if (!model_bound) {
4675 		LOG_ERR("Model not found");
4676 		return BTP_STATUS_FAILED;
4677 	}
4678 
4679 	group = model_bound->addr;
4680 
4681 	err = cmd_blob_target(group);
4682 	if (err) {
4683 		LOG_ERR("err target %d", err);
4684 		return BTP_STATUS_FAILED;
4685 	}
4686 
4687 	if (!blob_cli_xfer.target_count) {
4688 		LOG_ERR("Failed: No targets");
4689 		return BTP_STATUS_FAILED;
4690 	}
4691 
4692 	blob_cli_inputs_prepare(group, model_bound->appkey_idx);
4693 
4694 	err = bt_mesh_blob_cli_xfer_progress_get(&blob_cli, &blob_cli_xfer.inputs);
4695 
4696 	if (err) {
4697 		LOG_ERR("ERR %d", err);
4698 		return BTP_STATUS_FAILED;
4699 	}
4700 
4701 	return BTP_STATUS_SUCCESS;
4702 }
4703 #endif /* CONFIG_BT_MESH_BLOB_CLI */
4704 
4705 #if defined(CONFIG_BT_MESH_BLOB_SRV)
blob_srv_recv(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4706 static uint8_t blob_srv_recv(const void *cmd, uint16_t cmd_len,
4707 			     void *rsp, uint16_t *rsp_len)
4708 {
4709 	const struct btp_mmdl_blob_srv_recv_cmd *cp = cmd;
4710 	struct model_data *model_bound;
4711 	int err;
4712 
4713 #if defined(CONFIG_BT_MESH_DFD_SRV)
4714 	struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob;
4715 #elif defined(CONFIG_BT_MESH_DFU_SRV)
4716 	struct bt_mesh_blob_srv *srv = &dfu_srv.blob;
4717 #endif
4718 
4719 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV);
4720 	if (!model_bound) {
4721 		LOG_ERR("Model not found");
4722 		return BTP_STATUS_FAILED;
4723 	}
4724 
4725 	uint16_t timeout_base;
4726 	uint64_t id;
4727 	uint8_t ttl;
4728 
4729 	LOG_DBG("");
4730 
4731 	id = cp->id;
4732 	timeout_base = cp->timeout;
4733 	ttl = cp->ttl;
4734 
4735 	err = bt_mesh_blob_srv_recv(srv, id, &dummy_blob_io, ttl,
4736 				    timeout_base);
4737 
4738 	if (err) {
4739 		LOG_ERR("ERR %d", err);
4740 		return BTP_STATUS_FAILED;
4741 	}
4742 
4743 	return BTP_STATUS_SUCCESS;
4744 }
4745 
blob_srv_cancel(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)4746 static uint8_t blob_srv_cancel(const void *cmd, uint16_t cmd_len,
4747 			       void *rsp, uint16_t *rsp_len)
4748 {
4749 	struct model_data *model_bound;
4750 	int err;
4751 
4752 #if defined(CONFIG_BT_MESH_DFU_SRV)
4753 	struct bt_mesh_blob_srv *srv = &dfu_srv.blob;
4754 #elif defined(CONFIG_BT_MESH_DFD_SRV)
4755 	struct bt_mesh_blob_srv *srv = &dfd_srv.upload.blob;
4756 #endif
4757 
4758 	model_bound = lookup_model_bound(BT_MESH_MODEL_ID_BLOB_SRV);
4759 	if (!model_bound) {
4760 		LOG_ERR("Model not found");
4761 		return BTP_STATUS_FAILED;
4762 	}
4763 
4764 	LOG_DBG("");
4765 
4766 	err = bt_mesh_blob_srv_cancel(srv);
4767 
4768 	if (err) {
4769 		LOG_ERR("ERR %d", err);
4770 		return BTP_STATUS_FAILED;
4771 	}
4772 
4773 	return BTP_STATUS_SUCCESS;
4774 }
4775 #endif
4776 
4777 static const struct btp_handler handlers[] = {
4778 	{
4779 		.opcode = BTP_MESH_READ_SUPPORTED_COMMANDS,
4780 		.index = BTP_INDEX_NONE,
4781 		.expect_len = 0,
4782 		.func = supported_commands,
4783 	},
4784 	{
4785 		.opcode = BTP_MESH_CONFIG_PROVISIONING,
4786 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4787 		.func = config_prov,
4788 	},
4789 	{
4790 		.opcode = BTP_MESH_PROVISION_NODE,
4791 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4792 		.func = provision_node,
4793 	},
4794 	{
4795 		.opcode = BTP_MESH_INIT,
4796 		.expect_len = sizeof(struct btp_mesh_init_cmd),
4797 		.func = init,
4798 	},
4799 	{
4800 		.opcode = BTP_MESH_RESET,
4801 		.expect_len = 0,
4802 		.func = reset,
4803 	},
4804 	{
4805 		.opcode = BTP_MESH_INPUT_NUMBER,
4806 		.expect_len = sizeof(struct btp_mesh_input_number_cmd),
4807 		.func = input_number,
4808 	},
4809 	{
4810 		.opcode = BTP_MESH_INPUT_STRING,
4811 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4812 		.func = input_string,
4813 	},
4814 	{
4815 		.opcode = BTP_MESH_IVU_TEST_MODE,
4816 		.expect_len = sizeof(struct btp_mesh_ivu_test_mode_cmd),
4817 		.func = ivu_test_mode,
4818 	},
4819 	{
4820 		.opcode = BTP_MESH_IVU_TOGGLE_STATE,
4821 		.expect_len = 0,
4822 		.func = ivu_toggle_state,
4823 	},
4824 #if defined(CONFIG_BT_MESH_LOW_POWER)
4825 	{
4826 		.opcode = BTP_MESH_LPN,
4827 		.expect_len = sizeof(struct btp_mesh_lpn_set_cmd),
4828 		.func = lpn,
4829 	},
4830 	{
4831 		.opcode = BTP_MESH_LPN_POLL,
4832 		.expect_len = 0,
4833 		.func = lpn_poll,
4834 	},
4835 #endif /* CONFIG_BT_MESH_LOW_POWER */
4836 	{
4837 		.opcode = BTP_MESH_NET_SEND,
4838 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4839 		.func = net_send,
4840 	},
4841 	{
4842 		.opcode = BTP_MESH_HEALTH_GENERATE_FAULTS,
4843 		.expect_len = 0,
4844 		.func = health_generate_faults,
4845 	},
4846 	{
4847 		.opcode = BTP_MESH_HEALTH_CLEAR_FAULTS,
4848 		.expect_len = 0,
4849 		.func = health_clear_faults,
4850 	},
4851 	{
4852 		.opcode = BTP_MESH_MODEL_SEND,
4853 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
4854 		.func = model_send,
4855 	},
4856 	{
4857 		.opcode = BTP_MESH_COMP_DATA_GET,
4858 		.expect_len = sizeof(struct btp_mesh_comp_data_get_cmd),
4859 		.func = composition_data_get,
4860 	},
4861 	{
4862 		.opcode = BTP_MESH_CFG_BEACON_GET,
4863 		.expect_len = sizeof(struct btp_mesh_cfg_beacon_get_cmd),
4864 		.func = config_beacon_get,
4865 	},
4866 	{
4867 		.opcode = BTP_MESH_CFG_BEACON_SET,
4868 		.expect_len = sizeof(struct btp_mesh_cfg_beacon_set_cmd),
4869 		.func = config_beacon_set,
4870 	},
4871 	{
4872 		.opcode = BTP_MESH_CFG_DEFAULT_TTL_GET,
4873 		.expect_len = sizeof(struct btp_mesh_cfg_default_ttl_get_cmd),
4874 		.func = config_default_ttl_get,
4875 	},
4876 	{
4877 		.opcode = BTP_MESH_CFG_DEFAULT_TTL_SET,
4878 		.expect_len = sizeof(struct btp_mesh_cfg_default_ttl_set_cmd),
4879 		.func = config_default_ttl_set,
4880 	},
4881 	{
4882 		.opcode = BTP_MESH_CFG_GATT_PROXY_GET,
4883 		.expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_get_cmd),
4884 		.func = config_gatt_proxy_get,
4885 	},
4886 	{
4887 		.opcode = BTP_MESH_CFG_GATT_PROXY_SET,
4888 		.expect_len = sizeof(struct btp_mesh_cfg_gatt_proxy_set_cmd),
4889 		.func = config_gatt_proxy_set,
4890 	},
4891 	{
4892 		.opcode = BTP_MESH_CFG_FRIEND_GET,
4893 		.expect_len = sizeof(struct btp_mesh_cfg_friend_get_cmd),
4894 		.func = config_friend_get,
4895 	},
4896 	{
4897 		.opcode = BTP_MESH_CFG_FRIEND_SET,
4898 		.expect_len = sizeof(struct btp_mesh_cfg_friend_set_cmd),
4899 		.func = config_friend_set,
4900 	},
4901 	{
4902 		.opcode = BTP_MESH_CFG_RELAY_GET,
4903 		.expect_len = sizeof(struct btp_mesh_cfg_relay_get_cmd),
4904 		.func = config_relay_get,
4905 	},
4906 	{
4907 		.opcode = BTP_MESH_CFG_RELAY_SET,
4908 		.expect_len = sizeof(struct btp_mesh_cfg_relay_set_cmd),
4909 		.func = config_relay_set,
4910 	},
4911 	{
4912 		.opcode = BTP_MESH_CFG_MODEL_PUB_GET,
4913 		.expect_len = sizeof(struct btp_mesh_cfg_model_pub_get_cmd),
4914 		.func = config_mod_pub_get,
4915 	},
4916 	{
4917 		.opcode = BTP_MESH_CFG_MODEL_PUB_SET,
4918 		.expect_len = sizeof(struct btp_mesh_cfg_model_pub_set_cmd),
4919 		.func = config_mod_pub_set,
4920 	},
4921 	{
4922 		.opcode = BTP_MESH_CFG_MODEL_SUB_ADD,
4923 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_add_cmd),
4924 		.func = config_mod_sub_add,
4925 	},
4926 	{
4927 		.opcode = BTP_MESH_CFG_MODEL_SUB_DEL,
4928 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_del_cmd),
4929 		.func = config_mod_sub_del,
4930 	},
4931 	{
4932 		.opcode = BTP_MESH_CFG_MODEL_SUB_OVW,
4933 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_ovw_cmd),
4934 		.func = config_mod_sub_ovw,
4935 	},
4936 	{
4937 		.opcode = BTP_MESH_CFG_MODEL_SUB_DEL_ALL,
4938 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_del_all_cmd),
4939 		.func = config_mod_sub_del_all,
4940 	},
4941 	{
4942 		.opcode = BTP_MESH_CFG_MODEL_SUB_GET,
4943 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_get_cmd),
4944 		.func = config_mod_sub_get,
4945 	},
4946 	{
4947 		.opcode = BTP_MESH_CFG_MODEL_SUB_GET_VND,
4948 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_get_vnd_cmd),
4949 		.func = config_mod_sub_get_vnd,
4950 	},
4951 	{
4952 		.opcode = BTP_MESH_CFG_MODEL_SUB_VA_ADD,
4953 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_add_cmd),
4954 		.func = config_mod_sub_va_add,
4955 	},
4956 	{
4957 		.opcode = BTP_MESH_CFG_MODEL_SUB_VA_DEL,
4958 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_del_cmd),
4959 		.func = config_mod_sub_va_del,
4960 	},
4961 	{
4962 		.opcode = BTP_MESH_CFG_MODEL_SUB_VA_OVW,
4963 		.expect_len = sizeof(struct btp_mesh_cfg_model_sub_va_ovw_cmd),
4964 		.func = config_mod_sub_va_ovw,
4965 	},
4966 	{
4967 		.opcode = BTP_MESH_CFG_NETKEY_ADD,
4968 		.expect_len = sizeof(struct btp_mesh_cfg_netkey_add_cmd),
4969 		.func = config_netkey_add,
4970 	},
4971 	{
4972 		.opcode = BTP_MESH_CFG_NETKEY_GET,
4973 		.expect_len = sizeof(struct btp_mesh_cfg_netkey_get_cmd),
4974 		.func = config_netkey_get,
4975 	},
4976 	{
4977 		.opcode = BTP_MESH_CFG_NETKEY_DEL,
4978 		.expect_len = sizeof(struct btp_mesh_cfg_netkey_del_cmd),
4979 		.func = config_netkey_del,
4980 	},
4981 	{
4982 		.opcode = BTP_MESH_CFG_NETKEY_UPDATE,
4983 		.expect_len = sizeof(struct btp_mesh_cfg_netkey_update_cmd),
4984 		.func = config_netkey_update,
4985 	},
4986 	{
4987 		.opcode = BTP_MESH_CFG_APPKEY_ADD,
4988 		.expect_len = sizeof(struct btp_mesh_cfg_appkey_add_cmd),
4989 		.func = config_appkey_add,
4990 	},
4991 	{
4992 		.opcode = BTP_MESH_CFG_APPKEY_GET,
4993 		.expect_len = sizeof(struct btp_mesh_cfg_appkey_get_cmd),
4994 		.func = config_appkey_get,
4995 	},
4996 	{
4997 		.opcode = BTP_MESH_CFG_APPKEY_DEL,
4998 		.expect_len = sizeof(struct btp_mesh_cfg_appkey_del_cmd),
4999 		.func = config_appkey_del,
5000 	},
5001 	{
5002 		.opcode = BTP_MESH_CFG_APPKEY_UPDATE,
5003 		.expect_len = sizeof(struct btp_mesh_cfg_appkey_update_cmd),
5004 		.func = config_appkey_update,
5005 	},
5006 	{
5007 		.opcode = BTP_MESH_CFG_MODEL_APP_BIND,
5008 		.expect_len = sizeof(struct btp_mesh_cfg_model_app_bind_cmd),
5009 		.func = config_model_app_bind,
5010 	},
5011 	{
5012 		.opcode = BTP_MESH_CFG_MODEL_APP_UNBIND,
5013 		.expect_len = sizeof(struct btp_mesh_cfg_model_app_unbind_cmd),
5014 		.func = config_model_app_unbind,
5015 	},
5016 	{
5017 		.opcode = BTP_MESH_CFG_MODEL_APP_GET,
5018 		.expect_len = sizeof(struct btp_mesh_cfg_model_app_get_cmd),
5019 		.func = config_model_app_get,
5020 	},
5021 	{
5022 		.opcode = BTP_MESH_CFG_MODEL_APP_VND_GET,
5023 		.expect_len = sizeof(struct btp_mesh_cfg_model_app_vnd_get_cmd),
5024 		.func = config_model_app_vnd_get,
5025 	},
5026 	{
5027 		.opcode = BTP_MESH_CFG_HEARTBEAT_PUB_SET,
5028 		.expect_len = sizeof(struct btp_mesh_cfg_heartbeat_pub_set_cmd),
5029 		.func = config_hb_pub_set,
5030 	},
5031 	{
5032 		.opcode = BTP_MESH_CFG_HEARTBEAT_PUB_GET,
5033 		.expect_len = sizeof(struct btp_mesh_cfg_heartbeat_pub_get_cmd),
5034 		.func = config_hb_pub_get,
5035 	},
5036 	{
5037 		.opcode = BTP_MESH_CFG_HEARTBEAT_SUB_SET,
5038 		.expect_len = sizeof(struct btp_mesh_cfg_heartbeat_sub_set_cmd),
5039 		.func = config_hb_sub_set,
5040 	},
5041 	{
5042 		.opcode = BTP_MESH_CFG_HEARTBEAT_SUB_GET,
5043 		.expect_len = sizeof(struct btp_mesh_cfg_heartbeat_sub_get_cmd),
5044 		.func = config_hb_sub_get,
5045 	},
5046 	{
5047 		.opcode = BTP_MESH_CFG_NET_TRANS_GET,
5048 		.expect_len = sizeof(struct btp_mesh_cfg_net_trans_get_cmd),
5049 		.func = config_net_trans_get,
5050 	},
5051 	{
5052 		.opcode = BTP_MESH_CFG_NET_TRANS_SET,
5053 		.expect_len = sizeof(struct btp_mesh_cfg_net_trans_set_cmd),
5054 		.func = config_net_trans_set,
5055 	},
5056 	{
5057 		.opcode = BTP_MESH_CFG_NODE_IDT_SET,
5058 		.expect_len = sizeof(struct btp_mesh_cfg_node_idt_set_cmd),
5059 		.func = config_node_identity_set,
5060 	},
5061 	{
5062 		.opcode = BTP_MESH_CFG_NODE_IDT_GET,
5063 		.expect_len = sizeof(struct btp_mesh_cfg_node_idt_get_cmd),
5064 		.func = config_node_identity_get,
5065 	},
5066 	{
5067 		.opcode = BTP_MESH_CFG_NODE_RESET,
5068 		.expect_len = sizeof(struct btp_mesh_cfg_node_reset_cmd),
5069 		.func = config_node_reset,
5070 	},
5071 	{
5072 		.opcode = BTP_MESH_CFG_LPN_TIMEOUT_GET,
5073 		.expect_len = sizeof(struct btp_mesh_cfg_lpn_timeout_cmd),
5074 		.func = config_lpn_timeout_get,
5075 	},
5076 	{
5077 		.opcode = BTP_MESH_CFG_MODEL_PUB_VA_SET,
5078 		.expect_len = sizeof(struct btp_mesh_cfg_model_pub_va_set_cmd),
5079 		.func = config_mod_pub_va_set,
5080 	},
5081 	{
5082 		.opcode = BTP_MESH_CFG_MODEL_APP_BIND_VND,
5083 		.expect_len = sizeof(struct btp_mesh_cfg_model_app_bind_vnd_cmd),
5084 		.func = config_model_app_bind_vnd,
5085 	},
5086 	{
5087 		.opcode = BTP_MESH_HEALTH_FAULT_GET,
5088 		.expect_len = sizeof(struct btp_mesh_health_fault_get_cmd),
5089 		.func = health_fault_get,
5090 	},
5091 	{
5092 		.opcode = BTP_MESH_HEALTH_FAULT_CLEAR,
5093 		.expect_len = sizeof(struct btp_mesh_health_fault_clear_cmd),
5094 		.func = health_fault_clear,
5095 	},
5096 	{
5097 		.opcode = BTP_MESH_HEALTH_FAULT_TEST,
5098 		.expect_len = sizeof(struct btp_mesh_health_fault_test_cmd),
5099 		.func = health_fault_test,
5100 	},
5101 	{
5102 		.opcode = BTP_MESH_HEALTH_PERIOD_GET,
5103 		.expect_len = sizeof(struct btp_mesh_health_period_get_cmd),
5104 		.func = health_period_get,
5105 	},
5106 	{
5107 		.opcode = BTP_MESH_HEALTH_PERIOD_SET,
5108 		.expect_len = sizeof(struct btp_mesh_health_period_set_cmd),
5109 		.func = health_period_set,
5110 	},
5111 	{
5112 		.opcode = BTP_MESH_HEALTH_ATTENTION_GET,
5113 		.expect_len = sizeof(struct btp_mesh_health_attention_get_cmd),
5114 		.func = health_attention_get,
5115 	},
5116 	{
5117 		.opcode = BTP_MESH_HEALTH_ATTENTION_SET,
5118 		.expect_len = sizeof(struct btp_mesh_health_attention_set_cmd),
5119 		.func = health_attention_set,
5120 	},
5121 	{
5122 		.opcode = BTP_MESH_PROVISION_ADV,
5123 		.expect_len = sizeof(struct btp_mesh_provision_adv_cmd),
5124 		.func = provision_adv,
5125 	},
5126 	{
5127 		.opcode = BTP_MESH_CFG_KRP_GET,
5128 		.expect_len = sizeof(struct btp_mesh_cfg_krp_get_cmd),
5129 		.func = config_krp_get,
5130 	},
5131 	{
5132 		.opcode = BTP_MESH_CFG_KRP_SET,
5133 		.expect_len = sizeof(struct btp_mesh_cfg_krp_set_cmd),
5134 		.func = config_krp_set,
5135 	},
5136 	{
5137 		.opcode = BTP_MESH_VA_ADD,
5138 		.expect_len = sizeof(struct btp_mesh_va_add_cmd),
5139 		.func = va_add,
5140 	},
5141 	{
5142 		.opcode = BTP_MESH_VA_DEL,
5143 		.expect_len = sizeof(struct btp_mesh_va_del_cmd),
5144 		.func = va_del,
5145 	},
5146 #if defined(CONFIG_BT_TESTING)
5147 #if defined(CONFIG_BT_MESH_LOW_POWER)
5148 	{
5149 		.opcode = BTP_MESH_LPN_SUBSCRIBE,
5150 		.expect_len = sizeof(struct btp_mesh_lpn_subscribe_cmd),
5151 		.func = lpn_subscribe,
5152 	},
5153 	{
5154 		.opcode = BTP_MESH_LPN_UNSUBSCRIBE,
5155 		.expect_len = sizeof(struct btp_mesh_lpn_unsubscribe_cmd),
5156 		.func = lpn_unsubscribe,
5157 	},
5158 #endif /* CONFIG_BT_MESH_LOW_POWER */
5159 	{
5160 		.opcode = BTP_MESH_RPL_CLEAR,
5161 		.expect_len = 0,
5162 		.func = rpl_clear,
5163 	},
5164 #endif /* CONFIG_BT_TESTING */
5165 	{
5166 		.opcode = BTP_MESH_PROXY_IDENTITY,
5167 		.expect_len = 0,
5168 		.func = proxy_identity_enable,
5169 	},
5170 #if defined(CONFIG_BT_MESH_PROXY_CLIENT)
5171 	{.opcode = BTP_MESH_PROXY_CONNECT,
5172 	 .expect_len = sizeof(struct btp_proxy_connect_cmd),
5173 	 .func = proxy_connect},
5174 #endif
5175 #if defined(CONFIG_BT_MESH_SAR_CFG_CLI)
5176 	{.opcode = BTP_MESH_SAR_TRANSMITTER_GET,
5177 	 .expect_len = sizeof(struct btp_mesh_sar_transmitter_get_cmd),
5178 	 .func = sar_transmitter_get},
5179 	{.opcode = BTP_MESH_SAR_TRANSMITTER_SET,
5180 	 .expect_len = sizeof(struct btp_mesh_sar_transmitter_set_cmd),
5181 	 .func = sar_transmitter_set},
5182 	{.opcode = BTP_MESH_SAR_RECEIVER_GET,
5183 	 .expect_len = sizeof(struct btp_mesh_sar_receiver_get_cmd),
5184 	 .func = sar_receiver_get},
5185 	{.opcode = BTP_MESH_SAR_RECEIVER_SET,
5186 	 .expect_len = sizeof(struct btp_mesh_sar_receiver_set_cmd),
5187 	 .func = sar_receiver_set},
5188 #endif
5189 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI)
5190 	{.opcode = BTP_MESH_LARGE_COMP_DATA_GET,
5191 	 .expect_len = sizeof(struct btp_mesh_large_comp_data_get_cmd),
5192 	 .func = large_comp_data_get},
5193 	{.opcode = BTP_MESH_MODELS_METADATA_GET,
5194 	 .expect_len = sizeof(struct btp_mesh_models_metadata_get_cmd),
5195 	 .func = models_metadata_get},
5196 #endif
5197 #if defined(CONFIG_BT_MESH_OP_AGG_CLI)
5198 	{.opcode = BTP_MESH_OPCODES_AGGREGATOR_INIT,
5199 	 .expect_len = sizeof(struct btp_mesh_opcodes_aggregator_init_cmd),
5200 	 .func = opcodes_aggregator_init},
5201 	{.opcode = BTP_MESH_OPCODES_AGGREGATOR_SEND,
5202 	 .expect_len = 0,
5203 	 .func = opcodes_aggregator_send},
5204 #endif
5205 	{.opcode = BTP_MESH_COMP_CHANGE_PREPARE, .expect_len = 0, .func = change_prepare},
5206 #if defined(CONFIG_BT_MESH_RPR_CLI)
5207 	{.opcode = BTP_MESH_RPR_SCAN_START,
5208 	 .expect_len = sizeof(struct btp_rpr_scan_start_cmd),
5209 	 .func = rpr_scan_start},
5210 	{.opcode = BTP_MESH_RPR_EXT_SCAN_START,
5211 	 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5212 	 .func = rpr_ext_scan_start},
5213 	{.opcode = BTP_MESH_RPR_SCAN_CAPS_GET,
5214 	 .expect_len = sizeof(struct btp_rpr_scan_caps_get_cmd),
5215 	 .func = rpr_scan_caps_get},
5216 	{.opcode = BTP_MESH_RPR_SCAN_GET,
5217 	 .expect_len = sizeof(struct btp_rpr_scan_get_cmd),
5218 	 .func = rpr_scan_get},
5219 	{.opcode = BTP_MESH_RPR_SCAN_STOP,
5220 	 .expect_len = sizeof(struct btp_rpr_scan_stop_cmd),
5221 	 .func = rpr_scan_stop},
5222 	{.opcode = BTP_MESH_RPR_LINK_GET,
5223 	 .expect_len = sizeof(struct btp_rpr_link_get_cmd),
5224 	 .func = rpr_link_get},
5225 	{.opcode = BTP_MESH_RPR_LINK_CLOSE,
5226 	 .expect_len = sizeof(struct btp_rpr_link_close_cmd),
5227 	 .func = rpr_link_close},
5228 	{.opcode = BTP_MESH_RPR_PROV_REMOTE,
5229 	 .expect_len = sizeof(struct btp_rpr_prov_remote_cmd),
5230 	 .func = rpr_prov_remote},
5231 	{.opcode = BTP_MESH_RPR_REPROV_REMOTE,
5232 	 .expect_len = sizeof(struct btp_rpr_reprov_remote_cmd),
5233 	 .func = rpr_reprov_remote},
5234 #endif
5235 #if defined(CONFIG_BT_MESH_PRIV_BEACON_CLI)
5236 	{.opcode = BTP_MESH_PRIV_BEACON_GET,
5237 	 .expect_len = sizeof(struct btp_priv_beacon_get_cmd),
5238 	 .func = priv_beacon_get},
5239 	{.opcode = BTP_MESH_PRIV_BEACON_SET,
5240 	 .expect_len = sizeof(struct btp_priv_beacon_set_cmd),
5241 	 .func = priv_beacon_set},
5242 	{.opcode = BTP_MESH_PRIV_GATT_PROXY_GET,
5243 	 .expect_len = sizeof(struct btp_priv_gatt_proxy_get_cmd),
5244 	 .func = priv_gatt_proxy_get},
5245 	{.opcode = BTP_MESH_PRIV_GATT_PROXY_SET,
5246 	 .expect_len = sizeof(struct btp_priv_gatt_proxy_set_cmd),
5247 	 .func = priv_gatt_proxy_set},
5248 	{.opcode = BTP_MESH_PRIV_NODE_ID_GET,
5249 	 .expect_len = sizeof(struct btp_priv_node_id_get_cmd),
5250 	 .func = priv_node_id_get},
5251 	{.opcode = BTP_MESH_PRIV_NODE_ID_SET,
5252 	 .expect_len = sizeof(struct btp_priv_node_id_set_cmd),
5253 	 .func = priv_node_id_set},
5254 	{.opcode = BTP_MESH_PROXY_PRIVATE_IDENTITY,
5255 	 .expect_len = 0,
5256 	 .func = proxy_private_identity_enable},
5257 #endif
5258 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
5259 	{.opcode = BTP_MESH_OD_PRIV_PROXY_GET,
5260 	 .expect_len = sizeof(struct btp_od_priv_proxy_get_cmd),
5261 	 .func = od_priv_proxy_get},
5262 	{.opcode = BTP_MESH_OD_PRIV_PROXY_SET,
5263 	 .expect_len = sizeof(struct btp_od_priv_proxy_set_cmd),
5264 	 .func = od_priv_proxy_set},
5265 #endif
5266 #if defined(CONFIG_BT_MESH_SOL_PDU_RPL_CLI)
5267 	{.opcode = BTP_MESH_SRPL_CLEAR,
5268 	 .expect_len = sizeof(struct btp_srpl_clear_cmd),
5269 	 .func = srpl_clear},
5270 #endif
5271 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
5272 	{.opcode = BTP_MESH_SUBNET_BRIDGE_GET,
5273 	 .expect_len = sizeof(struct btp_mesh_subnet_bridge_get_cmd),
5274 	 .func = subnet_bridge_get},
5275 	{.opcode = BTP_MESH_SUBNET_BRIDGE_SET,
5276 	 .expect_len = sizeof(struct btp_mesh_subnet_bridge_set_cmd),
5277 	 .func = subnet_bridge_set},
5278 	{.opcode = BTP_MESH_BRIDGING_TABLE_ADD,
5279 	 .expect_len = sizeof(struct btp_mesh_bridging_table_add_cmd),
5280 	 .func = bridging_table_add},
5281 	{.opcode = BTP_MESH_BRIDGING_TABLE_REMOVE,
5282 	 .expect_len = sizeof(struct btp_mesh_bridging_table_remove_cmd),
5283 	 .func = bridging_table_remove},
5284 	{.opcode = BTP_MESH_BRIDGED_SUBNETS_GET,
5285 	 .expect_len = sizeof(struct btp_mesh_bridged_subnets_get_cmd),
5286 	 .func = bridged_subnets_get},
5287 	{.opcode = BTP_MESH_BRIDGING_TABLE_GET,
5288 	 .expect_len = sizeof(struct btp_mesh_bridging_table_get_cmd),
5289 	 .func = bridging_table_get},
5290 	{.opcode = BTP_MESH_BRIDGING_TABLE_SIZE_GET,
5291 	 .expect_len = sizeof(struct btp_mesh_bridging_table_size_get_cmd),
5292 	 .func = bridging_table_size_get},
5293 #endif
5294 #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION)
5295 	{.opcode = BTP_MESH_PROXY_SOLICIT,
5296 	 .expect_len = sizeof(struct btp_proxy_solicit_cmd),
5297 	 .func = proxy_solicit},
5298 #endif
5299 	{.opcode = BTP_MESH_START, .expect_len = 0, .func = start},
5300 };
5301 
5302 static const struct btp_handler mdl_handlers[] = {
5303 #if defined(CONFIG_BT_MESH_DFD_SRV)
5304 	{
5305 		.opcode = BTP_MMDL_DFU_INFO_GET,
5306 		.expect_len = sizeof(struct btp_mmdl_dfu_info_get_cmd),
5307 		.func = dfu_info_get,
5308 	},
5309 	{
5310 		.opcode = BTP_MMDL_DFU_UPDATE_METADATA_CHECK,
5311 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5312 		.func = dfu_update_metadata_check,
5313 	},
5314 	{
5315 		.opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_GET,
5316 		.expect_len = 0,
5317 		.func = dfu_firmware_update_get,
5318 	},
5319 	{
5320 		.opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_CANCEL,
5321 		.expect_len = 0,
5322 		.func = dfu_firmware_update_cancel,
5323 	},
5324 	{
5325 		.opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_START,
5326 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5327 		.func = dfu_firmware_update_start,
5328 	},
5329 	{
5330 		.opcode = BTP_MMDL_DFU_FIRMWARE_UPDATE_APPLY,
5331 		.expect_len = 0,
5332 		.func = dfu_firmware_update_apply,
5333 	},
5334 #endif
5335 #if defined(CONFIG_BT_MESH_BLOB_CLI)
5336 	{
5337 		.opcode = BTP_MMDL_BLOB_INFO_GET,
5338 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
5339 		.func = blob_info_get,
5340 	},
5341 	{
5342 		.opcode = BTP_MMDL_BLOB_TRANSFER_START,
5343 		.expect_len = sizeof(struct btp_mmdl_blob_transfer_start_cmd),
5344 		.func = blob_transfer_start,
5345 	},
5346 	{
5347 		.opcode = BTP_MMDL_BLOB_TRANSFER_CANCEL,
5348 		.expect_len = 0,
5349 		.func = blob_transfer_cancel,
5350 	},
5351 	{
5352 		.opcode = BTP_MMDL_BLOB_TRANSFER_GET,
5353 		.expect_len = 0,
5354 		.func = blob_transfer_get,
5355 	},
5356 #endif
5357 #if defined(CONFIG_BT_MESH_BLOB_SRV)
5358 	{.opcode = BTP_MMDL_BLOB_SRV_RECV,
5359 	 .expect_len = sizeof(struct btp_mmdl_blob_srv_recv_cmd),
5360 	 .func = blob_srv_recv},
5361 	{.opcode = BTP_MMDL_BLOB_SRV_CANCEL, .expect_len = 0, .func = blob_srv_cancel},
5362 #endif
5363 #if defined(CONFIG_BT_MESH_DFU_SRV)
5364 	{.opcode = BTP_MMDL_DFU_SRV_APPLY, .expect_len = 0, .func = dfu_srv_apply},
5365 #endif
5366 };
5367 
net_recv_ev(uint8_t ttl,uint8_t ctl,uint16_t src,uint16_t dst,const void * payload,size_t payload_len)5368 void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload,
5369 		 size_t payload_len)
5370 {
5371 	NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX);
5372 	struct btp_mesh_net_recv_ev *ev;
5373 
5374 	LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x payload_len %zu",
5375 		ttl, ctl, src, dst, payload_len);
5376 
5377 	if (payload_len > net_buf_simple_tailroom(&buf)) {
5378 		LOG_ERR("Payload size exceeds buffer size");
5379 		return;
5380 	}
5381 
5382 	ev = net_buf_simple_add(&buf, sizeof(*ev));
5383 	ev->ttl = ttl;
5384 	ev->ctl = ctl;
5385 	ev->src = sys_cpu_to_le16(src);
5386 	ev->dst = sys_cpu_to_le16(dst);
5387 	ev->payload_len = payload_len;
5388 	net_buf_simple_add_mem(&buf, payload, payload_len);
5389 
5390 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_NET_RECV, buf.data, buf.len);
5391 }
5392 
model_recv_ev(uint16_t src,uint16_t dst,const void * payload,size_t payload_len)5393 void model_recv_ev(uint16_t src, uint16_t dst, const void *payload,
5394 		   size_t payload_len)
5395 {
5396 	NET_BUF_SIMPLE_DEFINE(buf, UINT8_MAX);
5397 	struct btp_mesh_model_recv_ev *ev;
5398 
5399 	LOG_DBG("src 0x%04x dst 0x%04x payload_len %zu", src, dst, payload_len);
5400 
5401 	if (payload_len > net_buf_simple_tailroom(&buf)) {
5402 		LOG_ERR("Payload size exceeds buffer size");
5403 		return;
5404 	}
5405 
5406 	ev = net_buf_simple_add(&buf, sizeof(*ev));
5407 	ev->src = sys_cpu_to_le16(src);
5408 	ev->dst = sys_cpu_to_le16(dst);
5409 	ev->payload_len = payload_len;
5410 	net_buf_simple_add_mem(&buf, payload, payload_len);
5411 
5412 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_MODEL_RECV, buf.data, buf.len);
5413 }
5414 
model_bound_cb(uint16_t addr,const struct bt_mesh_model * model,uint16_t key_idx)5415 static void model_bound_cb(uint16_t addr, const struct bt_mesh_model *model,
5416 			   uint16_t key_idx)
5417 {
5418 	int i;
5419 
5420 	LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p",
5421 		addr, key_idx, model);
5422 
5423 	for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
5424 		if (!model_bound[i].model) {
5425 			model_bound[i].model = model;
5426 			model_bound[i].addr = addr;
5427 			model_bound[i].appkey_idx = key_idx;
5428 
5429 			return;
5430 		}
5431 	}
5432 
5433 	LOG_ERR("model_bound is full");
5434 }
5435 
model_unbound_cb(uint16_t addr,const struct bt_mesh_model * model,uint16_t key_idx)5436 static void model_unbound_cb(uint16_t addr, const struct bt_mesh_model *model,
5437 			     uint16_t key_idx)
5438 {
5439 	int i;
5440 
5441 	LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p",
5442 		addr, key_idx, model);
5443 
5444 	for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
5445 		if (model_bound[i].model == model) {
5446 			model_bound[i].model = NULL;
5447 			model_bound[i].addr = 0x0000;
5448 			model_bound[i].appkey_idx = BT_MESH_KEY_UNUSED;
5449 
5450 			return;
5451 		}
5452 	}
5453 
5454 	LOG_INF("model not found");
5455 }
5456 
invalid_bearer_cb(uint8_t opcode)5457 static void invalid_bearer_cb(uint8_t opcode)
5458 {
5459 	struct btp_mesh_invalid_bearer_ev ev = {
5460 		.opcode = opcode,
5461 	};
5462 
5463 	LOG_DBG("opcode 0x%02x", opcode);
5464 
5465 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, &ev, sizeof(ev));
5466 }
5467 
incomp_timer_exp_cb(void)5468 static void incomp_timer_exp_cb(void)
5469 {
5470 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, NULL, 0);
5471 }
5472 
5473 static struct bt_mesh_test_cb bt_mesh_test_cb = {
5474 	.net_recv = net_recv_ev,
5475 	.model_recv = model_recv_ev,
5476 	.model_bound = model_bound_cb,
5477 	.model_unbound = model_unbound_cb,
5478 	.prov_invalid_bearer = invalid_bearer_cb,
5479 	.trans_incomp_timer_exp = incomp_timer_exp_cb,
5480 };
5481 
friend_established(uint16_t net_idx,uint16_t lpn_addr,uint8_t recv_delay,uint32_t polltimeout)5482 static void friend_established(uint16_t net_idx, uint16_t lpn_addr,
5483 			       uint8_t recv_delay, uint32_t polltimeout)
5484 {
5485 	struct btp_mesh_frnd_established_ev ev = { net_idx, lpn_addr, recv_delay,
5486 					       polltimeout };
5487 
5488 	LOG_DBG("Friendship (as Friend) established with "
5489 			"LPN 0x%04x Receive Delay %u Poll Timeout %u",
5490 			lpn_addr, recv_delay, polltimeout);
5491 
5492 
5493 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_FRND_ESTABLISHED, &ev, sizeof(ev));
5494 }
5495 
friend_terminated(uint16_t net_idx,uint16_t lpn_addr)5496 static void friend_terminated(uint16_t net_idx, uint16_t lpn_addr)
5497 {
5498 	struct btp_mesh_frnd_terminated_ev ev = { net_idx, lpn_addr };
5499 
5500 	LOG_DBG("Friendship (as Friend) lost with LPN "
5501 			"0x%04x", lpn_addr);
5502 
5503 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_FRND_TERMINATED, &ev, sizeof(ev));
5504 }
5505 
5506 BT_MESH_FRIEND_CB_DEFINE(friend_cb) = {
5507 	.established = friend_established,
5508 	.terminated = friend_terminated,
5509 };
5510 
lpn_established(uint16_t net_idx,uint16_t friend_addr,uint8_t queue_size,uint8_t recv_win)5511 static void lpn_established(uint16_t net_idx, uint16_t friend_addr,
5512 					uint8_t queue_size, uint8_t recv_win)
5513 {
5514 	struct btp_mesh_lpn_established_ev ev = { net_idx, friend_addr, queue_size,
5515 					      recv_win };
5516 
5517 	LOG_DBG("Friendship (as LPN) established with "
5518 			"Friend 0x%04x Queue Size %d Receive Window %d",
5519 			friend_addr, queue_size, recv_win);
5520 
5521 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, &ev, sizeof(ev));
5522 }
5523 
lpn_terminated(uint16_t net_idx,uint16_t friend_addr)5524 static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr)
5525 {
5526 	struct btp_mesh_lpn_polled_ev ev = { net_idx, friend_addr };
5527 
5528 	LOG_DBG("Friendship (as LPN) lost with Friend "
5529 			"0x%04x", friend_addr);
5530 
5531 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, &ev, sizeof(ev));
5532 }
5533 
lpn_polled(uint16_t net_idx,uint16_t friend_addr,bool retry)5534 static void lpn_polled(uint16_t net_idx, uint16_t friend_addr, bool retry)
5535 {
5536 	struct btp_mesh_lpn_polled_ev ev = { net_idx, friend_addr, (uint8_t)retry };
5537 
5538 	LOG_DBG("LPN polled 0x%04x %s", friend_addr, retry ? "(retry)" : "");
5539 
5540 	tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_POLLED, &ev, sizeof(ev));
5541 }
5542 
5543 BT_MESH_LPN_CB_DEFINE(lpn_cb) = {
5544 	.established = lpn_established,
5545 	.terminated = lpn_terminated,
5546 	.polled = lpn_polled,
5547 };
5548 
tester_init_mesh(void)5549 uint8_t tester_init_mesh(void)
5550 {
5551 	if (IS_ENABLED(CONFIG_BT_TESTING)) {
5552 		bt_mesh_test_cb_register(&bt_mesh_test_cb);
5553 	}
5554 
5555 #if defined(CONFIG_BT_MESH_COMP_PAGE_2)
5556 	bt_mesh_comp2_register(&comp_p2);
5557 #endif
5558 
5559 	tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers,
5560 					 ARRAY_SIZE(handlers));
5561 
5562 	return BTP_STATUS_SUCCESS;
5563 }
5564 
tester_unregister_mesh(void)5565 uint8_t tester_unregister_mesh(void)
5566 {
5567 	return BTP_STATUS_SUCCESS;
5568 }
5569 
tester_init_mmdl(void)5570 uint8_t tester_init_mmdl(void)
5571 {
5572 	tester_register_command_handlers(BTP_SERVICE_ID_MESH_MDL, mdl_handlers,
5573 					 ARRAY_SIZE(mdl_handlers));
5574 	return BTP_STATUS_SUCCESS;
5575 }
5576 
tester_unregister_mmdl(void)5577 uint8_t tester_unregister_mmdl(void)
5578 {
5579 	return BTP_STATUS_SUCCESS;
5580 }
5581