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