1 /* Bluetooth TBS - Telephone Bearer Service
2  *
3  * Copyright (c) 2020 Bose Corporation
4  * Copyright (c) 2021 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <sys/types.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/att.h>
18 #include <zephyr/bluetooth/audio/tbs.h>
19 #include <zephyr/bluetooth/bluetooth.h>
20 #include <zephyr/bluetooth/conn.h>
21 #include <zephyr/bluetooth/gatt.h>
22 #include <zephyr/bluetooth/uuid.h>
23 #include <zephyr/init.h>
24 #include <zephyr/kernel.h>
25 #include <zephyr/logging/log.h>
26 #include <zephyr/net/buf.h>
27 #include <zephyr/sys/__assert.h>
28 #include <zephyr/sys/byteorder.h>
29 #include <zephyr/sys/util.h>
30 #include <zephyr/sys/util_macro.h>
31 #include <zephyr/types.h>
32 
33 #include "audio_internal.h"
34 #include "tbs_internal.h"
35 #include "ccid_internal.h"
36 
37 LOG_MODULE_REGISTER(bt_tbs, CONFIG_BT_TBS_LOG_LEVEL);
38 
39 #define BT_TBS_VALID_STATUS_FLAGS(val)         ((val) <= (BIT(0) | BIT(1)))
40 
41 struct service_inst {
42 	/* Attribute values */
43 	char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
44 	char uci[BT_TBS_MAX_UCI_SIZE];
45 	uint8_t technology;
46 	uint8_t signal_strength;
47 	uint8_t signal_strength_interval;
48 	uint8_t ccid;
49 	uint16_t optional_opcodes;
50 	uint16_t status_flags;
51 	struct bt_tbs_in_uri incoming_uri;
52 	struct bt_tbs_in_uri friendly_name;
53 	struct bt_tbs_in_uri in_call;
54 
55 	bool notify_current_calls;
56 	bool notify_call_states;
57 	bool pending_signal_strength_notification;
58 	struct k_work_delayable reporting_interval_work;
59 
60 	/** Service Attributes */
61 	const struct bt_gatt_attr *attrs;
62 	/** Service Attribute count */
63 	size_t attr_count;
64 };
65 
66 struct tbs_service_inst {
67 	struct service_inst inst;
68 
69 	/* Attribute values */
70 	char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
71 	struct bt_tbs_terminate_reason terminate_reason;
72 
73 	/* Instance values */
74 	struct bt_tbs_call calls[CONFIG_BT_TBS_MAX_CALLS];
75 };
76 
77 struct gtbs_service_inst {
78 	struct service_inst inst;
79 };
80 
81 #if defined(CONFIG_BT_GTBS)
82 #define READ_BUF_SIZE   (CONFIG_BT_TBS_MAX_CALLS * \
83 			 sizeof(struct bt_tbs_current_call_item) * \
84 			 CONFIG_BT_TBS_BEARER_COUNT)
85 #else
86 #define READ_BUF_SIZE   (CONFIG_BT_TBS_MAX_CALLS * \
87 			 sizeof(struct bt_tbs_current_call_item))
88 #endif /* defined(CONFIG_BT_GTBS) */
89 NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, READ_BUF_SIZE);
90 
91 static struct tbs_service_inst svc_insts[CONFIG_BT_TBS_BEARER_COUNT];
92 static struct gtbs_service_inst gtbs_inst;
93 
94 /* Used to notify app with held calls in case of join */
95 static struct bt_tbs_call *held_calls[CONFIG_BT_TBS_MAX_CALLS];
96 static uint8_t held_calls_cnt;
97 
98 static struct bt_tbs_cb *tbs_cbs;
99 
inst_is_gtbs(const struct service_inst * inst)100 static bool inst_is_gtbs(const struct service_inst *inst)
101 {
102 	return IS_ENABLED(CONFIG_BT_GTBS) && inst == &gtbs_inst.inst;
103 }
104 
inst_index(const struct service_inst * inst)105 static uint8_t inst_index(const struct service_inst *inst)
106 {
107 	const struct tbs_service_inst *tbs;
108 	ptrdiff_t index = 0;
109 
110 	__ASSERT_NO_MSG(inst);
111 
112 	if (inst_is_gtbs(inst)) {
113 		return BT_TBS_GTBS_INDEX;
114 	}
115 
116 	tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
117 
118 	index = tbs - svc_insts;
119 	__ASSERT(index >= 0 && index < ARRAY_SIZE(svc_insts), "Invalid tbs_inst pointer");
120 
121 	return (uint8_t)index;
122 }
123 
inst_lookup_index(uint8_t index)124 static struct service_inst *inst_lookup_index(uint8_t index)
125 {
126 	if (IS_ENABLED(CONFIG_BT_GTBS) && index == BT_TBS_GTBS_INDEX) {
127 		return &gtbs_inst.inst;
128 	}
129 
130 	if (index < CONFIG_BT_TBS_BEARER_COUNT) {
131 		return &svc_insts[index].inst;
132 	}
133 
134 	return NULL;
135 }
136 
lookup_call_in_inst(struct tbs_service_inst * inst,uint8_t call_index)137 static struct bt_tbs_call *lookup_call_in_inst(struct tbs_service_inst *inst,
138 					       uint8_t call_index)
139 {
140 	if (call_index == BT_TBS_FREE_CALL_INDEX) {
141 		return NULL;
142 	}
143 
144 	for (int i = 0; i < ARRAY_SIZE(svc_insts[i].calls); i++) {
145 		if (inst->calls[i].index == call_index) {
146 			return &inst->calls[i];
147 		}
148 	}
149 
150 	return NULL;
151 }
152 
153 /**
154  * @brief Finds and returns a call
155  *
156  * @param call_index The ID of the call
157  * @return struct bt_tbs_call* Pointer to the call. NULL if not found
158  */
lookup_call(uint8_t call_index)159 static struct bt_tbs_call *lookup_call(uint8_t call_index)
160 {
161 
162 	if (call_index == BT_TBS_FREE_CALL_INDEX) {
163 		return NULL;
164 	}
165 
166 	for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
167 		struct bt_tbs_call *call = lookup_call_in_inst(&svc_insts[i],
168 							       call_index);
169 
170 		if (call != NULL) {
171 			return call;
172 		}
173 	}
174 
175 	return NULL;
176 }
177 
inst_check_attr(struct service_inst * inst,const struct bt_gatt_attr * attr)178 static bool inst_check_attr(struct service_inst *inst, const struct bt_gatt_attr *attr)
179 {
180 	for (size_t j = 0; j < inst->attr_count; j++) {
181 		if (&inst->attrs[j] == attr) {
182 			return true;
183 		}
184 	}
185 
186 	return false;
187 }
188 
lookup_inst_by_attr(const struct bt_gatt_attr * attr)189 static struct service_inst *lookup_inst_by_attr(const struct bt_gatt_attr *attr)
190 {
191 	if (attr == NULL) {
192 		return NULL;
193 	}
194 
195 	for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
196 		if (inst_check_attr(&svc_insts[i].inst, attr)) {
197 			return &svc_insts[i].inst;
198 		}
199 	}
200 
201 	if (IS_ENABLED(CONFIG_BT_GTBS) && inst_check_attr(&gtbs_inst.inst, attr)) {
202 		return &gtbs_inst.inst;
203 	}
204 
205 	return NULL;
206 }
207 
lookup_inst_by_call_index(uint8_t call_index)208 static struct tbs_service_inst *lookup_inst_by_call_index(uint8_t call_index)
209 {
210 	if (call_index == BT_TBS_FREE_CALL_INDEX) {
211 		return NULL;
212 	}
213 
214 	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
215 		if (lookup_call_in_inst(&svc_insts[i], call_index) != NULL) {
216 			return &svc_insts[i];
217 		}
218 	}
219 
220 	return NULL;
221 }
222 
is_authorized(struct bt_conn * conn)223 static bool is_authorized(struct bt_conn *conn)
224 {
225 	if (IS_ENABLED(CONFIG_BT_TBS_AUTHORIZATION)) {
226 		if (tbs_cbs != NULL && tbs_cbs->authorize != NULL) {
227 			return tbs_cbs->authorize(conn);
228 		} else {
229 			return false;
230 		}
231 	}
232 
233 	return true;
234 }
235 
uri_scheme_in_list(const char * uri_scheme,const char * uri_scheme_list)236 static bool uri_scheme_in_list(const char *uri_scheme,
237 			       const char *uri_scheme_list)
238 {
239 	const size_t scheme_len = strlen(uri_scheme);
240 	const size_t scheme_list_len = strlen(uri_scheme_list);
241 	const char *uri_scheme_cand = uri_scheme_list;
242 	size_t uri_scheme_cand_len;
243 	size_t start_idx = 0;
244 
245 	for (size_t i = 0; i < scheme_list_len; i++) {
246 		if (uri_scheme_list[i] == ',') {
247 			uri_scheme_cand_len = i - start_idx;
248 			if (uri_scheme_cand_len != scheme_len) {
249 				continue;
250 			}
251 
252 			if (memcmp(uri_scheme, uri_scheme_cand, scheme_len) == 0) {
253 				return true;
254 			}
255 
256 			if (i + 1 < scheme_list_len) {
257 				uri_scheme_cand = &uri_scheme_list[i + 1];
258 			}
259 		}
260 	}
261 
262 	return false;
263 }
264 
lookup_inst_by_uri_scheme(const char * uri,uint8_t uri_len)265 static struct tbs_service_inst *lookup_inst_by_uri_scheme(const char *uri,
266 							  uint8_t uri_len)
267 {
268 	char uri_scheme[CONFIG_BT_TBS_MAX_URI_LENGTH] = { 0 };
269 
270 	/* Look for ':' between the first and last char */
271 	for (int i = 1; i < uri_len - 1; i++) {
272 		if (uri[i] == ':') {
273 			(void)memcpy(uri_scheme, uri, i);
274 		}
275 	}
276 
277 	if (strlen(uri_scheme) == 0) {
278 		/* No URI scheme found */
279 		return NULL;
280 	}
281 
282 	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
283 		for (size_t j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
284 			if (uri_scheme_in_list(uri_scheme,
285 					       svc_insts[i].uri_scheme_list)) {
286 				return &svc_insts[i];
287 			}
288 		}
289 	}
290 
291 	return NULL;
292 }
293 
tbs_set_terminate_reason(struct tbs_service_inst * inst,uint8_t call_index,uint8_t reason)294 static void tbs_set_terminate_reason(struct tbs_service_inst *inst,
295 				     uint8_t call_index, uint8_t reason)
296 {
297 	inst->terminate_reason.call_index = call_index;
298 	inst->terminate_reason.reason = reason;
299 	LOG_DBG("Index %u: call index 0x%02x, reason %s", inst_index(&inst->inst), call_index,
300 		bt_tbs_term_reason_str(reason));
301 
302 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TERMINATE_REASON,
303 			    inst->inst.attrs,
304 			    (void *)&inst->terminate_reason,
305 			    sizeof(inst->terminate_reason));
306 
307 	if (IS_ENABLED(CONFIG_BT_GTBS)) {
308 		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TERMINATE_REASON,
309 				    gtbs_inst.inst.attrs,
310 				    (void *)&inst->terminate_reason,
311 				    sizeof(inst->terminate_reason));
312 	}
313 }
314 
315 /**
316  * @brief Gets the next free call_index
317  *
318  * For each new call, the call index should be incremented and wrap at 255.
319  * However, the index = 0 is reserved for outgoing calls
320  *
321  * @return uint8_t The next free call index
322  */
next_free_call_index(void)323 static uint8_t next_free_call_index(void)
324 {
325 	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
326 		static uint8_t next_call_index;
327 		const struct bt_tbs_call *call;
328 
329 		/* For each new call, the call index should be incremented */
330 		next_call_index++;
331 
332 		if (next_call_index == BT_TBS_FREE_CALL_INDEX) {
333 			/* call_index = 0 reserved for outgoing calls */
334 			next_call_index = 1;
335 		}
336 
337 		call = lookup_call(next_call_index);
338 		if (call == NULL) {
339 			return next_call_index;
340 		}
341 	}
342 
343 	LOG_DBG("No more free call spots");
344 
345 	return BT_TBS_FREE_CALL_INDEX;
346 }
347 
call_alloc(struct tbs_service_inst * inst,uint8_t state,const char * uri,uint16_t uri_len)348 static struct bt_tbs_call *call_alloc(struct tbs_service_inst *inst, uint8_t state, const char *uri,
349 				      uint16_t uri_len)
350 {
351 	struct bt_tbs_call *free_call = NULL;
352 
353 	for (size_t i = 0; i < ARRAY_SIZE(inst->calls); i++) {
354 		if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
355 			free_call = &inst->calls[i];
356 			break;
357 		}
358 	}
359 
360 	if (free_call == NULL) {
361 		return NULL;
362 	}
363 
364 	__ASSERT_NO_MSG(uri_len < sizeof(free_call->remote_uri));
365 
366 	memset(free_call, 0, sizeof(*free_call));
367 
368 	/* Get the next free call_index */
369 	free_call->index = next_free_call_index();
370 	__ASSERT_NO_MSG(free_call->index != BT_TBS_FREE_CALL_INDEX);
371 
372 	free_call->state = state;
373 	(void)memcpy(free_call->remote_uri, uri, uri_len);
374 	free_call->remote_uri[uri_len] = '\0';
375 
376 	return free_call;
377 }
378 
call_free(struct bt_tbs_call * call)379 static void call_free(struct bt_tbs_call *call)
380 {
381 	call->index = BT_TBS_FREE_CALL_INDEX;
382 }
383 
net_buf_put_call_states_by_inst(const struct tbs_service_inst * inst,struct net_buf_simple * buf)384 static void net_buf_put_call_states_by_inst(const struct tbs_service_inst *inst,
385 					    struct net_buf_simple *buf)
386 {
387 	const struct bt_tbs_call *call;
388 	const struct bt_tbs_call *calls;
389 	size_t call_count;
390 
391 	calls = inst->calls;
392 	call_count = ARRAY_SIZE(inst->calls);
393 
394 	for (size_t i = 0; i < call_count; i++) {
395 		call = &calls[i];
396 		if (call->index == BT_TBS_FREE_CALL_INDEX) {
397 			continue;
398 		}
399 
400 		net_buf_simple_add_u8(buf, call->index);
401 		net_buf_simple_add_u8(buf, call->state);
402 		net_buf_simple_add_u8(buf, call->flags);
403 	}
404 }
405 
net_buf_put_call_states(const struct service_inst * inst,struct net_buf_simple * buf)406 static void net_buf_put_call_states(const struct service_inst *inst, struct net_buf_simple *buf)
407 {
408 	net_buf_simple_reset(buf);
409 
410 	if (inst_is_gtbs(inst)) {
411 		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
412 			net_buf_put_call_states_by_inst(&svc_insts[i], buf);
413 		}
414 	} else {
415 		struct tbs_service_inst *service_inst;
416 
417 		service_inst = CONTAINER_OF(inst, struct tbs_service_inst, inst);
418 
419 		net_buf_put_call_states_by_inst(service_inst, buf);
420 	}
421 }
422 
net_buf_put_current_calls_by_inst(const struct tbs_service_inst * inst,struct net_buf_simple * buf)423 static void net_buf_put_current_calls_by_inst(const struct tbs_service_inst *inst,
424 					      struct net_buf_simple *buf)
425 {
426 	const struct bt_tbs_call *call;
427 	const struct bt_tbs_call *calls;
428 	size_t call_count;
429 	size_t uri_length;
430 	size_t item_len;
431 
432 	calls = inst->calls;
433 	call_count = ARRAY_SIZE(inst->calls);
434 
435 	for (size_t i = 0; i < call_count; i++) {
436 		call = &calls[i];
437 		if (call->index == BT_TBS_FREE_CALL_INDEX) {
438 			continue;
439 		}
440 
441 		uri_length = strlen(call->remote_uri);
442 		item_len = sizeof(call->index) + sizeof(call->state) + sizeof(call->flags) +
443 			   uri_length;
444 		net_buf_simple_add_u8(buf, item_len);
445 		net_buf_simple_add_u8(buf, call->index);
446 		net_buf_simple_add_u8(buf, call->state);
447 		net_buf_simple_add_u8(buf, call->flags);
448 		net_buf_simple_add_mem(buf, call->remote_uri, uri_length);
449 	}
450 }
451 
net_buf_put_current_calls(const struct service_inst * inst,struct net_buf_simple * buf)452 static void net_buf_put_current_calls(const struct service_inst *inst, struct net_buf_simple *buf)
453 {
454 	net_buf_simple_reset(buf);
455 
456 	if (inst_is_gtbs(inst)) {
457 		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
458 			net_buf_put_current_calls_by_inst(&svc_insts[i], buf);
459 		}
460 	} else {
461 		struct tbs_service_inst *service_inst;
462 
463 		service_inst = CONTAINER_OF(inst, struct tbs_service_inst, inst);
464 
465 		net_buf_put_current_calls_by_inst(service_inst, buf);
466 	}
467 }
468 
inst_notify_calls(const struct service_inst * inst)469 static int inst_notify_calls(const struct service_inst *inst)
470 {
471 	int err;
472 
473 	if (inst->notify_call_states) {
474 		net_buf_put_call_states(inst, &read_buf);
475 
476 		err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_CALL_STATE, inst->attrs,
477 					  read_buf.data, read_buf.len);
478 		if (err != 0) {
479 			return err;
480 		}
481 	}
482 
483 	if (inst->notify_current_calls) {
484 		net_buf_put_current_calls(inst, &read_buf);
485 
486 		err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_LIST_CURRENT_CALLS, inst->attrs,
487 					  read_buf.data, read_buf.len);
488 		if (err != 0) {
489 			return err;
490 		}
491 	}
492 
493 	return 0;
494 }
495 
notify_calls(const struct tbs_service_inst * inst)496 static int notify_calls(const struct tbs_service_inst *inst)
497 {
498 	if (inst == NULL) {
499 		return -EINVAL;
500 	}
501 
502 	if (IS_ENABLED(CONFIG_BT_GTBS)) {
503 		int err;
504 
505 		err = inst_notify_calls(&gtbs_inst.inst);
506 		if (err != 0) {
507 			return err;
508 		}
509 	}
510 
511 	return inst_notify_calls(&inst->inst);
512 }
513 
read_provider_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)514 static ssize_t read_provider_name(struct bt_conn *conn,
515 				  const struct bt_gatt_attr *attr,
516 				  void *buf, uint16_t len, uint16_t offset)
517 {
518 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
519 
520 	LOG_DBG("Index %u, Provider name %s", inst_index(inst), inst->provider_name);
521 
522 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
523 				 inst->provider_name, strlen(inst->provider_name));
524 }
525 
provider_name_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)526 static void provider_name_cfg_changed(const struct bt_gatt_attr *attr,
527 				      uint16_t value)
528 {
529 	const struct service_inst *inst = lookup_inst_by_attr(attr);
530 
531 	if (inst != NULL) {
532 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
533 	}
534 }
535 
read_uci(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)536 static ssize_t read_uci(struct bt_conn *conn, const struct bt_gatt_attr *attr,
537 			void *buf, uint16_t len, uint16_t offset)
538 {
539 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
540 
541 	LOG_DBG("Index %u: UCI %s", inst_index(inst), inst->uci);
542 
543 	return bt_gatt_attr_read(conn, attr, buf, len, offset, inst->uci, strlen(inst->uci));
544 }
545 
read_technology(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)546 static ssize_t read_technology(struct bt_conn *conn,
547 			       const struct bt_gatt_attr *attr,
548 			       void *buf, uint16_t len, uint16_t offset)
549 {
550 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
551 
552 	LOG_DBG("Index %u: Technology 0x%02x", inst_index(inst), inst->technology);
553 
554 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
555 				 &inst->technology, sizeof(inst->technology));
556 }
557 
technology_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)558 static void technology_cfg_changed(const struct bt_gatt_attr *attr,
559 				   uint16_t value)
560 {
561 	const struct service_inst *inst = lookup_inst_by_attr(attr);
562 
563 	if (inst != NULL) {
564 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
565 	}
566 }
567 
read_uri_scheme_list(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)568 static ssize_t read_uri_scheme_list(struct bt_conn *conn,
569 				    const struct bt_gatt_attr *attr,
570 				    void *buf, uint16_t len, uint16_t offset)
571 {
572 	const struct service_inst *inst_p = BT_AUDIO_CHRC_USER_DATA(attr);
573 
574 	net_buf_simple_reset(&read_buf);
575 
576 	if (inst_is_gtbs(inst_p)) {
577 		/* TODO: Make uri schemes unique */
578 		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
579 			size_t uri_len = strlen(svc_insts[i].uri_scheme_list);
580 
581 			if (read_buf.len + uri_len >= read_buf.size) {
582 				LOG_WRN("Cannot fit all TBS instances in GTBS "
583 					"URI scheme list");
584 				break;
585 			}
586 
587 			net_buf_simple_add_mem(&read_buf,
588 					       svc_insts[i].uri_scheme_list,
589 					       uri_len);
590 		}
591 
592 		LOG_DBG("GTBS: URI scheme %.*s", read_buf.len, read_buf.data);
593 	} else {
594 		const struct tbs_service_inst *inst;
595 
596 		inst = CONTAINER_OF(inst_p, struct tbs_service_inst, inst);
597 
598 		net_buf_simple_add_mem(&read_buf, inst->uri_scheme_list,
599 				       strlen(inst->uri_scheme_list));
600 
601 		LOG_DBG("Index %u: URI scheme %.*s",
602 			inst_index(inst_p), read_buf.len, read_buf.data);
603 	}
604 
605 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
606 				 read_buf.data, read_buf.len);
607 }
608 
uri_scheme_list_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)609 static void uri_scheme_list_cfg_changed(const struct bt_gatt_attr *attr,
610 				   uint16_t value)
611 {
612 	const struct service_inst *inst = lookup_inst_by_attr(attr);
613 
614 	if (inst != NULL) {
615 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
616 	}
617 }
618 
read_signal_strength(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)619 static ssize_t read_signal_strength(struct bt_conn *conn,
620 				    const struct bt_gatt_attr *attr,
621 				    void *buf, uint16_t len, uint16_t offset)
622 {
623 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
624 
625 	LOG_DBG("Index %u: Signal strength 0x%02x", inst_index(inst), inst->signal_strength);
626 
627 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
628 				 &inst->signal_strength, sizeof(inst->signal_strength));
629 }
630 
signal_strength_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)631 static void signal_strength_cfg_changed(const struct bt_gatt_attr *attr,
632 					uint16_t value)
633 {
634 	const struct service_inst *inst = lookup_inst_by_attr(attr);
635 
636 	if (inst != NULL) {
637 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
638 	}
639 }
640 
read_signal_strength_interval(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)641 static ssize_t read_signal_strength_interval(struct bt_conn *conn,
642 					     const struct bt_gatt_attr *attr,
643 					     void *buf, uint16_t len,
644 					     uint16_t offset)
645 {
646 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
647 
648 	if (!is_authorized(conn)) {
649 		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
650 	}
651 
652 	LOG_DBG("Index %u: Signal strength interval 0x%02x",
653 		inst_index(inst), inst->signal_strength_interval);
654 
655 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
656 				 &inst->signal_strength_interval,
657 				 sizeof(inst->signal_strength_interval));
658 }
659 
write_signal_strength_interval(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)660 static ssize_t write_signal_strength_interval(struct bt_conn *conn,
661 					      const struct bt_gatt_attr *attr,
662 					      const void *buf, uint16_t len,
663 					      uint16_t offset, uint8_t flags)
664 {
665 	struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
666 	struct net_buf_simple net_buf;
667 	uint8_t signal_strength_interval;
668 
669 	if (!is_authorized(conn)) {
670 		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
671 	}
672 
673 	if (offset != 0) {
674 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
675 	}
676 
677 	if (len != sizeof(signal_strength_interval)) {
678 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
679 	}
680 
681 	net_buf_simple_init_with_data(&net_buf, (void *)buf, len);
682 	signal_strength_interval = net_buf_simple_pull_u8(&net_buf);
683 
684 	inst->signal_strength_interval = signal_strength_interval;
685 	LOG_DBG("Index %u: 0x%02x", inst_index(inst), signal_strength_interval);
686 
687 	return len;
688 }
689 
current_calls_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)690 static void current_calls_cfg_changed(const struct bt_gatt_attr *attr,
691 				      uint16_t value)
692 {
693 	struct service_inst *inst = lookup_inst_by_attr(attr);
694 
695 	if (inst != NULL) {
696 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
697 		inst->notify_current_calls = (value == BT_GATT_CCC_NOTIFY);
698 	}
699 }
700 
read_current_calls(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)701 static ssize_t read_current_calls(struct bt_conn *conn,
702 				  const struct bt_gatt_attr *attr,
703 				  void *buf, uint16_t len, uint16_t offset)
704 {
705 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
706 
707 	LOG_DBG("Index %u", inst_index(inst));
708 
709 	net_buf_put_current_calls(inst, &read_buf);
710 
711 	if (offset == 0) {
712 		LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Current calls");
713 	}
714 
715 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
716 				 read_buf.data, read_buf.len);
717 }
718 
read_ccid(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)719 static ssize_t read_ccid(struct bt_conn *conn,
720 			 const struct bt_gatt_attr *attr,
721 			 void *buf, uint16_t len, uint16_t offset)
722 {
723 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
724 
725 	LOG_DBG("Index %u: CCID 0x%02x", inst_index(inst), inst->ccid);
726 
727 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->ccid, sizeof(inst->ccid));
728 }
729 
read_status_flags(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)730 static ssize_t read_status_flags(struct bt_conn *conn,
731 				 const struct bt_gatt_attr *attr,
732 				 void *buf, uint16_t len, uint16_t offset)
733 {
734 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
735 	const uint16_t status_flags_le = sys_cpu_to_le16(inst->optional_opcodes);
736 
737 	LOG_DBG("Index %u: status_flags 0x%04x", inst_index(inst), inst->status_flags);
738 
739 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &status_flags_le,
740 				 sizeof(status_flags_le));
741 }
742 
status_flags_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)743 static void status_flags_cfg_changed(const struct bt_gatt_attr *attr,
744 					   uint16_t value)
745 {
746 	const struct service_inst *inst = lookup_inst_by_attr(attr);
747 
748 	if (inst != NULL) {
749 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
750 	}
751 }
752 
read_incoming_uri(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)753 static ssize_t read_incoming_uri(struct bt_conn *conn,
754 					    const struct bt_gatt_attr *attr,
755 					    void *buf, uint16_t len,
756 					    uint16_t offset)
757 {
758 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
759 	const struct bt_tbs_in_uri *inc_call_target;
760 	size_t val_len;
761 
762 	inc_call_target = &inst->incoming_uri;
763 
764 	LOG_DBG("Index %u: call index 0x%02x, URI %s", inst_index(inst),
765 		inc_call_target->call_index, inc_call_target->uri);
766 
767 	if (!inc_call_target->call_index) {
768 		LOG_DBG("URI not set");
769 
770 		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
771 	}
772 
773 	val_len = sizeof(inc_call_target->call_index) +
774 			strlen(inc_call_target->uri);
775 
776 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
777 				 inc_call_target, val_len);
778 }
779 
incoming_uri_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)780 static void incoming_uri_cfg_changed(const struct bt_gatt_attr *attr,
781 						uint16_t value)
782 {
783 	const struct service_inst *inst = lookup_inst_by_attr(attr);
784 
785 	if (inst != NULL) {
786 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
787 	}
788 }
789 
read_call_state(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)790 static ssize_t read_call_state(struct bt_conn *conn,
791 			       const struct bt_gatt_attr *attr,
792 			       void *buf, uint16_t len, uint16_t offset)
793 {
794 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
795 
796 	LOG_DBG("Index %u", inst_index(inst));
797 
798 	net_buf_put_call_states(inst, &read_buf);
799 
800 	if (offset == 0) {
801 		LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Call state");
802 	}
803 
804 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
805 				 read_buf.data, read_buf.len);
806 }
807 
call_state_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)808 static void call_state_cfg_changed(const struct bt_gatt_attr *attr,
809 				   uint16_t value)
810 {
811 	struct service_inst *inst = lookup_inst_by_attr(attr);
812 
813 	if (inst != NULL) {
814 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
815 		inst->notify_call_states = (value == BT_GATT_CCC_NOTIFY);
816 	}
817 }
818 
notify_ccp(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint8_t call_index,uint8_t opcode,uint8_t status)819 static int notify_ccp(struct bt_conn *conn, const struct bt_gatt_attr *attr,
820 		      uint8_t call_index, uint8_t opcode, uint8_t status)
821 {
822 	const struct bt_tbs_call_cp_notify ccp_not = {
823 		.call_index = call_index,
824 		.opcode = opcode,
825 		.status = status
826 	};
827 
828 	LOG_DBG("Notifying CCP: Call index %u, %s opcode and status %s", call_index,
829 		bt_tbs_opcode_str(opcode), bt_tbs_status_str(status));
830 
831 	return bt_gatt_notify(conn, attr, &ccp_not, sizeof(ccp_not));
832 }
833 
hold_other_calls(struct tbs_service_inst * inst,uint8_t call_index_cnt,const uint8_t * call_indexes)834 static void hold_other_calls(struct tbs_service_inst *inst,
835 			     uint8_t call_index_cnt,
836 			     const uint8_t *call_indexes)
837 {
838 	held_calls_cnt = 0;
839 
840 	for (int i = 0; i < ARRAY_SIZE(inst->calls); i++) {
841 		bool hold_call = true;
842 		uint8_t call_state;
843 
844 		for (int j = 0; j < call_index_cnt; j++) {
845 			if (inst->calls[i].index == call_indexes[j]) {
846 				hold_call = false;
847 				break;
848 			}
849 		}
850 
851 		if (!hold_call) {
852 			continue;
853 		}
854 
855 		call_state = inst->calls[i].state;
856 		if (call_state == BT_TBS_CALL_STATE_ACTIVE) {
857 			inst->calls[i].state = BT_TBS_CALL_STATE_LOCALLY_HELD;
858 			held_calls[held_calls_cnt++] = &inst->calls[i];
859 		} else if (call_state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
860 			inst->calls[i].state =
861 				BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
862 			held_calls[held_calls_cnt++] = &inst->calls[i];
863 		}
864 	}
865 }
866 
accept_call(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_acc * ccp)867 static uint8_t accept_call(struct tbs_service_inst *inst,
868 			   const struct bt_tbs_call_cp_acc *ccp)
869 {
870 	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
871 
872 	if (call == NULL) {
873 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
874 	}
875 
876 	if (call->state == BT_TBS_CALL_STATE_INCOMING) {
877 		call->state = BT_TBS_CALL_STATE_ACTIVE;
878 
879 		hold_other_calls(inst, 1, &ccp->call_index);
880 
881 		return BT_TBS_RESULT_CODE_SUCCESS;
882 	} else {
883 		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
884 	}
885 }
886 
terminate_call(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_term * ccp,uint8_t reason)887 static uint8_t terminate_call(struct tbs_service_inst *inst,
888 			      const struct bt_tbs_call_cp_term *ccp,
889 			      uint8_t reason)
890 {
891 	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
892 
893 	if (call == NULL) {
894 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
895 	}
896 
897 	call_free(call);
898 	tbs_set_terminate_reason(inst, ccp->call_index, reason);
899 
900 	return BT_TBS_RESULT_CODE_SUCCESS;
901 }
902 
tbs_hold_call(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_hold * ccp)903 static uint8_t tbs_hold_call(struct tbs_service_inst *inst,
904 			     const struct bt_tbs_call_cp_hold *ccp)
905 {
906 	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
907 
908 	if ((inst->inst.optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
909 		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
910 	}
911 
912 	if (call == NULL) {
913 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
914 	}
915 
916 	if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
917 		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
918 	} else if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
919 		call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
920 	} else if (call->state == BT_TBS_CALL_STATE_INCOMING) {
921 		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
922 	} else {
923 		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
924 	}
925 
926 	return BT_TBS_RESULT_CODE_SUCCESS;
927 }
928 
retrieve_call(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_retrieve * ccp)929 static uint8_t retrieve_call(struct tbs_service_inst *inst,
930 			     const struct bt_tbs_call_cp_retrieve *ccp)
931 {
932 	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
933 
934 	if ((inst->inst.optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
935 		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
936 	}
937 
938 	if (call == NULL) {
939 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
940 	}
941 
942 	if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
943 		call->state = BT_TBS_CALL_STATE_ACTIVE;
944 	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
945 		call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
946 	} else {
947 		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
948 	}
949 
950 	hold_other_calls(inst, 1, &ccp->call_index);
951 
952 	return BT_TBS_RESULT_CODE_SUCCESS;
953 }
954 
originate_call(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_originate * ccp,uint16_t uri_len,uint8_t * call_index)955 static int originate_call(struct tbs_service_inst *inst,
956 			  const struct bt_tbs_call_cp_originate *ccp,
957 			  uint16_t uri_len, uint8_t *call_index)
958 {
959 	struct bt_tbs_call *call;
960 
961 	/* Only allow one active outgoing call */
962 	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
963 		if (inst->calls[i].state == BT_TBS_CALL_STATE_ALERTING) {
964 			return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
965 		}
966 	}
967 
968 	if (!bt_tbs_valid_uri(ccp->uri, uri_len)) {
969 		return BT_TBS_RESULT_CODE_INVALID_URI;
970 	}
971 
972 	call = call_alloc(inst, BT_TBS_CALL_STATE_DIALING, ccp->uri, uri_len);
973 	if (call == NULL) {
974 		return BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
975 	}
976 
977 	BT_TBS_CALL_FLAG_SET_OUTGOING(call->flags);
978 
979 	hold_other_calls(inst, 1, &call->index);
980 
981 	notify_calls(inst);
982 	call->state = BT_TBS_CALL_STATE_ALERTING;
983 	notify_calls(inst);
984 
985 	LOG_DBG("New call with call index %u", call->index);
986 
987 	*call_index = call->index;
988 	return BT_TBS_RESULT_CODE_SUCCESS;
989 }
990 
join_calls(struct tbs_service_inst * inst,const struct bt_tbs_call_cp_join * ccp,uint16_t call_index_cnt)991 static uint8_t join_calls(struct tbs_service_inst *inst,
992 			  const struct bt_tbs_call_cp_join *ccp,
993 			  uint16_t call_index_cnt)
994 {
995 	struct bt_tbs_call *joined_calls[CONFIG_BT_TBS_MAX_CALLS];
996 	uint8_t call_state;
997 
998 	if ((inst->inst.optional_opcodes & BT_TBS_FEATURE_JOIN) == 0) {
999 		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
1000 	}
1001 
1002 	/* Check length */
1003 	if (call_index_cnt < 2 || call_index_cnt > CONFIG_BT_TBS_MAX_CALLS) {
1004 		return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
1005 	}
1006 
1007 	/* Check for duplicates */
1008 	for (int i = 0; i < call_index_cnt; i++) {
1009 		for (int j = 0; j < i; j++) {
1010 			if (ccp->call_indexes[i] == ccp->call_indexes[j]) {
1011 				return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1012 			}
1013 		}
1014 	}
1015 
1016 	/* Validate that all calls are in a joinable state */
1017 	for (int i = 0; i < call_index_cnt; i++) {
1018 		joined_calls[i] = lookup_call_in_inst(inst,
1019 						      ccp->call_indexes[i]);
1020 		if (joined_calls[i] == NULL) {
1021 			return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1022 		}
1023 
1024 		call_state = joined_calls[i]->state;
1025 
1026 		if (call_state == BT_TBS_CALL_STATE_INCOMING) {
1027 			return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
1028 		}
1029 
1030 		if (call_state != BT_TBS_CALL_STATE_LOCALLY_HELD &&
1031 		    call_state != BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD &&
1032 		    call_state != BT_TBS_CALL_STATE_ACTIVE) {
1033 			return BT_TBS_RESULT_CODE_STATE_MISMATCH;
1034 		}
1035 	}
1036 
1037 	/* Join all calls */
1038 	for (int i = 0; i < call_index_cnt; i++) {
1039 		call_state = joined_calls[i]->state;
1040 
1041 		if (call_state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
1042 			joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
1043 		} else if (call_state ==
1044 				BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
1045 			joined_calls[i]->state =
1046 				BT_TBS_CALL_STATE_REMOTELY_HELD;
1047 		} else if (call_state == BT_TBS_CALL_STATE_INCOMING) {
1048 			joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
1049 		}
1050 		/* else active => Do nothing */
1051 	}
1052 
1053 	hold_other_calls(inst, call_index_cnt, ccp->call_indexes);
1054 
1055 	return BT_TBS_RESULT_CODE_SUCCESS;
1056 }
1057 
notify_app(struct bt_conn * conn,struct tbs_service_inst * inst,uint16_t len,const union bt_tbs_call_cp_t * ccp,uint8_t status,uint8_t call_index)1058 static void notify_app(struct bt_conn *conn, struct tbs_service_inst *inst, uint16_t len,
1059 		       const union bt_tbs_call_cp_t *ccp, uint8_t status, uint8_t call_index)
1060 {
1061 	if (tbs_cbs == NULL) {
1062 		return;
1063 	}
1064 
1065 	switch (ccp->opcode) {
1066 	case BT_TBS_CALL_OPCODE_ACCEPT:
1067 		if (tbs_cbs->accept_call != NULL) {
1068 			tbs_cbs->accept_call(conn, call_index);
1069 		}
1070 		break;
1071 	case BT_TBS_CALL_OPCODE_TERMINATE:
1072 		if (tbs_cbs->terminate_call != NULL) {
1073 			tbs_cbs->terminate_call(conn, call_index,
1074 						inst->terminate_reason.reason);
1075 		}
1076 		break;
1077 	case BT_TBS_CALL_OPCODE_HOLD:
1078 		if (tbs_cbs->hold_call != NULL) {
1079 			tbs_cbs->hold_call(conn, call_index);
1080 		}
1081 		break;
1082 	case BT_TBS_CALL_OPCODE_RETRIEVE:
1083 		if (tbs_cbs->retrieve_call != NULL) {
1084 			tbs_cbs->retrieve_call(conn, call_index);
1085 		}
1086 		break;
1087 	case BT_TBS_CALL_OPCODE_ORIGINATE:
1088 	{
1089 		char uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
1090 		const uint16_t uri_len = len - sizeof(ccp->originate);
1091 		bool remote_party_alerted = false;
1092 		struct bt_tbs_call *call;
1093 
1094 		call = lookup_call_in_inst(inst, call_index);
1095 
1096 		if (call == NULL) {
1097 			LOG_DBG("Could not find call by call index 0x%02x", call_index);
1098 			break;
1099 		}
1100 
1101 		(void)memcpy(uri, ccp->originate.uri, uri_len);
1102 		uri[uri_len] = '\0';
1103 		if (tbs_cbs->originate_call != NULL) {
1104 			remote_party_alerted = tbs_cbs->originate_call(conn,
1105 								       call_index,
1106 								       uri);
1107 		}
1108 
1109 		if (remote_party_alerted) {
1110 			call->state = BT_TBS_CALL_STATE_ALERTING;
1111 		} else {
1112 			const struct bt_tbs_call_cp_term term = {
1113 				.call_index = call_index,
1114 				.opcode = BT_TBS_CALL_OPCODE_TERMINATE
1115 			};
1116 
1117 			/* Terminate and remove call */
1118 			terminate_call(inst, &term, BT_TBS_REASON_CALL_FAILED);
1119 		}
1120 
1121 		notify_calls(inst);
1122 
1123 		break;
1124 	}
1125 	case BT_TBS_CALL_OPCODE_JOIN:
1126 	{
1127 		const uint16_t call_index_cnt = len - sizeof(ccp->join);
1128 
1129 		/* Let the app know about joined calls */
1130 		if (tbs_cbs->join_calls != NULL) {
1131 			tbs_cbs->join_calls(conn, call_index_cnt,
1132 					    ccp->join.call_indexes);
1133 		}
1134 		break;
1135 	}
1136 	default:
1137 		break;
1138 	}
1139 
1140 	/* Let the app know about held calls */
1141 	if (held_calls_cnt != 0 && tbs_cbs->hold_call != NULL) {
1142 		for (int i = 0; i < held_calls_cnt; i++) {
1143 			tbs_cbs->hold_call(conn, held_calls[i]->index);
1144 		}
1145 	}
1146 }
1147 
write_call_cp(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)1148 static ssize_t write_call_cp(struct bt_conn *conn,
1149 			     const struct bt_gatt_attr *attr,
1150 			     const void *buf, uint16_t len,
1151 			     uint16_t offset, uint8_t flags)
1152 {
1153 	struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1154 	const union bt_tbs_call_cp_t *ccp = (union bt_tbs_call_cp_t *)buf;
1155 	struct tbs_service_inst *tbs = NULL;
1156 	uint8_t status;
1157 	uint8_t call_index = 0;
1158 	const bool is_gtbs = inst_is_gtbs(inst);
1159 
1160 	if (!is_authorized(conn)) {
1161 		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
1162 	}
1163 
1164 	if (offset != 0) {
1165 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
1166 	}
1167 
1168 	if (len < sizeof(ccp->opcode)) {
1169 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1170 	}
1171 
1172 	LOG_DBG("Index %u: Processing the %s opcode",
1173 		inst_index(inst), bt_tbs_opcode_str(ccp->opcode));
1174 
1175 	switch (ccp->opcode) {
1176 	case BT_TBS_CALL_OPCODE_ACCEPT:
1177 		if (len != sizeof(ccp->accept)) {
1178 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1179 		}
1180 
1181 		call_index = ccp->accept.call_index;
1182 
1183 		if (is_gtbs) {
1184 			tbs = lookup_inst_by_call_index(call_index);
1185 			if (tbs == NULL) {
1186 				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1187 				break;
1188 			}
1189 		} else {
1190 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1191 		}
1192 
1193 		status = accept_call(tbs, &ccp->accept);
1194 		break;
1195 	case BT_TBS_CALL_OPCODE_TERMINATE:
1196 		if (len != sizeof(ccp->terminate)) {
1197 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1198 		}
1199 
1200 		call_index = ccp->terminate.call_index;
1201 
1202 		if (is_gtbs) {
1203 			tbs = lookup_inst_by_call_index(call_index);
1204 			if (tbs == NULL) {
1205 				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1206 				break;
1207 			}
1208 		} else {
1209 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1210 		}
1211 
1212 		status = terminate_call(tbs, &ccp->terminate, BT_TBS_REASON_CLIENT_TERMINATED);
1213 		break;
1214 	case BT_TBS_CALL_OPCODE_HOLD:
1215 		if (len != sizeof(ccp->hold)) {
1216 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1217 		}
1218 
1219 		call_index = ccp->hold.call_index;
1220 
1221 		if (is_gtbs) {
1222 			tbs = lookup_inst_by_call_index(call_index);
1223 			if (tbs == NULL) {
1224 				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1225 				break;
1226 			}
1227 		} else {
1228 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1229 		}
1230 
1231 		status = tbs_hold_call(tbs, &ccp->hold);
1232 		break;
1233 	case BT_TBS_CALL_OPCODE_RETRIEVE:
1234 		if (len != sizeof(ccp->retrieve)) {
1235 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1236 		}
1237 
1238 		call_index = ccp->retrieve.call_index;
1239 
1240 		if (is_gtbs) {
1241 			tbs = lookup_inst_by_call_index(call_index);
1242 			if (tbs == NULL) {
1243 				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1244 				break;
1245 			}
1246 		} else {
1247 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1248 		}
1249 
1250 		status = retrieve_call(tbs, &ccp->retrieve);
1251 		break;
1252 	case BT_TBS_CALL_OPCODE_ORIGINATE:
1253 	{
1254 		const uint16_t uri_len = len - sizeof(ccp->originate);
1255 
1256 		if (len < sizeof(ccp->originate) + BT_TBS_MIN_URI_LEN) {
1257 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1258 		}
1259 
1260 		if (is_gtbs) {
1261 			tbs = lookup_inst_by_uri_scheme(ccp->originate.uri, uri_len);
1262 			if (tbs == NULL) {
1263 				/* TODO: Couldn't find fitting TBS instance;
1264 				 * use the first. If we want to be
1265 				 * restrictive about URIs, return
1266 				 * Invalid Caller ID instead
1267 				 */
1268 				tbs = &svc_insts[0];
1269 			}
1270 		} else {
1271 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1272 		}
1273 
1274 		status = originate_call(tbs, &ccp->originate, uri_len, &call_index);
1275 		break;
1276 	}
1277 	case BT_TBS_CALL_OPCODE_JOIN:
1278 	{
1279 		const uint16_t call_index_cnt = len - sizeof(ccp->join);
1280 
1281 		if (len < sizeof(ccp->join) + 1) { /* at least 1 call index */
1282 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1283 		}
1284 
1285 		call_index = ccp->join.call_indexes[0];
1286 
1287 		if (is_gtbs) {
1288 			tbs = lookup_inst_by_call_index(call_index);
1289 			if (tbs == NULL) {
1290 				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1291 				break;
1292 			}
1293 		} else {
1294 			tbs = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1295 		}
1296 
1297 		status = join_calls(tbs, &ccp->join, call_index_cnt);
1298 		break;
1299 	}
1300 	default:
1301 		status = BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
1302 		call_index = 0;
1303 		break;
1304 	}
1305 
1306 	if (tbs != NULL) {
1307 		LOG_DBG("Index %u: Processed the %s opcode with status %s for call index %u",
1308 			inst_index(inst), bt_tbs_opcode_str(ccp->opcode), bt_tbs_status_str(status),
1309 			call_index);
1310 
1311 		if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1312 			const struct bt_tbs_call *call = lookup_call(call_index);
1313 
1314 			if (call != NULL) {
1315 				LOG_DBG("Call is now in the %s state",
1316 					bt_tbs_state_str(call->state));
1317 			} else {
1318 				LOG_DBG("Call is now terminated");
1319 			}
1320 		}
1321 	}
1322 
1323 	if (status != BT_TBS_RESULT_CODE_SUCCESS) {
1324 		call_index = 0;
1325 	}
1326 
1327 	if (conn != NULL) {
1328 		notify_ccp(conn, attr, call_index, ccp->opcode, status);
1329 	} /* else local operation; don't notify */
1330 
1331 	if (tbs != NULL && status == BT_TBS_RESULT_CODE_SUCCESS) {
1332 		notify_calls(tbs);
1333 		notify_app(conn, tbs, len, ccp, status, call_index);
1334 	}
1335 
1336 	return len;
1337 }
1338 
call_cp_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1339 static void call_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1340 {
1341 	const struct service_inst *inst = lookup_inst_by_attr(attr);
1342 
1343 	if (inst != NULL) {
1344 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1345 	}
1346 }
1347 
read_optional_opcodes(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1348 static ssize_t read_optional_opcodes(struct bt_conn *conn,
1349 				     const struct bt_gatt_attr *attr,
1350 				     void *buf, uint16_t len, uint16_t offset)
1351 {
1352 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1353 	const uint16_t optional_opcodes_le = sys_cpu_to_le16(inst->optional_opcodes);
1354 
1355 	LOG_DBG("Index %u: Supported opcodes 0x%02x", inst_index(inst), inst->optional_opcodes);
1356 
1357 	return bt_gatt_attr_read(conn, attr, buf, len, offset, &optional_opcodes_le,
1358 				 sizeof(optional_opcodes_le));
1359 }
1360 
terminate_reason_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1361 static void terminate_reason_cfg_changed(const struct bt_gatt_attr *attr,
1362 					 uint16_t value)
1363 {
1364 	const struct service_inst *inst = lookup_inst_by_attr(attr);
1365 
1366 	if (inst != NULL) {
1367 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1368 	}
1369 }
1370 
read_friendly_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1371 static ssize_t read_friendly_name(struct bt_conn *conn,
1372 				     const struct bt_gatt_attr *attr,
1373 				     void *buf, uint16_t len, uint16_t offset)
1374 {
1375 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1376 	const struct bt_tbs_in_uri *friendly_name = &inst->friendly_name;
1377 	size_t val_len;
1378 
1379 	LOG_DBG("Index: 0x%02x call index 0x%02x, URI %s",
1380 		inst_index(inst), friendly_name->call_index, friendly_name->uri);
1381 
1382 	if (friendly_name->call_index == BT_TBS_FREE_CALL_INDEX) {
1383 		LOG_DBG("URI not set");
1384 		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1385 	}
1386 
1387 	val_len = sizeof(friendly_name->call_index) +
1388 			strlen(friendly_name->uri);
1389 
1390 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
1391 				 friendly_name, val_len);
1392 }
1393 
friendly_name_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1394 static void friendly_name_cfg_changed(const struct bt_gatt_attr *attr,
1395 					 uint16_t value)
1396 {
1397 	const struct service_inst *inst = lookup_inst_by_attr(attr);
1398 
1399 	if (inst != NULL) {
1400 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1401 	}
1402 }
1403 
read_incoming_call(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1404 static ssize_t read_incoming_call(struct bt_conn *conn,
1405 				  const struct bt_gatt_attr *attr,
1406 				  void *buf, uint16_t len, uint16_t offset)
1407 {
1408 	const struct service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1409 	const struct bt_tbs_in_uri *remote_uri = &inst->in_call;
1410 	size_t val_len;
1411 
1412 	LOG_DBG("Index: 0x%02x call index 0x%02x, URI %s",
1413 		inst_index(inst), remote_uri->call_index, remote_uri->uri);
1414 
1415 	if (remote_uri->call_index == BT_TBS_FREE_CALL_INDEX) {
1416 		LOG_DBG("URI not set");
1417 
1418 		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1419 	}
1420 
1421 	val_len = sizeof(remote_uri->call_index) + strlen(remote_uri->uri);
1422 
1423 	return bt_gatt_attr_read(conn, attr, buf, len, offset,
1424 				 remote_uri, val_len);
1425 }
1426 
in_call_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1427 static void in_call_cfg_changed(const struct bt_gatt_attr *attr,
1428 				      uint16_t value)
1429 {
1430 	const struct service_inst *inst = lookup_inst_by_attr(attr);
1431 
1432 	if (inst != NULL) {
1433 		LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1434 	}
1435 }
1436 
1437 #define BT_TBS_CHR_PROVIDER_NAME(inst) \
1438 	BT_AUDIO_CHRC(BT_UUID_TBS_PROVIDER_NAME, \
1439 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1440 		      BT_GATT_PERM_READ_ENCRYPT, \
1441 		      read_provider_name, NULL, inst), \
1442 	BT_AUDIO_CCC(provider_name_cfg_changed)
1443 
1444 #define BT_TBS_CHR_UCI(inst) \
1445 	BT_AUDIO_CHRC(BT_UUID_TBS_UCI, \
1446 		      BT_GATT_CHRC_READ, \
1447 		      BT_GATT_PERM_READ_ENCRYPT, \
1448 		      read_uci, NULL, inst)
1449 
1450 #define BT_TBS_CHR_TECHNOLOGY(inst) \
1451 	BT_AUDIO_CHRC(BT_UUID_TBS_TECHNOLOGY, \
1452 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1453 		      BT_GATT_PERM_READ_ENCRYPT, \
1454 		      read_technology, NULL, inst), \
1455 	BT_AUDIO_CCC(technology_cfg_changed)
1456 
1457 #define BT_TBS_CHR_URI_LIST(inst) \
1458 	BT_AUDIO_CHRC(BT_UUID_TBS_URI_LIST, \
1459 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1460 		      BT_GATT_PERM_READ_ENCRYPT, \
1461 		      read_uri_scheme_list, NULL, inst), \
1462 	BT_AUDIO_CCC(uri_scheme_list_cfg_changed)
1463 
1464 #define BT_TBS_CHR_SIGNAL_STRENGTH(inst) \
1465 	BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_STRENGTH, /* Optional */ \
1466 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1467 		      BT_GATT_PERM_READ_ENCRYPT, \
1468 		      read_signal_strength, NULL, inst), \
1469 	BT_AUDIO_CCC(signal_strength_cfg_changed)
1470 
1471 #define BT_TBS_CHR_SIGNAL_INTERVAL(inst) \
1472 	BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_INTERVAL, /* Conditional */ \
1473 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
1474 		      BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \
1475 		      read_signal_strength_interval, write_signal_strength_interval, inst)
1476 
1477 #define BT_TBS_CHR_CURRENT_CALLS(inst) \
1478 	BT_AUDIO_CHRC(BT_UUID_TBS_LIST_CURRENT_CALLS, \
1479 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1480 		      BT_GATT_PERM_READ_ENCRYPT, \
1481 		      read_current_calls, NULL, inst), \
1482 	BT_AUDIO_CCC(current_calls_cfg_changed)
1483 
1484 #define BT_TBS_CHR_CCID(inst) \
1485 	BT_AUDIO_CHRC(BT_UUID_CCID, \
1486 		      BT_GATT_CHRC_READ, \
1487 		      BT_GATT_PERM_READ_ENCRYPT, \
1488 		      read_ccid, NULL, inst)
1489 
1490 #define BT_TBS_CHR_STATUS_FLAGS(inst) \
1491 	BT_AUDIO_CHRC(BT_UUID_TBS_STATUS_FLAGS, \
1492 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1493 		      BT_GATT_PERM_READ_ENCRYPT, \
1494 		      read_status_flags, NULL, inst), \
1495 	BT_AUDIO_CCC(status_flags_cfg_changed)
1496 
1497 #define BT_TBS_CHR_INCOMING_URI(inst) \
1498 	BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_URI, /* Optional */ \
1499 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1500 		      BT_GATT_PERM_READ_ENCRYPT, \
1501 		      read_incoming_uri, NULL, inst), \
1502 	BT_AUDIO_CCC(incoming_uri_cfg_changed)
1503 
1504 #define BT_TBS_CHR_CALL_STATE(inst) \
1505 	BT_AUDIO_CHRC(BT_UUID_TBS_CALL_STATE, \
1506 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1507 		      BT_GATT_PERM_READ_ENCRYPT, \
1508 		      read_call_state, NULL, inst), \
1509 	BT_AUDIO_CCC(call_state_cfg_changed)
1510 
1511 #define BT_TBS_CHR_CONTROL_POINT(inst) \
1512 	BT_AUDIO_CHRC(BT_UUID_TBS_CALL_CONTROL_POINT, \
1513 		      BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
1514 		      BT_GATT_PERM_WRITE_ENCRYPT, \
1515 		      NULL, write_call_cp, inst), \
1516 	BT_AUDIO_CCC(call_cp_cfg_changed)
1517 
1518 #define BT_TBS_CHR_OPTIONAL_OPCODES(inst) \
1519 	BT_AUDIO_CHRC(BT_UUID_TBS_OPTIONAL_OPCODES, \
1520 		      BT_GATT_CHRC_READ, \
1521 		      BT_GATT_PERM_READ_ENCRYPT, \
1522 		      read_optional_opcodes, NULL, inst) \
1523 
1524 #define BT_TBS_CHR_TERMINATE_REASON(inst) \
1525 	BT_AUDIO_CHRC(BT_UUID_TBS_TERMINATE_REASON, \
1526 		      BT_GATT_CHRC_NOTIFY, \
1527 		      BT_GATT_PERM_READ_ENCRYPT, \
1528 		      NULL, NULL, inst), \
1529 	BT_AUDIO_CCC(terminate_reason_cfg_changed)
1530 
1531 #define BT_TBS_CHR_INCOMING_CALL(inst) \
1532 	BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_CALL, \
1533 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1534 		      BT_GATT_PERM_READ_ENCRYPT, \
1535 		      read_incoming_call, NULL, inst), \
1536 	BT_AUDIO_CCC(in_call_cfg_changed)
1537 
1538 #define BT_TBS_CHR_FRIENDLY_NAME(inst) \
1539 	BT_AUDIO_CHRC(BT_UUID_TBS_FRIENDLY_NAME, /* Optional */ \
1540 		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1541 		      BT_GATT_PERM_READ_ENCRYPT, \
1542 		      read_friendly_name, NULL, inst), \
1543 	BT_AUDIO_CCC(friendly_name_cfg_changed)
1544 
1545 #define BT_TBS_SERVICE_DEFINE(_uuid, _inst)                                                        \
1546 	BT_GATT_PRIMARY_SERVICE(_uuid),                                                            \
1547 	BT_TBS_CHR_PROVIDER_NAME(_inst),                                                           \
1548 	BT_TBS_CHR_UCI(_inst),                                                                     \
1549 	BT_TBS_CHR_TECHNOLOGY(_inst),                                                              \
1550 	BT_TBS_CHR_URI_LIST(_inst),                                                                \
1551 	BT_TBS_CHR_SIGNAL_STRENGTH(_inst),                                                         \
1552 	BT_TBS_CHR_SIGNAL_INTERVAL(_inst),                                                         \
1553 	BT_TBS_CHR_CURRENT_CALLS(_inst),                                                           \
1554 	BT_TBS_CHR_CCID(_inst),                                                                    \
1555 	BT_TBS_CHR_STATUS_FLAGS(_inst),                                                            \
1556 	BT_TBS_CHR_INCOMING_URI(_inst),                                                            \
1557 	BT_TBS_CHR_CALL_STATE(_inst),                                                              \
1558 	BT_TBS_CHR_CONTROL_POINT(_inst),                                                           \
1559 	BT_TBS_CHR_OPTIONAL_OPCODES(_inst),                                                        \
1560 	BT_TBS_CHR_TERMINATE_REASON(_inst),                                                        \
1561 	BT_TBS_CHR_INCOMING_CALL(_inst),                                                           \
1562 	BT_TBS_CHR_FRIENDLY_NAME(_inst)
1563 
1564 #define BT_TBS_SERVICE_DEFINITION(_inst) { BT_TBS_SERVICE_DEFINE(BT_UUID_TBS, &(_inst).inst) }
1565 
1566 /*
1567  * Defining this as extern make it possible to link code that otherwise would
1568  * give "unknown identifier" linking errors.
1569  */
1570 extern const struct bt_gatt_service_static gtbs_svc;
1571 
1572 /* TODO: Can we make the multiple service instance more generic? */
1573 #if CONFIG_BT_GTBS
1574 BT_GATT_SERVICE_DEFINE(gtbs_svc, BT_TBS_SERVICE_DEFINE(BT_UUID_GTBS, &gtbs_inst.inst));
1575 #endif /* CONFIG_BT_GTBS */
1576 
1577 BT_GATT_SERVICE_INSTANCE_DEFINE(tbs_service_list, svc_insts, CONFIG_BT_TBS_BEARER_COUNT,
1578 				BT_TBS_SERVICE_DEFINITION);
1579 
signal_interval_timeout(struct k_work * work)1580 static void signal_interval_timeout(struct k_work *work)
1581 {
1582 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1583 	struct service_inst *inst = CONTAINER_OF(dwork, struct service_inst,
1584 						 reporting_interval_work);
1585 
1586 	if (!inst->pending_signal_strength_notification) {
1587 		return;
1588 	}
1589 
1590 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_SIGNAL_STRENGTH, inst->attrs, &inst->signal_strength,
1591 			    sizeof(inst->signal_strength));
1592 
1593 	if (inst->signal_strength_interval) {
1594 		k_work_reschedule(&inst->reporting_interval_work,
1595 				  K_SECONDS(inst->signal_strength_interval));
1596 	}
1597 
1598 	inst->pending_signal_strength_notification = false;
1599 }
1600 
tbs_inst_init(struct service_inst * inst,const struct bt_gatt_attr * attrs,size_t attr_count,const char * provider_name)1601 static void tbs_inst_init(struct service_inst *inst, const struct bt_gatt_attr *attrs,
1602 			  size_t attr_count, const char *provider_name)
1603 {
1604 	LOG_DBG("inst %p index 0x%02x provider_name %s", inst, inst_index(inst), provider_name);
1605 
1606 	inst->ccid = bt_ccid_get_value();
1607 	(void)utf8_lcpy(inst->provider_name, provider_name, sizeof(inst->provider_name));
1608 	(void)utf8_lcpy(inst->uci, CONFIG_BT_TBS_UCI, sizeof(inst->uci));
1609 	inst->optional_opcodes = CONFIG_BT_TBS_SUPPORTED_FEATURES;
1610 	inst->technology = CONFIG_BT_TBS_TECHNOLOGY;
1611 	inst->signal_strength_interval = CONFIG_BT_TBS_SIGNAL_STRENGTH_INTERVAL;
1612 	inst->status_flags = CONFIG_BT_TBS_STATUS_FLAGS;
1613 	inst->attrs = attrs;
1614 	inst->attr_count = attr_count;
1615 
1616 	k_work_init_delayable(&inst->reporting_interval_work, signal_interval_timeout);
1617 }
1618 
gtbs_service_inst_init(struct gtbs_service_inst * inst,const struct bt_gatt_service_static * service)1619 static void gtbs_service_inst_init(struct gtbs_service_inst *inst,
1620 				   const struct bt_gatt_service_static *service)
1621 {
1622 	tbs_inst_init(&inst->inst, service->attrs, service->attr_count, "Generic TBS");
1623 }
1624 
tbs_service_inst_init(struct tbs_service_inst * inst,struct bt_gatt_service * service)1625 static void tbs_service_inst_init(struct tbs_service_inst *inst, struct bt_gatt_service *service)
1626 {
1627 	tbs_inst_init(&inst->inst, service->attrs, service->attr_count,
1628 		      CONFIG_BT_TBS_PROVIDER_NAME);
1629 	(void)utf8_lcpy(inst->uri_scheme_list, CONFIG_BT_TBS_URI_SCHEMES_LIST,
1630 			sizeof(inst->uri_scheme_list));
1631 }
1632 
bt_tbs_init(void)1633 static int bt_tbs_init(void)
1634 {
1635 	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
1636 		int err;
1637 
1638 		err = bt_gatt_service_register(&tbs_service_list[i]);
1639 		if (err != 0) {
1640 			LOG_ERR("Could not register TBS[%d]: %d", i, err);
1641 		}
1642 
1643 		tbs_service_inst_init(&svc_insts[i], &tbs_service_list[i]);
1644 	}
1645 
1646 	if (IS_ENABLED(CONFIG_BT_GTBS)) {
1647 		gtbs_service_inst_init(&gtbs_inst, &gtbs_svc);
1648 	}
1649 
1650 	return 0;
1651 }
1652 
1653 SYS_INIT(bt_tbs_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
1654 
1655 /***************************** Profile API *****************************/
bt_tbs_accept(uint8_t call_index)1656 int bt_tbs_accept(uint8_t call_index)
1657 {
1658 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1659 	int status = -EINVAL;
1660 	const struct bt_tbs_call_cp_acc ccp = {
1661 		.call_index = call_index,
1662 		.opcode = BT_TBS_CALL_OPCODE_ACCEPT
1663 	};
1664 
1665 	if (inst != NULL) {
1666 		status = accept_call(inst, &ccp);
1667 	}
1668 
1669 	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1670 		notify_calls(inst);
1671 	}
1672 
1673 	return status;
1674 }
1675 
bt_tbs_hold(uint8_t call_index)1676 int bt_tbs_hold(uint8_t call_index)
1677 {
1678 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1679 	int status = -EINVAL;
1680 	const struct bt_tbs_call_cp_hold ccp = {
1681 		.call_index = call_index,
1682 		.opcode = BT_TBS_CALL_OPCODE_HOLD
1683 	};
1684 
1685 	if (inst != NULL) {
1686 		status = tbs_hold_call(inst, &ccp);
1687 	}
1688 
1689 	notify_calls(inst);
1690 
1691 	return status;
1692 }
1693 
bt_tbs_retrieve(uint8_t call_index)1694 int bt_tbs_retrieve(uint8_t call_index)
1695 {
1696 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1697 	int status = -EINVAL;
1698 	const struct bt_tbs_call_cp_retrieve ccp = {
1699 		.call_index = call_index,
1700 		.opcode = BT_TBS_CALL_OPCODE_RETRIEVE
1701 	};
1702 
1703 	if (inst != NULL) {
1704 		status = retrieve_call(inst, &ccp);
1705 	}
1706 
1707 	notify_calls(inst);
1708 
1709 	return status;
1710 }
1711 
bt_tbs_terminate(uint8_t call_index)1712 int bt_tbs_terminate(uint8_t call_index)
1713 {
1714 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1715 	int status = -EINVAL;
1716 	const struct bt_tbs_call_cp_term ccp = {
1717 		.call_index = call_index,
1718 		.opcode = BT_TBS_CALL_OPCODE_TERMINATE
1719 	};
1720 
1721 	if (inst != NULL) {
1722 		status = terminate_call(inst, &ccp,
1723 					BT_TBS_REASON_SERVER_ENDED_CALL);
1724 	}
1725 
1726 	notify_calls(inst);
1727 
1728 	return status;
1729 }
1730 
bt_tbs_originate(uint8_t bearer_index,char * remote_uri,uint8_t * call_index)1731 int bt_tbs_originate(uint8_t bearer_index, char *remote_uri,
1732 		     uint8_t *call_index)
1733 {
1734 	struct service_inst *tbs = inst_lookup_index(bearer_index);
1735 	struct tbs_service_inst *inst;
1736 	uint8_t buf[CONFIG_BT_TBS_MAX_URI_LENGTH +
1737 		    sizeof(struct bt_tbs_call_cp_originate)];
1738 	struct bt_tbs_call_cp_originate *ccp =
1739 		(struct bt_tbs_call_cp_originate *)buf;
1740 	size_t uri_len;
1741 
1742 	if (tbs == NULL || inst_is_gtbs(tbs)) {
1743 		return -EINVAL;
1744 	} else if (!bt_tbs_valid_uri(remote_uri, strlen(remote_uri))) {
1745 		LOG_DBG("Invalid URI %s", remote_uri);
1746 		return -EINVAL;
1747 	}
1748 
1749 	uri_len = strlen(remote_uri);
1750 
1751 	inst = CONTAINER_OF(tbs, struct tbs_service_inst, inst);
1752 
1753 	ccp->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
1754 	(void)memcpy(ccp->uri, remote_uri, uri_len);
1755 
1756 	return originate_call(inst, ccp, uri_len, call_index);
1757 }
1758 
bt_tbs_join(uint8_t call_index_cnt,uint8_t * call_indexes)1759 int bt_tbs_join(uint8_t call_index_cnt, uint8_t *call_indexes)
1760 {
1761 	struct tbs_service_inst *inst;
1762 	uint8_t buf[CONFIG_BT_TBS_MAX_CALLS +
1763 		 sizeof(struct bt_tbs_call_cp_join)];
1764 	struct bt_tbs_call_cp_join *ccp = (struct bt_tbs_call_cp_join *)buf;
1765 	int status = -EINVAL;
1766 
1767 	if (call_index_cnt != 0 && call_indexes != 0) {
1768 		inst = lookup_inst_by_call_index(call_indexes[0]);
1769 	} else {
1770 		return status;
1771 	}
1772 
1773 	if (inst != NULL) {
1774 		ccp->opcode = BT_TBS_CALL_OPCODE_JOIN;
1775 		(void)memcpy(ccp->call_indexes, call_indexes,
1776 		MIN(call_index_cnt, CONFIG_BT_TBS_MAX_CALLS));
1777 
1778 		status = join_calls(inst, ccp, call_index_cnt);
1779 	}
1780 
1781 	return status;
1782 }
1783 
bt_tbs_remote_answer(uint8_t call_index)1784 int bt_tbs_remote_answer(uint8_t call_index)
1785 {
1786 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1787 	struct bt_tbs_call *call;
1788 
1789 	if (inst == NULL) {
1790 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1791 	}
1792 
1793 	call = lookup_call_in_inst(inst, call_index);
1794 
1795 	if (call == NULL) {
1796 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1797 	}
1798 
1799 	if (call->state == BT_TBS_CALL_STATE_ALERTING) {
1800 		call->state = BT_TBS_CALL_STATE_ACTIVE;
1801 		notify_calls(inst);
1802 		return BT_TBS_RESULT_CODE_SUCCESS;
1803 	} else {
1804 		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
1805 	}
1806 }
1807 
bt_tbs_remote_hold(uint8_t call_index)1808 int bt_tbs_remote_hold(uint8_t call_index)
1809 {
1810 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1811 	struct bt_tbs_call *call;
1812 	uint8_t status;
1813 
1814 	if (inst == NULL) {
1815 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1816 	}
1817 
1818 	call = lookup_call_in_inst(inst, call_index);
1819 
1820 	if (call == NULL) {
1821 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1822 	}
1823 
1824 	if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
1825 		call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
1826 		status = BT_TBS_RESULT_CODE_SUCCESS;
1827 	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
1828 		call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
1829 		status = BT_TBS_RESULT_CODE_SUCCESS;
1830 	} else {
1831 		status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
1832 	}
1833 
1834 	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1835 		notify_calls(inst);
1836 	}
1837 
1838 	return status;
1839 }
1840 
bt_tbs_remote_retrieve(uint8_t call_index)1841 int bt_tbs_remote_retrieve(uint8_t call_index)
1842 {
1843 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1844 	struct bt_tbs_call *call;
1845 	int status;
1846 
1847 	if (inst == NULL) {
1848 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1849 	}
1850 
1851 	call = lookup_call_in_inst(inst, call_index);
1852 
1853 	if (call == NULL) {
1854 		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1855 	}
1856 
1857 	if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
1858 		call->state = BT_TBS_CALL_STATE_ACTIVE;
1859 		status = BT_TBS_RESULT_CODE_SUCCESS;
1860 	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
1861 		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
1862 		status = BT_TBS_RESULT_CODE_SUCCESS;
1863 	} else {
1864 		status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
1865 	}
1866 
1867 	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1868 		notify_calls(inst);
1869 	}
1870 
1871 	return status;
1872 }
1873 
bt_tbs_remote_terminate(uint8_t call_index)1874 int bt_tbs_remote_terminate(uint8_t call_index)
1875 {
1876 	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
1877 	int status = -EINVAL;
1878 	const struct bt_tbs_call_cp_term ccp = {
1879 		.call_index = call_index,
1880 		.opcode = BT_TBS_CALL_OPCODE_TERMINATE
1881 	};
1882 
1883 	if (inst != NULL) {
1884 		status = terminate_call(inst, &ccp,
1885 					BT_TBS_REASON_REMOTE_ENDED_CALL);
1886 	}
1887 
1888 	notify_calls(inst);
1889 
1890 	return status;
1891 }
1892 
tbs_inst_remote_incoming(struct service_inst * inst,const char * to,const char * from,const char * friendly_name,const struct bt_tbs_call * call)1893 static void tbs_inst_remote_incoming(struct service_inst *inst, const char *to, const char *from,
1894 				     const char *friendly_name, const struct bt_tbs_call *call)
1895 {
1896 	size_t local_uri_ind_len;
1897 	size_t remote_uri_ind_len;
1898 	size_t friend_name_ind_len;
1899 
1900 	__ASSERT_NO_MSG(to != NULL);
1901 	__ASSERT_NO_MSG(from != NULL);
1902 
1903 	local_uri_ind_len = strlen(to) + 1;
1904 	remote_uri_ind_len = strlen(from) + 1;
1905 
1906 	inst->in_call.call_index = call->index;
1907 	(void)utf8_lcpy(inst->in_call.uri, from, sizeof(inst->in_call.uri));
1908 
1909 	inst->incoming_uri.call_index = call->index;
1910 	(void)utf8_lcpy(inst->incoming_uri.uri, to, sizeof(inst->incoming_uri.uri));
1911 
1912 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_URI, inst->attrs, &inst->incoming_uri,
1913 			    local_uri_ind_len);
1914 
1915 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_CALL, inst->attrs, &inst->in_call,
1916 			    remote_uri_ind_len);
1917 
1918 	if (friendly_name) {
1919 		inst->friendly_name.call_index = call->index;
1920 		utf8_lcpy(inst->friendly_name.uri, friendly_name, sizeof(inst->friendly_name.uri));
1921 		friend_name_ind_len = strlen(from) + 1;
1922 
1923 		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME, inst->attrs,
1924 				    &inst->friendly_name, friend_name_ind_len);
1925 	} else {
1926 		inst->friendly_name.call_index = BT_TBS_FREE_CALL_INDEX;
1927 		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME, inst->attrs, NULL, 0);
1928 	}
1929 }
1930 
bt_tbs_remote_incoming(uint8_t bearer_index,const char * to,const char * from,const char * friendly_name)1931 int bt_tbs_remote_incoming(uint8_t bearer_index, const char *to,
1932 			   const char *from, const char *friendly_name)
1933 {
1934 	struct service_inst *inst = inst_lookup_index(bearer_index);
1935 	struct tbs_service_inst *service_inst;
1936 	struct bt_tbs_call *call = NULL;
1937 
1938 	if (inst == NULL || inst_is_gtbs(inst)) {
1939 		return -EINVAL;
1940 	} else if (!bt_tbs_valid_uri(to, strlen(to))) {
1941 		LOG_DBG("Invalid \"to\" URI: %s", to);
1942 		return -EINVAL;
1943 	} else if (!bt_tbs_valid_uri(from, strlen(from))) {
1944 		LOG_DBG("Invalid \"from\" URI: %s", from);
1945 		return -EINVAL;
1946 	}
1947 
1948 	service_inst = CONTAINER_OF(inst, struct tbs_service_inst, inst);
1949 
1950 	call = call_alloc(service_inst, BT_TBS_CALL_STATE_INCOMING, from, strlen(from));
1951 	if (call == NULL) {
1952 		return -ENOMEM;
1953 	}
1954 
1955 	BT_TBS_CALL_FLAG_SET_INCOMING(call->flags);
1956 
1957 	tbs_inst_remote_incoming(inst, to, from, friendly_name, call);
1958 
1959 	if (IS_ENABLED(CONFIG_BT_GTBS)) {
1960 		tbs_inst_remote_incoming(&gtbs_inst.inst, to, from, friendly_name, call);
1961 	}
1962 
1963 	notify_calls(service_inst);
1964 
1965 	LOG_DBG("New call with call index %u", call->index);
1966 
1967 	return call->index;
1968 }
1969 
bt_tbs_set_bearer_provider_name(uint8_t bearer_index,const char * name)1970 int bt_tbs_set_bearer_provider_name(uint8_t bearer_index, const char *name)
1971 {
1972 	struct service_inst *inst = inst_lookup_index(bearer_index);
1973 	const size_t len = strlen(name);
1974 
1975 	if (len >= CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH || len == 0) {
1976 		return -EINVAL;
1977 	} else if (inst == NULL) {
1978 		return -EINVAL;
1979 	}
1980 
1981 	if (strcmp(inst->provider_name, name) == 0) {
1982 		return 0;
1983 	}
1984 
1985 	(void)utf8_lcpy(inst->provider_name, name, sizeof(inst->provider_name));
1986 
1987 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_PROVIDER_NAME, inst->attrs, inst->provider_name,
1988 			    strlen(inst->provider_name));
1989 	return 0;
1990 }
1991 
bt_tbs_set_bearer_technology(uint8_t bearer_index,uint8_t new_technology)1992 int bt_tbs_set_bearer_technology(uint8_t bearer_index, uint8_t new_technology)
1993 {
1994 	struct service_inst *inst = inst_lookup_index(bearer_index);
1995 
1996 	if (new_technology < BT_TBS_TECHNOLOGY_3G || new_technology > BT_TBS_TECHNOLOGY_WCDMA) {
1997 		return -EINVAL;
1998 	} else if (inst == NULL) {
1999 		return -EINVAL;
2000 	}
2001 
2002 	if (inst->technology == new_technology) {
2003 		return 0;
2004 	}
2005 
2006 	inst->technology = new_technology;
2007 
2008 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TECHNOLOGY, inst->attrs, &inst->technology,
2009 			    sizeof(inst->technology));
2010 
2011 	return 0;
2012 }
2013 
bt_tbs_set_signal_strength(uint8_t bearer_index,uint8_t new_signal_strength)2014 int bt_tbs_set_signal_strength(uint8_t bearer_index,
2015 			       uint8_t new_signal_strength)
2016 {
2017 	struct service_inst *inst = inst_lookup_index(bearer_index);
2018 	uint32_t timer_status;
2019 
2020 	if (new_signal_strength > BT_TBS_SIGNAL_STRENGTH_MAX &&
2021 	    new_signal_strength != BT_TBS_SIGNAL_STRENGTH_UNKNOWN) {
2022 		return -EINVAL;
2023 	} else if (inst == NULL) {
2024 		return -EINVAL;
2025 	}
2026 
2027 	if (inst->signal_strength == new_signal_strength) {
2028 		return 0;
2029 	}
2030 
2031 	inst->signal_strength = new_signal_strength;
2032 	inst->pending_signal_strength_notification = true;
2033 
2034 	timer_status = k_work_delayable_remaining_get(&inst->reporting_interval_work);
2035 	if (timer_status == 0) {
2036 		k_work_reschedule(&inst->reporting_interval_work, K_NO_WAIT);
2037 	}
2038 
2039 	LOG_DBG("Index %u: Reporting signal strength in %d ms", bearer_index, timer_status);
2040 
2041 	return 0;
2042 }
2043 
bt_tbs_set_status_flags(uint8_t bearer_index,uint16_t status_flags)2044 int bt_tbs_set_status_flags(uint8_t bearer_index, uint16_t status_flags)
2045 {
2046 	struct service_inst *inst = inst_lookup_index(bearer_index);
2047 
2048 	if (!BT_TBS_VALID_STATUS_FLAGS(status_flags)) {
2049 		return -EINVAL;
2050 	} else if (inst == NULL) {
2051 		return -EINVAL;
2052 	}
2053 
2054 	if (inst->status_flags == status_flags) {
2055 		return 0;
2056 	}
2057 
2058 	inst->status_flags = status_flags;
2059 
2060 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_STATUS_FLAGS,
2061 			    inst->attrs, &status_flags, sizeof(status_flags));
2062 	return 0;
2063 }
2064 
bt_tbs_set_uri_scheme_list(uint8_t bearer_index,const char ** uri_list,uint8_t uri_count)2065 int bt_tbs_set_uri_scheme_list(uint8_t bearer_index, const char **uri_list,
2066 			       uint8_t uri_count)
2067 {
2068 	char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
2069 	size_t len = 0;
2070 	struct tbs_service_inst *inst;
2071 
2072 	if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
2073 		return -EINVAL;
2074 	}
2075 
2076 	inst = &svc_insts[bearer_index];
2077 	(void)memset(uri_scheme_list, 0, sizeof(uri_scheme_list));
2078 
2079 	for (int i = 0; i < uri_count; i++) {
2080 		if (len) {
2081 			len++;
2082 			if (len > sizeof(uri_scheme_list) - 1)  {
2083 				return -ENOMEM;
2084 			}
2085 
2086 			strcat(uri_scheme_list, ",");
2087 		}
2088 
2089 		len += strlen(uri_list[i]);
2090 		if (len > sizeof(uri_scheme_list) - 1)  {
2091 			return -ENOMEM;
2092 		}
2093 
2094 		/* Store list in temp list in case something goes wrong */
2095 		strcat(uri_scheme_list, uri_list[i]);
2096 	}
2097 
2098 	if (strcmp(inst->uri_scheme_list, uri_scheme_list) == 0) {
2099 		/* identical; don't update or notify */
2100 		return 0;
2101 	}
2102 
2103 	/* Store final result */
2104 	(void)utf8_lcpy(inst->uri_scheme_list, uri_scheme_list, sizeof(inst->uri_scheme_list));
2105 
2106 	LOG_DBG("TBS instance %u uri prefix list is now %s", bearer_index, inst->uri_scheme_list);
2107 
2108 	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST,
2109 			    inst->inst.attrs, &inst->uri_scheme_list,
2110 			    strlen(inst->uri_scheme_list));
2111 
2112 	if (IS_ENABLED(CONFIG_BT_GTBS)) {
2113 		NET_BUF_SIMPLE_DEFINE(uri_scheme_buf, READ_BUF_SIZE);
2114 
2115 		/* TODO: Make uri schemes unique */
2116 		for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
2117 			const size_t uri_len = strlen(svc_insts[i].uri_scheme_list);
2118 
2119 			if (uri_scheme_buf.len + uri_len >= uri_scheme_buf.size) {
2120 				LOG_WRN("Cannot fit all TBS instances in GTBS "
2121 					"URI scheme list");
2122 				break;
2123 			}
2124 
2125 			net_buf_simple_add_mem(&uri_scheme_buf,
2126 					       svc_insts[i].uri_scheme_list,
2127 					       uri_len);
2128 		}
2129 
2130 		LOG_DBG("GTBS: URI scheme %.*s", uri_scheme_buf.len, uri_scheme_buf.data);
2131 
2132 		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST,
2133 				    inst->inst.attrs,
2134 				    uri_scheme_buf.data, uri_scheme_buf.len);
2135 	}
2136 
2137 	return 0;
2138 }
2139 
bt_tbs_register_cb(struct bt_tbs_cb * cbs)2140 void bt_tbs_register_cb(struct bt_tbs_cb *cbs)
2141 {
2142 	tbs_cbs = cbs;
2143 }
2144 
2145 #if defined(CONFIG_BT_TBS_LOG_LEVEL_DBG)
bt_tbs_dbg_print_calls(void)2146 void bt_tbs_dbg_print_calls(void)
2147 {
2148 	for (int i = 0; i < CONFIG_BT_TBS_BEARER_COUNT; i++) {
2149 		LOG_DBG("Bearer #%u", i);
2150 		for (int j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
2151 			struct bt_tbs_call *call = &svc_insts[i].calls[j];
2152 
2153 			if (call->index == BT_TBS_FREE_CALL_INDEX) {
2154 				continue;
2155 			}
2156 
2157 			LOG_DBG("  Call #%u", call->index);
2158 			LOG_DBG("    State: %s", bt_tbs_state_str(call->state));
2159 			LOG_DBG("    Flags: 0x%02X", call->flags);
2160 			LOG_DBG("    URI  : %s", call->remote_uri);
2161 		}
2162 	}
2163 }
2164 #endif /* defined(CONFIG_BT_TBS_LOG_LEVEL_DBG) */
2165