1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mocks/hci_core.h"
8 #include "mocks/hci_core_expects.h"
9 #include "mocks/net_buf.h"
10 #include "mocks/net_buf_expects.h"
11 #include "testing_common_defs.h"
12 
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/bluetooth/hci_vs.h>
15 #include <zephyr/fff.h>
16 #include <zephyr/kernel.h>
17 
18 #include <host/hci_core.h>
19 #include <host/id.h>
20 
21 DEFINE_FFF_GLOBALS;
22 
23 /* Hold data representing HCI command response for command BT_HCI_OP_VS_READ_STATIC_ADDRS */
24 static struct net_buf hci_cmd_rsp;
25 
26 /* Hold data representing response data for HCI command BT_HCI_OP_VS_READ_STATIC_ADDRS */
27 static struct custom_bt_hci_rp_vs_read_static_addrs {
28 	struct bt_hci_rp_vs_read_static_addrs hci_rp_vs_read_static_addrs;
29 	struct bt_hci_vs_static_addr hci_vs_static_addr[CONFIG_BT_ID_MAX];
30 } __packed hci_cmd_rsp_data;
31 
fff_reset_rule_before(const struct ztest_unit_test * test,void * fixture)32 static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
33 {
34 	memset(&bt_dev, 0x00, sizeof(struct bt_dev));
35 
36 	NET_BUF_FFF_FAKES_LIST(RESET_FAKE);
37 	HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
38 }
39 
40 ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
41 
tc_setup(void * f)42 static void tc_setup(void *f)
43 {
44 	memset(&bt_dev, 0x00, sizeof(struct bt_dev));
45 	memset(&hci_cmd_rsp, 0x00, sizeof(struct net_buf));
46 	memset(&hci_cmd_rsp_data, 0x00, sizeof(struct custom_bt_hci_rp_vs_read_static_addrs));
47 
48 	NET_BUF_FFF_FAKES_LIST(RESET_FAKE);
49 	HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
50 }
51 
52 ZTEST_SUITE(bt_setup_random_id_addr, NULL, NULL, tc_setup, NULL, NULL);
53 
bt_hci_cmd_send_sync_custom_fake(uint16_t opcode,struct net_buf * buf,struct net_buf ** rsp)54 static int bt_hci_cmd_send_sync_custom_fake(uint16_t opcode, struct net_buf *buf,
55 					    struct net_buf **rsp)
56 {
57 	const char *func_name = "bt_hci_cmd_send_sync";
58 
59 	zassert_equal(opcode, BT_HCI_OP_VS_READ_STATIC_ADDRS,
60 		      "'%s()' was called with incorrect '%s' value", func_name, "opcode");
61 	zassert_is_null(buf, "'%s()' was called with incorrect '%s' value", func_name, "buf");
62 	zassert_not_null(rsp, "'%s()' was called with incorrect '%s' value", func_name, "rsp");
63 
64 	*rsp = &hci_cmd_rsp;
65 	hci_cmd_rsp.data = (void *)&hci_cmd_rsp_data.hci_rp_vs_read_static_addrs;
66 
67 	return 0;
68 }
69 
70 /*
71  *  Test reading controller static random address through bt_hci_cmd_send_sync().
72  *  bt_hci_cmd_send_sync() returns 0 (success), the returned number of addresses
73  *  is 1, and actual addresses information exists in the response.
74  *
75  *  Response size should follow the formula
76  *  hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
77  *            rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
78  *
79  *  Response length is properly configured, and response data contains a valid identity
80  *  information.
81  *
82  *  Constraints:
83  *   - bt_hci_cmd_send_sync() returns 0 (success)
84  *   - bt_hci_cmd_send_sync() response contains single identity address
85  *
86  *  Expected behaviour:
87  *   - Non-zero positive number equals to the number of addresses in the response
88  */
ZTEST(bt_setup_random_id_addr,test_bt_hci_cmd_send_sync_returns_single_identity)89 ZTEST(bt_setup_random_id_addr, test_bt_hci_cmd_send_sync_returns_single_identity)
90 {
91 	int err;
92 	uint16_t *vs_commands = (uint16_t *)bt_dev.vs_commands;
93 	struct bt_hci_rp_vs_read_static_addrs *rp =
94 		(void *)&hci_cmd_rsp_data.hci_rp_vs_read_static_addrs;
95 	struct bt_hci_vs_static_addr *static_addr = (void *)&hci_cmd_rsp_data.hci_vs_static_addr;
96 
97 	*vs_commands = (1 << BT_VS_CMD_BIT_READ_STATIC_ADDRS);
98 
99 	rp->num_addrs = 1;
100 	bt_addr_copy(&static_addr[0].bdaddr, &BT_STATIC_RANDOM_LE_ADDR_1->a);
101 
102 	hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
103 			  rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
104 
105 	bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
106 
107 	err = bt_setup_random_id_addr();
108 
109 	expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS);
110 	expect_single_call_net_buf_unref(&hci_cmd_rsp);
111 
112 	zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
113 
114 	zassert_true(bt_dev.id_count == 1, "Incorrect value '%d' was set to bt_dev.id_count",
115 		     bt_dev.id_count);
116 
117 	zassert_mem_equal(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1, sizeof(bt_addr_le_t),
118 			  "Incorrect address was set");
119 }
120 
121 #if CONFIG_BT_ID_MAX > 1
122 
123 /*
124  *  Test reading controller static random address through bt_hci_cmd_send_sync().
125  *  bt_hci_cmd_send_sync() returns 0 (success), the returned number of addresses
126  *  is 2, and actual addresses information exists in the response.
127  *
128  *  Response size should follow the formula
129  *  hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
130  *            rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
131  *
132  *  Response length is properly configured, and response data contains a mixed data with
133  *  2 identities.
134  *
135  *  Constraints:
136  *   - bt_hci_cmd_send_sync() returns 0 (success)
137  *   - bt_hci_cmd_send_sync() response contains multiple identities, but only one is a static
138  *     random address and the other should be discarded
139  *
140  *  Expected behaviour:
141  *   - Non-zero positive number equals to the number of addresses in the response
142  */
ZTEST(bt_setup_random_id_addr,test_bt_hci_cmd_send_sync_returns_single_valid_identity)143 ZTEST(bt_setup_random_id_addr, test_bt_hci_cmd_send_sync_returns_single_valid_identity)
144 {
145 	int err;
146 	uint16_t *vs_commands = (uint16_t *)bt_dev.vs_commands;
147 	struct bt_hci_rp_vs_read_static_addrs *rp =
148 		(void *)&hci_cmd_rsp_data.hci_rp_vs_read_static_addrs;
149 	struct bt_hci_vs_static_addr *static_addr = (void *)&hci_cmd_rsp_data.hci_vs_static_addr;
150 
151 	*vs_commands = (1 << BT_VS_CMD_BIT_READ_STATIC_ADDRS);
152 
153 	rp->num_addrs = 2;
154 	bt_addr_copy(&static_addr[0].bdaddr, &BT_STATIC_RANDOM_LE_ADDR_1->a);
155 	bt_addr_copy(&static_addr[1].bdaddr, BT_ADDR);
156 
157 	hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
158 			  rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
159 
160 	bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
161 
162 	err = bt_setup_random_id_addr();
163 
164 	expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS);
165 	expect_single_call_net_buf_unref(&hci_cmd_rsp);
166 
167 	zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
168 
169 	zassert_true(bt_dev.id_count == 2, "Incorrect value '%d' was set to bt_dev.id_count",
170 		     bt_dev.id_count);
171 
172 	zassert_mem_equal(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1, sizeof(bt_addr_le_t),
173 			  "Incorrect address was set");
174 	zassert_mem_equal(&bt_dev.id_addr[1].a, BT_ADDR, sizeof(bt_addr_t),
175 			  "Incorrect address was set");
176 	zassert_equal(bt_dev.id_addr[1].type, BT_ADDR_LE_RANDOM, "Incorrect address was set");
177 }
178 
179 /*
180  *  Test reading controller static random address through bt_hci_cmd_send_sync().
181  *  bt_hci_cmd_send_sync() returns 0 (success), the returned number of addresses
182  *  is 2, and actual addresses information exists in the response.
183  *
184  *  Response size should follow the formula
185  *  hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
186  *            rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
187  *
188  *  Response length is properly configured, and response data contains 2 valid identities.
189  *
190  *  Constraints:
191  *   - bt_hci_cmd_send_sync() returns 0 (success)
192  *   - bt_hci_cmd_send_sync() response contains multiple identity addresses
193  *
194  *  Expected behaviour:
195  *   - Non-zero positive number equals to the number of addresses in the response
196  */
ZTEST(bt_setup_random_id_addr,test_bt_hci_cmd_send_sync_returns_multiple_identities)197 ZTEST(bt_setup_random_id_addr, test_bt_hci_cmd_send_sync_returns_multiple_identities)
198 {
199 	int err;
200 	uint16_t *vs_commands = (uint16_t *)bt_dev.vs_commands;
201 	struct bt_hci_rp_vs_read_static_addrs *rp =
202 		(void *)&hci_cmd_rsp_data.hci_rp_vs_read_static_addrs;
203 	struct bt_hci_vs_static_addr *static_addr = (void *)&hci_cmd_rsp_data.hci_vs_static_addr;
204 
205 	*vs_commands = (1 << BT_VS_CMD_BIT_READ_STATIC_ADDRS);
206 
207 	rp->num_addrs = 2;
208 	bt_addr_copy(&static_addr[0].bdaddr, &BT_STATIC_RANDOM_LE_ADDR_1->a);
209 	bt_addr_copy(&static_addr[1].bdaddr, &BT_STATIC_RANDOM_LE_ADDR_2->a);
210 
211 	hci_cmd_rsp.len = sizeof(struct bt_hci_rp_vs_read_static_addrs) +
212 			  rp->num_addrs * sizeof(struct bt_hci_vs_static_addr);
213 
214 	bt_hci_cmd_send_sync_fake.custom_fake = bt_hci_cmd_send_sync_custom_fake;
215 
216 	err = bt_setup_random_id_addr();
217 
218 	expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS);
219 	expect_single_call_net_buf_unref(&hci_cmd_rsp);
220 
221 	zassert_true(err == 0, "Unexpected error code '%d' was returned", err);
222 
223 	zassert_true(bt_dev.id_count == 2, "Incorrect value '%d' was set to bt_dev.id_count",
224 		     bt_dev.id_count);
225 
226 	zassert_mem_equal(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1, sizeof(bt_addr_le_t),
227 			  "Incorrect address was set");
228 	zassert_mem_equal(&bt_dev.id_addr[1], BT_STATIC_RANDOM_LE_ADDR_2, sizeof(bt_addr_le_t),
229 			  "Incorrect address was set");
230 }
231 #endif /* CONFIG_BT_ID_MAX > 1 */
232