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