1 /* test_distribute_broadcast_code.c - unit test for distribute broadcast code */
2
3 /*
4 * Copyright (c) 2024 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <stdlib.h>
10
11 #include <zephyr/bluetooth/audio/cap.h>
12 #include <zephyr/fff.h>
13
14 #include "bluetooth.h"
15 #include "cap_commander.h"
16 #include "conn.h"
17 #include "expects_util.h"
18 #include "cap_mocks.h"
19 #include "test_common.h"
20
21 #include <zephyr/logging/log.h>
22
23 LOG_MODULE_REGISTER(bt_distribute_broadcast_code, CONFIG_BT_CAP_COMMANDER_LOG_LEVEL);
24
25 #define FFF_GLOBALS
26
27 struct cap_commander_test_distribute_broadcast_code_fixture {
28 struct bt_conn conns[CONFIG_BT_MAX_CONN];
29
30 struct bt_bap_bass_subgroup subgroups[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
31 struct bt_cap_commander_broadcast_reception_start_member_param
32 start_member_params[CONFIG_BT_MAX_CONN];
33 struct bt_cap_commander_broadcast_reception_start_param start_param;
34 struct bt_cap_commander_distribute_broadcast_code_member_param
35 broadcast_code_member_params[CONFIG_BT_MAX_CONN];
36 struct bt_cap_commander_distribute_broadcast_code_param distribute_broadcast_code_param;
37 struct bt_bap_broadcast_assistant_cb broadcast_assistant_cb;
38 };
39
cap_commander_test_distribute_broadcast_code_fixture_init(struct cap_commander_test_distribute_broadcast_code_fixture * fixture)40 static void cap_commander_test_distribute_broadcast_code_fixture_init(
41 struct cap_commander_test_distribute_broadcast_code_fixture *fixture)
42 {
43 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
44 test_conn_init(&fixture->conns[i]);
45 fixture->conns[i].index = i;
46 }
47
48 fixture->distribute_broadcast_code_param.type = BT_CAP_SET_TYPE_AD_HOC;
49 fixture->distribute_broadcast_code_param.param = fixture->broadcast_code_member_params;
50 fixture->distribute_broadcast_code_param.count =
51 ARRAY_SIZE(fixture->broadcast_code_member_params);
52 memcpy(fixture->distribute_broadcast_code_param.broadcast_code, BROADCAST_CODE,
53 sizeof(BROADCAST_CODE));
54 for (size_t i = 0; i < ARRAY_SIZE(fixture->broadcast_code_member_params); i++) {
55 fixture->broadcast_code_member_params[i].member.member = &fixture->conns[i];
56 fixture->broadcast_code_member_params[i].src_id = RANDOM_SRC_ID;
57 }
58 }
59
cap_commander_test_distribute_broadcast_code_setup(void)60 static void *cap_commander_test_distribute_broadcast_code_setup(void)
61 {
62 struct cap_commander_test_distribute_broadcast_code_fixture *fixture;
63
64 fixture = malloc(sizeof(*fixture));
65 zassert_not_null(fixture);
66
67 return fixture;
68 }
69
cap_commander_test_distribute_broadcast_code_before(void * f)70 static void cap_commander_test_distribute_broadcast_code_before(void *f)
71 {
72 int err;
73 struct cap_commander_test_distribute_broadcast_code_fixture *fixture = f;
74
75 memset(f, 0, sizeof(struct cap_commander_test_distribute_broadcast_code_fixture));
76 cap_commander_test_distribute_broadcast_code_fixture_init(fixture);
77
78 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
79 err = bt_cap_commander_discover(&fixture->conns[i]);
80 zassert_equal(0, err, "Unexpected return value %d", err);
81 }
82 }
83
cap_commander_test_distribute_broadcast_code_after(void * f)84 static void cap_commander_test_distribute_broadcast_code_after(void *f)
85 {
86 struct cap_commander_test_distribute_broadcast_code_fixture *fixture = f;
87
88 bt_cap_commander_unregister_cb(&mock_cap_commander_cb);
89 bt_bap_broadcast_assistant_unregister_cb(&fixture->broadcast_assistant_cb);
90
91 /* We need to cleanup since the CAP commander remembers state */
92 bt_cap_commander_cancel();
93
94 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
95 mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
96 }
97 }
98
cap_commander_test_distribute_broadcast_code_teardown(void * f)99 static void cap_commander_test_distribute_broadcast_code_teardown(void *f)
100 {
101 free(f);
102 }
103
test_distribute_broadcast_code(struct bt_cap_commander_distribute_broadcast_code_param * distribute_broadcast_code_param)104 static void test_distribute_broadcast_code(
105 struct bt_cap_commander_distribute_broadcast_code_param *distribute_broadcast_code_param)
106 {
107 int err;
108
109 err = bt_cap_commander_distribute_broadcast_code(distribute_broadcast_code_param);
110 zassert_equal(0, err, "Unexpected return value %d", err);
111
112 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 1,
113 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
114 zassert_equal_ptr(NULL,
115 mock_cap_commander_distribute_broadcast_code_cb_fake.arg0_history[0]);
116 zassert_equal(0, mock_cap_commander_distribute_broadcast_code_cb_fake.arg1_history[0]);
117 }
118
119 ZTEST_SUITE(cap_commander_test_distribute_broadcast_code, NULL,
120 cap_commander_test_distribute_broadcast_code_setup,
121 cap_commander_test_distribute_broadcast_code_before,
122 cap_commander_test_distribute_broadcast_code_after,
123 cap_commander_test_distribute_broadcast_code_teardown);
124
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code)125 ZTEST_F(cap_commander_test_distribute_broadcast_code, test_commander_distribute_broadcast_code)
126 {
127 int err;
128
129 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
130 zassert_equal(0, err, "Unexpected return value %d", err);
131
132 test_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
133 }
134
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_reception_distribute_broadcast_code_double)135 ZTEST_F(cap_commander_test_distribute_broadcast_code,
136 test_commander_reception_distribute_broadcast_code_double)
137 {
138 int err;
139
140 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
141 zassert_equal(0, err, "Unexpected return value %d", err);
142
143 test_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
144
145 /*
146 * We can not use test_distribute_broadcast_code because of the check on how often the
147 * callback function is called
148 */
149 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
150 zassert_equal(0, err, "Unexpected return value %d", err);
151
152 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 2,
153 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
154 zassert_equal_ptr(NULL,
155 mock_cap_commander_distribute_broadcast_code_cb_fake.arg0_history[1]);
156 zassert_equal(0, mock_cap_commander_distribute_broadcast_code_cb_fake.arg1_history[1]);
157 }
158
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_reception_distribute_broadcast_code_param_null)159 ZTEST_F(cap_commander_test_distribute_broadcast_code,
160 test_commander_reception_distribute_broadcast_code_param_null)
161 {
162 int err;
163
164 err = bt_cap_commander_distribute_broadcast_code(NULL);
165 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
166
167 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
168 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
169 }
170
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_param_zero_count)171 ZTEST_F(cap_commander_test_distribute_broadcast_code,
172 test_commander_distribute_broadcast_code_param_zero_count)
173 {
174 int err;
175
176 fixture->distribute_broadcast_code_param.count = 0;
177
178 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
179 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
180
181 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
182 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
183 }
184
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_param_high_count)185 ZTEST_F(cap_commander_test_distribute_broadcast_code,
186 test_commander_distribute_broadcast_code_param_high_count)
187 {
188 int err;
189
190 fixture->distribute_broadcast_code_param.count = CONFIG_BT_MAX_CONN + 1;
191
192 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
193 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
194
195 zexpect_call_count("bt_cap_commander_cb.broadcast_distribute_broadcast_code", 0,
196 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
197 }
198
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_inval_param_null_param)199 ZTEST_F(cap_commander_test_distribute_broadcast_code,
200 test_commander_distribute_broadcast_code_inval_param_null_param)
201 {
202 int err;
203
204 fixture->distribute_broadcast_code_param.type = BT_CAP_SET_TYPE_AD_HOC;
205 fixture->distribute_broadcast_code_param.param = NULL;
206 fixture->distribute_broadcast_code_param.count = ARRAY_SIZE(fixture->conns);
207
208 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
209 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
210
211 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
212 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
213 }
214
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_inval_null_member)215 ZTEST_F(cap_commander_test_distribute_broadcast_code,
216 test_commander_distribute_broadcast_code_inval_null_member)
217 {
218 int err;
219
220 fixture->distribute_broadcast_code_param.param[0].member.member = NULL;
221
222 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
223 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
224
225 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
226 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
227 }
228
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_inval_missing_cas)229 ZTEST_F(cap_commander_test_distribute_broadcast_code,
230 test_commander_distribute_broadcast_code_inval_missing_cas)
231 {
232 int err;
233
234 fixture->distribute_broadcast_code_param.type = BT_CAP_SET_TYPE_CSIP;
235
236 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
237 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
238
239 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
240 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
241 }
242
ZTEST_F(cap_commander_test_distribute_broadcast_code,test_commander_distribute_broadcast_code_double_conn)243 ZTEST_F(cap_commander_test_distribute_broadcast_code,
244 test_commander_distribute_broadcast_code_double_conn)
245 {
246 int err;
247
248 if (CONFIG_BT_MAX_CONN == 1) {
249 ztest_test_skip();
250 }
251
252 for (size_t i = 0; i < ARRAY_SIZE(fixture->broadcast_code_member_params); i++) {
253 fixture->broadcast_code_member_params[i].member.member = &fixture->conns[0];
254 }
255
256 err = bt_cap_commander_distribute_broadcast_code(&fixture->distribute_broadcast_code_param);
257 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
258
259 zexpect_call_count("bt_cap_commander_cb.distribute_broadcast_code", 0,
260 mock_cap_commander_distribute_broadcast_code_cb_fake.call_count);
261 }
262