1 /* test_micp.c - unit test for microphone settings */
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/bluetooth/audio/micp.h>
13 #include <zephyr/fff.h>
14
15 #include "bluetooth.h"
16 #include "cap_commander.h"
17 #include "conn.h"
18 #include "expects_util.h"
19 #include "cap_mocks.h"
20 #include "test_common.h"
21
22 #define FFF_GLOBALS
23
24 struct cap_commander_test_micp_fixture {
25 struct bt_conn conns[CONFIG_BT_MAX_CONN];
26 };
27
cap_commander_test_micp_fixture_init(struct cap_commander_test_micp_fixture * fixture)28 static void cap_commander_test_micp_fixture_init(struct cap_commander_test_micp_fixture *fixture)
29 {
30 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
31 test_conn_init(&fixture->conns[i]);
32 }
33 }
34
cap_commander_test_micp_setup(void)35 static void *cap_commander_test_micp_setup(void)
36 {
37 struct cap_commander_test_micp_fixture *fixture;
38
39 fixture = malloc(sizeof(*fixture));
40 zassert_not_null(fixture);
41
42 return fixture;
43 }
44
cap_commander_test_micp_before(void * f)45 static void cap_commander_test_micp_before(void *f)
46 {
47 memset(f, 0, sizeof(struct cap_commander_test_micp_fixture));
48 cap_commander_test_micp_fixture_init(f);
49 }
50
cap_commander_test_micp_after(void * f)51 static void cap_commander_test_micp_after(void *f)
52 {
53 struct cap_commander_test_micp_fixture *fixture = f;
54
55 bt_cap_commander_unregister_cb(&mock_cap_commander_cb);
56
57 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
58 mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
59 }
60 }
61
cap_commander_test_micp_teardown(void * f)62 static void cap_commander_test_micp_teardown(void *f)
63 {
64 free(f);
65 }
66
67 ZTEST_SUITE(cap_commander_test_micp, NULL, cap_commander_test_micp_setup,
68 cap_commander_test_micp_before, cap_commander_test_micp_after,
69 cap_commander_test_micp_teardown);
70
71
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting)72 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting)
73 {
74 struct bt_cap_commander_change_microphone_gain_setting_member_param
75 member_params[ARRAY_SIZE(fixture->conns)];
76 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
77 .type = BT_CAP_SET_TYPE_AD_HOC,
78 .param = member_params,
79 .count = ARRAY_SIZE(member_params),
80 };
81 int err;
82
83 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
84 member_params[i].member.member = &fixture->conns[i];
85 member_params[i].gain = 10 + i;
86 }
87
88 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
89 zassert_equal(0, err, "Unexpected return value %d", err);
90
91 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
92 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
93
94 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
95 zassert_equal(0, err, "Unexpected return value %d", err);
96 }
97
98 err = bt_cap_commander_change_microphone_gain_setting(¶m);
99 zassert_equal(0, err, "Unexpected return value %d", err);
100
101 zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1,
102 mock_cap_commander_microphone_gain_changed_cb_fake.call_count);
103 }
104
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_double)105 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_double)
106 {
107 struct bt_cap_commander_change_microphone_gain_setting_member_param
108 member_params[ARRAY_SIZE(fixture->conns)];
109 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
110 .type = BT_CAP_SET_TYPE_AD_HOC,
111 .param = member_params,
112 .count = ARRAY_SIZE(member_params),
113 };
114 int err;
115
116 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
117 member_params[i].member.member = &fixture->conns[i];
118 member_params[i].gain = 10 + i;
119 }
120
121 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
122 zassert_equal(0, err, "Unexpected return value %d", err);
123
124 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
125 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
126
127 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
128 zassert_equal(0, err, "Unexpected return value %d", err);
129 }
130
131 err = bt_cap_commander_change_microphone_gain_setting(¶m);
132 zassert_equal(0, err, "Unexpected return value %d", err);
133
134 zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1,
135 mock_cap_commander_microphone_gain_changed_cb_fake.call_count);
136
137 /* Test that it still works as expected if we set the same value twice */
138 err = bt_cap_commander_change_microphone_gain_setting(¶m);
139 zassert_equal(0, err, "Unexpected return value %d", err);
140
141 zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 2,
142 mock_cap_commander_microphone_gain_changed_cb_fake.call_count);
143 }
144
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_param_null)145 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_param_null)
146 {
147 int err;
148
149 err = bt_cap_commander_change_microphone_gain_setting(NULL);
150 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
151 }
152
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_param_null_param)153 ZTEST_F(cap_commander_test_micp,
154 test_commander_change_microphone_gain_setting_inval_param_null_param)
155 {
156 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
157 .type = BT_CAP_SET_TYPE_AD_HOC,
158 .param = NULL,
159 .count = ARRAY_SIZE(fixture->conns),
160 };
161 int err;
162
163 err = bt_cap_commander_change_microphone_gain_setting(¶m);
164 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
165 }
166
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_param_null_member)167 ZTEST_F(cap_commander_test_micp,
168 test_commander_change_microphone_gain_setting_inval_param_null_member)
169 {
170 struct bt_cap_commander_change_microphone_gain_setting_member_param
171 member_params[ARRAY_SIZE(fixture->conns)];
172 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
173 .type = BT_CAP_SET_TYPE_AD_HOC,
174 .param = member_params,
175 .count = ARRAY_SIZE(member_params),
176 };
177 int err;
178
179 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
180 member_params[i].member.member = &fixture->conns[i];
181 member_params[i].gain = 10 + i;
182 }
183 member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL;
184
185 err = bt_cap_commander_change_microphone_gain_setting(¶m);
186 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
187 }
188
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_missing_cas)189 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_missing_cas)
190 {
191 struct bt_cap_commander_change_microphone_gain_setting_member_param
192 member_params[ARRAY_SIZE(fixture->conns)];
193 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
194 .type = BT_CAP_SET_TYPE_CSIP,
195 .param = member_params,
196 .count = ARRAY_SIZE(member_params),
197 };
198 int err;
199
200 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
201 member_params[i].member.member = &fixture->conns[i];
202 member_params[i].gain = 10 + i;
203 }
204
205 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
206 zassert_equal(0, err, "Unexpected return value %d", err);
207
208 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
209 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
210
211 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
212 zassert_equal(0, err, "Unexpected return value %d", err);
213 }
214
215 err = bt_cap_commander_change_microphone_gain_setting(¶m);
216 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
217 }
218
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_missing_aics)219 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_missing_aics)
220 {
221 struct bt_cap_commander_change_microphone_gain_setting_member_param
222 member_params[ARRAY_SIZE(fixture->conns)];
223 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
224 .type = BT_CAP_SET_TYPE_AD_HOC,
225 .param = member_params,
226 .count = ARRAY_SIZE(member_params),
227 };
228 int err;
229
230 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
231 member_params[i].member.member = &fixture->conns[i];
232 member_params[i].gain = 10 + i;
233 }
234
235 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
236 zassert_equal(0, err, "Unexpected return value %d", err);
237
238 err = bt_cap_commander_change_microphone_gain_setting(¶m);
239 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
240 }
241
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_param_zero_count)242 ZTEST_F(cap_commander_test_micp,
243 test_commander_change_microphone_gain_setting_inval_param_zero_count)
244 {
245 struct bt_cap_commander_change_microphone_gain_setting_member_param
246 member_params[ARRAY_SIZE(fixture->conns)];
247 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
248 .type = BT_CAP_SET_TYPE_AD_HOC,
249 .param = member_params,
250 .count = 0U,
251 };
252 int err;
253
254 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
255 member_params[i].member.member = &fixture->conns[i];
256 member_params[i].gain = 10 + i;
257 }
258
259 err = bt_cap_commander_change_microphone_gain_setting(¶m);
260 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
261 }
262
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_gain_setting_inval_param_inval_count)263 ZTEST_F(cap_commander_test_micp,
264 test_commander_change_microphone_gain_setting_inval_param_inval_count)
265 {
266 struct bt_cap_commander_change_microphone_gain_setting_member_param
267 member_params[ARRAY_SIZE(fixture->conns)];
268 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
269 .type = BT_CAP_SET_TYPE_AD_HOC,
270 .param = member_params,
271 .count = CONFIG_BT_MAX_CONN + 1,
272 };
273 int err;
274
275 for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
276 member_params[i].member.member = &fixture->conns[i];
277 member_params[i].gain = 10 + i;
278 }
279
280 err = bt_cap_commander_change_microphone_gain_setting(¶m);
281 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
282 }
283
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state)284 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state)
285 {
286 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
287 const struct bt_cap_commander_change_microphone_mute_state_param param = {
288 .type = BT_CAP_SET_TYPE_AD_HOC,
289 .members = members,
290 .count = ARRAY_SIZE(fixture->conns),
291 .mute = true,
292 };
293 int err;
294
295 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
296 members[i].member = &fixture->conns[i];
297 }
298
299 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
300 zassert_equal(0, err, "Unexpected return value %d", err);
301
302 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
303 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
304
305 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
306 zassert_equal(0, err, "Unexpected return value %d", err);
307 }
308
309 err = bt_cap_commander_change_microphone_mute_state(¶m);
310 zassert_equal(0, err, "Unexpected return value %d", err);
311
312 zexpect_call_count("bt_cap_commander_cb.microphone_mute_changed", 1,
313 mock_cap_commander_microphone_mute_changed_cb_fake.call_count);
314 }
315
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_double)316 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state_double)
317 {
318 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
319 const struct bt_cap_commander_change_microphone_mute_state_param param = {
320 .type = BT_CAP_SET_TYPE_AD_HOC,
321 .members = members,
322 .count = ARRAY_SIZE(fixture->conns),
323 .mute = true,
324 };
325 int err;
326
327 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
328 members[i].member = &fixture->conns[i];
329 }
330
331 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
332 zassert_equal(0, err, "Unexpected return value %d", err);
333
334 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
335 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
336
337 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
338 zassert_equal(0, err, "Unexpected return value %d", err);
339 }
340
341 err = bt_cap_commander_change_microphone_mute_state(¶m);
342 zassert_equal(0, err, "Unexpected return value %d", err);
343
344 zexpect_call_count("bt_cap_commander_cb.microphone_mute_changed", 1,
345 mock_cap_commander_microphone_mute_changed_cb_fake.call_count);
346
347 /* Test that it still works as expected if we set the same value twice */
348 err = bt_cap_commander_change_microphone_mute_state(¶m);
349 zassert_equal(0, err, "Unexpected return value %d", err);
350
351 zexpect_call_count("bt_cap_commander_cb.microphone_mute_changed", 2,
352 mock_cap_commander_microphone_mute_changed_cb_fake.call_count);
353 }
354
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_param_null)355 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state_inval_param_null)
356 {
357 int err;
358
359 err = bt_cap_commander_change_microphone_mute_state(NULL);
360 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
361 }
362
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_param_null_members)363 ZTEST_F(cap_commander_test_micp,
364 test_commander_change_microphone_mute_state_inval_param_null_members)
365 {
366 const struct bt_cap_commander_change_microphone_mute_state_param param = {
367 .type = BT_CAP_SET_TYPE_AD_HOC,
368 .members = NULL,
369 .count = ARRAY_SIZE(fixture->conns),
370 .mute = true,
371 };
372 int err;
373
374 err = bt_cap_commander_change_microphone_mute_state(¶m);
375 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
376 }
377
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_param_null_member)378 ZTEST_F(cap_commander_test_micp,
379 test_commander_change_microphone_mute_state_inval_param_null_member)
380 {
381 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
382 const struct bt_cap_commander_change_microphone_mute_state_param param = {
383 .type = BT_CAP_SET_TYPE_AD_HOC,
384 .members = members,
385 .count = ARRAY_SIZE(fixture->conns),
386 .mute = true,
387 };
388 int err;
389
390 for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) {
391 members[i].member = &fixture->conns[i];
392 }
393 members[ARRAY_SIZE(members) - 1].member = NULL;
394
395 err = bt_cap_commander_change_microphone_mute_state(¶m);
396 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
397 }
398
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_missing_cas)399 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state_inval_missing_cas)
400 {
401 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
402 const struct bt_cap_commander_change_microphone_mute_state_param param = {
403 .type = BT_CAP_SET_TYPE_CSIP,
404 .members = members,
405 .count = ARRAY_SIZE(fixture->conns),
406 .mute = true,
407 };
408 int err;
409
410 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
411 members[i].member = &fixture->conns[i];
412 }
413
414 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
415 zassert_equal(0, err, "Unexpected return value %d", err);
416
417 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
418 struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */
419
420 err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr);
421 zassert_equal(0, err, "Unexpected return value %d", err);
422 }
423
424 err = bt_cap_commander_change_microphone_mute_state(¶m);
425 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
426 }
427
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_missing_vcs)428 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state_inval_missing_vcs)
429 {
430 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
431 const struct bt_cap_commander_change_microphone_mute_state_param param = {
432 .type = BT_CAP_SET_TYPE_AD_HOC,
433 .members = members,
434 .count = ARRAY_SIZE(fixture->conns),
435 .mute = true,
436 };
437 int err;
438
439 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
440 members[i].member = &fixture->conns[i];
441 }
442
443 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
444 zassert_equal(0, err, "Unexpected return value %d", err);
445
446 err = bt_cap_commander_change_microphone_mute_state(¶m);
447 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
448 }
449
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_param_zero_count)450 ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_mute_state_inval_param_zero_count)
451 {
452 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
453 const struct bt_cap_commander_change_microphone_mute_state_param param = {
454 .type = BT_CAP_SET_TYPE_AD_HOC,
455 .members = members,
456 .count = 0U,
457 .mute = true,
458 };
459 int err;
460
461 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
462 members[i].member = &fixture->conns[i];
463 }
464
465 err = bt_cap_commander_change_microphone_mute_state(¶m);
466 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
467 }
468
ZTEST_F(cap_commander_test_micp,test_commander_change_microphone_mute_state_inval_param_inval_count)469 ZTEST_F(cap_commander_test_micp,
470 test_commander_change_microphone_mute_state_inval_param_inval_count)
471 {
472 union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
473 const struct bt_cap_commander_change_microphone_mute_state_param param = {
474 .type = BT_CAP_SET_TYPE_AD_HOC,
475 .members = members,
476 .count = CONFIG_BT_MAX_CONN + 1,
477 .mute = true,
478 };
479 int err;
480
481 for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
482 members[i].member = &fixture->conns[i];
483 }
484
485 err = bt_cap_commander_change_microphone_mute_state(¶m);
486 zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
487 }
488