1 /* Bluetooth TBS - Telephone Bearer Service
2 *
3 * Copyright (c) 2020 Bose Corporation
4 * Copyright (c) 2021-2024 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <sys/types.h>
15
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/att.h>
18 #include <zephyr/bluetooth/audio/ccid.h>
19 #include <zephyr/bluetooth/audio/tbs.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/conn.h>
22 #include <zephyr/bluetooth/gatt.h>
23 #include <zephyr/bluetooth/uuid.h>
24 #include <zephyr/init.h>
25 #include <zephyr/kernel.h>
26 #include <zephyr/logging/log.h>
27 #include <zephyr/net_buf.h>
28 #include <zephyr/sys/__assert.h>
29 #include <zephyr/sys/byteorder.h>
30 #include <zephyr/sys/check.h>
31 #include <zephyr/sys/util.h>
32 #include <zephyr/sys/util_macro.h>
33 #include <zephyr/types.h>
34
35 #include "audio_internal.h"
36 #include "tbs_internal.h"
37
38 LOG_MODULE_REGISTER(bt_tbs, CONFIG_BT_TBS_LOG_LEVEL);
39
40 #define BT_TBS_VALID_STATUS_FLAGS(val) ((val) <= (BIT(0) | BIT(1)))
41
42 /* A service instance can either be a GTBS or a TBS instance */
43 struct tbs_inst {
44 /* Attribute values */
45 char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
46 char uci[BT_TBS_MAX_UCI_SIZE];
47 uint8_t technology;
48 uint8_t signal_strength;
49 uint8_t signal_strength_interval;
50 uint8_t ccid;
51 uint16_t optional_opcodes;
52 uint16_t status_flags;
53 struct bt_tbs_in_uri incoming_uri;
54 struct bt_tbs_in_uri friendly_name;
55 struct bt_tbs_in_uri in_call;
56 char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
57 struct bt_tbs_terminate_reason terminate_reason;
58 struct bt_tbs_call calls[CONFIG_BT_TBS_MAX_CALLS];
59
60 bool notify_current_calls;
61 bool notify_call_states;
62 bool pending_signal_strength_notification;
63 struct k_work_delayable reporting_interval_work;
64
65 /** Service Attributes */
66 const struct bt_gatt_attr *attrs;
67 /** Service Attribute count */
68 size_t attr_count;
69
70 bool authorization_required;
71 };
72
73 static struct tbs_inst svc_insts[CONFIG_BT_TBS_BEARER_COUNT];
74 static struct tbs_inst gtbs_inst;
75
76 #define READ_BUF_SIZE \
77 MAX(BT_ATT_MAX_ATTRIBUTE_LEN, \
78 (CONFIG_BT_TBS_MAX_CALLS * sizeof(struct bt_tbs_current_call_item) * \
79 (1U + ARRAY_SIZE(svc_insts))))
80 NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, READ_BUF_SIZE);
81
82 /* Used to notify app with held calls in case of join */
83 static struct bt_tbs_call *held_calls[CONFIG_BT_TBS_MAX_CALLS];
84 static uint8_t held_calls_cnt;
85
86 static struct bt_tbs_cb *tbs_cbs;
87
inst_is_registered(const struct tbs_inst * inst)88 static bool inst_is_registered(const struct tbs_inst *inst)
89 {
90 return inst->attrs != NULL;
91 }
92
inst_is_gtbs(const struct tbs_inst * inst)93 static bool inst_is_gtbs(const struct tbs_inst *inst)
94 {
95 if (CONFIG_BT_TBS_BEARER_COUNT > 0) {
96 return inst == >bs_inst;
97 } else {
98 return true;
99 }
100 }
101
inst_index(const struct tbs_inst * inst)102 static uint8_t inst_index(const struct tbs_inst *inst)
103 {
104 ptrdiff_t index = 0;
105
106 __ASSERT_NO_MSG(inst);
107
108 if (inst_is_gtbs(inst)) {
109 return BT_TBS_GTBS_INDEX;
110 }
111
112 index = inst - svc_insts;
113 __ASSERT(index >= 0 && index < ARRAY_SIZE(svc_insts), "Invalid tbs_inst pointer");
114
115 return (uint8_t)index;
116 }
117
inst_lookup_index(uint8_t index)118 static struct tbs_inst *inst_lookup_index(uint8_t index)
119 {
120 struct tbs_inst *inst = NULL;
121
122 if (index == BT_TBS_GTBS_INDEX) {
123 inst = >bs_inst;
124 } else if (ARRAY_SIZE(svc_insts) > 0U && index < ARRAY_SIZE(svc_insts)) {
125 inst = &svc_insts[index];
126 }
127
128 if (inst == NULL || !inst_is_registered(inst)) {
129 return NULL;
130 }
131
132 return inst;
133 }
134
lookup_call_in_inst(struct tbs_inst * inst,uint8_t call_index)135 static struct bt_tbs_call *lookup_call_in_inst(struct tbs_inst *inst, uint8_t call_index)
136 {
137 if (call_index == BT_TBS_FREE_CALL_INDEX) {
138 return NULL;
139 }
140
141 for (int i = 0; i < ARRAY_SIZE(svc_insts[i].calls); i++) {
142 if (inst->calls[i].index == call_index) {
143 return &inst->calls[i];
144 }
145 }
146
147 return NULL;
148 }
149
150 /**
151 * @brief Finds and returns a call
152 *
153 * @param call_index The ID of the call
154 * @return struct bt_tbs_call* Pointer to the call. NULL if not found
155 */
lookup_call(uint8_t call_index)156 static struct bt_tbs_call *lookup_call(uint8_t call_index)
157 {
158 struct bt_tbs_call *call;
159
160 if (call_index == BT_TBS_FREE_CALL_INDEX) {
161 return NULL;
162 }
163
164 call = lookup_call_in_inst(>bs_inst, call_index);
165 if (call != NULL) {
166 return call;
167 }
168
169 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
170 call = lookup_call_in_inst(&svc_insts[i], call_index);
171 if (call != NULL) {
172 return call;
173 }
174 }
175
176 return NULL;
177 }
178
inst_check_attr(struct tbs_inst * inst,const struct bt_gatt_attr * attr)179 static bool inst_check_attr(struct tbs_inst *inst, const struct bt_gatt_attr *attr)
180 {
181 for (size_t j = 0; j < inst->attr_count; j++) {
182 if (&inst->attrs[j] == attr) {
183 return true;
184 }
185 }
186
187 return false;
188 }
189
lookup_inst_by_attr(const struct bt_gatt_attr * attr)190 static struct tbs_inst *lookup_inst_by_attr(const struct bt_gatt_attr *attr)
191 {
192 if (attr == NULL) {
193 return NULL;
194 }
195
196 for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
197 if (inst_check_attr(&svc_insts[i], attr)) {
198 return &svc_insts[i];
199 }
200 }
201
202 if (inst_check_attr(>bs_inst, attr)) {
203 return >bs_inst;
204 }
205
206 return NULL;
207 }
208
lookup_inst_by_call_index(uint8_t call_index)209 static struct tbs_inst *lookup_inst_by_call_index(uint8_t call_index)
210 {
211 if (call_index == BT_TBS_FREE_CALL_INDEX) {
212 return NULL;
213 }
214
215 if (lookup_call_in_inst(>bs_inst, call_index) != NULL) {
216 return >bs_inst;
217 }
218
219 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
220 if (lookup_call_in_inst(&svc_insts[i], call_index) != NULL) {
221 return &svc_insts[i];
222 }
223 }
224
225 return NULL;
226 }
227
is_authorized(const struct tbs_inst * inst,struct bt_conn * conn)228 static bool is_authorized(const struct tbs_inst *inst, struct bt_conn *conn)
229 {
230 if (inst->authorization_required) {
231 if (tbs_cbs != NULL && tbs_cbs->authorize != NULL) {
232 return tbs_cbs->authorize(conn);
233 } else {
234 return false;
235 }
236 }
237
238 return true;
239 }
240
uri_scheme_in_list(const char * uri_scheme,const char * uri_scheme_list)241 static bool uri_scheme_in_list(const char *uri_scheme, const char *uri_scheme_list)
242 {
243 const size_t scheme_len = strlen(uri_scheme);
244 const size_t scheme_list_len = strlen(uri_scheme_list);
245 const char *uri_scheme_cand = uri_scheme_list;
246 size_t uri_scheme_cand_len;
247 size_t start_idx = 0;
248
249 for (size_t i = 0; i < scheme_list_len; i++) {
250 if (uri_scheme_list[i] == ',') {
251 uri_scheme_cand_len = i - start_idx;
252 if (uri_scheme_cand_len != scheme_len) {
253 continue;
254 }
255
256 if (memcmp(uri_scheme, uri_scheme_cand, scheme_len) == 0) {
257 return true;
258 }
259
260 if (i + 1 < scheme_list_len) {
261 uri_scheme_cand = &uri_scheme_list[i + 1];
262 }
263 }
264 }
265
266 return false;
267 }
268
lookup_inst_by_uri_scheme(const uint8_t * uri,uint8_t uri_len)269 static struct tbs_inst *lookup_inst_by_uri_scheme(const uint8_t *uri, uint8_t uri_len)
270 {
271 char uri_scheme[CONFIG_BT_TBS_MAX_URI_LENGTH] = {0};
272
273 if (uri_len == 0) {
274 return NULL;
275 }
276
277 /* Look for ':' between the first and last char */
278 for (uint8_t i = 1U; i < uri_len - 1U; i++) {
279 if (uri[i] == ':') {
280 (void)memcpy(uri_scheme, uri, i);
281 break;
282 }
283 }
284
285 if (uri_scheme[0] == '\0') {
286 /* No URI scheme found */
287 return NULL;
288 }
289
290 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
291 for (size_t j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
292 if (uri_scheme_in_list(uri_scheme, svc_insts[i].uri_scheme_list)) {
293 return &svc_insts[i];
294 }
295 }
296 }
297
298 /* If not found in any TBS instance, check GTBS */
299 if (uri_scheme_in_list(uri_scheme, gtbs_inst.uri_scheme_list)) {
300 return >bs_inst;
301 }
302
303 return NULL;
304 }
305
tbs_set_terminate_reason(struct tbs_inst * inst,uint8_t call_index,uint8_t reason)306 static void tbs_set_terminate_reason(struct tbs_inst *inst, uint8_t call_index, uint8_t reason)
307 {
308 inst->terminate_reason.call_index = call_index;
309 inst->terminate_reason.reason = reason;
310 LOG_DBG("Index %u: call index 0x%02x, reason %s", inst_index(inst), call_index,
311 bt_tbs_term_reason_str(reason));
312
313 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TERMINATE_REASON, inst->attrs,
314 (void *)&inst->terminate_reason, sizeof(inst->terminate_reason));
315 }
316
317 /**
318 * @brief Gets the next free call_index
319 *
320 * For each new call, the call index should be incremented and wrap at 255.
321 * However, the index = 0 is reserved for outgoing calls
322 *
323 * Call indexes are shared among all bearers, so there is always a 1:1 between a call index and a
324 * bearer
325 *
326 * @return uint8_t The next free call index
327 */
next_free_call_index(void)328 static uint8_t next_free_call_index(void)
329 {
330 for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
331 static uint8_t next_call_index;
332 const struct bt_tbs_call *call;
333
334 /* For each new call, the call index should be incremented */
335 next_call_index++;
336
337 if (next_call_index == BT_TBS_FREE_CALL_INDEX) {
338 /* call_index = 0 reserved for outgoing calls */
339 next_call_index = 1;
340 }
341
342 call = lookup_call(next_call_index);
343 if (call == NULL) {
344 return next_call_index;
345 }
346 }
347
348 LOG_DBG("No more free call spots");
349
350 return BT_TBS_FREE_CALL_INDEX;
351 }
352
call_alloc(struct tbs_inst * inst,uint8_t state,const uint8_t * uri,uint16_t uri_len)353 static struct bt_tbs_call *call_alloc(struct tbs_inst *inst, uint8_t state, const uint8_t *uri,
354 uint16_t uri_len)
355 {
356 struct bt_tbs_call *free_call = NULL;
357
358 for (size_t i = 0; i < ARRAY_SIZE(inst->calls); i++) {
359 if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
360 free_call = &inst->calls[i];
361 break;
362 }
363 }
364
365 if (free_call == NULL) {
366 return NULL;
367 }
368
369 __ASSERT_NO_MSG(uri_len < sizeof(free_call->remote_uri));
370
371 memset(free_call, 0, sizeof(*free_call));
372
373 /* Get the next free call_index */
374 free_call->index = next_free_call_index();
375 __ASSERT_NO_MSG(free_call->index != BT_TBS_FREE_CALL_INDEX);
376
377 free_call->state = state;
378 (void)memcpy(free_call->remote_uri, uri, uri_len);
379 free_call->remote_uri[uri_len] = '\0';
380
381 return free_call;
382 }
383
call_free(struct bt_tbs_call * call)384 static void call_free(struct bt_tbs_call *call)
385 {
386 call->index = BT_TBS_FREE_CALL_INDEX;
387 }
388
net_buf_put_call_states_by_inst(const struct tbs_inst * inst,struct net_buf_simple * buf)389 static void net_buf_put_call_states_by_inst(const struct tbs_inst *inst, struct net_buf_simple *buf)
390 {
391 const struct bt_tbs_call *call;
392 const struct bt_tbs_call *calls;
393 size_t call_count;
394
395 calls = inst->calls;
396 call_count = ARRAY_SIZE(inst->calls);
397
398 for (size_t i = 0; i < call_count; i++) {
399 call = &calls[i];
400 if (call->index == BT_TBS_FREE_CALL_INDEX) {
401 continue;
402 }
403
404 if (buf->len + 3U > buf->size) {
405 LOG_WRN("Not able to store all call states in buffer");
406 return;
407 }
408
409 net_buf_simple_add_u8(buf, call->index);
410 net_buf_simple_add_u8(buf, call->state);
411 net_buf_simple_add_u8(buf, call->flags);
412 }
413 }
414
net_buf_put_call_states(const struct tbs_inst * inst,struct net_buf_simple * buf)415 static void net_buf_put_call_states(const struct tbs_inst *inst, struct net_buf_simple *buf)
416 {
417 net_buf_simple_reset(buf);
418
419 net_buf_put_call_states_by_inst(inst, buf);
420
421 /* For GTBS we add all the calls the GTBS bearer has itself, as well as all the other
422 * bearers
423 */
424 if (inst_is_gtbs(inst)) {
425 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
426 net_buf_put_call_states_by_inst(&svc_insts[i], buf);
427 }
428 }
429 }
430
net_buf_put_current_calls_by_inst(const struct tbs_inst * inst,struct net_buf_simple * buf)431 static void net_buf_put_current_calls_by_inst(const struct tbs_inst *inst,
432 struct net_buf_simple *buf)
433 {
434 const struct bt_tbs_call *call;
435 const struct bt_tbs_call *calls;
436 size_t call_count;
437 size_t uri_length;
438 size_t item_len;
439
440 calls = inst->calls;
441 call_count = ARRAY_SIZE(inst->calls);
442
443 for (size_t i = 0; i < call_count; i++) {
444 call = &calls[i];
445 if (call->index == BT_TBS_FREE_CALL_INDEX) {
446 continue;
447 }
448
449 uri_length = strlen(call->remote_uri);
450 item_len = sizeof(call->index) + sizeof(call->state) + sizeof(call->flags) +
451 uri_length;
452
453 __ASSERT_NO_MSG(item_len <= UINT8_MAX);
454
455 if (buf->len + sizeof(uint8_t) + item_len > buf->size) {
456 LOG_WRN("Not able to store all calls in buffer");
457 return;
458 }
459
460 net_buf_simple_add_u8(buf, (uint8_t)item_len);
461 net_buf_simple_add_u8(buf, call->index);
462 net_buf_simple_add_u8(buf, call->state);
463 net_buf_simple_add_u8(buf, call->flags);
464 net_buf_simple_add_mem(buf, call->remote_uri, uri_length);
465 }
466 }
467
net_buf_put_current_calls(const struct tbs_inst * inst,struct net_buf_simple * buf)468 static void net_buf_put_current_calls(const struct tbs_inst *inst, struct net_buf_simple *buf)
469 {
470 net_buf_simple_reset(buf);
471
472 net_buf_put_current_calls_by_inst(inst, buf);
473
474 /* For GTBS we add all the calls the GTBS bearer has itself, as well as all the other
475 * bearers
476 */
477 if (inst_is_gtbs(inst)) {
478 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
479 net_buf_put_current_calls_by_inst(&svc_insts[i], buf);
480 }
481 }
482 }
483
inst_notify_calls(const struct tbs_inst * inst)484 static int inst_notify_calls(const struct tbs_inst *inst)
485 {
486 int err;
487
488 if (inst->notify_call_states) {
489 net_buf_put_call_states(inst, &read_buf);
490
491 err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_CALL_STATE, inst->attrs, read_buf.data,
492 read_buf.len);
493 if (err != 0) {
494 return err;
495 }
496 }
497
498 if (inst->notify_current_calls) {
499 net_buf_put_current_calls(inst, &read_buf);
500
501 err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_LIST_CURRENT_CALLS, inst->attrs,
502 read_buf.data, read_buf.len);
503 if (err != 0) {
504 return err;
505 }
506 }
507
508 return 0;
509 }
510
notify_calls(const struct tbs_inst * inst)511 static int notify_calls(const struct tbs_inst *inst)
512 {
513 int err;
514
515 if (inst == NULL) {
516 return -EINVAL;
517 }
518
519 /* Notify TBS */
520 err = inst_notify_calls(inst);
521 if (err != 0) {
522 return err;
523 }
524
525 if (!inst_is_gtbs(inst)) {
526 /* If the instance is different than the GTBS notify on the GTBS instance as well */
527 err = inst_notify_calls(>bs_inst);
528 if (err != 0) {
529 return err;
530 }
531 }
532
533 return 0;
534 }
535
read_provider_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)536 static ssize_t read_provider_name(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
537 uint16_t len, uint16_t offset)
538 {
539 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
540
541 LOG_DBG("Index %u, Provider name %s", inst_index(inst), inst->provider_name);
542
543 return bt_gatt_attr_read(conn, attr, buf, len, offset, inst->provider_name,
544 strlen(inst->provider_name));
545 }
546
provider_name_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)547 static void provider_name_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
548 {
549 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
550
551 if (inst != NULL) {
552 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
553 }
554 }
555
read_uci(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)556 static ssize_t read_uci(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
557 uint16_t len, uint16_t offset)
558 {
559 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
560
561 LOG_DBG("Index %u: UCI %s", inst_index(inst), inst->uci);
562
563 return bt_gatt_attr_read(conn, attr, buf, len, offset, inst->uci, strlen(inst->uci));
564 }
565
read_technology(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)566 static ssize_t read_technology(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
567 uint16_t len, uint16_t offset)
568 {
569 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
570
571 LOG_DBG("Index %u: Technology 0x%02x", inst_index(inst), inst->technology);
572
573 return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->technology,
574 sizeof(inst->technology));
575 }
576
technology_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)577 static void technology_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
578 {
579 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
580
581 if (inst != NULL) {
582 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
583 }
584 }
585
read_uri_scheme_list(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)586 static ssize_t read_uri_scheme_list(struct bt_conn *conn, const struct bt_gatt_attr *attr,
587 void *buf, uint16_t len, uint16_t offset)
588 {
589 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
590
591 net_buf_simple_reset(&read_buf);
592
593 net_buf_simple_add_mem(&read_buf, inst->uri_scheme_list, strlen(inst->uri_scheme_list));
594
595 if (inst_is_gtbs(inst)) {
596 /* TODO: Make uri schemes unique */
597 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
598 size_t uri_len = strlen(svc_insts[i].uri_scheme_list);
599
600 if (read_buf.len + uri_len >= read_buf.size) {
601 LOG_WRN("Cannot fit all TBS instances in GTBS "
602 "URI scheme list");
603 break;
604 }
605
606 net_buf_simple_add_mem(&read_buf, svc_insts[i].uri_scheme_list, uri_len);
607 }
608
609 LOG_DBG("GTBS: URI scheme %.*s", read_buf.len, read_buf.data);
610 } else {
611 LOG_DBG("Index %u: URI scheme %.*s", inst_index(inst), read_buf.len, read_buf.data);
612 }
613
614 return bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data, read_buf.len);
615 }
616
uri_scheme_list_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)617 static void uri_scheme_list_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
618 {
619 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
620
621 if (inst != NULL) {
622 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
623 }
624 }
625
read_signal_strength(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)626 static ssize_t read_signal_strength(struct bt_conn *conn, const struct bt_gatt_attr *attr,
627 void *buf, uint16_t len, uint16_t offset)
628 {
629 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
630
631 LOG_DBG("Index %u: Signal strength 0x%02x", inst_index(inst), inst->signal_strength);
632
633 return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->signal_strength,
634 sizeof(inst->signal_strength));
635 }
636
signal_strength_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)637 static void signal_strength_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
638 {
639 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
640
641 if (inst != NULL) {
642 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
643 }
644 }
645
read_signal_strength_interval(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)646 static ssize_t read_signal_strength_interval(struct bt_conn *conn, const struct bt_gatt_attr *attr,
647 void *buf, uint16_t len, uint16_t offset)
648 {
649 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
650
651 LOG_DBG("Index %u: Signal strength interval 0x%02x",
652 inst_index(inst), inst->signal_strength_interval);
653
654 return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->signal_strength_interval,
655 sizeof(inst->signal_strength_interval));
656 }
657
write_signal_strength_interval(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)658 static ssize_t write_signal_strength_interval(struct bt_conn *conn, const struct bt_gatt_attr *attr,
659 const void *buf, uint16_t len, uint16_t offset,
660 uint8_t flags)
661 {
662 struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
663 struct net_buf_simple net_buf;
664 uint8_t signal_strength_interval;
665
666 if (!is_authorized(inst, conn)) {
667 return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
668 }
669
670 if (offset != 0) {
671 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
672 }
673
674 if (len != sizeof(signal_strength_interval)) {
675 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
676 }
677
678 net_buf_simple_init_with_data(&net_buf, (void *)buf, len);
679 signal_strength_interval = net_buf_simple_pull_u8(&net_buf);
680
681 inst->signal_strength_interval = signal_strength_interval;
682 LOG_DBG("Index %u: 0x%02x", inst_index(inst), signal_strength_interval);
683
684 return len;
685 }
686
current_calls_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)687 static void current_calls_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
688 {
689 struct tbs_inst *inst = lookup_inst_by_attr(attr);
690
691 if (inst != NULL) {
692 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
693 inst->notify_current_calls = (value == BT_GATT_CCC_NOTIFY);
694 }
695 }
696
read_current_calls(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)697 static ssize_t read_current_calls(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
698 uint16_t len, uint16_t offset)
699 {
700 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
701
702 LOG_DBG("Index %u", inst_index(inst));
703
704 net_buf_put_current_calls(inst, &read_buf);
705
706 if (offset == 0) {
707 LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Current calls");
708 }
709
710 return bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data, read_buf.len);
711 }
712
read_ccid(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)713 static ssize_t read_ccid(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
714 uint16_t len, uint16_t offset)
715 {
716 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
717
718 LOG_DBG("Index %u: CCID 0x%02x", inst_index(inst), inst->ccid);
719
720 return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->ccid, sizeof(inst->ccid));
721 }
722
read_status_flags(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)723 static ssize_t read_status_flags(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
724 uint16_t len, uint16_t offset)
725 {
726 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
727 const uint16_t status_flags_le = sys_cpu_to_le16(inst->optional_opcodes);
728
729 LOG_DBG("Index %u: status_flags 0x%04x", inst_index(inst), inst->status_flags);
730
731 return bt_gatt_attr_read(conn, attr, buf, len, offset, &status_flags_le,
732 sizeof(status_flags_le));
733 }
734
status_flags_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)735 static void status_flags_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
736 {
737 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
738
739 if (inst != NULL) {
740 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
741 }
742 }
743
read_incoming_uri(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)744 static ssize_t read_incoming_uri(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
745 uint16_t len, uint16_t offset)
746 {
747 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
748 const struct bt_tbs_in_uri *inc_call_target;
749 size_t val_len;
750
751 inc_call_target = &inst->incoming_uri;
752
753 LOG_DBG("Index %u: call index 0x%02x, URI %s", inst_index(inst),
754 inc_call_target->call_index, inc_call_target->uri);
755
756 if (!inc_call_target->call_index) {
757 LOG_DBG("URI not set");
758
759 return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
760 }
761
762 val_len = sizeof(inc_call_target->call_index) + strlen(inc_call_target->uri);
763
764 return bt_gatt_attr_read(conn, attr, buf, len, offset, inc_call_target, val_len);
765 }
766
incoming_uri_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)767 static void incoming_uri_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
768 {
769 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
770
771 if (inst != NULL) {
772 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
773 }
774 }
775
read_call_state(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)776 static ssize_t read_call_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
777 uint16_t len, uint16_t offset)
778 {
779 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
780
781 LOG_DBG("Index %u", inst_index(inst));
782
783 net_buf_put_call_states(inst, &read_buf);
784
785 if (offset == 0) {
786 LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Call state");
787 }
788
789 return bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data, read_buf.len);
790 }
791
call_state_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)792 static void call_state_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
793 {
794 struct tbs_inst *inst = lookup_inst_by_attr(attr);
795
796 if (inst != NULL) {
797 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
798 inst->notify_call_states = (value == BT_GATT_CCC_NOTIFY);
799 }
800 }
801
notify_ccp(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint8_t call_index,uint8_t opcode,uint8_t status)802 static int notify_ccp(struct bt_conn *conn, const struct bt_gatt_attr *attr, uint8_t call_index,
803 uint8_t opcode, uint8_t status)
804 {
805 const struct bt_tbs_call_cp_notify ccp_not = {
806 .call_index = call_index, .opcode = opcode, .status = status};
807
808 LOG_DBG("Notifying CCP: Call index %u, %s opcode and status %s", call_index,
809 bt_tbs_opcode_str(opcode), bt_tbs_status_str(status));
810
811 return bt_gatt_notify(conn, attr, &ccp_not, sizeof(ccp_not));
812 }
813
hold_other_calls(struct tbs_inst * inst,uint8_t call_index_cnt,const uint8_t * call_indexes)814 static void hold_other_calls(struct tbs_inst *inst, uint8_t call_index_cnt,
815 const uint8_t *call_indexes)
816 {
817 held_calls_cnt = 0;
818
819 for (int i = 0; i < ARRAY_SIZE(inst->calls); i++) {
820 bool hold_call = true;
821 uint8_t call_state;
822
823 for (int j = 0; j < call_index_cnt; j++) {
824 if (inst->calls[i].index == call_indexes[j]) {
825 hold_call = false;
826 break;
827 }
828 }
829
830 if (!hold_call) {
831 continue;
832 }
833
834 call_state = inst->calls[i].state;
835 if (call_state == BT_TBS_CALL_STATE_ACTIVE) {
836 inst->calls[i].state = BT_TBS_CALL_STATE_LOCALLY_HELD;
837 held_calls[held_calls_cnt++] = &inst->calls[i];
838 } else if (call_state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
839 inst->calls[i].state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
840 held_calls[held_calls_cnt++] = &inst->calls[i];
841 }
842 }
843 }
844
accept_call(struct tbs_inst * inst,const struct bt_tbs_call_cp_acc * ccp)845 static uint8_t accept_call(struct tbs_inst *inst, const struct bt_tbs_call_cp_acc *ccp)
846 {
847 struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
848
849 if (call == NULL) {
850 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
851 }
852
853 if (call->state == BT_TBS_CALL_STATE_INCOMING) {
854 call->state = BT_TBS_CALL_STATE_ACTIVE;
855
856 hold_other_calls(inst, 1, &ccp->call_index);
857
858 return BT_TBS_RESULT_CODE_SUCCESS;
859 } else {
860 return BT_TBS_RESULT_CODE_STATE_MISMATCH;
861 }
862 }
863
terminate_call(struct tbs_inst * inst,const struct bt_tbs_call_cp_term * ccp,uint8_t reason)864 static uint8_t terminate_call(struct tbs_inst *inst, const struct bt_tbs_call_cp_term *ccp,
865 uint8_t reason)
866 {
867 struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
868
869 if (call == NULL) {
870 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
871 }
872
873 call_free(call);
874 tbs_set_terminate_reason(inst, ccp->call_index, reason);
875
876 if (!inst_is_gtbs(inst)) {
877 /* If the instance is different than the GTBS we set the termination reason and
878 * notify on the GTBS instance as well
879 */
880 tbs_set_terminate_reason(>bs_inst, ccp->call_index, reason);
881 }
882
883 return BT_TBS_RESULT_CODE_SUCCESS;
884 }
885
tbs_hold_call(struct tbs_inst * inst,const struct bt_tbs_call_cp_hold * ccp)886 static uint8_t tbs_hold_call(struct tbs_inst *inst, const struct bt_tbs_call_cp_hold *ccp)
887 {
888 struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
889
890 if ((inst->optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
891 return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
892 }
893
894 if (call == NULL) {
895 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
896 }
897
898 if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
899 call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
900 } else if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
901 call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
902 } else if (call->state == BT_TBS_CALL_STATE_INCOMING) {
903 call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
904 } else {
905 return BT_TBS_RESULT_CODE_STATE_MISMATCH;
906 }
907
908 return BT_TBS_RESULT_CODE_SUCCESS;
909 }
910
retrieve_call(struct tbs_inst * inst,const struct bt_tbs_call_cp_retrieve * ccp)911 static uint8_t retrieve_call(struct tbs_inst *inst, const struct bt_tbs_call_cp_retrieve *ccp)
912 {
913 struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);
914
915 if ((inst->optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
916 return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
917 }
918
919 if (call == NULL) {
920 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
921 }
922
923 if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
924 call->state = BT_TBS_CALL_STATE_ACTIVE;
925 } else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
926 call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
927 } else {
928 return BT_TBS_RESULT_CODE_STATE_MISMATCH;
929 }
930
931 hold_other_calls(inst, 1, &ccp->call_index);
932
933 return BT_TBS_RESULT_CODE_SUCCESS;
934 }
935
originate_call(struct tbs_inst * inst,const struct bt_tbs_call_cp_originate * ccp,uint16_t uri_len,uint8_t * call_index)936 static int originate_call(struct tbs_inst *inst, const struct bt_tbs_call_cp_originate *ccp,
937 uint16_t uri_len, uint8_t *call_index)
938 {
939 struct bt_tbs_call *call;
940
941 /* Only allow one active outgoing call */
942 for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
943 if (inst->calls[i].state == BT_TBS_CALL_STATE_ALERTING) {
944 return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
945 }
946 }
947
948 if (!bt_tbs_valid_uri(ccp->uri, uri_len)) {
949 return BT_TBS_RESULT_CODE_INVALID_URI;
950 }
951
952 call = call_alloc(inst, BT_TBS_CALL_STATE_DIALING, ccp->uri, uri_len);
953 if (call == NULL) {
954 return BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
955 }
956
957 BT_TBS_CALL_FLAG_SET_OUTGOING(call->flags);
958
959 hold_other_calls(inst, 1, &call->index);
960
961 notify_calls(inst);
962 call->state = BT_TBS_CALL_STATE_ALERTING;
963 notify_calls(inst);
964
965 LOG_DBG("New call with call index %u", call->index);
966
967 *call_index = call->index;
968 return BT_TBS_RESULT_CODE_SUCCESS;
969 }
970
join_calls(struct tbs_inst * inst,const struct bt_tbs_call_cp_join * ccp,uint16_t call_index_cnt)971 static uint8_t join_calls(struct tbs_inst *inst, const struct bt_tbs_call_cp_join *ccp,
972 uint16_t call_index_cnt)
973 {
974 struct bt_tbs_call *joined_calls[CONFIG_BT_TBS_MAX_CALLS];
975 uint8_t call_state;
976
977 if ((inst->optional_opcodes & BT_TBS_FEATURE_JOIN) == 0) {
978 return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
979 }
980
981 /* Check length */
982 if (call_index_cnt < 2 || call_index_cnt > CONFIG_BT_TBS_MAX_CALLS) {
983 return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
984 }
985
986 /* Check for duplicates */
987 for (int i = 0; i < call_index_cnt; i++) {
988 for (int j = 0; j < i; j++) {
989 if (ccp->call_indexes[i] == ccp->call_indexes[j]) {
990 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
991 }
992 }
993 }
994
995 /* Validate that all calls are in a joinable state */
996 for (int i = 0; i < call_index_cnt; i++) {
997 joined_calls[i] = lookup_call_in_inst(inst, ccp->call_indexes[i]);
998 if (joined_calls[i] == NULL) {
999 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1000 }
1001
1002 call_state = joined_calls[i]->state;
1003
1004 if (call_state == BT_TBS_CALL_STATE_INCOMING) {
1005 return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
1006 }
1007
1008 if (call_state != BT_TBS_CALL_STATE_LOCALLY_HELD &&
1009 call_state != BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD &&
1010 call_state != BT_TBS_CALL_STATE_ACTIVE) {
1011 return BT_TBS_RESULT_CODE_STATE_MISMATCH;
1012 }
1013 }
1014
1015 /* Join all calls */
1016 for (int i = 0; i < call_index_cnt; i++) {
1017 call_state = joined_calls[i]->state;
1018
1019 if (call_state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
1020 joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
1021 } else if (call_state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
1022 joined_calls[i]->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
1023 } else if (call_state == BT_TBS_CALL_STATE_INCOMING) {
1024 joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
1025 }
1026 /* else active => Do nothing */
1027 }
1028
1029 hold_other_calls(inst, call_index_cnt, ccp->call_indexes);
1030
1031 return BT_TBS_RESULT_CODE_SUCCESS;
1032 }
1033
notify_app(struct bt_conn * conn,struct tbs_inst * inst,uint16_t len,const union bt_tbs_call_cp_t * ccp,uint8_t status,uint8_t call_index)1034 static void notify_app(struct bt_conn *conn, struct tbs_inst *inst, uint16_t len,
1035 const union bt_tbs_call_cp_t *ccp, uint8_t status, uint8_t call_index)
1036 {
1037 if (tbs_cbs == NULL) {
1038 return;
1039 }
1040
1041 switch (ccp->opcode) {
1042 case BT_TBS_CALL_OPCODE_ACCEPT:
1043 if (tbs_cbs->accept_call != NULL) {
1044 tbs_cbs->accept_call(conn, call_index);
1045 }
1046 break;
1047 case BT_TBS_CALL_OPCODE_TERMINATE:
1048 if (tbs_cbs->terminate_call != NULL) {
1049 tbs_cbs->terminate_call(conn, call_index, inst->terminate_reason.reason);
1050 }
1051 break;
1052 case BT_TBS_CALL_OPCODE_HOLD:
1053 if (tbs_cbs->hold_call != NULL) {
1054 tbs_cbs->hold_call(conn, call_index);
1055 }
1056 break;
1057 case BT_TBS_CALL_OPCODE_RETRIEVE:
1058 if (tbs_cbs->retrieve_call != NULL) {
1059 tbs_cbs->retrieve_call(conn, call_index);
1060 }
1061 break;
1062 case BT_TBS_CALL_OPCODE_ORIGINATE: {
1063 char uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
1064 const uint16_t uri_len = len - sizeof(ccp->originate);
1065 bool remote_party_alerted = false;
1066 struct bt_tbs_call *call;
1067
1068 call = lookup_call_in_inst(inst, call_index);
1069
1070 if (call == NULL) {
1071 LOG_DBG("Could not find call by call index 0x%02x", call_index);
1072 break;
1073 }
1074
1075 (void)memcpy(uri, ccp->originate.uri, uri_len);
1076 uri[uri_len] = '\0';
1077 if (tbs_cbs->originate_call != NULL) {
1078 remote_party_alerted = tbs_cbs->originate_call(conn, call_index, uri);
1079 }
1080
1081 if (remote_party_alerted) {
1082 call->state = BT_TBS_CALL_STATE_ALERTING;
1083 } else {
1084 const struct bt_tbs_call_cp_term term = {
1085 .call_index = call_index, .opcode = BT_TBS_CALL_OPCODE_TERMINATE};
1086
1087 /* Terminate and remove call */
1088 terminate_call(inst, &term, BT_TBS_REASON_CALL_FAILED);
1089 }
1090
1091 notify_calls(inst);
1092
1093 break;
1094 }
1095 case BT_TBS_CALL_OPCODE_JOIN: {
1096 const uint16_t call_index_cnt = len - sizeof(ccp->join);
1097
1098 /* Let the app know about joined calls */
1099 if (tbs_cbs->join_calls != NULL) {
1100 tbs_cbs->join_calls(conn, call_index_cnt, ccp->join.call_indexes);
1101 }
1102 break;
1103 }
1104 default:
1105 break;
1106 }
1107
1108 /* Let the app know about held calls */
1109 if (held_calls_cnt != 0 && tbs_cbs->hold_call != NULL) {
1110 for (int i = 0; i < held_calls_cnt; i++) {
1111 tbs_cbs->hold_call(conn, held_calls[i]->index);
1112 }
1113 }
1114 }
1115
write_call_cp(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)1116 static ssize_t write_call_cp(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
1117 uint16_t len, uint16_t offset, uint8_t flags)
1118 {
1119 struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1120 const union bt_tbs_call_cp_t *ccp = (union bt_tbs_call_cp_t *)buf;
1121 struct tbs_inst *tbs = NULL;
1122 uint8_t status;
1123 uint8_t call_index = 0;
1124 const bool is_gtbs = inst_is_gtbs(inst);
1125
1126 if (!is_authorized(inst, conn)) {
1127 return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
1128 }
1129
1130 if (offset != 0) {
1131 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
1132 }
1133
1134 if (len < sizeof(ccp->opcode)) {
1135 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1136 }
1137
1138 LOG_DBG("Index %u: Processing the %s opcode", inst_index(inst),
1139 bt_tbs_opcode_str(ccp->opcode));
1140
1141 switch (ccp->opcode) {
1142 case BT_TBS_CALL_OPCODE_ACCEPT:
1143 if (len != sizeof(ccp->accept)) {
1144 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1145 }
1146
1147 call_index = ccp->accept.call_index;
1148
1149 if (is_gtbs) {
1150 tbs = lookup_inst_by_call_index(call_index);
1151 if (tbs == NULL) {
1152 status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1153 break;
1154 }
1155 } else {
1156 tbs = inst;
1157 }
1158
1159 status = accept_call(tbs, &ccp->accept);
1160 break;
1161 case BT_TBS_CALL_OPCODE_TERMINATE:
1162 if (len != sizeof(ccp->terminate)) {
1163 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1164 }
1165
1166 call_index = ccp->terminate.call_index;
1167
1168 if (is_gtbs) {
1169 tbs = lookup_inst_by_call_index(call_index);
1170 if (tbs == NULL) {
1171 status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1172 break;
1173 }
1174 } else {
1175 tbs = inst;
1176 }
1177
1178 status = terminate_call(tbs, &ccp->terminate, BT_TBS_REASON_CLIENT_TERMINATED);
1179 break;
1180 case BT_TBS_CALL_OPCODE_HOLD:
1181 if (len != sizeof(ccp->hold)) {
1182 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1183 }
1184
1185 call_index = ccp->hold.call_index;
1186
1187 if (is_gtbs) {
1188 tbs = lookup_inst_by_call_index(call_index);
1189 if (tbs == NULL) {
1190 status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1191 break;
1192 }
1193 } else {
1194 tbs = inst;
1195 }
1196
1197 status = tbs_hold_call(tbs, &ccp->hold);
1198 break;
1199 case BT_TBS_CALL_OPCODE_RETRIEVE:
1200 if (len != sizeof(ccp->retrieve)) {
1201 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1202 }
1203
1204 call_index = ccp->retrieve.call_index;
1205
1206 if (is_gtbs) {
1207 tbs = lookup_inst_by_call_index(call_index);
1208 if (tbs == NULL) {
1209 status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1210 break;
1211 }
1212 } else {
1213 tbs = inst;
1214 }
1215
1216 status = retrieve_call(tbs, &ccp->retrieve);
1217 break;
1218 case BT_TBS_CALL_OPCODE_ORIGINATE: {
1219 const uint16_t uri_len = len - sizeof(ccp->originate);
1220
1221 if (len < sizeof(ccp->originate) + BT_TBS_MIN_URI_LEN) {
1222 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1223 }
1224
1225 if (is_gtbs) {
1226 tbs = lookup_inst_by_uri_scheme(ccp->originate.uri, uri_len);
1227 if (tbs == NULL) {
1228 status = BT_TBS_RESULT_CODE_INVALID_URI;
1229 break;
1230 }
1231 } else {
1232 tbs = inst;
1233 }
1234
1235 status = originate_call(tbs, &ccp->originate, uri_len, &call_index);
1236 break;
1237 }
1238 case BT_TBS_CALL_OPCODE_JOIN: {
1239 const uint16_t call_index_cnt = len - sizeof(ccp->join);
1240
1241 if (len < sizeof(ccp->join) + 1) { /* at least 1 call index */
1242 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
1243 }
1244
1245 call_index = ccp->join.call_indexes[0];
1246
1247 if (is_gtbs) {
1248 tbs = lookup_inst_by_call_index(call_index);
1249 if (tbs == NULL) {
1250 status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1251 break;
1252 }
1253 } else {
1254 tbs = inst;
1255 }
1256
1257 status = join_calls(tbs, &ccp->join, call_index_cnt);
1258 break;
1259 }
1260 default:
1261 status = BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
1262 call_index = 0;
1263 break;
1264 }
1265
1266 if (tbs != NULL) {
1267 LOG_DBG("Index %u: Processed the %s opcode with status %s for call index %u",
1268 inst_index(inst), bt_tbs_opcode_str(ccp->opcode), bt_tbs_status_str(status),
1269 call_index);
1270
1271 if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1272 const struct bt_tbs_call *call = lookup_call(call_index);
1273
1274 if (call != NULL) {
1275 LOG_DBG("Call is now in the %s state",
1276 bt_tbs_state_str(call->state));
1277 } else {
1278 LOG_DBG("Call is now terminated");
1279 }
1280 }
1281 }
1282
1283 if (status != BT_TBS_RESULT_CODE_SUCCESS) {
1284 call_index = 0;
1285 }
1286
1287 if (conn != NULL) {
1288 notify_ccp(conn, attr, call_index, ccp->opcode, status);
1289 } /* else local operation; don't notify */
1290
1291 if (tbs != NULL && status == BT_TBS_RESULT_CODE_SUCCESS) {
1292 notify_calls(tbs);
1293 notify_app(conn, tbs, len, ccp, status, call_index);
1294 }
1295
1296 return len;
1297 }
1298
call_cp_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1299 static void call_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1300 {
1301 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
1302
1303 if (inst != NULL) {
1304 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1305 }
1306 }
1307
read_optional_opcodes(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1308 static ssize_t read_optional_opcodes(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1309 void *buf, uint16_t len, uint16_t offset)
1310 {
1311 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1312 const uint16_t optional_opcodes_le = sys_cpu_to_le16(inst->optional_opcodes);
1313
1314 LOG_DBG("Index %u: Supported opcodes 0x%02x", inst_index(inst), inst->optional_opcodes);
1315
1316 return bt_gatt_attr_read(conn, attr, buf, len, offset, &optional_opcodes_le,
1317 sizeof(optional_opcodes_le));
1318 }
1319
terminate_reason_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1320 static void terminate_reason_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1321 {
1322 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
1323
1324 if (inst != NULL) {
1325 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1326 }
1327 }
1328
read_friendly_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1329 static ssize_t read_friendly_name(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
1330 uint16_t len, uint16_t offset)
1331 {
1332 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1333 const struct bt_tbs_in_uri *friendly_name = &inst->friendly_name;
1334 size_t val_len;
1335
1336 LOG_DBG("Index: 0x%02x call index 0x%02x, URI %s", inst_index(inst),
1337 friendly_name->call_index, friendly_name->uri);
1338
1339 if (friendly_name->call_index == BT_TBS_FREE_CALL_INDEX) {
1340 LOG_DBG("URI not set");
1341 return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1342 }
1343
1344 val_len = sizeof(friendly_name->call_index) + strlen(friendly_name->uri);
1345
1346 return bt_gatt_attr_read(conn, attr, buf, len, offset, friendly_name, val_len);
1347 }
1348
friendly_name_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1349 static void friendly_name_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1350 {
1351 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
1352
1353 if (inst != NULL) {
1354 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1355 }
1356 }
1357
read_incoming_call(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1358 static ssize_t read_incoming_call(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
1359 uint16_t len, uint16_t offset)
1360 {
1361 const struct tbs_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);
1362 const struct bt_tbs_in_uri *remote_uri = &inst->in_call;
1363 size_t val_len;
1364
1365 LOG_DBG("Index: 0x%02x call index 0x%02x, URI %s", inst_index(inst), remote_uri->call_index,
1366 remote_uri->uri);
1367
1368 if (remote_uri->call_index == BT_TBS_FREE_CALL_INDEX) {
1369 LOG_DBG("URI not set");
1370
1371 return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1372 }
1373
1374 val_len = sizeof(remote_uri->call_index) + strlen(remote_uri->uri);
1375
1376 return bt_gatt_attr_read(conn, attr, buf, len, offset, remote_uri, val_len);
1377 }
1378
in_call_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1379 static void in_call_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
1380 {
1381 const struct tbs_inst *inst = lookup_inst_by_attr(attr);
1382
1383 if (inst != NULL) {
1384 LOG_DBG("Index %u: value 0x%04x", inst_index(inst), value);
1385 }
1386 }
1387
1388 #define BT_TBS_CHR_PROVIDER_NAME(inst) \
1389 BT_AUDIO_CHRC(BT_UUID_TBS_PROVIDER_NAME, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1390 BT_GATT_PERM_READ_ENCRYPT, read_provider_name, NULL, inst), \
1391 BT_AUDIO_CCC(provider_name_cfg_changed)
1392
1393 #define BT_TBS_CHR_UCI(inst) \
1394 BT_AUDIO_CHRC(BT_UUID_TBS_UCI, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, read_uci, \
1395 NULL, inst)
1396
1397 #define BT_TBS_CHR_TECHNOLOGY(inst) \
1398 BT_AUDIO_CHRC(BT_UUID_TBS_TECHNOLOGY, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1399 BT_GATT_PERM_READ_ENCRYPT, read_technology, NULL, inst), \
1400 BT_AUDIO_CCC(technology_cfg_changed)
1401
1402 #define BT_TBS_CHR_URI_LIST(inst) \
1403 BT_AUDIO_CHRC(BT_UUID_TBS_URI_LIST, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1404 BT_GATT_PERM_READ_ENCRYPT, read_uri_scheme_list, NULL, inst), \
1405 BT_AUDIO_CCC(uri_scheme_list_cfg_changed)
1406
1407 #define BT_TBS_CHR_SIGNAL_STRENGTH(inst) \
1408 BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_STRENGTH, /* Optional */ \
1409 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT, \
1410 read_signal_strength, NULL, inst), \
1411 BT_AUDIO_CCC(signal_strength_cfg_changed)
1412
1413 #define BT_TBS_CHR_SIGNAL_INTERVAL(inst) \
1414 BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_INTERVAL, /* Conditional */ \
1415 BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
1416 BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \
1417 read_signal_strength_interval, write_signal_strength_interval, inst)
1418
1419 #define BT_TBS_CHR_CURRENT_CALLS(inst) \
1420 BT_AUDIO_CHRC(BT_UUID_TBS_LIST_CURRENT_CALLS, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1421 BT_GATT_PERM_READ_ENCRYPT, read_current_calls, NULL, inst), \
1422 BT_AUDIO_CCC(current_calls_cfg_changed)
1423
1424 #define BT_TBS_CHR_CCID(inst) \
1425 BT_AUDIO_CHRC(BT_UUID_CCID, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, read_ccid, NULL, \
1426 inst)
1427
1428 #define BT_TBS_CHR_STATUS_FLAGS(inst) \
1429 BT_AUDIO_CHRC(BT_UUID_TBS_STATUS_FLAGS, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1430 BT_GATT_PERM_READ_ENCRYPT, read_status_flags, NULL, inst), \
1431 BT_AUDIO_CCC(status_flags_cfg_changed)
1432
1433 #define BT_TBS_CHR_INCOMING_URI(inst) \
1434 BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_URI, /* Optional */ \
1435 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT, \
1436 read_incoming_uri, NULL, inst), \
1437 BT_AUDIO_CCC(incoming_uri_cfg_changed)
1438
1439 #define BT_TBS_CHR_CALL_STATE(inst) \
1440 BT_AUDIO_CHRC(BT_UUID_TBS_CALL_STATE, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1441 BT_GATT_PERM_READ_ENCRYPT, read_call_state, NULL, inst), \
1442 BT_AUDIO_CCC(call_state_cfg_changed)
1443
1444 #define BT_TBS_CHR_CONTROL_POINT(inst) \
1445 BT_AUDIO_CHRC(BT_UUID_TBS_CALL_CONTROL_POINT, \
1446 BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
1447 BT_GATT_PERM_WRITE_ENCRYPT, NULL, write_call_cp, inst), \
1448 BT_AUDIO_CCC(call_cp_cfg_changed)
1449
1450 #define BT_TBS_CHR_OPTIONAL_OPCODES(inst) \
1451 BT_AUDIO_CHRC(BT_UUID_TBS_OPTIONAL_OPCODES, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \
1452 read_optional_opcodes, NULL, inst)
1453
1454 #define BT_TBS_CHR_TERMINATE_REASON(inst) \
1455 BT_AUDIO_CHRC(BT_UUID_TBS_TERMINATE_REASON, BT_GATT_CHRC_NOTIFY, \
1456 BT_GATT_PERM_READ_ENCRYPT, NULL, NULL, inst), \
1457 BT_AUDIO_CCC(terminate_reason_cfg_changed)
1458
1459 #define BT_TBS_CHR_INCOMING_CALL(inst) \
1460 BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_CALL, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
1461 BT_GATT_PERM_READ_ENCRYPT, read_incoming_call, NULL, inst), \
1462 BT_AUDIO_CCC(in_call_cfg_changed)
1463
1464 #define BT_TBS_CHR_FRIENDLY_NAME(inst) \
1465 BT_AUDIO_CHRC(BT_UUID_TBS_FRIENDLY_NAME, /* Optional */ \
1466 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT, \
1467 read_friendly_name, NULL, inst), \
1468 BT_AUDIO_CCC(friendly_name_cfg_changed)
1469
1470 #define BT_TBS_SERVICE_DEFINE(_uuid, _inst) \
1471 BT_GATT_PRIMARY_SERVICE(_uuid), BT_TBS_CHR_PROVIDER_NAME(_inst), BT_TBS_CHR_UCI(_inst), \
1472 BT_TBS_CHR_TECHNOLOGY(_inst), BT_TBS_CHR_URI_LIST(_inst), \
1473 BT_TBS_CHR_SIGNAL_STRENGTH(_inst), BT_TBS_CHR_SIGNAL_INTERVAL(_inst), \
1474 BT_TBS_CHR_CURRENT_CALLS(_inst), BT_TBS_CHR_CCID(_inst), \
1475 BT_TBS_CHR_STATUS_FLAGS(_inst), BT_TBS_CHR_INCOMING_URI(_inst), \
1476 BT_TBS_CHR_CALL_STATE(_inst), BT_TBS_CHR_CONTROL_POINT(_inst), \
1477 BT_TBS_CHR_OPTIONAL_OPCODES(_inst), BT_TBS_CHR_TERMINATE_REASON(_inst), \
1478 BT_TBS_CHR_INCOMING_CALL(_inst), BT_TBS_CHR_FRIENDLY_NAME(_inst)
1479
1480 #define BT_TBS_SERVICE_DEFINITION(_inst) \
1481 { \
1482 BT_TBS_SERVICE_DEFINE(BT_UUID_TBS, &(_inst)) \
1483 }
1484
1485 static struct bt_gatt_service gtbs_svc =
1486 BT_GATT_SERVICE(((struct bt_gatt_attr[]){BT_TBS_SERVICE_DEFINE(BT_UUID_GTBS, >bs_inst)}));
1487
1488 BT_GATT_SERVICE_INSTANCE_DEFINE(tbs_service_list, svc_insts, CONFIG_BT_TBS_BEARER_COUNT,
1489 BT_TBS_SERVICE_DEFINITION);
1490
signal_interval_timeout(struct k_work * work)1491 static void signal_interval_timeout(struct k_work *work)
1492 {
1493 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1494 struct tbs_inst *inst = CONTAINER_OF(dwork, struct tbs_inst, reporting_interval_work);
1495
1496 if (!inst->pending_signal_strength_notification) {
1497 return;
1498 }
1499
1500 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_SIGNAL_STRENGTH, inst->attrs, &inst->signal_strength,
1501 sizeof(inst->signal_strength));
1502
1503 if (inst->signal_strength_interval) {
1504 k_work_reschedule(&inst->reporting_interval_work,
1505 K_SECONDS(inst->signal_strength_interval));
1506 }
1507
1508 inst->pending_signal_strength_notification = false;
1509 }
1510
tbs_inst_init_and_register(struct tbs_inst * inst,struct bt_gatt_service * svc,const struct bt_tbs_register_param * param)1511 static int tbs_inst_init_and_register(struct tbs_inst *inst, struct bt_gatt_service *svc,
1512 const struct bt_tbs_register_param *param)
1513 {
1514 int ret;
1515
1516 LOG_DBG("inst %p index 0x%02x", inst, inst_index(inst));
1517
1518 ret = bt_ccid_alloc_value();
1519 if (ret < 0) {
1520 LOG_DBG("Could not allocate CCID: %d", ret);
1521 return ret;
1522 }
1523
1524 inst->ccid = (uint8_t)ret;
1525 (void)utf8_lcpy(inst->provider_name, param->provider_name, sizeof(inst->provider_name));
1526 (void)utf8_lcpy(inst->uci, param->uci, sizeof(inst->uci));
1527 (void)utf8_lcpy(inst->uri_scheme_list, param->uri_schemes_supported,
1528 sizeof(inst->uri_scheme_list));
1529 inst->optional_opcodes = param->supported_features;
1530 inst->technology = param->technology;
1531 inst->attrs = svc->attrs;
1532 inst->attr_count = svc->attr_count;
1533 inst->authorization_required = param->authorization_required;
1534
1535 k_work_init_delayable(&inst->reporting_interval_work, signal_interval_timeout);
1536
1537 ret = bt_gatt_service_register(svc);
1538 if (ret != 0) {
1539 LOG_DBG("Could not register %sTBS: %d", param->gtbs ? "G" : "", ret);
1540 memset(inst, 0, sizeof(*inst));
1541
1542 return ret;
1543 }
1544
1545 return inst_index(inst);
1546 }
1547
gtbs_service_inst_register(const struct bt_tbs_register_param * param)1548 static int gtbs_service_inst_register(const struct bt_tbs_register_param *param)
1549 {
1550 return tbs_inst_init_and_register(>bs_inst, >bs_svc, param);
1551 }
1552
tbs_service_inst_register(const struct bt_tbs_register_param * param)1553 static int tbs_service_inst_register(const struct bt_tbs_register_param *param)
1554 {
1555 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
1556 struct tbs_inst *inst = &svc_insts[i];
1557
1558 if (!(inst_is_registered(inst))) {
1559 return tbs_inst_init_and_register(inst, &tbs_service_list[i], param);
1560 }
1561 }
1562
1563 return -ENOMEM;
1564 }
1565
valid_register_param(const struct bt_tbs_register_param * param)1566 static bool valid_register_param(const struct bt_tbs_register_param *param)
1567 {
1568 size_t str_len;
1569
1570 if (param == NULL) {
1571 LOG_DBG("param is NULL");
1572
1573 return false;
1574 }
1575
1576 if (param->provider_name == NULL) {
1577 LOG_DBG("provider_name is NULL");
1578
1579 return false;
1580 }
1581
1582 str_len = strlen(param->provider_name);
1583 if (str_len > CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH) {
1584 LOG_DBG("Provider name length (%zu) larger than "
1585 "CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH %d",
1586 str_len, CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH);
1587
1588 return false;
1589 }
1590
1591 if (param->uci == NULL) {
1592 LOG_DBG("uci is NULL");
1593
1594 return false;
1595 }
1596
1597 if (param->uri_schemes_supported == NULL) {
1598 LOG_DBG("uri_schemes_supported is NULL");
1599
1600 return false;
1601 }
1602
1603 if (!IN_RANGE(param->technology, BT_TBS_TECHNOLOGY_3G, BT_TBS_TECHNOLOGY_WCDMA)) {
1604 LOG_DBG("Invalid technology: %u", param->technology);
1605
1606 return false;
1607 }
1608
1609 if (param->supported_features > BT_TBS_FEATURE_ALL) {
1610 LOG_DBG("Invalid supported_features: %u", param->supported_features);
1611
1612 return false;
1613 }
1614
1615 if (CONFIG_BT_TBS_BEARER_COUNT == 0 && !param->gtbs) {
1616 LOG_DBG("Cannot register TBS when CONFIG_BT_TBS_BEARER_COUNT=0");
1617
1618 return false;
1619 }
1620
1621 return true;
1622 }
1623
bt_tbs_register_bearer(const struct bt_tbs_register_param * param)1624 int bt_tbs_register_bearer(const struct bt_tbs_register_param *param)
1625 {
1626 int ret;
1627
1628 CHECKIF(!valid_register_param(param)) {
1629 LOG_DBG("Invalid parameters");
1630
1631 return -EINVAL;
1632 }
1633
1634 if (param->gtbs && inst_is_registered(>bs_inst)) {
1635 LOG_DBG("GTBS already registered");
1636
1637 return -EALREADY;
1638 }
1639
1640 if (!param->gtbs && !inst_is_registered(>bs_inst)) {
1641 LOG_DBG("GTBS not yet registered");
1642
1643 return -EAGAIN;
1644 }
1645
1646 if (param->gtbs) {
1647 ret = gtbs_service_inst_register(param);
1648 if (ret < 0) {
1649 LOG_DBG("Failed to register GTBS: %d", ret);
1650
1651 return -ENOEXEC;
1652 }
1653 } else if (CONFIG_BT_TBS_BEARER_COUNT > 0) {
1654 ret = tbs_service_inst_register(param);
1655 if (ret < 0) {
1656 LOG_DBG("Failed to register GTBS: %d", ret);
1657
1658 if (ret == -ENOMEM) {
1659 return -ENOMEM;
1660 }
1661
1662 return -ENOEXEC;
1663 }
1664 }
1665
1666 /* ret will contain the index of the registered service */
1667 return ret;
1668 }
1669
bt_tbs_unregister_bearer(uint8_t bearer_index)1670 int bt_tbs_unregister_bearer(uint8_t bearer_index)
1671 {
1672 struct tbs_inst *inst = inst_lookup_index(bearer_index);
1673 struct bt_gatt_service *svc;
1674 struct k_work_sync sync;
1675 bool restart_reporting_interval;
1676 int err;
1677
1678 if (inst == NULL) {
1679 LOG_DBG("Could not find inst by index %u", bearer_index);
1680
1681 return -EINVAL;
1682 }
1683
1684 if (!inst_is_registered(inst)) {
1685 LOG_DBG("Instance from index %u is not registered", bearer_index);
1686
1687 return -EALREADY;
1688 }
1689
1690 if (inst_is_gtbs(inst)) {
1691 for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
1692 struct tbs_inst *tbs = &svc_insts[i];
1693
1694 if (inst_is_registered(tbs)) {
1695 LOG_DBG("TBS[%u] is registered, please unregister all TBS first",
1696 bearer_index);
1697 return -EAGAIN;
1698 }
1699 }
1700 svc = >bs_svc;
1701 } else {
1702 svc = &tbs_service_list[bearer_index];
1703 }
1704
1705 restart_reporting_interval =
1706 k_work_cancel_delayable_sync(&inst->reporting_interval_work, &sync);
1707
1708 err = bt_gatt_service_unregister(svc);
1709 if (err != 0) {
1710 LOG_DBG("Failed to unregister service %p: %d", svc, err);
1711
1712 if (restart_reporting_interval && inst->signal_strength_interval != 0U) {
1713 /* In this unlikely scenario we may report interval later than expected if
1714 * the k_work was cancelled right before it was set to trigger. It is not a
1715 * big deal and not worth trying to reschedule in a way that it would
1716 * trigger at the same time again, as specific timing over GATT is a wishful
1717 * dream anyways
1718 */
1719 k_work_schedule(&inst->reporting_interval_work,
1720 K_SECONDS(inst->signal_strength_interval));
1721 }
1722
1723 return -ENOEXEC;
1724 }
1725
1726 memset(inst, 0, sizeof(*inst));
1727
1728 return 0;
1729 }
1730
bt_tbs_accept(uint8_t call_index)1731 int bt_tbs_accept(uint8_t call_index)
1732 {
1733 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1734 int status = -EINVAL;
1735 const struct bt_tbs_call_cp_acc ccp = {.call_index = call_index,
1736 .opcode = BT_TBS_CALL_OPCODE_ACCEPT};
1737
1738 if (inst != NULL) {
1739 status = accept_call(inst, &ccp);
1740 }
1741
1742 if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1743 notify_calls(inst);
1744 }
1745
1746 return status;
1747 }
1748
bt_tbs_hold(uint8_t call_index)1749 int bt_tbs_hold(uint8_t call_index)
1750 {
1751 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1752 int status = -EINVAL;
1753 const struct bt_tbs_call_cp_hold ccp = {.call_index = call_index,
1754 .opcode = BT_TBS_CALL_OPCODE_HOLD};
1755
1756 if (inst != NULL) {
1757 status = tbs_hold_call(inst, &ccp);
1758 }
1759
1760 notify_calls(inst);
1761
1762 return status;
1763 }
1764
bt_tbs_retrieve(uint8_t call_index)1765 int bt_tbs_retrieve(uint8_t call_index)
1766 {
1767 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1768 int status = -EINVAL;
1769 const struct bt_tbs_call_cp_retrieve ccp = {.call_index = call_index,
1770 .opcode = BT_TBS_CALL_OPCODE_RETRIEVE};
1771
1772 if (inst != NULL) {
1773 status = retrieve_call(inst, &ccp);
1774 }
1775
1776 notify_calls(inst);
1777
1778 return status;
1779 }
1780
bt_tbs_terminate(uint8_t call_index)1781 int bt_tbs_terminate(uint8_t call_index)
1782 {
1783 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1784 int status = -EINVAL;
1785 const struct bt_tbs_call_cp_term ccp = {.call_index = call_index,
1786 .opcode = BT_TBS_CALL_OPCODE_TERMINATE};
1787
1788 if (inst != NULL) {
1789 status = terminate_call(inst, &ccp, BT_TBS_REASON_SERVER_ENDED_CALL);
1790 }
1791
1792 notify_calls(inst);
1793
1794 return status;
1795 }
1796
bt_tbs_originate(uint8_t bearer_index,char * remote_uri,uint8_t * call_index)1797 int bt_tbs_originate(uint8_t bearer_index, char *remote_uri, uint8_t *call_index)
1798 {
1799 struct tbs_inst *tbs = inst_lookup_index(bearer_index);
1800 uint8_t buf[CONFIG_BT_TBS_MAX_URI_LENGTH + sizeof(struct bt_tbs_call_cp_originate)];
1801 struct bt_tbs_call_cp_originate *ccp = (struct bt_tbs_call_cp_originate *)buf;
1802 size_t uri_len;
1803
1804 if (tbs == NULL) {
1805 LOG_DBG("Could not find TBS instance from index %u", bearer_index);
1806 return -EINVAL;
1807 } else if (!bt_tbs_valid_uri((uint8_t *)remote_uri, strlen(remote_uri))) {
1808 LOG_DBG("Invalid URI %s", remote_uri);
1809 return -EINVAL;
1810 }
1811
1812 uri_len = strlen(remote_uri);
1813
1814 ccp->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
1815 (void)memcpy(ccp->uri, remote_uri, uri_len);
1816
1817 return originate_call(tbs, ccp, uri_len, call_index);
1818 }
1819
bt_tbs_join(uint8_t call_index_cnt,uint8_t * call_indexes)1820 int bt_tbs_join(uint8_t call_index_cnt, uint8_t *call_indexes)
1821 {
1822 struct tbs_inst *inst;
1823 uint8_t buf[CONFIG_BT_TBS_MAX_CALLS + sizeof(struct bt_tbs_call_cp_join)];
1824 struct bt_tbs_call_cp_join *ccp = (struct bt_tbs_call_cp_join *)buf;
1825 int status = -EINVAL;
1826
1827 if (call_index_cnt != 0 && call_indexes != 0) {
1828 inst = lookup_inst_by_call_index(call_indexes[0]);
1829 } else {
1830 return status;
1831 }
1832
1833 if (inst != NULL) {
1834 ccp->opcode = BT_TBS_CALL_OPCODE_JOIN;
1835 (void)memcpy(ccp->call_indexes, call_indexes,
1836 MIN(call_index_cnt, CONFIG_BT_TBS_MAX_CALLS));
1837
1838 status = join_calls(inst, ccp, call_index_cnt);
1839 }
1840
1841 return status;
1842 }
1843
bt_tbs_remote_answer(uint8_t call_index)1844 int bt_tbs_remote_answer(uint8_t call_index)
1845 {
1846 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1847 struct bt_tbs_call *call;
1848
1849 if (inst == NULL) {
1850 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1851 }
1852
1853 call = lookup_call_in_inst(inst, call_index);
1854
1855 if (call == NULL) {
1856 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1857 }
1858
1859 if (call->state == BT_TBS_CALL_STATE_ALERTING) {
1860 call->state = BT_TBS_CALL_STATE_ACTIVE;
1861 notify_calls(inst);
1862 return BT_TBS_RESULT_CODE_SUCCESS;
1863 } else {
1864 return BT_TBS_RESULT_CODE_STATE_MISMATCH;
1865 }
1866 }
1867
bt_tbs_remote_hold(uint8_t call_index)1868 int bt_tbs_remote_hold(uint8_t call_index)
1869 {
1870 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1871 struct bt_tbs_call *call;
1872 uint8_t status;
1873
1874 if (inst == NULL) {
1875 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1876 }
1877
1878 call = lookup_call_in_inst(inst, call_index);
1879
1880 if (call == NULL) {
1881 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1882 }
1883
1884 if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
1885 call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
1886 status = BT_TBS_RESULT_CODE_SUCCESS;
1887 } else if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
1888 call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
1889 status = BT_TBS_RESULT_CODE_SUCCESS;
1890 } else {
1891 status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
1892 }
1893
1894 if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1895 notify_calls(inst);
1896 }
1897
1898 return status;
1899 }
1900
bt_tbs_remote_retrieve(uint8_t call_index)1901 int bt_tbs_remote_retrieve(uint8_t call_index)
1902 {
1903 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1904 struct bt_tbs_call *call;
1905 int status;
1906
1907 if (inst == NULL) {
1908 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1909 }
1910
1911 call = lookup_call_in_inst(inst, call_index);
1912
1913 if (call == NULL) {
1914 return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
1915 }
1916
1917 if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
1918 call->state = BT_TBS_CALL_STATE_ACTIVE;
1919 status = BT_TBS_RESULT_CODE_SUCCESS;
1920 } else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
1921 call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
1922 status = BT_TBS_RESULT_CODE_SUCCESS;
1923 } else {
1924 status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
1925 }
1926
1927 if (status == BT_TBS_RESULT_CODE_SUCCESS) {
1928 notify_calls(inst);
1929 }
1930
1931 return status;
1932 }
1933
bt_tbs_remote_terminate(uint8_t call_index)1934 int bt_tbs_remote_terminate(uint8_t call_index)
1935 {
1936 struct tbs_inst *inst = lookup_inst_by_call_index(call_index);
1937 int status = -EINVAL;
1938 const struct bt_tbs_call_cp_term ccp = {.call_index = call_index,
1939 .opcode = BT_TBS_CALL_OPCODE_TERMINATE};
1940
1941 if (inst != NULL) {
1942 status = terminate_call(inst, &ccp, BT_TBS_REASON_REMOTE_ENDED_CALL);
1943 }
1944
1945 notify_calls(inst);
1946
1947 return status;
1948 }
1949
tbs_inst_remote_incoming(struct tbs_inst * inst,const char * to,const char * from,const char * friendly_name,const struct bt_tbs_call * call)1950 static void tbs_inst_remote_incoming(struct tbs_inst *inst, const char *to, const char *from,
1951 const char *friendly_name, const struct bt_tbs_call *call)
1952 {
1953 size_t local_uri_ind_len;
1954 size_t remote_uri_ind_len;
1955 size_t friend_name_ind_len;
1956
1957 __ASSERT_NO_MSG(to != NULL);
1958 __ASSERT_NO_MSG(from != NULL);
1959
1960 local_uri_ind_len = strlen(to) + 1;
1961 remote_uri_ind_len = strlen(from) + 1;
1962
1963 inst->in_call.call_index = call->index;
1964 (void)utf8_lcpy(inst->in_call.uri, from, sizeof(inst->in_call.uri));
1965
1966 inst->incoming_uri.call_index = call->index;
1967 (void)utf8_lcpy(inst->incoming_uri.uri, to, sizeof(inst->incoming_uri.uri));
1968
1969 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_URI, inst->attrs, &inst->incoming_uri,
1970 local_uri_ind_len);
1971
1972 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_CALL, inst->attrs, &inst->in_call,
1973 remote_uri_ind_len);
1974
1975 if (friendly_name) {
1976 inst->friendly_name.call_index = call->index;
1977 utf8_lcpy(inst->friendly_name.uri, friendly_name, sizeof(inst->friendly_name.uri));
1978 friend_name_ind_len = strlen(from) + 1;
1979
1980 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME, inst->attrs,
1981 &inst->friendly_name, friend_name_ind_len);
1982 } else {
1983 inst->friendly_name.call_index = BT_TBS_FREE_CALL_INDEX;
1984 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME, inst->attrs, NULL, 0);
1985 }
1986 }
1987
bt_tbs_remote_incoming(uint8_t bearer_index,const char * to,const char * from,const char * friendly_name)1988 int bt_tbs_remote_incoming(uint8_t bearer_index, const char *to, const char *from,
1989 const char *friendly_name)
1990 {
1991 struct tbs_inst *inst = inst_lookup_index(bearer_index);
1992 struct bt_tbs_call *call = NULL;
1993
1994 if (inst == NULL) {
1995 LOG_DBG("Could not find TBS instance from index %u", bearer_index);
1996 return -EINVAL;
1997 } else if (!bt_tbs_valid_uri((uint8_t *)to, strlen(to))) {
1998 LOG_DBG("Invalid \"to\" URI: %s", to);
1999 return -EINVAL;
2000 } else if (!bt_tbs_valid_uri((uint8_t *)from, strlen(from))) {
2001 LOG_DBG("Invalid \"from\" URI: %s", from);
2002 return -EINVAL;
2003 }
2004
2005 call = call_alloc(inst, BT_TBS_CALL_STATE_INCOMING, (uint8_t *)from, strlen(from));
2006 if (call == NULL) {
2007 return -ENOMEM;
2008 }
2009
2010 BT_TBS_CALL_FLAG_SET_INCOMING(call->flags);
2011
2012 /* Notify TBS*/
2013 tbs_inst_remote_incoming(inst, to, from, friendly_name, call);
2014
2015 if (!inst_is_gtbs(inst)) {
2016 /* If the instance is different than the GTBS we set the remote incoming and
2017 * notify on the GTBS instance as well
2018 */
2019 tbs_inst_remote_incoming(>bs_inst, to, from, friendly_name, call);
2020 }
2021
2022 notify_calls(inst);
2023
2024 LOG_DBG("New call with call index %u", call->index);
2025
2026 return call->index;
2027 }
2028
bt_tbs_set_bearer_provider_name(uint8_t bearer_index,const char * name)2029 int bt_tbs_set_bearer_provider_name(uint8_t bearer_index, const char *name)
2030 {
2031 struct tbs_inst *inst = inst_lookup_index(bearer_index);
2032 const size_t len = strlen(name);
2033
2034 if (len >= CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH || len == 0) {
2035 return -EINVAL;
2036 } else if (inst == NULL) {
2037 return -EINVAL;
2038 }
2039
2040 if (strcmp(inst->provider_name, name) == 0) {
2041 return 0;
2042 }
2043
2044 (void)utf8_lcpy(inst->provider_name, name, sizeof(inst->provider_name));
2045
2046 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_PROVIDER_NAME, inst->attrs, inst->provider_name,
2047 strlen(inst->provider_name));
2048 return 0;
2049 }
2050
bt_tbs_set_bearer_technology(uint8_t bearer_index,uint8_t new_technology)2051 int bt_tbs_set_bearer_technology(uint8_t bearer_index, uint8_t new_technology)
2052 {
2053 struct tbs_inst *inst = inst_lookup_index(bearer_index);
2054
2055 if (new_technology < BT_TBS_TECHNOLOGY_3G || new_technology > BT_TBS_TECHNOLOGY_WCDMA) {
2056 return -EINVAL;
2057 } else if (inst == NULL) {
2058 return -EINVAL;
2059 }
2060
2061 if (inst->technology == new_technology) {
2062 return 0;
2063 }
2064
2065 inst->technology = new_technology;
2066
2067 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TECHNOLOGY, inst->attrs, &inst->technology,
2068 sizeof(inst->technology));
2069
2070 return 0;
2071 }
2072
bt_tbs_set_signal_strength(uint8_t bearer_index,uint8_t new_signal_strength)2073 int bt_tbs_set_signal_strength(uint8_t bearer_index, uint8_t new_signal_strength)
2074 {
2075 struct tbs_inst *inst = inst_lookup_index(bearer_index);
2076 uint32_t timer_status;
2077
2078 if (new_signal_strength > BT_TBS_SIGNAL_STRENGTH_MAX &&
2079 new_signal_strength != BT_TBS_SIGNAL_STRENGTH_UNKNOWN) {
2080 return -EINVAL;
2081 } else if (inst == NULL) {
2082 return -EINVAL;
2083 }
2084
2085 if (inst->signal_strength == new_signal_strength) {
2086 return 0;
2087 }
2088
2089 inst->signal_strength = new_signal_strength;
2090 inst->pending_signal_strength_notification = true;
2091
2092 timer_status = k_work_delayable_remaining_get(&inst->reporting_interval_work);
2093 if (timer_status == 0) {
2094 k_work_reschedule(&inst->reporting_interval_work, K_NO_WAIT);
2095 }
2096
2097 LOG_DBG("Index %u: Reporting signal strength in %d ms", bearer_index, timer_status);
2098
2099 return 0;
2100 }
2101
bt_tbs_set_status_flags(uint8_t bearer_index,uint16_t status_flags)2102 int bt_tbs_set_status_flags(uint8_t bearer_index, uint16_t status_flags)
2103 {
2104 struct tbs_inst *inst = inst_lookup_index(bearer_index);
2105
2106 if (!BT_TBS_VALID_STATUS_FLAGS(status_flags)) {
2107 return -EINVAL;
2108 } else if (inst == NULL) {
2109 return -EINVAL;
2110 }
2111
2112 if (inst->status_flags == status_flags) {
2113 return 0;
2114 }
2115
2116 inst->status_flags = status_flags;
2117
2118 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_STATUS_FLAGS, inst->attrs, &status_flags,
2119 sizeof(status_flags));
2120 return 0;
2121 }
2122
bt_tbs_set_uri_scheme_list(uint8_t bearer_index,const char ** uri_list,uint8_t uri_count)2123 int bt_tbs_set_uri_scheme_list(uint8_t bearer_index, const char **uri_list, uint8_t uri_count)
2124 {
2125 char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
2126 size_t len = 0;
2127 struct tbs_inst *inst;
2128
2129 NET_BUF_SIMPLE_DEFINE(uri_scheme_buf, READ_BUF_SIZE);
2130
2131 if (bearer_index >= ARRAY_SIZE(svc_insts)) {
2132 return -EINVAL;
2133 }
2134
2135 inst = &svc_insts[bearer_index];
2136 (void)memset(uri_scheme_list, 0, sizeof(uri_scheme_list));
2137
2138 for (int i = 0; i < uri_count; i++) {
2139 if (len) {
2140 len++;
2141 if (len > sizeof(uri_scheme_list) - 1) {
2142 return -ENOMEM;
2143 }
2144
2145 strcat(uri_scheme_list, ",");
2146 }
2147
2148 len += strlen(uri_list[i]);
2149 if (len > sizeof(uri_scheme_list) - 1) {
2150 return -ENOMEM;
2151 }
2152
2153 /* Store list in temp list in case something goes wrong */
2154 strcat(uri_scheme_list, uri_list[i]);
2155 }
2156
2157 if (strcmp(inst->uri_scheme_list, uri_scheme_list) == 0) {
2158 /* identical; don't update or notify */
2159 return 0;
2160 }
2161
2162 /* Store final result */
2163 (void)utf8_lcpy(inst->uri_scheme_list, uri_scheme_list, sizeof(inst->uri_scheme_list));
2164
2165 LOG_DBG("TBS instance %u uri prefix list is now %s", bearer_index, inst->uri_scheme_list);
2166
2167 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST, inst->attrs, &inst->uri_scheme_list,
2168 strlen(inst->uri_scheme_list));
2169
2170 if (!inst_is_gtbs(inst)) {
2171 /* If the instance is different than the GTBS notify on the GTBS instance as well */
2172 net_buf_simple_add_mem(&uri_scheme_buf, gtbs_inst.uri_scheme_list,
2173 strlen(gtbs_inst.uri_scheme_list));
2174
2175 /* TODO: Make uri schemes unique */
2176 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
2177 const size_t uri_len = strlen(svc_insts[i].uri_scheme_list);
2178
2179 if (uri_scheme_buf.len + uri_len >= uri_scheme_buf.size) {
2180 LOG_WRN("Cannot fit all TBS instances in GTBS "
2181 "URI scheme list");
2182 break;
2183 }
2184
2185 net_buf_simple_add_mem(&uri_scheme_buf, svc_insts[i].uri_scheme_list,
2186 uri_len);
2187 }
2188
2189 LOG_DBG("GTBS: URI scheme %.*s", uri_scheme_buf.len, uri_scheme_buf.data);
2190
2191 bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST, gtbs_inst.attrs,
2192 uri_scheme_buf.data, uri_scheme_buf.len);
2193 }
2194 return 0;
2195 }
2196
bt_tbs_register_cb(struct bt_tbs_cb * cbs)2197 void bt_tbs_register_cb(struct bt_tbs_cb *cbs)
2198 {
2199 tbs_cbs = cbs;
2200 }
2201
2202 #if defined(CONFIG_BT_TBS_LOG_LEVEL_DBG)
bt_tbs_dbg_print_calls(void)2203 void bt_tbs_dbg_print_calls(void)
2204 {
2205 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
2206 LOG_DBG("Bearer #%u", i);
2207 for (int j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
2208 struct bt_tbs_call *call = &svc_insts[i].calls[j];
2209
2210 if (call->index == BT_TBS_FREE_CALL_INDEX) {
2211 continue;
2212 }
2213
2214 LOG_DBG(" Call #%u", call->index);
2215 LOG_DBG(" State: %s", bt_tbs_state_str(call->state));
2216 LOG_DBG(" Flags: 0x%02X", call->flags);
2217 LOG_DBG(" URI : %s", call->remote_uri);
2218 }
2219 }
2220 }
2221 #endif /* defined(CONFIG_BT_TBS_LOG_LEVEL_DBG) */
2222