1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mocks/adv.h"
8 #include "mocks/adv_expects.h"
9 #include "mocks/hci_core.h"
10 #include "mocks/hci_core_expects.h"
11 #include "testing_common_defs.h"
12 
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/ztest.h>
16 
17 #include <host/hci_core.h>
18 #include <host/id.h>
19 
20 ZTEST_SUITE(bt_id_reset_invalid_inputs, NULL, NULL, NULL, NULL, NULL);
21 
22 /*
23  *  Test resetting default ID which shouldn't be allowed
24  *
25  *  Constraints:
26  *   - BT_ID_DEFAULT value is used for the ID
27  *   - Input address is NULL
28  *   - Input IRK is NULL
29  *
30  *  Expected behaviour:
31  *   - '-EINVAL' error code is returned representing invalid values were used.
32  */
ZTEST(bt_id_reset_invalid_inputs,test_resetting_default_id)33 ZTEST(bt_id_reset_invalid_inputs, test_resetting_default_id)
34 {
35 	int err;
36 
37 	err = bt_id_reset(BT_ID_DEFAULT, NULL, NULL);
38 
39 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
40 }
41 
42 /*
43  *  Test resetting ID value that is equal to bt_dev.id_count
44  *
45  *  Constraints:
46  *   - bt_dev.id_count is greater than 0
47  *   - ID value used is equal to bt_dev.id_count
48  *   - Input address is NULL
49  *   - Input IRK is NULL
50  *
51  *  Expected behaviour:
52  *   - '-EINVAL' error code is returned representing invalid values were used.
53  */
ZTEST(bt_id_reset_invalid_inputs,test_resetting_id_value_equal_to_dev_id_count)54 ZTEST(bt_id_reset_invalid_inputs, test_resetting_id_value_equal_to_dev_id_count)
55 {
56 	int err;
57 
58 	bt_dev.id_count = 1;
59 
60 	err = bt_id_reset(bt_dev.id_count, NULL, NULL);
61 
62 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
63 }
64 
65 /*
66  *  Test using a valid IRK pointer value while privacy isn't enabled
67  *
68  *  Constraints:
69  *   - BT_ID_DEFAULT is used for the ID
70  *   - Input address is NULL
71  *   - Input IRK isn't NULL
72  *   - 'CONFIG_BT_PRIVACY' isn't enabled
73  *
74  *  Expected behaviour:
75  *   - '-EINVAL' error code is returned representing invalid values were used.
76  */
ZTEST(bt_id_reset_invalid_inputs,test_null_addr_valid_irk_no_privacy_enabled)77 ZTEST(bt_id_reset_invalid_inputs, test_null_addr_valid_irk_no_privacy_enabled)
78 {
79 	int err;
80 	uint8_t valid_irk_ptr[16];
81 
82 	err = bt_id_reset(BT_ID_DEFAULT, NULL, valid_irk_ptr);
83 
84 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
85 }
86 
87 /*
88  *  Test invalid input arguments to bt_id_reset() by using a valid address of type public and using
89  *  NULL value for the IRK.
90  *
91  *  Constraints:
92  *   - BT_ID_DEFAULT is used for the ID
93  *   - A valid address of type public is used
94  *   - Input IRK is NULL
95  *
96  *  Expected behaviour:
97  *   - '-EINVAL' error code is returned representing invalid values were used.
98  */
ZTEST(bt_id_reset_invalid_inputs,test_public_address)99 ZTEST(bt_id_reset_invalid_inputs, test_public_address)
100 {
101 	int err;
102 
103 	err = bt_id_reset(BT_ID_DEFAULT, BT_LE_ADDR, NULL);
104 
105 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
106 }
107 
108 /*
109  *  Test invalid input arguments to bt_id_reset() by using a valid address of type RPA and using
110  *  NULL value for the IRK.
111  *
112  *  Constraints:
113  *   - BT_ID_DEFAULT is used for the ID
114  *   - An RPA address of type random is used
115  *   - Input IRK is NULL
116  *
117  *  Expected behaviour:
118  *   - '-EINVAL' error code is returned representing invalid values were used.
119  */
ZTEST(bt_id_reset_invalid_inputs,test_rpa_address)120 ZTEST(bt_id_reset_invalid_inputs, test_rpa_address)
121 {
122 	int err;
123 
124 	err = bt_id_reset(BT_ID_DEFAULT, BT_RPA_LE_ADDR, NULL);
125 
126 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
127 }
128 
129 /*
130  *  Test invalid input arguments to bt_id_reset() by using an address that already exists
131  *  in the identity list.
132  *
133  *  Constraints:
134  *   - BT_ID_DEFAULT is used for the ID
135  *   - A valid random static address is used
136  *   - Input address already exists in the identity list
137  *   - Input IRK is NULL
138  *
139  *  Expected behaviour:
140  *   - '-EALREADY' error code is returned representing invalid values were used.
141  */
ZTEST(bt_id_reset_invalid_inputs,test_pa_address_exists_in_id_list)142 ZTEST(bt_id_reset_invalid_inputs, test_pa_address_exists_in_id_list)
143 {
144 	int err;
145 
146 	bt_dev.id_count = 1;
147 	bt_addr_le_copy(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1);
148 
149 	err = bt_id_reset(BT_ID_DEFAULT, BT_STATIC_RANDOM_LE_ADDR_1, NULL);
150 
151 	zassert_true(err == -EALREADY, "Unexpected error code '%d' was returned", err);
152 }
153 
bt_le_ext_adv_foreach_custom_fake(void (* func)(struct bt_le_ext_adv * adv,void * data),void * data)154 static void bt_le_ext_adv_foreach_custom_fake(void (*func)(struct bt_le_ext_adv *adv, void *data),
155 					      void *data)
156 {
157 	struct bt_le_ext_adv adv_params = {0};
158 
159 	__ASSERT_NO_MSG(func != NULL);
160 	__ASSERT_NO_MSG(data != NULL);
161 
162 	if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
163 		/* Only check if the ID is in use, as the advertiser can be
164 		 * started and stopped without reconfiguring parameters.
165 		 */
166 		adv_params.id = bt_dev.id_count - 1;
167 	} else {
168 		atomic_set_bit(adv_params.flags, BT_ADV_ENABLED);
169 		adv_params.id = bt_dev.id_count - 1;
170 	}
171 
172 	func(&adv_params, data);
173 }
174 
175 /*
176  *  Test resetting an ID if the 'CONFIG_BT_BROADCASTER' is enabled and the same ID is already
177  *  in use with the advertising data.
178  *
179  *  Constraints:
180  *   - A valid random static address is used
181  *   - Input address doesn't exist in the identity list
182  *   - Input IRK is NULL
183  *   - 'CONFIG_BT_BROADCASTER' is enabled
184  *
185  *  Expected behaviour:
186  *   - '-EBUSY' error code is returned representing invalid values were used.
187  */
ZTEST(bt_id_reset_invalid_inputs,test_resetting_id_used_in_advertising)188 ZTEST(bt_id_reset_invalid_inputs, test_resetting_id_used_in_advertising)
189 {
190 	int err;
191 
192 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);
193 
194 	bt_dev.id_count = 2;
195 
196 	/* When bt_le_ext_adv_foreach() is called, this callback will be triggered and causes
197 	 * adv_id_check_func() to set the advertising enable flag to true.
198 	 */
199 	bt_le_ext_adv_foreach_fake.custom_fake = bt_le_ext_adv_foreach_custom_fake;
200 
201 	err = bt_id_reset(bt_dev.id_count - 1, BT_STATIC_RANDOM_LE_ADDR_1, NULL);
202 
203 	expect_single_call_bt_le_ext_adv_foreach();
204 
205 	zassert_true(err == -EBUSY, "Unexpected error code '%d' was returned", err);
206 }
207 
208 /*
209  *  Test returning error when the ID used corresponds to an empty address and bt_unpair() fails
210  *
211  *  Constraints:
212  *   - A valid random static address is used
213  *   - Input address doesn't exist in the identity list
214  *   - Input IRK is NULL
215  *   - 'CONFIG_BT_CONN' is enabled
216  *   - bt_unpair() fails and returns a negative error code
217  *
218  *  Expected behaviour:
219  *   - '-EALREADY' error code is returned representing invalid values were used.
220  */
ZTEST(bt_id_reset_invalid_inputs,test_bt_unpair_fails)221 ZTEST(bt_id_reset_invalid_inputs, test_bt_unpair_fails)
222 {
223 	int err;
224 	uint8_t id;
225 
226 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_CONN);
227 
228 	bt_dev.id_count = 2;
229 	id = bt_dev.id_count - 1;
230 
231 	bt_addr_le_copy(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1);
232 	bt_addr_le_copy(&bt_dev.id_addr[1], BT_STATIC_RANDOM_LE_ADDR_1);
233 
234 	bt_unpair_fake.return_val = -1;
235 
236 	err = bt_id_reset(id, BT_STATIC_RANDOM_LE_ADDR_2, NULL);
237 
238 	expect_single_call_bt_unpair(id, NULL);
239 
240 	zassert_true(err < 0, "Unexpected error code '%d' was returned", err);
241 }
242