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