1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stddef.h>
8 
9 #include <zephyr/kernel.h>
10 
11 #include <zephyr/sys/printk.h>
12 #include <zephyr/sys/util.h>
13 
14 #include "bs_types.h"
15 #include "bs_tracing.h"
16 #include "time_machine.h"
17 #include "bstests.h"
18 
19 #define COUNT      5000   /* Arbitrary GATT Write Cmd iterations used */
20 
21 /* Write Throughput calculation:
22  *  Measure interval = 1 s
23  *  Connection interval = 50 ms
24  *  No. of connection intervals = 20
25  *  Single Tx time, 2M PHY = 1064 us
26  *  tIFS = 150 us
27  *  Single Tx duration = 1214 us
28  *  Full duplex Tx-Rx duration = 2428 us
29  *  Implementation dependent event overhead = 340 us
30  *  Max. incomplete PDU time = 1064 us
31  *  Max. radio idle time per 1 second = (1064 + 340) * 20 = 28080 us
32  *  Packets per 1 second = (1000000 - 28080) / 2428 = 400.297
33  *  GATT Write data length = 244 bytes
34  *  Throughput = 400 * 244 * 8 = 780800 bps
35  */
36 #define WRITE_RATE 780800 /* GATT Write bps recorded in this test */
37 
38 extern uint32_t central_gatt_write(uint32_t count);
39 extern uint32_t peripheral_gatt_write(uint32_t count);
40 
41 #define FAIL(...)					\
42 	do {						\
43 		bst_result = Failed;			\
44 		bs_trace_error_time_line(__VA_ARGS__);	\
45 	} while (0)
46 
47 #define PASS(...)					\
48 	do {						\
49 		bst_result = Passed;			\
50 		bs_trace_info_time(1, __VA_ARGS__);	\
51 	} while (0)
52 
53 extern enum bst_result_t bst_result;
54 
test_central_main(void)55 static void test_central_main(void)
56 {
57 	uint32_t write_rate;
58 
59 	write_rate = central_gatt_write(COUNT);
60 
61 	printk("%s: Write Rate = %u bps\n", __func__, write_rate);
62 	if (write_rate == WRITE_RATE) {
63 		PASS("Central tests passed\n");
64 	} else {
65 		FAIL("Central tests failed\n");
66 	}
67 
68 	/* Give extra time for peripheral side to finish its iterations */
69 	k_sleep(K_SECONDS(1));
70 
71 	bs_trace_silent_exit(0);
72 }
73 
test_peripheral_main(void)74 static void test_peripheral_main(void)
75 {
76 	uint32_t write_rate;
77 
78 	write_rate = peripheral_gatt_write(COUNT);
79 
80 	printk("%s: Write Rate = %u bps\n", __func__, write_rate);
81 	if (write_rate == WRITE_RATE) {
82 		PASS("Peripheral tests passed\n");
83 	} else {
84 		FAIL("Peripheral tests failed\n");
85 	}
86 }
87 
test_gatt_write_init(void)88 static void test_gatt_write_init(void)
89 {
90 	bst_ticker_set_next_tick_absolute(60e6);
91 	bst_result = In_progress;
92 }
93 
test_gatt_write_tick(bs_time_t HW_device_time)94 static void test_gatt_write_tick(bs_time_t HW_device_time)
95 {
96 	bst_result = Failed;
97 	bs_trace_error_line("Test GATT Write finished.\n");
98 }
99 
100 static const struct bst_test_instance test_def[] = {
101 	{
102 		.test_id = "central",
103 		.test_descr = "Central GATT Write",
104 		.test_post_init_f = test_gatt_write_init,
105 		.test_tick_f = test_gatt_write_tick,
106 		.test_main_f = test_central_main
107 	},
108 	{
109 		.test_id = "peripheral",
110 		.test_descr = "Peripheral GATT Write",
111 		.test_post_init_f = test_gatt_write_init,
112 		.test_tick_f = test_gatt_write_tick,
113 		.test_main_f = test_peripheral_main
114 	},
115 	BSTEST_END_MARKER
116 };
117 
test_gatt_write_install(struct bst_test_list * tests)118 struct bst_test_list *test_gatt_write_install(struct bst_test_list *tests)
119 {
120 	return bst_add_tests(tests, test_def);
121 }
122 
123 bst_test_install_t test_installers[] = {
124 	test_gatt_write_install,
125 	NULL
126 };
127 
main(void)128 int main(void)
129 {
130 	bst_main();
131 	return 0;
132 }
133