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