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