1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <stddef.h>
6 #include <stdint.h>
7 
8 #include <zephyr/kernel.h>
9 
10 #include <zephyr/sys/printk.h>
11 
12 #include <zephyr/bluetooth/ead.h>
13 #include <zephyr/bluetooth/conn.h>
14 
15 #include "bs_types.h"
16 #include "bs_tracing.h"
17 #include "bstests.h"
18 
19 #include <zephyr/logging/log.h>
20 
21 #include "data.h"
22 #include "common.h"
23 
24 LOG_MODULE_REGISTER(bt_bsim_ead_sample, CONFIG_BT_EAD_LOG_LEVEL);
25 
26 #define FAIL(...)                                                                                  \
27 	do {                                                                                       \
28 		bst_result = Failed;                                                               \
29 		bs_trace_error_time_line(__VA_ARGS__);                                             \
30 	} while (0)
31 
32 #define PASS(...)                                                                                  \
33 	do {                                                                                       \
34 		bst_result = Passed;                                                               \
35 		bs_trace_info_time(1, __VA_ARGS__);                                                \
36 	} while (0)
37 
38 extern enum bst_result_t bst_result;
39 
40 #define WAIT_TIME_S 60
41 #define WAIT_TIME   (WAIT_TIME_S * 1e6)
42 
43 extern int run_peripheral_sample(int get_passkey_confirmation(struct bt_conn *conn));
44 extern int run_central_sample(int get_passkey_confirmation(struct bt_conn *conn),
45 			      uint8_t *received_data, size_t received_data_size,
46 			      struct key_material *received_keymat);
47 
get_passkey_confirmation(struct bt_conn * conn)48 static int get_passkey_confirmation(struct bt_conn *conn)
49 {
50 	int err;
51 
52 	err = bt_conn_auth_passkey_confirm(conn);
53 	if (err) {
54 		LOG_ERR("Failed to confirm passkey (err %d)", err);
55 		return -1;
56 	}
57 
58 	printk("Passkey confirmed.\n");
59 
60 	return 0;
61 }
62 
central_main(void)63 static void central_main(void)
64 {
65 	int err;
66 
67 	size_t offset;
68 	size_t expected_data_size = bt_data_get_len(ad, ARRAY_SIZE(ad));
69 	uint8_t expected_data[expected_data_size];
70 
71 	uint8_t received_data[expected_data_size];
72 	struct key_material received_keymat;
73 
74 	offset = 0;
75 	for (size_t i = 0; i < ARRAY_SIZE(ad); i++) {
76 		offset += bt_data_serialize(&ad[i], &expected_data[offset]);
77 	}
78 
79 	err = run_central_sample(get_passkey_confirmation, received_data, expected_data_size,
80 				 &received_keymat);
81 
82 	LOG_DBG("Expected data size: %zu", expected_data_size);
83 
84 	LOG_HEXDUMP_DBG(received_data, expected_data_size, "Received data");
85 	LOG_HEXDUMP_DBG(received_keymat.session_key, BT_EAD_KEY_SIZE, "Receveid key");
86 	LOG_HEXDUMP_DBG(received_keymat.iv, BT_EAD_IV_SIZE, "Received IV");
87 
88 	if (err != 0) {
89 		FAIL("Central test failed. (sample err %d)\n", err);
90 	}
91 
92 	if (memcmp(&received_keymat, &mk, BT_EAD_KEY_SIZE + BT_EAD_IV_SIZE) != 0) {
93 		FAIL("Received Key Material does not match expected one.");
94 	}
95 
96 	if (memcmp(expected_data, received_data, expected_data_size) != 0) {
97 		FAIL("Received data does not match expected ones.\n");
98 	}
99 
100 	PASS("Central test passed.\n");
101 }
102 
peripheral_main(void)103 static void peripheral_main(void)
104 {
105 	int err = run_peripheral_sample(get_passkey_confirmation);
106 
107 	if (err) {
108 		FAIL("Peripheral test failed. (sample err %d)\n");
109 	}
110 
111 	PASS("Peripheral test passed.\n");
112 }
113 
test_tick(bs_time_t HW_device_time)114 void test_tick(bs_time_t HW_device_time)
115 {
116 	if (bst_result != Passed) {
117 		bst_result = Failed;
118 		bs_trace_error_time_line("Test failed (not passed after %d seconds)\n",
119 					 WAIT_TIME_S);
120 	}
121 }
122 
test_ead_sample_init(void)123 static void test_ead_sample_init(void)
124 {
125 	bst_ticker_set_next_tick_absolute(WAIT_TIME);
126 }
127 
128 static const struct bst_test_instance test_def[] = {
129 	{
130 		.test_id = "central",
131 		.test_descr = "Central device",
132 		.test_pre_init_f = test_ead_sample_init,
133 		.test_tick_f = test_tick,
134 		.test_main_f = central_main,
135 	},
136 	{
137 		.test_id = "peripheral",
138 		.test_descr = "Peripheral device",
139 		.test_pre_init_f = test_ead_sample_init,
140 		.test_tick_f = test_tick,
141 		.test_main_f = peripheral_main,
142 	},
143 	BSTEST_END_MARKER};
144 
test_ead_sample_install(struct bst_test_list * tests)145 struct bst_test_list *test_ead_sample_install(struct bst_test_list *tests)
146 {
147 	return bst_add_tests(tests, test_def);
148 }
149 
150 bst_test_install_t test_installers[] = {test_ead_sample_install, NULL};
151 
main(void)152 int main(void)
153 {
154 	bst_main();
155 	return 0;
156 }
157