1 /* test_cancel.c - unit test for cancel command */
2
3 /*
4 * Copyright (c) 2024 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/addr.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/audio/cap.h>
16 #include <zephyr/bluetooth/hci_types.h>
17 #include <zephyr/fff.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/sys/util_macro.h>
20 #include <zephyr/ztest_assert.h>
21 #include <zephyr/ztest_test.h>
22
23 #include "cap_commander.h"
24 #include "conn.h"
25 #include "expects_util.h"
26 #include "cap_mocks.h"
27 #include "test_common.h"
28 #include "bap_broadcast_assistant.h"
29
30 #define FFF_GLOBALS
31
32 struct cap_commander_test_cancel_fixture {
33 struct bt_conn conns[CONFIG_BT_MAX_CONN];
34
35 struct bt_bap_bass_subgroup subgroups[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
36 struct bt_cap_commander_broadcast_reception_start_member_param
37 start_member_params[CONFIG_BT_MAX_CONN];
38 struct bt_cap_commander_broadcast_reception_start_param start_param;
39 };
40
test_start_param_init(void * f)41 static void test_start_param_init(void *f)
42 {
43 struct cap_commander_test_cancel_fixture *fixture = f;
44 int err;
45
46 fixture->start_param.type = BT_CAP_SET_TYPE_AD_HOC;
47 fixture->start_param.param = fixture->start_member_params;
48
49 fixture->start_param.count = ARRAY_SIZE(fixture->start_member_params);
50
51 for (size_t i = 0; i < ARRAY_SIZE(fixture->subgroups); i++) {
52 fixture->subgroups[i].bis_sync = BIT(i);
53 fixture->subgroups[i].metadata_len = 0;
54 }
55
56 for (size_t i = 0U; i < ARRAY_SIZE(fixture->start_member_params); i++) {
57 fixture->start_member_params[i].member.member = &fixture->conns[i];
58 bt_addr_le_copy(&fixture->start_member_params[i].addr, BT_ADDR_LE_ANY);
59 fixture->start_member_params[i].adv_sid = 0;
60 fixture->start_member_params[i].pa_interval = 10;
61 fixture->start_member_params[i].broadcast_id = 0;
62 memcpy(fixture->start_member_params[i].subgroups, &fixture->subgroups[0],
63 sizeof(struct bt_bap_bass_subgroup) * CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
64 fixture->start_member_params[i].num_subgroups = CONFIG_BT_BAP_BASS_MAX_SUBGROUPS;
65 }
66
67 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
68 err = bt_cap_commander_discover(&fixture->conns[i]);
69 zassert_equal(0, err, "Unexpected return value %d", err);
70 }
71 }
72
73 static void
cap_commander_test_cancel_fixture_init(struct cap_commander_test_cancel_fixture * fixture)74 cap_commander_test_cancel_fixture_init(struct cap_commander_test_cancel_fixture *fixture)
75 {
76 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
77 test_conn_init(&fixture->conns[i]);
78 }
79
80 test_start_param_init(fixture);
81 }
82
cap_commander_test_cancel_setup(void)83 static void *cap_commander_test_cancel_setup(void)
84 {
85 struct cap_commander_test_cancel_fixture *fixture;
86
87 fixture = malloc(sizeof(*fixture));
88 zassert_not_null(fixture);
89
90 return fixture;
91 }
92
cap_commander_test_cancel_before(void * f)93 static void cap_commander_test_cancel_before(void *f)
94 {
95 struct cap_commander_test_cancel_fixture *fixture = f;
96
97 memset(f, 0, sizeof(struct cap_commander_test_cancel_fixture));
98 cap_commander_test_cancel_fixture_init(fixture);
99 }
100
cap_commander_test_cancel_after(void * f)101 static void cap_commander_test_cancel_after(void *f)
102 {
103 struct cap_commander_test_cancel_fixture *fixture = f;
104
105 bt_cap_commander_unregister_cb(&mock_cap_commander_cb);
106
107 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
108 mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
109 }
110 }
111
cap_commander_test_cancel_teardown(void * f)112 static void cap_commander_test_cancel_teardown(void *f)
113 {
114 free(f);
115 }
116
test_cancel(void)117 static void test_cancel(void)
118 {
119 int err;
120
121 err = bt_cap_commander_cancel();
122 zassert_equal(0, err, "Unexpected return value %d", err);
123
124 zexpect_call_count("bt_cap_commander_cb.broadcast_reception_start", 1,
125 mock_cap_commander_broadcast_reception_start_cb_fake.call_count);
126 zassert_equal(-ECANCELED,
127 mock_cap_commander_broadcast_reception_start_cb_fake.arg1_history[0]);
128 }
129
130 ZTEST_SUITE(cap_commander_test_cancel, NULL, cap_commander_test_cancel_setup,
131 cap_commander_test_cancel_before, cap_commander_test_cancel_after,
132 cap_commander_test_cancel_teardown);
133
ZTEST_F(cap_commander_test_cancel,test_commander_cancel)134 ZTEST_F(cap_commander_test_cancel, test_commander_cancel)
135 {
136 int err;
137
138 if (CONFIG_BT_MAX_CONN == 1) {
139 ztest_test_skip();
140 }
141
142 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
143 zassert_equal(0, err, "Unexpected return value %d", err);
144
145 /* Do not run the add_src callback, so that the broadcast reception start procedure does not
146 * run until completion
147 */
148 set_skip_add_src(1);
149
150 /* initiate a CAP procedure; for this test we use broadcast reception start*/
151 err = bt_cap_commander_broadcast_reception_start(&fixture->start_param);
152 zassert_equal(0, err, "Could not start CAP procedure: %d", err);
153
154 test_cancel();
155 }
156
ZTEST_F(cap_commander_test_cancel,test_commander_cancel_double)157 ZTEST_F(cap_commander_test_cancel, test_commander_cancel_double)
158 {
159 int err;
160
161 if (CONFIG_BT_MAX_CONN == 1) {
162 ztest_test_skip();
163 }
164
165 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
166 zassert_equal(0, err, "Unexpected return value %d", err);
167
168 set_skip_add_src(1);
169 err = bt_cap_commander_broadcast_reception_start(&fixture->start_param);
170 zassert_equal(0, err, "Could not start CAP procedure: %d", err);
171
172 test_cancel();
173
174 err = bt_cap_commander_cancel();
175 zassert_equal(-EALREADY, err, "Unexpected return value %d", err);
176 }
177
ZTEST_F(cap_commander_test_cancel,test_commander_cancel_no_proc_in_progress)178 ZTEST_F(cap_commander_test_cancel, test_commander_cancel_no_proc_in_progress)
179 {
180 int err;
181
182 err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
183 zassert_equal(0, err, "Unexpected return value %d", err);
184
185 err = bt_cap_commander_cancel();
186 zassert_equal(-EALREADY, err, "Unexpected return value %d", err);
187 }
188