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 
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/tbs.h>
14 #include <zephyr/bluetooth/addr.h>
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/sys/printk.h>
18 
19 #include "bstests.h"
20 #include "common.h"
21 
22 #ifdef CONFIG_BT_TBS
23 extern enum bst_result_t bst_result;
24 static uint8_t g_call_index;
25 static volatile uint8_t call_state;
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 
test_main(void)331 static void test_main(void)
332 {
333 	int err;
334 
335 	err = bt_enable(NULL);
336 	if (err != 0) {
337 		printk("Bluetooth init failed (err %d)\n", err);
338 		return;
339 	}
340 
341 	printk("Audio Client: Bluetooth initialized\n");
342 
343 	bt_conn_cb_register(&conn_callbacks);
344 	bt_le_scan_cb_register(&common_scan_cb);
345 	bt_tbs_register_cb(&tbs_cbs);
346 
347 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
348 	if (err != 0) {
349 		FAIL("Scanning failed to start (err %d)\n", err);
350 		return;
351 	}
352 
353 	printk("Scanning successfully started\n");
354 
355 	WAIT_FOR_COND(is_connected);
356 
357 	WAIT_FOR_COND(call_placed);
358 
359 	err = bt_tbs_remote_answer(g_call_index);
360 	if (err != BT_TBS_RESULT_CODE_SUCCESS) {
361 		FAIL("Remote could not answer call: %d\n", err);
362 		return;
363 	}
364 	printk("Remote answered %u\n", g_call_index);
365 
366 	err = bt_tbs_remote_hold(g_call_index);
367 	if (err != BT_TBS_RESULT_CODE_SUCCESS) {
368 		FAIL("Remote could not hold call: %d\n", err);
369 	}
370 	printk("Remote held %u\n", g_call_index);
371 
372 	WAIT_FOR_COND(call_held);
373 
374 	err = bt_tbs_remote_retrieve(g_call_index);
375 	if (err != BT_TBS_RESULT_CODE_SUCCESS) {
376 		FAIL("Remote could not answer call: %d\n", err);
377 		return;
378 	}
379 	printk("Remote retrieved %u\n", g_call_index);
380 
381 	PASS("TBS Passed\n");
382 }
383 
tbs_test_server_only(void)384 static void tbs_test_server_only(void)
385 {
386 	int err;
387 
388 	err = bt_enable(NULL);
389 
390 	if (err != 0) {
391 		FAIL("Bluetooth init failed (err %d)\n", err);
392 		return;
393 	}
394 
395 	test_tbs_server_only();
396 
397 	PASS("TBS server tests passed\n");
398 }
399 
400 static const struct bst_test_instance test_tbs[] = {
401 	{
402 		.test_id = "tbs_test_server_only",
403 		.test_pre_init_f = test_init,
404 		.test_tick_f = test_tick,
405 		.test_main_f = tbs_test_server_only
406 	},
407 	{
408 		.test_id = "tbs",
409 		.test_pre_init_f = test_init,
410 		.test_tick_f = test_tick,
411 		.test_main_f = test_main
412 	},
413 	BSTEST_END_MARKER
414 };
415 
test_tbs_install(struct bst_test_list * tests)416 struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
417 {
418 	return bst_add_tests(tests, test_tbs);
419 }
420 #else
test_tbs_install(struct bst_test_list * tests)421 struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
422 {
423 	return tests;
424 }
425 
426 #endif /* CONFIG_BT_TBS */
427