1 /*  Bluetooth TBS - Telephone Bearer Service - Client
2  *
3  * Copyright (c) 2020 Bose Corporation
4  * Copyright (c) 2021-2024 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #include <errno.h>
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <string.h>
13 
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/att.h>
16 #include <zephyr/bluetooth/audio/tbs.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/buf.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/bluetooth/gatt.h>
21 #include <zephyr/bluetooth/uuid.h>
22 #include <zephyr/init.h>
23 #include <zephyr/kernel.h>
24 #include <zephyr/logging/log.h>
25 #include <zephyr/net_buf.h>
26 #include <zephyr/sys/__assert.h>
27 #include <zephyr/sys/atomic.h>
28 #include <zephyr/sys/slist.h>
29 #include <zephyr/sys/util.h>
30 #include <zephyr/sys/util_macro.h>
31 #include <zephyr/toolchain.h>
32 #include <zephyr/types.h>
33 #include <zephyr/sys/check.h>
34 
35 #include "tbs_internal.h"
36 
37 LOG_MODULE_REGISTER(bt_tbs_client, CONFIG_BT_TBS_CLIENT_LOG_LEVEL);
38 /* TODO TBS client attempts to subscribe to all characteristics at once if the MTU is large enough.
39  * This requires a significant amount of buffers, and should be optimized.
40  */
41 
42 /* Calculate the required buffers for TBS Client discovery */
43 #define TBS_CLIENT_BUF_COUNT                                                                       \
44 	(1 /* Discover buffer */ + 1 /* terminate reason */ +                                      \
45 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) +                                   \
46 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) +                                      \
47 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) +                                 \
48 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) +                              \
49 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_INCOMING_URI) +                                           \
50 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) +                                           \
51 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES) +                                          \
52 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) +                                     \
53 	 IS_ENABLED(CONFIG_BT_TBS_CLIENT_INCOMING_CALL))
54 
55 BUILD_ASSERT(CONFIG_BT_ATT_TX_COUNT >= TBS_CLIENT_BUF_COUNT, "Too few ATT buffers");
56 
57 #include "common/bt_str.h"
58 
59 struct bt_tbs_server_inst {
60 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
61 	struct bt_tbs_instance tbs_insts[CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES];
62 	uint8_t inst_cnt;
63 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
64 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
65 	struct bt_tbs_instance gtbs_inst;
66 #endif /* defined(CONFIG_BT_TBS_CLIENT_GTBS) */
67 	struct bt_gatt_discover_params discover_params;
68 	struct bt_tbs_instance *current_inst;
69 };
70 
71 static sys_slist_t tbs_client_cbs = SYS_SLIST_STATIC_INIT(&tbs_client_cbs);
72 
73 static struct bt_tbs_server_inst srv_insts[CONFIG_BT_MAX_CONN];
74 
75 static void discover_next_instance(struct bt_conn *conn);
76 
77 typedef  bool (*tbs_instance_find_func_t)(struct bt_tbs_instance *inst, void *user_data);
78 
tbs_instance_find(struct bt_tbs_server_inst * server,tbs_instance_find_func_t func,void * user_data)79 static struct bt_tbs_instance *tbs_instance_find(struct bt_tbs_server_inst *server,
80 						 tbs_instance_find_func_t func, void *user_data)
81 {
82 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
83 		if (func(&server->gtbs_inst, user_data)) {
84 			return &server->gtbs_inst;
85 		}
86 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
87 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
88 	for (size_t i = 0; i < server->inst_cnt; i++) {
89 		if (func(&server->tbs_insts[i], user_data)) {
90 			return &server->tbs_insts[i];
91 		}
92 	}
93 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
94 
95 	return NULL;
96 }
97 
tbs_inst_by_index(struct bt_conn * conn,uint8_t index)98 static struct bt_tbs_instance *tbs_inst_by_index(struct bt_conn *conn, uint8_t index)
99 {
100 	struct bt_tbs_server_inst *server;
101 
102 	__ASSERT(conn, "NULL conn");
103 
104 	server = &srv_insts[bt_conn_index(conn)];
105 
106 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
107 	if (index == BT_TBS_GTBS_INDEX) {
108 		return &server->gtbs_inst;
109 	}
110 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
111 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
112 	if (index < server->inst_cnt) {
113 		return &server->tbs_insts[index];
114 	}
115 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
116 
117 	return NULL;
118 }
119 
tbs_index(struct bt_conn * conn,const struct bt_tbs_instance * inst)120 static uint8_t tbs_index(struct bt_conn *conn, const struct bt_tbs_instance *inst)
121 {
122 	struct bt_tbs_server_inst *server;
123 	ptrdiff_t index = 0;
124 
125 	__ASSERT_NO_MSG(conn);
126 	__ASSERT_NO_MSG(inst);
127 
128 	server = &srv_insts[bt_conn_index(conn)];
129 
130 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
131 	if (inst == &server->gtbs_inst) {
132 		return BT_TBS_GTBS_INDEX;
133 	}
134 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
135 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
136 	index = inst - server->tbs_insts;
137 	__ASSERT(index >= 0 && index < ARRAY_SIZE(server->tbs_insts),
138 		 "Invalid bt_tbs_instance pointer");
139 
140 #else
141 	__ASSERT_PRINT("Invalid bt_tbs_instance pointer");
142 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
143 
144 	return (uint8_t)index;
145 }
146 
147 #if defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL)
free_call_spot(struct bt_tbs_instance * inst)148 static bool free_call_spot(struct bt_tbs_instance *inst)
149 {
150 	for (int i = 0; i < CONFIG_BT_TBS_CLIENT_MAX_CALLS; i++) {
151 		if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
152 			return true;
153 		}
154 	}
155 
156 	return false;
157 }
158 #endif /* defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL) */
159 
is_instance_handle(struct bt_tbs_instance * inst,void * user_data)160 static bool is_instance_handle(struct bt_tbs_instance *inst, void *user_data)
161 {
162 	uint16_t handle = POINTER_TO_UINT(user_data);
163 
164 	return inst->start_handle <= handle && inst->end_handle >= handle;
165 }
166 
lookup_inst_by_handle(struct bt_conn * conn,uint16_t handle)167 static struct bt_tbs_instance *lookup_inst_by_handle(struct bt_conn *conn,
168 							 uint16_t handle)
169 {
170 	uint8_t conn_index;
171 	struct bt_tbs_server_inst *srv_inst;
172 	struct bt_tbs_instance *inst;
173 
174 	__ASSERT(conn, "NULL conn");
175 
176 	conn_index = bt_conn_index(conn);
177 	srv_inst = &srv_insts[conn_index];
178 
179 	inst = tbs_instance_find(srv_inst, is_instance_handle, UINT_TO_POINTER(handle));
180 	if (inst != NULL) {
181 		return inst;
182 	}
183 
184 	LOG_DBG("Could not find instance with handle 0x%04x", handle);
185 
186 	return NULL;
187 }
188 
net_buf_pull_call_state(struct net_buf_simple * buf,struct bt_tbs_client_call_state * call_state)189 static uint8_t net_buf_pull_call_state(struct net_buf_simple *buf,
190 				       struct bt_tbs_client_call_state *call_state)
191 {
192 	if (buf->len < sizeof(*call_state)) {
193 		LOG_DBG("Invalid buffer length %u", buf->len);
194 		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
195 	}
196 
197 	call_state->index = net_buf_simple_pull_u8(buf);
198 	call_state->state = net_buf_simple_pull_u8(buf);
199 	call_state->flags = net_buf_simple_pull_u8(buf);
200 
201 	return 0;
202 }
203 
204 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
net_buf_pull_call(struct net_buf_simple * buf,struct bt_tbs_client_call * call)205 static uint8_t net_buf_pull_call(struct net_buf_simple *buf,
206 				 struct bt_tbs_client_call *call)
207 {
208 	const size_t min_item_len = sizeof(call->call_info) + BT_TBS_MIN_URI_LEN;
209 	uint8_t item_len;
210 	uint8_t uri_len;
211 	uint8_t err;
212 	uint8_t *uri;
213 
214 	__ASSERT(buf, "NULL buf");
215 	__ASSERT(call, "NULL call");
216 
217 	if (buf->len < sizeof(item_len) + min_item_len) {
218 		LOG_DBG("Invalid buffer length %u", buf->len);
219 		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
220 	}
221 
222 	item_len = net_buf_simple_pull_u8(buf);
223 	uri_len = item_len - sizeof(call->call_info);
224 
225 	if (item_len > buf->len || item_len < min_item_len) {
226 		LOG_DBG("Invalid current call item length %u", item_len);
227 		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
228 	}
229 
230 	err = net_buf_pull_call_state(buf, &call->call_info);
231 	if (err != 0) {
232 		return err;
233 	}
234 
235 	uri = net_buf_simple_pull_mem(buf, uri_len);
236 	if (uri_len > CONFIG_BT_TBS_MAX_URI_LENGTH) {
237 		LOG_WRN("Current call (index %u) uri length larger than supported %u/%zu",
238 			call->call_info.index, uri_len, CONFIG_BT_TBS_MAX_URI_LENGTH);
239 		return BT_ATT_ERR_INSUFFICIENT_RESOURCES;
240 	}
241 
242 	(void)memcpy(call->remote_uri, uri, uri_len);
243 	call->remote_uri[uri_len] = '\0';
244 
245 	return 0;
246 }
247 
current_calls_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_count,const struct bt_tbs_client_call * calls)248 static void current_calls_changed(struct bt_conn *conn, int err, uint8_t inst_index,
249 				  uint8_t call_count, const struct bt_tbs_client_call *calls)
250 {
251 	struct bt_tbs_client_cb *listener, *next;
252 
253 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
254 		if (listener->current_calls != NULL) {
255 			listener->current_calls(conn, err, inst_index, call_count, calls);
256 		}
257 	}
258 }
259 
bearer_list_current_calls(struct bt_conn * conn,const struct bt_tbs_instance * inst,struct net_buf_simple * buf)260 static void bearer_list_current_calls(struct bt_conn *conn, const struct bt_tbs_instance *inst,
261 				      struct net_buf_simple *buf)
262 {
263 	struct bt_tbs_client_call calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
264 	char remote_uris[CONFIG_BT_TBS_CLIENT_MAX_CALLS][CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
265 	uint8_t cnt = 0;
266 	int err;
267 
268 	while (buf->len) {
269 		struct bt_tbs_client_call *call;
270 
271 		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
272 			LOG_WRN("Could not parse all calls due to memory restrictions");
273 			break;
274 		}
275 
276 		call = &calls[cnt];
277 		call->remote_uri = remote_uris[cnt];
278 
279 		err = net_buf_pull_call(buf, call);
280 		if (err == BT_ATT_ERR_INSUFFICIENT_RESOURCES) {
281 			LOG_WRN("Call with skipped due to too long URI");
282 			continue;
283 		} else if (err != 0) {
284 			LOG_DBG("Invalid current call notification: %d", err);
285 			return;
286 		}
287 
288 		cnt++;
289 	}
290 
291 	current_calls_changed(conn, 0, tbs_index(conn, inst), cnt, calls);
292 }
293 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
294 
295 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
call_cp_callback_handler(struct bt_conn * conn,int err,uint8_t index,uint8_t opcode,uint8_t call_index)296 static void call_cp_callback_handler(struct bt_conn *conn, int err,
297 				     uint8_t index, uint8_t opcode,
298 				     uint8_t call_index)
299 {
300 	struct bt_tbs_client_cb *listener, *next;
301 
302 	LOG_DBG("Status: %s for the %s opcode for call 0x%02x", bt_tbs_status_str(err),
303 		bt_tbs_opcode_str(opcode), call_index);
304 
305 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
306 		switch (opcode) {
307 #if defined(CONFIG_BT_TBS_CLIENT_ACCEPT_CALL)
308 		case BT_TBS_CALL_OPCODE_ACCEPT:
309 			if (listener->accept_call != NULL) {
310 				listener->accept_call(conn, err, index, call_index);
311 			}
312 			break;
313 #endif /* defined(CONFIG_BT_TBS_CLIENT_ACCEPT_CALL) */
314 #if defined(CONFIG_BT_TBS_CLIENT_TERMINATE_CALL)
315 		case BT_TBS_CALL_OPCODE_TERMINATE:
316 			if (listener->terminate_call != NULL) {
317 				listener->terminate_call(conn, err, index, call_index);
318 			}
319 			break;
320 #endif /* defined(CONFIG_BT_TBS_CLIENT_TERMINATE_CALL) */
321 #if defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL)
322 		case BT_TBS_CALL_OPCODE_HOLD:
323 			if (listener->hold_call != NULL) {
324 				listener->hold_call(conn, err, index, call_index);
325 			}
326 			break;
327 #endif /* defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL) */
328 #if defined(CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL)
329 		case BT_TBS_CALL_OPCODE_RETRIEVE:
330 			if (listener->retrieve_call != NULL) {
331 				listener->retrieve_call(conn, err, index, call_index);
332 			}
333 			break;
334 #endif /* defined(CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL) */
335 #if defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL)
336 		case BT_TBS_CALL_OPCODE_ORIGINATE:
337 			if (listener->originate_call != NULL) {
338 				listener->originate_call(conn, err, index, call_index);
339 			}
340 			break;
341 #endif /* defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL) */
342 #if defined(CONFIG_BT_TBS_CLIENT_JOIN_CALLS)
343 		case BT_TBS_CALL_OPCODE_JOIN:
344 			if (listener->join_calls != NULL) {
345 				listener->join_calls(conn, err, index, call_index);
346 			}
347 			break;
348 #endif /* defined(CONFIG_BT_TBS_CLIENT_JOIN_CALLS) */
349 		default:
350 			break;
351 		}
352 	}
353 }
354 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
355 
parse_string_value(const void * data,uint16_t length,uint16_t max_len)356 const char *parse_string_value(const void *data, uint16_t length,
357 				      uint16_t max_len)
358 {
359 	static char string_val[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
360 	const size_t len = MIN(length, max_len);
361 
362 	if (len != 0) {
363 		(void)memcpy(string_val, data, len);
364 	}
365 
366 	string_val[len] = '\0';
367 
368 	return string_val;
369 }
370 
371 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
provider_name_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * name)372 static void provider_name_changed(struct bt_conn *conn, int err, uint8_t inst_index,
373 				  const char *name)
374 {
375 	struct bt_tbs_client_cb *listener, *next;
376 
377 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
378 		if (listener->bearer_provider_name != NULL) {
379 			listener->bearer_provider_name(conn, err, inst_index, name);
380 		}
381 	}
382 }
383 
provider_name_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)384 static void provider_name_notify_handler(struct bt_conn *conn,
385 					 const struct bt_tbs_instance *tbs_inst,
386 					 const void *data, uint16_t length)
387 {
388 	const char *name = parse_string_value(data, length,
389 					      CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH);
390 
391 	LOG_DBG("%s", name);
392 
393 	provider_name_changed(conn, 0, tbs_index(conn, tbs_inst), name);
394 }
395 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
396 
397 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
technology_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t technology)398 static void technology_changed(struct bt_conn *conn, int err, uint8_t inst_index,
399 			       uint8_t technology)
400 {
401 	struct bt_tbs_client_cb *listener, *next;
402 
403 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
404 		if (listener->technology != NULL) {
405 			listener->technology(conn, err, inst_index, technology);
406 		}
407 	}
408 }
409 
technology_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)410 static void technology_notify_handler(struct bt_conn *conn,
411 				      const struct bt_tbs_instance *tbs_inst,
412 				      const void *data, uint16_t length)
413 {
414 	uint8_t technology;
415 
416 	LOG_DBG("");
417 
418 	if (length == sizeof(technology)) {
419 		(void)memcpy(&technology, data, length);
420 		LOG_DBG("%s (0x%02x)", bt_tbs_technology_str(technology), technology);
421 
422 		technology_changed(conn, 0, tbs_index(conn, tbs_inst), technology);
423 	}
424 }
425 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
426 
427 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
signal_strength_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t signal_strength)428 static void signal_strength_changed(struct bt_conn *conn, int err, uint8_t inst_index,
429 				    uint8_t signal_strength)
430 {
431 	struct bt_tbs_client_cb *listener, *next;
432 
433 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
434 		if (listener->signal_strength != NULL) {
435 			listener->signal_strength(conn, err, inst_index, signal_strength);
436 		}
437 	}
438 }
439 
signal_strength_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)440 static void signal_strength_notify_handler(struct bt_conn *conn,
441 					   const struct bt_tbs_instance *tbs_inst,
442 					   const void *data, uint16_t length)
443 {
444 	uint8_t signal_strength;
445 
446 	LOG_DBG("");
447 
448 	if (length == sizeof(signal_strength)) {
449 		(void)memcpy(&signal_strength, data, length);
450 		LOG_DBG("0x%02x", signal_strength);
451 
452 		signal_strength_changed(conn, 0, tbs_index(conn, tbs_inst), signal_strength);
453 	}
454 }
455 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
456 
457 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
current_calls_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)458 static void current_calls_notify_handler(struct bt_conn *conn,
459 					 const struct bt_tbs_instance *tbs_inst,
460 					 const void *data, uint16_t length)
461 {
462 	struct net_buf_simple buf;
463 
464 	LOG_DBG("");
465 
466 	net_buf_simple_init_with_data(&buf, (void *)data, length);
467 
468 	/* TODO: If length == MTU, do long read for all calls */
469 
470 	bearer_list_current_calls(conn, tbs_inst, &buf);
471 }
472 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
473 
474 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
status_flags_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint16_t status_flags)475 static void status_flags_changed(struct bt_conn *conn, int err, uint8_t inst_index,
476 				 uint16_t status_flags)
477 {
478 	struct bt_tbs_client_cb *listener, *next;
479 
480 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
481 		if (listener->status_flags != NULL) {
482 			listener->status_flags(conn, err, inst_index, status_flags);
483 		}
484 	}
485 }
486 
status_flags_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)487 static void status_flags_notify_handler(struct bt_conn *conn,
488 					const struct bt_tbs_instance *tbs_inst,
489 					const void *data, uint16_t length)
490 {
491 	uint16_t status_flags;
492 
493 	LOG_DBG("");
494 
495 	if (length == sizeof(status_flags)) {
496 		(void)memcpy(&status_flags, data, length);
497 		LOG_DBG("0x%04x", status_flags);
498 
499 		status_flags_changed(conn, 0, tbs_index(conn, tbs_inst), status_flags);
500 	}
501 }
502 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
503 
504 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
call_uri_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * call_uri)505 static void call_uri_changed(struct bt_conn *conn, int err, uint8_t inst_index,
506 			     const char *call_uri)
507 {
508 	struct bt_tbs_client_cb *listener, *next;
509 
510 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
511 		if (listener->call_uri != NULL) {
512 			listener->call_uri(conn, err, inst_index, call_uri);
513 		}
514 	}
515 }
516 
incoming_uri_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)517 static void incoming_uri_notify_handler(struct bt_conn *conn,
518 					const struct bt_tbs_instance *tbs_inst,
519 					const void *data, uint16_t length)
520 {
521 	const char *uri = parse_string_value(data, length,
522 					     CONFIG_BT_TBS_MAX_URI_LENGTH);
523 
524 	LOG_DBG("%s", uri);
525 
526 	call_uri_changed(conn, 0, tbs_index(conn, tbs_inst), uri);
527 }
528 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
529 
call_state_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t call_count,const struct bt_tbs_client_call_state * call_states)530 static void call_state_changed(struct bt_conn *conn, int err, uint8_t inst_index,
531 			       uint8_t call_count,
532 			       const struct bt_tbs_client_call_state *call_states)
533 {
534 	struct bt_tbs_client_cb *listener, *next;
535 
536 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
537 		if (listener->call_state != NULL) {
538 			listener->call_state(conn, err, inst_index, call_count, call_states);
539 		}
540 	}
541 }
542 
call_state_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)543 static void call_state_notify_handler(struct bt_conn *conn,
544 				      const struct bt_tbs_instance *tbs_inst,
545 				      const void *data, uint16_t length)
546 {
547 	struct bt_tbs_client_call_state call_states[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
548 	uint8_t cnt = 0;
549 	struct net_buf_simple buf;
550 
551 	LOG_DBG("");
552 
553 	net_buf_simple_init_with_data(&buf, (void *)data, length);
554 
555 	/* TODO: If length == MTU, do long read for all call states */
556 
557 	while (buf.len) {
558 		struct bt_tbs_client_call_state *call_state;
559 		int err;
560 
561 		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
562 			LOG_WRN("Could not parse all calls due to memory restrictions");
563 			break;
564 		}
565 
566 		call_state = &call_states[cnt];
567 
568 		err = net_buf_pull_call_state(&buf, call_state);
569 		if (err != 0) {
570 			LOG_DBG("Invalid current call notification: %d", err);
571 			return;
572 		}
573 
574 		cnt++;
575 	}
576 
577 	call_state_changed(conn, 0, tbs_index(conn, tbs_inst), cnt, call_states);
578 }
579 
580 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
call_cp_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)581 static void call_cp_notify_handler(struct bt_conn *conn,
582 				  const struct bt_tbs_instance *tbs_inst,
583 				  const void *data, uint16_t length)
584 {
585 	struct bt_tbs_call_cp_notify *ind_val;
586 
587 	LOG_DBG("");
588 
589 	if (length == sizeof(*ind_val)) {
590 		ind_val = (struct bt_tbs_call_cp_notify *)data;
591 		LOG_DBG("Status: %s for the %s opcode for call 0x%02X",
592 			bt_tbs_status_str(ind_val->status), bt_tbs_opcode_str(ind_val->opcode),
593 			ind_val->call_index);
594 
595 		call_cp_callback_handler(conn, ind_val->status, tbs_index(conn, tbs_inst),
596 					 ind_val->opcode, ind_val->call_index);
597 	}
598 }
599 #endif /* defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES) */
600 
terminate_reason_changed(struct bt_conn * conn,int err,uint8_t inst_index,struct bt_tbs_terminate_reason reason)601 static void terminate_reason_changed(struct bt_conn *conn, int err, uint8_t inst_index,
602 				     struct bt_tbs_terminate_reason reason)
603 {
604 	struct bt_tbs_client_cb *listener, *next;
605 
606 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
607 		if (listener->termination_reason != NULL) {
608 			listener->termination_reason(conn, err, inst_index, reason.call_index,
609 						     reason.reason);
610 		}
611 	}
612 }
613 
termination_reason_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)614 static void termination_reason_notify_handler(struct bt_conn *conn,
615 					      const struct bt_tbs_instance *tbs_inst,
616 					      const void *data, uint16_t length)
617 {
618 	struct bt_tbs_terminate_reason reason;
619 
620 	LOG_DBG("");
621 
622 	if (length == sizeof(reason)) {
623 		(void)memcpy(&reason, data, length);
624 		LOG_DBG("ID 0x%02X, reason %s", reason.call_index,
625 			bt_tbs_term_reason_str(reason.reason));
626 
627 		terminate_reason_changed(conn, 0, tbs_index(conn, tbs_inst), reason);
628 	}
629 }
630 
631 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
remote_uri_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * remote_uri)632 static void remote_uri_changed(struct bt_conn *conn, int err, uint8_t inst_index,
633 			       const char *remote_uri)
634 {
635 	struct bt_tbs_client_cb *listener, *next;
636 
637 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
638 		if (listener->remote_uri != NULL) {
639 			listener->remote_uri(conn, err, inst_index, remote_uri);
640 		}
641 	}
642 }
643 
in_call_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)644 static void in_call_notify_handler(struct bt_conn *conn,
645 				   const struct bt_tbs_instance *tbs_inst,
646 				   const void *data, uint16_t length)
647 {
648 	const char *uri = parse_string_value(data, length,
649 					     CONFIG_BT_TBS_MAX_URI_LENGTH);
650 
651 	LOG_DBG("%s", uri);
652 
653 	remote_uri_changed(conn, 0, tbs_index(conn, tbs_inst), uri);
654 }
655 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
656 
657 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
friendly_name_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * friendly_name)658 static void friendly_name_changed(struct bt_conn *conn, int err, uint8_t inst_index,
659 				  const char *friendly_name)
660 {
661 	struct bt_tbs_client_cb *listener, *next;
662 
663 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
664 		if (listener->friendly_name != NULL) {
665 			listener->friendly_name(conn, err, inst_index, friendly_name);
666 		}
667 	}
668 }
669 
friendly_name_notify_handler(struct bt_conn * conn,const struct bt_tbs_instance * tbs_inst,const void * data,uint16_t length)670 static void friendly_name_notify_handler(struct bt_conn *conn,
671 					 const struct bt_tbs_instance *tbs_inst,
672 					 const void *data, uint16_t length)
673 {
674 	const char *name = parse_string_value(data, length,
675 					      CONFIG_BT_TBS_MAX_URI_LENGTH);
676 
677 	LOG_DBG("%s", name);
678 
679 	friendly_name_changed(conn, 0, tbs_index(conn, tbs_inst), name);
680 }
681 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
682 
683 /** @brief Handles notifications and indications from the server */
notify_handler(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)684 static uint8_t notify_handler(struct bt_conn *conn,
685 			      struct bt_gatt_subscribe_params *params,
686 			      const void *data, uint16_t length)
687 {
688 	uint16_t handle = params->value_handle;
689 	struct bt_tbs_instance *tbs_inst;
690 
691 	if (data == NULL || conn == NULL) {
692 		LOG_DBG("[UNSUBSCRIBED] 0x%04X", params->value_handle);
693 		params->value_handle = 0U;
694 
695 		return BT_GATT_ITER_STOP;
696 	}
697 
698 	tbs_inst = lookup_inst_by_handle(conn, handle);
699 	if (tbs_inst != NULL) {
700 		uint8_t inst_index = tbs_index(conn, tbs_inst);
701 
702 		LOG_DBG("Index %u", inst_index);
703 
704 		LOG_HEXDUMP_DBG(data, length, "notify handler value");
705 
706 		if (handle == tbs_inst->call_state_sub_params.value_handle) {
707 			call_state_notify_handler(conn, tbs_inst, data, length);
708 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
709 		} else if (handle == tbs_inst->name_sub_params.value_handle) {
710 			provider_name_notify_handler(conn, tbs_inst, data,
711 						     length);
712 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
713 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
714 		} else if (handle == tbs_inst->technology_sub_params.value_handle) {
715 			technology_notify_handler(conn, tbs_inst, data, length);
716 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
717 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
718 		} else if (handle == tbs_inst->signal_strength_sub_params.value_handle) {
719 			signal_strength_notify_handler(conn, tbs_inst, data,
720 						       length);
721 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
722 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
723 		} else if (handle == tbs_inst->status_flags_sub_params.value_handle) {
724 			status_flags_notify_handler(conn, tbs_inst, data,
725 						    length);
726 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
727 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
728 		} else if (handle == tbs_inst->current_calls_sub_params.value_handle) {
729 			current_calls_notify_handler(conn, tbs_inst, data,
730 						     length);
731 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
732 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
733 		} else if (handle == tbs_inst->in_target_uri_sub_params.value_handle) {
734 			incoming_uri_notify_handler(conn, tbs_inst, data,
735 						    length);
736 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
737 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
738 		} else if (handle == tbs_inst->call_cp_sub_params.value_handle) {
739 			call_cp_notify_handler(conn, tbs_inst, data, length);
740 #endif /* defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES) */
741 		} else if (handle == tbs_inst->termination_reason_handle) {
742 			termination_reason_notify_handler(conn, tbs_inst, data,
743 							  length);
744 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
745 		} else if (handle == tbs_inst->incoming_call_sub_params.value_handle) {
746 			in_call_notify_handler(conn, tbs_inst, data, length);
747 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
748 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
749 		} else if (handle == tbs_inst->friendly_name_sub_params.value_handle) {
750 			friendly_name_notify_handler(conn, tbs_inst, data,
751 						     length);
752 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
753 		}
754 	} else {
755 		LOG_DBG("Notification/Indication on unknown TBS inst");
756 	}
757 
758 	return BT_GATT_ITER_CONTINUE;
759 }
760 
initialize_net_buf_read_buffer(struct bt_tbs_instance * inst)761 static void initialize_net_buf_read_buffer(struct bt_tbs_instance *inst)
762 {
763 	net_buf_simple_init_with_data(&inst->net_buf, &inst->read_buf,
764 				      sizeof(inst->read_buf));
765 	net_buf_simple_reset(&inst->net_buf);
766 }
767 
tbs_client_gatt_read_complete(struct bt_tbs_instance * inst)768 static void tbs_client_gatt_read_complete(struct bt_tbs_instance *inst)
769 {
770 	(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
771 	atomic_clear_bit(inst->flags, BT_TBS_CLIENT_FLAG_BUSY);
772 }
773 
tbs_client_gatt_read(struct bt_conn * conn,struct bt_tbs_instance * inst,uint16_t handle,bt_gatt_read_func_t func)774 static int tbs_client_gatt_read(struct bt_conn *conn, struct bt_tbs_instance *inst, uint16_t handle,
775 				bt_gatt_read_func_t func)
776 {
777 	int err;
778 
779 	if (atomic_test_and_set_bit(inst->flags, BT_TBS_CLIENT_FLAG_BUSY)) {
780 		LOG_DBG("Instance is busy");
781 
782 		return -EBUSY;
783 	}
784 
785 	/* Use read_buf; length may be larger than minimum BT_ATT_MTU */
786 	initialize_net_buf_read_buffer(inst);
787 	inst->read_params.func = func;
788 	inst->read_params.handle_count = 1U;
789 	inst->read_params.single.handle = handle;
790 	inst->read_params.single.offset = 0U;
791 
792 	err = bt_gatt_read(conn, &inst->read_params);
793 	if (err != 0) {
794 		tbs_client_gatt_read_complete(inst);
795 
796 		return err;
797 	}
798 
799 	return 0;
800 }
801 
gtbs_found(struct bt_tbs_server_inst * srv_inst)802 static bool gtbs_found(struct bt_tbs_server_inst *srv_inst)
803 {
804 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
805 	return srv_inst->gtbs_inst.start_handle != 0;
806 #else
807 	return false;
808 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
809 }
810 
inst_cnt(struct bt_tbs_server_inst * srv_inst)811 static uint8_t inst_cnt(struct bt_tbs_server_inst *srv_inst)
812 {
813 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
814 	return srv_inst->inst_cnt;
815 #else
816 	return 0;
817 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
818 }
819 
tbs_client_discover_complete(struct bt_conn * conn,int err)820 static void tbs_client_discover_complete(struct bt_conn *conn, int err)
821 {
822 	struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
823 	struct bt_tbs_client_cb *listener, *next;
824 
825 	LOG_DBG("conn %p err %d", (void *)conn, err);
826 
827 	/* Clear the current instance in discovery */
828 	srv_inst->current_inst = NULL;
829 
830 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
831 	atomic_clear_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY);
832 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
833 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
834 	for (size_t i = 0U; i < ARRAY_SIZE(srv_inst->tbs_insts); i++) {
835 		atomic_clear_bit(srv_inst->tbs_insts[i].flags, BT_TBS_CLIENT_FLAG_BUSY);
836 	}
837 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
838 
839 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
840 		if (listener->discover != NULL) {
841 			listener->discover(conn, err, inst_cnt(srv_inst), gtbs_found(srv_inst));
842 		}
843 	}
844 }
845 
846 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) ||                                          \
847 	defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) ||                                                \
848 	defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) ||                         \
849 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) ||                                              \
850 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) ||                                             \
851 	defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
852 
can_add_string_to_net_buf(const struct net_buf_simple * buf,size_t len)853 static bool can_add_string_to_net_buf(const struct net_buf_simple *buf, size_t len)
854 {
855 	return buf->len + len + sizeof('\0') <= buf->size;
856 }
857 
858 /**
859  * Common function to read tbs_client strings which may require long reads
860  *
861  * @return BT_GATT_ITER_CONTINUE, BT_GATT_ITER_STOP or a negative value if there's an error
862  */
handle_string_long_read(struct bt_tbs_instance * inst,uint8_t err,const void * data,uint16_t offset,uint16_t length,bool truncatable)863 static int handle_string_long_read(struct bt_tbs_instance *inst, uint8_t err, const void *data,
864 				   uint16_t offset, uint16_t length, bool truncatable)
865 {
866 	if (err != 0) {
867 		LOG_DBG("err: %u", err);
868 
869 		return BT_GATT_ERR(err);
870 	}
871 
872 	if (data != NULL) {
873 		/* Get data and try to read more using read long procedure */
874 		LOG_DBG("Read (offset %u): %s", offset, bt_hex(data, length));
875 
876 		if (!can_add_string_to_net_buf(&inst->net_buf, length)) {
877 			LOG_DBG("Read length %u: String buffer full", length);
878 			if (truncatable) {
879 				/* Use the remaining buffer and stop reading and leave room for NULL
880 				 * terminator
881 				 */
882 				LOG_DBG("Truncating string");
883 				length = net_buf_simple_tailroom(&inst->net_buf) - sizeof('\0');
884 				net_buf_simple_add_mem(&inst->net_buf, data, length);
885 
886 				/* Ensure that the data is correctly truncated */
887 				utf8_trunc(inst->net_buf.data);
888 			} else {
889 				return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
890 			}
891 		} else {
892 			net_buf_simple_add_mem(&inst->net_buf, data, length);
893 
894 			return BT_GATT_ITER_CONTINUE;
895 		}
896 	} /* else we are done reading and since the buffer is always 0-initialized, it will have the
897 	   *  NULL terminator automatically
898 	   */
899 
900 	return BT_GATT_ITER_STOP;
901 }
902 #endif /* CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME ||                                             \
903 	* CONFIG_BT_TBS_CLIENT_BEARER_UCI ||                                                       \
904 	* CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST ||                                \
905 	* CONFIG_BT_TBS_CLIENT_INCOMING_URI ||                                                     \
906 	* CONFIG_BT_TBS_CLIENT_INCOMING_CALL ||                                                    \
907 	* CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME                                                  \
908 	*/
909 
910 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
tbs_client_common_call_control(struct bt_conn * conn,uint8_t inst_index,uint8_t call_index,uint8_t opcode)911 static int tbs_client_common_call_control(struct bt_conn *conn,
912 					  uint8_t inst_index,
913 					  uint8_t call_index,
914 					  uint8_t opcode)
915 {
916 	struct bt_tbs_instance *inst;
917 	struct bt_tbs_call_cp_acc common;
918 
919 	inst = tbs_inst_by_index(conn, inst_index);
920 	if (inst == NULL) {
921 		return -EINVAL;
922 	}
923 
924 	if (inst->call_cp_sub_params.value_handle == 0) {
925 		LOG_DBG("Handle not set");
926 		return -EINVAL;
927 	}
928 
929 	common.opcode = opcode;
930 	common.call_index = call_index;
931 
932 	return bt_gatt_write_without_response(conn, inst->call_cp_sub_params.value_handle,
933 					      &common, sizeof(common), false);
934 }
935 #endif /* CONFIG_BT_TBS_CLIENT_CP_PROCEDURES */
936 
937 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
read_bearer_provider_name_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)938 static uint8_t read_bearer_provider_name_cb(struct bt_conn *conn, uint8_t err,
939 					    struct bt_gatt_read_params *params,
940 					    const void *data, uint16_t length)
941 {
942 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
943 	const uint8_t inst_index = tbs_index(conn, inst);
944 	int ret;
945 
946 	LOG_DBG("");
947 
948 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
949 	if (ret != BT_GATT_ITER_CONTINUE) {
950 		if (ret == BT_GATT_ITER_STOP) {
951 			/* At this point the inst->net_buf.data contains a NULL terminator string */
952 			provider_name_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
953 		} else {
954 			provider_name_changed(conn, ret, inst_index, NULL);
955 		}
956 
957 		tbs_client_gatt_read_complete(inst);
958 
959 		return BT_GATT_ITER_STOP;
960 	}
961 
962 	return BT_GATT_ITER_CONTINUE;
963 }
964 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
965 
966 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
bearer_uci_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * uci)967 static void bearer_uci_changed(struct bt_conn *conn, int err, uint8_t inst_index, const char *uci)
968 {
969 	struct bt_tbs_client_cb *listener, *next;
970 
971 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
972 		if (listener->bearer_uci != NULL) {
973 			listener->bearer_uci(conn, err, inst_index, uci);
974 		}
975 	}
976 }
977 
read_bearer_uci_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)978 static uint8_t read_bearer_uci_cb(struct bt_conn *conn, uint8_t err,
979 				   struct bt_gatt_read_params *params,
980 				   const void *data, uint16_t length)
981 {
982 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
983 	const uint8_t inst_index = tbs_index(conn, inst);
984 	int ret;
985 
986 	LOG_DBG("");
987 
988 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
989 	if (ret != BT_GATT_ITER_CONTINUE) {
990 		if (ret == BT_GATT_ITER_STOP) {
991 			/* At this point the inst->net_buf.data contains a NULL terminator string */
992 			bearer_uci_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
993 		} else {
994 			bearer_uci_changed(conn, ret, inst_index, NULL);
995 		}
996 
997 		tbs_client_gatt_read_complete(inst);
998 
999 		return BT_GATT_ITER_STOP;
1000 	}
1001 
1002 	return BT_GATT_ITER_CONTINUE;
1003 }
1004 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
1005 
1006 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
read_technology_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1007 static uint8_t read_technology_cb(struct bt_conn *conn, uint8_t err,
1008 				   struct bt_gatt_read_params *params,
1009 				   const void *data, uint16_t length)
1010 {
1011 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1012 						    struct bt_tbs_instance,
1013 						    read_params);
1014 	uint8_t inst_index = tbs_index(conn, inst);
1015 	uint8_t cb_err = err;
1016 	uint8_t technology = 0;
1017 
1018 	LOG_DBG("Index %u", inst_index);
1019 
1020 	if (err != 0) {
1021 		LOG_DBG("err: 0x%02X", err);
1022 	} else if (data != NULL) {
1023 		LOG_HEXDUMP_DBG(data, length, "Data read");
1024 		if (length == sizeof(technology)) {
1025 			(void)memcpy(&technology, data, length);
1026 			LOG_DBG("%s (0x%02x)", bt_tbs_technology_str(technology), technology);
1027 		} else {
1028 			LOG_DBG("Invalid length");
1029 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1030 		}
1031 	}
1032 
1033 	tbs_client_gatt_read_complete(inst);
1034 
1035 	technology_changed(conn, cb_err, inst_index, technology);
1036 
1037 	return BT_GATT_ITER_STOP;
1038 }
1039 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
1040 
1041 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
uri_list_changed(struct bt_conn * conn,int err,uint8_t inst_index,const char * uri_list)1042 static void uri_list_changed(struct bt_conn *conn, int err, uint8_t inst_index,
1043 			     const char *uri_list)
1044 {
1045 	struct bt_tbs_client_cb *listener, *next;
1046 
1047 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
1048 		if (listener->uri_list != NULL) {
1049 			listener->uri_list(conn, err, inst_index, uri_list);
1050 		}
1051 	}
1052 }
1053 
read_uri_list_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1054 static uint8_t read_uri_list_cb(struct bt_conn *conn, uint8_t err,
1055 				    struct bt_gatt_read_params *params,
1056 				    const void *data, uint16_t length)
1057 {
1058 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1059 	const uint8_t inst_index = tbs_index(conn, inst);
1060 	int ret;
1061 
1062 	LOG_DBG("");
1063 
1064 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
1065 	if (ret != BT_GATT_ITER_CONTINUE) {
1066 		if (ret == BT_GATT_ITER_STOP) {
1067 			/* At this point the inst->net_buf.data contains a NULL terminator string */
1068 			uri_list_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
1069 		} else {
1070 			uri_list_changed(conn, ret, inst_index, NULL);
1071 		}
1072 
1073 		tbs_client_gatt_read_complete(inst);
1074 
1075 		return BT_GATT_ITER_STOP;
1076 	}
1077 
1078 	return BT_GATT_ITER_CONTINUE;
1079 }
1080 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
1081 
1082 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
read_signal_strength_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1083 static uint8_t read_signal_strength_cb(struct bt_conn *conn, uint8_t err,
1084 					struct bt_gatt_read_params *params,
1085 					const void *data, uint16_t length)
1086 {
1087 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1088 						    struct bt_tbs_instance,
1089 						    read_params);
1090 	uint8_t inst_index = tbs_index(conn, inst);
1091 	uint8_t cb_err = err;
1092 	uint8_t signal_strength = 0;
1093 
1094 	LOG_DBG("Index %u", inst_index);
1095 
1096 	if (err != 0) {
1097 		LOG_DBG("err: 0x%02X", err);
1098 	} else if (data != NULL) {
1099 		LOG_HEXDUMP_DBG(data, length, "Data read");
1100 		if (length == sizeof(signal_strength)) {
1101 			(void)memcpy(&signal_strength, data, length);
1102 			LOG_DBG("0x%02x", signal_strength);
1103 		} else {
1104 			LOG_DBG("Invalid length");
1105 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1106 		}
1107 	}
1108 
1109 	tbs_client_gatt_read_complete(inst);
1110 
1111 	signal_strength_changed(conn, cb_err, inst_index, signal_strength);
1112 
1113 	return BT_GATT_ITER_STOP;
1114 }
1115 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
1116 
1117 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL)
signal_interval_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t signal_interval)1118 static void signal_interval_changed(struct bt_conn *conn, int err, uint8_t inst_index,
1119 				    uint8_t signal_interval)
1120 {
1121 	struct bt_tbs_client_cb *listener, *next;
1122 
1123 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
1124 		if (listener->signal_interval != NULL) {
1125 			listener->signal_interval(conn, err, inst_index, signal_interval);
1126 		}
1127 	}
1128 }
1129 
read_signal_interval_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1130 static uint8_t read_signal_interval_cb(struct bt_conn *conn, uint8_t err,
1131 					struct bt_gatt_read_params *params,
1132 					const void *data, uint16_t length)
1133 {
1134 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1135 						    struct bt_tbs_instance,
1136 						    read_params);
1137 	uint8_t inst_index = tbs_index(conn, inst);
1138 	uint8_t cb_err = err;
1139 	uint8_t signal_interval = 0;
1140 
1141 	LOG_DBG("Index %u", inst_index);
1142 
1143 	if (err != 0) {
1144 		LOG_DBG("err: 0x%02X", err);
1145 	} else if (data != NULL) {
1146 		LOG_HEXDUMP_DBG(data, length, "Data read");
1147 		if (length == sizeof(signal_interval)) {
1148 			(void)memcpy(&signal_interval, data, length);
1149 			LOG_DBG("0x%02x", signal_interval);
1150 		} else {
1151 			LOG_DBG("Invalid length");
1152 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1153 		}
1154 	}
1155 
1156 	tbs_client_gatt_read_complete(inst);
1157 
1158 	signal_interval_changed(conn, cb_err, inst_index, signal_interval);
1159 
1160 	return BT_GATT_ITER_STOP;
1161 }
1162 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
1163 
1164 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
read_current_calls_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1165 static uint8_t read_current_calls_cb(struct bt_conn *conn, uint8_t err,
1166 				      struct bt_gatt_read_params *params,
1167 				      const void *data, uint16_t length)
1168 {
1169 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1170 						    struct bt_tbs_instance,
1171 						    read_params);
1172 	uint8_t inst_index = tbs_index(conn, inst);
1173 	int tbs_err = err;
1174 
1175 	LOG_DBG("Read bearer list current calls, index %u", inst_index);
1176 
1177 	if ((tbs_err == 0) && (data != NULL) &&
1178 	    (net_buf_simple_tailroom(&inst->net_buf) < length)) {
1179 		tbs_err = BT_ATT_ERR_INSUFFICIENT_RESOURCES;
1180 	}
1181 
1182 	if (tbs_err != 0) {
1183 		LOG_DBG("err: %d", tbs_err);
1184 
1185 		tbs_client_gatt_read_complete(inst);
1186 
1187 		current_calls_changed(conn, tbs_err, inst_index, 0, NULL);
1188 
1189 		return BT_GATT_ITER_STOP;
1190 	}
1191 
1192 	if (data != NULL) {
1193 		LOG_DBG("Current calls read (offset %u): %s",
1194 			params->single.offset,
1195 			bt_hex(data, length));
1196 
1197 		net_buf_simple_add_mem(&inst->net_buf, data, length);
1198 
1199 		/* Returning continue will try to read more using read
1200 		 * long procedure
1201 		 */
1202 		return BT_GATT_ITER_CONTINUE;
1203 	}
1204 
1205 	tbs_client_gatt_read_complete(inst);
1206 
1207 	if (inst->net_buf.len == 0) {
1208 		current_calls_changed(conn, 0, inst_index, 0, NULL);
1209 
1210 		return BT_GATT_ITER_STOP;
1211 	}
1212 
1213 	bearer_list_current_calls(conn, inst, &inst->net_buf);
1214 
1215 	return BT_GATT_ITER_STOP;
1216 }
1217 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
1218 
1219 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
ccid_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint8_t ccid)1220 static void ccid_changed(struct bt_conn *conn, int err, uint8_t inst_index, uint8_t ccid)
1221 {
1222 	struct bt_tbs_client_cb *listener, *next;
1223 
1224 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
1225 		if (listener->ccid != NULL) {
1226 			listener->ccid(conn, err, inst_index, ccid);
1227 		}
1228 	}
1229 }
1230 
read_ccid_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1231 static uint8_t read_ccid_cb(struct bt_conn *conn, uint8_t err,
1232 			    struct bt_gatt_read_params *params,
1233 			    const void *data, uint16_t length)
1234 {
1235 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1236 						    struct bt_tbs_instance,
1237 						    read_params);
1238 	uint8_t inst_index = tbs_index(conn, inst);
1239 	uint8_t cb_err = err;
1240 	uint8_t ccid = 0;
1241 
1242 	LOG_DBG("Index %u", inst_index);
1243 
1244 	if (err != 0) {
1245 		LOG_DBG("err: 0x%02X", err);
1246 	} else if (data != NULL) {
1247 		LOG_HEXDUMP_DBG(data, length, "Data read");
1248 		if (length == sizeof(ccid)) {
1249 			(void)memcpy(&ccid, data, length);
1250 			LOG_DBG("0x%02x", ccid);
1251 		} else {
1252 			LOG_DBG("Invalid length");
1253 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1254 		}
1255 	}
1256 
1257 	tbs_client_gatt_read_complete(inst);
1258 
1259 	ccid_changed(conn, cb_err, inst_index, ccid);
1260 
1261 	return BT_GATT_ITER_STOP;
1262 }
1263 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
1264 
1265 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
read_status_flags_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1266 static uint8_t read_status_flags_cb(struct bt_conn *conn, uint8_t err,
1267 				    struct bt_gatt_read_params *params,
1268 				    const void *data, uint16_t length)
1269 {
1270 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1271 						    struct bt_tbs_instance,
1272 						    read_params);
1273 	uint8_t inst_index = tbs_index(conn, inst);
1274 	uint8_t cb_err = err;
1275 	uint16_t status_flags = 0;
1276 
1277 	LOG_DBG("Index %u", inst_index);
1278 
1279 	if (err != 0) {
1280 		LOG_DBG("err: 0x%02X", err);
1281 	} else if (data != NULL) {
1282 		LOG_HEXDUMP_DBG(data, length, "Data read");
1283 		if (length == sizeof(status_flags)) {
1284 			(void)memcpy(&status_flags, data, length);
1285 			LOG_DBG("0x%04x", status_flags);
1286 		} else {
1287 			LOG_DBG("Invalid length");
1288 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1289 		}
1290 	}
1291 
1292 	tbs_client_gatt_read_complete(inst);
1293 
1294 	status_flags_changed(conn, cb_err, inst_index, status_flags);
1295 
1296 	return BT_GATT_ITER_STOP;
1297 }
1298 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
1299 
1300 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
read_call_uri_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1301 static uint8_t read_call_uri_cb(struct bt_conn *conn, uint8_t err,
1302 				struct bt_gatt_read_params *params,
1303 				const void *data, uint16_t length)
1304 {
1305 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1306 	const uint8_t inst_index = tbs_index(conn, inst);
1307 	int ret;
1308 
1309 	LOG_DBG("");
1310 
1311 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
1312 	if (ret != BT_GATT_ITER_CONTINUE) {
1313 		if (ret == BT_GATT_ITER_STOP) {
1314 			/* At this point the inst->net_buf.data contains a NULL terminator string */
1315 			call_uri_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
1316 		} else {
1317 			call_uri_changed(conn, ret, inst_index, NULL);
1318 		}
1319 
1320 		tbs_client_gatt_read_complete(inst);
1321 
1322 		return BT_GATT_ITER_STOP;
1323 	}
1324 
1325 	return BT_GATT_ITER_CONTINUE;
1326 }
1327 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
1328 
read_call_state_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1329 static uint8_t read_call_state_cb(struct bt_conn *conn, uint8_t err,
1330 				  struct bt_gatt_read_params *params,
1331 				  const void *data, uint16_t length)
1332 {
1333 	struct bt_tbs_instance *inst = CONTAINER_OF(params,
1334 						    struct bt_tbs_instance,
1335 						    read_params);
1336 	uint8_t inst_index = tbs_index(conn, inst);
1337 	uint8_t cnt = 0;
1338 	struct bt_tbs_client_call_state call_states[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
1339 	int tbs_err = err;
1340 
1341 	LOG_DBG("Index %u", inst_index);
1342 
1343 	if ((tbs_err == 0) && (data != NULL) &&
1344 	    (net_buf_simple_tailroom(&inst->net_buf) < length)) {
1345 		tbs_err = BT_ATT_ERR_INSUFFICIENT_RESOURCES;
1346 	}
1347 
1348 	if (tbs_err != 0) {
1349 		LOG_DBG("err: %d", tbs_err);
1350 
1351 		tbs_client_gatt_read_complete(inst);
1352 
1353 		call_state_changed(conn, tbs_err, inst_index, 0, NULL);
1354 
1355 		return BT_GATT_ITER_STOP;
1356 	}
1357 
1358 	if (data != NULL) {
1359 		LOG_DBG("Call states read (offset %u): %s", params->single.offset,
1360 			bt_hex(data, length));
1361 
1362 		net_buf_simple_add_mem(&inst->net_buf, data, length);
1363 
1364 		/* Returning continue will try to read more using read long procedure */
1365 		return BT_GATT_ITER_CONTINUE;
1366 	}
1367 
1368 	if (inst->net_buf.len == 0) {
1369 		tbs_client_gatt_read_complete(inst);
1370 
1371 		call_state_changed(conn, 0, inst_index, 0, NULL);
1372 
1373 		return BT_GATT_ITER_STOP;
1374 	}
1375 
1376 	/* Finished reading, start parsing */
1377 	while (inst->net_buf.len != 0) {
1378 		struct bt_tbs_client_call_state *call_state;
1379 
1380 		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
1381 			LOG_WRN("Could not parse all calls due to memory restrictions");
1382 			break;
1383 		}
1384 
1385 		call_state = &call_states[cnt];
1386 
1387 		tbs_err = net_buf_pull_call_state(&inst->net_buf, call_state);
1388 		if (tbs_err != 0) {
1389 			LOG_DBG("Invalid current call notification: %d", err);
1390 			break;
1391 		}
1392 
1393 		cnt++;
1394 	}
1395 
1396 	tbs_client_gatt_read_complete(inst);
1397 
1398 	call_state_changed(conn, tbs_err, inst_index, cnt, call_states);
1399 
1400 	return BT_GATT_ITER_STOP;
1401 }
1402 
1403 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
optional_opcodes_changed(struct bt_conn * conn,int err,uint8_t inst_index,uint16_t optional_opcodes)1404 static void optional_opcodes_changed(struct bt_conn *conn, int err, uint8_t inst_index,
1405 				     uint16_t optional_opcodes)
1406 {
1407 	struct bt_tbs_client_cb *listener, *next;
1408 
1409 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tbs_client_cbs, listener, next, _node) {
1410 		if (listener->optional_opcodes != NULL) {
1411 			listener->optional_opcodes(conn, err, inst_index, optional_opcodes);
1412 		}
1413 	}
1414 }
1415 
read_optional_opcodes_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1416 static uint8_t read_optional_opcodes_cb(struct bt_conn *conn, uint8_t err,
1417 					struct bt_gatt_read_params *params,
1418 					const void *data, uint16_t length)
1419 {
1420 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1421 	uint8_t inst_index = tbs_index(conn, inst);
1422 	uint8_t cb_err = err;
1423 	uint16_t optional_opcodes = 0;
1424 
1425 	LOG_DBG("Index %u", inst_index);
1426 
1427 	if (err != 0) {
1428 		LOG_DBG("err: 0x%02X", err);
1429 	} else if (data != NULL) {
1430 		LOG_HEXDUMP_DBG(data, length, "Data read");
1431 		if (length == sizeof(optional_opcodes)) {
1432 			(void)memcpy(&optional_opcodes, data, length);
1433 			LOG_DBG("0x%04x", optional_opcodes);
1434 		} else {
1435 			LOG_DBG("Invalid length");
1436 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1437 		}
1438 	}
1439 
1440 	tbs_client_gatt_read_complete(inst);
1441 
1442 	optional_opcodes_changed(conn, cb_err, inst_index, optional_opcodes);
1443 
1444 	return BT_GATT_ITER_STOP;
1445 }
1446 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
1447 
1448 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
read_remote_uri_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1449 static uint8_t read_remote_uri_cb(struct bt_conn *conn, uint8_t err,
1450 				  struct bt_gatt_read_params *params,
1451 				  const void *data, uint16_t length)
1452 {
1453 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1454 	const uint8_t inst_index = tbs_index(conn, inst);
1455 	int ret;
1456 
1457 	LOG_DBG("");
1458 
1459 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
1460 	if (ret != BT_GATT_ITER_CONTINUE) {
1461 		if (ret == BT_GATT_ITER_STOP) {
1462 			/* At this point the inst->net_buf.data contains a NULL terminator string */
1463 			remote_uri_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
1464 		} else {
1465 			remote_uri_changed(conn, ret, inst_index, NULL);
1466 		}
1467 
1468 		tbs_client_gatt_read_complete(inst);
1469 
1470 		return BT_GATT_ITER_STOP;
1471 	}
1472 
1473 	return BT_GATT_ITER_CONTINUE;
1474 }
1475 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
1476 
1477 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
read_friendly_name_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1478 static uint8_t read_friendly_name_cb(struct bt_conn *conn, uint8_t err,
1479 					 struct bt_gatt_read_params *params,
1480 					 const void *data, uint16_t length)
1481 {
1482 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1483 	const uint8_t inst_index = tbs_index(conn, inst);
1484 	int ret;
1485 
1486 	LOG_DBG("");
1487 
1488 	ret = handle_string_long_read(inst, err, data, params->single.offset, length, true);
1489 	if (ret != BT_GATT_ITER_CONTINUE) {
1490 		if (ret == BT_GATT_ITER_STOP) {
1491 			/* At this point the inst->net_buf.data contains a NULL terminator string */
1492 			friendly_name_changed(conn, 0, inst_index, (char *)inst->net_buf.data);
1493 		} else {
1494 			friendly_name_changed(conn, ret, inst_index, NULL);
1495 		}
1496 
1497 		tbs_client_gatt_read_complete(inst);
1498 
1499 		return BT_GATT_ITER_STOP;
1500 	}
1501 
1502 	return BT_GATT_ITER_CONTINUE;
1503 }
1504 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
1505 
1506 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
disc_read_ccid_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1507 static uint8_t disc_read_ccid_cb(struct bt_conn *conn, uint8_t err,
1508 				 struct bt_gatt_read_params *params,
1509 				 const void *data, uint16_t length)
1510 {
1511 	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
1512 	uint8_t inst_index = tbs_index(conn, inst);
1513 	int cb_err = err;
1514 
1515 	LOG_DBG("Index %u", inst_index);
1516 
1517 	if (cb_err != 0) {
1518 		LOG_DBG("err: 0x%02X", cb_err);
1519 	} else if (data != NULL) {
1520 		if (length == sizeof(inst->ccid)) {
1521 			inst->ccid = ((uint8_t *)data)[0];
1522 			LOG_DBG("0x%02x", inst->ccid);
1523 		} else {
1524 			LOG_DBG("Invalid length");
1525 			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
1526 		}
1527 	}
1528 
1529 	tbs_client_gatt_read_complete(inst);
1530 
1531 	if (cb_err != 0) {
1532 		tbs_client_discover_complete(conn, cb_err);
1533 	} else {
1534 		discover_next_instance(conn);
1535 	}
1536 
1537 	return BT_GATT_ITER_STOP;
1538 }
1539 
tbs_client_disc_read_ccid(struct bt_conn * conn)1540 static void tbs_client_disc_read_ccid(struct bt_conn *conn)
1541 {
1542 	const uint8_t conn_index = bt_conn_index(conn);
1543 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1544 	struct bt_tbs_instance *inst = srv_inst->current_inst;
1545 	int err;
1546 
1547 	err = tbs_client_gatt_read(conn, inst, inst->ccid_handle, disc_read_ccid_cb);
1548 	if (err != 0) {
1549 		tbs_client_discover_complete(conn, err);
1550 	}
1551 }
1552 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
1553 
1554 /**
1555  * @brief This will discover all characteristics on the server, retrieving the
1556  * handles of the writeable characteristics and subscribing to all notify and
1557  * indicate characteristics.
1558  */
discover_func(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1559 static uint8_t discover_func(struct bt_conn *conn,
1560 			     const struct bt_gatt_attr *attr,
1561 			     struct bt_gatt_discover_params *params)
1562 {
1563 	const uint8_t conn_index = bt_conn_index(conn);
1564 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1565 	struct bt_tbs_instance *current_inst = srv_inst->current_inst;
1566 
1567 	if (attr == NULL) {
1568 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
1569 		/* Read the CCID as the last part of discovering a TBS instance */
1570 		tbs_client_disc_read_ccid(conn);
1571 #else
1572 		discover_next_instance(conn);
1573 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
1574 
1575 		return BT_GATT_ITER_STOP;
1576 	}
1577 
1578 	LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
1579 
1580 	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
1581 		const struct bt_gatt_chrc *chrc;
1582 		struct bt_gatt_subscribe_params *sub_params = NULL;
1583 
1584 		chrc = (struct bt_gatt_chrc *)attr->user_data;
1585 
1586 		if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_CALL_STATE) == 0) {
1587 			LOG_DBG("Call state");
1588 			sub_params = &current_inst->call_state_sub_params;
1589 			sub_params->value_handle = chrc->value_handle;
1590 			sub_params->disc_params = &current_inst->call_state_sub_disc_params;
1591 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
1592 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_PROVIDER_NAME) == 0) {
1593 			LOG_DBG("Provider name");
1594 			sub_params = &current_inst->name_sub_params;
1595 			sub_params->value_handle = chrc->value_handle;
1596 			sub_params->disc_params = &current_inst->name_sub_disc_params;
1597 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
1598 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
1599 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_UCI) == 0) {
1600 			LOG_DBG("Bearer UCI");
1601 			current_inst->bearer_uci_handle = chrc->value_handle;
1602 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
1603 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
1604 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_TECHNOLOGY) == 0) {
1605 			LOG_DBG("Technology");
1606 			sub_params = &current_inst->technology_sub_params;
1607 			sub_params->value_handle = chrc->value_handle;
1608 			sub_params->disc_params = &current_inst->technology_sub_disc_params;
1609 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
1610 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
1611 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_URI_LIST) == 0) {
1612 			LOG_DBG("URI Scheme List");
1613 			current_inst->uri_list_handle = chrc->value_handle;
1614 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
1615 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
1616 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_SIGNAL_STRENGTH) == 0) {
1617 			LOG_DBG("Signal strength");
1618 			sub_params = &current_inst->signal_strength_sub_params;
1619 			sub_params->value_handle = chrc->value_handle;
1620 			sub_params->disc_params = &current_inst->signal_strength_sub_disc_params;
1621 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
1622 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) \
1623 || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL)
1624 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_SIGNAL_INTERVAL) == 0) {
1625 			LOG_DBG("Signal strength reporting interval");
1626 			current_inst->signal_interval_handle = chrc->value_handle;
1627 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
1628 /* || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
1629 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
1630 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_LIST_CURRENT_CALLS) == 0) {
1631 			LOG_DBG("Current calls");
1632 			sub_params = &current_inst->current_calls_sub_params;
1633 			sub_params->value_handle = chrc->value_handle;
1634 			sub_params->disc_params = &current_inst->current_calls_sub_disc_params;
1635 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
1636 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
1637 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_CCID) == 0) {
1638 			LOG_DBG("CCID");
1639 			current_inst->ccid_handle = chrc->value_handle;
1640 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
1641 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
1642 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_INCOMING_URI) == 0) {
1643 			LOG_DBG("Incoming target URI");
1644 			sub_params = &current_inst->in_target_uri_sub_params;
1645 			sub_params->value_handle = chrc->value_handle;
1646 			sub_params->disc_params = &current_inst->in_target_uri_sub_disc_params;
1647 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
1648 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
1649 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_STATUS_FLAGS) == 0) {
1650 			LOG_DBG("Status flags");
1651 			sub_params = &current_inst->status_flags_sub_params;
1652 			sub_params->value_handle = chrc->value_handle;
1653 			sub_params->disc_params = &current_inst->status_sub_disc_params;
1654 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
1655 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
1656 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_CALL_CONTROL_POINT) == 0) {
1657 			LOG_DBG("Call control point");
1658 			sub_params = &current_inst->call_cp_sub_params;
1659 			sub_params->value_handle = chrc->value_handle;
1660 			sub_params->disc_params = &current_inst->call_cp_sub_disc_params;
1661 #endif /* defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES) */
1662 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
1663 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_OPTIONAL_OPCODES) == 0) {
1664 			LOG_DBG("Supported opcodes");
1665 			current_inst->optional_opcodes_handle = chrc->value_handle;
1666 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
1667 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_TERMINATE_REASON) == 0) {
1668 			LOG_DBG("Termination reason");
1669 			current_inst->termination_reason_handle = chrc->value_handle;
1670 			sub_params = &current_inst->termination_sub_params;
1671 			sub_params->value_handle = chrc->value_handle;
1672 			sub_params->disc_params = &current_inst->termination_sub_disc_params;
1673 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
1674 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_FRIENDLY_NAME) == 0) {
1675 			LOG_DBG("Incoming friendly name");
1676 			sub_params = &current_inst->friendly_name_sub_params;
1677 			sub_params->value_handle = chrc->value_handle;
1678 			sub_params->disc_params = &current_inst->friendly_name_sub_disc_params;
1679 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
1680 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
1681 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_INCOMING_CALL) == 0) {
1682 			LOG_DBG("Incoming call");
1683 			sub_params = &current_inst->incoming_call_sub_params;
1684 			sub_params->value_handle = chrc->value_handle;
1685 			sub_params->disc_params = &current_inst->incoming_call_sub_disc_params;
1686 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
1687 		}
1688 
1689 		if (sub_params != NULL) {
1690 			sub_params->value = 0;
1691 			if (chrc->properties & BT_GATT_CHRC_NOTIFY) {
1692 				sub_params->value = BT_GATT_CCC_NOTIFY;
1693 			} else if (chrc->properties & BT_GATT_CHRC_INDICATE) {
1694 				sub_params->value = BT_GATT_CCC_INDICATE;
1695 			}
1696 
1697 			if (sub_params->value != 0) {
1698 				int err;
1699 
1700 				sub_params->ccc_handle = BT_GATT_AUTO_DISCOVER_CCC_HANDLE;
1701 				sub_params->end_handle = current_inst->end_handle;
1702 				sub_params->notify = notify_handler;
1703 				atomic_set_bit(sub_params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);
1704 
1705 				err = bt_gatt_subscribe(conn, sub_params);
1706 				if (err != 0 && err != -EALREADY) {
1707 					LOG_DBG("Could not subscribe to "
1708 					       "characteristic at handle 0x%04X"
1709 					       "(%d)",
1710 					       sub_params->value_handle, err);
1711 					tbs_client_discover_complete(conn, err);
1712 
1713 					return BT_GATT_ITER_STOP;
1714 				} else {
1715 					LOG_DBG("Subscribed to characteristic at "
1716 					       "handle 0x%04X",
1717 					       sub_params->value_handle);
1718 				}
1719 			}
1720 		}
1721 	}
1722 
1723 	return BT_GATT_ITER_CONTINUE;
1724 }
1725 
get_next_instance(struct bt_conn * conn,struct bt_tbs_server_inst * srv_inst)1726 static struct bt_tbs_instance *get_next_instance(struct bt_conn *conn,
1727 						 struct bt_tbs_server_inst *srv_inst)
1728 {
1729 	uint8_t inst_index;
1730 
1731 	if (srv_inst->current_inst != NULL) {
1732 		inst_index = tbs_index(conn, srv_inst->current_inst);
1733 		if (inst_index == BT_TBS_GTBS_INDEX) {
1734 			inst_index = 0;
1735 		} else {
1736 			inst_index++;
1737 		}
1738 
1739 		return tbs_inst_by_index(conn, inst_index);
1740 	}
1741 
1742 	inst_index = gtbs_found(srv_inst) ? BT_TBS_GTBS_INDEX : 0;
1743 
1744 	return tbs_inst_by_index(conn, inst_index);
1745 }
1746 
discover_next_instance(struct bt_conn * conn)1747 static void discover_next_instance(struct bt_conn *conn)
1748 {
1749 	int err;
1750 	uint8_t conn_index = bt_conn_index(conn);
1751 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1752 
1753 	srv_inst->current_inst = get_next_instance(conn, srv_inst);
1754 	if (srv_inst->current_inst == NULL) {
1755 		tbs_client_discover_complete(conn, 0);
1756 		return;
1757 	}
1758 
1759 	LOG_DBG("inst_index %u", tbs_index(conn, srv_inst->current_inst));
1760 
1761 	(void)memset(&srv_inst->discover_params, 0, sizeof(srv_inst->discover_params));
1762 	srv_inst->discover_params.uuid = NULL;
1763 	srv_inst->discover_params.start_handle = srv_inst->current_inst->start_handle;
1764 	srv_inst->discover_params.end_handle = srv_inst->current_inst->end_handle;
1765 	srv_inst->discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
1766 	srv_inst->discover_params.func = discover_func;
1767 
1768 	err = bt_gatt_discover(conn, &srv_inst->discover_params);
1769 	if (err != 0) {
1770 		tbs_client_discover_complete(conn, err);
1771 	}
1772 }
1773 
primary_discover_complete(struct bt_tbs_server_inst * server,struct bt_conn * conn)1774 static void primary_discover_complete(struct bt_tbs_server_inst *server, struct bt_conn *conn)
1775 {
1776 	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
1777 		LOG_DBG("Discover complete, found %u instances (GTBS%s found)",
1778 			inst_cnt(server), gtbs_found(server) ? "" : " not");
1779 	} else {
1780 		LOG_DBG("Discover complete, found %u instances", inst_cnt(server));
1781 	}
1782 
1783 	server->current_inst = NULL;
1784 
1785 	if (gtbs_found(server) || inst_cnt(server) > 0) {
1786 		discover_next_instance(conn);
1787 	} else {
1788 		tbs_client_discover_complete(conn, 0);
1789 	}
1790 }
1791 
1792 /**
1793  * @brief This will discover all characteristics on the server, retrieving the
1794  * handles of the writeable characteristics and subscribing to all notify and
1795  * indicate characteristics.
1796  */
1797 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
1798 static const struct bt_uuid *tbs_uuid = BT_UUID_TBS;
1799 
primary_discover_tbs_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1800 static uint8_t primary_discover_tbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1801 				       struct bt_gatt_discover_params *params)
1802 {
1803 	const uint8_t conn_index = bt_conn_index(conn);
1804 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1805 
1806 	LOG_DBG("conn %p attr %p", (void *)conn, attr);
1807 
1808 	if (attr != NULL) {
1809 		const struct bt_gatt_service_val *prim_service;
1810 
1811 		LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
1812 
1813 		prim_service = (struct bt_gatt_service_val *)attr->user_data;
1814 
1815 		srv_inst->current_inst = &srv_inst->tbs_insts[srv_inst->inst_cnt++];
1816 		srv_inst->current_inst->start_handle = attr->handle + 1;
1817 		srv_inst->current_inst->end_handle = prim_service->end_handle;
1818 
1819 		if (srv_inst->inst_cnt < ARRAY_SIZE(srv_inst->tbs_insts)) {
1820 			return BT_GATT_ITER_CONTINUE;
1821 		}
1822 	}
1823 
1824 	primary_discover_complete(srv_inst, conn);
1825 
1826 	return BT_GATT_ITER_STOP;
1827 }
1828 
primary_discover_tbs(struct bt_conn * conn)1829 static int primary_discover_tbs(struct bt_conn *conn)
1830 {
1831 	struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
1832 	struct bt_gatt_discover_params *params = &srv_inst->discover_params;
1833 
1834 	LOG_DBG("conn %p", (void *)conn);
1835 
1836 	(void)memset(params, 0, sizeof(*params));
1837 	params->uuid = tbs_uuid;
1838 	params->func = primary_discover_tbs_cb;
1839 	params->type = BT_GATT_DISCOVER_PRIMARY;
1840 	params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1841 	params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1842 
1843 	return bt_gatt_discover(conn, params);
1844 }
1845 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
1846 
1847 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
1848 static const struct bt_uuid *gtbs_uuid = BT_UUID_GTBS;
1849 
primary_discover_gtbs_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1850 static uint8_t primary_discover_gtbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1851 					struct bt_gatt_discover_params *params)
1852 {
1853 	const uint8_t conn_index = bt_conn_index(conn);
1854 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1855 
1856 	LOG_DBG("conn %p attr %p", (void *)conn, attr);
1857 
1858 	if (attr != NULL) {
1859 		const struct bt_gatt_service_val *prim_service;
1860 
1861 		LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
1862 
1863 		prim_service = (struct bt_gatt_service_val *)attr->user_data;
1864 
1865 		srv_inst->current_inst = &srv_inst->gtbs_inst;
1866 		srv_inst->current_inst->start_handle = attr->handle + 1;
1867 		srv_inst->current_inst->end_handle = prim_service->end_handle;
1868 	}
1869 
1870 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
1871 	int err;
1872 
1873 	err = primary_discover_tbs(conn);
1874 	if (err == 0) {
1875 		return BT_GATT_ITER_STOP;
1876 	}
1877 
1878 	LOG_DBG("Discover failed (err %d)", err);
1879 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
1880 
1881 	primary_discover_complete(srv_inst, conn);
1882 
1883 	return BT_GATT_ITER_STOP;
1884 }
1885 
primary_discover_gtbs(struct bt_conn * conn)1886 static int primary_discover_gtbs(struct bt_conn *conn)
1887 {
1888 	struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
1889 	struct bt_gatt_discover_params *params = &srv_inst->discover_params;
1890 
1891 	LOG_DBG("conn %p", (void *)conn);
1892 
1893 	(void)memset(params, 0, sizeof(*params));
1894 	params->uuid = gtbs_uuid;
1895 	params->func = primary_discover_gtbs_cb;
1896 	params->type = BT_GATT_DISCOVER_PRIMARY;
1897 	params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1898 	params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1899 
1900 	return bt_gatt_discover(conn, params);
1901 }
1902 #endif /* defined(CONFIG_BT_TBS_CLIENT_GTBS) */
1903 
1904 /****************************** PUBLIC API ******************************/
1905 
1906 #if defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL)
bt_tbs_client_hold_call(struct bt_conn * conn,uint8_t inst_index,uint8_t call_index)1907 int bt_tbs_client_hold_call(struct bt_conn *conn, uint8_t inst_index,
1908 			    uint8_t call_index)
1909 {
1910 	return tbs_client_common_call_control(conn, inst_index, call_index,
1911 					      BT_TBS_CALL_OPCODE_HOLD);
1912 }
1913 #endif /* defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL) */
1914 
1915 #if defined(CONFIG_BT_TBS_CLIENT_ACCEPT_CALL)
bt_tbs_client_accept_call(struct bt_conn * conn,uint8_t inst_index,uint8_t call_index)1916 int bt_tbs_client_accept_call(struct bt_conn *conn, uint8_t inst_index,
1917 			      uint8_t call_index)
1918 {
1919 	return tbs_client_common_call_control(conn, inst_index, call_index,
1920 					      BT_TBS_CALL_OPCODE_ACCEPT);
1921 }
1922 #endif /* defined(CONFIG_BT_TBS_CLIENT_ACCEPT_CALL) */
1923 
1924 #if defined(CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL)
bt_tbs_client_retrieve_call(struct bt_conn * conn,uint8_t inst_index,uint8_t call_index)1925 int bt_tbs_client_retrieve_call(struct bt_conn *conn, uint8_t inst_index,
1926 				uint8_t call_index)
1927 {
1928 	return tbs_client_common_call_control(conn, inst_index, call_index,
1929 					      BT_TBS_CALL_OPCODE_RETRIEVE);
1930 }
1931 #endif /* defined(CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL) */
1932 
1933 #if defined(CONFIG_BT_TBS_CLIENT_TERMINATE_CALL)
bt_tbs_client_terminate_call(struct bt_conn * conn,uint8_t inst_index,uint8_t call_index)1934 int bt_tbs_client_terminate_call(struct bt_conn *conn, uint8_t inst_index,
1935 				 uint8_t call_index)
1936 {
1937 	return tbs_client_common_call_control(conn, inst_index, call_index,
1938 					      BT_TBS_CALL_OPCODE_TERMINATE);
1939 }
1940 #endif /* defined(CONFIG_BT_TBS_CLIENT_TERMINATE_CALL) */
1941 
1942 #if defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL)
bt_tbs_client_originate_call(struct bt_conn * conn,uint8_t inst_index,const char * uri)1943 int bt_tbs_client_originate_call(struct bt_conn *conn, uint8_t inst_index,
1944 				 const char *uri)
1945 {
1946 	struct bt_tbs_instance *inst;
1947 	uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
1948 	struct bt_tbs_call_cp_originate *originate;
1949 	size_t uri_len;
1950 	const size_t max_uri_len = sizeof(write_buf) - sizeof(*originate);
1951 
1952 	if (conn == NULL) {
1953 		return -ENOTCONN;
1954 	} else if (!bt_tbs_valid_uri(uri, strlen(uri))) {
1955 		LOG_DBG("Invalid URI: %s", uri);
1956 		return -EINVAL;
1957 	}
1958 
1959 	inst = tbs_inst_by_index(conn, inst_index);
1960 	if (inst == NULL) {
1961 		return -EINVAL;
1962 	}
1963 
1964 	/* Check if there are free spots */
1965 	if (!free_call_spot(inst)) {
1966 		LOG_DBG("Cannot originate more calls");
1967 		return -ENOMEM;
1968 	}
1969 
1970 	uri_len = strlen(uri);
1971 
1972 	if (uri_len > max_uri_len) {
1973 		LOG_DBG("URI len (%zu) longer than maximum writable %zu", uri_len, max_uri_len);
1974 		return -ENOMEM;
1975 	}
1976 
1977 	originate = (struct bt_tbs_call_cp_originate *)write_buf;
1978 	originate->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
1979 	(void)memcpy(originate->uri, uri, uri_len);
1980 
1981 	return bt_gatt_write_without_response(conn, inst->call_cp_sub_params.value_handle,
1982 					      originate,
1983 					      sizeof(*originate) + uri_len,
1984 					      false);
1985 }
1986 #endif /* defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL) */
1987 
1988 #if defined(CONFIG_BT_TBS_CLIENT_JOIN_CALLS)
bt_tbs_client_join_calls(struct bt_conn * conn,uint8_t inst_index,const uint8_t * call_indexes,uint8_t count)1989 int bt_tbs_client_join_calls(struct bt_conn *conn, uint8_t inst_index,
1990 			     const uint8_t *call_indexes, uint8_t count)
1991 {
1992 	if (conn == NULL) {
1993 		return -ENOTCONN;
1994 	}
1995 
1996 	/* Write to call control point */
1997 	if (call_indexes && count > 1 &&
1998 	    count <= CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
1999 		struct bt_tbs_instance *inst;
2000 		struct bt_tbs_call_cp_join *join;
2001 		uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
2002 		const size_t max_call_cnt = sizeof(write_buf) - sizeof(join->opcode);
2003 
2004 		inst = tbs_inst_by_index(conn, inst_index);
2005 		if (inst == NULL) {
2006 			return -EINVAL;
2007 		}
2008 
2009 		if (inst->call_cp_sub_params.value_handle == 0) {
2010 			LOG_DBG("Handle not set");
2011 			return -EINVAL;
2012 		}
2013 
2014 		if (count > max_call_cnt) {
2015 			LOG_DBG("Call count (%u) larger than maximum writable %zu", count,
2016 				max_call_cnt);
2017 			return -ENOMEM;
2018 		}
2019 
2020 		join = (struct bt_tbs_call_cp_join *)write_buf;
2021 
2022 		join->opcode = BT_TBS_CALL_OPCODE_JOIN;
2023 		(void)memcpy(join->call_indexes, call_indexes, count);
2024 
2025 		return bt_gatt_write_without_response(conn,
2026 						      inst->call_cp_sub_params.value_handle,
2027 						      join,
2028 						      sizeof(*join) + count,
2029 						      false);
2030 	}
2031 
2032 	return -EINVAL;
2033 }
2034 #endif /* defined(CONFIG_BT_TBS_CLIENT_JOIN_CALLS) */
2035 
2036 #if defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL)
bt_tbs_client_set_signal_strength_interval(struct bt_conn * conn,uint8_t inst_index,uint8_t interval)2037 int bt_tbs_client_set_signal_strength_interval(struct bt_conn *conn,
2038 					       uint8_t inst_index,
2039 					       uint8_t interval)
2040 {
2041 	struct bt_tbs_instance *inst;
2042 
2043 	if (conn == NULL) {
2044 		return -ENOTCONN;
2045 	}
2046 
2047 	inst = tbs_inst_by_index(conn, inst_index);
2048 	if (inst == NULL) {
2049 		return -EINVAL;
2050 	}
2051 
2052 	/* Populate Outgoing Remote URI */
2053 	if (inst->signal_interval_handle == 0) {
2054 		LOG_DBG("Handle not set");
2055 		return -EINVAL;
2056 	}
2057 
2058 	return bt_gatt_write_without_response(conn,
2059 					      inst->signal_interval_handle,
2060 					      &interval, sizeof(interval),
2061 					      false);
2062 }
2063 #endif /* defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
2064 
2065 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
bt_tbs_client_read_bearer_provider_name(struct bt_conn * conn,uint8_t inst_index)2066 int bt_tbs_client_read_bearer_provider_name(struct bt_conn *conn,
2067 					    uint8_t inst_index)
2068 {
2069 	struct bt_tbs_instance *inst;
2070 
2071 	if (conn == NULL) {
2072 		return -ENOTCONN;
2073 	}
2074 
2075 	inst = tbs_inst_by_index(conn, inst_index);
2076 	if (inst == NULL) {
2077 		return -EINVAL;
2078 	}
2079 
2080 	if (inst->name_sub_params.value_handle == 0) {
2081 		LOG_DBG("Handle not set");
2082 		return -EINVAL;
2083 	}
2084 
2085 	return tbs_client_gatt_read(conn, inst, inst->name_sub_params.value_handle,
2086 				    read_bearer_provider_name_cb);
2087 }
2088 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
2089 
2090 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
bt_tbs_client_read_bearer_uci(struct bt_conn * conn,uint8_t inst_index)2091 int bt_tbs_client_read_bearer_uci(struct bt_conn *conn, uint8_t inst_index)
2092 {
2093 	struct bt_tbs_instance *inst;
2094 
2095 	if (conn == NULL) {
2096 		return -ENOTCONN;
2097 	}
2098 
2099 	inst = tbs_inst_by_index(conn, inst_index);
2100 	if (inst == NULL) {
2101 		return -EINVAL;
2102 	}
2103 
2104 	if (inst->bearer_uci_handle == 0) {
2105 		LOG_DBG("Handle not set");
2106 		return -EINVAL;
2107 	}
2108 
2109 	return tbs_client_gatt_read(conn, inst, inst->bearer_uci_handle, read_bearer_uci_cb);
2110 }
2111 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
2112 
2113 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
bt_tbs_client_read_technology(struct bt_conn * conn,uint8_t inst_index)2114 int bt_tbs_client_read_technology(struct bt_conn *conn, uint8_t inst_index)
2115 {
2116 	struct bt_tbs_instance *inst;
2117 
2118 	if (conn == NULL) {
2119 		return -ENOTCONN;
2120 	}
2121 
2122 	inst = tbs_inst_by_index(conn, inst_index);
2123 	if (inst == NULL) {
2124 		return -EINVAL;
2125 	}
2126 
2127 	if (inst->technology_sub_params.value_handle == 0) {
2128 		LOG_DBG("Handle not set");
2129 		return -EINVAL;
2130 	}
2131 
2132 	return tbs_client_gatt_read(conn, inst, inst->technology_sub_params.value_handle,
2133 				    read_technology_cb);
2134 }
2135 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
2136 
2137 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
bt_tbs_client_read_uri_list(struct bt_conn * conn,uint8_t inst_index)2138 int bt_tbs_client_read_uri_list(struct bt_conn *conn, uint8_t inst_index)
2139 {
2140 	struct bt_tbs_instance *inst;
2141 
2142 	if (conn == NULL) {
2143 		return -ENOTCONN;
2144 	}
2145 
2146 	inst = tbs_inst_by_index(conn, inst_index);
2147 	if (inst == NULL) {
2148 		return -EINVAL;
2149 	}
2150 
2151 	if (inst->uri_list_handle == 0) {
2152 		LOG_DBG("Handle not set");
2153 		return -EINVAL;
2154 	}
2155 
2156 	return tbs_client_gatt_read(conn, inst, inst->uri_list_handle, read_uri_list_cb);
2157 }
2158 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
2159 
2160 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
bt_tbs_client_read_signal_strength(struct bt_conn * conn,uint8_t inst_index)2161 int bt_tbs_client_read_signal_strength(struct bt_conn *conn, uint8_t inst_index)
2162 {
2163 	struct bt_tbs_instance *inst;
2164 
2165 	if (conn == NULL) {
2166 		return -ENOTCONN;
2167 	}
2168 
2169 	inst = tbs_inst_by_index(conn, inst_index);
2170 	if (inst == NULL) {
2171 		return -EINVAL;
2172 	}
2173 
2174 	if (inst->signal_strength_sub_params.value_handle == 0) {
2175 		LOG_DBG("Handle not set");
2176 		return -EINVAL;
2177 	}
2178 
2179 	return tbs_client_gatt_read(conn, inst, inst->signal_strength_sub_params.value_handle,
2180 				    read_signal_strength_cb);
2181 }
2182 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
2183 
2184 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL)
bt_tbs_client_read_signal_interval(struct bt_conn * conn,uint8_t inst_index)2185 int bt_tbs_client_read_signal_interval(struct bt_conn *conn, uint8_t inst_index)
2186 {
2187 	struct bt_tbs_instance *inst;
2188 
2189 	if (conn == NULL) {
2190 		return -ENOTCONN;
2191 	}
2192 
2193 	inst = tbs_inst_by_index(conn, inst_index);
2194 	if (inst == NULL) {
2195 		return -EINVAL;
2196 	}
2197 
2198 	if (inst->signal_interval_handle == 0) {
2199 		LOG_DBG("Handle not set");
2200 		return -EINVAL;
2201 	}
2202 
2203 	return tbs_client_gatt_read(conn, inst, inst->signal_interval_handle,
2204 				    read_signal_interval_cb);
2205 }
2206 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
2207 
2208 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
bt_tbs_client_read_current_calls(struct bt_conn * conn,uint8_t inst_index)2209 int bt_tbs_client_read_current_calls(struct bt_conn *conn, uint8_t inst_index)
2210 {
2211 	struct bt_tbs_instance *inst;
2212 
2213 	if (conn == NULL) {
2214 		return -ENOTCONN;
2215 	}
2216 
2217 	inst = tbs_inst_by_index(conn, inst_index);
2218 	if (inst == NULL) {
2219 		return -EINVAL;
2220 	}
2221 
2222 	if (inst->current_calls_sub_params.value_handle == 0) {
2223 		LOG_DBG("Handle not set");
2224 		return -EINVAL;
2225 	}
2226 
2227 	return tbs_client_gatt_read(conn, inst, inst->current_calls_sub_params.value_handle,
2228 				    read_current_calls_cb);
2229 }
2230 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
2231 
2232 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
bt_tbs_client_read_ccid(struct bt_conn * conn,uint8_t inst_index)2233 int bt_tbs_client_read_ccid(struct bt_conn *conn, uint8_t inst_index)
2234 {
2235 	struct bt_tbs_instance *inst;
2236 
2237 	if (conn == NULL) {
2238 		return -ENOTCONN;
2239 	}
2240 
2241 	inst = tbs_inst_by_index(conn, inst_index);
2242 	if (inst == NULL) {
2243 		return -EINVAL;
2244 	}
2245 
2246 	if (inst->ccid_handle == 0) {
2247 		LOG_DBG("Handle not set");
2248 		return -EINVAL;
2249 	}
2250 
2251 	return tbs_client_gatt_read(conn, inst, inst->ccid_handle, read_ccid_cb);
2252 }
2253 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
2254 
2255 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
bt_tbs_client_read_call_uri(struct bt_conn * conn,uint8_t inst_index)2256 int bt_tbs_client_read_call_uri(struct bt_conn *conn, uint8_t inst_index)
2257 {
2258 	struct bt_tbs_instance *inst;
2259 
2260 	if (conn == NULL) {
2261 		return -ENOTCONN;
2262 	}
2263 
2264 	inst = tbs_inst_by_index(conn, inst_index);
2265 	if (inst == NULL) {
2266 		return -EINVAL;
2267 	}
2268 
2269 	if (inst->in_target_uri_sub_params.value_handle == 0) {
2270 		LOG_DBG("Handle not set");
2271 		return -EINVAL;
2272 	}
2273 
2274 	return tbs_client_gatt_read(conn, inst, inst->in_target_uri_sub_params.value_handle,
2275 				    read_call_uri_cb);
2276 }
2277 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
2278 
2279 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
bt_tbs_client_read_status_flags(struct bt_conn * conn,uint8_t inst_index)2280 int bt_tbs_client_read_status_flags(struct bt_conn *conn, uint8_t inst_index)
2281 {
2282 	struct bt_tbs_instance *inst;
2283 
2284 	if (conn == NULL) {
2285 		return -ENOTCONN;
2286 	}
2287 
2288 	inst = tbs_inst_by_index(conn, inst_index);
2289 	if (inst == NULL) {
2290 		return -EINVAL;
2291 	}
2292 
2293 	if (inst->status_flags_sub_params.value_handle == 0) {
2294 		LOG_DBG("Handle not set");
2295 		return -EINVAL;
2296 	}
2297 
2298 	return tbs_client_gatt_read(conn, inst, inst->status_flags_sub_params.value_handle,
2299 				    read_status_flags_cb);
2300 }
2301 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
2302 
bt_tbs_client_read_call_state(struct bt_conn * conn,uint8_t inst_index)2303 int bt_tbs_client_read_call_state(struct bt_conn *conn, uint8_t inst_index)
2304 {
2305 	struct bt_tbs_instance *inst;
2306 
2307 	if (conn == NULL) {
2308 		return -ENOTCONN;
2309 	}
2310 
2311 	inst = tbs_inst_by_index(conn, inst_index);
2312 	if (inst == NULL) {
2313 		return -EINVAL;
2314 	}
2315 
2316 	if (inst->call_state_sub_params.value_handle == 0) {
2317 		LOG_DBG("Handle not set");
2318 		return -EINVAL;
2319 	}
2320 
2321 	return tbs_client_gatt_read(conn, inst, inst->call_state_sub_params.value_handle,
2322 				    read_call_state_cb);
2323 }
2324 
2325 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
bt_tbs_client_read_optional_opcodes(struct bt_conn * conn,uint8_t inst_index)2326 int bt_tbs_client_read_optional_opcodes(struct bt_conn *conn,
2327 					uint8_t inst_index)
2328 {
2329 	struct bt_tbs_instance *inst;
2330 
2331 	if (conn == NULL) {
2332 		return -ENOTCONN;
2333 	}
2334 
2335 	inst = tbs_inst_by_index(conn, inst_index);
2336 	if (inst == NULL) {
2337 		return -EINVAL;
2338 	}
2339 
2340 	if (inst->optional_opcodes_handle == 0) {
2341 		LOG_DBG("Handle not set");
2342 		return -EINVAL;
2343 	}
2344 
2345 	return tbs_client_gatt_read(conn, inst, inst->optional_opcodes_handle,
2346 				    read_optional_opcodes_cb);
2347 }
2348 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
2349 
2350 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
bt_tbs_client_read_remote_uri(struct bt_conn * conn,uint8_t inst_index)2351 int bt_tbs_client_read_remote_uri(struct bt_conn *conn, uint8_t inst_index)
2352 {
2353 	struct bt_tbs_instance *inst;
2354 
2355 	if (conn == NULL) {
2356 		return -ENOTCONN;
2357 	}
2358 
2359 	inst = tbs_inst_by_index(conn, inst_index);
2360 	if (inst == NULL) {
2361 		return -EINVAL;
2362 	}
2363 
2364 	if (inst->incoming_call_sub_params.value_handle == 0) {
2365 		LOG_DBG("Handle not set");
2366 		return -EINVAL;
2367 	}
2368 
2369 	return tbs_client_gatt_read(conn, inst, inst->incoming_call_sub_params.value_handle,
2370 				    read_remote_uri_cb);
2371 }
2372 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
2373 
2374 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
bt_tbs_client_read_friendly_name(struct bt_conn * conn,uint8_t inst_index)2375 int bt_tbs_client_read_friendly_name(struct bt_conn *conn, uint8_t inst_index)
2376 {
2377 	struct bt_tbs_instance *inst;
2378 
2379 	if (conn == NULL) {
2380 		return -ENOTCONN;
2381 	}
2382 
2383 	inst = tbs_inst_by_index(conn, inst_index);
2384 	if (inst == NULL) {
2385 		return -EINVAL;
2386 	}
2387 
2388 	if (inst->friendly_name_sub_params.value_handle == 0) {
2389 		LOG_DBG("Handle not set");
2390 		return -EINVAL;
2391 	}
2392 
2393 	return tbs_client_gatt_read(conn, inst, inst->friendly_name_sub_params.value_handle,
2394 				    read_friendly_name_cb);
2395 }
2396 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
2397 
check_and_set_all_busy(struct bt_tbs_server_inst * srv_inst)2398 static bool check_and_set_all_busy(struct bt_tbs_server_inst *srv_inst)
2399 {
2400 	bool all_idle = true;
2401 
2402 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2403 	if (atomic_test_and_set_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY)) {
2404 		LOG_DBG("GTBS is busy");
2405 
2406 		return false;
2407 	}
2408 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2409 
2410 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
2411 	size_t num_free;
2412 
2413 	for (num_free = 0U; num_free < ARRAY_SIZE(srv_inst->tbs_insts); num_free++) {
2414 		struct bt_tbs_instance *tbs_inst = &srv_inst->tbs_insts[num_free];
2415 
2416 		if (atomic_test_and_set_bit(tbs_inst->flags, BT_TBS_CLIENT_FLAG_BUSY)) {
2417 			LOG_DBG("inst[%zu] (%p) is busy", num_free, tbs_inst);
2418 			all_idle = false;
2419 
2420 			break;
2421 		}
2422 	}
2423 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
2424 
2425 	/* If any is busy, revert any busy states we've set */
2426 	if (!all_idle) {
2427 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2428 		atomic_clear_bit(srv_inst->gtbs_inst.flags, BT_TBS_CLIENT_FLAG_BUSY);
2429 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2430 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
2431 		for (uint8_t i = 0U; i < num_free; i++) {
2432 			atomic_clear_bit(srv_inst->tbs_insts[i].flags, BT_TBS_CLIENT_FLAG_BUSY);
2433 		}
2434 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
2435 	}
2436 
2437 	return all_idle;
2438 }
2439 
bt_tbs_client_discover(struct bt_conn * conn)2440 int bt_tbs_client_discover(struct bt_conn *conn)
2441 {
2442 	uint8_t conn_index;
2443 	struct bt_tbs_server_inst *srv_inst;
2444 
2445 	if (conn == NULL) {
2446 		return -ENOTCONN;
2447 	}
2448 
2449 	conn_index = bt_conn_index(conn);
2450 	srv_inst = &srv_insts[conn_index];
2451 
2452 	/* Before we do discovery we ensure that all TBS instances are currently not busy as to not
2453 	 * interfere with any procedures in progress
2454 	 */
2455 	if (!check_and_set_all_busy(srv_inst)) {
2456 		return -EBUSY;
2457 	}
2458 
2459 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
2460 	(void)memset(srv_inst->tbs_insts, 0, sizeof(srv_inst->tbs_insts)); /* reset data */
2461 	srv_inst->inst_cnt = 0;
2462 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
2463 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2464 	(void)memset(&srv_inst->gtbs_inst, 0, sizeof(srv_inst->gtbs_inst)); /* reset data */
2465 	return primary_discover_gtbs(conn);
2466 #else
2467 	return primary_discover_tbs(conn);
2468 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2469 }
2470 
bt_tbs_client_register_cb(struct bt_tbs_client_cb * cb)2471 int bt_tbs_client_register_cb(struct bt_tbs_client_cb *cb)
2472 {
2473 	CHECKIF(cb == NULL) {
2474 		LOG_DBG("cb is NULL");
2475 
2476 		return -EINVAL;
2477 	}
2478 
2479 	if (sys_slist_find(&tbs_client_cbs, &cb->_node, NULL)) {
2480 		return -EEXIST;
2481 	}
2482 
2483 	sys_slist_append(&tbs_client_cbs, &cb->_node);
2484 
2485 	return 0;
2486 }
2487 
2488 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
tbs_instance_ccid_is_eq(struct bt_tbs_instance * inst,void * user_data)2489 static bool tbs_instance_ccid_is_eq(struct bt_tbs_instance *inst, void *user_data)
2490 {
2491 	uint8_t ccid = POINTER_TO_UINT(user_data);
2492 
2493 	return inst->ccid == ccid;
2494 }
2495 
bt_tbs_client_get_by_ccid(const struct bt_conn * conn,uint8_t ccid)2496 struct bt_tbs_instance *bt_tbs_client_get_by_ccid(const struct bt_conn *conn,
2497 						  uint8_t ccid)
2498 {
2499 	struct bt_tbs_server_inst *server;
2500 
2501 	CHECKIF(conn == NULL) {
2502 		LOG_DBG("conn was NULL");
2503 		return NULL;
2504 	}
2505 
2506 	server = &srv_insts[bt_conn_index(conn)];
2507 
2508 	return tbs_instance_find(server, tbs_instance_ccid_is_eq, UINT_TO_POINTER(ccid));
2509 }
2510 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
2511