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