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  * @param len The length of uri
176  * @return true If the above is true
177  * @return false If the above is not true
178  */
bt_tbs_valid_uri(const char * uri,size_t len)179 static inline bool bt_tbs_valid_uri(const char *uri, size_t len)
180 {
181 	if (!uri) {
182 		return false;
183 	}
184 
185 	if (len > CONFIG_BT_TBS_MAX_URI_LENGTH ||
186 	    len < BT_TBS_MIN_URI_LEN) {
187 		return false;
188 	} else if (uri[0] < FIRST_PRINTABLE_ASCII_CHAR) {
189 		/* Invalid first char */
190 		return false;
191 	}
192 
193 	for (int i = 1; i < len; i++) {
194 		if (uri[i] == ':' && uri[i + 1] >= FIRST_PRINTABLE_ASCII_CHAR) {
195 			return true;
196 		}
197 	}
198 
199 	return false;
200 }
201 
202 /* TODO: The bt_tbs_call could use the bt_tbs_call_state struct for the first
203  * 3 fields
204  */
205 struct bt_tbs_call {
206 	uint8_t index;
207 	uint8_t state;
208 	uint8_t flags;
209 	char remote_uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
210 } __packed;
211 
212 struct bt_tbs_call_state {
213 	uint8_t index;
214 	uint8_t state;
215 	uint8_t flags;
216 } __packed;
217 
218 struct bt_tbs_call_cp_acc {
219 	uint8_t opcode;
220 	uint8_t call_index;
221 } __packed;
222 
223 struct bt_tbs_call_cp_term {
224 	uint8_t opcode;
225 	uint8_t call_index;
226 } __packed;
227 
228 struct bt_tbs_call_cp_hold {
229 	uint8_t opcode;
230 	uint8_t call_index;
231 } __packed;
232 
233 struct bt_tbs_call_cp_retrieve {
234 	uint8_t opcode;
235 	uint8_t call_index;
236 } __packed;
237 
238 struct bt_tbs_call_cp_originate {
239 	uint8_t opcode;
240 	uint8_t uri[0];
241 } __packed;
242 
243 struct bt_tbs_call_cp_join {
244 	uint8_t opcode;
245 	uint8_t call_indexes[0];
246 } __packed;
247 
248 union bt_tbs_call_cp_t {
249 	uint8_t opcode;
250 	struct bt_tbs_call_cp_acc accept;
251 	struct bt_tbs_call_cp_term terminate;
252 	struct bt_tbs_call_cp_hold hold;
253 	struct bt_tbs_call_cp_retrieve retrieve;
254 	struct bt_tbs_call_cp_originate originate;
255 	struct bt_tbs_call_cp_join join;
256 } __packed;
257 
258 struct bt_tbs_call_cp_notify {
259 	uint8_t opcode;
260 	uint8_t call_index;
261 	uint8_t status;
262 } __packed;
263 
264 struct bt_tbs_call_state_notify {
265 	uint8_t call_index;
266 	uint8_t state;
267 } __packed;
268 
269 struct bt_tbs_terminate_reason {
270 	uint8_t call_index;
271 	uint8_t reason;
272 } __packed;
273 
274 struct bt_tbs_current_call_item {
275 	uint8_t length;
276 	uint8_t call_index;
277 	uint8_t call_state;
278 	uint8_t uri[CONFIG_BT_TBS_MAX_URI_LENGTH];
279 } __packed;
280 
281 struct bt_tbs_in_uri {
282 	uint8_t call_index;
283 	char uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
284 } __packed;
285 
286 #if defined(CONFIG_BT_TBS_CLIENT)
287 
288 /* Features which may require long string reads */
289 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) || \
290 	defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) || \
291 	defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) || \
292 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) || \
293 	defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) || \
294 	defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) || \
295 	defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
296 #define BT_TBS_CLIENT_INST_READ_BUF_SIZE (BT_ATT_MAX_ATTRIBUTE_LEN)
297 #else
298 /* Need only be the size of call state reads which is the largest of the
299  * remaining characteristic values
300  */
301 #define BT_TBS_CLIENT_INST_READ_BUF_SIZE \
302 		MIN(BT_ATT_MAX_ATTRIBUTE_LEN, \
303 			(CONFIG_BT_TBS_CLIENT_MAX_CALLS \
304 			* sizeof(struct bt_tbs_client_call_state)))
305 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
306 
307 struct bt_tbs_instance {
308 	struct bt_tbs_client_call_state calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
309 
310 	uint16_t start_handle;
311 	uint16_t end_handle;
312 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
313 	uint16_t bearer_uci_handle;
314 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
315 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
316 	uint16_t uri_list_handle;
317 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
318 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) \
319 || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL)
320 	uint16_t signal_interval_handle;
321 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
322 /* || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
323 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
324 	uint16_t ccid_handle;
325 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
326 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
327 	uint16_t optional_opcodes_handle;
328 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
329 	uint16_t termination_reason_handle;
330 
331 	bool busy;
332 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
333 	uint8_t ccid;
334 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
335 
336 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
337 	struct bt_gatt_subscribe_params name_sub_params;
338 	struct bt_gatt_discover_params name_sub_disc_params;
339 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
340 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
341 	struct bt_gatt_subscribe_params technology_sub_params;
342 	struct bt_gatt_discover_params technology_sub_disc_params;
343 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
344 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
345 	struct bt_gatt_subscribe_params signal_strength_sub_params;
346 	struct bt_gatt_discover_params signal_strength_sub_disc_params;
347 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
348 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
349 	struct bt_gatt_subscribe_params current_calls_sub_params;
350 	struct bt_gatt_discover_params current_calls_sub_disc_params;
351 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
352 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
353 	struct bt_gatt_subscribe_params status_flags_sub_params;
354 	struct bt_gatt_discover_params status_sub_disc_params;
355 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
356 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
357 	struct bt_gatt_subscribe_params in_target_uri_sub_params;
358 	struct bt_gatt_discover_params in_target_uri_sub_disc_params;
359 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
360 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
361 	struct bt_gatt_subscribe_params call_cp_sub_params;
362 	struct bt_gatt_discover_params call_cp_sub_disc_params;
363 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
364 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
365 	struct bt_gatt_subscribe_params friendly_name_sub_params;
366 	struct bt_gatt_discover_params friendly_name_sub_disc_params;
367 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
368 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
369 	struct bt_gatt_subscribe_params incoming_call_sub_params;
370 	struct bt_gatt_discover_params incoming_call_sub_disc_params;
371 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
372 	struct bt_gatt_subscribe_params call_state_sub_params;
373 	struct bt_gatt_discover_params call_state_sub_disc_params;
374 	struct bt_gatt_subscribe_params termination_sub_params;
375 	struct bt_gatt_discover_params termination_sub_disc_params;
376 	struct bt_gatt_read_params read_params;
377 	uint8_t read_buf[BT_TBS_CLIENT_INST_READ_BUF_SIZE];
378 	struct net_buf_simple net_buf;
379 };
380 #endif /* CONFIG_BT_TBS_CLIENT */
381