1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "hfp_hf.c" 39 40 // ***************************************************************************** 41 // 42 // HFP Hands-Free (HF) unit 43 // 44 // ***************************************************************************** 45 46 #include "btstack_config.h" 47 48 #include <stdint.h> 49 #include <stdio.h> 50 #include <string.h> 51 52 #include "bluetooth_sdp.h" 53 #include "btstack_debug.h" 54 #include "btstack_event.h" 55 #include "btstack_memory.h" 56 #include "btstack_run_loop.h" 57 #include "classic/core.h" 58 #include "classic/hfp.h" 59 #include "classic/hfp_hf.h" 60 #include "classic/sdp_client_rfcomm.h" 61 #include "classic/sdp_server.h" 62 #include "classic/sdp_util.h" 63 #include "hci.h" 64 #include "hci_cmd.h" 65 #include "hci_dump.h" 66 #include "l2cap.h" 67 68 // const 69 static const char hfp_hf_default_service_name[] = "Hands-Free unit"; 70 71 // globals 72 73 // higher layer callbacks 74 static btstack_packet_handler_t hfp_hf_callback; 75 76 static btstack_packet_callback_registration_t hfp_hf_hci_event_callback_registration; 77 78 static uint16_t hfp_hf_supported_features; 79 static uint8_t hfp_hf_codecs_nr; 80 static uint8_t hfp_hf_codecs[HFP_MAX_NUM_CODECS]; 81 82 static uint8_t hfp_hf_indicators_nr; 83 static uint8_t hfp_hf_indicators[HFP_MAX_NUM_INDICATORS]; 84 static uint32_t hfp_hf_indicators_value[HFP_MAX_NUM_INDICATORS]; 85 86 static uint8_t hfp_hf_speaker_gain; 87 static uint8_t hfp_hf_microphone_gain; 88 static char hfp_hf_phone_number[25]; 89 90 // Apple Accessory Information 91 static uint16_t hfp_hf_apple_vendor_id; 92 static uint16_t hfp_hf_apple_product_id; 93 static const char * hfp_hf_apple_version; 94 static uint8_t hfp_hf_apple_features; 95 static int8_t hfp_hf_apple_battery_level; 96 static int8_t hfp_hf_apple_docked; 97 98 99 static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ 100 int hf = get_bit(hfp_hf_supported_features, HFP_HFSF_CODEC_NEGOTIATION); 101 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); 102 return hf && ag; 103 } 104 105 static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){ 106 int hf = get_bit(hfp_hf_supported_features, HFP_HFSF_THREE_WAY_CALLING); 107 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); 108 return hf && ag; 109 } 110 111 112 static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ 113 int hf = get_bit(hfp_hf_supported_features, HFP_HFSF_HF_INDICATORS); 114 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); 115 return hf && ag; 116 } 117 118 static bool hfp_hf_vra_flag_supported(hfp_connection_t * hfp_connection){ 119 int hf = get_bit(hfp_hf_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION); 120 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION); 121 return hf && ag; 122 } 123 124 static bool hfp_hf_enhanced_vra_flag_supported(hfp_connection_t * hfp_connection){ 125 int hf = get_bit(hfp_hf_supported_features, HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS); 126 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS); 127 return hf && ag; 128 } 129 130 static hfp_connection_t * get_hfp_hf_connection_context_for_acl_handle(uint16_t handle){ 131 btstack_linked_list_iterator_t it; 132 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 133 while (btstack_linked_list_iterator_has_next(&it)){ 134 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 135 if (hfp_connection->acl_handle != handle) continue; 136 if (hfp_connection->local_role != HFP_ROLE_HF) continue; 137 return hfp_connection; 138 } 139 return NULL; 140 } 141 142 /* emit functions */ 143 144 static void hfp_hf_emit_subscriber_information(const hfp_connection_t * hfp_connection, uint8_t status){ 145 if (hfp_hf_callback == NULL) return; 146 uint16_t bnip_number_len = btstack_min((uint16_t) strlen(hfp_connection->bnip_number), sizeof(hfp_connection->bnip_number)-1); 147 uint8_t event[7 + sizeof(hfp_connection->bnip_number)]; 148 event[0] = HCI_EVENT_HFP_META; 149 event[1] = 6 + bnip_number_len; 150 event[2] = HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION; 151 little_endian_store_16(event, 3, hfp_connection->acl_handle); 152 event[5] = status; 153 event[6] = hfp_connection->bnip_type; 154 memcpy(&event[7], hfp_connection->bnip_number, bnip_number_len); 155 event[7 + bnip_number_len] = 0; 156 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 8 + bnip_number_len); 157 } 158 159 static void hfp_hf_emit_type_number_alpha(const hfp_connection_t * hfp_connection, uint8_t event_subtype){ 160 if (hfp_hf_callback == NULL) return; 161 uint16_t bnip_number_len = btstack_min((uint16_t) strlen(hfp_connection->bnip_number), sizeof(hfp_connection->bnip_number)-1); 162 // 10 fixed - 1 (bnip_number_len <= sizeof(hfp_connection->bnip_number)-1) + 1 (trailing \0 for line buffer) 163 uint8_t event[10 + sizeof(hfp_connection->bnip_number) + sizeof(hfp_connection->line_buffer)]; 164 uint8_t alpha_len = hfp_connection->clip_have_alpha ? (uint16_t) strlen((const char *) hfp_connection->line_buffer) : 0; 165 uint8_t pos = 0; 166 event[pos++] = HCI_EVENT_HFP_META; 167 event[pos++] = 8 + bnip_number_len + alpha_len; 168 event[pos++] = event_subtype; 169 little_endian_store_16(event, 3, hfp_connection->acl_handle); 170 pos += 2; 171 event[pos++] = hfp_connection->bnip_type; 172 event[pos++] = bnip_number_len + 1; 173 memcpy(&event[7], hfp_connection->bnip_number, bnip_number_len); 174 pos += bnip_number_len; 175 event[pos++] = 0; 176 event[pos++] = alpha_len + 1; 177 memcpy(&event[pos], hfp_connection->line_buffer, alpha_len); 178 pos += alpha_len; 179 event[pos++] = 0; 180 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, pos); 181 } 182 183 static void hfp_hf_emit_enhanced_call_status(const hfp_connection_t * hfp_connection){ 184 if (hfp_hf_callback == NULL) return; 185 186 uint16_t bnip_number_len = (uint16_t) strlen((const char *) hfp_connection->bnip_number); 187 uint8_t event[11 + HFP_BNEP_NUM_MAX_SIZE]; 188 event[0] = HCI_EVENT_HFP_META; 189 event[1] = 10 + bnip_number_len + 1; 190 event[2] = HFP_SUBEVENT_ENHANCED_CALL_STATUS; 191 little_endian_store_16(event, 3, hfp_connection->acl_handle); 192 event[5] = hfp_connection->clcc_idx; 193 event[6] = hfp_connection->clcc_dir; 194 event[7] = hfp_connection->clcc_status; 195 event[8] = hfp_connection->clcc_mode; 196 event[9] = hfp_connection->clcc_mpty; 197 event[10] = hfp_connection->bnip_type; 198 memcpy(&event[11], hfp_connection->bnip_number, bnip_number_len + 1); 199 200 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 11 + bnip_number_len + 1); 201 } 202 203 static void hfp_emit_ag_indicator_mapping_event(const hfp_connection_t * hfp_connection, const hfp_ag_indicator_t * indicator){ 204 if (hfp_hf_callback == NULL) return; 205 uint8_t event[8 + HFP_MAX_INDICATOR_DESC_SIZE]; 206 uint16_t indicator_len = btstack_min((uint16_t) strlen(indicator->name), HFP_MAX_INDICATOR_DESC_SIZE-1); 207 event[0] = HCI_EVENT_HFP_META; 208 event[1] = 7 + indicator_len; 209 event[2] = HFP_SUBEVENT_AG_INDICATOR_MAPPING; 210 little_endian_store_16(event, 3, hfp_connection->acl_handle); 211 event[5] = indicator->index; 212 event[6] = indicator->min_range; 213 event[7] = indicator->max_range; 214 memcpy(&event[8], indicator->name, indicator_len); 215 event[8+indicator_len] = 0; 216 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 9 + indicator_len); 217 } 218 219 static void hfp_emit_ag_indicator_status_event(const hfp_connection_t * hfp_connection, const hfp_ag_indicator_t * indicator){ 220 if (hfp_hf_callback == NULL) return; 221 uint8_t event[12+HFP_MAX_INDICATOR_DESC_SIZE]; 222 uint16_t indicator_len = btstack_min((uint16_t) strlen(indicator->name), HFP_MAX_INDICATOR_DESC_SIZE-1); 223 event[0] = HCI_EVENT_HFP_META; 224 event[1] = 11 + indicator_len; 225 event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; 226 little_endian_store_16(event, 3, hfp_connection->acl_handle); 227 event[5] = indicator->index; 228 event[6] = indicator->status; 229 event[7] = indicator->min_range; 230 event[8] = indicator->max_range; 231 event[9] = indicator->mandatory; 232 event[10] = indicator->enabled; 233 event[11] = indicator->status_changed; 234 memcpy(&event[12], indicator->name, indicator_len); 235 event[12+indicator_len] = 0; 236 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 13 + indicator_len); 237 } 238 239 static void hfp_emit_network_operator_event(const hfp_connection_t * hfp_connection){ 240 if (hfp_hf_callback == NULL) return; 241 uint16_t operator_len = btstack_min((uint16_t) strlen(hfp_connection->network_operator.name), HFP_MAX_NETWORK_OPERATOR_NAME_SIZE-1); 242 uint8_t event[7+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE]; 243 event[0] = HCI_EVENT_HFP_META; 244 event[1] = sizeof(event) - 2; 245 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; 246 little_endian_store_16(event, 3, hfp_connection->acl_handle); 247 event[5] = hfp_connection->network_operator.mode; 248 event[6] = hfp_connection->network_operator.format; 249 memcpy(&event[7], hfp_connection->network_operator.name, operator_len); 250 event[7+operator_len] = 0; 251 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 8 + operator_len); 252 } 253 254 255 static void hfp_hf_emit_enhanced_voice_recognition_text(hfp_connection_t * hfp_connection){ 256 btstack_assert(hfp_connection != NULL); 257 uint8_t event[HFP_MAX_VR_TEXT_SIZE + 11]; 258 int pos = 0; 259 event[pos++] = HCI_EVENT_HFP_META; 260 event[pos++] = sizeof(event) - 2; 261 event[pos++] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_MESSAGE; 262 little_endian_store_16(event, pos, hfp_connection->acl_handle); 263 pos += 2; 264 little_endian_store_16(event, pos, hfp_connection->ag_msg.text_id); 265 pos += 2; 266 event[pos++] = hfp_connection->ag_msg.text_type; 267 event[pos++] = hfp_connection->ag_msg.text_operation; 268 269 // length, zero ending is already in message 270 uint8_t * value = &hfp_connection->line_buffer[0]; 271 uint16_t value_length = hfp_connection->ag_vra_msg_length; 272 273 little_endian_store_16(event, pos, value_length); 274 pos += 2; 275 memcpy(&event[pos], value, value_length); 276 pos += value_length; 277 278 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, pos); 279 } 280 281 static void hfp_hf_emit_custom_command_event(hfp_connection_t * hfp_connection){ 282 btstack_assert(sizeof(hfp_connection->line_buffer) < (255-5)); 283 284 uint16_t line_len = (uint16_t) strlen((const char*)hfp_connection->line_buffer) + 1; 285 uint8_t event[7 + sizeof(hfp_connection->line_buffer)]; 286 event[0] = HCI_EVENT_HFP_META; 287 event[1] = 5 + line_len; 288 event[2] = HFP_SUBEVENT_CUSTOM_AT_COMMAND; 289 little_endian_store_16(event, 3, hfp_connection->acl_handle); 290 little_endian_store_16(event, 5, hfp_connection->custom_at_command_id); 291 memcpy(&event[7], hfp_connection->line_buffer, line_len); 292 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, 7 + line_len); 293 } 294 295 /* send commands */ 296 297 static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){ 298 char buffer[20]; 299 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s\r", cmd); 300 return send_str_over_rfcomm(cid, buffer); 301 } 302 303 static inline int hfp_hf_send_cmd_with_mark(uint16_t cid, const char * cmd, const char * mark){ 304 char buffer[20]; 305 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s%s\r", cmd, mark); 306 return send_str_over_rfcomm(cid, buffer); 307 } 308 309 static inline int hfp_hf_send_cmd_with_int(uint16_t cid, const char * cmd, uint16_t value){ 310 char buffer[40]; 311 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%d\r", cmd, value); 312 return send_str_over_rfcomm(cid, buffer); 313 } 314 315 static int hfp_hf_cmd_notify_on_codecs(uint16_t cid){ 316 char buffer[30]; 317 const int size = sizeof(buffer); 318 int offset = btstack_snprintf_assert_complete(buffer, size, "AT%s=", HFP_AVAILABLE_CODECS); 319 offset += join(buffer+offset, size-offset, hfp_hf_codecs, hfp_hf_codecs_nr); 320 offset += btstack_snprintf_assert_complete(buffer+offset, size-offset, "\r"); 321 return send_str_over_rfcomm(cid, buffer); 322 } 323 324 static int hfp_hf_cmd_activate_status_update_for_ag_indicator(uint16_t cid, uint32_t indicators_status, int indicators_nr){ 325 char buffer[50]; 326 const int size = sizeof(buffer); 327 int offset = btstack_snprintf_assert_complete(buffer, size, "AT%s=", HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 328 offset += join_bitmap(buffer+offset, size-offset, indicators_status, indicators_nr); 329 offset += btstack_snprintf_assert_complete(buffer+offset, size-offset, "\r"); 330 return send_str_over_rfcomm(cid, buffer); 331 } 332 333 static int hfp_hf_cmd_list_supported_generic_status_indicators(uint16_t cid){ 334 char buffer[30]; 335 const int size = sizeof(buffer); 336 int offset = btstack_snprintf_assert_complete(buffer, size, "AT%s=", HFP_GENERIC_STATUS_INDICATOR); 337 offset += join(buffer+offset, size-offset, hfp_hf_indicators, hfp_hf_indicators_nr); 338 offset += btstack_snprintf_assert_complete(buffer+offset, size-offset, "\r"); 339 return send_str_over_rfcomm(cid, buffer); 340 } 341 342 static int hfp_hf_cmd_activate_status_update_for_all_ag_indicators(uint16_t cid, uint8_t activate){ 343 char buffer[20]; 344 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=3,0,0,%d\r", HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, activate); 345 return send_str_over_rfcomm(cid, buffer); 346 } 347 348 static int hfp_hf_initiate_outgoing_call_cmd(uint16_t cid){ 349 char buffer[40]; 350 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%s%s;\r", HFP_CALL_PHONE_NUMBER, hfp_hf_phone_number); 351 return send_str_over_rfcomm(cid, buffer); 352 } 353 354 static int hfp_hf_send_memory_dial_cmd(uint16_t cid, int memory_id){ 355 char buffer[40]; 356 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "%s>%d;\r", HFP_CALL_PHONE_NUMBER, memory_id); 357 return send_str_over_rfcomm(cid, buffer); 358 } 359 360 static int hfp_hf_send_chld(uint16_t cid, unsigned int number){ 361 char buffer[40]; 362 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%u\r", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, number); 363 return send_str_over_rfcomm(cid, buffer); 364 } 365 366 static int hfp_hf_send_dtmf(uint16_t cid, char code){ 367 char buffer[20]; 368 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%c\r", HFP_TRANSMIT_DTMF_CODES, code); 369 return send_str_over_rfcomm(cid, buffer); 370 } 371 372 static int hfp_hf_cmd_ata(uint16_t cid){ 373 return send_str_over_rfcomm(cid, (char *) "ATA\r"); 374 } 375 376 static int hfp_hf_cmd_exchange_supported_features(uint16_t cid){ 377 return hfp_hf_send_cmd_with_int(cid, HFP_SUPPORTED_FEATURES, hfp_hf_supported_features); 378 } 379 380 static int hfp_hf_cmd_retrieve_indicators(uint16_t cid){ 381 return hfp_hf_send_cmd_with_mark(cid, HFP_INDICATOR, "=?"); 382 } 383 384 static int hfp_hf_cmd_retrieve_indicators_status(uint16_t cid){ 385 return hfp_hf_send_cmd_with_mark(cid, HFP_INDICATOR, "?"); 386 } 387 388 static int hfp_hf_cmd_retrieve_can_hold_call(uint16_t cid){ 389 return hfp_hf_send_cmd_with_mark(cid, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, "=?"); 390 } 391 392 static int hfp_hf_cmd_retrieve_supported_generic_status_indicators(uint16_t cid){ 393 return hfp_hf_send_cmd_with_mark(cid, HFP_GENERIC_STATUS_INDICATOR, "=?"); 394 } 395 396 static int hfp_hf_cmd_list_initital_supported_generic_status_indicators(uint16_t cid){ 397 return hfp_hf_send_cmd_with_mark(cid, HFP_GENERIC_STATUS_INDICATOR, "?"); 398 } 399 400 static int hfp_hf_cmd_query_operator_name_format(uint16_t cid){ 401 return hfp_hf_send_cmd_with_mark(cid, HFP_QUERY_OPERATOR_SELECTION, "=3,0"); 402 } 403 404 static int hfp_hf_cmd_query_operator_name(uint16_t cid){ 405 return hfp_hf_send_cmd_with_mark(cid, HFP_QUERY_OPERATOR_SELECTION, "?"); 406 } 407 408 static int hfp_hf_cmd_trigger_codec_connection_setup(uint16_t cid){ 409 return hfp_hf_send_cmd(cid, HFP_TRIGGER_CODEC_CONNECTION_SETUP); 410 } 411 412 static int hfp_hf_set_microphone_gain_cmd(uint16_t cid, int gain){ 413 return hfp_hf_send_cmd_with_int(cid, HFP_SET_MICROPHONE_GAIN, gain); 414 } 415 416 static int hfp_hf_set_speaker_gain_cmd(uint16_t cid, int gain){ 417 return hfp_hf_send_cmd_with_int(cid, HFP_SET_SPEAKER_GAIN, gain); 418 } 419 420 static int hfp_hf_set_calling_line_notification_cmd(uint16_t cid, uint8_t activate){ 421 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CLIP, activate); 422 } 423 424 static int hfp_hf_set_voice_recognition_notification_cmd(uint16_t cid, uint8_t activate){ 425 return hfp_hf_send_cmd_with_int(cid, HFP_ACTIVATE_VOICE_RECOGNITION, activate); 426 } 427 428 static int hfp_hf_set_call_waiting_notification_cmd(uint16_t cid, uint8_t activate){ 429 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CALL_WAITING_NOTIFICATION, activate); 430 } 431 432 static int hfp_hf_cmd_confirm_codec(uint16_t cid, uint8_t codec){ 433 return hfp_hf_send_cmd_with_int(cid, HFP_CONFIRM_COMMON_CODEC, codec); 434 } 435 436 static int hfp_hf_cmd_enable_extended_audio_gateway_error_report(uint16_t cid, uint8_t enable){ 437 return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, enable); 438 } 439 440 static int hfp_hf_send_redial_last_number_cmd(uint16_t cid){ 441 return hfp_hf_send_cmd(cid, HFP_REDIAL_LAST_NUMBER); 442 } 443 444 static int hfp_hf_send_chup(uint16_t cid){ 445 return hfp_hf_send_cmd(cid, HFP_HANG_UP_CALL); 446 } 447 448 static int hfp_hf_send_binp(uint16_t cid){ 449 return hfp_hf_send_cmd_with_mark(cid, HFP_PHONE_NUMBER_FOR_VOICE_TAG, "=1"); 450 } 451 452 static int hfp_hf_send_clcc(uint16_t cid){ 453 return hfp_hf_send_cmd(cid, HFP_LIST_CURRENT_CALLS); 454 } 455 456 /* state machines */ 457 458 static bool hfp_hf_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){ 459 if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return false; 460 if (hfp_connection->ok_pending) return false; 461 462 log_info("hfp_hf_run_for_context_service_level_connection state %d\n", hfp_connection->state); 463 switch (hfp_connection->state){ 464 case HFP_EXCHANGE_SUPPORTED_FEATURES: 465 hfp_hf_drop_mSBC_if_eSCO_not_supported(hfp_hf_codecs, &hfp_hf_codecs_nr); 466 hfp_connection->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; 467 hfp_hf_cmd_exchange_supported_features(hfp_connection->rfcomm_cid); 468 break; 469 case HFP_NOTIFY_ON_CODECS: 470 hfp_connection->state = HFP_W4_NOTIFY_ON_CODECS; 471 hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid); 472 break; 473 case HFP_RETRIEVE_INDICATORS: 474 hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS; 475 hfp_hf_cmd_retrieve_indicators(hfp_connection->rfcomm_cid); 476 break; 477 case HFP_RETRIEVE_INDICATORS_STATUS: 478 hfp_connection->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; 479 hfp_hf_cmd_retrieve_indicators_status(hfp_connection->rfcomm_cid); 480 break; 481 case HFP_ENABLE_INDICATORS_STATUS_UPDATE: 482 hfp_connection->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; 483 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, 1); 484 break; 485 case HFP_RETRIEVE_CAN_HOLD_CALL: 486 hfp_connection->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; 487 hfp_hf_cmd_retrieve_can_hold_call(hfp_connection->rfcomm_cid); 488 break; 489 case HFP_LIST_GENERIC_STATUS_INDICATORS: 490 hfp_connection->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; 491 hfp_hf_cmd_list_supported_generic_status_indicators(hfp_connection->rfcomm_cid); 492 break; 493 case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS: 494 hfp_connection->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; 495 hfp_hf_cmd_retrieve_supported_generic_status_indicators(hfp_connection->rfcomm_cid); 496 break; 497 case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 498 hfp_connection->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 499 hfp_hf_cmd_list_initital_supported_generic_status_indicators(hfp_connection->rfcomm_cid); 500 break; 501 default: 502 return false; 503 } 504 return true; 505 } 506 507 508 static bool hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * hfp_connection){ 509 if (hfp_connection->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return false; 510 if (hfp_connection->ok_pending){ 511 return false; 512 } 513 514 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ 515 hfp_connection->ok_pending = 1; 516 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(hfp_connection->rfcomm_cid, hfp_connection->enable_status_update_for_ag_indicators); 517 return true; 518 }; 519 520 if (hfp_connection->change_status_update_for_individual_ag_indicators){ 521 hfp_connection->ok_pending = 1; 522 hfp_hf_cmd_activate_status_update_for_ag_indicator(hfp_connection->rfcomm_cid, 523 hfp_connection->ag_indicators_status_update_bitmap, 524 hfp_connection->ag_indicators_nr); 525 return true; 526 } 527 528 switch (hfp_connection->hf_query_operator_state){ 529 case HFP_HF_QUERY_OPERATOR_SET_FORMAT: 530 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK; 531 hfp_connection->ok_pending = 1; 532 hfp_hf_cmd_query_operator_name_format(hfp_connection->rfcomm_cid); 533 return true; 534 case HFP_HF_QUERY_OPERATOR_SEND_QUERY: 535 hfp_connection->hf_query_operator_state = HPF_HF_QUERY_OPERATOR_W4_RESULT; 536 hfp_connection->ok_pending = 1; 537 hfp_hf_cmd_query_operator_name(hfp_connection->rfcomm_cid); 538 return true; 539 default: 540 break; 541 } 542 543 if (hfp_connection->enable_extended_audio_gateway_error_report){ 544 hfp_connection->ok_pending = 1; 545 hfp_hf_cmd_enable_extended_audio_gateway_error_report(hfp_connection->rfcomm_cid, hfp_connection->enable_extended_audio_gateway_error_report); 546 return true; 547 } 548 549 return false; 550 } 551 552 static bool hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connection){ 553 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) { 554 return false; 555 } 556 557 if (hfp_connection->ok_pending == 1){ 558 return false; 559 } 560 // voice recognition activated from AG 561 if (hfp_connection->command == HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION){ 562 switch(hfp_connection->vra_state_requested){ 563 case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED: 564 case HFP_VRA_W4_VOICE_RECOGNITION_OFF: 565 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 566 // ignore AG command, continue to wait for OK 567 return false; 568 569 default: 570 if (hfp_connection->ag_vra_msg_length > 0){ 571 hfp_hf_emit_enhanced_voice_recognition_text(hfp_connection); 572 hfp_connection->ag_vra_msg_length = 0; 573 break; 574 } 575 switch(hfp_connection->ag_vra_state){ 576 case HFP_VOICE_RECOGNITION_STATE_AG_READY: 577 switch (hfp_connection->ag_vra_status){ 578 case 0: 579 hfp_connection->vra_state_requested = HFP_VRA_W4_VOICE_RECOGNITION_OFF; 580 break; 581 case 1: 582 hfp_connection->vra_state_requested = HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED; 583 break; 584 case 2: 585 hfp_connection->vra_state_requested = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO; 586 break; 587 default: 588 break; 589 } 590 break; 591 default: 592 // state messages from AG 593 hfp_emit_enhanced_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS); 594 hfp_connection->ag_vra_state = HFP_VOICE_RECOGNITION_STATE_AG_READY; 595 break; 596 } 597 break; 598 } 599 hfp_connection->command = HFP_CMD_NONE; 600 } 601 602 switch (hfp_connection->vra_state_requested){ 603 case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF: 604 hfp_connection->vra_state_requested = HFP_VRA_W4_VOICE_RECOGNITION_OFF; 605 hfp_connection->ok_pending = 1; 606 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 0); 607 return true; 608 609 case HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED: 610 hfp_connection->vra_state_requested = HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED; 611 hfp_connection->ok_pending = 1; 612 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 1); 613 return true; 614 615 case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 616 hfp_connection->vra_state_requested = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO; 617 hfp_connection->ok_pending = 1; 618 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 2); 619 return true; 620 621 case HFP_VRA_W4_VOICE_RECOGNITION_OFF: 622 hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF; 623 hfp_connection->vra_state_requested = hfp_connection->vra_state; 624 hfp_connection->activate_voice_recognition = false; 625 if (hfp_connection->activate_voice_recognition){ 626 hfp_connection->enhanced_voice_recognition_enabled = hfp_hf_enhanced_vra_flag_supported(hfp_connection); 627 hfp_hf_activate_voice_recognition(hfp_connection->acl_handle); 628 } else { 629 hfp_emit_voice_recognition_disabled(hfp_connection, ERROR_CODE_SUCCESS); 630 } 631 break; 632 633 case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED: 634 hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_ACTIVATED; 635 hfp_connection->vra_state_requested = hfp_connection->vra_state; 636 hfp_connection->activate_voice_recognition = false; 637 if (hfp_connection->deactivate_voice_recognition){ 638 hfp_hf_deactivate_voice_recognition(hfp_connection->acl_handle); 639 } else { 640 hfp_connection->enhanced_voice_recognition_enabled = hfp_hf_enhanced_vra_flag_supported(hfp_connection); 641 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED){ 642 hfp_emit_voice_recognition_enabled(hfp_connection, ERROR_CODE_SUCCESS); 643 } else { 644 // postpone VRA event to simplify application logic 645 hfp_connection->emit_vra_enabled_after_audio_established = true; 646 } 647 } 648 break; 649 650 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 651 hfp_connection->vra_state = HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO; 652 hfp_connection->vra_state_requested = hfp_connection->vra_state; 653 hfp_connection->activate_voice_recognition = false; 654 if (hfp_connection->deactivate_voice_recognition){ 655 hfp_hf_deactivate_voice_recognition(hfp_connection->acl_handle); 656 } else { 657 hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_SUCCESS); 658 } 659 break; 660 661 default: 662 break; 663 } 664 return false; 665 } 666 667 668 static bool codecs_exchange_state_machine(hfp_connection_t * hfp_connection){ 669 if (hfp_connection->ok_pending) return false; 670 671 if (hfp_connection->trigger_codec_exchange){ 672 hfp_connection->trigger_codec_exchange = false; 673 674 hfp_connection->ok_pending = 1; 675 hfp_hf_cmd_trigger_codec_connection_setup(hfp_connection->rfcomm_cid); 676 return true; 677 } 678 679 if (hfp_connection->hf_send_codec_confirm){ 680 hfp_connection->hf_send_codec_confirm = false; 681 682 hfp_connection->ok_pending = 1; 683 hfp_hf_cmd_confirm_codec(hfp_connection->rfcomm_cid, hfp_connection->codec_confirmed); 684 return true; 685 } 686 687 if (hfp_connection->hf_send_supported_codecs){ 688 hfp_connection->hf_send_supported_codecs = false; 689 690 hfp_connection->ok_pending = 1; 691 hfp_hf_cmd_notify_on_codecs(hfp_connection->rfcomm_cid); 692 return true; 693 } 694 695 return false; 696 } 697 698 static bool hfp_hf_run_for_audio_connection(hfp_connection_t * hfp_connection){ 699 if ((hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) || 700 (hfp_connection->state > HFP_W2_DISCONNECT_SCO)) return false; 701 702 if (hfp_connection->release_audio_connection){ 703 hfp_connection->state = HFP_W4_SCO_DISCONNECTED; 704 hfp_connection->release_audio_connection = 0; 705 gap_disconnect(hfp_connection->sco_handle); 706 return true; 707 } 708 709 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return false; 710 711 // run codecs exchange 712 bool done = codecs_exchange_state_machine(hfp_connection); 713 if (done) return true; 714 715 if (hfp_connection->codecs_state != HFP_CODECS_EXCHANGED) return false; 716 if (hfp_sco_setup_active()) return false; 717 if (hfp_connection->establish_audio_connection){ 718 hfp_connection->state = HFP_W4_SCO_CONNECTED; 719 hfp_connection->establish_audio_connection = 0; 720 hfp_setup_synchronous_connection(hfp_connection); 721 return true; 722 } 723 return false; 724 } 725 726 727 static bool call_setup_state_machine(hfp_connection_t * hfp_connection){ 728 729 if (hfp_connection->ok_pending) return false; 730 731 if (hfp_connection->hf_answer_incoming_call){ 732 hfp_connection->hf_answer_incoming_call = 0; 733 hfp_hf_cmd_ata(hfp_connection->rfcomm_cid); 734 return true; 735 } 736 return false; 737 } 738 739 static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){ 740 741 btstack_assert(hfp_connection != NULL); 742 btstack_assert(hfp_connection->local_role == HFP_ROLE_HF); 743 744 // during SDP query, RFCOMM CID is not set 745 if (hfp_connection->rfcomm_cid == 0) return; 746 747 // emit postponed VRA event 748 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED && hfp_connection->emit_vra_enabled_after_audio_established){ 749 hfp_connection->emit_vra_enabled_after_audio_established = false; 750 hfp_emit_voice_recognition_enabled(hfp_connection, ERROR_CODE_SUCCESS); 751 } 752 753 // assert command could be sent 754 if (hci_can_send_command_packet_now() == 0) return; 755 756 #ifdef ENABLE_CC256X_ASSISTED_HFP 757 // WBS Disassociate 758 if (hfp_connection->cc256x_send_wbs_disassociate){ 759 hfp_connection->cc256x_send_wbs_disassociate = false; 760 hci_send_cmd(&hci_ti_wbs_disassociate); 761 return; 762 } 763 // Write Codec Config 764 if (hfp_connection->cc256x_send_write_codec_config){ 765 hfp_connection->cc256x_send_write_codec_config = false; 766 hfp_cc256x_write_codec_config(hfp_connection); 767 return; 768 } 769 // WBS Associate 770 if (hfp_connection->cc256x_send_wbs_associate){ 771 hfp_connection->cc256x_send_wbs_associate = false; 772 hci_send_cmd(&hci_ti_wbs_associate, hfp_connection->acl_handle); 773 return; 774 } 775 #endif 776 #ifdef ENABLE_BCM_PCM_WBS 777 // Enable WBS 778 if (hfp_connection->bcm_send_enable_wbs){ 779 hfp_connection->bcm_send_enable_wbs = false; 780 hci_send_cmd(&hci_bcm_enable_wbs, 1, 2); 781 return; 782 } 783 // Write I2S/PCM params 784 if (hfp_connection->bcm_send_write_i2spcm_interface_param){ 785 hfp_connection->bcm_send_write_i2spcm_interface_param = false; 786 hfp_bcm_write_i2spcm_interface_param(hfp_connection); 787 return; 788 } 789 // Disable WBS 790 if (hfp_connection->bcm_send_disable_wbs){ 791 hfp_connection->bcm_send_disable_wbs = false; 792 hci_send_cmd(&hci_bcm_enable_wbs, 0, 2); 793 return; 794 } 795 #endif 796 #ifdef ENABLE_RTK_PCM_WBS 797 if (hfp_connection->rtk_send_sco_config){ 798 hfp_connection->rtk_send_sco_config = false; 799 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 800 log_info("RTK SCO: 16k + mSBC"); 801 hci_send_cmd(&hci_rtk_configure_sco_routing, 0x81, 0x90, 0x00, 0x00, 0x1a, 0x0c, 0x00, 0x00, 0x41); 802 } else { 803 log_info("RTK SCO: 16k + CVSD"); 804 hci_send_cmd(&hci_rtk_configure_sco_routing, 0x81, 0x90, 0x00, 0x00, 0x1a, 0x0c, 0x0c, 0x00, 0x01); 805 } 806 return; 807 } 808 #endif 809 #ifdef ENABLE_NXP_PCM_WBS 810 if (hfp_connection->nxp_start_audio_handle != HCI_CON_HANDLE_INVALID){ 811 hci_con_handle_t sco_handle = hfp_connection->nxp_start_audio_handle; 812 hfp_connection->nxp_start_audio_handle = HCI_CON_HANDLE_INVALID; 813 hci_send_cmd(&hci_nxp_host_pcm_i2s_audio_config, 0, 0, sco_handle, 0); 814 return; 815 } 816 if (hfp_connection->nxp_stop_audio_handle != HCI_CON_HANDLE_INVALID){ 817 hci_con_handle_t sco_handle = hfp_connection->nxp_stop_audio_handle; 818 hfp_connection->nxp_stop_audio_handle = HCI_CON_HANDLE_INVALID; 819 hci_send_cmd(&hci_nxp_host_pcm_i2s_audio_config, 1, 0, sco_handle, 0); 820 return; 821 } 822 #endif 823 #if defined (ENABLE_CC256X_ASSISTED_HFP) || defined (ENABLE_BCM_PCM_WBS) 824 if (hfp_connection->state == HFP_W4_WBS_SHUTDOWN){ 825 hfp_finalize_connection_context(hfp_connection); 826 return; 827 } 828 #endif 829 830 if (hfp_connection->accept_sco && (hfp_sco_setup_active() == false)){ 831 bool incoming_eSCO = hfp_connection->accept_sco == 2; 832 // notify about codec selection if not done already 833 if (hfp_connection->negotiated_codec == 0){ 834 hfp_connection->negotiated_codec = HFP_CODEC_CVSD; 835 } 836 hfp_accept_synchronous_connection(hfp_connection, incoming_eSCO); 837 return; 838 } 839 840 if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) { 841 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid); 842 return; 843 } 844 845 // we can send at least an RFCOMM packet or a HCI Command now 846 847 bool done = hfp_hf_run_for_context_service_level_connection(hfp_connection); 848 if (!done){ 849 done = hfp_hf_run_for_context_service_level_connection_queries(hfp_connection); 850 } 851 if (!done){ 852 done = hfp_hf_run_for_audio_connection(hfp_connection); 853 } 854 if (!done){ 855 done = hfp_hf_voice_recognition_state_machine(hfp_connection); 856 } 857 if (!done){ 858 done = call_setup_state_machine(hfp_connection); 859 } 860 861 // don't send a new command while ok still pending or SLC is not established 862 if (hfp_connection->ok_pending || (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED)){ 863 return; 864 } 865 866 if (hfp_connection->send_microphone_gain){ 867 hfp_connection->send_microphone_gain = 0; 868 hfp_connection->ok_pending = 1; 869 hfp_hf_set_microphone_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->microphone_gain); 870 return; 871 } 872 873 if (hfp_connection->send_speaker_gain){ 874 hfp_connection->send_speaker_gain = 0; 875 hfp_connection->ok_pending = 1; 876 hfp_hf_set_speaker_gain_cmd(hfp_connection->rfcomm_cid, hfp_connection->speaker_gain); 877 return; 878 } 879 880 if (hfp_connection->hf_deactivate_calling_line_notification){ 881 hfp_connection->hf_deactivate_calling_line_notification = 0; 882 hfp_connection->ok_pending = 1; 883 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 0); 884 return; 885 } 886 887 if (hfp_connection->hf_activate_calling_line_notification){ 888 hfp_connection->hf_activate_calling_line_notification = 0; 889 hfp_connection->ok_pending = 1; 890 hfp_hf_set_calling_line_notification_cmd(hfp_connection->rfcomm_cid, 1); 891 return; 892 } 893 894 if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){ 895 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0; 896 hfp_connection->response_pending_for_command = HFP_CMD_TURN_OFF_EC_AND_NR; 897 hfp_connection->ok_pending = 1; 898 hfp_hf_send_cmd_with_int(hfp_connection->rfcomm_cid, HFP_TURN_OFF_EC_AND_NR, 0); 899 return; 900 } 901 902 if (hfp_connection->hf_deactivate_call_waiting_notification){ 903 hfp_connection->hf_deactivate_call_waiting_notification = 0; 904 hfp_connection->ok_pending = 1; 905 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 0); 906 return; 907 } 908 909 if (hfp_connection->hf_activate_call_waiting_notification){ 910 hfp_connection->hf_activate_call_waiting_notification = 0; 911 hfp_connection->ok_pending = 1; 912 hfp_hf_set_call_waiting_notification_cmd(hfp_connection->rfcomm_cid, 1); 913 return; 914 } 915 916 if (hfp_connection->hf_initiate_outgoing_call){ 917 hfp_connection->hf_initiate_outgoing_call = 0; 918 hfp_connection->ok_pending = 1; 919 hfp_hf_initiate_outgoing_call_cmd(hfp_connection->rfcomm_cid); 920 return; 921 } 922 923 if (hfp_connection->hf_initiate_memory_dialing){ 924 hfp_connection->hf_initiate_memory_dialing = 0; 925 hfp_connection->ok_pending = 1; 926 hfp_hf_send_memory_dial_cmd(hfp_connection->rfcomm_cid, hfp_connection->memory_id); 927 return; 928 } 929 930 if (hfp_connection->hf_initiate_redial_last_number){ 931 hfp_connection->hf_initiate_redial_last_number = 0; 932 hfp_connection->ok_pending = 1; 933 hfp_hf_send_redial_last_number_cmd(hfp_connection->rfcomm_cid); 934 return; 935 } 936 937 if (hfp_connection->hf_send_chup){ 938 hfp_connection->hf_send_chup = 0; 939 hfp_connection->ok_pending = 1; 940 hfp_hf_send_chup(hfp_connection->rfcomm_cid); 941 return; 942 } 943 944 if (hfp_connection->hf_send_chld_0){ 945 hfp_connection->hf_send_chld_0 = 0; 946 hfp_connection->ok_pending = 1; 947 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 0); 948 return; 949 } 950 951 if (hfp_connection->hf_send_chld_1){ 952 hfp_connection->hf_send_chld_1 = 0; 953 hfp_connection->ok_pending = 1; 954 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 1); 955 return; 956 } 957 958 if (hfp_connection->hf_send_chld_2){ 959 hfp_connection->hf_send_chld_2 = 0; 960 hfp_connection->ok_pending = 1; 961 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 2); 962 return; 963 } 964 965 if (hfp_connection->hf_send_chld_3){ 966 hfp_connection->hf_send_chld_3 = 0; 967 hfp_connection->ok_pending = 1; 968 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 3); 969 return; 970 } 971 972 if (hfp_connection->hf_send_chld_4){ 973 hfp_connection->hf_send_chld_4 = 0; 974 hfp_connection->ok_pending = 1; 975 hfp_hf_send_chld(hfp_connection->rfcomm_cid, 4); 976 return; 977 } 978 979 if (hfp_connection->hf_send_chld_x){ 980 hfp_connection->hf_send_chld_x = 0; 981 hfp_connection->ok_pending = 1; 982 hfp_hf_send_chld(hfp_connection->rfcomm_cid, hfp_connection->hf_send_chld_x_index); 983 return; 984 } 985 986 if (hfp_connection->hf_send_dtmf_code){ 987 char code = hfp_connection->hf_send_dtmf_code; 988 hfp_connection->hf_send_dtmf_code = 0; 989 hfp_connection->ok_pending = 1; 990 hfp_hf_send_dtmf(hfp_connection->rfcomm_cid, code); 991 // notify client that dtmf was sent 992 char buffer[2]; 993 buffer[0] = code; 994 buffer[1] = 0; 995 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, buffer); 996 return; 997 } 998 999 if (hfp_connection->hf_send_binp){ 1000 hfp_connection->hf_send_binp = 0; 1001 hfp_connection->ok_pending = 1; 1002 hfp_hf_send_binp(hfp_connection->rfcomm_cid); 1003 return; 1004 } 1005 1006 if (hfp_connection->hf_send_clcc){ 1007 hfp_connection->hf_send_clcc = 0; 1008 hfp_connection->ok_pending = 1; 1009 hfp_hf_send_clcc(hfp_connection->rfcomm_cid); 1010 return; 1011 } 1012 1013 if (hfp_connection->hf_send_rrh){ 1014 hfp_connection->hf_send_rrh = 0; 1015 char buffer[20]; 1016 switch (hfp_connection->hf_send_rrh_command){ 1017 case '?': 1018 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s?\r", 1019 HFP_RESPONSE_AND_HOLD); 1020 buffer[sizeof(buffer) - 1] = 0; 1021 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1022 return; 1023 case '0': 1024 case '1': 1025 case '2': 1026 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%c\r", 1027 HFP_RESPONSE_AND_HOLD, 1028 hfp_connection->hf_send_rrh_command); 1029 buffer[sizeof(buffer) - 1] = 0; 1030 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1031 return; 1032 default: 1033 break; 1034 } 1035 return; 1036 } 1037 1038 if (hfp_connection->hf_send_cnum){ 1039 hfp_connection->hf_send_cnum = 0; 1040 char buffer[20]; 1041 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s\r", 1042 HFP_SUBSCRIBER_NUMBER_INFORMATION); 1043 buffer[sizeof(buffer) - 1] = 0; 1044 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1045 return; 1046 } 1047 1048 // update HF indicators 1049 if (hfp_connection->generic_status_update_bitmap){ 1050 int i; 1051 for (i=0; i < hfp_hf_indicators_nr; i++){ 1052 if (get_bit(hfp_connection->generic_status_update_bitmap, i)){ 1053 hfp_connection->generic_status_update_bitmap = store_bit(hfp_connection->generic_status_update_bitmap, i, 0); 1054 if (hfp_connection->generic_status_indicators[i].state){ 1055 hfp_connection->ok_pending = 1; 1056 char buffer[30]; 1057 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%u,%u\r", 1058 HFP_TRANSFER_HF_INDICATOR_STATUS, 1059 hfp_hf_indicators[i], 1060 (unsigned int)hfp_hf_indicators_value[i]); 1061 buffer[sizeof(buffer) - 1] = 0; 1062 send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1063 } else { 1064 log_info("Not sending HF indicator %u as it is disabled", hfp_hf_indicators[i]); 1065 } 1066 return; 1067 } 1068 } 1069 } 1070 1071 if (hfp_connection->send_apple_information){ 1072 hfp_connection->send_apple_information = false; 1073 hfp_connection->ok_pending = 1; 1074 hfp_connection->response_pending_for_command = HFP_CMD_APPLE_ACCESSORY_INFORMATION; 1075 char buffer[40]; 1076 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=%04x-%04x-%s,%u\r", HFP_APPLE_ACCESSORY_INFORMATION, 1077 hfp_hf_apple_vendor_id, hfp_hf_apple_product_id, hfp_hf_apple_version, hfp_hf_apple_features); 1078 (void) send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1079 return; 1080 } 1081 1082 if (hfp_connection->apple_accessory_commands_supported){ 1083 uint8_t num_apple_values = 0; 1084 uint8_t first_key = 0; 1085 uint8_t first_value = 0; 1086 if (hfp_connection->apple_accessory_battery_level >= 0){ 1087 num_apple_values++; 1088 first_key = 1; 1089 first_value = hfp_connection->apple_accessory_battery_level; 1090 } 1091 if (hfp_connection->apple_accessory_docked >= 0){ 1092 num_apple_values++; 1093 first_key = 2; 1094 first_value = hfp_connection->apple_accessory_docked; 1095 } 1096 if (num_apple_values > 0){ 1097 char buffer[40]; 1098 switch (num_apple_values){ 1099 case 1: 1100 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=1,%u,%u\r", HFP_APPLE_ACCESSORY_STATE, 1101 first_key, first_value); 1102 break; 1103 case 2: 1104 btstack_snprintf_assert_complete(buffer, sizeof(buffer), "AT%s=2,1,%u,2,%u\r", HFP_APPLE_ACCESSORY_STATE, 1105 hfp_connection->apple_accessory_battery_level, hfp_connection->apple_accessory_docked); 1106 break; 1107 default: 1108 btstack_unreachable(); 1109 break; 1110 } 1111 // clear 1112 hfp_connection->apple_accessory_battery_level = -1; 1113 hfp_connection->apple_accessory_docked = -1; 1114 // construct 1115 hfp_connection->ok_pending = 1; 1116 hfp_connection->response_pending_for_command = HFP_CMD_APPLE_ACCESSORY_STATE; 1117 (void) send_str_over_rfcomm(hfp_connection->rfcomm_cid, buffer); 1118 return; 1119 } 1120 } 1121 1122 if (hfp_connection->send_custom_message != NULL){ 1123 const char * message = hfp_connection->send_custom_message; 1124 hfp_connection->send_custom_message = NULL; 1125 hfp_connection->ok_pending = 1; 1126 hfp_connection->response_pending_for_command = HFP_CMD_CUSTOM_MESSAGE; 1127 send_str_over_rfcomm(hfp_connection->rfcomm_cid, message); 1128 return; 1129 } 1130 1131 if (done) return; 1132 // deal with disconnect 1133 switch (hfp_connection->state){ 1134 case HFP_W2_DISCONNECT_RFCOMM: 1135 hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED; 1136 rfcomm_disconnect(hfp_connection->rfcomm_cid); 1137 break; 1138 1139 default: 1140 break; 1141 } 1142 } 1143 1144 1145 static void hfp_hf_apple_trigger_send(void){ 1146 btstack_linked_list_iterator_t it; 1147 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 1148 while (btstack_linked_list_iterator_has_next(&it)){ 1149 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 1150 if (hfp_connection->local_role == HFP_ROLE_HF) { 1151 hfp_connection->apple_accessory_battery_level = hfp_hf_apple_battery_level; 1152 hfp_connection->apple_accessory_docked = hfp_hf_apple_docked; 1153 } 1154 } 1155 } 1156 1157 static void hfp_hf_slc_established(hfp_connection_t * hfp_connection){ 1158 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1159 1160 hfp_emit_slc_connection_event(hfp_connection->local_role, 0, hfp_connection->acl_handle, hfp_connection->remote_addr); 1161 1162 uint8_t i; 1163 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1164 hfp_emit_ag_indicator_mapping_event(hfp_connection, &hfp_connection->ag_indicators[i]); 1165 } 1166 1167 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1168 hfp_connection->ag_indicators[i].status_changed = 0; 1169 hfp_emit_ag_indicator_status_event(hfp_connection, &hfp_connection->ag_indicators[i]); 1170 } 1171 1172 hfp_connection->apple_accessory_commands_supported = false; 1173 hfp_connection->send_apple_information = hfp_hf_apple_vendor_id != 0; 1174 1175 // restore volume settings 1176 hfp_connection->speaker_gain = hfp_hf_speaker_gain; 1177 hfp_connection->send_speaker_gain = 1; 1178 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain); 1179 hfp_connection->microphone_gain = hfp_hf_microphone_gain; 1180 hfp_connection->send_microphone_gain = 1; 1181 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain); 1182 } 1183 1184 static void hfp_hf_handle_suggested_codec(hfp_connection_t * hfp_connection){ 1185 if (hfp_supports_codec(hfp_connection->suggested_codec, hfp_hf_codecs_nr, hfp_hf_codecs)){ 1186 // Codec supported, confirm 1187 hfp_connection->negotiated_codec = hfp_connection->suggested_codec; 1188 hfp_connection->codec_confirmed = hfp_connection->suggested_codec; 1189 log_info("hfp: codec confirmed: %s", (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? "mSBC" : "CVSD"); 1190 hfp_connection->codecs_state = HFP_CODECS_HF_CONFIRMED_CODEC; 1191 1192 hfp_connection->hf_send_codec_confirm = true; 1193 } else { 1194 // Codec not supported, send supported codecs 1195 hfp_connection->codec_confirmed = 0; 1196 hfp_connection->suggested_codec = 0; 1197 hfp_connection->negotiated_codec = 0; 1198 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; 1199 1200 hfp_connection->hf_send_supported_codecs = true; 1201 } 1202 } 1203 static void hfp_hf_apple_extension_supported(hfp_connection_t * hfp_connection, bool supported){ 1204 hfp_connection->apple_accessory_commands_supported = supported; 1205 log_info("Apple Extension supported: %u", supported); 1206 hfp_emit_event(hfp_connection, HFP_SUBEVENT_APPLE_EXTENSION_SUPPORTED, hfp_hf_microphone_gain); 1207 } 1208 1209 static bool hfp_hf_switch_on_ok_pending(hfp_connection_t *hfp_connection, uint8_t status){ 1210 bool event_emited = true; 1211 1212 // cache state and reset 1213 hfp_command_t response_pending_for_command = hfp_connection->response_pending_for_command; 1214 hfp_connection->response_pending_for_command = HFP_CMD_NONE; 1215 hfp_connection->command = HFP_CMD_NONE; 1216 hfp_connection->ok_pending = 0; 1217 1218 switch (response_pending_for_command){ 1219 case HFP_CMD_TURN_OFF_EC_AND_NR: 1220 hfp_emit_event(hfp_connection, HFP_SUBEVENT_ECHO_CANCELING_AND_NOISE_REDUCTION_DEACTIVATE, status); 1221 break; 1222 case HFP_CMD_CUSTOM_MESSAGE: 1223 hfp_emit_event(hfp_connection, HFP_SUBEVENT_CUSTOM_AT_MESSAGE_SENT, status); 1224 break; 1225 case HFP_CMD_APPLE_ACCESSORY_INFORMATION: 1226 hfp_hf_apple_extension_supported(hfp_connection, true); 1227 break; 1228 default: 1229 event_emited = false; 1230 1231 switch (hfp_connection->state){ 1232 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: 1233 if (has_codec_negotiation_feature(hfp_connection)){ 1234 hfp_connection->state = HFP_NOTIFY_ON_CODECS; 1235 break; 1236 } 1237 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1238 break; 1239 1240 case HFP_W4_NOTIFY_ON_CODECS: 1241 hfp_connection->state = HFP_RETRIEVE_INDICATORS; 1242 break; 1243 1244 case HFP_W4_RETRIEVE_INDICATORS: 1245 hfp_connection->state = HFP_RETRIEVE_INDICATORS_STATUS; 1246 break; 1247 1248 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1249 hfp_connection->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; 1250 break; 1251 1252 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: 1253 if (has_call_waiting_and_3way_calling_feature(hfp_connection)){ 1254 hfp_connection->state = HFP_RETRIEVE_CAN_HOLD_CALL; 1255 break; 1256 } 1257 if (has_hf_indicators_feature(hfp_connection)){ 1258 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1259 break; 1260 } 1261 hfp_hf_slc_established(hfp_connection); 1262 break; 1263 1264 case HFP_W4_RETRIEVE_CAN_HOLD_CALL: 1265 if (has_hf_indicators_feature(hfp_connection)){ 1266 hfp_connection->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 1267 break; 1268 } 1269 hfp_hf_slc_established(hfp_connection); 1270 break; 1271 1272 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 1273 hfp_connection->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; 1274 break; 1275 1276 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 1277 hfp_connection->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 1278 break; 1279 1280 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 1281 hfp_hf_slc_established(hfp_connection); 1282 break; 1283 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 1284 if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){ 1285 hfp_connection->enable_status_update_for_ag_indicators = 0xFF; 1286 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, ERROR_CODE_SUCCESS); 1287 break; 1288 } 1289 1290 if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){ 1291 hfp_connection->change_status_update_for_individual_ag_indicators = 0; 1292 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, ERROR_CODE_SUCCESS); 1293 break; 1294 } 1295 1296 switch (hfp_connection->hf_query_operator_state){ 1297 case HFP_HF_QUERY_OPERATOR_W4_SET_FORMAT_OK: 1298 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; 1299 break; 1300 case HPF_HF_QUERY_OPERATOR_W4_RESULT: 1301 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET; 1302 hfp_emit_network_operator_event(hfp_connection); 1303 break; 1304 default: 1305 break; 1306 } 1307 1308 if (hfp_connection->enable_extended_audio_gateway_error_report){ 1309 hfp_connection->enable_extended_audio_gateway_error_report = 0; 1310 break; 1311 } 1312 1313 switch (hfp_connection->codecs_state){ 1314 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: 1315 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC; 1316 break; 1317 case HFP_CODECS_HF_CONFIRMED_CODEC: 1318 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; 1319 break; 1320 default: 1321 break; 1322 } 1323 hfp_hf_voice_recognition_state_machine(hfp_connection); 1324 break; 1325 case HFP_AUDIO_CONNECTION_ESTABLISHED: 1326 hfp_hf_voice_recognition_state_machine(hfp_connection); 1327 break; 1328 default: 1329 break; 1330 } 1331 break; 1332 } 1333 1334 return event_emited; 1335 } 1336 1337 static bool hfp_is_ringing(hfp_callsetup_status_t callsetup_status){ 1338 switch (callsetup_status){ 1339 case HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS: 1340 case HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE: 1341 return true; 1342 default: 1343 return false; 1344 } 1345 } 1346 1347 static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_connection) { 1348 uint16_t i; 1349 1350 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1351 if (hfp_connection->ag_indicators[i].status_changed) { 1352 if (strcmp(hfp_connection->ag_indicators[i].name, "callsetup") == 0){ 1353 hfp_callsetup_status_t new_hf_callsetup_status = (hfp_callsetup_status_t) hfp_connection->ag_indicators[i].status; 1354 bool ringing_old = hfp_is_ringing(hfp_connection->hf_callsetup_status); 1355 bool ringing_new = hfp_is_ringing(new_hf_callsetup_status); 1356 if (ringing_old != ringing_new){ 1357 if (ringing_new){ 1358 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_START_RINGING); 1359 } else { 1360 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_STOP_RINGING); 1361 } 1362 } 1363 hfp_connection->hf_callsetup_status = new_hf_callsetup_status; 1364 } else if (strcmp(hfp_connection->ag_indicators[i].name, "callheld") == 0){ 1365 hfp_connection->hf_callheld_status = (hfp_callheld_status_t) hfp_connection->ag_indicators[i].status; 1366 // avoid set but not used warning 1367 (void) hfp_connection->hf_callheld_status; 1368 } else if (strcmp(hfp_connection->ag_indicators[i].name, "call") == 0){ 1369 hfp_call_status_t new_hf_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status; 1370 if (hfp_connection->hf_call_status != new_hf_call_status){ 1371 if (new_hf_call_status == HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS){ 1372 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_CALL_TERMINATED); 1373 } else { 1374 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_CALL_ANSWERED); 1375 } 1376 } 1377 hfp_connection->hf_call_status = new_hf_call_status; 1378 } 1379 hfp_connection->ag_indicators[i].status_changed = 0; 1380 hfp_emit_ag_indicator_status_event(hfp_connection, &hfp_connection->ag_indicators[i]); 1381 break; 1382 } 1383 } 1384 } 1385 1386 static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ 1387 int value; 1388 int i; 1389 bool event_emited; 1390 1391 // last argument is still in line_buffer 1392 1393 switch (hfp_connection->command){ 1394 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1395 hfp_connection->command = HFP_CMD_NONE; 1396 hfp_hf_emit_subscriber_information(hfp_connection, 0); 1397 break; 1398 case HFP_CMD_RESPONSE_AND_HOLD_STATUS: 1399 hfp_connection->command = HFP_CMD_NONE; 1400 hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0])); 1401 break; 1402 case HFP_CMD_LIST_CURRENT_CALLS: 1403 hfp_connection->command = HFP_CMD_NONE; 1404 hfp_hf_emit_enhanced_call_status(hfp_connection); 1405 break; 1406 case HFP_CMD_SET_SPEAKER_GAIN: 1407 hfp_connection->command = HFP_CMD_NONE; 1408 value = btstack_atoi((char*)hfp_connection->line_buffer); 1409 hfp_hf_speaker_gain = value; 1410 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value); 1411 break; 1412 case HFP_CMD_SET_MICROPHONE_GAIN: 1413 hfp_connection->command = HFP_CMD_NONE; 1414 value = btstack_atoi((char*)hfp_connection->line_buffer); 1415 hfp_hf_microphone_gain = value; 1416 hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value); 1417 break; 1418 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1419 hfp_connection->command = HFP_CMD_NONE; 1420 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number); 1421 break; 1422 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1423 hfp_connection->command = HFP_CMD_NONE; 1424 hfp_hf_emit_type_number_alpha(hfp_connection, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION); 1425 break; 1426 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1427 hfp_connection->command = HFP_CMD_NONE; 1428 hfp_hf_emit_type_number_alpha(hfp_connection, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION); 1429 break; 1430 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1431 hfp_connection->command = HFP_CMD_NONE; 1432 hfp_connection->ok_pending = 0; 1433 hfp_connection->extended_audio_gateway_error = 0; 1434 hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value); 1435 break; 1436 case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION: 1437 break; 1438 case HFP_CMD_ERROR: 1439 switch (hfp_connection->state){ 1440 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 1441 switch (hfp_connection->codecs_state){ 1442 case HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE: 1443 hfp_reset_context_flags(hfp_connection); 1444 hfp_emit_sco_connection_established(hfp_connection, HFP_REMOTE_REJECTS_AUDIO_CONNECTION, 1445 hfp_connection->negotiated_codec, 0, 0); 1446 return; 1447 default: 1448 break; 1449 } 1450 break; 1451 default: 1452 break; 1453 } 1454 1455 switch (hfp_connection->response_pending_for_command){ 1456 case HFP_CMD_APPLE_ACCESSORY_INFORMATION: 1457 hfp_connection->response_pending_for_command = HFP_CMD_NONE; 1458 hfp_hf_apple_extension_supported(hfp_connection, false); 1459 return; 1460 default: 1461 break; 1462 } 1463 1464 // handle error response for voice activation (HF initiated) 1465 switch(hfp_connection->vra_state_requested){ 1466 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 1467 hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1468 break; 1469 default: 1470 if (hfp_connection->vra_state_requested == hfp_connection->vra_state){ 1471 break; 1472 } 1473 hfp_connection->vra_state_requested = hfp_connection->vra_state; 1474 hfp_emit_voice_recognition_enabled(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1475 hfp_reset_context_flags(hfp_connection); 1476 return; 1477 } 1478 event_emited = hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); 1479 if (!event_emited){ 1480 hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, ERROR_CODE_UNSPECIFIED_ERROR); 1481 } 1482 hfp_reset_context_flags(hfp_connection); 1483 break; 1484 1485 case HFP_CMD_OK: 1486 hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_SUCCESS); 1487 break; 1488 case HFP_CMD_RING: 1489 hfp_connection->command = HFP_CMD_NONE; 1490 hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING); 1491 break; 1492 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1493 hfp_connection->command = HFP_CMD_NONE; 1494 hfp_hf_handle_transfer_ag_indicator_status(hfp_connection); 1495 break; 1496 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1497 hfp_connection->command = HFP_CMD_NONE; 1498 // report status after SLC established 1499 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){ 1500 break; 1501 } 1502 for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ 1503 hfp_emit_ag_indicator_mapping_event(hfp_connection, &hfp_connection->ag_indicators[i]); 1504 } 1505 break; 1506 case HFP_CMD_AG_SUGGESTED_CODEC: 1507 hfp_connection->command = HFP_CMD_NONE; 1508 hfp_hf_handle_suggested_codec(hfp_connection); 1509 break; 1510 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1511 hfp_emit_event(hfp_connection, HFP_SUBEVENT_IN_BAND_RING_TONE, get_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE)); 1512 break; 1513 case HFP_CMD_CUSTOM_MESSAGE: 1514 hfp_connection->command = HFP_CMD_NONE; 1515 hfp_parser_reset_line_buffer(hfp_connection); 1516 log_info("Custom AT Command ID 0x%04x", hfp_connection->custom_at_command_id); 1517 hfp_hf_emit_custom_command_event(hfp_connection); 1518 break; 1519 default: 1520 break; 1521 } 1522 } 1523 1524 static int hfp_parser_is_end_of_line(uint8_t byte){ 1525 return (byte == '\n') || (byte == '\r'); 1526 } 1527 1528 static void hfp_hf_handle_rfcomm_data(hfp_connection_t * hfp_connection, uint8_t *packet, uint16_t size){ 1529 // assertion: size >= 1 as rfcomm.c does not deliver empty packets 1530 if (size < 1) return; 1531 1532 hfp_log_rfcomm_message("HFP_HF_RX", packet, size); 1533 #ifdef ENABLE_HFP_AT_MESSAGES 1534 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_AT_MESSAGE_RECEIVED, (char *) packet); 1535 #endif 1536 1537 // process messages byte-wise 1538 uint8_t pos; 1539 for (pos = 0; pos < size; pos++){ 1540 hfp_parse(hfp_connection, packet[pos], 1); 1541 // parse until end of line "\r" or "\n" 1542 if (!hfp_parser_is_end_of_line(packet[pos])) continue; 1543 hfp_hf_handle_rfcomm_command(hfp_connection); 1544 } 1545 } 1546 1547 static void hfp_hf_run(void){ 1548 btstack_linked_list_iterator_t it; 1549 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 1550 while (btstack_linked_list_iterator_has_next(&it)){ 1551 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 1552 if (hfp_connection->local_role != HFP_ROLE_HF) continue; 1553 hfp_hf_run_for_context(hfp_connection); 1554 } 1555 } 1556 1557 static void hfp_hf_rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1558 hfp_connection_t * hfp_connection; 1559 switch (packet_type){ 1560 case RFCOMM_DATA_PACKET: 1561 hfp_connection = get_hfp_connection_context_for_rfcomm_cid(channel); 1562 if (!hfp_connection) return; 1563 hfp_hf_handle_rfcomm_data(hfp_connection, packet, size); 1564 hfp_hf_run_for_context(hfp_connection); 1565 return; 1566 case HCI_EVENT_PACKET: 1567 if (packet[0] == RFCOMM_EVENT_CAN_SEND_NOW){ 1568 uint16_t rfcomm_cid = rfcomm_event_can_send_now_get_rfcomm_cid(packet); 1569 hfp_hf_run_for_context(get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid)); 1570 return; 1571 } 1572 hfp_handle_rfcomm_event(packet_type, channel, packet, size, HFP_ROLE_HF); 1573 break; 1574 default: 1575 break; 1576 } 1577 hfp_hf_run(); 1578 } 1579 1580 static void hfp_hf_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1581 hfp_handle_hci_event(packet_type, channel, packet, size, HFP_ROLE_HF); 1582 hfp_hf_run(); 1583 } 1584 1585 static void hfp_hf_set_defaults(void){ 1586 hfp_hf_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES; 1587 hfp_hf_codecs_nr = 0; 1588 hfp_hf_speaker_gain = 9; 1589 hfp_hf_microphone_gain = 9; 1590 hfp_hf_indicators_nr = 0; 1591 // Apple extension 1592 hfp_hf_apple_docked = -1; 1593 hfp_hf_apple_battery_level = -1; 1594 } 1595 1596 uint8_t hfp_hf_set_default_microphone_gain(uint8_t gain){ 1597 if (gain > 15){ 1598 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 1599 } 1600 hfp_hf_microphone_gain = gain; 1601 return ERROR_CODE_SUCCESS; 1602 } 1603 1604 uint8_t hfp_hf_set_default_speaker_gain(uint8_t gain){ 1605 if (gain > 15){ 1606 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 1607 } 1608 hfp_hf_speaker_gain = gain; 1609 return ERROR_CODE_SUCCESS; 1610 } 1611 1612 uint8_t hfp_hf_init(uint8_t rfcomm_channel_nr){ 1613 uint8_t status = rfcomm_register_service(hfp_hf_rfcomm_packet_handler, rfcomm_channel_nr, 0xffff); 1614 if (status != ERROR_CODE_SUCCESS){ 1615 return status; 1616 } 1617 1618 hfp_init(); 1619 hfp_hf_set_defaults(); 1620 1621 hfp_hf_hci_event_callback_registration.callback = &hfp_hf_hci_event_packet_handler; 1622 hci_add_event_handler(&hfp_hf_hci_event_callback_registration); 1623 1624 // used to set packet handler for outgoing rfcomm connections - could be handled by emitting an event to us 1625 hfp_set_hf_rfcomm_packet_handler(&hfp_hf_rfcomm_packet_handler); 1626 return ERROR_CODE_SUCCESS; 1627 } 1628 1629 void hfp_hf_deinit(void){ 1630 hfp_deinit(); 1631 hfp_hf_set_defaults(); 1632 1633 hfp_hf_callback = NULL; 1634 hfp_hf_apple_vendor_id = 0; 1635 (void) memset(&hfp_hf_hci_event_callback_registration, 0, sizeof(btstack_packet_callback_registration_t)); 1636 (void) memset(hfp_hf_phone_number, 0, sizeof(hfp_hf_phone_number)); 1637 } 1638 1639 void hfp_hf_init_codecs(uint8_t codecs_nr, const uint8_t * codecs){ 1640 btstack_assert(codecs_nr <= HFP_MAX_NUM_CODECS); 1641 if (codecs_nr > HFP_MAX_NUM_CODECS) return; 1642 1643 hfp_hf_codecs_nr = codecs_nr; 1644 uint8_t i; 1645 for (i=0; i<codecs_nr; i++){ 1646 hfp_hf_codecs[i] = codecs[i]; 1647 } 1648 } 1649 1650 void hfp_hf_init_supported_features(uint32_t supported_features){ 1651 hfp_hf_supported_features = supported_features; 1652 } 1653 1654 void hfp_hf_init_hf_indicators(int indicators_nr, const uint16_t * indicators){ 1655 btstack_assert(hfp_hf_indicators_nr < HFP_MAX_NUM_INDICATORS); 1656 if (hfp_hf_indicators_nr > HFP_MAX_NUM_INDICATORS) return; 1657 1658 hfp_hf_indicators_nr = indicators_nr; 1659 int i; 1660 for (i = 0; i < hfp_hf_indicators_nr ; i++){ 1661 hfp_hf_indicators[i] = (uint8_t) indicators[i]; 1662 } 1663 1664 // store copy in hfp to setup generic_status_indicators during SLC 1665 hfp_set_hf_indicators(indicators_nr, hfp_hf_indicators); 1666 } 1667 1668 uint8_t hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){ 1669 return hfp_establish_service_level_connection(bd_addr, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, HFP_ROLE_HF); 1670 } 1671 1672 uint8_t hfp_hf_release_service_level_connection(hci_con_handle_t acl_handle){ 1673 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1674 if (!hfp_connection){ 1675 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1676 } 1677 hfp_trigger_release_service_level_connection(hfp_connection); 1678 hfp_hf_run_for_context(hfp_connection); 1679 return ERROR_CODE_SUCCESS; 1680 } 1681 1682 static uint8_t hfp_hf_set_status_update_for_all_ag_indicators(hci_con_handle_t acl_handle, uint8_t enable){ 1683 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1684 if (!hfp_connection) { 1685 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1686 } 1687 hfp_connection->enable_status_update_for_ag_indicators = enable; 1688 hfp_hf_run_for_context(hfp_connection); 1689 return ERROR_CODE_SUCCESS; 1690 } 1691 1692 uint8_t hfp_hf_enable_status_update_for_all_ag_indicators(hci_con_handle_t acl_handle){ 1693 return hfp_hf_set_status_update_for_all_ag_indicators(acl_handle, 1); 1694 } 1695 1696 uint8_t hfp_hf_disable_status_update_for_all_ag_indicators(hci_con_handle_t acl_handle){ 1697 return hfp_hf_set_status_update_for_all_ag_indicators(acl_handle, 0); 1698 } 1699 1700 // TODO: returned ERROR - wrong format 1701 uint8_t hfp_hf_set_status_update_for_individual_ag_indicators(hci_con_handle_t acl_handle, uint32_t indicators_status_bitmap){ 1702 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1703 if (!hfp_connection) { 1704 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1705 } 1706 hfp_connection->change_status_update_for_individual_ag_indicators = 1; 1707 hfp_connection->ag_indicators_status_update_bitmap = indicators_status_bitmap; 1708 hfp_hf_run_for_context(hfp_connection); 1709 return ERROR_CODE_SUCCESS; 1710 } 1711 1712 uint8_t hfp_hf_query_operator_selection(hci_con_handle_t acl_handle){ 1713 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1714 if (!hfp_connection) { 1715 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1716 } 1717 1718 switch (hfp_connection->hf_query_operator_state){ 1719 case HFP_HF_QUERY_OPERATOR_FORMAT_NOT_SET: 1720 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SET_FORMAT; 1721 break; 1722 case HFP_HF_QUERY_OPERATOR_FORMAT_SET: 1723 hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_SEND_QUERY; 1724 break; 1725 default: 1726 return ERROR_CODE_COMMAND_DISALLOWED; 1727 } 1728 hfp_hf_run_for_context(hfp_connection); 1729 return ERROR_CODE_SUCCESS; 1730 } 1731 1732 static uint8_t hfp_hf_set_report_extended_audio_gateway_error_result_code(hci_con_handle_t acl_handle, uint8_t enable){ 1733 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1734 if (!hfp_connection) { 1735 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1736 } 1737 hfp_connection->enable_extended_audio_gateway_error_report = enable; 1738 hfp_hf_run_for_context(hfp_connection); 1739 return ERROR_CODE_SUCCESS; 1740 } 1741 1742 1743 uint8_t hfp_hf_enable_report_extended_audio_gateway_error_result_code(hci_con_handle_t acl_handle){ 1744 return hfp_hf_set_report_extended_audio_gateway_error_result_code(acl_handle, 1); 1745 } 1746 1747 uint8_t hfp_hf_disable_report_extended_audio_gateway_error_result_code(hci_con_handle_t acl_handle){ 1748 return hfp_hf_set_report_extended_audio_gateway_error_result_code(acl_handle, 0); 1749 } 1750 1751 static uint8_t hfp_hf_esco_s4_supported(hfp_connection_t * hfp_connection){ 1752 return (hfp_connection->remote_supported_features & (1<<HFP_AGSF_ESCO_S4)) && (hfp_hf_supported_features & (1 << HFP_HFSF_ESCO_S4)); 1753 } 1754 1755 uint8_t hfp_hf_establish_audio_connection(hci_con_handle_t acl_handle){ 1756 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1757 if (!hfp_connection) { 1758 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1759 } 1760 1761 if (hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED){ 1762 return ERROR_CODE_COMMAND_DISALLOWED; 1763 } 1764 1765 if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO){ 1766 return ERROR_CODE_COMMAND_DISALLOWED; 1767 } 1768 if (has_codec_negotiation_feature(hfp_connection)) { 1769 switch (hfp_connection->codecs_state) { 1770 case HFP_CODECS_W4_AG_COMMON_CODEC: 1771 break; 1772 case HFP_CODECS_EXCHANGED: 1773 hfp_connection->trigger_codec_exchange = 1; 1774 break; 1775 default: 1776 hfp_connection->codec_confirmed = 0; 1777 hfp_connection->suggested_codec = 0; 1778 hfp_connection->negotiated_codec = 0; 1779 hfp_connection->codecs_state = HFP_CODECS_RECEIVED_TRIGGER_CODEC_EXCHANGE; 1780 hfp_connection->trigger_codec_exchange = 1; 1781 break; 1782 } 1783 } else { 1784 log_info("no codec negotiation feature, use CVSD"); 1785 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED; 1786 hfp_connection->suggested_codec = HFP_CODEC_CVSD; 1787 hfp_connection->codec_confirmed = hfp_connection->suggested_codec; 1788 hfp_connection->negotiated_codec = hfp_connection->suggested_codec; 1789 hfp_init_link_settings(hfp_connection, hfp_hf_esco_s4_supported(hfp_connection)); 1790 hfp_connection->establish_audio_connection = 1; 1791 hfp_connection->state = HFP_W4_SCO_CONNECTED; 1792 } 1793 1794 hfp_hf_run_for_context(hfp_connection); 1795 return ERROR_CODE_SUCCESS; 1796 } 1797 1798 uint8_t hfp_hf_release_audio_connection(hci_con_handle_t acl_handle){ 1799 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1800 if (!hfp_connection) { 1801 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1802 } 1803 if (hfp_connection->vra_state == HFP_VRA_VOICE_RECOGNITION_ACTIVATED){ 1804 return ERROR_CODE_COMMAND_DISALLOWED; 1805 } 1806 uint8_t status = hfp_trigger_release_audio_connection(hfp_connection); 1807 if (status == ERROR_CODE_SUCCESS){ 1808 hfp_hf_run_for_context(hfp_connection); 1809 } 1810 return ERROR_CODE_SUCCESS; 1811 } 1812 1813 uint8_t hfp_hf_answer_incoming_call(hci_con_handle_t acl_handle){ 1814 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1815 if (!hfp_connection) { 1816 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1817 } 1818 1819 if (hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ 1820 hfp_connection->hf_answer_incoming_call = 1; 1821 hfp_hf_run_for_context(hfp_connection); 1822 } else { 1823 log_error("HFP HF: answering incoming call with wrong callsetup status %u", hfp_connection->hf_callsetup_status); 1824 return ERROR_CODE_COMMAND_DISALLOWED; 1825 } 1826 return ERROR_CODE_SUCCESS; 1827 } 1828 1829 uint8_t hfp_hf_terminate_call(hci_con_handle_t acl_handle){ 1830 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1831 if (!hfp_connection) { 1832 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1833 } 1834 hfp_connection->hf_send_chup = 1; 1835 hfp_hf_run_for_context(hfp_connection); 1836 return ERROR_CODE_SUCCESS; 1837 } 1838 1839 uint8_t hfp_hf_reject_incoming_call(hci_con_handle_t acl_handle){ 1840 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1841 if (!hfp_connection) { 1842 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1843 } 1844 1845 if (hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ 1846 hfp_connection->hf_send_chup = 1; 1847 hfp_hf_run_for_context(hfp_connection); 1848 } 1849 return ERROR_CODE_SUCCESS; 1850 } 1851 1852 uint8_t hfp_hf_user_busy(hci_con_handle_t acl_handle){ 1853 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1854 if (!hfp_connection) { 1855 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1856 } 1857 1858 if (hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ 1859 hfp_connection->hf_send_chld_0 = 1; 1860 hfp_hf_run_for_context(hfp_connection); 1861 } 1862 return ERROR_CODE_SUCCESS; 1863 } 1864 1865 uint8_t hfp_hf_terminate_held_calls(hci_con_handle_t acl_handle){ 1866 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1867 if (!hfp_connection) { 1868 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1869 } 1870 1871 hfp_connection->hf_send_chld_0 = 1; 1872 hfp_hf_run_for_context(hfp_connection); 1873 1874 return ERROR_CODE_SUCCESS; 1875 } 1876 1877 uint8_t hfp_hf_end_active_and_accept_other(hci_con_handle_t acl_handle){ 1878 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1879 if (!hfp_connection) { 1880 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1881 } 1882 1883 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1884 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1885 hfp_connection->hf_send_chld_1 = 1; 1886 hfp_hf_run_for_context(hfp_connection); 1887 } 1888 return ERROR_CODE_SUCCESS; 1889 } 1890 1891 uint8_t hfp_hf_swap_calls(hci_con_handle_t acl_handle){ 1892 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1893 if (!hfp_connection) { 1894 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1895 } 1896 1897 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1898 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1899 hfp_connection->hf_send_chld_2 = 1; 1900 hfp_hf_run_for_context(hfp_connection); 1901 } 1902 return ERROR_CODE_SUCCESS; 1903 } 1904 1905 uint8_t hfp_hf_join_held_call(hci_con_handle_t acl_handle){ 1906 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1907 if (!hfp_connection) { 1908 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1909 } 1910 1911 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1912 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1913 hfp_connection->hf_send_chld_3 = 1; 1914 hfp_hf_run_for_context(hfp_connection); 1915 } 1916 return ERROR_CODE_SUCCESS; 1917 } 1918 1919 uint8_t hfp_hf_connect_calls(hci_con_handle_t acl_handle){ 1920 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1921 if (!hfp_connection) { 1922 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1923 } 1924 1925 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1926 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1927 hfp_connection->hf_send_chld_4 = 1; 1928 hfp_hf_run_for_context(hfp_connection); 1929 } 1930 return ERROR_CODE_SUCCESS; 1931 } 1932 1933 uint8_t hfp_hf_release_call_with_index(hci_con_handle_t acl_handle, int index){ 1934 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1935 if (!hfp_connection) { 1936 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1937 } 1938 1939 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1940 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1941 hfp_connection->hf_send_chld_x = 1; 1942 hfp_connection->hf_send_chld_x_index = 10 + index; 1943 hfp_hf_run_for_context(hfp_connection); 1944 } 1945 return ERROR_CODE_SUCCESS; 1946 } 1947 1948 uint8_t hfp_hf_private_consultation_with_call(hci_con_handle_t acl_handle, int index){ 1949 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1950 if (!hfp_connection) { 1951 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1952 } 1953 1954 if ((hfp_connection->hf_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS) || 1955 (hfp_connection->hf_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ 1956 hfp_connection->hf_send_chld_x = 1; 1957 hfp_connection->hf_send_chld_x_index = 20 + index; 1958 hfp_hf_run_for_context(hfp_connection); 1959 } 1960 return ERROR_CODE_SUCCESS; 1961 } 1962 1963 uint8_t hfp_hf_dial_number(hci_con_handle_t acl_handle, char * number){ 1964 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1965 if (!hfp_connection) { 1966 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1967 } 1968 1969 hfp_connection->hf_initiate_outgoing_call = 1; 1970 btstack_snprintf_assert_complete(hfp_hf_phone_number, sizeof(hfp_hf_phone_number), "%s", number); 1971 hfp_hf_run_for_context(hfp_connection); 1972 return ERROR_CODE_SUCCESS; 1973 } 1974 1975 uint8_t hfp_hf_dial_memory(hci_con_handle_t acl_handle, int memory_id){ 1976 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1977 if (!hfp_connection) { 1978 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1979 } 1980 1981 hfp_connection->hf_initiate_memory_dialing = 1; 1982 hfp_connection->memory_id = memory_id; 1983 1984 hfp_hf_run_for_context(hfp_connection); 1985 return ERROR_CODE_SUCCESS; 1986 } 1987 1988 uint8_t hfp_hf_redial_last_number(hci_con_handle_t acl_handle){ 1989 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 1990 if (!hfp_connection) { 1991 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1992 } 1993 1994 hfp_connection->hf_initiate_redial_last_number = 1; 1995 hfp_hf_run_for_context(hfp_connection); 1996 return ERROR_CODE_SUCCESS; 1997 } 1998 1999 uint8_t hfp_hf_activate_call_waiting_notification(hci_con_handle_t acl_handle){ 2000 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2001 if (!hfp_connection) { 2002 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2003 } 2004 2005 hfp_connection->hf_activate_call_waiting_notification = 1; 2006 hfp_hf_run_for_context(hfp_connection); 2007 return ERROR_CODE_SUCCESS; 2008 } 2009 2010 2011 uint8_t hfp_hf_deactivate_call_waiting_notification(hci_con_handle_t acl_handle){ 2012 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2013 if (!hfp_connection) { 2014 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2015 } 2016 2017 hfp_connection->hf_deactivate_call_waiting_notification = 1; 2018 hfp_hf_run_for_context(hfp_connection); 2019 return ERROR_CODE_SUCCESS; 2020 } 2021 2022 2023 uint8_t hfp_hf_activate_calling_line_notification(hci_con_handle_t acl_handle){ 2024 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2025 if (!hfp_connection) { 2026 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2027 } 2028 2029 hfp_connection->hf_activate_calling_line_notification = 1; 2030 hfp_hf_run_for_context(hfp_connection); 2031 return ERROR_CODE_SUCCESS; 2032 } 2033 2034 uint8_t hfp_hf_deactivate_calling_line_notification(hci_con_handle_t acl_handle){ 2035 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2036 if (!hfp_connection) { 2037 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2038 } 2039 2040 hfp_connection->hf_deactivate_calling_line_notification = 1; 2041 hfp_hf_run_for_context(hfp_connection); 2042 return ERROR_CODE_SUCCESS; 2043 } 2044 2045 uint8_t hfp_hf_deactivate_echo_canceling_and_noise_reduction(hci_con_handle_t acl_handle){ 2046 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2047 if (!hfp_connection) { 2048 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2049 } 2050 if (get_bit(hfp_connection->remote_supported_features, HFP_AGSF_EC_NR_FUNCTION) == 0){ 2051 return ERROR_CODE_COMMAND_DISALLOWED; 2052 } 2053 2054 hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 1; 2055 hfp_hf_run_for_context(hfp_connection); 2056 return ERROR_CODE_SUCCESS; 2057 } 2058 2059 uint8_t hfp_hf_activate_voice_recognition(hci_con_handle_t acl_handle){ 2060 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2061 if (!hfp_connection) { 2062 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2063 } 2064 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || hfp_connection->state > HFP_AUDIO_CONNECTION_ESTABLISHED){ 2065 return ERROR_CODE_COMMAND_DISALLOWED; 2066 } 2067 2068 bool enhanced_vra_supported = hfp_hf_enhanced_vra_flag_supported(hfp_connection); 2069 bool legacy_vra_supported = hfp_hf_vra_flag_supported(hfp_connection); 2070 if (!enhanced_vra_supported && !legacy_vra_supported){ 2071 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 2072 } 2073 2074 switch (hfp_connection->vra_state){ 2075 case HFP_VRA_VOICE_RECOGNITION_OFF: 2076 case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF: 2077 hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED; 2078 hfp_connection->enhanced_voice_recognition_enabled = enhanced_vra_supported; 2079 break; 2080 case HFP_VRA_W4_VOICE_RECOGNITION_OFF: 2081 hfp_connection->activate_voice_recognition = true; 2082 break; 2083 default: 2084 return ERROR_CODE_COMMAND_DISALLOWED; 2085 } 2086 2087 hfp_hf_run_for_context(hfp_connection); 2088 return ERROR_CODE_SUCCESS; 2089 } 2090 2091 uint8_t hfp_hf_enhanced_voice_recognition_report_ready_for_audio(hci_con_handle_t acl_handle){ 2092 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2093 if (!hfp_connection) { 2094 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2095 } 2096 2097 if (hfp_connection->emit_vra_enabled_after_audio_established){ 2098 return ERROR_CODE_COMMAND_DISALLOWED; 2099 } 2100 2101 if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED){ 2102 return ERROR_CODE_COMMAND_DISALLOWED; 2103 } 2104 2105 bool enhanced_vra_supported = hfp_hf_enhanced_vra_flag_supported(hfp_connection); 2106 if (!enhanced_vra_supported){ 2107 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 2108 } 2109 2110 switch (hfp_connection->vra_state){ 2111 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED: 2112 case HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 2113 hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO; 2114 break; 2115 default: 2116 return ERROR_CODE_COMMAND_DISALLOWED; 2117 } 2118 2119 hfp_hf_run_for_context(hfp_connection); 2120 return ERROR_CODE_SUCCESS; 2121 } 2122 2123 2124 uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle){ 2125 // return deactivate_voice_recognition(acl_handle, false); 2126 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2127 if (!hfp_connection) { 2128 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2129 } 2130 2131 if (hfp_connection->emit_vra_enabled_after_audio_established){ 2132 return ERROR_CODE_COMMAND_DISALLOWED; 2133 } 2134 2135 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || 2136 hfp_connection->state > HFP_AUDIO_CONNECTION_ESTABLISHED){ 2137 return ERROR_CODE_COMMAND_DISALLOWED; 2138 } 2139 2140 bool enhanced_vra_supported = hfp_hf_enhanced_vra_flag_supported(hfp_connection); 2141 bool legacy_vra_supported = hfp_hf_vra_flag_supported(hfp_connection); 2142 if (!enhanced_vra_supported && !legacy_vra_supported){ 2143 return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 2144 } 2145 2146 switch (hfp_connection->vra_state){ 2147 case HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED: 2148 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED: 2149 case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 2150 case HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 2151 hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF; 2152 break; 2153 2154 case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED: 2155 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: 2156 hfp_connection->deactivate_voice_recognition = true; 2157 break; 2158 2159 case HFP_VRA_VOICE_RECOGNITION_OFF: 2160 case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF: 2161 case HFP_VRA_W4_VOICE_RECOGNITION_OFF: 2162 default: 2163 return ERROR_CODE_COMMAND_DISALLOWED; 2164 } 2165 2166 hfp_hf_run_for_context(hfp_connection); 2167 return ERROR_CODE_SUCCESS; 2168 } 2169 2170 uint8_t hfp_hf_set_microphone_gain(hci_con_handle_t acl_handle, int gain){ 2171 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2172 if (!hfp_connection) { 2173 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2174 } 2175 2176 if (hfp_connection->microphone_gain == gain) { 2177 return ERROR_CODE_SUCCESS; 2178 } 2179 2180 if ((gain < 0) || (gain > 15)){ 2181 log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain); 2182 return ERROR_CODE_COMMAND_DISALLOWED; 2183 } 2184 2185 hfp_connection->microphone_gain = gain; 2186 hfp_connection->send_microphone_gain = 1; 2187 hfp_hf_run_for_context(hfp_connection); 2188 return ERROR_CODE_SUCCESS; 2189 } 2190 2191 uint8_t hfp_hf_set_speaker_gain(hci_con_handle_t acl_handle, int gain){ 2192 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2193 if (!hfp_connection) { 2194 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2195 } 2196 2197 if (hfp_connection->speaker_gain == gain){ 2198 return ERROR_CODE_SUCCESS; 2199 } 2200 2201 if ((gain < 0) || (gain > 15)){ 2202 log_info("Valid range for a gain is [0..15]. Currently sent: %d", gain); 2203 return ERROR_CODE_COMMAND_DISALLOWED; 2204 } 2205 2206 hfp_connection->speaker_gain = gain; 2207 hfp_connection->send_speaker_gain = 1; 2208 hfp_hf_run_for_context(hfp_connection); 2209 return ERROR_CODE_SUCCESS; 2210 } 2211 2212 uint8_t hfp_hf_send_dtmf_code(hci_con_handle_t acl_handle, char code){ 2213 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2214 if (!hfp_connection) { 2215 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2216 } 2217 hfp_connection->hf_send_dtmf_code = code; 2218 hfp_hf_run_for_context(hfp_connection); 2219 return ERROR_CODE_SUCCESS; 2220 } 2221 2222 uint8_t hfp_hf_request_phone_number_for_voice_tag(hci_con_handle_t acl_handle){ 2223 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2224 if (!hfp_connection) { 2225 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2226 } 2227 hfp_connection->hf_send_binp = 1; 2228 hfp_hf_run_for_context(hfp_connection); 2229 return ERROR_CODE_SUCCESS; 2230 } 2231 2232 uint8_t hfp_hf_query_current_call_status(hci_con_handle_t acl_handle){ 2233 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2234 if (!hfp_connection) { 2235 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2236 } 2237 hfp_connection->hf_send_clcc = 1; 2238 hfp_hf_run_for_context(hfp_connection); 2239 return ERROR_CODE_SUCCESS; 2240 } 2241 2242 2243 uint8_t hfp_hf_rrh_query_status(hci_con_handle_t acl_handle){ 2244 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2245 if (!hfp_connection) { 2246 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2247 } 2248 hfp_connection->hf_send_rrh = 1; 2249 hfp_connection->hf_send_rrh_command = '?'; 2250 hfp_hf_run_for_context(hfp_connection); 2251 return ERROR_CODE_SUCCESS; 2252 } 2253 2254 uint8_t hfp_hf_rrh_hold_call(hci_con_handle_t acl_handle){ 2255 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2256 if (!hfp_connection) { 2257 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2258 } 2259 hfp_connection->hf_send_rrh = 1; 2260 hfp_connection->hf_send_rrh_command = '0'; 2261 hfp_hf_run_for_context(hfp_connection); 2262 return ERROR_CODE_SUCCESS; 2263 } 2264 2265 uint8_t hfp_hf_rrh_accept_held_call(hci_con_handle_t acl_handle){ 2266 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2267 if (!hfp_connection) { 2268 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2269 } 2270 hfp_connection->hf_send_rrh = 1; 2271 hfp_connection->hf_send_rrh_command = '1'; 2272 hfp_hf_run_for_context(hfp_connection); 2273 return ERROR_CODE_SUCCESS; 2274 } 2275 2276 uint8_t hfp_hf_rrh_reject_held_call(hci_con_handle_t acl_handle){ 2277 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2278 if (!hfp_connection) { 2279 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2280 } 2281 hfp_connection->hf_send_rrh = 1; 2282 hfp_connection->hf_send_rrh_command = '2'; 2283 hfp_hf_run_for_context(hfp_connection); 2284 return ERROR_CODE_SUCCESS; 2285 } 2286 2287 uint8_t hfp_hf_query_subscriber_number(hci_con_handle_t acl_handle){ 2288 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2289 if (!hfp_connection) { 2290 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2291 } 2292 hfp_connection->hf_send_cnum = 1; 2293 hfp_hf_run_for_context(hfp_connection); 2294 return ERROR_CODE_SUCCESS; 2295 } 2296 2297 uint8_t hfp_hf_set_hf_indicator(hci_con_handle_t acl_handle, int assigned_number, int value){ 2298 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2299 if (!hfp_connection) { 2300 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2301 } 2302 // find index for assigned number 2303 uint8_t i; 2304 for (i = 0; i < hfp_hf_indicators_nr ; i++){ 2305 if (hfp_hf_indicators[i] == assigned_number){ 2306 // check if connection ready and indicator enabled 2307 if (hfp_connection->state > HFP_LIST_GENERIC_STATUS_INDICATORS){ 2308 if (hfp_connection->generic_status_indicators[i].state != 0) { 2309 // set value 2310 hfp_hf_indicators_value[i] = value; 2311 // mark for update 2312 hfp_connection->generic_status_update_bitmap |= (1 << i); 2313 // send update 2314 hfp_hf_run_for_context(hfp_connection); 2315 break; 2316 } 2317 } 2318 } 2319 } 2320 if (i == hfp_hf_indicators_nr){ 2321 return ERROR_CODE_COMMAND_DISALLOWED; 2322 } 2323 return ERROR_CODE_SUCCESS; 2324 } 2325 2326 void hfp_hf_apple_set_identification(uint16_t vendor_id, uint16_t product_id, const char * version, uint8_t features){ 2327 hfp_hf_apple_vendor_id = vendor_id; 2328 hfp_hf_apple_product_id = product_id; 2329 hfp_hf_apple_version = version; 2330 hfp_hf_apple_features = features; 2331 } 2332 2333 uint8_t hfp_hf_apple_set_battery_level(uint8_t battery_level){ 2334 if (battery_level > 9) { 2335 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 2336 } 2337 hfp_hf_apple_battery_level = (int8_t) battery_level; 2338 hfp_hf_apple_trigger_send(); 2339 return ERROR_CODE_SUCCESS; 2340 } 2341 2342 uint8_t hfp_hf_apple_set_docked_state(uint8_t docked){ 2343 if (docked > 1) { 2344 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 2345 } 2346 hfp_hf_apple_docked = (int8_t) docked; 2347 hfp_hf_apple_trigger_send(); 2348 return ERROR_CODE_SUCCESS; 2349 } 2350 2351 uint8_t hfp_hf_send_at_command(hci_con_handle_t acl_handle, const char * at_command){ 2352 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2353 if (!hfp_connection) { 2354 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 2355 } 2356 if (hfp_connection->send_custom_message != NULL){ 2357 return ERROR_CODE_COMMAND_DISALLOWED; 2358 } 2359 hfp_connection->send_custom_message = at_command; 2360 hfp_hf_run_for_context(hfp_connection); 2361 return ERROR_CODE_SUCCESS; 2362 } 2363 2364 int hfp_hf_in_band_ringtone_active(hci_con_handle_t acl_handle){ 2365 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle); 2366 if (!hfp_connection) { 2367 return 0; 2368 } 2369 return get_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE); 2370 } 2371 2372 void hfp_hf_create_sdp_record_with_codecs(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, 2373 const char * name, uint16_t supported_features, uint8_t codecs_nr, const uint8_t * codecs){ 2374 if (!name){ 2375 name = hfp_hf_default_service_name; 2376 } 2377 hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name); 2378 2379 // Construct SupportedFeatures for SDP bitmap: 2380 // 2381 // "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values 2382 // of the Bits 0 to 4 of the unsolicited result code +BRSF" 2383 // 2384 // Wide band speech (bit 5) and LC3-SWB (bit 8) require Codec negotiation 2385 // 2386 uint16_t sdp_features = supported_features & 0x1f; 2387 2388 if (supported_features & (1 << HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS)){ 2389 sdp_features |= 1 << 6; 2390 } 2391 2392 if (supported_features & (1 << HFP_HFSF_VOICE_RECOGNITION_TEXT)){ 2393 sdp_features |= 1 << 7; 2394 } 2395 2396 // codecs 2397 if ((supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION)) != 0){ 2398 uint8_t i; 2399 for (i=0;i<codecs_nr;i++){ 2400 switch (codecs[i]){ 2401 case HFP_CODEC_MSBC: 2402 sdp_features |= 1 << 5; 2403 break; 2404 case HFP_CODEC_LC3_SWB: 2405 sdp_features |= 1 << 8; 2406 break; 2407 default: 2408 break; 2409 } 2410 } 2411 } 2412 2413 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SUPPORTED_FEATURES); 2414 de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features); 2415 } 2416 2417 // @deprecated, call new API 2418 void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){ 2419 uint8_t codecs_nr; 2420 const uint8_t * codecs; 2421 const uint8_t wide_band_codecs[] = { HFP_CODEC_MSBC }; 2422 if (wide_band_speech == 0){ 2423 codecs_nr = 0; 2424 codecs = NULL; 2425 } else { 2426 codecs_nr = 1; 2427 codecs = wide_band_codecs; 2428 } 2429 hfp_hf_create_sdp_record_with_codecs(service, service_record_handle, rfcomm_channel_nr, name, supported_features, codecs_nr, codecs); 2430 } 2431 2432 void hfp_hf_register_custom_at_command(hfp_custom_at_command_t * custom_at_command){ 2433 hfp_register_custom_hf_command(custom_at_command); 2434 } 2435 2436 void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){ 2437 btstack_assert(callback != NULL); 2438 2439 hfp_hf_callback = callback; 2440 hfp_set_hf_callback(callback); 2441 } 2442