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