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