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)42static 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)64static 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)96static 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)118static 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)146static 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)178static 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 #if defined(CONFIG_BT_TBS_CLIENT_CCID) 335 uint8_t ccid; 336 #endif /* defined(CONFIG_BT_TBS_CLIENT_CCID) */ 337 338 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) 339 struct bt_gatt_subscribe_params name_sub_params; 340 struct bt_gatt_discover_params name_sub_disc_params; 341 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_PROVIDER_NAME) */ 342 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) 343 struct bt_gatt_subscribe_params technology_sub_params; 344 struct bt_gatt_discover_params technology_sub_disc_params; 345 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_TECHNOLOGY) */ 346 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) 347 struct bt_gatt_subscribe_params signal_strength_sub_params; 348 struct bt_gatt_discover_params signal_strength_sub_disc_params; 349 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_SIGNAL_STRENGTH) */ 350 #if defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) 351 struct bt_gatt_subscribe_params current_calls_sub_params; 352 struct bt_gatt_discover_params current_calls_sub_disc_params; 353 #endif /* defined(CONFIG_BT_TBS_CLIENT_BEARER_LIST_CURRENT_CALLS) */ 354 #if defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) 355 struct bt_gatt_subscribe_params status_flags_sub_params; 356 struct bt_gatt_discover_params status_sub_disc_params; 357 #endif /* defined(CONFIG_BT_TBS_CLIENT_STATUS_FLAGS) */ 358 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) 359 struct bt_gatt_subscribe_params in_target_uri_sub_params; 360 struct bt_gatt_discover_params in_target_uri_sub_disc_params; 361 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_URI) */ 362 #if defined(CONFIG_BT_TBS_CLIENT_CP_PROCEDURES) 363 struct bt_gatt_subscribe_params call_cp_sub_params; 364 struct bt_gatt_discover_params call_cp_sub_disc_params; 365 #endif /* defined(CONFIG_BT_TBS_CLIENT_OPTIONAL_OPCODES) */ 366 #if defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) 367 struct bt_gatt_subscribe_params friendly_name_sub_params; 368 struct bt_gatt_discover_params friendly_name_sub_disc_params; 369 #endif /* defined(CONFIG_BT_TBS_CLIENT_CALL_FRIENDLY_NAME) */ 370 #if defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) 371 struct bt_gatt_subscribe_params incoming_call_sub_params; 372 struct bt_gatt_discover_params incoming_call_sub_disc_params; 373 #endif /* defined(CONFIG_BT_TBS_CLIENT_INCOMING_CALL) */ 374 struct bt_gatt_subscribe_params call_state_sub_params; 375 struct bt_gatt_discover_params call_state_sub_disc_params; 376 struct bt_gatt_subscribe_params termination_sub_params; 377 struct bt_gatt_discover_params termination_sub_disc_params; 378 struct bt_gatt_read_params read_params; 379 uint8_t read_buf[BT_TBS_CLIENT_INST_READ_BUF_SIZE]; 380 struct net_buf_simple net_buf; 381 }; 382 #endif /* CONFIG_BT_TBS_CLIENT */ 383