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