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