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