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_delete_invalid_inputs, NULL, NULL, NULL, NULL, NULL);
21 
22 /*
23  *  Test deleting default ID which shouldn't be allowed
24  *
25  *  Constraints:
26  *   - BT_ID_DEFAULT value is used for the ID
27  *
28  *  Expected behaviour:
29  *   - '-EINVAL' error code is returned representing invalid values were used.
30  */
ZTEST(bt_id_delete_invalid_inputs,test_deleting_default_id)31 ZTEST(bt_id_delete_invalid_inputs, test_deleting_default_id)
32 {
33 	int err;
34 
35 	err = bt_id_delete(BT_ID_DEFAULT);
36 
37 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
38 }
39 
40 /*
41  *  Test deleting ID value that is equal to bt_dev.id_count
42  *
43  *  Constraints:
44  *   - bt_dev.id_count is greater than 0
45  *   - ID value used is equal to bt_dev.id_count
46  *
47  *  Expected behaviour:
48  *   - '-EINVAL' error code is returned representing invalid values were used.
49  */
ZTEST(bt_id_delete_invalid_inputs,test_deleting_id_value_equal_to_dev_id_count)50 ZTEST(bt_id_delete_invalid_inputs, test_deleting_id_value_equal_to_dev_id_count)
51 {
52 	int err;
53 
54 	bt_dev.id_count = 1;
55 
56 	err = bt_id_delete(bt_dev.id_count);
57 
58 	zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
59 }
60 
61 /*
62  *  Test deleting ID that corresponds to a zero-filled item
63  *
64  *  Constraints:
65  *   - bt_dev.id_count is greater than 1
66  *   - ID value used corresponds to a zero-filled item
67  *
68  *  Expected behaviour:
69  *   - '-EALREADY' error code is returned representing invalid values were used.
70  */
ZTEST(bt_id_delete_invalid_inputs,test_deleting_id_with_zero_filled_item)71 ZTEST(bt_id_delete_invalid_inputs, test_deleting_id_with_zero_filled_item)
72 {
73 	int err;
74 
75 	bt_dev.id_count = 2;
76 	bt_addr_le_copy(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1);
77 	bt_addr_le_copy(&bt_dev.id_addr[1], BT_ADDR_LE_ANY);
78 
79 	err = bt_id_delete(1);
80 
81 	zassert_true(err == -EALREADY, "Unexpected error code '%d' was returned", err);
82 }
83 
bt_le_ext_adv_foreach_custom_fake(void (* func)(struct bt_le_ext_adv * adv,void * data),void * data)84 static void bt_le_ext_adv_foreach_custom_fake(void (*func)(struct bt_le_ext_adv *adv, void *data),
85 					      void *data)
86 {
87 	struct bt_le_ext_adv adv_params = {0};
88 
89 	__ASSERT_NO_MSG(func != NULL);
90 	__ASSERT_NO_MSG(data != NULL);
91 
92 	if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
93 		/* Only check if the ID is in use, as the advertiser can be
94 		 * started and stopped without reconfiguring parameters.
95 		 */
96 		adv_params.id = bt_dev.id_count - 1;
97 	} else {
98 		atomic_set_bit(adv_params.flags, BT_ADV_ENABLED);
99 		adv_params.id = bt_dev.id_count - 1;
100 	}
101 
102 	func(&adv_params, data);
103 }
104 
105 /*
106  *  Test deleting an ID if the 'CONFIG_BT_BROADCASTER' is enabled and the same ID is already
107  *  in use with the advertising data.
108  *
109  *  Constraints:
110  *   - ID value used corresponds to a currently used ID in advertising
111  *   - 'CONFIG_BT_BROADCASTER' is enabled
112  *
113  *  Expected behaviour:
114  *   - '-EBUSY' error code is returned representing invalid values were used.
115  */
ZTEST(bt_id_delete_invalid_inputs,test_deleting_id_used_in_advertising)116 ZTEST(bt_id_delete_invalid_inputs, test_deleting_id_used_in_advertising)
117 {
118 	int err;
119 
120 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);
121 
122 	bt_dev.id_count = 2;
123 	bt_addr_le_copy(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1);
124 	bt_addr_le_copy(&bt_dev.id_addr[1], BT_STATIC_RANDOM_LE_ADDR_2);
125 
126 	/* When bt_le_ext_adv_foreach() is called, this callback will be triggered and causes
127 	 * adv_id_check_func() to set the advertising enable flag to true.
128 	 */
129 	bt_le_ext_adv_foreach_fake.custom_fake = bt_le_ext_adv_foreach_custom_fake;
130 
131 	err = bt_id_delete(bt_dev.id_count - 1);
132 
133 	expect_single_call_bt_le_ext_adv_foreach();
134 
135 	zassert_true(err == -EBUSY, "Unexpected error code '%d' was returned", err);
136 }
137 
138 /*
139  *  Test returning error when bt_unpair() fails
140  *
141  *  Constraints:
142  *   - 'CONFIG_BT_CONN' is enabled
143  *   - bt_unpair() fails and returns a negative error code
144  *
145  *  Expected behaviour:
146  *   - '-EALREADY' error code is returned representing invalid values were used.
147  */
ZTEST(bt_id_delete_invalid_inputs,test_bt_unpair_fails)148 ZTEST(bt_id_delete_invalid_inputs, test_bt_unpair_fails)
149 {
150 	int err;
151 	uint8_t id;
152 
153 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_CONN);
154 
155 	bt_dev.id_count = 2;
156 	id = bt_dev.id_count - 1;
157 
158 	bt_addr_le_copy(&bt_dev.id_addr[0], BT_STATIC_RANDOM_LE_ADDR_1);
159 	bt_addr_le_copy(&bt_dev.id_addr[1], BT_STATIC_RANDOM_LE_ADDR_2);
160 
161 	bt_unpair_fake.return_val = -1;
162 
163 	err = bt_id_delete(id);
164 
165 	expect_single_call_bt_unpair(id, NULL);
166 
167 	zassert_true(err < 0, "Unexpected error code '%d' was returned", err);
168 }
169