1 /*
2 * Copyright (c) 2019 Bose Corporation
3 * Copyright (c) 2021 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #ifdef CONFIG_BT_TBS
9 #include <zephyr/bluetooth/audio/tbs.h>
10 #include "common.h"
11
12 extern enum bst_result_t bst_result;
13 static uint8_t call_index;
14 static volatile uint8_t call_state;
15
16 CREATE_FLAG(is_connected);
17 CREATE_FLAG(call_placed);
18 CREATE_FLAG(call_held);
19 CREATE_FLAG(call_id);
20 CREATE_FLAG(call_terminated);
21 CREATE_FLAG(call_accepted);
22 CREATE_FLAG(call_retrieved);
23 CREATE_FLAG(call_joined);
24
tbs_hold_call_cb(struct bt_conn * conn,uint8_t call_index)25 static void tbs_hold_call_cb(struct bt_conn *conn, uint8_t call_index)
26 {
27 if (call_index == call_id) {
28 SET_FLAG(call_held);
29 }
30 }
31
tbs_originate_call_cb(struct bt_conn * conn,uint8_t call_index,const char * caller_id)32 static bool tbs_originate_call_cb(struct bt_conn *conn, uint8_t call_index,
33 const char *caller_id)
34 {
35 printk("Placing call to remote with id %u to %s\n", call_index, caller_id);
36 call_id = call_index;
37 SET_FLAG(call_placed);
38 return true;
39 }
40
tbs_authorize_cb(struct bt_conn * conn)41 static bool tbs_authorize_cb(struct bt_conn *conn)
42 {
43 return conn == default_conn;
44 }
45
tbs_terminate_call_cb(struct bt_conn * conn,uint8_t call_index,uint8_t reason)46 static void tbs_terminate_call_cb(struct bt_conn *conn, uint8_t call_index,
47 uint8_t reason)
48 {
49 printk("Terminating call with id %u reason: %u", call_index, reason);
50 SET_FLAG(call_terminated);
51 UNSET_FLAG(call_placed);
52 }
53
tbs_accept_call_cb(struct bt_conn * conn,uint8_t call_index)54 static void tbs_accept_call_cb(struct bt_conn *conn, uint8_t call_index)
55 {
56 printk("Accepting call with index %u\n", call_index);
57 SET_FLAG(call_accepted);
58 }
59
tbs_retrieve_call_cb(struct bt_conn * conn,uint8_t call_index)60 static void tbs_retrieve_call_cb(struct bt_conn *conn, uint8_t call_index)
61 {
62 printk("Retrieve call with index %u\n", call_index);
63 SET_FLAG(call_retrieved);
64 }
65
tbs_join_calls_cb(struct bt_conn * conn,uint8_t call_index_count,const uint8_t * call_indexes)66 static void tbs_join_calls_cb(struct bt_conn *conn,
67 uint8_t call_index_count,
68 const uint8_t *call_indexes)
69 {
70 for (size_t i = 0; i < sizeof(call_indexes); i++) {
71 printk("Call index: %u joined\n", call_indexes[i]);
72 }
73 SET_FLAG(call_joined);
74 }
75
76 static struct bt_tbs_cb tbs_cbs = {
77 .originate_call = tbs_originate_call_cb,
78 .terminate_call = tbs_terminate_call_cb,
79 .hold_call = tbs_hold_call_cb,
80 .accept_call = tbs_accept_call_cb,
81 .retrieve_call = tbs_retrieve_call_cb,
82 .join_calls = tbs_join_calls_cb,
83 .authorize = tbs_authorize_cb,
84 };
85
connected(struct bt_conn * conn,uint8_t err)86 static void connected(struct bt_conn *conn, uint8_t err)
87 {
88 char addr[BT_ADDR_LE_STR_LEN];
89
90 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
91
92 if (err != 0) {
93 FAIL("Failed to connect to %s (%u)\n", addr, err);
94 return;
95 }
96
97 printk("Connected to %s\n", addr);
98
99 default_conn = bt_conn_ref(conn);
100 SET_FLAG(is_connected);
101 }
102
103 static struct bt_conn_cb conn_callbacks = {
104 .connected = connected,
105 .disconnected = disconnected,
106 };
107
test_provider_name(void)108 static int test_provider_name(void)
109 {
110 int err;
111
112 printk("%s\n", __func__);
113 err = bt_tbs_set_bearer_provider_name(0, "BabblesimTBS");
114 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
115 FAIL("Could not set bearer provider name: %d\n", err);
116 return err;
117 }
118
119 printk("Set bearer provider name test success\n");
120
121 return err;
122 }
123
test_set_signal_strength(void)124 static int test_set_signal_strength(void)
125 {
126 int err;
127
128 printk("%s\n", __func__);
129 err = bt_tbs_set_signal_strength(0, 6);
130 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
131 FAIL("Could not set bearer provider name: %d\n", err);
132 return err;
133 }
134
135 printk("Set signal strength test success\n");
136
137 return err;
138 }
139
test_set_bearer_technology(void)140 static int test_set_bearer_technology(void)
141 {
142 int err;
143
144 printk("%s\n", __func__);
145 err = bt_tbs_set_bearer_technology(0, BT_TBS_TECHNOLOGY_GSM);
146 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
147 FAIL("Could not set bearer technology: %d\n", err);
148 return err;
149 }
150
151 printk("Set bearer technology test success\n");
152
153 return err;
154 }
155
test_set_status_flags(void)156 static int test_set_status_flags(void)
157 {
158 int err;
159
160 printk("%s\n", __func__);
161 err = bt_tbs_set_status_flags(0, 3);
162 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
163 FAIL("Could not set status flags: %d\n", err);
164 return err;
165 }
166
167 printk("Set status flags test success\n");
168
169 return err;
170 }
171
test_answer_terminate(void)172 static int test_answer_terminate(void)
173 {
174 int err;
175
176 printk("%s\n", __func__);
177 printk("Placing call\n");
178 err = bt_tbs_originate(0, "tel:000000000001", &call_index);
179 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
180 FAIL("Could not originate call: %d\n", err);
181 return err;
182 }
183
184 printk("Answering call\n");
185 err = bt_tbs_remote_answer(call_index);
186 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
187 FAIL("Could not accept call: %d\n", err);
188 return err;
189 }
190
191 printk("Terminating call\n");
192 err = bt_tbs_terminate(call_index);
193 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
194 FAIL("Could not terminate call: %d\n", err);
195 return err;
196 }
197
198 printk("Test answer & terminate successful\n");
199
200 return err;
201 }
202
test_hold_retrieve(void)203 static int test_hold_retrieve(void)
204 {
205 int err;
206
207 printk("%s\n", __func__);
208 err = bt_tbs_originate(0, "tel:000000000001", &call_index);
209 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
210 FAIL("Could not originate call: %d\n", err);
211 return err;
212 }
213
214 err = bt_tbs_remote_answer(call_index);
215 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
216 FAIL("Could not accept call: %d\n", err);
217 return err;
218 }
219
220 printk("Holding call\n");
221 err = bt_tbs_hold(call_index);
222 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
223 FAIL("Could not terminate call: %d\n", err);
224 return err;
225 }
226
227 printk("Retrieving call\n");
228 err = bt_tbs_retrieve(call_index);
229 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
230 FAIL("Could not retrieve call: %d\n", err);
231 return err;
232 }
233
234 printk("Terminating call\n");
235 err = bt_tbs_terminate(call_index);
236 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
237 FAIL("Could not terminate call: %d\n", err);
238 return err;
239 }
240
241 printk("Hold & retrieve test sucessfull\n");
242
243 return err;
244 }
245
test_join(void)246 static int test_join(void)
247 {
248 int err;
249 uint8_t call_indexes[2];
250
251 printk("%s\n", __func__);
252 printk("Placing first call\n");
253 err = bt_tbs_originate(0, "tel:000000000001", &call_index);
254 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
255 FAIL("Could not originate first call: %d\n", err);
256 return err;
257 }
258
259 printk("Answering first call\n");
260 err = bt_tbs_remote_answer(call_index);
261 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
262 FAIL("Could not answer first call: %d\n", err);
263 return err;
264 }
265 printk("First call answered\n");
266
267 call_indexes[0] = (uint8_t)call_index;
268
269 printk("Placing second call\n");
270 err = bt_tbs_originate(0, "tel:000000000002", &call_index);
271 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
272 FAIL("Could not originate second call: %d\n", err);
273 return err;
274 }
275
276 printk("Answering second call\n");
277 err = bt_tbs_remote_answer(call_index);
278 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
279 FAIL("Could not answer second call: %d\n", err);
280 return err;
281 }
282 printk("Second call answered\n");
283
284 call_indexes[1] = (uint8_t)call_index;
285
286 printk("Joining calls\n");
287 err = bt_tbs_join(2, call_indexes);
288 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
289 FAIL("Could not join calls: %d\n", err);
290 return err;
291 }
292
293 err = bt_tbs_terminate(call_indexes[0]);
294 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
295 FAIL("Could not terminate first call: %d\n", err);
296 return err;
297 }
298
299 err = bt_tbs_terminate(call_indexes[1]);
300 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
301 FAIL("Could not terminate second call: %d\n", err);
302 return err;
303 }
304
305 printk("Join calls test succesfull\n");
306
307 return err;
308 }
309
test_tbs_server_only(void)310 static void test_tbs_server_only(void)
311 {
312 test_answer_terminate();
313 test_hold_retrieve();
314 test_join();
315 test_provider_name();
316 test_set_signal_strength();
317 test_set_bearer_technology();
318 test_set_status_flags();
319 }
320
test_main(void)321 static void test_main(void)
322 {
323 int err;
324
325 err = bt_enable(NULL);
326 if (err != 0) {
327 printk("Bluetooth init failed (err %d)\n", err);
328 return;
329 }
330
331 printk("Audio Client: Bluetooth initialized\n");
332
333 bt_conn_cb_register(&conn_callbacks);
334 bt_le_scan_cb_register(&common_scan_cb);
335 bt_tbs_register_cb(&tbs_cbs);
336
337 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
338 if (err != 0) {
339 FAIL("Scanning failed to start (err %d)\n", err);
340 return;
341 }
342
343 printk("Scanning successfully started\n");
344
345 WAIT_FOR_COND(is_connected);
346
347 WAIT_FOR_COND(call_placed);
348
349 err = bt_tbs_remote_answer(call_id);
350 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
351 FAIL("Remote could not answer call: %d\n", err);
352 return;
353 }
354 printk("Remote answered %u\n", call_id);
355
356 err = bt_tbs_remote_hold(call_id);
357 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
358 FAIL("Remote could not hold call: %d\n", err);
359 }
360 printk("Remote held %u\n", call_id);
361
362 WAIT_FOR_COND(call_held);
363
364 err = bt_tbs_remote_retrieve(call_id);
365 if (err != BT_TBS_RESULT_CODE_SUCCESS) {
366 FAIL("Remote could not answer call: %d\n", err);
367 return;
368 }
369 printk("Remote retrieved %u\n", call_id);
370
371 PASS("TBS Passed\n");
372 }
373
tbs_test_server_only(void)374 static void tbs_test_server_only(void)
375 {
376 int err;
377
378 err = bt_enable(NULL);
379
380 if (err != 0) {
381 FAIL("Bluetooth init failed (err %d)\n", err);
382 return;
383 }
384
385 test_tbs_server_only();
386
387 PASS("TBS server tests passed\n");
388 }
389
390 static const struct bst_test_instance test_tbs[] = {
391 {
392 .test_id = "tbs_test_server_only",
393 .test_post_init_f = test_init,
394 .test_tick_f = test_tick,
395 .test_main_f = tbs_test_server_only
396 },
397 {
398 .test_id = "tbs",
399 .test_post_init_f = test_init,
400 .test_tick_f = test_tick,
401 .test_main_f = test_main
402 },
403 BSTEST_END_MARKER
404 };
405
test_tbs_install(struct bst_test_list * tests)406 struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
407 {
408 return bst_add_tests(tests, test_tbs);
409 }
410 #else
test_tbs_install(struct bst_test_list * tests)411 struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
412 {
413 return tests;
414 }
415
416 #endif /* CONFIG_BT_TBS */
417