1 /*
2  * Copyright (c) 2022 Nordic Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/bluetooth/hci.h>
9 #include "mesh_test.h"
10 #include "mesh/net.h"
11 #include "mesh/mesh.h"
12 #include "mesh/foundation.h"
13 #include "gatt_common.h"
14 
15 #define LOG_MODULE_NAME test_adv
16 
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
19 
20 #define WAIT_TIME 60 /*seconds*/
21 
22 extern const struct bt_mesh_comp comp;
23 
24 static uint8_t test_prov_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0xaa };
25 
26 static const struct bt_mesh_test_cfg adv_cfg = {
27 	.addr = 0x0001,
28 	.dev_key = { 0x01 },
29 };
30 
31 static struct bt_mesh_send_cb send_cb;
32 static struct bt_mesh_test_adv xmit_param;
33 static const char txt_msg[] = "adv test";
34 static const char cb_msg[] = "cb test";
35 static int64_t tx_timestamp;
36 static int seq_checker;
37 static struct bt_mesh_test_gatt gatt_param;
38 static int num_adv_sent;
39 static uint8_t previous_checker = 0xff;
40 static bool local_sent, relay_sent;
41 
42 static K_SEM_DEFINE(observer_sem, 0, 1);
43 
test_tx_init(void)44 static void test_tx_init(void)
45 {
46 	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
47 }
48 
test_rx_init(void)49 static void test_rx_init(void)
50 {
51 	bt_mesh_test_cfg_set(NULL, WAIT_TIME);
52 }
53 
bt_init(void)54 static void bt_init(void)
55 {
56 	ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed");
57 	LOG_INF("Bluetooth initialized");
58 }
59 
adv_init(void)60 static void adv_init(void)
61 {
62 	bt_mesh_adv_init();
63 	ASSERT_OK_MSG(bt_mesh_adv_enable(), "Mesh adv init failed");
64 }
65 
allocate_all_array(struct bt_mesh_adv ** adv,size_t num_adv,uint8_t xmit)66 static void allocate_all_array(struct bt_mesh_adv **adv, size_t num_adv, uint8_t xmit)
67 {
68 	for (int i = 0; i < num_adv; i++) {
69 		*adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
70 					  xmit, K_NO_WAIT);
71 
72 		ASSERT_FALSE_MSG(!*adv, "Out of advs\n");
73 		adv++;
74 	}
75 }
76 
verify_adv_queue_overflow(void)77 static void verify_adv_queue_overflow(void)
78 {
79 	struct bt_mesh_adv *dummy_adv;
80 
81 	/* Verity Queue overflow */
82 	dummy_adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
83 				       BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
84 	ASSERT_TRUE_MSG(!dummy_adv, "Unexpected extra adv\n");
85 }
86 
check_delta_time(uint8_t transmit,uint64_t interval)87 static bool check_delta_time(uint8_t transmit, uint64_t interval)
88 {
89 	static int cnt;
90 	static int64_t timestamp;
91 
92 	if (cnt) {
93 		int64_t delta = k_uptime_delta(&timestamp);
94 
95 		LOG_INF("rx: cnt(%d) delta(%dms) interval(%ums)",
96 			cnt, (int32_t)delta, (uint32_t)interval);
97 
98 		ASSERT_TRUE(delta >= (interval - 5) &&
99 			    delta < (interval + 15));
100 	} else {
101 		timestamp = k_uptime_get();
102 
103 		LOG_INF("rx: cnt(%d) delta(0ms)", cnt);
104 	}
105 
106 	cnt++;
107 
108 	if (cnt >= transmit) {
109 		cnt = 0;
110 		timestamp = 0;
111 		return true;
112 	}
113 
114 	return false;
115 }
116 
single_start_cb(uint16_t duration,int err,void * cb_data)117 static void single_start_cb(uint16_t duration, int err, void *cb_data)
118 {
119 	int64_t delta;
120 
121 	delta = k_uptime_delta(&tx_timestamp);
122 	LOG_INF("tx start: +%d ms", delta);
123 	ASSERT_TRUE(duration >= 90 && duration <= 200);
124 	ASSERT_EQUAL(0, err);
125 	ASSERT_EQUAL(cb_msg, cb_data);
126 	ASSERT_EQUAL(0, seq_checker & 1);
127 	seq_checker++;
128 }
129 
single_end_cb(int err,void * cb_data)130 static void single_end_cb(int err, void *cb_data)
131 {
132 	int64_t delta;
133 
134 	delta = k_uptime_delta(&tx_timestamp);
135 	LOG_INF("tx end: +%d ms", delta);
136 	ASSERT_EQUAL(0, err);
137 	ASSERT_EQUAL(cb_msg, cb_data);
138 	ASSERT_EQUAL(1, seq_checker & 1);
139 	seq_checker++;
140 	k_sem_give(&observer_sem);
141 }
142 
realloc_end_cb(int err,void * cb_data)143 static void realloc_end_cb(int err, void *cb_data)
144 {
145 	struct bt_mesh_adv *adv = (struct bt_mesh_adv *)cb_data;
146 
147 	ASSERT_EQUAL(0, err);
148 	adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
149 			BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
150 	ASSERT_FALSE_MSG(!adv, "Out of advs\n");
151 
152 	k_sem_give(&observer_sem);
153 }
154 
seq_start_cb(uint16_t duration,int err,void * cb_data)155 static void seq_start_cb(uint16_t duration, int err, void *cb_data)
156 {
157 	ASSERT_EQUAL(0, err);
158 	ASSERT_EQUAL(seq_checker, (intptr_t)cb_data);
159 }
160 
seq_end_cb(int err,void * cb_data)161 static void seq_end_cb(int err, void *cb_data)
162 {
163 	ASSERT_EQUAL(0, err);
164 	ASSERT_EQUAL(seq_checker, (intptr_t)cb_data);
165 	seq_checker++;
166 
167 	if (seq_checker == CONFIG_BT_MESH_ADV_BUF_COUNT) {
168 		k_sem_give(&observer_sem);
169 	}
170 }
171 
gatt_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)172 static void gatt_scan_cb(const bt_addr_le_t *addr, int8_t rssi,
173 			  uint8_t adv_type, struct net_buf_simple *buf)
174 {
175 	if (adv_type != BT_GAP_ADV_TYPE_ADV_IND) {
176 		return;
177 	}
178 
179 	bt_mesh_test_parse_mesh_gatt_preamble(buf);
180 
181 	if (gatt_param.service == MESH_SERVICE_PROVISIONING) {
182 		bt_mesh_test_parse_mesh_pb_gatt_service(buf);
183 	} else {
184 		bt_mesh_test_parse_mesh_proxy_service(buf);
185 	}
186 
187 	LOG_INF("rx: %s", txt_msg);
188 
189 	if (check_delta_time(gatt_param.transmits, gatt_param.interval)) {
190 		LOG_INF("rx completed. stop observer.");
191 		k_sem_give(&observer_sem);
192 	}
193 }
194 
xmit_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)195 static void xmit_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
196 			struct net_buf_simple *buf)
197 {
198 	uint8_t length;
199 
200 	if (adv_type != BT_GAP_ADV_TYPE_ADV_NONCONN_IND) {
201 		return;
202 	}
203 
204 	length = net_buf_simple_pull_u8(buf);
205 	ASSERT_EQUAL(buf->len, length);
206 	ASSERT_EQUAL(length, sizeof(uint8_t) + sizeof(txt_msg));
207 	ASSERT_EQUAL(BT_DATA_MESH_MESSAGE, net_buf_simple_pull_u8(buf));
208 
209 	char *data = net_buf_simple_pull_mem(buf, sizeof(txt_msg));
210 
211 	LOG_INF("rx: %s", txt_msg);
212 	ASSERT_EQUAL(0, memcmp(txt_msg, data, sizeof(txt_msg)));
213 
214 	/* Add 1 initial transmit to the retransmit. */
215 	if (check_delta_time(xmit_param.retr + 1, xmit_param.interval)) {
216 		LOG_INF("rx completed. stop observer.");
217 		k_sem_give(&observer_sem);
218 	}
219 }
220 
send_order_start_cb(uint16_t duration,int err,void * user_data)221 static void send_order_start_cb(uint16_t duration, int err, void *user_data)
222 {
223 	struct bt_mesh_adv *adv = (struct bt_mesh_adv *)user_data;
224 
225 	ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err);
226 	ASSERT_EQUAL(2, adv->b.len);
227 
228 	uint8_t current = adv->b.data[0];
229 	uint8_t previous = adv->b.data[1];
230 
231 	LOG_INF("tx start: current(%d) previous(%d)", current, previous);
232 
233 	ASSERT_EQUAL(previous_checker, previous);
234 	previous_checker = current;
235 }
236 
send_order_end_cb(int err,void * user_data)237 static void send_order_end_cb(int err, void *user_data)
238 {
239 	ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err);
240 	seq_checker++;
241 	LOG_INF("tx end: seq(%d)", seq_checker);
242 
243 	if (seq_checker == num_adv_sent) {
244 		seq_checker = 0;
245 		previous_checker = 0xff;
246 		k_sem_give(&observer_sem);
247 	}
248 }
249 
receive_order_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)250 static void receive_order_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
251 			struct net_buf_simple *buf)
252 {
253 	uint8_t length;
254 	uint8_t current;
255 	uint8_t previous;
256 
257 	length = net_buf_simple_pull_u8(buf);
258 	ASSERT_EQUAL(buf->len, length);
259 	ASSERT_EQUAL(BT_DATA_MESH_MESSAGE, net_buf_simple_pull_u8(buf));
260 	current = net_buf_simple_pull_u8(buf);
261 	previous = net_buf_simple_pull_u8(buf);
262 	LOG_INF("rx: current(%d) previous(%d)", current, previous);
263 	ASSERT_EQUAL(previous_checker, previous);
264 
265 	/* Add 1 initial transmit to the retransmit. */
266 	if (check_delta_time(xmit_param.retr + 1, xmit_param.interval)) {
267 		previous_checker = current;
268 		k_sem_give(&observer_sem);
269 	}
270 }
271 
receive_order(int expect_adv)272 static void receive_order(int expect_adv)
273 {
274 	previous_checker = 0xff;
275 	for (int i = 0; i < expect_adv; i++) {
276 		ASSERT_OK(bt_mesh_test_wait_for_packet(receive_order_scan_cb, &observer_sem, 10));
277 	}
278 }
279 
send_adv_buf(struct bt_mesh_adv * adv,uint8_t curr,uint8_t prev)280 static void send_adv_buf(struct bt_mesh_adv *adv, uint8_t curr, uint8_t prev)
281 {
282 	send_cb.start = send_order_start_cb;
283 	send_cb.end = send_order_end_cb;
284 
285 	(void)net_buf_simple_add_u8(&adv->b, curr);
286 	(void)net_buf_simple_add_u8(&adv->b, prev);
287 
288 	bt_mesh_adv_send(adv, &send_cb, adv);
289 	bt_mesh_adv_unref(adv);
290 }
291 
send_adv_array(struct bt_mesh_adv ** adv,size_t num_buf,bool reverse)292 static void send_adv_array(struct bt_mesh_adv **adv, size_t num_buf, bool reverse)
293 {
294 	uint8_t previous;
295 	int i;
296 
297 	num_adv_sent = num_buf;
298 	previous = 0xff;
299 	if (!reverse) {
300 		i = 0;
301 	} else {
302 		i = num_buf - 1;
303 	}
304 	while ((!reverse && i < num_buf) || (reverse && i >= 0)) {
305 		send_adv_buf(*adv, (uint8_t)i, previous);
306 		previous = (uint8_t)i;
307 		if (!reverse) {
308 			adv++;
309 			i++;
310 		} else {
311 			adv--;
312 			i--;
313 		}
314 	}
315 }
316 
test_tx_cb_single(void)317 static void test_tx_cb_single(void)
318 {
319 	struct bt_mesh_adv *adv;
320 	int err;
321 
322 	bt_init();
323 	adv_init();
324 
325 	adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
326 			BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
327 	ASSERT_FALSE_MSG(!adv, "Out of advs\n");
328 
329 	send_cb.start = single_start_cb;
330 	send_cb.end = single_end_cb;
331 
332 	net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg));
333 	seq_checker = 0;
334 	tx_timestamp = k_uptime_get();
335 	bt_mesh_adv_send(adv, &send_cb, (void *)cb_msg);
336 	bt_mesh_adv_unref(adv);
337 
338 	err = k_sem_take(&observer_sem, K_SECONDS(1));
339 	ASSERT_OK_MSG(err, "Didn't call end tx cb.");
340 
341 	PASS();
342 }
343 
test_rx_xmit(void)344 static void test_rx_xmit(void)
345 {
346 	xmit_param.retr = 2;
347 	xmit_param.interval = 20;
348 
349 	bt_init();
350 	ASSERT_OK(bt_mesh_test_wait_for_packet(xmit_scan_cb, &observer_sem, 20));
351 
352 	PASS();
353 }
354 
test_tx_cb_multi(void)355 static void test_tx_cb_multi(void)
356 {
357 	struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT];
358 	int err;
359 
360 	bt_init();
361 	adv_init();
362 
363 	/* Allocate all network advs. */
364 	allocate_all_array(adv, ARRAY_SIZE(adv), BT_MESH_TRANSMIT(2, 20));
365 
366 	/* Start single adv to reallocate one network adv in callback.
367 	 * Check that the adv is freed before cb is triggered.
368 	 */
369 	send_cb.start = NULL;
370 	send_cb.end = realloc_end_cb;
371 	net_buf_simple_add_mem(&(adv[0]->b), txt_msg, sizeof(txt_msg));
372 
373 	bt_mesh_adv_send(adv[0], &send_cb, adv[0]);
374 	bt_mesh_adv_unref(adv[0]);
375 
376 	err = k_sem_take(&observer_sem, K_SECONDS(1));
377 	ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates adv one more time.");
378 
379 	/* Start multi advs to check that all advs are sent and cbs are triggered. */
380 	send_cb.start = seq_start_cb;
381 	send_cb.end = seq_end_cb;
382 	seq_checker = 0;
383 
384 	for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
385 		net_buf_simple_add_le32(&(adv[i]->b), i);
386 		bt_mesh_adv_send(adv[i], &send_cb, (void *)(intptr_t)i);
387 		bt_mesh_adv_unref(adv[i]);
388 	}
389 
390 	err = k_sem_take(&observer_sem, K_SECONDS(10));
391 	ASSERT_OK_MSG(err, "Didn't call the last end tx cb.");
392 
393 	PASS();
394 }
395 
test_tx_proxy_mixin(void)396 static void test_tx_proxy_mixin(void)
397 {
398 	static struct bt_mesh_prov prov = {
399 		.uuid = test_prov_uuid,
400 	};
401 	uint8_t status;
402 	int err;
403 
404 	/* Initialize mesh stack and enable pb gatt bearer to emit beacons. */
405 	bt_mesh_device_setup(&prov, &comp);
406 	err = bt_mesh_prov_enable(BT_MESH_PROV_GATT);
407 	ASSERT_OK_MSG(err, "Failed to enable GATT provisioner");
408 
409 	/* Let the tester to measure an interval between advertisements.
410 	 * The node should advertise pb gatt service with 100 msec interval.
411 	 */
412 	k_sleep(K_MSEC(1800));
413 
414 	LOG_INF("Provision device under test");
415 	/* Provision dut and start gatt proxy beacons. */
416 	bt_mesh_provision(test_net_key, 0, 0, 0, adv_cfg.addr, adv_cfg.dev_key);
417 	/* Disable secured network beacons to exclude influence of them on proxy beaconing. */
418 	ASSERT_OK(bt_mesh_cfg_cli_beacon_set(0, adv_cfg.addr, BT_MESH_BEACON_DISABLED, &status));
419 	ASSERT_EQUAL(BT_MESH_BEACON_DISABLED, status);
420 
421 	/* Let the tester to measure an interval between advertisements.
422 	 * The node should advertise proxy service with 1 second interval.
423 	 */
424 	k_sleep(K_MSEC(6000));
425 
426 	/* Send a mesh message while advertising proxy service.
427 	 * Advertising the proxy service should be resumed after
428 	 * finishing advertising the message.
429 	 */
430 	struct bt_mesh_adv *adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
431 			BT_MESH_TRANSMIT(5, 20), K_NO_WAIT);
432 	net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg));
433 	bt_mesh_adv_send(adv, NULL, NULL);
434 	k_sleep(K_MSEC(150));
435 
436 	/* Let the tester to measure an interval between advertisements again. */
437 	k_sleep(K_MSEC(6000));
438 
439 	PASS();
440 }
441 
test_rx_proxy_mixin(void)442 static void test_rx_proxy_mixin(void)
443 {
444 	/* (total transmit duration) / (transmit interval) */
445 	gatt_param.transmits = 1500 / 100;
446 	gatt_param.interval = 100;
447 	gatt_param.service = MESH_SERVICE_PROVISIONING;
448 
449 	bt_init();
450 
451 	/* Scan pb gatt beacons. */
452 	ASSERT_OK(bt_mesh_test_wait_for_packet(gatt_scan_cb, &observer_sem, 20));
453 
454 	/* Delay to provision dut */
455 	k_sleep(K_MSEC(1000));
456 
457 	/* Scan proxy beacons. */
458 	/* (total transmit duration) / (transmit interval) */
459 	gatt_param.transmits = 5000 / 1000;
460 	gatt_param.interval = 1000;
461 	gatt_param.service = MESH_SERVICE_PROXY;
462 	ASSERT_OK(bt_mesh_test_wait_for_packet(gatt_scan_cb, &observer_sem, 20));
463 
464 	/* Scan adv data. */
465 	xmit_param.retr = 5;
466 	xmit_param.interval = 20;
467 	ASSERT_OK(bt_mesh_test_wait_for_packet(xmit_scan_cb, &observer_sem, 20));
468 
469 	/* Scan proxy beacons again. */
470 	ASSERT_OK(bt_mesh_test_wait_for_packet(gatt_scan_cb, &observer_sem, 20));
471 
472 	PASS();
473 }
474 
test_tx_send_order(void)475 static void test_tx_send_order(void)
476 {
477 	struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT];
478 	uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
479 
480 	bt_init();
481 	adv_init();
482 
483 	/* Verify sending order */
484 	allocate_all_array(adv, ARRAY_SIZE(adv), xmit);
485 	verify_adv_queue_overflow();
486 	send_adv_array(&adv[0], ARRAY_SIZE(adv), false);
487 
488 	/* Wait for no message receive window to end. */
489 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
490 		      "Didn't call the last end tx cb.");
491 
492 	/* Verify adv allocation/deallocation after sending */
493 	allocate_all_array(adv, ARRAY_SIZE(adv), xmit);
494 	verify_adv_queue_overflow();
495 	for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
496 		bt_mesh_adv_unref(adv[i]);
497 		adv[i] = NULL;
498 	}
499 	/* Check that it possible to add just one net adv. */
500 	allocate_all_array(adv, 1, xmit);
501 
502 	PASS();
503 }
504 
cancel_adv_send_start(uint16_t duration,int err,void * cb_data)505 static void cancel_adv_send_start(uint16_t duration, int err, void *cb_data)
506 {
507 	if (cb_data != NULL) {
508 		struct bt_mesh_adv *adv_cancel = (struct bt_mesh_adv *)cb_data;
509 
510 		adv_cancel->ctx.busy = 0;
511 
512 		bt_mesh_adv_unref(adv_cancel);
513 
514 		return;
515 	}
516 
517 	ASSERT_FALSE_MSG(true, "The adv should be canceled.\n");
518 }
519 
cancel_adv_send_end(int err,void * cb_data)520 static void cancel_adv_send_end(int err, void *cb_data)
521 {
522 	k_sem_give(&observer_sem);
523 }
524 
test_tx_send_cancel(void)525 static void test_tx_send_cancel(void)
526 {
527 	static const struct bt_mesh_send_cb local_send_cb = {
528 		.start = cancel_adv_send_start,
529 		.end = cancel_adv_send_end,
530 	};
531 	struct bt_mesh_adv *adv_cancel;
532 	uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
533 	struct bt_mesh_adv *local;
534 
535 	bt_init();
536 	adv_init();
537 
538 	local = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
539 				   xmit, K_NO_WAIT);
540 	ASSERT_FALSE_MSG(!local, "Out of local advs\n");
541 
542 	adv_cancel = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
543 					 xmit, K_NO_WAIT);
544 	ASSERT_FALSE_MSG(!adv_cancel, "Out of local advs\n");
545 
546 	net_buf_simple_add_u8(&local->b, 0x00);
547 	net_buf_simple_add_u8(&adv_cancel->b, 0x01);
548 
549 	bt_mesh_adv_send(local, &local_send_cb, bt_mesh_adv_ref(adv_cancel));
550 	bt_mesh_adv_send(adv_cancel, &local_send_cb, NULL);
551 
552 	bt_mesh_adv_unref(local);
553 	bt_mesh_adv_unref(adv_cancel);
554 
555 	/* Make relay advs sent out. */
556 	k_sleep(K_SECONDS(1));
557 
558 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
559 		      "Didn't call the last end tx cb.");
560 
561 	PASS();
562 }
563 
terminate_adv_send_start(uint16_t duration,int err,void * cb_data)564 static void terminate_adv_send_start(uint16_t duration, int err, void *cb_data)
565 {
566 	if (cb_data == NULL) {
567 		k_sem_give(&observer_sem);
568 		return;
569 	}
570 }
571 
terminate_adv_send_end(int err,void * cb_data)572 static void terminate_adv_send_end(int err, void *cb_data)
573 {
574 	ASSERT_FALSE_MSG(true, "The adv should be terminated.\n");
575 }
576 
test_tx_send_terminate(void)577 static void test_tx_send_terminate(void)
578 {
579 	static const struct bt_mesh_send_cb local_send_cb = {
580 		.start = terminate_adv_send_start,
581 		.end = terminate_adv_send_end,
582 	};
583 	uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
584 	struct bt_mesh_adv *local;
585 
586 	bt_init();
587 	adv_init();
588 
589 	local = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
590 				   xmit, K_NO_WAIT);
591 	ASSERT_FALSE_MSG(!local, "Out of local advs\n");
592 
593 	net_buf_simple_add_u8(&local->b, 0x00);
594 
595 	bt_mesh_adv_send(local, &local_send_cb, NULL);
596 
597 	bt_mesh_adv_unref(local);
598 
599 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
600 		      "Didn't call the last start tx cb.");
601 
602 	bt_mesh_adv_terminate(local);
603 
604 	/* Make relay advs sent out. */
605 	k_sleep(K_SECONDS(1));
606 
607 	PASS();
608 }
609 
local_adv_send_end(int err,void * cb_data)610 static void local_adv_send_end(int err, void *cb_data)
611 {
612 	local_sent = true;
613 }
614 
relay_adv_send_start(uint16_t duration,int err,void * cb_data)615 static void relay_adv_send_start(uint16_t duration, int err, void *cb_data)
616 {
617 #if defined(CONFIG_BT_MESH_RELAY_ADV_SETS) && CONFIG_BT_MESH_RELAY_ADV_SETS > 0
618 	ASSERT_FALSE_MSG(local_sent,
619 			 "The relay adv should sending with the local adv in parallel.\n");
620 #else
621 	ASSERT_FALSE_MSG(!local_sent,
622 			 "The relay adv should start to sending after sent local adv.\n");
623 #endif
624 }
625 
relay_adv_send_end(int err,void * cb_data)626 static void relay_adv_send_end(int err, void *cb_data)
627 {
628 	relay_sent = true;
629 }
630 
second_relay_adv_send_start(uint16_t duration,int err,void * cb_data)631 static void second_relay_adv_send_start(uint16_t duration, int err, void *cb_data)
632 {
633 #if defined(CONFIG_BT_MESH_RELAY_ADV_SETS) && CONFIG_BT_MESH_RELAY_ADV_SETS > 0
634 	ASSERT_FALSE_MSG(relay_sent,
635 			 "The second relay adv should sending with the first relay"
636 			 " adv in parallel\n");
637 #else
638 	ASSERT_FALSE_MSG(!relay_sent,
639 			 "The second relay adv should start to sending after sent"
640 			 " first relay adv\n");
641 #endif
642 }
643 
second_relay_adv_send_end(int err,void * cb_data)644 static void second_relay_adv_send_end(int err, void *cb_data)
645 {
646 	k_sem_give(&observer_sem);
647 }
648 
test_tx_send_relay(void)649 static void test_tx_send_relay(void)
650 {
651 	static const struct bt_mesh_send_cb local_send_cb = {
652 		.end = local_adv_send_end,
653 	};
654 	static const struct bt_mesh_send_cb relay_first_send_cb = {
655 		.start = relay_adv_send_start,
656 		.end = relay_adv_send_end,
657 	};
658 	static const struct bt_mesh_send_cb relay_second_send_cb = {
659 		.start = second_relay_adv_send_start,
660 		.end = second_relay_adv_send_end,
661 	};
662 	struct bt_mesh_adv *local, *relay_first, *relay_second;
663 	uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
664 
665 	bt_init();
666 	adv_init();
667 
668 	local = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
669 				   xmit, K_NO_WAIT);
670 	ASSERT_FALSE_MSG(!local, "Out of local advs\n");
671 
672 	relay_first = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY,
673 					 xmit, K_NO_WAIT);
674 	ASSERT_FALSE_MSG(!relay_first, "Out of relay advs\n");
675 
676 	relay_second = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY,
677 					  xmit, K_NO_WAIT);
678 	ASSERT_FALSE_MSG(!relay_second, "Out of relay advs\n");
679 
680 	net_buf_simple_add_u8(&local->b, 0x00);
681 	net_buf_simple_add_u8(&relay_first->b, 0x01);
682 	net_buf_simple_add_u8(&relay_second->b, 0x02);
683 
684 	bt_mesh_adv_send(local, &local_send_cb, NULL);
685 	bt_mesh_adv_send(relay_first, &relay_first_send_cb, NULL);
686 	bt_mesh_adv_send(relay_second, &relay_second_send_cb, NULL);
687 
688 	bt_mesh_adv_unref(local);
689 	bt_mesh_adv_unref(relay_first);
690 	bt_mesh_adv_unref(relay_second);
691 
692 	/* Make relay advs sent out. */
693 	k_sleep(K_SECONDS(1));
694 
695 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
696 		      "Didn't call the last end tx cb.");
697 
698 	PASS();
699 }
700 
test_tx_reverse_order(void)701 static void test_tx_reverse_order(void)
702 {
703 	struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT];
704 	uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
705 
706 	bt_init();
707 	adv_init();
708 
709 	/* Verify reversed sending order */
710 	allocate_all_array(adv, ARRAY_SIZE(adv), xmit);
711 
712 	send_adv_array(&adv[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(adv), true);
713 
714 	/* Wait for no message receive window to end. */
715 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
716 		      "Didn't call the last end tx cb.");
717 
718 	PASS();
719 }
720 
test_tx_random_order(void)721 static void test_tx_random_order(void)
722 {
723 	struct bt_mesh_adv *adv[3];
724 	uint8_t xmit = BT_MESH_TRANSMIT(0, 20);
725 
726 	bt_init();
727 	adv_init();
728 
729 	/* Verify random order calls */
730 	num_adv_sent = ARRAY_SIZE(adv);
731 	previous_checker = 0xff;
732 	adv[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
733 				    xmit, K_NO_WAIT);
734 	ASSERT_FALSE_MSG(!adv[0], "Out of advs\n");
735 	adv[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
736 				    xmit, K_NO_WAIT);
737 	ASSERT_FALSE_MSG(!adv[1], "Out of advs\n");
738 
739 	send_adv_buf(adv[0], 0, 0xff);
740 
741 	adv[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
742 				    xmit, K_NO_WAIT);
743 	ASSERT_FALSE_MSG(!adv[2], "Out of advs\n");
744 
745 	send_adv_buf(adv[2], 2, 0);
746 
747 	send_adv_buf(adv[1], 1, 2);
748 
749 	/* Wait for no message receive window to end. */
750 	ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
751 		      "Didn't call the last end tx cb.");
752 
753 	PASS();
754 }
755 
test_rx_receive_order(void)756 static void test_rx_receive_order(void)
757 {
758 	bt_init();
759 
760 	xmit_param.retr = 2;
761 	xmit_param.interval = 20;
762 
763 	receive_order(CONFIG_BT_MESH_ADV_BUF_COUNT);
764 
765 	PASS();
766 }
767 
test_rx_random_order(void)768 static void test_rx_random_order(void)
769 {
770 	bt_init();
771 
772 	xmit_param.retr = 0;
773 	xmit_param.interval = 20;
774 
775 	receive_order(3);
776 
777 	PASS();
778 }
779 
adv_suspend(void)780 static void adv_suspend(void)
781 {
782 	atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
783 
784 	ASSERT_OK_MSG(bt_mesh_adv_disable(), "Failed to disable advertiser sync");
785 }
786 
adv_resume(void)787 static void adv_resume(void)
788 {
789 	atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
790 
791 	if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
792 		bt_mesh_adv_init();
793 	}
794 
795 	ASSERT_OK_MSG(bt_mesh_adv_enable(), "Failed to enable advertiser");
796 }
797 
798 struct adv_suspend_ctx {
799 	bool suspend;
800 	int instance_idx;
801 };
802 
803 static K_SEM_DEFINE(adv_sent_sem, 0, 1);
804 static K_SEM_DEFINE(adv_suspended_sem, 0, 1);
805 
adv_send_end(int err,void * cb_data)806 static void adv_send_end(int err, void *cb_data)
807 {
808 	struct adv_suspend_ctx *adv_data = cb_data;
809 
810 	LOG_DBG("end(): err (%d), suspend (%d), i (%d)", err, adv_data->suspend,
811 		adv_data->instance_idx);
812 
813 	ASSERT_EQUAL(err, 0);
814 
815 	if (adv_data->suspend) {
816 		/* When suspending, the end callback will be called only for the first adv, because
817 		 * it was already scheduled.
818 		 */
819 		ASSERT_EQUAL(adv_data->instance_idx, 0);
820 	} else {
821 		if (adv_data->instance_idx == CONFIG_BT_MESH_ADV_BUF_COUNT - 1) {
822 			k_sem_give(&adv_sent_sem);
823 		}
824 	}
825 }
826 
adv_send_start(uint16_t duration,int err,void * cb_data)827 static void adv_send_start(uint16_t duration, int err, void *cb_data)
828 {
829 	struct adv_suspend_ctx *adv_data = cb_data;
830 
831 	LOG_DBG("start(): err (%d), suspend (%d), i (%d)", err, adv_data->suspend,
832 		adv_data->instance_idx);
833 
834 	if (adv_data->suspend) {
835 		if (adv_data->instance_idx == 0) {
836 			ASSERT_EQUAL(err, 0);
837 			adv_suspend();
838 		} else {
839 			/* For the advs that were pushed to the mesh advertiser by calling
840 			 * `bt_mesh_adv_send` function but not sent to the host, the start callback
841 			 * shall be called with -ENODEV.
842 			 */
843 			ASSERT_EQUAL(err, -ENODEV);
844 		}
845 
846 		if (adv_data->instance_idx == CONFIG_BT_MESH_ADV_BUF_COUNT - 1) {
847 			k_sem_give(&adv_suspended_sem);
848 		}
849 	} else {
850 		ASSERT_EQUAL(err, 0);
851 	}
852 }
853 
adv_create_and_send(bool suspend,uint8_t first_byte,struct adv_suspend_ctx * adv_data)854 static void adv_create_and_send(bool suspend, uint8_t first_byte, struct adv_suspend_ctx *adv_data)
855 {
856 	struct bt_mesh_adv *advs[CONFIG_BT_MESH_ADV_BUF_COUNT];
857 	static const struct bt_mesh_send_cb send_cb = {
858 		.start = adv_send_start,
859 		.end = adv_send_end,
860 	};
861 
862 	for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
863 		adv_data[i].suspend = suspend;
864 		adv_data[i].instance_idx = i;
865 
866 		advs[i] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
867 					    BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
868 		ASSERT_FALSE_MSG(!advs[i], "Out of advs\n");
869 
870 		net_buf_simple_add_u8(&advs[i]->b, first_byte);
871 		net_buf_simple_add_u8(&advs[i]->b, i);
872 	}
873 
874 	for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
875 		bt_mesh_adv_send(advs[i], &send_cb, &adv_data[i]);
876 		bt_mesh_adv_unref(advs[i]);
877 	}
878 }
879 
test_tx_disable(void)880 static void test_tx_disable(void)
881 {
882 	struct adv_suspend_ctx adv_data[CONFIG_BT_MESH_ADV_BUF_COUNT];
883 	struct bt_mesh_adv *extra_adv;
884 	int err;
885 
886 	bt_init();
887 	adv_init();
888 
889 	/* Fill up the adv pool and suspend the advertiser in the first start callback call. */
890 	adv_create_and_send(true, 0xAA, adv_data);
891 
892 	err = k_sem_take(&adv_suspended_sem, K_SECONDS(10));
893 	ASSERT_OK_MSG(err, "Not all advs were sent");
894 
895 	extra_adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL,
896 				       BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
897 	ASSERT_TRUE_MSG(!extra_adv, "Created adv while suspended");
898 
899 	adv_resume();
900 
901 	/* Fill up the adv pool and suspend the advertiser and let it send all advs. */
902 	adv_create_and_send(false, 0xBB, adv_data);
903 
904 	err = k_sem_take(&adv_sent_sem, K_SECONDS(10));
905 	ASSERT_OK_MSG(err, "Not all advs were sent");
906 
907 	PASS();
908 }
909 
suspended_adv_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)910 static void suspended_adv_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
911 				  struct net_buf_simple *buf)
912 {
913 	uint8_t length;
914 	uint8_t type;
915 	uint8_t pdu;
916 
917 	length = net_buf_simple_pull_u8(buf);
918 	ASSERT_EQUAL(buf->len, length);
919 	ASSERT_EQUAL(length, sizeof(uint8_t) * 3);
920 	type = net_buf_simple_pull_u8(buf);
921 	ASSERT_EQUAL(BT_DATA_MESH_MESSAGE, type);
922 
923 	pdu = net_buf_simple_pull_u8(buf);
924 	if (pdu == 0xAA) {
925 		pdu = net_buf_simple_pull_u8(buf);
926 
927 		/* Because the advertiser is stopped after the advertisement has been passed to the
928 		 * host, the controller could already start sending the message. Therefore, if the
929 		 * tester receives an advertisement with the first byte as 0xAA, the second byte can
930 		 * only be 0x00. This applies to both advertisers.
931 		 */
932 		ASSERT_EQUAL(0, pdu);
933 	}
934 }
935 
test_rx_disable(void)936 static void test_rx_disable(void)
937 {
938 	int err;
939 
940 	bt_init();
941 
942 	/* It is sufficient to check that the advertiser didn't sent PDUs which the end callback was
943 	 * not called for.
944 	 */
945 	err = bt_mesh_test_wait_for_packet(suspended_adv_scan_cb, &observer_sem, 20);
946 	/* The error will always be -ETIMEDOUT as the semaphore is never given in the callback. */
947 	ASSERT_EQUAL(-ETIMEDOUT, err);
948 
949 	PASS();
950 }
951 
952 #define TEST_CASE(role, name, description)                     \
953 	{                                                      \
954 		.test_id = "adv_" #role "_" #name,             \
955 		.test_descr = description,                     \
956 		.test_pre_init_f = test_##role##_init,         \
957 		.test_tick_f = bt_mesh_test_timeout,           \
958 		.test_main_f = test_##role##_##name,           \
959 	}
960 
961 static const struct bst_test_instance test_adv[] = {
962 	TEST_CASE(tx, cb_single,     "ADV: tx cb parameter checker"),
963 	TEST_CASE(tx, cb_multi,      "ADV: tx cb sequence checker"),
964 	TEST_CASE(tx, proxy_mixin,   "ADV: proxy mix-in gatt adv"),
965 	TEST_CASE(tx, send_cancel,   "ADV: tx send cancel"),
966 	TEST_CASE(tx, send_terminate, "ADV: tx send terminate"),
967 	TEST_CASE(tx, send_order,    "ADV: tx send order"),
968 	TEST_CASE(tx, send_relay,    "ADV: tx relay sent order"),
969 	TEST_CASE(tx, reverse_order, "ADV: tx reversed order"),
970 	TEST_CASE(tx, random_order,  "ADV: tx random order"),
971 	TEST_CASE(tx, disable,       "ADV: test suspending/resuming advertiser"),
972 
973 	TEST_CASE(rx, xmit,          "ADV: xmit checker"),
974 	TEST_CASE(rx, proxy_mixin,   "ADV: proxy mix-in scanner"),
975 	TEST_CASE(rx, receive_order, "ADV: rx receive order"),
976 	TEST_CASE(rx, random_order,  "ADV: rx random order"),
977 	TEST_CASE(rx, disable,       "ADV: rx adv from resumed advertiser"),
978 
979 	BSTEST_END_MARKER
980 };
981 
test_adv_install(struct bst_test_list * tests)982 struct bst_test_list *test_adv_install(struct bst_test_list *tests)
983 {
984 	tests = bst_add_tests(tests, test_adv);
985 	return tests;
986 }
987