1 /**
2  * @file
3  * @brief Bluetooth Call Control Profile (CCP) APIs.
4  */
5 
6 /*
7  * Copyright (c) 2024 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_
13 #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_
14 
15 /**
16  * @brief Call Control Profile (CCP)
17  *
18  * @defgroup bt_ccp Call Control Profile (CCP)
19  *
20  * @since 3.7
21  * @version 0.1.0
22  *
23  * @ingroup bluetooth
24  * @{
25  *
26  * Call Control Profile (CCP) provides procedures to initiate and control calls.
27  * It provides the Call Control Client and the Call Control Server roles,
28  * where the former is usually placed on resource constrained devices like headphones,
29  * and the latter placed on more powerful devices like phones and PCs.
30  *
31  * The profile is not limited to carrier phone calls and can be used with common applications like
32  * Discord and Teams.
33  */
34 #include <stdint.h>
35 
36 #include <zephyr/autoconf.h>
37 #include <zephyr/bluetooth/audio/tbs.h>
38 #include <zephyr/bluetooth/conn.h>
39 #include <zephyr/sys/slist.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 /**
45  * @defgroup bt_ccp_call_control_server CCP Call Control Server APIs
46  * @ingroup bt_ccp
47  * @{
48  */
49 /** @brief Abstract Call Control Server Telephone Bearer structure. */
50 struct bt_ccp_call_control_server_bearer;
51 
52 /**
53  * @brief Register a Telephone Bearer
54  *
55  * This will register a Telephone Bearer Service (TBS) (or a Generic Telephone Bearer service
56  * (GTBS)) with the provided parameters.
57  *
58  * As per the TBS specification, the GTBS shall be instantiated for the feature,
59  * and as such a GTBS shall always be registered before any TBS can be registered.
60  * Similarly, all TBS shall be unregistered before the GTBS can be unregistered with
61  * bt_ccp_call_control_server_unregister_bearer().
62  *
63  * @param[in]  param   The parameters to initialize the bearer.
64  * @param[out] bearer  Pointer to the initialized bearer.
65  *
66  * @retval 0 Success
67  * @retval -EINVAL @p param contains invalid data
68  * @retval -EALREADY @p param.gtbs is true and GTBS has already been registered
69  * @retval -EAGAIN @p param.gtbs is false and GTBS has not been registered
70  * @retval -ENOMEM @p param.gtbs is false and no more TBS can be registered (see
71  *         @kconfig{CONFIG_BT_TBS_BEARER_COUNT})
72  * @retval -ENOEXEC The service failed to be registered
73  */
74 int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_param *param,
75 					       struct bt_ccp_call_control_server_bearer **bearer);
76 
77 /**
78  * @brief Unregister a Telephone Bearer
79  *
80  * This will unregister a Telephone Bearer Service (TBS) (or a Generic Telephone Bearer service
81  * (GTBS)) with the provided parameters. The bearer shall be registered first by
82  * bt_ccp_call_control_server_register_bearer() before it can be unregistered.
83  *
84  * All TBS shall be unregistered before the GTBS can be unregistered with.
85  *
86  * @param bearer The bearer to unregister.
87  *
88  * @retval 0 Success
89  * @retval -EINVAL @p bearer is NULL
90  * @retval -EALREADY The bearer is not registered
91  * @retval -ENOEXEC The service failed to be unregistered
92  */
93 int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer);
94 
95 /** @} */ /* End of group bt_ccp_call_control_server */
96 
97 /**
98  * @defgroup bt_ccp_call_control_client CCP Call Control Client APIs
99  * @ingroup bt_ccp
100  * @{
101  */
102 /** Abstract Call Control Client structure. */
103 struct bt_ccp_call_control_client;
104 
105 /** Abstract Call Control Client bearer structure. */
106 struct bt_ccp_call_control_client_bearer;
107 
108 /** Struct with information about bearers of a client */
109 struct bt_ccp_call_control_client_bearers {
110 #if defined(CONFIG_BT_TBS_CLIENT_GTBS)
111 	/** The GTBS bearer. */
112 	struct bt_ccp_call_control_client_bearer *gtbs_bearer;
113 #endif /* CONFIG_BT_TBS_CLIENT_GTBS */
114 
115 #if defined(CONFIG_BT_TBS_CLIENT_TBS)
116 	/** Number of TBS bearers in @p tbs_bearers */
117 	size_t tbs_count;
118 
119 	/** Array of pointers of TBS bearers */
120 	struct bt_ccp_call_control_client_bearer
121 		*tbs_bearers[CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT];
122 #endif /* CONFIG_BT_TBS_CLIENT_TBS */
123 };
124 
125 /**
126  * @brief Struct to hold the Telephone Bearer Service client callbacks
127  *
128  * These can be registered for usage with bt_tbs_client_register_cb().
129  */
130 struct bt_ccp_call_control_client_cb {
131 	/**
132 	 * @brief Callback function for bt_ccp_call_control_client_discover().
133 	 *
134 	 * This callback is called once the discovery procedure is completed.
135 	 *
136 	 * @param client       Call Control Client pointer.
137 	 * @param err          Error value. 0 on success, GATT error on positive
138 	 *                     value or errno on negative value.
139 	 * @param bearers      The bearers found.
140 	 */
141 	void (*discover)(struct bt_ccp_call_control_client *client, int err,
142 			 struct bt_ccp_call_control_client_bearers *bearers);
143 
144 	/** @cond INTERNAL_HIDDEN */
145 	/** Internally used field for list handling */
146 	sys_snode_t _node;
147 	/** @endcond */
148 };
149 
150 /**
151  * @brief Discovers the Telephone Bearer Service (TBS) support on a remote device.
152  *
153  * This will discover the Telephone Bearer Service (TBS) and Generic Telephone Bearer Service (GTBS)
154  * on the remote device.
155  *
156  * @kconfig_dep{CONFIG_BT_CCP_CALL_CONTROL_CLIENT}.
157  *
158  * @param conn Connection to a remote server.
159  * @param out_client Pointer to client instance on success
160  *
161  * @retval 0 Success
162  * @retval -EINVAL @p conn or @p out_client is NULL
163  * @retval -ENOTCONN @p conn is not connected
164  * @retval -ENOMEM Could not allocated memory for the request
165  * @retval -EBUSY Already doing discovery for @p conn
166  * @retval -ENOEXEC Rejected by the GATT layer
167  */
168 int bt_ccp_call_control_client_discover(struct bt_conn *conn,
169 					struct bt_ccp_call_control_client **out_client);
170 
171 /**
172  * @brief Register callbacks for the Call Control Client
173  *
174  * @param cb The callback struct
175  *
176  * @retval 0 Succsss
177  * @retval -EINVAL @p cb is NULL
178  * @retval -EEXISTS @p cb is already registered
179  */
180 int bt_ccp_call_control_client_register_cb(struct bt_ccp_call_control_client_cb *cb);
181 
182 /**
183  * @brief Unregister callbacks for the Call Control Client
184  *
185  * @param cb The callback struct
186  *
187  * @retval 0 Succsss
188  * @retval -EINVAL @p cb is NULL
189  * @retval -EALREADY @p cb is not registered
190  */
191 int bt_ccp_call_control_client_unregister_cb(struct bt_ccp_call_control_client_cb *cb);
192 /** @} */ /* End of group bt_ccp_call_control_client */
193 #ifdef __cplusplus
194 }
195 #endif
196 
197 /**
198  * @}
199  */
200 
201 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_ */
202