1 /* Bluetooth CCP - Call Control Profile Call Control Server 2 * 3 * Copyright (c) 2024 Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <errno.h> 9 #include <stddef.h> 10 #include <stdint.h> 11 12 #include <zephyr/autoconf.h> 13 #include <zephyr/bluetooth/audio/tbs.h> 14 #include <zephyr/logging/log.h> 15 #include <zephyr/sys/check.h> 16 #include <zephyr/sys/util.h> 17 18 LOG_MODULE_REGISTER(bt_ccp_call_control_server, CONFIG_BT_CCP_CALL_CONTROL_SERVER_LOG_LEVEL); 19 20 /* A service instance can either be a GTBS or a TBS instance */ 21 struct bt_ccp_call_control_server_bearer { 22 uint8_t tbs_index; 23 bool registered; 24 }; 25 26 static struct bt_ccp_call_control_server_bearer 27 bearers[CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT]; 28 get_free_bearer(void)29static struct bt_ccp_call_control_server_bearer *get_free_bearer(void) 30 { 31 32 for (size_t i = 0; i < ARRAY_SIZE(bearers); i++) { 33 if (!bearers[i].registered) { 34 return &bearers[i]; 35 } 36 } 37 38 return NULL; 39 } 40 bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_param * param,struct bt_ccp_call_control_server_bearer ** bearer)41int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_param *param, 42 struct bt_ccp_call_control_server_bearer **bearer) 43 { 44 struct bt_ccp_call_control_server_bearer *free_bearer; 45 int ret; 46 47 CHECKIF(bearer == NULL) { 48 LOG_DBG("bearer is NULL"); 49 50 return -EINVAL; 51 } 52 53 free_bearer = get_free_bearer(); 54 if (free_bearer == NULL) { 55 return -ENOMEM; 56 } 57 58 ret = bt_tbs_register_bearer(param); 59 if (ret < 0) { 60 LOG_DBG("Failed to register TBS bearer: %d", ret); 61 62 /* Return known errors */ 63 if (ret == -EINVAL || ret == -EALREADY || ret == -EAGAIN || ret == -ENOMEM) { 64 return ret; 65 } 66 67 return -ENOEXEC; 68 } 69 70 free_bearer->registered = true; 71 free_bearer->tbs_index = (uint8_t)ret; 72 *bearer = free_bearer; 73 74 return 0; 75 } 76 bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer * bearer)77int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer) 78 { 79 int err; 80 81 CHECKIF(bearer == NULL) { 82 LOG_DBG("bearer is NULL"); 83 84 return -EINVAL; 85 } 86 87 if (!bearer->registered) { 88 LOG_DBG("Bearer %p already unregistered", bearer); 89 90 return -EALREADY; 91 } 92 93 err = bt_tbs_unregister_bearer(bearer->tbs_index); 94 if (err != 0) { 95 /* Return known errors */ 96 if (err == -EINVAL || err == -EALREADY) { 97 return err; 98 } 99 100 return -ENOEXEC; 101 } 102 103 bearer->registered = false; 104 105 return 0; 106 } 107