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/types.h>
22 
23 #define BT_TBS_MAX_UCI_SIZE                        6
24 #define BT_TBS_MIN_URI_LEN                         3 /* a:b */
25 #define BT_TBS_FREE_CALL_INDEX                     0
26 
27 /* Call Control Point Opcodes */
28 #define BT_TBS_CALL_OPCODE_ACCEPT                  0x00
29 #define BT_TBS_CALL_OPCODE_TERMINATE               0x01
30 #define BT_TBS_CALL_OPCODE_HOLD                    0x02
31 #define BT_TBS_CALL_OPCODE_RETRIEVE                0x03
32 #define BT_TBS_CALL_OPCODE_ORIGINATE               0x04
33 #define BT_TBS_CALL_OPCODE_JOIN                    0x05
34 
35 /* Local Control Points - Used to do local control operations but still being
36  * able to determine if it is a local or remote operation
37  */
38 #define BT_TBS_LOCAL_OPCODE_ANSWER                 0x80
39 #define BT_TBS_LOCAL_OPCODE_HOLD                   0x81
40 #define BT_TBS_LOCAL_OPCODE_RETRIEVE               0x82
41 #define BT_TBS_LOCAL_OPCODE_TERMINATE              0x83
42 #define BT_TBS_LOCAL_OPCODE_INCOMING               0x84
43 #define BT_TBS_LOCAL_OPCODE_SERVER_TERMINATE       0x85
44 
45 #define FIRST_PRINTABLE_ASCII_CHAR ' ' /* space */
46 
47 #define BT_TBS_CALL_FLAG_SET_INCOMING(flag) (flag &= ~BT_TBS_CALL_FLAG_OUTGOING)
48 #define BT_TBS_CALL_FLAG_SET_OUTGOING(flag) (flag |= BT_TBS_CALL_FLAG_OUTGOING)
49 
50 const char *parse_string_value(const void *data, uint16_t length,
51 				      uint16_t max_len);
52 
bt_tbs_state_str(uint8_t state)53 static inline const char *bt_tbs_state_str(uint8_t state)
54 {
55 	switch (state) {
56 	case BT_TBS_CALL_STATE_INCOMING:
57 		return "incoming";
58 	case BT_TBS_CALL_STATE_DIALING:
59 		return "dialing";
60 	case BT_TBS_CALL_STATE_ALERTING:
61 		return "alerting";
62 	case BT_TBS_CALL_STATE_ACTIVE:
63 		return "active";
64 	case BT_TBS_CALL_STATE_LOCALLY_HELD:
65 		return "locally held";
66 	case BT_TBS_CALL_STATE_REMOTELY_HELD:
67 		return "remote held";
68 	case BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD:
69 		return "locally and remotely held";
70 	default:
71 		return "unknown";
72 	}
73 }
74 
bt_tbs_opcode_str(uint8_t opcode)75 static inline const char *bt_tbs_opcode_str(uint8_t opcode)
76 {
77 	switch (opcode) {
78 	case BT_TBS_CALL_OPCODE_ACCEPT:
79 		return "accept";
80 	case BT_TBS_CALL_OPCODE_TERMINATE:
81 		return "terminate";
82 	case BT_TBS_CALL_OPCODE_HOLD:
83 		return "hold";
84 	case BT_TBS_CALL_OPCODE_RETRIEVE:
85 		return "retrieve";
86 	case BT_TBS_CALL_OPCODE_ORIGINATE:
87 		return "originate";
88 	case BT_TBS_CALL_OPCODE_JOIN:
89 		return "join";
90 	case BT_TBS_LOCAL_OPCODE_ANSWER:
91 		return "remote answer";
92 	case BT_TBS_LOCAL_OPCODE_HOLD:
93 		return "remote hold";
94 	case BT_TBS_LOCAL_OPCODE_RETRIEVE:
95 		return "remote retrieve";
96 	case BT_TBS_LOCAL_OPCODE_TERMINATE:
97 		return "remote terminate";
98 	case BT_TBS_LOCAL_OPCODE_INCOMING:
99 		return "remote incoming";
100 	case BT_TBS_LOCAL_OPCODE_SERVER_TERMINATE:
101 		return "server terminate";
102 	default:
103 		return "unknown";
104 	}
105 }
106 
bt_tbs_status_str(uint8_t status)107 static inline const char *bt_tbs_status_str(uint8_t status)
108 {
109 	switch (status) {
110 	case BT_TBS_RESULT_CODE_SUCCESS:
111 		return "success";
112 	case BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED:
113 		return "opcode not supported";
114 	case BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE:
115 		return "operation not possible";
116 	case BT_TBS_RESULT_CODE_INVALID_CALL_INDEX:
117 		return "invalid call index";
118 	case BT_TBS_RESULT_CODE_STATE_MISMATCH:
119 		return "state mismatch";
120 	case BT_TBS_RESULT_CODE_OUT_OF_RESOURCES:
121 		return "out of resources";
122 	case BT_TBS_RESULT_CODE_INVALID_URI:
123 		return "invalid URI";
124 	default:
125 		return "ATT err";
126 	}
127 }
128 
bt_tbs_technology_str(uint8_t status)129 static inline const char *bt_tbs_technology_str(uint8_t status)
130 {
131 	switch (status) {
132 	case BT_TBS_TECHNOLOGY_3G:
133 		return "3G";
134 	case BT_TBS_TECHNOLOGY_4G:
135 		return "4G";
136 	case BT_TBS_TECHNOLOGY_LTE:
137 		return "LTE";
138 	case BT_TBS_TECHNOLOGY_WIFI:
139 		return "WIFI";
140 	case BT_TBS_TECHNOLOGY_5G:
141 		return "5G";
142 	case BT_TBS_TECHNOLOGY_GSM:
143 		return "GSM";
144 	case BT_TBS_TECHNOLOGY_CDMA:
145 		return "CDMA";
146 	case BT_TBS_TECHNOLOGY_2G:
147 		return "2G";
148 	case BT_TBS_TECHNOLOGY_WCDMA:
149 		return "WCDMA";
150 	default:
151 		return "unknown technology";
152 	}
153 }
154 
bt_tbs_term_reason_str(uint8_t reason)155 static inline const char *bt_tbs_term_reason_str(uint8_t reason)
156 {
157 	switch (reason) {
158 	case BT_TBS_REASON_BAD_REMOTE_URI:
159 		return "bad remote URI";
160 	case BT_TBS_REASON_CALL_FAILED:
161 		return "call failed";
162 	case BT_TBS_REASON_REMOTE_ENDED_CALL:
163 		return "remote ended call";
164 	case BT_TBS_REASON_SERVER_ENDED_CALL:
165 		return "server ended call";
166 	case BT_TBS_REASON_LINE_BUSY:
167 		return "line busy";
168 	case BT_TBS_REASON_NETWORK_CONGESTED:
169 		return "network congested";
170 	case BT_TBS_REASON_CLIENT_TERMINATED:
171 		return "client terminated";
172 	case BT_TBS_REASON_UNSPECIFIED:
173 		return "unspecified";
174 	default:
175 		return "unknown reason";
176 	}
177 }
178 
179 /**
180  * @brief Checks if a string contains a colon (':') followed by a printable
181  * character. Minimal uri is "a:b".
182  *
183  * @param uri The uri "scheme:id"
184  * @param len The length of uri
185  * @return true If the above is true
186  * @return false If the above is not true
187  */
bt_tbs_valid_uri(const char * uri,size_t len)188 static inline bool bt_tbs_valid_uri(const char *uri, size_t len)
189 {
190 	if (!uri) {
191 		return false;
192 	}
193 
194 	if (len > CONFIG_BT_TBS_MAX_URI_LENGTH ||
195 	    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 (int i = 1; i < 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)
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 struct bt_tbs_instance {
317 	struct bt_tbs_client_call_state calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
318 
319 	uint16_t start_handle;
320 	uint16_t end_handle;
321 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI)
322 	uint16_t bearer_uci_handle;
323 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_UCI) */
324 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST)
325 	uint16_t uri_list_handle;
326 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST) */
327 #if defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) \
328 || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL)
329 	uint16_t signal_interval_handle;
330 #endif /* defined(CONFIG_BT_TBS_CLIENT_READ_BEARER_SIGNAL_INTERVAL) */
331 /* || defined(CONFIG_BT_TBS_CLIENT_SET_BEARER_SIGNAL_INTERVAL) */
332 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
333 	uint16_t ccid_handle;
334 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
335 #if defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES)
336 	uint16_t optional_opcodes_handle;
337 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
338 	uint16_t termination_reason_handle;
339 
340 	bool busy;
341 #if defined(CONFIG_BT_TBS_CLIENT_CCID)
342 	uint8_t ccid;
343 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */
344 
345 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME)
346 	struct bt_gatt_subscribe_params name_sub_params;
347 	struct bt_gatt_discover_params name_sub_disc_params;
348 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */
349 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY)
350 	struct bt_gatt_subscribe_params technology_sub_params;
351 	struct bt_gatt_discover_params technology_sub_disc_params;
352 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */
353 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH)
354 	struct bt_gatt_subscribe_params signal_strength_sub_params;
355 	struct bt_gatt_discover_params signal_strength_sub_disc_params;
356 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */
357 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS)
358 	struct bt_gatt_subscribe_params current_calls_sub_params;
359 	struct bt_gatt_discover_params current_calls_sub_disc_params;
360 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */
361 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS)
362 	struct bt_gatt_subscribe_params status_flags_sub_params;
363 	struct bt_gatt_discover_params status_sub_disc_params;
364 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */
365 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI)
366 	struct bt_gatt_subscribe_params in_target_uri_sub_params;
367 	struct bt_gatt_discover_params in_target_uri_sub_disc_params;
368 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */
369 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES)
370 	struct bt_gatt_subscribe_params call_cp_sub_params;
371 	struct bt_gatt_discover_params call_cp_sub_disc_params;
372 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */
373 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME)
374 	struct bt_gatt_subscribe_params friendly_name_sub_params;
375 	struct bt_gatt_discover_params friendly_name_sub_disc_params;
376 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */
377 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL)
378 	struct bt_gatt_subscribe_params incoming_call_sub_params;
379 	struct bt_gatt_discover_params incoming_call_sub_disc_params;
380 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */
381 	struct bt_gatt_subscribe_params call_state_sub_params;
382 	struct bt_gatt_discover_params call_state_sub_disc_params;
383 	struct bt_gatt_subscribe_params termination_sub_params;
384 	struct bt_gatt_discover_params termination_sub_disc_params;
385 	struct bt_gatt_read_params read_params;
386 	uint8_t read_buf[BT_TBS_CLIENT_INST_READ_BUF_SIZE];
387 	struct net_buf_simple net_buf;
388 };
389 #endif /* CONFIG_BT_TBS_CLIENT */
390