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