1 /** @file
2  *  @brief Internal APIs for Bluetooth TBS.
3  */
4 
5 /*
6  * Copyright (c) 2019 Bose Corporation
7  * Copyright (c) 2021 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/att.h>
18 #include <zephyr/bluetooth/audio/tbs.h>
19 #include <zephyr/bluetooth/gatt.h>
20 #include <zephyr/net_buf.h>
21 #include <zephyr/sys/atomic.h>
22 #include <zephyr/types.h>
23 
24 #define BT_TBS_MAX_UCI_SIZE                        6
25 #define BT_TBS_MIN_URI_LEN                         3 /* a:b */
26 #define BT_TBS_FREE_CALL_INDEX                     0
27 
28 /* Call Control Point Opcodes */
29 #define BT_TBS_CALL_OPCODE_ACCEPT                  0x00
30 #define BT_TBS_CALL_OPCODE_TERMINATE               0x01
31 #define BT_TBS_CALL_OPCODE_HOLD                    0x02
32 #define BT_TBS_CALL_OPCODE_RETRIEVE                0x03
33 #define BT_TBS_CALL_OPCODE_ORIGINATE               0x04
34 #define BT_TBS_CALL_OPCODE_JOIN                    0x05
35 
36 /* Local Control Points - Used to do local control operations but still being
37  * able to determine if it is a local or remote operation
38  */
39 #define BT_TBS_LOCAL_OPCODE_ANSWER                 0x80
40 #define BT_TBS_LOCAL_OPCODE_HOLD                   0x81
41 #define BT_TBS_LOCAL_OPCODE_RETRIEVE               0x82
42 #define BT_TBS_LOCAL_OPCODE_TERMINATE              0x83
43 #define BT_TBS_LOCAL_OPCODE_INCOMING               0x84
44 #define BT_TBS_LOCAL_OPCODE_SERVER_TERMINATE       0x85
45 
46 #define FIRST_PRINTABLE_ASCII_CHAR ' ' /* space */
47 
48 #define BT_TBS_CALL_FLAG_SET_INCOMING(flag) (flag &= ~BT_TBS_CALL_FLAG_OUTGOING)
49 #define BT_TBS_CALL_FLAG_SET_OUTGOING(flag) (flag |= BT_TBS_CALL_FLAG_OUTGOING)
50 
51 const char *parse_string_value(const void *data, uint16_t length,
52 				      uint16_t max_len);
53 
bt_tbs_state_str(uint8_t state)54 static inline const char *bt_tbs_state_str(uint8_t state)
55 {
56 	switch (state) {
57 	case BT_TBS_CALL_STATE_INCOMING:
58 		return "incoming";
59 	case BT_TBS_CALL_STATE_DIALING:
60 		return "dialing";
61 	case BT_TBS_CALL_STATE_ALERTING:
62 		return "alerting";
63 	case BT_TBS_CALL_STATE_ACTIVE:
64 		return "active";
65 	case BT_TBS_CALL_STATE_LOCALLY_HELD:
66 		return "locally held";
67 	case BT_TBS_CALL_STATE_REMOTELY_HELD:
68 		return "remote held";
69 	case BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD:
70 		return "locally and remotely held";
71 	default:
72 		return "unknown";
73 	}
74 }
75 
bt_tbs_opcode_str(uint8_t opcode)76 static inline const char *bt_tbs_opcode_str(uint8_t opcode)
77 {
78 	switch (opcode) {
79 	case BT_TBS_CALL_OPCODE_ACCEPT:
80 		return "accept";
81 	case BT_TBS_CALL_OPCODE_TERMINATE:
82 		return "terminate";
83 	case BT_TBS_CALL_OPCODE_HOLD:
84 		return "hold";
85 	case BT_TBS_CALL_OPCODE_RETRIEVE:
86 		return "retrieve";
87 	case BT_TBS_CALL_OPCODE_ORIGINATE:
88 		return "originate";
89 	case BT_TBS_CALL_OPCODE_JOIN:
90 		return "join";
91 	case BT_TBS_LOCAL_OPCODE_ANSWER:
92 		return "remote answer";
93 	case BT_TBS_LOCAL_OPCODE_HOLD:
94 		return "remote hold";
95 	case BT_TBS_LOCAL_OPCODE_RETRIEVE:
96 		return "remote retrieve";
97 	case BT_TBS_LOCAL_OPCODE_TERMINATE:
98 		return "remote terminate";
99 	case BT_TBS_LOCAL_OPCODE_INCOMING:
100 		return "remote incoming";
101 	case BT_TBS_LOCAL_OPCODE_SERVER_TERMINATE:
102 		return "server terminate";
103 	default:
104 		return "unknown";
105 	}
106 }
107 
bt_tbs_status_str(uint8_t status)108 static inline const char *bt_tbs_status_str(uint8_t status)
109 {
110 	switch (status) {
111 	case BT_TBS_RESULT_CODE_SUCCESS:
112 		return "success";
113 	case BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED:
114 		return "opcode not supported";
115 	case BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE:
116 		return "operation not possible";
117 	case BT_TBS_RESULT_CODE_INVALID_CALL_INDEX:
118 		return "invalid call index";
119 	case BT_TBS_RESULT_CODE_STATE_MISMATCH:
120 		return "state mismatch";
121 	case BT_TBS_RESULT_CODE_OUT_OF_RESOURCES:
122 		return "out of resources";
123 	case BT_TBS_RESULT_CODE_INVALID_URI:
124 		return "invalid URI";
125 	default:
126 		return "ATT err";
127 	}
128 }
129 
bt_tbs_technology_str(uint8_t status)130 static inline const char *bt_tbs_technology_str(uint8_t status)
131 {
132 	switch (status) {
133 	case BT_TBS_TECHNOLOGY_3G:
134 		return "3G";
135 	case BT_TBS_TECHNOLOGY_4G:
136 		return "4G";
137 	case BT_TBS_TECHNOLOGY_LTE:
138 		return "LTE";
139 	case BT_TBS_TECHNOLOGY_WIFI:
140 		return "WIFI";
141 	case BT_TBS_TECHNOLOGY_5G:
142 		return "5G";
143 	case BT_TBS_TECHNOLOGY_GSM:
144 		return "GSM";
145 	case BT_TBS_TECHNOLOGY_CDMA:
146 		return "CDMA";
147 	case BT_TBS_TECHNOLOGY_2G:
148 		return "2G";
149 	case BT_TBS_TECHNOLOGY_WCDMA:
150 		return "WCDMA";
151 	default:
152 		return "unknown technology";
153 	}
154 }
155 
bt_tbs_term_reason_str(uint8_t reason)156 static inline const char *bt_tbs_term_reason_str(uint8_t reason)
157 {
158 	switch (reason) {
159 	case BT_TBS_REASON_BAD_REMOTE_URI:
160 		return "bad remote URI";
161 	case BT_TBS_REASON_CALL_FAILED:
162 		return "call failed";
163 	case BT_TBS_REASON_REMOTE_ENDED_CALL:
164 		return "remote ended call";
165 	case BT_TBS_REASON_SERVER_ENDED_CALL:
166 		return "server ended call";
167 	case BT_TBS_REASON_LINE_BUSY:
168 		return "line busy";
169 	case BT_TBS_REASON_NETWORK_CONGESTED:
170 		return "network congested";
171 	case BT_TBS_REASON_CLIENT_TERMINATED:
172 		return "client terminated";
173 	case BT_TBS_REASON_UNSPECIFIED:
174 		return "unspecified";
175 	default:
176 		return "unknown reason";
177 	}
178 }
179 
180 /**
181  * @brief Checks if @p uri contains a colon (':') followed by a printable
182  * character. Minimal uri is "a:b".
183  *
184  * @param uri The uri "scheme:id"
185  * @param len The length of uri
186  * @return true If the above is true
187  * @return false If the above is not true
188  */
bt_tbs_valid_uri(const uint8_t * uri,size_t uri_len)189 static inline bool bt_tbs_valid_uri(const uint8_t *uri, size_t uri_len)
190 {
191 	if (!uri) {
192 		return false;
193 	}
194 
195 	if (uri_len > CONFIG_BT_TBS_MAX_URI_LENGTH || uri_len < BT_TBS_MIN_URI_LEN) {
196 		return false;
197 	} else if (uri[0] < FIRST_PRINTABLE_ASCII_CHAR) {
198 		/* Invalid first char */
199 		return false;
200 	}
201 
202 	for (size_t i = 1; i < uri_len; i++) {
203 		if (uri[i] == ':' && uri[i + 1] >= FIRST_PRINTABLE_ASCII_CHAR) {
204 			return true;
205 		}
206 	}
207 
208 	return false;
209 }
210 
211 /* TODO: The bt_tbs_call could use the bt_tbs_call_state struct for the first
212  * 3 fields
213  */
214 struct bt_tbs_call {
215 	uint8_t index;
216 	uint8_t state;
217 	uint8_t flags;
218 	char remote_uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
219 } __packed;
220 
221 struct bt_tbs_call_state {
222 	uint8_t index;
223 	uint8_t state;
224 	uint8_t flags;
225 } __packed;
226 
227 struct bt_tbs_call_cp_acc {
228 	uint8_t opcode;
229 	uint8_t call_index;
230 } __packed;
231 
232 struct bt_tbs_call_cp_term {
233 	uint8_t opcode;
234 	uint8_t call_index;
235 } __packed;
236 
237 struct bt_tbs_call_cp_hold {
238 	uint8_t opcode;
239 	uint8_t call_index;
240 } __packed;
241 
242 struct bt_tbs_call_cp_retrieve {
243 	uint8_t opcode;
244 	uint8_t call_index;
245 } __packed;
246 
247 struct bt_tbs_call_cp_originate {
248 	uint8_t opcode;
249 	uint8_t uri[0];
250 } __packed;
251 
252 struct bt_tbs_call_cp_join {
253 	uint8_t opcode;
254 	uint8_t call_indexes[0];
255 } __packed;
256 
257 union bt_tbs_call_cp_t {
258 	uint8_t opcode;
259 	struct bt_tbs_call_cp_acc accept;
260 	struct bt_tbs_call_cp_term terminate;
261 	struct bt_tbs_call_cp_hold hold;
262 	struct bt_tbs_call_cp_retrieve retrieve;
263 	struct bt_tbs_call_cp_originate originate;
264 	struct bt_tbs_call_cp_join join;
265 } __packed;
266 
267 struct bt_tbs_call_cp_notify {
268 	uint8_t opcode;
269 	uint8_t call_index;
270 	uint8_t status;
271 } __packed;
272 
273 struct bt_tbs_call_state_notify {
274 	uint8_t call_index;
275 	uint8_t state;
276 } __packed;
277 
278 struct bt_tbs_terminate_reason {
279 	uint8_t call_index;
280 	uint8_t reason;
281 } __packed;
282 
283 struct bt_tbs_current_call_item {
284 	uint8_t length;
285 	uint8_t call_index;
286 	uint8_t call_state;
287 	uint8_t uri[CONFIG_BT_TBS_MAX_URI_LENGTH];
288 } __packed;
289 
290 struct bt_tbs_in_uri {
291 	uint8_t call_index;
292 	char uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
293 } __packed;
294 
295 #if defined(CONFIG_BT_TBS_CLIENT)
296 
297 /* Features which may require long string reads */
298 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) || \
299 	defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) || \
300 	defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) || \
301 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) || \
302 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) || \
303 	defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) || \
304 	defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
305 #define BT_TBS_CLIENT_INST_READ_BUF_SIZE (BT_ATT_MAX_ATTRIBUTE_LEN + 1 /* NULL terminator*/)
306 #else
307 /* Need only be the size of call state reads which is the largest of the
308  * remaining characteristic values
309  */
310 #define BT_TBS_CLIENT_INST_READ_BUF_SIZE \
311 		MIN(BT_ATT_MAX_ATTRIBUTE_LEN, \
312 			(CONFIG_BT_TBS_CLIENT_MAX_CALLS \
313 			* sizeof(struct bt_tbs_client_call_state)))
314 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
315 
316 enum bt_tbs_client_flag {
317 	BT_TBS_CLIENT_FLAG_BUSY,
318 
319 	BT_TBS_CLIENT_FLAG_NUM_FLAGS, /* keep as last */
320 };
321 
322 struct bt_tbs_instance {
323 	struct bt_tbs_client_call_state calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
324 
325 	uint16_t start_handle;
326 	uint16_t end_handle;
327 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
328 	uint16_t bearer_uci_handle;
329 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
330 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
331 	uint16_t uri_list_handle;
332 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
333 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) \
334 || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL)
335 	uint16_t signal_interval_handle;
336 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
337 /* || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
338 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
339 	uint16_t ccid_handle;
340 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
341 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
342 	uint16_t optional_opcodes_handle;
343 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
344 	uint16_t termination_reason_handle;
345 
346 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
347 	uint8_t ccid;
348 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
349 
350 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
351 	struct bt_gatt_subscribe_params name_sub_params;
352 	struct bt_gatt_discover_params name_sub_disc_params;
353 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
354 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
355 	struct bt_gatt_subscribe_params technology_sub_params;
356 	struct bt_gatt_discover_params technology_sub_disc_params;
357 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
358 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
359 	struct bt_gatt_subscribe_params signal_strength_sub_params;
360 	struct bt_gatt_discover_params signal_strength_sub_disc_params;
361 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
362 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
363 	struct bt_gatt_subscribe_params current_calls_sub_params;
364 	struct bt_gatt_discover_params current_calls_sub_disc_params;
365 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
366 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
367 	struct bt_gatt_subscribe_params status_flags_sub_params;
368 	struct bt_gatt_discover_params status_sub_disc_params;
369 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
370 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
371 	struct bt_gatt_subscribe_params in_target_uri_sub_params;
372 	struct bt_gatt_discover_params in_target_uri_sub_disc_params;
373 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
374 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
375 	struct bt_gatt_subscribe_params call_cp_sub_params;
376 	struct bt_gatt_discover_params call_cp_sub_disc_params;
377 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
378 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
379 	struct bt_gatt_subscribe_params friendly_name_sub_params;
380 	struct bt_gatt_discover_params friendly_name_sub_disc_params;
381 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
382 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
383 	struct bt_gatt_subscribe_params incoming_call_sub_params;
384 	struct bt_gatt_discover_params incoming_call_sub_disc_params;
385 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
386 	struct bt_gatt_subscribe_params call_state_sub_params;
387 	struct bt_gatt_discover_params call_state_sub_disc_params;
388 	struct bt_gatt_subscribe_params termination_sub_params;
389 	struct bt_gatt_discover_params termination_sub_disc_params;
390 	struct bt_gatt_read_params read_params;
391 	uint8_t read_buf[BT_TBS_CLIENT_INST_READ_BUF_SIZE];
392 	struct net_buf_simple net_buf;
393 
394 	ATOMIC_DEFINE(flags, BT_TBS_CLIENT_FLAG_NUM_FLAGS);
395 };
396 #endif /* CONFIG_BT_TBS_CLIENT */
397