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