1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "mesh_test.h"
7 #include "argparse.h"
8 #include <bs_pc_backchannel.h>
9 #include "mesh/crypto.h"
10 #include <zephyr/bluetooth/hci.h>
11 
12 #define LOG_MODULE_NAME mesh_test
13 #define COMPANY_ID_LF 0x05F1
14 #define COMPANY_ID_NORDIC_SEMI 0x05F9
15 
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
18 
19 #include "common/bt_str.h"
20 
21 /* Max number of messages that can be pending on RX at the same time */
22 #define RECV_QUEUE_SIZE 32
23 
24 const struct bt_mesh_test_cfg *cfg;
25 
26 K_MEM_SLAB_DEFINE_STATIC(msg_pool, sizeof(struct bt_mesh_test_msg),
27 			 RECV_QUEUE_SIZE, 4);
28 static K_QUEUE_DEFINE(recv);
29 struct bt_mesh_test_stats test_stats;
30 struct bt_mesh_msg_ctx test_send_ctx;
31 static void (*data_cb)(uint8_t *, size_t);
32 
msg_rx(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)33 static int msg_rx(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
34 		   struct net_buf_simple *buf)
35 {
36 	size_t len = buf->len + BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1);
37 	static uint8_t prev_seq;
38 	struct bt_mesh_test_msg *msg;
39 	uint8_t seq = 0;
40 
41 	if (buf->len) {
42 		seq = net_buf_simple_pull_u8(buf);
43 		if (prev_seq == seq) {
44 			FAIL("Received same message twice");
45 			return -EINVAL;
46 		}
47 
48 		prev_seq = seq;
49 	}
50 
51 	LOG_INF("Received packet 0x%02x:", seq);
52 	LOG_INF("\tlen: %d bytes", len);
53 	LOG_INF("\tsrc: 0x%04x", ctx->addr);
54 	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
55 	LOG_INF("\tttl: %u", ctx->recv_ttl);
56 	LOG_INF("\trssi: %d", ctx->recv_rssi);
57 
58 	for (int i = 1; buf->len; i++) {
59 		if (net_buf_simple_pull_u8(buf) != (i & 0xff)) {
60 			FAIL("Invalid message content (byte %u)", i);
61 			return -EINVAL;
62 		}
63 	}
64 
65 	test_stats.received++;
66 
67 	if (k_mem_slab_alloc(&msg_pool, (void **)&msg, K_NO_WAIT)) {
68 		test_stats.recv_overflow++;
69 		return -EOVERFLOW;
70 	}
71 
72 	msg->len = len;
73 	msg->seq = seq;
74 	msg->ctx = *ctx;
75 
76 	k_queue_append(&recv, msg);
77 
78 	return 0;
79 }
80 
data_rx(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)81 static int data_rx(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
82 		   struct net_buf_simple *buf)
83 {
84 	LOG_INF("\tlen: %d bytes", buf->len);
85 	LOG_INF("\tsrc: 0x%04x", ctx->addr);
86 	LOG_INF("\tdst: 0x%04x", ctx->recv_dst);
87 	LOG_INF("\tttl: %u", ctx->recv_ttl);
88 	LOG_INF("\trssi: %d", ctx->recv_rssi);
89 
90 	if (data_cb) {
91 		data_cb(buf->data, buf->len);
92 	}
93 
94 	return 0;
95 }
96 
97 static const struct bt_mesh_model_op model_op[] = {
98 	{TEST_MSG_OP_1, 0, msg_rx}, {TEST_MSG_OP_2, 0, data_rx}, BT_MESH_MODEL_OP_END};
99 
test_model_pub_update(const struct bt_mesh_model * mod)100 int __weak test_model_pub_update(const struct bt_mesh_model *mod)
101 {
102 	return -1;
103 }
104 
test_model_settings_set(const struct bt_mesh_model * model,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)105 int __weak test_model_settings_set(const struct bt_mesh_model *model,
106 				   const char *name, size_t len_rd,
107 				   settings_read_cb read_cb, void *cb_arg)
108 {
109 	return -1;
110 }
111 
test_model_reset(const struct bt_mesh_model * model)112 void __weak test_model_reset(const struct bt_mesh_model *model)
113 {
114 	/* No-op. */
115 }
116 
117 static const struct bt_mesh_model_cb test_model_cb = {
118 	.settings_set = test_model_settings_set,
119 	.reset = test_model_reset,
120 };
121 
122 static struct bt_mesh_model_pub pub = {
123 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
124 	.update = test_model_pub_update,
125 };
126 
127 static const struct bt_mesh_model_op vnd_model_op[] = {
128 	BT_MESH_MODEL_OP_END,
129 };
130 
test_vnd_model_pub_update(const struct bt_mesh_model * mod)131 int __weak test_vnd_model_pub_update(const struct bt_mesh_model *mod)
132 {
133 	return -1;
134 }
135 
test_vnd_model_settings_set(const struct bt_mesh_model * model,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)136 int __weak test_vnd_model_settings_set(const struct bt_mesh_model *model,
137 				       const char *name, size_t len_rd,
138 				       settings_read_cb read_cb, void *cb_arg)
139 {
140 	return -1;
141 }
142 
test_vnd_model_reset(const struct bt_mesh_model * model)143 void __weak test_vnd_model_reset(const struct bt_mesh_model *model)
144 {
145 	/* No-op. */
146 }
147 
148 static const struct bt_mesh_model_cb test_vnd_model_cb = {
149 	.settings_set = test_vnd_model_settings_set,
150 	.reset = test_vnd_model_reset,
151 };
152 
153 static struct bt_mesh_model_pub vnd_pub = {
154 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
155 	.update = test_vnd_model_pub_update,
156 };
157 
158 static struct bt_mesh_cfg_cli cfg_cli;
159 
160 static struct bt_mesh_health_srv health_srv;
161 static struct bt_mesh_model_pub health_pub = {
162 	.msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
163 };
164 static const uint8_t health_tests[] = {
165 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_LF, 6, 0x01, 0x02, 0x03, 0x04, 0x34, 0x15),
166 	BT_MESH_HEALTH_TEST_INFO(COMPANY_ID_NORDIC_SEMI, 3, 0x01, 0x02, 0x03),
167 };
168 
169 const struct bt_mesh_models_metadata_entry health_srv_meta[] = {
170 	BT_MESH_HEALTH_TEST_INFO_METADATA(health_tests),
171 	BT_MESH_MODELS_METADATA_END,
172 };
173 
174 #if defined(CONFIG_BT_MESH_SAR_CFG)
175 static struct bt_mesh_sar_cfg_cli sar_cfg_cli;
176 #endif
177 
178 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
179 static struct bt_mesh_priv_beacon_cli priv_beacon_cli;
180 #endif
181 
182 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
183 static struct bt_mesh_od_priv_proxy_cli priv_proxy_cli;
184 #endif
185 
186 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
187 static struct bt_mesh_brg_cfg_cli brg_cfg_cli;
188 #endif
189 
190 static const struct bt_mesh_model models[] = {
191 	BT_MESH_MODEL_CFG_SRV,
192 	BT_MESH_MODEL_CFG_CLI(&cfg_cli),
193 	BT_MESH_MODEL_CB(TEST_MOD_ID, model_op, &pub, NULL, &test_model_cb),
194 	BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub, health_srv_meta),
195 #if defined(CONFIG_BT_MESH_SAR_CFG)
196 	BT_MESH_MODEL_SAR_CFG_SRV,
197 	BT_MESH_MODEL_SAR_CFG_CLI(&sar_cfg_cli),
198 #endif
199 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
200 	BT_MESH_MODEL_PRIV_BEACON_SRV,
201 	BT_MESH_MODEL_PRIV_BEACON_CLI(&priv_beacon_cli),
202 #endif
203 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
204 	BT_MESH_MODEL_OD_PRIV_PROXY_SRV,
205 #endif
206 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_CLI)
207 	BT_MESH_MODEL_OD_PRIV_PROXY_CLI(&priv_proxy_cli),
208 #endif
209 #if defined(CONFIG_BT_MESH_BRG_CFG_SRV)
210 	BT_MESH_MODEL_BRG_CFG_SRV,
211 #endif
212 #if defined(CONFIG_BT_MESH_BRG_CFG_CLI)
213 	BT_MESH_MODEL_BRG_CFG_CLI(&brg_cfg_cli),
214 #endif
215 };
216 
217 const struct bt_mesh_model *test_model = &models[2];
218 
219 static const struct bt_mesh_model vnd_models[] = {
220 	BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MOD_ID, vnd_model_op, &vnd_pub,
221 			     NULL, &test_vnd_model_cb),
222 };
223 
224 const struct bt_mesh_model *test_vnd_model = &vnd_models[0];
225 
226 static const struct bt_mesh_elem elems[] = {
227 	BT_MESH_ELEM(0, models, vnd_models),
228 };
229 
230 const struct bt_mesh_comp comp = {
231 	.elem = elems,
232 	.elem_count = ARRAY_SIZE(elems),
233 };
234 
235 const uint8_t test_net_key[16] = { 1, 2, 3 };
236 const uint8_t test_app_key[16] = { 4, 5, 6 };
237 const uint8_t test_va_uuid[16] = "Mesh Label UUID";
238 
bt_mesh_device_provision_and_configure(void)239 static void bt_mesh_device_provision_and_configure(void)
240 {
241 	uint8_t status;
242 	int err;
243 
244 	err = bt_mesh_provision(test_net_key, 0, 0, 0, cfg->addr, cfg->dev_key);
245 	if (err == -EALREADY) {
246 		LOG_INF("Using stored settings");
247 		return;
248 	} else if (err) {
249 		FAIL("Provisioning failed (err %d)", err);
250 		return;
251 	}
252 
253 	/* Self configure */
254 
255 	err = bt_mesh_cfg_cli_app_key_add(0, cfg->addr, 0, 0, test_app_key, &status);
256 	if (err || status) {
257 		FAIL("AppKey add failed (err %d, status %u)", err, status);
258 		return;
259 	}
260 
261 	err = bt_mesh_cfg_cli_mod_app_bind(0, cfg->addr, cfg->addr, 0, TEST_MOD_ID, &status);
262 	if (err || status) {
263 		FAIL("Mod app bind failed (err %d, status %u)", err, status);
264 		return;
265 	}
266 
267 	err = bt_mesh_cfg_cli_net_transmit_set(0, cfg->addr, BT_MESH_TRANSMIT(2, 20), &status);
268 	if (err || status != BT_MESH_TRANSMIT(2, 20)) {
269 		FAIL("Net transmit set failed (err %d, status %u)", err,
270 		     status);
271 		return;
272 	}
273 }
274 
bt_mesh_device_setup(const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp)275 void bt_mesh_device_setup(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp)
276 {
277 	int err;
278 
279 	err = bt_enable(NULL);
280 	if (err) {
281 		FAIL("Bluetooth init failed (err %d)", err);
282 		return;
283 	}
284 
285 	LOG_INF("Bluetooth initialized");
286 
287 	err = bt_mesh_init(prov, comp);
288 	if (err) {
289 		FAIL("Initializing mesh failed (err %d)", err);
290 		return;
291 	}
292 
293 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
294 		LOG_INF("Loading stored settings");
295 		if (IS_ENABLED(CONFIG_BT_MESH_USES_MBEDTLS_PSA)) {
296 			settings_load_subtree("itsemul");
297 		}
298 		settings_load_subtree("bt");
299 	}
300 
301 	LOG_INF("Mesh initialized");
302 }
303 
bt_mesh_test_setup(void)304 void bt_mesh_test_setup(void)
305 {
306 	static struct bt_mesh_prov prov;
307 
308 	net_buf_simple_init(pub.msg, 0);
309 	net_buf_simple_init(vnd_pub.msg, 0);
310 
311 	bt_mesh_device_setup(&prov, &comp);
312 	bt_mesh_device_provision_and_configure();
313 }
314 
bt_mesh_test_timeout(bs_time_t HW_device_time)315 void bt_mesh_test_timeout(bs_time_t HW_device_time)
316 {
317 	if (bst_result != Passed) {
318 		FAIL("Test timeout (not passed after %i seconds)",
319 		     HW_device_time / USEC_PER_SEC);
320 	}
321 
322 	bs_trace_silent_exit(0);
323 }
324 
bt_mesh_test_cfg_set(const struct bt_mesh_test_cfg * my_cfg,int wait_time)325 void bt_mesh_test_cfg_set(const struct bt_mesh_test_cfg *my_cfg, int wait_time)
326 {
327 	bst_ticker_set_next_tick_absolute(wait_time * USEC_PER_SEC);
328 	bst_result = In_progress;
329 	cfg = my_cfg;
330 
331 	/* Ensure those test devices will not drift more than
332 	 * 100ms for each other in emulated time
333 	 */
334 	tm_set_phy_max_resync_offset(100000);
335 }
336 
blocking_recv(k_timeout_t timeout)337 static struct bt_mesh_test_msg *blocking_recv(k_timeout_t timeout)
338 {
339 	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
340 		return 0;
341 	}
342 
343 	return k_queue_get(&recv, timeout);
344 }
345 
bt_mesh_test_recv(uint16_t len,uint16_t dst,const uint8_t * uuid,k_timeout_t timeout)346 int bt_mesh_test_recv(uint16_t len, uint16_t dst, const uint8_t *uuid, k_timeout_t timeout)
347 {
348 	struct bt_mesh_test_msg *msg = blocking_recv(timeout);
349 
350 	if (!msg) {
351 		return -ETIMEDOUT;
352 	}
353 
354 	if (len != msg->len) {
355 		LOG_ERR("Recv: Invalid message length (%u, expected %u)", msg->len, len);
356 		return -EINVAL;
357 	}
358 
359 	if (dst != BT_MESH_ADDR_UNASSIGNED && dst != msg->ctx.recv_dst) {
360 		LOG_ERR("Recv: Invalid dst 0x%04x, expected 0x%04x", msg->ctx.recv_dst, dst);
361 		return -EINVAL;
362 	}
363 
364 	if (BT_MESH_ADDR_IS_VIRTUAL(msg->ctx.recv_dst) &&
365 	    ((uuid != NULL && msg->ctx.uuid == NULL) ||
366 	     (uuid == NULL && msg->ctx.uuid != NULL) ||
367 	     memcmp(uuid, msg->ctx.uuid, 16))) {
368 		LOG_ERR("Recv: Label UUID mismatch for virtual address 0x%04x");
369 		if (uuid && msg->ctx.uuid) {
370 			LOG_ERR("Got: %s", bt_hex(msg->ctx.uuid, 16));
371 			LOG_ERR("Expected: %s", bt_hex(uuid, 16));
372 		}
373 
374 		return -EINVAL;
375 	}
376 
377 	k_mem_slab_free(&msg_pool, (void *)msg);
378 
379 	return 0;
380 }
381 
bt_mesh_test_recv_msg(struct bt_mesh_test_msg * msg,k_timeout_t timeout)382 int bt_mesh_test_recv_msg(struct bt_mesh_test_msg *msg, k_timeout_t timeout)
383 {
384 	struct bt_mesh_test_msg *queued = blocking_recv(timeout);
385 
386 	if (!queued) {
387 		return -ETIMEDOUT;
388 	}
389 
390 	*msg = *queued;
391 
392 	k_mem_slab_free(&msg_pool, (void *)queued);
393 
394 	return 0;
395 }
396 
bt_mesh_test_recv_clear(void)397 int bt_mesh_test_recv_clear(void)
398 {
399 	struct bt_mesh_test_msg *queued;
400 	int count = 0;
401 
402 	while ((queued = k_queue_get(&recv, K_NO_WAIT))) {
403 		k_mem_slab_free(&msg_pool, (void *)queued);
404 		count++;
405 	}
406 
407 	return count;
408 }
409 
410 struct sync_send_ctx {
411 	struct k_sem sem;
412 	int err;
413 };
414 
tx_started(uint16_t dur,int err,void * data)415 static void tx_started(uint16_t dur, int err, void *data)
416 {
417 	struct sync_send_ctx *send_ctx = data;
418 
419 	if (err) {
420 		LOG_ERR("Couldn't start sending (err: %d)", err);
421 
422 		send_ctx->err = err;
423 		k_sem_give(&send_ctx->sem);
424 
425 		return;
426 	}
427 
428 	LOG_INF("Sending started");
429 }
430 
tx_ended(int err,void * data)431 static void tx_ended(int err, void *data)
432 {
433 	struct sync_send_ctx *send_ctx = data;
434 
435 	send_ctx->err = err;
436 
437 	if (err) {
438 		LOG_ERR("Send failed (%d)", err);
439 	} else {
440 		LOG_INF("Sending ended");
441 	}
442 
443 	k_sem_give(&send_ctx->sem);
444 }
445 
bt_mesh_test_send_async(uint16_t addr,const uint8_t * uuid,size_t len,enum bt_mesh_test_send_flags flags,const struct bt_mesh_send_cb * send_cb,void * cb_data)446 int bt_mesh_test_send_async(uint16_t addr, const uint8_t *uuid, size_t len,
447 			    enum bt_mesh_test_send_flags flags,
448 			    const struct bt_mesh_send_cb *send_cb,
449 			    void *cb_data)
450 {
451 	const size_t mic_len =
452 		(flags & LONG_MIC) ? BT_MESH_MIC_LONG : BT_MESH_MIC_SHORT;
453 	static uint8_t count = 1;
454 	int err;
455 
456 	test_send_ctx.addr = addr;
457 	test_send_ctx.send_rel = (flags & FORCE_SEGMENTATION);
458 	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;
459 	test_send_ctx.uuid = uuid;
460 
461 	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_1, BT_MESH_TX_SDU_MAX);
462 	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_1);
463 
464 	if (len > BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1)) {
465 		net_buf_simple_add_u8(&buf, count);
466 	}
467 
468 	/* Subtract the length of the opcode and the sequence ID */
469 	for (int i = 1; i < len - BT_MESH_MODEL_OP_LEN(TEST_MSG_OP_1); i++) {
470 		net_buf_simple_add_u8(&buf, i);
471 	}
472 
473 	if (net_buf_simple_tailroom(&buf) < mic_len) {
474 		LOG_ERR("No room for MIC of len %u in %u byte buffer", mic_len,
475 			buf.len);
476 		return -EINVAL;
477 	}
478 
479 	/* Seal the buffer to prevent accidentally long MICs: */
480 	buf.size = buf.len + mic_len;
481 
482 	LOG_INF("Sending packet 0x%02x: %u %s to 0x%04x force seg: %u...",
483 		count, buf.len, (buf.len == 1 ? "byte" : "bytes"), addr,
484 		(flags & FORCE_SEGMENTATION));
485 
486 	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb,
487 				 cb_data);
488 	if (err) {
489 		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
490 		return err;
491 	}
492 
493 	count++;
494 	test_stats.sent++;
495 	return 0;
496 }
497 
bt_mesh_test_send(uint16_t addr,const uint8_t * uuid,size_t len,enum bt_mesh_test_send_flags flags,k_timeout_t timeout)498 int bt_mesh_test_send(uint16_t addr, const uint8_t *uuid, size_t len,
499 		      enum bt_mesh_test_send_flags flags, k_timeout_t timeout)
500 {
501 	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
502 		return bt_mesh_test_send_async(addr, uuid, len, flags, NULL, NULL);
503 	}
504 
505 	static const struct bt_mesh_send_cb send_cb = {
506 		.start = tx_started,
507 		.end = tx_ended,
508 	};
509 	int64_t uptime = k_uptime_get();
510 	struct sync_send_ctx send_ctx;
511 	int err;
512 
513 	k_sem_init(&send_ctx.sem, 0, 1);
514 	err = bt_mesh_test_send_async(addr, uuid, len, flags, &send_cb, &send_ctx);
515 	if (err) {
516 		return err;
517 	}
518 
519 	err = k_sem_take(&send_ctx.sem, timeout);
520 	if (err) {
521 		LOG_ERR("Send timed out");
522 		return err;
523 	}
524 
525 	if (send_ctx.err) {
526 		return send_ctx.err;
527 	}
528 
529 	LOG_INF("Sending completed (%lld ms)", k_uptime_delta(&uptime));
530 
531 	return 0;
532 }
533 
bt_mesh_test_send_data(uint16_t addr,const uint8_t * uuid,uint8_t * data,size_t len,const struct bt_mesh_send_cb * send_cb,void * cb_data)534 int bt_mesh_test_send_data(uint16_t addr, const uint8_t *uuid, uint8_t *data, size_t len,
535 			   const struct bt_mesh_send_cb *send_cb, void *cb_data)
536 {
537 	int err;
538 
539 	test_send_ctx.addr = addr;
540 	test_send_ctx.send_rel = 0;
541 	test_send_ctx.send_ttl = BT_MESH_TTL_DEFAULT;
542 	test_send_ctx.uuid = uuid;
543 
544 	BT_MESH_MODEL_BUF_DEFINE(buf, TEST_MSG_OP_2, BT_MESH_TX_SDU_MAX);
545 	bt_mesh_model_msg_init(&buf, TEST_MSG_OP_2);
546 
547 	net_buf_simple_add_mem(&buf, data, len);
548 
549 	err = bt_mesh_model_send(test_model, &test_send_ctx, &buf, send_cb, cb_data);
550 	if (err) {
551 		LOG_ERR("bt_mesh_model_send failed (err: %d)", err);
552 		return err;
553 	}
554 
555 	return 0;
556 }
557 
bt_mesh_test_data_cb_setup(void (* cb)(uint8_t *,size_t))558 void bt_mesh_test_data_cb_setup(void (*cb)(uint8_t *, size_t))
559 {
560 	data_cb = cb;
561 }
562 
bt_mesh_test_own_addr_get(uint16_t start_addr)563 uint16_t bt_mesh_test_own_addr_get(uint16_t start_addr)
564 {
565 	return start_addr + get_device_nbr();
566 }
567 
bt_mesh_test_send_over_adv(void * data,size_t len)568 void bt_mesh_test_send_over_adv(void *data, size_t len)
569 {
570 	bt_mesh_test_send_over_adv_cb(data, len, NULL, NULL);
571 }
572 
bt_mesh_test_send_over_adv_cb(void * data,size_t len,const struct bt_mesh_send_cb * cb,void * cb_data)573 void bt_mesh_test_send_over_adv_cb(void *data, size_t len, const struct bt_mesh_send_cb *cb,
574 				   void *cb_data)
575 {
576 	struct bt_mesh_adv *adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
577 						     BT_MESH_TRANSMIT(0, 20), K_NO_WAIT);
578 	net_buf_simple_add_mem(&adv->b, data, len);
579 	bt_mesh_adv_send(adv, cb, cb_data);
580 }
581 
bt_mesh_test_wait_for_packet(bt_le_scan_cb_t scan_cb,struct k_sem * observer_sem,uint16_t wait)582 int bt_mesh_test_wait_for_packet(bt_le_scan_cb_t scan_cb, struct k_sem *observer_sem, uint16_t wait)
583 {
584 	struct bt_le_scan_param scan_param = {
585 		.type       = BT_LE_SCAN_TYPE_PASSIVE,
586 		.options    = BT_LE_SCAN_OPT_NONE,
587 		.interval   = BT_MESH_ADV_SCAN_UNIT(1000),
588 		.window     = BT_MESH_ADV_SCAN_UNIT(1000)
589 	};
590 	int err;
591 	int returned_value = 0;
592 
593 	err = bt_le_scan_start(&scan_param, scan_cb);
594 	if (err && err != -EALREADY) {
595 		LOG_ERR("Starting scan failed (err %d)", err);
596 		return err;
597 	}
598 
599 	err = k_sem_take(observer_sem, K_SECONDS(wait));
600 	if (err == -EAGAIN) {
601 		LOG_WRN("Taking sem timed out (err %d)", err);
602 		returned_value = -ETIMEDOUT;
603 	} else if (err) {
604 		LOG_ERR("Taking sem failed (err %d)", err);
605 		return err;
606 	}
607 
608 	err = bt_le_scan_stop();
609 	if (err && err != -EALREADY) {
610 		LOG_ERR("Stopping scan failed (err %d)", err);
611 		return err;
612 	}
613 
614 	return returned_value;
615 }
616 
617 
618 #if defined(CONFIG_BT_MESH_SAR_CFG)
bt_mesh_test_sar_conf_set(struct bt_mesh_sar_tx * tx_set,struct bt_mesh_sar_rx * rx_set)619 void bt_mesh_test_sar_conf_set(struct bt_mesh_sar_tx *tx_set, struct bt_mesh_sar_rx *rx_set)
620 {
621 	int err;
622 
623 	if (tx_set) {
624 		struct bt_mesh_sar_tx tx_rsp;
625 
626 		err = bt_mesh_sar_cfg_cli_transmitter_set(0, cfg->addr, tx_set, &tx_rsp);
627 		if (err) {
628 			FAIL("Failed to configure SAR Transmitter state (err %d)", err);
629 		}
630 	}
631 
632 	if (rx_set) {
633 		struct bt_mesh_sar_rx rx_rsp;
634 
635 		err = bt_mesh_sar_cfg_cli_receiver_set(0, cfg->addr, rx_set, &rx_rsp);
636 		if (err) {
637 			FAIL("Failed to configure SAR Receiver state (err %d)", err);
638 		}
639 	}
640 }
641 #endif /* defined(CONFIG_BT_MESH_SAR_CFG) */
642