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 MATTHIAS 24 * RINGWALD 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.c" 39 40 41 #include "btstack_config.h" 42 43 #include <stdint.h> 44 #include <stdio.h> 45 #include <string.h> 46 #include <inttypes.h> 47 48 #include "bluetooth_sdp.h" 49 #include "btstack_debug.h" 50 #include "btstack_event.h" 51 #include "btstack_memory.h" 52 #include "btstack_run_loop.h" 53 #include "classic/sdp_client_rfcomm.h" 54 #include "classic/sdp_server.h" 55 #include "classic/sdp_util.h" 56 #include "classic/sdp_client.h" 57 #include "hci.h" 58 #include "hci_cmd.h" 59 #include "hci_dump.h" 60 61 #if defined(ENABLE_CC256X_ASSISTED_HFP) && !defined(ENABLE_SCO_OVER_PCM) 62 #error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM" 63 #endif 64 65 #if defined(ENABLE_BCM_PCM_WBS) && !defined(ENABLE_SCO_OVER_PCM) 66 #error "WBS for PCM is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM" 67 #endif 68 69 #define HFP_HF_FEATURES_SIZE 10 70 #define HFP_AG_FEATURES_SIZE 12 71 72 typedef struct { 73 hfp_role_t local_role; 74 bd_addr_t remote_address; 75 } hfp_sdp_query_context_t; 76 77 // globals 78 79 static hfp_sdp_query_context_t sdp_query_context; 80 static btstack_context_callback_registration_t hfp_handle_sdp_client_query_request; 81 82 static btstack_linked_list_t hfp_connections ; 83 84 static btstack_packet_handler_t hfp_hf_callback; 85 static btstack_packet_handler_t hfp_ag_callback; 86 87 static btstack_packet_handler_t hfp_hf_rfcomm_packet_handler; 88 static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler; 89 90 static hfp_connection_t * sco_establishment_active; 91 92 static uint16_t hfp_allowed_sco_packet_types; 93 94 // prototypes 95 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported); 96 static void parse_sequence(hfp_connection_t * context); 97 98 99 static const char * hfp_hf_features[] = { 100 "EC and/or NR function", 101 "Three-way calling", 102 "CLI presentation capability", 103 "Voice recognition activation", 104 "Remote volume control", 105 106 "Enhanced call status", 107 "Enhanced call control", 108 109 "Codec negotiation", 110 111 "HF Indicators", 112 "eSCO S4 (and T2) Settings Supported", 113 "Reserved for future definition" 114 }; 115 116 static const char * hfp_ag_features[] = { 117 "Three-way calling", 118 "EC and/or NR function", 119 "Voice recognition function", 120 "In-band ring tone capability", 121 "Attach a number to a voice tag", 122 "Ability to reject a call", 123 "Enhanced call status", 124 "Enhanced call control", 125 "Extended Error Result Codes", 126 "Codec negotiation", 127 "HF Indicators", 128 "eSCO S4 (and T2) Settings Supported", 129 "Reserved for future definition" 130 }; 131 132 static const char * hfp_enhanced_call_dir[] = { 133 "outgoing", 134 "incoming" 135 }; 136 137 static const char * hfp_enhanced_call_status[] = { 138 "active", 139 "held", 140 "outgoing dialing", 141 "outgoing alerting", 142 "incoming", 143 "incoming waiting", 144 "call held by response and hold" 145 }; 146 147 static const char * hfp_enhanced_call_mode[] = { 148 "voice", 149 "data", 150 "fax" 151 }; 152 153 static const char * hfp_enhanced_call_mpty[] = { 154 "not a conference call", 155 "conference call" 156 }; 157 158 const char * hfp_enhanced_call_dir2str(uint16_t index){ 159 if (index <= HFP_ENHANCED_CALL_DIR_INCOMING) return hfp_enhanced_call_dir[index]; 160 return "not defined"; 161 } 162 163 const char * hfp_enhanced_call_status2str(uint16_t index){ 164 if (index <= HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD) return hfp_enhanced_call_status[index]; 165 return "not defined"; 166 } 167 168 const char * hfp_enhanced_call_mode2str(uint16_t index){ 169 if (index <= HFP_ENHANCED_CALL_MODE_FAX) return hfp_enhanced_call_mode[index]; 170 return "not defined"; 171 } 172 173 const char * hfp_enhanced_call_mpty2str(uint16_t index){ 174 if (index <= HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL) return hfp_enhanced_call_mpty[index]; 175 return "not defined"; 176 } 177 178 static uint16_t hfp_parse_indicator_index(hfp_connection_t * hfp_connection){ 179 uint16_t index = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 180 181 if (index > HFP_MAX_NUM_INDICATORS){ 182 log_info("ignoring invalid indicator index bigger then HFP_MAX_NUM_INDICATORS"); 183 return HFP_MAX_NUM_INDICATORS - 1; 184 } 185 186 // indicator index enumeration starts with 1, we substract 1 to store in array with starting index 0 187 if (index > 0){ 188 index -= 1; 189 } else { 190 log_info("ignoring invalid indicator index 0"); 191 return 0; 192 } 193 return index; 194 } 195 196 static void hfp_next_indicators_index(hfp_connection_t * hfp_connection){ 197 if (hfp_connection->parser_item_index < HFP_MAX_NUM_INDICATORS - 1){ 198 hfp_connection->parser_item_index++; 199 } else { 200 log_info("Ignoring additional indicator"); 201 } 202 } 203 204 static void hfp_next_codec_index(hfp_connection_t * hfp_connection){ 205 if (hfp_connection->parser_item_index < HFP_MAX_NUM_CODECS - 1){ 206 hfp_connection->parser_item_index++; 207 } else { 208 log_info("Ignoring additional codec index"); 209 } 210 } 211 212 static void hfp_next_remote_call_services_index(hfp_connection_t * hfp_connection){ 213 if (hfp_connection->remote_call_services_index < HFP_MAX_NUM_CALL_SERVICES - 1){ 214 hfp_connection->remote_call_services_index++; 215 } else { 216 log_info("Ignoring additional remote_call_services"); 217 } 218 } 219 220 const char * hfp_hf_feature(int index){ 221 if (index > HFP_HF_FEATURES_SIZE){ 222 return hfp_hf_features[HFP_HF_FEATURES_SIZE]; 223 } 224 return hfp_hf_features[index]; 225 } 226 227 const char * hfp_ag_feature(int index){ 228 if (index > HFP_AG_FEATURES_SIZE){ 229 return hfp_ag_features[HFP_AG_FEATURES_SIZE]; 230 } 231 return hfp_ag_features[index]; 232 } 233 234 int send_str_over_rfcomm(uint16_t cid, char * command){ 235 if (!rfcomm_can_send_packet_now(cid)) return 1; 236 log_info("HFP_TX %s", command); 237 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command)); 238 if (err){ 239 log_error("rfcomm_send -> error 0x%02x \n", err); 240 } 241 #ifdef ENABLE_HFP_AT_MESSAGES 242 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(cid); 243 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_AT_MESSAGE_SENT, command); 244 #endif 245 return 1; 246 } 247 248 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){ 249 250 // mSBC requires support for eSCO connections 251 if ((codec == HFP_CODEC_MSBC) && !hci_extended_sco_link_supported()) return 0; 252 253 int i; 254 for (i = 0; i < codecs_nr; i++){ 255 if (codecs[i] != codec) continue; 256 return 1; 257 } 258 return 0; 259 } 260 261 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){ 262 if (hci_extended_sco_link_supported()) return; 263 uint8_t tmp_codecs[HFP_MAX_NUM_CODECS]; 264 int i; 265 int tmp_codec_nr = 0; 266 for (i=0; i < *codecs_nr; i++){ 267 if (codecs[i] == HFP_CODEC_MSBC) continue; 268 tmp_codecs[tmp_codec_nr++] = codecs[i]; 269 } 270 *codecs_nr = tmp_codec_nr; 271 (void)memcpy(codecs, tmp_codecs, tmp_codec_nr); 272 } 273 274 // UTILS 275 int get_bit(uint16_t bitmap, int position){ 276 return (bitmap >> position) & 1; 277 } 278 279 int store_bit(uint32_t bitmap, int position, uint8_t value){ 280 if (value){ 281 bitmap |= 1 << position; 282 } else { 283 bitmap &= ~ (1 << position); 284 } 285 return bitmap; 286 } 287 288 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ 289 if (buffer_size < (values_nr * 3)) return 0; 290 int i; 291 int offset = 0; 292 for (i = 0; i < (values_nr-1); i++) { 293 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer 294 } 295 if (i<values_nr){ 296 offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]); 297 } 298 return offset; 299 } 300 301 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){ 302 if (buffer_size < (values_nr * 3)) return 0; 303 304 int i; 305 int offset = 0; 306 for (i = 0; i < (values_nr-1); i++) { 307 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer 308 } 309 310 if (i<values_nr){ 311 offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i)); 312 } 313 return offset; 314 } 315 316 static void hfp_emit_event_for_context(hfp_connection_t * hfp_connection, uint8_t * packet, uint16_t size){ 317 if (!hfp_connection) return; 318 btstack_packet_handler_t callback = NULL; 319 switch (hfp_connection->local_role){ 320 case HFP_ROLE_HF: 321 callback = hfp_hf_callback; 322 break; 323 case HFP_ROLE_AG: 324 callback = hfp_ag_callback; 325 break; 326 default: 327 return; 328 } 329 (*callback)(HCI_EVENT_PACKET, 0, packet, size); 330 } 331 332 void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype){ 333 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID; 334 uint8_t event[5]; 335 event[0] = HCI_EVENT_HFP_META; 336 event[1] = sizeof(event) - 2; 337 event[2] = event_subtype; 338 little_endian_store_16(event, 3, acl_handle); 339 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 340 } 341 342 void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value){ 343 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID; 344 uint8_t event[6]; 345 event[0] = HCI_EVENT_HFP_META; 346 event[1] = sizeof(event) - 2; 347 event[2] = event_subtype; 348 little_endian_store_16(event, 3, acl_handle); 349 event[5] = value; // status 0 == OK 350 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 351 } 352 353 void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){ 354 btstack_assert(hfp_connection != NULL); 355 uint8_t event[12]; 356 int pos = 0; 357 event[pos++] = HCI_EVENT_HFP_META; 358 event[pos++] = sizeof(event) - 2; 359 event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 360 event[pos++] = status; // status 0 == OK 361 little_endian_store_16(event, pos, con_handle); 362 pos += 2; 363 reverse_bd_addr(addr,&event[pos]); 364 pos += 6; 365 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 366 } 367 368 static void hfp_emit_audio_connection_released(hfp_connection_t * hfp_connection, hci_con_handle_t sco_handle){ 369 btstack_assert(hfp_connection != NULL); 370 uint8_t event[7]; 371 int pos = 0; 372 event[pos++] = HCI_EVENT_HFP_META; 373 event[pos++] = sizeof(event) - 2; 374 event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED; 375 little_endian_store_16(event, pos, hfp_connection->acl_handle); 376 pos += 2; 377 little_endian_store_16(event, pos, sco_handle); 378 pos += 2; 379 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 380 } 381 382 void hfp_emit_sco_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t sco_handle, bd_addr_t addr, uint8_t negotiated_codec){ 383 btstack_assert(hfp_connection != NULL); 384 uint8_t event[15]; 385 int pos = 0; 386 event[pos++] = HCI_EVENT_HFP_META; 387 event[pos++] = sizeof(event) - 2; 388 event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED; 389 little_endian_store_16(event, pos, hfp_connection->acl_handle); 390 pos += 2; 391 event[pos++] = status; // status 0 == OK 392 little_endian_store_16(event, pos, sco_handle); 393 pos += 2; 394 reverse_bd_addr(addr,&event[pos]); 395 pos += 6; 396 event[pos++] = negotiated_codec; 397 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 398 } 399 400 void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value){ 401 btstack_assert(hfp_connection != NULL); 402 #ifdef ENABLE_HFP_AT_MESSAGES 403 uint8_t event[256]; 404 #else 405 uint8_t event[40]; 406 #endif 407 event[0] = HCI_EVENT_HFP_META; 408 event[1] = sizeof(event) - 2; 409 event[2] = event_subtype; 410 little_endian_store_16(event, 3, hfp_connection->acl_handle); 411 uint16_t size = btstack_min(strlen(value), sizeof(event) - 6); 412 strncpy((char*)&event[5], value, size); 413 event[5 + size] = 0; 414 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 415 } 416 417 static void hfp_emit_enhanced_voice_recognition_state(hfp_connection_t * hfp_connection){ 418 btstack_assert(hfp_connection != NULL); 419 uint8_t event[7]; 420 int pos = 0; 421 event[pos++] = HCI_EVENT_HFP_META; 422 event[pos++] = sizeof(event) - 2; 423 event[pos++] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS; 424 little_endian_store_16(event, pos, hfp_connection->acl_handle); 425 pos += 2; 426 event[pos++] = hfp_connection->ag_vra_status; 427 event[pos++] = hfp_connection->ag_vra_state; 428 hfp_emit_event_for_context(hfp_connection, event, sizeof(event)); 429 } 430 431 static void hfp_emit_enhanced_voice_recognition_text(hfp_connection_t * hfp_connection, uint16_t value_length, uint8_t * value){ 432 btstack_assert(hfp_connection != NULL); 433 uint8_t event[HFP_MAX_VR_TEXT_SIZE]; 434 int pos = 0; 435 event[pos++] = HCI_EVENT_HFP_META; 436 event[pos++] = sizeof(event) - 2; 437 event[pos++] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_TEXT; 438 little_endian_store_16(event, pos, hfp_connection->acl_handle); 439 pos += 2; 440 little_endian_store_16(event, pos, hfp_connection->ag_msg.text_id); 441 pos += 2; 442 event[pos++] = hfp_connection->ag_msg.text_operation; 443 event[pos++] = hfp_connection->ag_msg.text_type; 444 445 // length, zero ending 446 uint16_t size = btstack_min(value_length, sizeof(event) - pos - 2 - 1); 447 little_endian_store_16(event, pos, size+1); 448 pos += 2; 449 memcpy(&event[pos], value, size); 450 event[pos + size] = 0; 451 pos += size + 1; 452 hfp_emit_event_for_context(hfp_connection, event, pos); 453 } 454 455 btstack_linked_list_t * hfp_get_connections(void){ 456 return (btstack_linked_list_t *) &hfp_connections; 457 } 458 459 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){ 460 btstack_linked_list_iterator_t it; 461 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 462 while (btstack_linked_list_iterator_has_next(&it)){ 463 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 464 if (hfp_connection->rfcomm_cid == cid){ 465 return hfp_connection; 466 } 467 } 468 return NULL; 469 } 470 471 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role){ 472 btstack_linked_list_iterator_t it; 473 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 474 while (btstack_linked_list_iterator_has_next(&it)){ 475 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 476 if ((memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) && (hfp_connection->local_role == hfp_role)) { 477 return hfp_connection; 478 } 479 } 480 return NULL; 481 } 482 483 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role){ 484 btstack_linked_list_iterator_t it; 485 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 486 while (btstack_linked_list_iterator_has_next(&it)){ 487 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 488 if ((hfp_connection->sco_handle == handle) && (hfp_connection->local_role == hfp_role)){ 489 return hfp_connection; 490 } 491 } 492 return NULL; 493 } 494 495 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role){ 496 btstack_linked_list_iterator_t it; 497 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 498 while (btstack_linked_list_iterator_has_next(&it)){ 499 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 500 if ((hfp_connection->acl_handle == handle) && (hfp_connection->local_role == hfp_role)){ 501 return hfp_connection; 502 } 503 } 504 return NULL; 505 } 506 507 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){ 508 if (!hfp_connection) return; 509 hfp_connection->ok_pending = 0; 510 hfp_connection->send_error = 0; 511 512 hfp_connection->found_equal_sign = false; 513 514 hfp_connection->change_status_update_for_individual_ag_indicators = 0; 515 hfp_connection->operator_name_changed = 0; 516 517 hfp_connection->enable_extended_audio_gateway_error_report = 0; 518 hfp_connection->extended_audio_gateway_error = 0; 519 520 // establish codecs hfp_connection 521 hfp_connection->suggested_codec = 0; 522 hfp_connection->negotiated_codec = 0; 523 hfp_connection->codec_confirmed = 0; 524 525 hfp_connection->establish_audio_connection = 0; 526 hfp_connection->call_waiting_notification_enabled = 0; 527 hfp_connection->command = HFP_CMD_NONE; 528 hfp_connection->enable_status_update_for_ag_indicators = 0xFF; 529 } 530 531 static hfp_connection_t * create_hfp_connection_context(void){ 532 hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get(); 533 if (!hfp_connection) return NULL; 534 535 hfp_connection->state = HFP_IDLE; 536 hfp_connection->call_state = HFP_CALL_IDLE; 537 hfp_connection->codecs_state = HFP_CODECS_IDLE; 538 539 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 540 hfp_connection->command = HFP_CMD_NONE; 541 542 hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID; 543 hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID; 544 545 hfp_reset_context_flags(hfp_connection); 546 547 btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection); 548 return hfp_connection; 549 } 550 551 void hfp_finalize_connection_context(hfp_connection_t * hfp_connection){ 552 btstack_run_loop_remove_timer(&hfp_connection->hfp_timeout); 553 btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection); 554 btstack_memory_hfp_connection_free(hfp_connection); 555 } 556 557 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t local_role){ 558 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role); 559 if (hfp_connection) return hfp_connection; 560 hfp_connection = create_hfp_connection_context(); 561 (void)memcpy(hfp_connection->remote_addr, bd_addr, 6); 562 hfp_connection->local_role = local_role; 563 log_info("Create HFP context %p: role %u, addr %s", hfp_connection, local_role, bd_addr_to_str(bd_addr)); 564 565 return hfp_connection; 566 } 567 568 /* @param network. 569 * 0 == no ability to reject a call. 570 * 1 == ability to reject a call. 571 */ 572 573 /* @param suported_features 574 * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no) 575 * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no) 576 * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no) 577 * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no) 578 * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no) 579 * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 580 */ 581 /* Bit position: 582 * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no) 583 * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no) 584 * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no) 585 * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no) 586 * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no) 587 * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 588 */ 589 590 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){ 591 uint8_t* attribute; 592 de_create_sequence(service); 593 594 // 0x0000 "Service Record Handle" 595 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE); 596 de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 597 598 // 0x0001 "Service Class ID List" 599 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST); 600 attribute = de_push_sequence(service); 601 { 602 // "UUID for Service" 603 de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid); 604 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO); 605 } 606 de_pop_sequence(service, attribute); 607 608 // 0x0004 "Protocol Descriptor List" 609 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 610 attribute = de_push_sequence(service); 611 { 612 uint8_t* l2cpProtocol = de_push_sequence(attribute); 613 { 614 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 615 } 616 de_pop_sequence(attribute, l2cpProtocol); 617 618 uint8_t* rfcomm = de_push_sequence(attribute); 619 { 620 de_add_number(rfcomm, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM); // rfcomm_service 621 de_add_number(rfcomm, DE_UINT, DE_SIZE_8, rfcomm_channel_nr); // rfcomm channel 622 } 623 de_pop_sequence(attribute, rfcomm); 624 } 625 de_pop_sequence(service, attribute); 626 627 628 // 0x0005 "Public Browse Group" 629 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group 630 attribute = de_push_sequence(service); 631 { 632 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT); 633 } 634 de_pop_sequence(service, attribute); 635 636 // 0x0009 "Bluetooth Profile Descriptor List" 637 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); 638 attribute = de_push_sequence(service); 639 { 640 uint8_t *sppProfile = de_push_sequence(attribute); 641 { 642 de_add_number(sppProfile, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HANDSFREE); 643 de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0108); // Verision 1.8 644 } 645 de_pop_sequence(attribute, sppProfile); 646 } 647 de_pop_sequence(service, attribute); 648 649 // 0x0100 "Service Name" 650 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 651 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name); 652 } 653 654 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 655 UNUSED(packet_type); // ok: handling own sdp events 656 UNUSED(channel); // ok: no channel 657 UNUSED(size); // ok: handling own sdp events 658 659 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(sdp_query_context.remote_address, sdp_query_context.local_role); 660 if (hfp_connection == NULL) { 661 log_info("connection with %s and local role %d not found", sdp_query_context.remote_address, sdp_query_context.local_role); 662 return; 663 } 664 665 switch (hci_event_packet_get_type(packet)){ 666 case SDP_EVENT_QUERY_RFCOMM_SERVICE: 667 hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet); 668 break; 669 case SDP_EVENT_QUERY_COMPLETE: 670 if (hfp_connection->rfcomm_channel_nr > 0){ 671 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; 672 btstack_packet_handler_t packet_handler; 673 switch (hfp_connection->local_role){ 674 case HFP_ROLE_AG: 675 packet_handler = hfp_ag_rfcomm_packet_handler; 676 break; 677 case HFP_ROLE_HF: 678 packet_handler = hfp_hf_rfcomm_packet_handler; 679 break; 680 default: 681 btstack_assert(false); 682 return; 683 } 684 685 rfcomm_create_channel(packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL); 686 687 } else { 688 hfp_connection->state = HFP_IDLE; 689 uint8_t status = sdp_event_query_complete_get_status(packet); 690 if (status == ERROR_CODE_SUCCESS){ 691 // report service not found 692 status = SDP_SERVICE_NOT_FOUND; 693 } 694 hfp_emit_slc_connection_event(hfp_connection, status, HCI_CON_HANDLE_INVALID, hfp_connection->remote_addr); 695 log_info("rfcomm service not found, status 0x%02x", status); 696 } 697 698 // register the SDP Query request to check if there is another connection waiting for the query 699 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback 700 (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request); 701 break; 702 default: 703 break; 704 } 705 } 706 707 // returns 0 if unexpected error or no other link options remained, otherwise 1 708 static int hfp_handle_failed_sco_connection(uint8_t status){ 709 710 if (!sco_establishment_active){ 711 log_info("(e)SCO Connection failed but not started by us"); 712 return 0; 713 } 714 715 log_info("(e)SCO Connection failed 0x%02x", status); 716 switch (status){ 717 case ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE: 718 case ERROR_CODE_UNSPECIFIED_ERROR: 719 case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES: 720 break; 721 default: 722 return 0; 723 } 724 725 // note: eSCO_S4 supported flag not available, but it's only relevant for highest CVSD link setting (and the current failed) 726 hfp_link_settings_t next_setting = hfp_next_link_setting_for_connection(sco_establishment_active->link_setting, sco_establishment_active, false); 727 728 // handle no valid setting found 729 if (next_setting == HFP_LINK_SETTINGS_NONE) { 730 if (sco_establishment_active->negotiated_codec == HFP_CODEC_MSBC){ 731 log_info("T2/T1 failed, fallback to CVSD - D1"); 732 sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD; 733 sco_establishment_active->sco_for_msbc_failed = 1; 734 sco_establishment_active->command = HFP_CMD_AG_SEND_COMMON_CODEC; 735 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1; 736 } else { 737 // no other options 738 return 0; 739 } 740 } 741 742 log_info("e)SCO Connection: try new link_setting %d", next_setting); 743 sco_establishment_active->establish_audio_connection = 1; 744 sco_establishment_active->link_setting = next_setting; 745 sco_establishment_active = NULL; 746 return 1; 747 } 748 749 750 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){ 751 UNUSED(packet_type); 752 UNUSED(channel); // ok: no channel 753 UNUSED(size); 754 755 bd_addr_t event_addr; 756 hci_con_handle_t handle; 757 hfp_connection_t * hfp_connection = NULL; 758 uint8_t status; 759 760 log_debug("HFP HCI event handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size); 761 762 switch (hci_event_packet_get_type(packet)) { 763 764 case HCI_EVENT_CONNECTION_REQUEST: 765 switch(hci_event_connection_request_get_link_type(packet)){ 766 case 0: // SCO 767 case 2: // eSCO 768 hci_event_connection_request_get_bd_addr(packet, event_addr); 769 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role); 770 if (!hfp_connection) break; 771 if (hci_event_connection_request_get_link_type(packet) == 2){ 772 hfp_connection->accept_sco = 2; 773 } else { 774 hfp_connection->accept_sco = 1; 775 } 776 #ifdef ENABLE_CC256X_ASSISTED_HFP 777 hfp_cc256x_prepare_for_sco(hfp_connection); 778 #endif 779 #ifdef ENABLE_BCM_PCM_WBS 780 hfp_bcm_prepare_for_sco(hfp_connection); 781 #endif 782 log_info("accept sco %u\n", hfp_connection->accept_sco); 783 sco_establishment_active = hfp_connection; 784 break; 785 default: 786 break; 787 } 788 break; 789 790 case HCI_EVENT_COMMAND_STATUS: 791 if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) { 792 if (sco_establishment_active == NULL) break; 793 status = hci_event_command_status_get_status(packet); 794 if (status == ERROR_CODE_SUCCESS) break; 795 796 hfp_connection = sco_establishment_active; 797 if (hfp_handle_failed_sco_connection(status)) break; 798 hfp_connection->establish_audio_connection = 0; 799 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 800 hfp_emit_sco_event(hfp_connection, status, 0, hfp_connection->remote_addr, hfp_connection->negotiated_codec); 801 } 802 break; 803 804 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ 805 if (sco_establishment_active == NULL) break; 806 hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr); 807 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role); 808 if (!hfp_connection) { 809 log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr)); 810 return; 811 } 812 813 status = hci_event_synchronous_connection_complete_get_status(packet); 814 if (status != ERROR_CODE_SUCCESS){ 815 hfp_connection->accept_sco = 0; 816 if (hfp_handle_failed_sco_connection(status)) break; 817 818 hfp_connection->establish_audio_connection = 0; 819 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 820 hfp_emit_sco_event(hfp_connection, status, 0, event_addr, hfp_connection->negotiated_codec); 821 break; 822 } 823 824 uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet); 825 uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet); 826 uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots 827 uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots 828 uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes 829 uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes 830 831 switch (link_type){ 832 case 0x00: 833 log_info("SCO Connection established."); 834 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); 835 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); 836 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); 837 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); 838 break; 839 case 0x02: 840 log_info("eSCO Connection established. \n"); 841 break; 842 default: 843 log_error("(e)SCO reserved link_type 0x%2x", link_type); 844 break; 845 } 846 847 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 848 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle, 849 bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, 850 hci_event_synchronous_connection_complete_get_air_mode(packet)); 851 852 if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ 853 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN"); 854 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 855 break; 856 } 857 hfp_connection->sco_handle = sco_handle; 858 hfp_connection->establish_audio_connection = 0; 859 hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED; 860 hfp_emit_sco_event(hfp_connection, status, sco_handle, event_addr, hfp_connection->negotiated_codec); 861 break; 862 } 863 864 case HCI_EVENT_DISCONNECTION_COMPLETE: 865 handle = little_endian_read_16(packet,3); 866 hfp_connection = get_hfp_connection_context_for_sco_handle(handle, local_role); 867 868 if (!hfp_connection) break; 869 870 #ifdef ENABLE_CC256X_ASSISTED_HFP 871 hfp_connection->cc256x_send_wbs_disassociate = true; 872 #endif 873 #ifdef ENABLE_BCM_PCM_WBS 874 hfp_connection->bcm_send_disable_wbs = true; 875 #endif 876 hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID; 877 hfp_connection->release_audio_connection = 0; 878 879 if (hfp_connection->state == HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN){ 880 // RFCOMM already closed -> remote power off 881 #if defined(ENABLE_CC256X_ASSISTED_HFP) || defined (ENABLE_BCM_PCM_WBS) 882 hfp_connection->state = HFP_W4_WBS_SHUTDOWN; 883 #else 884 hfp_finalize_connection_context(hfp_connection); 885 #endif 886 break; 887 } 888 889 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 890 hfp_emit_audio_connection_released(hfp_connection, handle); 891 892 if (hfp_connection->release_slc_connection){ 893 hfp_connection->release_slc_connection = 0; 894 log_info("SCO disconnected, w2 disconnect RFCOMM\n"); 895 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 896 } 897 break; 898 899 default: 900 break; 901 } 902 } 903 904 905 void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){ 906 UNUSED(packet_type); 907 UNUSED(channel); // ok: no channel 908 UNUSED(size); 909 910 bd_addr_t event_addr; 911 uint16_t rfcomm_cid; 912 hfp_connection_t * hfp_connection = NULL; 913 uint8_t status; 914 915 log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size); 916 917 switch (hci_event_packet_get_type(packet)) { 918 919 case RFCOMM_EVENT_INCOMING_CONNECTION: 920 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 921 rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 922 hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr, local_role); 923 if (!hfp_connection){ 924 log_info("hfp: no memory to accept incoming connection - decline"); 925 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet)); 926 return; 927 } 928 if (hfp_connection->state != HFP_IDLE) { 929 log_error("hfp: incoming connection but not idle, reject"); 930 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet)); 931 return; 932 } 933 934 hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 935 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; 936 rfcomm_accept_connection(hfp_connection->rfcomm_cid); 937 break; 938 939 case RFCOMM_EVENT_CHANNEL_OPENED: 940 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) 941 942 rfcomm_event_channel_opened_get_bd_addr(packet, event_addr); 943 status = rfcomm_event_channel_opened_get_status(packet); 944 945 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role); 946 if (!hfp_connection || (hfp_connection->state != HFP_W4_RFCOMM_CONNECTED)) return; 947 948 if (status) { 949 hfp_emit_slc_connection_event(hfp_connection, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr); 950 hfp_finalize_connection_context(hfp_connection); 951 } else { 952 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet); 953 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet); 954 bd_addr_copy(hfp_connection->remote_addr, event_addr); 955 956 switch (hfp_connection->state){ 957 case HFP_W4_RFCOMM_CONNECTED: 958 hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES; 959 break; 960 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN: 961 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 962 break; 963 default: 964 break; 965 } 966 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid); 967 } 968 break; 969 970 case RFCOMM_EVENT_CHANNEL_CLOSED: 971 rfcomm_cid = little_endian_read_16(packet,2); 972 hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); 973 if (!hfp_connection) break; 974 if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 975 hfp_connection->state = HFP_IDLE; 976 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role); 977 break; 978 } 979 if ( hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED){ 980 // service connection was released, this implicitly releases audio connection as well 981 hfp_connection->release_audio_connection = 0; 982 hci_con_handle_t sco_handle = hfp_connection->sco_handle; 983 gap_disconnect(hfp_connection->sco_handle); 984 hfp_connection->state = HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN; 985 hfp_emit_audio_connection_released(hfp_connection, sco_handle); 986 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 987 } else { 988 // regular case 989 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 990 hfp_finalize_connection_context(hfp_connection); 991 } 992 break; 993 994 default: 995 break; 996 } 997 } 998 // translates command string into hfp_command_t CMD 999 1000 typedef struct { 1001 const char * command; 1002 hfp_command_t command_id; 1003 } hfp_command_entry_t; 1004 1005 static hfp_command_entry_t hfp_ag_commmand_table[] = { 1006 { "AT+BAC=", HFP_CMD_AVAILABLE_CODECS }, 1007 { "AT+BCC", HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP }, 1008 { "AT+BCS=", HFP_CMD_HF_CONFIRMED_CODEC }, 1009 { "AT+BIA=", HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, }, // +BIA:<enabled>,,<enabled>,,,<enabled> 1010 { "AT+BIEV=", HFP_CMD_HF_INDICATOR_STATUS }, 1011 { "AT+BIND=", HFP_CMD_LIST_GENERIC_STATUS_INDICATORS }, 1012 { "AT+BIND=?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS }, 1013 { "AT+BIND?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE }, 1014 { "AT+BINP=", HFP_CMD_HF_REQUEST_PHONE_NUMBER }, 1015 { "AT+BLDN", HFP_CMD_REDIAL_LAST_NUMBER }, 1016 { "AT+BRSF=", HFP_CMD_SUPPORTED_FEATURES }, 1017 { "AT+BTRH=", HFP_CMD_RESPONSE_AND_HOLD_COMMAND }, 1018 { "AT+BTRH?", HFP_CMD_RESPONSE_AND_HOLD_QUERY }, 1019 { "AT+BVRA=", HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION }, 1020 { "AT+CCWA=", HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION}, 1021 { "AT+CHLD=", HFP_CMD_CALL_HOLD }, 1022 { "AT+CHLD=?", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES }, 1023 { "AT+CHUP", HFP_CMD_HANG_UP_CALL }, 1024 { "AT+CIND=?", HFP_CMD_RETRIEVE_AG_INDICATORS }, 1025 { "AT+CIND?", HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS }, 1026 { "AT+CLCC", HFP_CMD_LIST_CURRENT_CALLS }, 1027 { "AT+CLIP=", HFP_CMD_ENABLE_CLIP}, 1028 { "AT+CMEE=", HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR}, 1029 { "AT+CMER=", HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE }, 1030 { "AT+CNUM", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION }, 1031 { "AT+COPS=", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT }, 1032 { "AT+COPS?", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME }, 1033 { "AT+NREC=", HFP_CMD_TURN_OFF_EC_AND_NR, }, 1034 { "AT+VGM=", HFP_CMD_SET_MICROPHONE_GAIN }, 1035 { "AT+VGS=", HFP_CMD_SET_SPEAKER_GAIN }, 1036 { "AT+VTS=", HFP_CMD_TRANSMIT_DTMF_CODES }, 1037 { "ATA", HFP_CMD_CALL_ANSWERED }, 1038 }; 1039 1040 static hfp_command_entry_t hfp_hf_commmand_table[] = { 1041 { "+BCS:", HFP_CMD_AG_SUGGESTED_CODEC }, 1042 { "+BIND:", HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS }, 1043 { "+BINP", HFP_CMD_AG_SENT_PHONE_NUMBER }, 1044 { "+BRSF:", HFP_CMD_SUPPORTED_FEATURES }, 1045 { "+BSIR:", HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING }, 1046 { "+BTRH:", HFP_CMD_RESPONSE_AND_HOLD_STATUS }, 1047 { "+BVRA:", HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION }, 1048 { "+CCWA:", HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, }, 1049 { "+CHLD:", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES }, 1050 { "+CIEV:", HFP_CMD_TRANSFER_AG_INDICATOR_STATUS}, 1051 { "+CIND:", HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC }, 1052 { "+CLCC:", HFP_CMD_LIST_CURRENT_CALLS }, 1053 { "+CLIP:", HFP_CMD_AG_SENT_CLIP_INFORMATION }, 1054 { "+CME ERROR:", HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR }, 1055 { "+CNUM:", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION}, 1056 { "+COPS:", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME }, 1057 { "+VGM:", HFP_CMD_SET_MICROPHONE_GAIN }, 1058 { "+VGS:", HFP_CMD_SET_SPEAKER_GAIN}, 1059 { "ERROR", HFP_CMD_ERROR}, 1060 { "NOP", HFP_CMD_NONE}, // dummy command used by unit tests 1061 { "OK", HFP_CMD_OK }, 1062 { "RING", HFP_CMD_RING }, 1063 }; 1064 1065 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ 1066 1067 // table lookup based on role 1068 uint16_t num_entries; 1069 hfp_command_entry_t * table; 1070 if (isHandsFree == 0){ 1071 table = hfp_ag_commmand_table; 1072 num_entries = sizeof(hfp_ag_commmand_table) / sizeof(hfp_command_entry_t); 1073 } else { 1074 table = hfp_hf_commmand_table; 1075 num_entries = sizeof(hfp_hf_commmand_table) / sizeof(hfp_command_entry_t); 1076 } 1077 // binary search 1078 uint16_t left = 0; 1079 uint16_t right = num_entries - 1; 1080 while (left <= right){ 1081 uint16_t middle = left + (right - left) / 2; 1082 hfp_command_entry_t *entry = &table[middle]; 1083 int match = strcmp(line_buffer, entry->command); 1084 if (match < 0){ 1085 // search term is lower than middle element 1086 if (right == 0) break; 1087 right = middle - 1; 1088 } else if (match == 0){ 1089 return entry->command_id; 1090 } else { 1091 // search term is higher than middle element 1092 left = middle + 1; 1093 } 1094 } 1095 1096 // note: if parser in CMD_HEADER state would treats digits and maybe '+' as separator, match on "ATD" would work. 1097 // note: phone number is currently expected in line_buffer[3..] 1098 // prefix match on 'ATD', AG only 1099 if ((isHandsFree == 0) && (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0)){ 1100 return HFP_CMD_CALL_PHONE_NUMBER; 1101 } 1102 1103 // Valid looking, but unknown commands/responses 1104 if ((isHandsFree == 0) && (strncmp(line_buffer, "AT+", 3) == 0)){ 1105 return HFP_CMD_UNKNOWN; 1106 } 1107 1108 if ((isHandsFree != 0) && (strncmp(line_buffer, "+", 1) == 0)){ 1109 return HFP_CMD_UNKNOWN; 1110 } 1111 1112 return HFP_CMD_NONE; 1113 } 1114 1115 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){ 1116 if ((hfp_connection->line_size + 1 ) >= HFP_MAX_INDICATOR_DESC_SIZE) return; 1117 hfp_connection->line_buffer[hfp_connection->line_size++] = byte; 1118 hfp_connection->line_buffer[hfp_connection->line_size] = 0; 1119 } 1120 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){ 1121 return hfp_connection->line_size == 0; 1122 } 1123 1124 static int hfp_parser_is_end_of_line(uint8_t byte){ 1125 return (byte == '\n') || (byte == '\r'); 1126 } 1127 1128 static void hfp_parser_reset_line_buffer(hfp_connection_t *hfp_connection) { 1129 hfp_connection->line_size = 0; 1130 } 1131 1132 static void hfp_parser_store_if_token(hfp_connection_t * hfp_connection, uint8_t byte){ 1133 switch (byte){ 1134 case ',': 1135 case '-': 1136 case ';': 1137 case '(': 1138 case ')': 1139 case '\n': 1140 case '\r': 1141 break; 1142 default: 1143 hfp_parser_store_byte(hfp_connection, byte); 1144 break; 1145 } 1146 } 1147 1148 static bool hfp_parser_is_separator( uint8_t byte){ 1149 switch (byte){ 1150 case ',': 1151 case '-': 1152 case ';': 1153 case '\n': 1154 case '\r': 1155 return true; 1156 default: 1157 return false; 1158 } 1159 } 1160 1161 static bool hfp_parse_byte(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){ 1162 1163 // handle doubles quotes 1164 if (byte == '"'){ 1165 hfp_connection->parser_quoted = !hfp_connection->parser_quoted; 1166 return true; 1167 } 1168 if (hfp_connection->parser_quoted) { 1169 hfp_parser_store_byte(hfp_connection, byte); 1170 return true; 1171 } 1172 1173 // ignore spaces outside command or double quotes (required e.g. for '+CME ERROR:..") command 1174 if ((byte == ' ') && (hfp_connection->parser_state != HFP_PARSER_CMD_HEADER)) return true; 1175 1176 bool processed = true; 1177 1178 switch (hfp_connection->parser_state) { 1179 case HFP_PARSER_CMD_HEADER: 1180 switch (byte) { 1181 case '\n': 1182 case '\r': 1183 case ';': 1184 // ignore separator 1185 break; 1186 case ':': 1187 case '?': 1188 // store separator 1189 hfp_parser_store_byte(hfp_connection, byte); 1190 break; 1191 case '=': 1192 // equal sign: remember and wait for next char to decided between '=?' and '=\?' 1193 hfp_connection->found_equal_sign = true; 1194 hfp_parser_store_byte(hfp_connection, byte); 1195 return true; 1196 default: 1197 // store if not lookahead 1198 if (!hfp_connection->found_equal_sign) { 1199 hfp_parser_store_byte(hfp_connection, byte); 1200 return true; 1201 } 1202 // mark as lookahead 1203 processed = false; 1204 break; 1205 } 1206 1207 // ignore empty tokens 1208 if (hfp_parser_is_buffer_empty(hfp_connection)) return true; 1209 1210 // parse 1211 hfp_connection->command = parse_command((char *)hfp_connection->line_buffer, isHandsFree); 1212 1213 // pick +CIND version based on connection state: descriptions during SLC vs. states later 1214 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC){ 1215 switch(hfp_connection->state){ 1216 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1217 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 1218 break; 1219 case HFP_W4_RETRIEVE_INDICATORS: 1220 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS; 1221 break; 1222 default: 1223 hfp_connection->command = HFP_CMD_UNKNOWN; 1224 break; 1225 } 1226 } 1227 1228 log_info("command string '%s', handsfree %u -> cmd id %u", (char *)hfp_connection->line_buffer, isHandsFree, hfp_connection->command); 1229 1230 // next state 1231 hfp_connection->found_equal_sign = false; 1232 hfp_parser_reset_line_buffer(hfp_connection); 1233 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 1234 1235 return processed; 1236 1237 case HFP_PARSER_CMD_SEQUENCE: 1238 // handle empty fields 1239 if ((byte == ',' ) && (hfp_connection->line_size == 0)){ 1240 hfp_connection->line_buffer[0] = 0; 1241 hfp_connection->ignore_value = 1; 1242 parse_sequence(hfp_connection); 1243 return true; 1244 } 1245 1246 hfp_parser_store_if_token(hfp_connection, byte); 1247 if (!hfp_parser_is_separator(byte)) return true; 1248 1249 // ignore empty tokens 1250 if (hfp_parser_is_buffer_empty(hfp_connection) && (hfp_connection->ignore_value == 0)) return true; 1251 1252 parse_sequence(hfp_connection); 1253 1254 hfp_parser_reset_line_buffer(hfp_connection); 1255 1256 switch (hfp_connection->command){ 1257 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1258 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1259 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1260 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1261 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1262 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1263 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1264 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1265 case HFP_CMD_HF_INDICATOR_STATUS: 1266 hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM; 1267 break; 1268 default: 1269 break; 1270 } 1271 return true; 1272 1273 case HFP_PARSER_SECOND_ITEM: 1274 1275 hfp_parser_store_if_token(hfp_connection, byte); 1276 if (!hfp_parser_is_separator(byte)) return true; 1277 1278 switch (hfp_connection->command){ 1279 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1280 log_info("format %s, ", hfp_connection->line_buffer); 1281 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1282 break; 1283 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1284 log_info("format %s \n", hfp_connection->line_buffer); 1285 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1286 break; 1287 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1288 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1289 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1290 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1291 break; 1292 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1293 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1294 log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status); 1295 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1; 1296 break; 1297 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1298 hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer); 1299 log_info("%s, ", hfp_connection->line_buffer); 1300 break; 1301 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1302 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1303 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1304 hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1305 break; 1306 case HFP_CMD_HF_INDICATOR_STATUS: 1307 hfp_connection->parser_indicator_value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1308 break; 1309 default: 1310 break; 1311 } 1312 1313 hfp_parser_reset_line_buffer(hfp_connection); 1314 1315 hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM; 1316 1317 return true; 1318 1319 case HFP_PARSER_THIRD_ITEM: 1320 1321 hfp_parser_store_if_token(hfp_connection, byte); 1322 if (!hfp_parser_is_separator(byte)) return true; 1323 1324 switch (hfp_connection->command){ 1325 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1326 strncpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE); 1327 hfp_connection->network_operator.name[HFP_MAX_NETWORK_OPERATOR_NAME_SIZE - 1] = 0; 1328 log_info("name %s\n", hfp_connection->line_buffer); 1329 break; 1330 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1331 hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer); 1332 hfp_next_indicators_index(hfp_connection); 1333 hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index; 1334 log_info("%s)\n", hfp_connection->line_buffer); 1335 break; 1336 default: 1337 break; 1338 } 1339 1340 hfp_parser_reset_line_buffer(hfp_connection); 1341 1342 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ 1343 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 1344 } else { 1345 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 1346 } 1347 return true; 1348 1349 default: 1350 btstack_assert(false); 1351 return true; 1352 } 1353 } 1354 1355 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){ 1356 bool processed = false; 1357 while (!processed){ 1358 processed = hfp_parse_byte(hfp_connection, byte, isHandsFree); 1359 } 1360 // reset parser state on end-of-line 1361 if (hfp_parser_is_end_of_line(byte)){ 1362 hfp_connection->parser_item_index = 0; 1363 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 1364 } 1365 } 1366 1367 static void parse_sequence(hfp_connection_t * hfp_connection){ 1368 int value; 1369 switch (hfp_connection->command){ 1370 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: 1371 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1372 int i; 1373 switch (hfp_connection->parser_item_index){ 1374 case 0: 1375 for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){ 1376 if (hfp_connection->generic_status_indicators[i].uuid == value){ 1377 hfp_connection->parser_indicator_index = i; 1378 break; 1379 } 1380 } 1381 break; 1382 case 1: 1383 if (hfp_connection->parser_indicator_index <0) break; 1384 hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value; 1385 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", 1386 hfp_connection->parser_item_index, value); 1387 break; 1388 default: 1389 break; 1390 } 1391 hfp_next_indicators_index(hfp_connection); 1392 break; 1393 1394 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1395 switch(hfp_connection->parser_item_index){ 1396 case 0: 1397 // <alpha>: This optional field is not supported, and shall be left blank. 1398 break; 1399 case 1: 1400 // <number>: Quoted string containing the phone number in the format specified by <type>. 1401 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1402 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1403 break; 1404 case 2: 1405 /* 1406 <type> field specifies the format of the phone number provided, and can be one of the following values: 1407 - values 128-143: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required. 1408 - values 144-159: The phone number format is an international number, including the country code prefix. If the plus sign ("+") is not included as part of the number and shall be added by the AG as needed. 1409 - values 160-175: National number. No prefix nor escape digits included. 1410 */ 1411 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1412 hfp_connection->bnip_type = value; 1413 break; 1414 case 3: 1415 // <speed>: This optional field is not supported, and shall be left blank. 1416 break; 1417 case 4: 1418 // <service>: Indicates which service this phone number relates to. Shall be either 4 (voice) or 5 (fax). 1419 default: 1420 break; 1421 } 1422 // index > 2 are ignored in switch above 1423 hfp_connection->parser_item_index++; 1424 break; 1425 case HFP_CMD_LIST_CURRENT_CALLS: 1426 switch(hfp_connection->parser_item_index){ 1427 case 0: 1428 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1429 hfp_connection->clcc_idx = value; 1430 break; 1431 case 1: 1432 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1433 hfp_connection->clcc_dir = value; 1434 break; 1435 case 2: 1436 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1437 hfp_connection->clcc_status = value; 1438 break; 1439 case 3: 1440 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1441 hfp_connection->clcc_mode = value; 1442 break; 1443 case 4: 1444 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1445 hfp_connection->clcc_mpty = value; 1446 break; 1447 case 5: 1448 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1449 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1450 break; 1451 case 6: 1452 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1453 hfp_connection->bnip_type = value; 1454 break; 1455 default: 1456 break; 1457 } 1458 // index > 6 are ignored in switch above 1459 hfp_connection->parser_item_index++; 1460 break; 1461 case HFP_CMD_SET_MICROPHONE_GAIN: 1462 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1463 hfp_connection->microphone_gain = value; 1464 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); 1465 break; 1466 case HFP_CMD_SET_SPEAKER_GAIN: 1467 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1468 hfp_connection->speaker_gain = value; 1469 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); 1470 break; 1471 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: 1472 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1473 hfp_connection->ag_activate_voice_recognition = value; 1474 log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); 1475 break; 1476 case HFP_CMD_TURN_OFF_EC_AND_NR: 1477 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1478 hfp_connection->ag_echo_and_noise_reduction = value; 1479 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); 1480 break; 1481 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1482 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1483 hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); 1484 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); 1485 break; 1486 case HFP_CMD_HF_CONFIRMED_CODEC: 1487 hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer); 1488 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed); 1489 break; 1490 case HFP_CMD_AG_SUGGESTED_CODEC: 1491 hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer); 1492 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec); 1493 break; 1494 case HFP_CMD_SUPPORTED_FEATURES: 1495 hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer); 1496 log_info("Parsed supported feature %d\n", (int) hfp_connection->remote_supported_features); 1497 break; 1498 case HFP_CMD_AVAILABLE_CODECS: 1499 log_info("Parsed codec %s\n", hfp_connection->line_buffer); 1500 hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1501 hfp_next_codec_index(hfp_connection); 1502 hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index; 1503 break; 1504 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1505 strncpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, (char *)hfp_connection->line_buffer, HFP_MAX_INDICATOR_DESC_SIZE); 1506 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name[HFP_MAX_INDICATOR_DESC_SIZE-1] = 0; 1507 hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1; 1508 log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer); 1509 break; 1510 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1511 log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer); 1512 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer); 1513 hfp_next_indicators_index(hfp_connection); 1514 break; 1515 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 1516 hfp_next_indicators_index(hfp_connection); 1517 if (hfp_connection->parser_item_index != 4) break; 1518 log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer); 1519 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1520 hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value; 1521 break; 1522 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 1523 log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer); 1524 if (hfp_connection->line_size > 2 ) break; 1525 memcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE-1); 1526 hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name[HFP_CALL_SERVICE_SIZE - 1] = 0; 1527 hfp_next_remote_call_services_index(hfp_connection); 1528 break; 1529 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1530 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1531 log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer); 1532 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1533 hfp_next_indicators_index(hfp_connection); 1534 hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index; 1535 break; 1536 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1537 // HF parses inital AG gen. ind. state 1538 log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer); 1539 hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection); 1540 break; 1541 case HFP_CMD_HF_INDICATOR_STATUS: 1542 hfp_connection->parser_indicator_index = hfp_parse_indicator_index(hfp_connection); 1543 log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index); 1544 break; 1545 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 1546 // AG parses new gen. ind. state 1547 if (hfp_connection->ignore_value){ 1548 hfp_connection->ignore_value = 0; 1549 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index, 1550 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled); 1551 } 1552 else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){ 1553 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", 1554 hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name); 1555 } else { 1556 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1557 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value; 1558 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index, 1559 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value); 1560 } 1561 hfp_next_indicators_index(hfp_connection); 1562 break; 1563 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1564 // indicators are indexed starting with 1 1565 hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection); 1566 log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index); 1567 break; 1568 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1569 hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1570 log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode); 1571 break; 1572 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1573 if (hfp_connection->line_buffer[0] == '3'){ 1574 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer); 1575 break; 1576 } 1577 // TODO emit ERROR, wrong format 1578 log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer); 1579 break; 1580 case HFP_CMD_ERROR: 1581 break; 1582 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1583 hfp_connection->extended_audio_gateway_error = 1; 1584 hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1585 break; 1586 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 1587 hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1588 hfp_connection->ok_pending = 1; 1589 hfp_connection->extended_audio_gateway_error = 0; 1590 break; 1591 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1592 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1593 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1594 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1595 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1596 break; 1597 case HFP_CMD_CALL_HOLD: 1598 hfp_connection->ag_call_hold_action = hfp_connection->line_buffer[0] - '0'; 1599 if (hfp_connection->line_buffer[1] != '\0'){ 1600 hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]); 1601 } 1602 break; 1603 case HFP_CMD_RESPONSE_AND_HOLD_COMMAND: 1604 hfp_connection->ag_response_and_hold_action = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1605 break; 1606 case HFP_CMD_TRANSMIT_DTMF_CODES: 1607 hfp_connection->ag_dtmf_code = hfp_connection->line_buffer[0]; 1608 break; 1609 case HFP_CMD_ENABLE_CLIP: 1610 hfp_connection->clip_enabled = hfp_connection->line_buffer[0] != '0'; 1611 break; 1612 case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION: 1613 hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[0] != '0'; 1614 break; 1615 case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION: 1616 switch(hfp_connection->parser_item_index){ 1617 case 0: 1618 hfp_connection->ag_vra_status = (hfp_voice_recognition_activation_status_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1619 break; 1620 case 1: 1621 hfp_connection->ag_vra_state = (hfp_voice_recognition_state_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1622 hfp_emit_enhanced_voice_recognition_state(hfp_connection); 1623 break; 1624 case 2: 1625 hfp_connection->ag_msg.text_id = 0; 1626 for (i = 0 ; i < 4; i++){ 1627 hfp_connection->ag_msg.text_id = (hfp_connection->ag_msg.text_id << 4) | nibble_for_char(hfp_connection->line_buffer[i]); 1628 } 1629 break; 1630 case 3: 1631 hfp_connection->ag_msg.text_operation = (hfp_text_operation_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1632 break; 1633 case 4: 1634 hfp_connection->ag_msg.text_type = (hfp_text_type_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1635 break; 1636 case 5: 1637 hfp_emit_enhanced_voice_recognition_text(hfp_connection, hfp_connection->line_size, &hfp_connection->line_buffer[0]); 1638 break; 1639 default: 1640 break; 1641 } 1642 break; 1643 default: 1644 break; 1645 } 1646 } 1647 1648 static void hfp_handle_start_sdp_client_query(void * context){ 1649 UNUSED(context); 1650 1651 btstack_linked_list_iterator_t it; 1652 btstack_linked_list_iterator_init(&it, &hfp_connections); 1653 while (btstack_linked_list_iterator_has_next(&it)){ 1654 hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 1655 1656 if (connection->state != HFP_W2_SEND_SDP_QUERY) continue; 1657 1658 connection->state = HFP_W4_SDP_QUERY_COMPLETE; 1659 sdp_query_context.local_role = connection->local_role; 1660 (void)memcpy(sdp_query_context.remote_address, connection->remote_addr, 6); 1661 sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(&handle_query_rfcomm_event, connection->remote_addr, connection->service_uuid); 1662 return; 1663 } 1664 } 1665 1666 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){ 1667 hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr, local_role); 1668 log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection); 1669 1670 if (!hfp_connection) { 1671 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1672 return; 1673 } 1674 switch (hfp_connection->state){ 1675 case HFP_W2_DISCONNECT_RFCOMM: 1676 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1677 return; 1678 case HFP_W4_RFCOMM_DISCONNECTED: 1679 hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1680 return; 1681 case HFP_IDLE: 1682 (void)memcpy(hfp_connection->remote_addr, bd_addr, 6); 1683 hfp_connection->state = HFP_W2_SEND_SDP_QUERY; 1684 hfp_connection->service_uuid = service_uuid; 1685 1686 hfp_handle_sdp_client_query_request.callback = &hfp_handle_start_sdp_client_query; 1687 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback 1688 (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request); 1689 break; 1690 default: 1691 break; 1692 } 1693 } 1694 1695 void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){ 1696 if (!hfp_connection) return; 1697 hfp_release_audio_connection(hfp_connection); 1698 1699 if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){ 1700 hfp_connection->state = HFP_IDLE; 1701 return; 1702 } 1703 1704 if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){ 1705 hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1706 return; 1707 } 1708 1709 if (hfp_connection->state < HFP_W4_SCO_CONNECTED){ 1710 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 1711 return; 1712 } 1713 1714 if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){ 1715 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 1716 return; 1717 } 1718 1719 // HFP_W4_SCO_DISCONNECTED or later 1720 hfp_connection->release_slc_connection = 1; 1721 } 1722 1723 void hfp_release_audio_connection(hfp_connection_t * hfp_connection){ 1724 if (!hfp_connection) return; 1725 if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; 1726 hfp_connection->release_audio_connection = 1; 1727 } 1728 1729 static const struct link_settings { 1730 const uint16_t max_latency; 1731 const uint8_t retransmission_effort; 1732 const uint16_t packet_types; 1733 const bool eSCO; 1734 const uint8_t codec; 1735 } hfp_link_settings [] = { 1736 { 0xffff, 0xff, SCO_PACKET_TYPES_HV1, false, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_D0 1737 { 0xffff, 0xff, SCO_PACKET_TYPES_HV3, false, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_D1 1738 { 0x0007, 0x01, SCO_PACKET_TYPES_EV3, true, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S1 1739 { 0x0007, 0x01, SCO_PACKET_TYPES_2EV3, true, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S2 1740 { 0x000a, 0x01, SCO_PACKET_TYPES_2EV3, true, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S3 1741 { 0x000c, 0x02, SCO_PACKET_TYPES_2EV3, true, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S4 1742 { 0x0008, 0x02, SCO_PACKET_TYPES_EV3, true, HFP_CODEC_MSBC }, // HFP_LINK_SETTINGS_T1 1743 { 0x000d, 0x02, SCO_PACKET_TYPES_2EV3, true, HFP_CODEC_MSBC } // HFP_LINK_SETTINGS_T2 1744 }; 1745 1746 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){ 1747 // all packet types, fixed bandwidth 1748 int setting = hfp_connection->link_setting; 1749 log_info("hfp_setup_synchronous_connection using setting nr %u", setting); 1750 sco_establishment_active = hfp_connection; 1751 uint16_t sco_voice_setting = hci_get_sco_voice_setting(); 1752 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1753 #ifdef ENABLE_BCM_PCM_WBS 1754 sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers 1755 #else 1756 sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise 1757 #endif 1758 } 1759 // get packet types - bits 6-9 are 'don't allow' 1760 uint16_t packet_types = hfp_link_settings[setting].packet_types ^ 0x03c0; 1761 hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency, 1762 sco_voice_setting, hfp_link_settings[setting].retransmission_effort, packet_types); 1763 } 1764 1765 void hfp_accept_synchronous_connection(hfp_connection_t * hfp_connection, bool incoming_eSCO){ 1766 1767 // remote supported feature eSCO is set if link type is eSCO 1768 // eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms, 1769 uint16_t max_latency; 1770 uint8_t retransmission_effort; 1771 uint16_t packet_types; 1772 1773 if (incoming_eSCO && hci_extended_sco_link_supported() && hci_remote_esco_supported(hfp_connection->acl_handle)){ 1774 max_latency = 0x000c; 1775 retransmission_effort = 0x02; 1776 // eSCO: EV3 and 2-EV3 1777 packet_types = 0x0048; 1778 } else { 1779 max_latency = 0xffff; 1780 retransmission_effort = 0xff; 1781 // sco: HV1 and HV3 1782 packet_types = 0x005; 1783 } 1784 1785 // mSBC only allows for transparent data 1786 uint16_t sco_voice_setting = hci_get_sco_voice_setting(); 1787 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1788 #ifdef ENABLE_BCM_PCM_WBS 1789 sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers 1790 #else 1791 sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise 1792 #endif 1793 } 1794 1795 // filter packet types 1796 packet_types &= hfp_get_sco_packet_types(); 1797 1798 // bits 6-9 are 'don't allow' 1799 packet_types ^= 0x3c0; 1800 1801 log_info("HFP: sending hci_accept_connection_request, packet types 0x%04x, sco_voice_setting 0x%02x", packet_types, sco_voice_setting); 1802 hci_send_cmd(&hci_accept_synchronous_connection, hfp_connection->remote_addr, 8000, 8000, max_latency, 1803 sco_voice_setting, retransmission_effort, packet_types); 1804 } 1805 1806 #ifdef ENABLE_CC256X_ASSISTED_HFP 1807 void hfp_cc256x_prepare_for_sco(hfp_connection_t * hfp_connection){ 1808 hfp_connection->cc256x_send_write_codec_config = true; 1809 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1810 hfp_connection->cc256x_send_wbs_associate = true; 1811 } 1812 } 1813 1814 void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){ 1815 uint32_t sample_rate_hz; 1816 uint16_t clock_rate_khz; 1817 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1818 clock_rate_khz = 512; 1819 sample_rate_hz = 16000; 1820 } else { 1821 clock_rate_khz = 256; 1822 sample_rate_hz = 8000; 1823 } 1824 uint8_t clock_direction = 0; // master 1825 uint16_t frame_sync_duty_cycle = 0; // i2s with 50% 1826 uint8_t frame_sync_edge = 1; // rising edge 1827 uint8_t frame_sync_polarity = 0; // active high 1828 uint8_t reserved = 0; 1829 uint16_t size = 16; 1830 uint16_t chan_1_offset = 1; 1831 uint16_t chan_2_offset = chan_1_offset + size; 1832 uint8_t out_edge = 1; // rising 1833 uint8_t in_edge = 0; // falling 1834 hci_send_cmd(&hci_ti_write_codec_config, clock_rate_khz, clock_direction, sample_rate_hz, frame_sync_duty_cycle, 1835 frame_sync_edge, frame_sync_polarity, reserved, 1836 size, chan_1_offset, out_edge, size, chan_1_offset, in_edge, reserved, 1837 size, chan_2_offset, out_edge, size, chan_2_offset, in_edge, reserved); 1838 } 1839 #endif 1840 1841 #ifdef ENABLE_BCM_PCM_WBS 1842 void hfp_bcm_prepare_for_sco(hfp_connection_t * hfp_connection){ 1843 hfp_connection->bcm_send_write_i2spcm_interface_param = true; 1844 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1845 hfp_connection->bcm_send_enable_wbs = true; 1846 } 1847 } 1848 void hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection){ 1849 uint8_t sample_rate = (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? 1 : 0; 1850 // i2s enable, master, 8/16 kHz, 512 kHz 1851 hci_send_cmd(&hci_bcm_write_i2spcm_interface_paramhci_bcm_write_i2spcm_interface_param, 1, 1, sample_rate, 2); 1852 } 1853 #endif 1854 1855 void hfp_set_hf_callback(btstack_packet_handler_t callback){ 1856 hfp_hf_callback = callback; 1857 } 1858 1859 void hfp_set_ag_callback(btstack_packet_handler_t callback){ 1860 hfp_ag_callback = callback; 1861 } 1862 1863 void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler){ 1864 hfp_ag_rfcomm_packet_handler = handler; 1865 } 1866 1867 void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler){ 1868 hfp_hf_rfcomm_packet_handler = handler; 1869 } 1870 1871 void hfp_init(void){ 1872 hfp_allowed_sco_packet_types = SCO_PACKET_TYPES_ALL; 1873 } 1874 1875 void hfp_deinit(void){ 1876 hfp_connections = NULL; 1877 hfp_hf_callback = NULL; 1878 hfp_ag_callback = NULL; 1879 hfp_hf_rfcomm_packet_handler = NULL; 1880 hfp_ag_rfcomm_packet_handler = NULL; 1881 sco_establishment_active = NULL; 1882 (void) memset(&sdp_query_context, 0, sizeof(hfp_sdp_query_context_t)); 1883 (void) memset(&hfp_handle_sdp_client_query_request, 0, sizeof(btstack_context_callback_registration_t)); 1884 } 1885 1886 void hfp_set_sco_packet_types(uint16_t packet_types){ 1887 hfp_allowed_sco_packet_types = packet_types; 1888 } 1889 1890 uint16_t hfp_get_sco_packet_types(void){ 1891 return hfp_allowed_sco_packet_types; 1892 } 1893 1894 hfp_link_settings_t hfp_next_link_setting(hfp_link_settings_t current_setting, bool local_eSCO_supported, bool remote_eSCO_supported, bool eSCO_S4_supported, uint8_t negotiated_codec){ 1895 int8_t setting = (int8_t) current_setting; 1896 bool can_use_eSCO = local_eSCO_supported && remote_eSCO_supported; 1897 while (setting > 0){ 1898 setting--; 1899 // skip if eSCO required but not available 1900 if (hfp_link_settings[setting].eSCO && !can_use_eSCO) continue; 1901 // skip if S4 but not supported 1902 if ((setting == (int8_t) HFP_LINK_SETTINGS_S4) && !eSCO_S4_supported) continue; 1903 // skip wrong codec 1904 if ( hfp_link_settings[setting].codec != negotiated_codec) continue; 1905 // skip disabled packet types 1906 uint16_t required_packet_types = hfp_link_settings[setting].packet_types; 1907 uint16_t allowed_packet_types = hfp_allowed_sco_packet_types; 1908 if ((required_packet_types & allowed_packet_types) == 0) continue; 1909 1910 // found matching setting 1911 return (hfp_link_settings_t) setting; 1912 } 1913 return HFP_LINK_SETTINGS_NONE; 1914 } 1915 1916 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){ 1917 bool local_eSCO_supported = hci_extended_sco_link_supported(); 1918 bool remote_eSCO_supported = hci_remote_esco_supported(hfp_connection->acl_handle); 1919 uint8_t negotiated_codec = hfp_connection->negotiated_codec; 1920 return hfp_next_link_setting(current_setting, local_eSCO_supported, remote_eSCO_supported, eSCO_S4_supported, negotiated_codec); 1921 } 1922 1923 void hfp_init_link_settings(hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){ 1924 // get highest possible link setting 1925 hfp_connection->link_setting = hfp_next_link_setting_for_connection(HFP_LINK_SETTINGS_NONE, hfp_connection, eSCO_S4_supported); 1926 log_info("hfp_init_link_settings: %u", hfp_connection->link_setting); 1927 } 1928 1929 #define HFP_HF_RX_DEBUG_PRINT_LINE 80 1930 1931 void hfp_log_rfcomm_message(const char * tag, uint8_t * packet, uint16_t size){ 1932 #ifdef ENABLE_LOG_INFO 1933 // encode \n\r 1934 char printable[HFP_HF_RX_DEBUG_PRINT_LINE+2]; 1935 int i = 0; 1936 int pos; 1937 for (pos=0 ; (pos < size) && (i < (HFP_HF_RX_DEBUG_PRINT_LINE - 3)) ; pos++){ 1938 switch (packet[pos]){ 1939 case '\n': 1940 printable[i++] = '\\'; 1941 printable[i++] = 'n'; 1942 break; 1943 case '\r': 1944 printable[i++] = '\\'; 1945 printable[i++] = 'r'; 1946 break; 1947 default: 1948 printable[i++] = packet[pos]; 1949 break; 1950 } 1951 } 1952 printable[i] = 0; 1953 log_info("%s: '%s'", tag, printable); 1954 #endif 1955 } 1956