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