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