1 /*
2 * Copyright (c) 2019 Bose Corporation
3 * Copyright (c) 2021 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <zephyr/autoconf.h>
12 #include <zephyr/bluetooth/addr.h>
13 #include <zephyr/bluetooth/audio/tbs.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/sys/printk.h>
17
18 #include "bstests.h"
19 #include "common.h"
20
21 #ifdef CONFIG_BT_TBS_CLIENT
22 static struct bt_conn_cb conn_callbacks;
23 extern enum bst_result_t bst_result;
24
25 static volatile uint8_t call_state;
26 static volatile uint8_t call_index;
27 static volatile uint8_t tbs_count;
28
29 CREATE_FLAG(bt_init);
30 CREATE_FLAG(is_connected);
31 CREATE_FLAG(discovery_complete);
32 CREATE_FLAG(is_gtbs_found);
33 CREATE_FLAG(read_complete);
34 CREATE_FLAG(call_placed);
35 CREATE_FLAG(call_terminated);
36 CREATE_FLAG(provider_name);
37 CREATE_FLAG(ccid_read_flag);
38 CREATE_FLAG(signal_strength);
39 CREATE_FLAG(technology);
40 CREATE_FLAG(status_flags);
41 CREATE_FLAG(signal_interval);
42 CREATE_FLAG(call_accepted);
43 CREATE_FLAG(bearer_uci);
44 CREATE_FLAG(uri_list);
45 CREATE_FLAG(current_calls);
46 CREATE_FLAG(uri_inc);
47 CREATE_FLAG(term_reason);
48
tbs_client_call_states_cb(struct bt_conn * conn,int err,uint8_t index,uint8_t call_count,const struct bt_tbs_client_call_state * call_states)49 static void tbs_client_call_states_cb(struct bt_conn *conn, int err,
50 uint8_t index, uint8_t call_count,
51 const struct bt_tbs_client_call_state *call_states)
52 {
53 if (index != 0) {
54 return;
55 }
56
57 printk("Index %u\n", index);
58 if (err != 0) {
59 FAIL("Call could not read call states (%d)\n", err);
60 return;
61 }
62
63 call_index = call_states[0].index;
64 call_state = call_states[0].state;
65 printk("call index %u - state %u\n", call_index, call_state);
66 }
67
tbs_client_read_bearer_provider_name(struct bt_conn * conn,int err,uint8_t index,const char * value)68 static void tbs_client_read_bearer_provider_name(struct bt_conn *conn, int err,
69 uint8_t index,
70 const char *value)
71 {
72 if (err != 0) {
73 FAIL("Call could not read bearer name (%d)\n", err);
74 return;
75 }
76
77 printk("Index %u\n", index);
78 printk("Bearer name pointer: %p\n", value);
79 printk("Bearer name: %s\n", value);
80 read_complete = true;
81 SET_FLAG(provider_name);
82 }
83
tbs_client_discover_cb(struct bt_conn * conn,int err,uint8_t count,bool gtbs_found)84 static void tbs_client_discover_cb(struct bt_conn *conn, int err,
85 uint8_t count, bool gtbs_found)
86 {
87 printk("%s\n", __func__);
88
89 if (err != 0) {
90 FAIL("TBS_CLIENT could not be discovered (%d)\n", err);
91 return;
92 }
93
94 tbs_count = count;
95 is_gtbs_found = true;
96 discovery_complete = true;
97 }
98
tbs_client_read_ccid_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint32_t value)99 static void tbs_client_read_ccid_cb(struct bt_conn *conn, int err,
100 uint8_t inst_index, uint32_t value)
101 {
102 struct bt_tbs_instance *inst;
103
104 if (value > UINT8_MAX) {
105 FAIL("Invalid CCID: %u", value);
106 return;
107 }
108
109 printk("Read CCID %u on index %u\n", value, inst_index);
110
111 inst = bt_tbs_client_get_by_ccid(conn, (uint8_t)value);
112 if (inst == NULL) {
113 FAIL("Could not get instance by CCID: %u", value);
114 return;
115 }
116
117 SET_FLAG(ccid_read_flag);
118 }
119
tbs_client_originate_call_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index)120 static void tbs_client_originate_call_cb(struct bt_conn *conn, int err,
121 uint8_t inst_index,
122 uint8_t call_index)
123 {
124 printk("%s %u:\n", __func__, call_index);
125 call_placed = true;
126 }
127
tbs_client_hold_call_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index)128 static void tbs_client_hold_call_cb(struct bt_conn *conn, int err,
129 uint8_t inst_index,
130 uint8_t call_index)
131 {
132 if (err != 0) {
133 FAIL("Client hold call error: (%d)\n", err);
134 return;
135 }
136
137 printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
138 call_index);
139 }
140
tbs_client_retrieve_call_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index)141 static void tbs_client_retrieve_call_cb(struct bt_conn *conn, int err,
142 uint8_t inst_index,
143 uint8_t call_index)
144 {
145 if (err != 0) {
146 FAIL("Client retrieve call error: (%d)\n", err);
147 return;
148 }
149
150 printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
151 call_index);
152 }
153
tbs_client_technology_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint32_t value)154 static void tbs_client_technology_cb(struct bt_conn *conn, int err,
155 uint8_t inst_index,
156 uint32_t value)
157 {
158 if (err != 0) {
159 FAIL("Client bearer technology error: (%d)\n", err);
160 return;
161 }
162
163 printk("%s Instance: %u Technology: %u\n", __func__, inst_index, value);
164
165 SET_FLAG(technology);
166 }
167
tbs_client_signal_strength_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint32_t value)168 static void tbs_client_signal_strength_cb(struct bt_conn *conn, int err,
169 uint8_t inst_index,
170 uint32_t value)
171 {
172 if (err != 0) {
173 FAIL("Client signal strength error: (%d)\n", err);
174 return;
175 }
176
177 printk("%s Instance: %u, Strength: %u\n", __func__, inst_index, value);
178
179 SET_FLAG(signal_strength);
180 }
181
tbs_client_signal_interval_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint32_t value)182 static void tbs_client_signal_interval_cb(struct bt_conn *conn, int err,
183 uint8_t inst_index,
184 uint32_t value)
185 {
186 if (err != 0) {
187 FAIL("Client signal interval error: (%d)\n", err);
188 return;
189 }
190
191 printk("%s Instance: %u Interval: %u\n", __func__, inst_index, value);
192
193 SET_FLAG(signal_interval);
194 }
195
tbs_client_status_flags_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint32_t value)196 static void tbs_client_status_flags_cb(struct bt_conn *conn, int err,
197 uint8_t inst_index,
198 uint32_t value)
199 {
200 if (err != 0) {
201 FAIL("Status flags error: (%d)\n", err);
202 return;
203 }
204
205 printk("%s Instance: %u Flags: %u\n", __func__, inst_index, value);
206
207 SET_FLAG(status_flags);
208 }
209
tbs_client_terminate_call_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index)210 static void tbs_client_terminate_call_cb(struct bt_conn *conn, int err,
211 uint8_t inst_index, uint8_t call_index)
212 {
213 if (err != 0) {
214 FAIL("Terminate call error: (%d)\n", err);
215 return;
216 }
217
218 printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
219 call_index);
220
221 SET_FLAG(call_terminated);
222 }
223
tbs_client_accept_call_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index)224 static void tbs_client_accept_call_cb(struct bt_conn *conn, int err,
225 uint8_t inst_index, uint8_t call_index)
226 {
227 if (err != 0) {
228 FAIL("Accept call error: (%d)\n", err);
229 return;
230 }
231
232 printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
233 call_index);
234
235 SET_FLAG(call_accepted);
236 }
237
tbs_client_bearer_uci_cb(struct bt_conn * conn,int err,uint8_t inst_index,const char * value)238 static void tbs_client_bearer_uci_cb(struct bt_conn *conn, int err,
239 uint8_t inst_index,
240 const char *value)
241 {
242 if (err != 0) {
243 FAIL("Bearer UCI error: (%d)\n", err);
244 return;
245 }
246
247 printk("%s Instance: %u UCI: %s\n", __func__, inst_index, value);
248
249 SET_FLAG(bearer_uci);
250 }
251
tbs_client_uri_list_cb(struct bt_conn * conn,int err,uint8_t inst_index,const char * value)252 static void tbs_client_uri_list_cb(struct bt_conn *conn, int err,
253 uint8_t inst_index, const char *value)
254 {
255 if (err != 0) {
256 FAIL("URI list error: (%d)\n", err);
257 return;
258 }
259
260 printk("%s Instance: %u URI list: %s\n", __func__, inst_index, value);
261
262 SET_FLAG(uri_list);
263 }
264
tbs_client_current_calls_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_count,const struct bt_tbs_client_call * calls)265 static void tbs_client_current_calls_cb(struct bt_conn *conn, int err,
266 uint8_t inst_index,
267 uint8_t call_count,
268 const struct bt_tbs_client_call *calls)
269 {
270 if (err != 0) {
271 FAIL("Current calls error: (%d)\n", err);
272 return;
273 }
274
275 printk("%s Instance: %u Call count: %u\n", __func__, inst_index,
276 call_count);
277
278 SET_FLAG(current_calls);
279 }
280
tbs_client_call_uri_cb(struct bt_conn * conn,int err,uint8_t inst_index,const char * value)281 static void tbs_client_call_uri_cb(struct bt_conn *conn, int err,
282 uint8_t inst_index,
283 const char *value)
284 {
285 if (err != 0) {
286 FAIL("Incoming URI error: (%d)\n", err);
287 return;
288 }
289
290 printk("Incoming URI callback\n");
291 printk("%s Instance: %u URI: %s\n", __func__, inst_index, value);
292
293 SET_FLAG(uri_inc);
294 }
295
tbs_client_term_reason_cb(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_index,uint8_t reason)296 static void tbs_client_term_reason_cb(struct bt_conn *conn,
297 int err, uint8_t inst_index,
298 uint8_t call_index,
299 uint8_t reason)
300 {
301 printk("%s Instance: %u Reason: %u\n", __func__, inst_index, reason);
302
303 SET_FLAG(term_reason);
304 }
305
306 static struct bt_tbs_client_cb tbs_client_cbs = {
307 .discover = tbs_client_discover_cb,
308 .originate_call = tbs_client_originate_call_cb,
309 .terminate_call = tbs_client_terminate_call_cb,
310 .hold_call = tbs_client_hold_call_cb,
311 .accept_call = tbs_client_accept_call_cb,
312 .retrieve_call = tbs_client_retrieve_call_cb,
313 .bearer_provider_name = tbs_client_read_bearer_provider_name,
314 .bearer_uci = tbs_client_bearer_uci_cb,
315 .technology = tbs_client_technology_cb,
316 .uri_list = tbs_client_uri_list_cb,
317 .signal_strength = tbs_client_signal_strength_cb,
318 .signal_interval = tbs_client_signal_interval_cb,
319 .current_calls = tbs_client_current_calls_cb,
320 .ccid = tbs_client_read_ccid_cb,
321 .status_flags = tbs_client_status_flags_cb,
322 .call_uri = tbs_client_call_uri_cb,
323 .call_state = tbs_client_call_states_cb,
324 .termination_reason = tbs_client_term_reason_cb
325 };
326
connected(struct bt_conn * conn,uint8_t err)327 static void connected(struct bt_conn *conn, uint8_t err)
328 {
329 char addr[BT_ADDR_LE_STR_LEN];
330
331 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
332
333 if (err != 0) {
334 bt_conn_unref(default_conn);
335 FAIL("Failed to connect to %s (%u)\n", addr, err);
336 return;
337 }
338
339 printk("Connected to %s\n", addr);
340 is_connected = true;
341 }
342
bt_ready(int err)343 static void bt_ready(int err)
344 {
345 if (err != 0) {
346 FAIL("Bluetooth discover failed (err %d)\n", err);
347 return;
348 }
349
350 bt_init = true;
351 }
352
353 static struct bt_conn_cb conn_callbacks = {
354 .connected = connected,
355 .disconnected = disconnected,
356 };
357
test_ccid(void)358 static void test_ccid(void)
359 {
360 if (is_gtbs_found) {
361 int err;
362
363 UNSET_FLAG(ccid_read_flag);
364 printk("Reading GTBS CCID\n");
365
366 err = bt_tbs_client_read_ccid(default_conn, BT_TBS_GTBS_INDEX);
367 if (err != 0) {
368 FAIL("Read GTBS CCID failed (%d)\n", err);
369 return;
370 }
371
372 WAIT_FOR_FLAG(ccid_read_flag);
373 }
374
375 for (uint8_t i = 0; i < tbs_count; i++) {
376 int err;
377
378 UNSET_FLAG(ccid_read_flag);
379 printk("Reading bearer CCID on index %u\n", i);
380
381 err = bt_tbs_client_read_ccid(default_conn, i);
382 if (err != 0) {
383 FAIL("Read bearer CCID failed (%d)\n", err);
384 return;
385 }
386
387 WAIT_FOR_FLAG(ccid_read_flag);
388 }
389 }
390
test_signal_strength(uint8_t index)391 static void test_signal_strength(uint8_t index)
392 {
393 int err;
394
395 UNSET_FLAG(signal_strength);
396
397 printk("%s\n", __func__);
398
399 err = bt_tbs_client_read_signal_strength(default_conn, index);
400 if (err != 0) {
401 FAIL("Read signal strength failed (%d)\n", err);
402 return;
403 }
404
405 WAIT_FOR_FLAG(signal_strength);
406
407 printk("Client read signal strength test success\n");
408 }
409
test_technology(uint8_t index)410 static void test_technology(uint8_t index)
411 {
412 int err;
413
414 UNSET_FLAG(technology);
415
416 printk("%s\n", __func__);
417
418 err = bt_tbs_client_read_technology(default_conn, index);
419 if (err != 0) {
420 FAIL("Read technology failed (%d)\n", err);
421 return;
422 }
423
424 WAIT_FOR_FLAG(technology);
425
426 printk("Client read technology test success\n");
427 }
428
test_status_flags(uint8_t index)429 static void test_status_flags(uint8_t index)
430 {
431 int err;
432
433 UNSET_FLAG(status_flags);
434
435 printk("%s\n", __func__);
436
437 err = bt_tbs_client_read_status_flags(default_conn, index);
438 if (err != 0) {
439 FAIL("Read status flags failed (%d)\n", err);
440 return;
441 }
442
443 WAIT_FOR_FLAG(status_flags);
444
445 printk("Client read status flags test success\n");
446 }
447
test_signal_interval(uint8_t index)448 static void test_signal_interval(uint8_t index)
449 {
450 int err;
451
452 UNSET_FLAG(signal_interval);
453
454 printk("%s\n", __func__);
455
456 err = bt_tbs_client_read_signal_interval(default_conn, index);
457 if (err != 0) {
458 FAIL("Read signal interval failed (%d)\n", err);
459 return;
460 }
461
462 WAIT_FOR_FLAG(signal_interval);
463
464 printk("Client signal interval test success\n");
465 }
466
discover_tbs(void)467 static void discover_tbs(void)
468 {
469 int err;
470
471 discovery_complete = false;
472
473 err = bt_tbs_client_discover(default_conn);
474 if (err) {
475 FAIL("Failed to discover TBS: %d", err);
476 return;
477 }
478
479 WAIT_FOR_COND(discovery_complete);
480 }
481
test_main(void)482 static void test_main(void)
483 {
484 int err;
485 int index = 0;
486
487 err = bt_enable(bt_ready);
488
489 if (err != 0) {
490 FAIL("Bluetooth discover failed (err %d)\n", err);
491 return;
492 }
493
494 bt_conn_cb_register(&conn_callbacks);
495
496 err = bt_tbs_client_register_cb(&tbs_client_cbs);
497 if (err != 0) {
498 FAIL("Failed to register TBS client cbs (err %d)\n", err);
499 return;
500 }
501
502 WAIT_FOR_COND(bt_init);
503
504 printk("Audio Server: Bluetooth discovered\n");
505
506 err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, AD_SIZE, NULL, 0);
507 if (err != 0) {
508 FAIL("Advertising failed to start (err %d)\n", err);
509 return;
510 }
511
512 printk("Advertising successfully started\n");
513
514 WAIT_FOR_COND(is_connected);
515
516 discover_tbs();
517 discover_tbs(); /* test that we can discover twice */
518
519 printk("GTBS %sfound\n", is_gtbs_found ? "" : "not ");
520
521 printk("Placing call\n");
522 err = bt_tbs_client_originate_call(default_conn, 0, "tel:123456789012");
523 if (err != 0) {
524 FAIL("Originate call failed (%d)\n", err);
525 }
526
527 /* Call transitions:
528 * 1) Dialing
529 * 2) Alerting
530 * 3) Active
531 * 4) Remotely Held
532 */
533 printk("Waiting for remotely held\n");
534 WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_REMOTELY_HELD);
535
536 printk("Holding call\n");
537 err = bt_tbs_client_hold_call(default_conn, index, call_index);
538 if (err != 0) {
539 FAIL("Hold call failed (%d)\n", err);
540 }
541
542 /* Call transitions:
543 * 1) Locally and remotely held
544 * 2) Locally held
545 */
546 WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_LOCALLY_HELD);
547
548 printk("Retrieving call\n");
549 err = bt_tbs_client_retrieve_call(default_conn, index, call_index);
550 if (err != 0) {
551 FAIL("Retrieve call failed (%d)\n", err);
552 }
553
554 WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_ACTIVE);
555
556 printk("Reading bearer provider name\n");
557 UNSET_FLAG(provider_name);
558 err = bt_tbs_client_read_bearer_provider_name(default_conn, index);
559 if (err != 0) {
560 FAIL("Read bearer provider name failed (%d)\n", err);
561 }
562
563 test_ccid();
564 WAIT_FOR_COND(read_complete);
565
566 test_signal_strength(index);
567 test_technology(index);
568 test_status_flags(index);
569 test_signal_interval(index);
570
571 PASS("TBS_CLIENT Passed\n");
572 }
573
574 static const struct bst_test_instance test_tbs_client[] = {
575 {
576 .test_id = "tbs_client",
577 .test_pre_init_f = test_init,
578 .test_tick_f = test_tick,
579 .test_main_f = test_main
580 },
581 BSTEST_END_MARKER
582 };
583
test_tbs_client_install(struct bst_test_list * tests)584 struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests)
585 {
586 return bst_add_tests(tests, test_tbs_client);
587 }
588
589 #else
test_tbs_client_install(struct bst_test_list * tests)590 struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests)
591 {
592 return tests;
593 }
594
595 #endif /* CONFIG_BT_TBS_CLIENT */
596