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 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 				err = bt_gatt_subscribe(conn, sub_params);
1543 				if (err != 0) {
1544 					LOG_DBG("Could not subscribe to "
1545 					       "characterstic at handle 0x%04X"
1546 					       "(%d)",
1547 					       sub_params->value_handle, err);
1548 				} else {
1549 					LOG_DBG("Subscribed to characterstic at "
1550 					       "handle 0x%04X",
1551 					       sub_params->value_handle);
1552 				}
1553 			}
1554 		}
1555 	}
1556 
1557 	return BT_GATT_ITER_CONTINUE;
1558 }
1559 
get_next_instance(struct bt_conn * conn,struct bt_tbs_server_inst * srv_inst)1560 static struct bt_tbs_instance *get_next_instance(struct bt_conn *conn,
1561 						 struct bt_tbs_server_inst *srv_inst)
1562 {
1563 	uint8_t inst_index;
1564 
1565 	if (srv_inst->current_inst != NULL) {
1566 		inst_index = tbs_index(conn, srv_inst->current_inst);
1567 		if (inst_index == BT_TBS_GTBS_INDEX) {
1568 			inst_index = 0;
1569 		} else {
1570 			inst_index++;
1571 		}
1572 
1573 		return tbs_inst_by_index(conn, inst_index);
1574 	}
1575 
1576 	inst_index = gtbs_found(srv_inst) ? BT_TBS_GTBS_INDEX : 0;
1577 
1578 	return tbs_inst_by_index(conn, inst_index);
1579 }
1580 
discover_next_instance(struct bt_conn * conn)1581 static void discover_next_instance(struct bt_conn *conn)
1582 {
1583 	int err;
1584 	uint8_t conn_index = bt_conn_index(conn);
1585 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1586 
1587 	srv_inst->current_inst = get_next_instance(conn, srv_inst);
1588 	if (srv_inst->current_inst == NULL) {
1589 		tbs_client_discover_complete(conn, 0);
1590 		return;
1591 	}
1592 
1593 	LOG_DBG("inst_index %u", tbs_index(conn, srv_inst->current_inst));
1594 
1595 	(void)memset(&srv_inst->discover_params, 0, sizeof(srv_inst->discover_params));
1596 	srv_inst->discover_params.uuid = NULL;
1597 	srv_inst->discover_params.start_handle = srv_inst->current_inst->start_handle;
1598 	srv_inst->discover_params.end_handle = srv_inst->current_inst->end_handle;
1599 	srv_inst->discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
1600 	srv_inst->discover_params.func = discover_func;
1601 
1602 	err = bt_gatt_discover(conn, &srv_inst->discover_params);
1603 	if (err != 0) {
1604 		tbs_client_discover_complete(conn, err);
1605 	}
1606 }
1607 
primary_discover_complete(struct bt_tbs_server_inst * server,struct bt_conn * conn)1608 static void primary_discover_complete(struct bt_tbs_server_inst *server, struct bt_conn *conn)
1609 {
1610 	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
1611 		LOG_DBG("Discover complete, found %u instances (GTBS%s found)",
1612 			inst_cnt(server), gtbs_found(server) ? "" : " not");
1613 	} else {
1614 		LOG_DBG("Discover complete, found %u instances", inst_cnt(server));
1615 	}
1616 
1617 	server->current_inst = NULL;
1618 
1619 	if (gtbs_found(server) || inst_cnt(server) > 0) {
1620 		discover_next_instance(conn);
1621 	} else {
1622 		tbs_client_discover_complete(conn, 0);
1623 	}
1624 }
1625 
1626 /**
1627  * @brief This will discover all characteristics on the server, retrieving the
1628  * handles of the writeable characteristics and subscribing to all notify and
1629  * indicate characteristics.
1630  */
1631 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
1632 static const struct bt_uuid *tbs_uuid = BT_UUID_TBS;
1633 
primary_discover_tbs_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1634 static uint8_t primary_discover_tbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1635 				       struct bt_gatt_discover_params *params)
1636 {
1637 	const uint8_t conn_index = bt_conn_index(conn);
1638 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1639 
1640 	LOG_DBG("conn %p attr %p", (void *)conn, attr);
1641 
1642 	if (attr != NULL) {
1643 		const struct bt_gatt_service_val *prim_service;
1644 
1645 		LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
1646 
1647 		prim_service = (struct bt_gatt_service_val *)attr->user_data;
1648 
1649 		srv_inst->current_inst = &srv_inst->tbs_insts[srv_inst->inst_cnt++];
1650 		srv_inst->current_inst->start_handle = attr->handle + 1;
1651 		srv_inst->current_inst->end_handle = prim_service->end_handle;
1652 
1653 		if (srv_inst->inst_cnt < ARRAY_SIZE(srv_inst->tbs_insts)) {
1654 			return BT_GATT_ITER_CONTINUE;
1655 		}
1656 	}
1657 
1658 	primary_discover_complete(srv_inst, conn);
1659 
1660 	return BT_GATT_ITER_STOP;
1661 }
1662 
primary_discover_tbs(struct bt_conn * conn)1663 static int primary_discover_tbs(struct bt_conn *conn)
1664 {
1665 	struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
1666 	struct bt_gatt_discover_params *params = &srv_inst->discover_params;
1667 
1668 	LOG_DBG("conn %p", (void *)conn);
1669 
1670 	(void)memset(params, 0, sizeof(*params));
1671 	params->uuid = tbs_uuid;
1672 	params->func = primary_discover_tbs_cb;
1673 	params->type = BT_GATT_DISCOVER_PRIMARY;
1674 	params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1675 	params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1676 
1677 	return bt_gatt_discover(conn, params);
1678 }
1679 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
1680 
1681 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
1682 static const struct bt_uuid *gtbs_uuid = BT_UUID_GTBS;
1683 
primary_discover_gtbs_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1684 static uint8_t primary_discover_gtbs_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1685 					struct bt_gatt_discover_params *params)
1686 {
1687 	const uint8_t conn_index = bt_conn_index(conn);
1688 	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
1689 
1690 	LOG_DBG("conn %p attr %p", (void *)conn, attr);
1691 
1692 	if (attr != NULL) {
1693 		const struct bt_gatt_service_val *prim_service;
1694 
1695 		LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
1696 
1697 		prim_service = (struct bt_gatt_service_val *)attr->user_data;
1698 
1699 		srv_inst->current_inst = &srv_inst->gtbs_inst;
1700 		srv_inst->current_inst->start_handle = attr->handle + 1;
1701 		srv_inst->current_inst->end_handle = prim_service->end_handle;
1702 	}
1703 
1704 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
1705 	int err;
1706 
1707 	err = primary_discover_tbs(conn);
1708 	if (err == 0) {
1709 		return BT_GATT_ITER_STOP;
1710 	}
1711 
1712 	LOG_DBG("Discover failed (err %d)", err);
1713 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
1714 
1715 	primary_discover_complete(srv_inst, conn);
1716 
1717 	return BT_GATT_ITER_STOP;
1718 }
1719 
primary_discover_gtbs(struct bt_conn * conn)1720 static int primary_discover_gtbs(struct bt_conn *conn)
1721 {
1722 	struct bt_tbs_server_inst *srv_inst = &srv_insts[bt_conn_index(conn)];
1723 	struct bt_gatt_discover_params *params = &srv_inst->discover_params;
1724 
1725 	LOG_DBG("conn %p", (void *)conn);
1726 
1727 	(void)memset(params, 0, sizeof(*params));
1728 	params->uuid = gtbs_uuid;
1729 	params->func = primary_discover_gtbs_cb;
1730 	params->type = BT_GATT_DISCOVER_PRIMARY;
1731 	params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1732 	params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1733 
1734 	return bt_gatt_discover(conn, params);
1735 }
1736 #endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */
1737 
1738 /****************************** PUBLIC API ******************************/
1739 
1740 #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)1741 int bt_tbs_client_hold_call(struct bt_conn *conn, uint8_t inst_index,
1742 			    uint8_t call_index)
1743 {
1744 	return tbs_client_common_call_control(conn, inst_index, call_index,
1745 					      BT_TBS_CALL_OPCODE_HOLD);
1746 }
1747 #endif /* defined(CONFIG_BT_TBS_CLIENT_HOLD_CALL) */
1748 
1749 #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)1750 int bt_tbs_client_accept_call(struct bt_conn *conn, uint8_t inst_index,
1751 			      uint8_t call_index)
1752 {
1753 	return tbs_client_common_call_control(conn, inst_index, call_index,
1754 					      BT_TBS_CALL_OPCODE_ACCEPT);
1755 }
1756 #endif /* defined(CONFIG_BT_TBS_CLIENT_ACCEPT_CALL) */
1757 
1758 #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)1759 int bt_tbs_client_retrieve_call(struct bt_conn *conn, uint8_t inst_index,
1760 				uint8_t call_index)
1761 {
1762 	return tbs_client_common_call_control(conn, inst_index, call_index,
1763 					      BT_TBS_CALL_OPCODE_RETRIEVE);
1764 }
1765 #endif /* defined(CONFIG_BT_TBS_CLIENT_RETRIEVE_CALL) */
1766 
1767 #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)1768 int bt_tbs_client_terminate_call(struct bt_conn *conn, uint8_t inst_index,
1769 				 uint8_t call_index)
1770 {
1771 	return tbs_client_common_call_control(conn, inst_index, call_index,
1772 					      BT_TBS_CALL_OPCODE_TERMINATE);
1773 }
1774 #endif /* defined(CONFIG_BT_TBS_CLIENT_TERMINATE_CALL) */
1775 
1776 #if defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL)
bt_tbs_client_originate_call(struct bt_conn * conn,uint8_t inst_index,const char * uri)1777 int bt_tbs_client_originate_call(struct bt_conn *conn, uint8_t inst_index,
1778 				 const char *uri)
1779 {
1780 	struct bt_tbs_instance *inst;
1781 	uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
1782 	struct bt_tbs_call_cp_originate *originate;
1783 	size_t uri_len;
1784 	const size_t max_uri_len = sizeof(write_buf) - sizeof(*originate);
1785 
1786 	if (conn == NULL) {
1787 		return -ENOTCONN;
1788 	} else if (!bt_tbs_valid_uri(uri)) {
1789 		LOG_DBG("Invalid URI: %s", uri);
1790 		return -EINVAL;
1791 	}
1792 
1793 	inst = tbs_inst_by_index(conn, inst_index);
1794 	if (inst == NULL) {
1795 		return -EINVAL;
1796 	}
1797 
1798 	/* Check if there are free spots */
1799 	if (!free_call_spot(inst)) {
1800 		LOG_DBG("Cannot originate more calls");
1801 		return -ENOMEM;
1802 	}
1803 
1804 	uri_len = strlen(uri);
1805 
1806 	if (uri_len > max_uri_len) {
1807 		LOG_DBG("URI len (%zu) longer than maximum writable %zu", uri_len, max_uri_len);
1808 		return -ENOMEM;
1809 	}
1810 
1811 	originate = (struct bt_tbs_call_cp_originate *)write_buf;
1812 	originate->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
1813 	(void)memcpy(originate->uri, uri, uri_len);
1814 
1815 	return bt_gatt_write_without_response(conn, inst->call_cp_sub_params.value_handle,
1816 					      originate,
1817 					      sizeof(*originate) + uri_len,
1818 					      false);
1819 }
1820 #endif /* defined(CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL) */
1821 
1822 #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)1823 int bt_tbs_client_join_calls(struct bt_conn *conn, uint8_t inst_index,
1824 			     const uint8_t *call_indexes, uint8_t count)
1825 {
1826 	if (conn == NULL) {
1827 		return -ENOTCONN;
1828 	}
1829 
1830 	/* Write to call control point */
1831 	if (call_indexes && count > 1 &&
1832 	    count <= CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
1833 		struct bt_tbs_instance *inst;
1834 		struct bt_tbs_call_cp_join *join;
1835 		uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
1836 		const size_t max_call_cnt = sizeof(write_buf) - sizeof(join->opcode);
1837 
1838 		inst = tbs_inst_by_index(conn, inst_index);
1839 		if (inst == NULL) {
1840 			return -EINVAL;
1841 		}
1842 
1843 		if (inst->call_cp_sub_params.value_handle == 0) {
1844 			LOG_DBG("Handle not set");
1845 			return -EINVAL;
1846 		}
1847 
1848 		if (count > max_call_cnt) {
1849 			LOG_DBG("Call count (%u) larger than maximum writable %zu", count,
1850 				max_call_cnt);
1851 			return -ENOMEM;
1852 		}
1853 
1854 		join = (struct bt_tbs_call_cp_join *)write_buf;
1855 
1856 		join->opcode = BT_TBS_CALL_OPCODE_JOIN;
1857 		(void)memcpy(join->call_indexes, call_indexes, count);
1858 
1859 		return bt_gatt_write_without_response(conn,
1860 						      inst->call_cp_sub_params.value_handle,
1861 						      join,
1862 						      sizeof(*join) + count,
1863 						      false);
1864 	}
1865 
1866 	return -EINVAL;
1867 }
1868 #endif /* defined(CONFIG_BT_TBS_CLIENT_JOIN_CALLS) */
1869 
1870 #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)1871 int bt_tbs_client_set_signal_strength_interval(struct bt_conn *conn,
1872 					       uint8_t inst_index,
1873 					       uint8_t interval)
1874 {
1875 	struct bt_tbs_instance *inst;
1876 
1877 	if (conn == NULL) {
1878 		return -ENOTCONN;
1879 	}
1880 
1881 	inst = tbs_inst_by_index(conn, inst_index);
1882 	if (inst == NULL) {
1883 		return -EINVAL;
1884 	}
1885 
1886 	/* Populate Outgoing Remote URI */
1887 	if (inst->signal_interval_handle == 0) {
1888 		LOG_DBG("Handle not set");
1889 		return -EINVAL;
1890 	}
1891 
1892 	return bt_gatt_write_without_response(conn,
1893 					      inst->signal_interval_handle,
1894 					      &interval, sizeof(interval),
1895 					      false);
1896 }
1897 #endif /* defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
1898 
1899 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
bt_tbs_client_read_bearer_provider_name(struct bt_conn * conn,uint8_t inst_index)1900 int bt_tbs_client_read_bearer_provider_name(struct bt_conn *conn,
1901 					    uint8_t inst_index)
1902 {
1903 	struct bt_tbs_instance *inst;
1904 
1905 	if (conn == NULL) {
1906 		return -ENOTCONN;
1907 	}
1908 
1909 	inst = tbs_inst_by_index(conn, inst_index);
1910 	if (inst == NULL) {
1911 		return -EINVAL;
1912 	}
1913 
1914 	if (inst->name_sub_params.value_handle == 0) {
1915 		LOG_DBG("Handle not set");
1916 		return -EINVAL;
1917 	}
1918 
1919 	return tbs_client_gatt_read(conn, inst, inst->name_sub_params.value_handle,
1920 				    read_bearer_provider_name_cb);
1921 }
1922 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
1923 
1924 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
bt_tbs_client_read_bearer_uci(struct bt_conn * conn,uint8_t inst_index)1925 int bt_tbs_client_read_bearer_uci(struct bt_conn *conn, uint8_t inst_index)
1926 {
1927 	struct bt_tbs_instance *inst;
1928 
1929 	if (conn == NULL) {
1930 		return -ENOTCONN;
1931 	}
1932 
1933 	inst = tbs_inst_by_index(conn, inst_index);
1934 	if (inst == NULL) {
1935 		return -EINVAL;
1936 	}
1937 
1938 	if (inst->bearer_uci_handle == 0) {
1939 		LOG_DBG("Handle not set");
1940 		return -EINVAL;
1941 	}
1942 
1943 	return tbs_client_gatt_read(conn, inst, inst->bearer_uci_handle, read_bearer_uci_cb);
1944 }
1945 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
1946 
1947 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
bt_tbs_client_read_technology(struct bt_conn * conn,uint8_t inst_index)1948 int bt_tbs_client_read_technology(struct bt_conn *conn, uint8_t inst_index)
1949 {
1950 	struct bt_tbs_instance *inst;
1951 
1952 	if (conn == NULL) {
1953 		return -ENOTCONN;
1954 	}
1955 
1956 	inst = tbs_inst_by_index(conn, inst_index);
1957 	if (inst == NULL) {
1958 		return -EINVAL;
1959 	}
1960 
1961 	if (inst->technology_sub_params.value_handle == 0) {
1962 		LOG_DBG("Handle not set");
1963 		return -EINVAL;
1964 	}
1965 
1966 	return tbs_client_gatt_read(conn, inst, inst->technology_sub_params.value_handle,
1967 				    read_technology_cb);
1968 }
1969 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
1970 
1971 #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)1972 int bt_tbs_client_read_uri_list(struct bt_conn *conn, uint8_t inst_index)
1973 {
1974 	struct bt_tbs_instance *inst;
1975 
1976 	if (conn == NULL) {
1977 		return -ENOTCONN;
1978 	}
1979 
1980 	inst = tbs_inst_by_index(conn, inst_index);
1981 	if (inst == NULL) {
1982 		return -EINVAL;
1983 	}
1984 
1985 	if (inst->uri_list_handle == 0) {
1986 		LOG_DBG("Handle not set");
1987 		return -EINVAL;
1988 	}
1989 
1990 	return tbs_client_gatt_read(conn, inst, inst->uri_list_handle, read_uri_list_cb);
1991 }
1992 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
1993 
1994 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
bt_tbs_client_read_signal_strength(struct bt_conn * conn,uint8_t inst_index)1995 int bt_tbs_client_read_signal_strength(struct bt_conn *conn, uint8_t inst_index)
1996 {
1997 	struct bt_tbs_instance *inst;
1998 
1999 	if (conn == NULL) {
2000 		return -ENOTCONN;
2001 	}
2002 
2003 	inst = tbs_inst_by_index(conn, inst_index);
2004 	if (inst == NULL) {
2005 		return -EINVAL;
2006 	}
2007 
2008 	if (inst->signal_strength_sub_params.value_handle == 0) {
2009 		LOG_DBG("Handle not set");
2010 		return -EINVAL;
2011 	}
2012 
2013 	return tbs_client_gatt_read(conn, inst, inst->signal_strength_sub_params.value_handle,
2014 				    read_signal_strength_cb);
2015 }
2016 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
2017 
2018 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL)
bt_tbs_client_read_signal_interval(struct bt_conn * conn,uint8_t inst_index)2019 int bt_tbs_client_read_signal_interval(struct bt_conn *conn, uint8_t inst_index)
2020 {
2021 	struct bt_tbs_instance *inst;
2022 
2023 	if (conn == NULL) {
2024 		return -ENOTCONN;
2025 	}
2026 
2027 	inst = tbs_inst_by_index(conn, inst_index);
2028 	if (inst == NULL) {
2029 		return -EINVAL;
2030 	}
2031 
2032 	if (inst->signal_interval_handle == 0) {
2033 		LOG_DBG("Handle not set");
2034 		return -EINVAL;
2035 	}
2036 
2037 	return tbs_client_gatt_read(conn, inst, inst->signal_interval_handle,
2038 				    read_signal_interval_cb);
2039 }
2040 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
2041 
2042 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
bt_tbs_client_read_current_calls(struct bt_conn * conn,uint8_t inst_index)2043 int bt_tbs_client_read_current_calls(struct bt_conn *conn, uint8_t inst_index)
2044 {
2045 	struct bt_tbs_instance *inst;
2046 
2047 	if (conn == NULL) {
2048 		return -ENOTCONN;
2049 	}
2050 
2051 	inst = tbs_inst_by_index(conn, inst_index);
2052 	if (inst == NULL) {
2053 		return -EINVAL;
2054 	}
2055 
2056 	if (inst->current_calls_sub_params.value_handle == 0) {
2057 		LOG_DBG("Handle not set");
2058 		return -EINVAL;
2059 	}
2060 
2061 	return tbs_client_gatt_read(conn, inst, inst->current_calls_sub_params.value_handle,
2062 				    read_current_calls_cb);
2063 }
2064 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
2065 
2066 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
bt_tbs_client_read_ccid(struct bt_conn * conn,uint8_t inst_index)2067 int bt_tbs_client_read_ccid(struct bt_conn *conn, uint8_t inst_index)
2068 {
2069 	struct bt_tbs_instance *inst;
2070 
2071 	if (conn == NULL) {
2072 		return -ENOTCONN;
2073 	}
2074 
2075 	inst = tbs_inst_by_index(conn, inst_index);
2076 	if (inst == NULL) {
2077 		return -EINVAL;
2078 	}
2079 
2080 	if (inst->ccid_handle == 0) {
2081 		LOG_DBG("Handle not set");
2082 		return -EINVAL;
2083 	}
2084 
2085 	return tbs_client_gatt_read(conn, inst, inst->ccid_handle, read_ccid_cb);
2086 }
2087 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
2088 
2089 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
bt_tbs_client_read_call_uri(struct bt_conn * conn,uint8_t inst_index)2090 int bt_tbs_client_read_call_uri(struct bt_conn *conn, uint8_t inst_index)
2091 {
2092 	struct bt_tbs_instance *inst;
2093 
2094 	if (conn == NULL) {
2095 		return -ENOTCONN;
2096 	}
2097 
2098 	inst = tbs_inst_by_index(conn, inst_index);
2099 	if (inst == NULL) {
2100 		return -EINVAL;
2101 	}
2102 
2103 	if (inst->in_target_uri_sub_params.value_handle == 0) {
2104 		LOG_DBG("Handle not set");
2105 		return -EINVAL;
2106 	}
2107 
2108 	return tbs_client_gatt_read(conn, inst, inst->in_target_uri_sub_params.value_handle,
2109 				    read_call_uri_cb);
2110 }
2111 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
2112 
2113 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
bt_tbs_client_read_status_flags(struct bt_conn * conn,uint8_t inst_index)2114 int bt_tbs_client_read_status_flags(struct bt_conn *conn, uint8_t inst_index)
2115 {
2116 	struct bt_tbs_instance *inst;
2117 
2118 	if (conn == NULL) {
2119 		return -ENOTCONN;
2120 	}
2121 
2122 	inst = tbs_inst_by_index(conn, inst_index);
2123 	if (inst == NULL) {
2124 		return -EINVAL;
2125 	}
2126 
2127 	if (inst->status_flags_sub_params.value_handle == 0) {
2128 		LOG_DBG("Handle not set");
2129 		return -EINVAL;
2130 	}
2131 
2132 	return tbs_client_gatt_read(conn, inst, inst->status_flags_sub_params.value_handle,
2133 				    read_status_flags_cb);
2134 }
2135 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
2136 
bt_tbs_client_read_call_state(struct bt_conn * conn,uint8_t inst_index)2137 int bt_tbs_client_read_call_state(struct bt_conn *conn, uint8_t inst_index)
2138 {
2139 	struct bt_tbs_instance *inst;
2140 
2141 	if (conn == NULL) {
2142 		return -ENOTCONN;
2143 	}
2144 
2145 	inst = tbs_inst_by_index(conn, inst_index);
2146 	if (inst == NULL) {
2147 		return -EINVAL;
2148 	}
2149 
2150 	if (inst->call_state_sub_params.value_handle == 0) {
2151 		LOG_DBG("Handle not set");
2152 		return -EINVAL;
2153 	}
2154 
2155 	return tbs_client_gatt_read(conn, inst, inst->call_state_sub_params.value_handle,
2156 				    read_call_state_cb);
2157 }
2158 
2159 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
bt_tbs_client_read_optional_opcodes(struct bt_conn * conn,uint8_t inst_index)2160 int bt_tbs_client_read_optional_opcodes(struct bt_conn *conn,
2161 					uint8_t inst_index)
2162 {
2163 	struct bt_tbs_instance *inst;
2164 
2165 	if (conn == NULL) {
2166 		return -ENOTCONN;
2167 	}
2168 
2169 	inst = tbs_inst_by_index(conn, inst_index);
2170 	if (inst == NULL) {
2171 		return -EINVAL;
2172 	}
2173 
2174 	if (inst->optional_opcodes_handle == 0) {
2175 		LOG_DBG("Handle not set");
2176 		return -EINVAL;
2177 	}
2178 
2179 	return tbs_client_gatt_read(conn, inst, inst->optional_opcodes_handle,
2180 				    read_optional_opcodes_cb);
2181 }
2182 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
2183 
2184 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
bt_tbs_client_read_remote_uri(struct bt_conn * conn,uint8_t inst_index)2185 int bt_tbs_client_read_remote_uri(struct bt_conn *conn, uint8_t inst_index)
2186 {
2187 	struct bt_tbs_instance *inst;
2188 
2189 	if (conn == NULL) {
2190 		return -ENOTCONN;
2191 	}
2192 
2193 	inst = tbs_inst_by_index(conn, inst_index);
2194 	if (inst == NULL) {
2195 		return -EINVAL;
2196 	}
2197 
2198 	if (inst->incoming_call_sub_params.value_handle == 0) {
2199 		LOG_DBG("Handle not set");
2200 		return -EINVAL;
2201 	}
2202 
2203 	return tbs_client_gatt_read(conn, inst, inst->incoming_call_sub_params.value_handle,
2204 				    read_remote_uri_cb);
2205 }
2206 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
2207 
2208 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
bt_tbs_client_read_friendly_name(struct bt_conn * conn,uint8_t inst_index)2209 int bt_tbs_client_read_friendly_name(struct bt_conn *conn, uint8_t inst_index)
2210 {
2211 	struct bt_tbs_instance *inst;
2212 
2213 	if (conn == NULL) {
2214 		return -ENOTCONN;
2215 	}
2216 
2217 	inst = tbs_inst_by_index(conn, inst_index);
2218 	if (inst == NULL) {
2219 		return -EINVAL;
2220 	}
2221 
2222 	if (inst->friendly_name_sub_params.value_handle == 0) {
2223 		LOG_DBG("Handle not set");
2224 		return -EINVAL;
2225 	}
2226 
2227 	return tbs_client_gatt_read(conn, inst, inst->friendly_name_sub_params.value_handle,
2228 				    read_friendly_name_cb);
2229 }
2230 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
2231 
bt_tbs_client_discover(struct bt_conn * conn)2232 int bt_tbs_client_discover(struct bt_conn *conn)
2233 {
2234 	uint8_t conn_index;
2235 	struct bt_tbs_server_inst *srv_inst;
2236 
2237 	if (conn == NULL) {
2238 		return -ENOTCONN;
2239 	}
2240 
2241 	conn_index = bt_conn_index(conn);
2242 	srv_inst = &srv_insts[conn_index];
2243 
2244 	if (srv_inst->current_inst) {
2245 		return -EBUSY;
2246 	}
2247 
2248 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
2249 	(void)memset(srv_inst->tbs_insts, 0, sizeof(srv_inst->tbs_insts)); /* reset data */
2250 	srv_inst->inst_cnt = 0;
2251 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
2252 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
2253 	(void)memset(&srv_inst->gtbs_inst, 0, sizeof(srv_inst->gtbs_inst)); /* reset data */
2254 	return primary_discover_gtbs(conn);
2255 #else
2256 	return primary_discover_tbs(conn);
2257 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
2258 }
2259 
bt_tbs_client_register_cb(const struct bt_tbs_client_cb * cbs)2260 void bt_tbs_client_register_cb(const struct bt_tbs_client_cb *cbs)
2261 {
2262 	tbs_client_cbs = cbs;
2263 }
2264 
2265 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
tbs_instance_ccid_is_eq(struct bt_tbs_instance * inst,void * user_data)2266 static bool tbs_instance_ccid_is_eq(struct bt_tbs_instance *inst, void *user_data)
2267 {
2268 	uint8_t ccid = POINTER_TO_UINT(user_data);
2269 
2270 	return inst->ccid == ccid;
2271 }
2272 
bt_tbs_client_get_by_ccid(const struct bt_conn * conn,uint8_t ccid)2273 struct bt_tbs_instance *bt_tbs_client_get_by_ccid(const struct bt_conn *conn,
2274 						  uint8_t ccid)
2275 {
2276 	struct bt_tbs_server_inst *server;
2277 
2278 	CHECKIF(conn == NULL) {
2279 		LOG_DBG("conn was NULL");
2280 		return NULL;
2281 	}
2282 
2283 	server = &srv_insts[bt_conn_index(conn)];
2284 
2285 	return tbs_instance_find(server, tbs_instance_ccid_is_eq, UINT_TO_POINTER(ccid));
2286 }
2287 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
2288