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 39 #include "btstack_config.h" 40 41 #include <stdint.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <inttypes.h> 46 47 #include "btstack_debug.h" 48 #include "btstack_event.h" 49 #include "btstack_memory.h" 50 #include "btstack_run_loop.h" 51 #include "classic/core.h" 52 #include "classic/sdp_client_rfcomm.h" 53 #include "classic/sdp_server.h" 54 #include "classic/sdp_util.h" 55 #include "hci.h" 56 #include "hci_cmd.h" 57 #include "hci_dump.h" 58 #include "l2cap.h" 59 60 #define HFP_HF_FEATURES_SIZE 10 61 #define HFP_AG_FEATURES_SIZE 12 62 63 64 static const char * hfp_hf_features[] = { 65 "EC and/or NR function", 66 "Three-way calling", 67 "CLI presentation capability", 68 "Voice recognition activation", 69 "Remote volume control", 70 71 "Enhanced call status", 72 "Enhanced call control", 73 74 "Codec negotiation", 75 76 "HF Indicators", 77 "eSCO S4 (and T2) Settings Supported", 78 "Reserved for future definition" 79 }; 80 81 static const char * hfp_ag_features[] = { 82 "Three-way calling", 83 "EC and/or NR function", 84 "Voice recognition function", 85 "In-band ring tone capability", 86 "Attach a number to a voice tag", 87 "Ability to reject a call", 88 "Enhanced call status", 89 "Enhanced call control", 90 "Extended Error Result Codes", 91 "Codec negotiation", 92 "HF Indicators", 93 "eSCO S4 (and T2) Settings Supported", 94 "Reserved for future definition" 95 }; 96 97 static btstack_linked_list_t hfp_connections = NULL; 98 static void parse_sequence(hfp_connection_t * context); 99 static btstack_packet_handler_t hfp_callback; 100 static btstack_packet_handler_t rfcomm_packet_handler; 101 102 static hfp_connection_t * sco_establishment_active; 103 104 void hfp_set_callback(btstack_packet_handler_t callback){ 105 hfp_callback = callback; 106 } 107 108 const char * hfp_hf_feature(int index){ 109 if (index > HFP_HF_FEATURES_SIZE){ 110 return hfp_hf_features[HFP_HF_FEATURES_SIZE]; 111 } 112 return hfp_hf_features[index]; 113 } 114 115 const char * hfp_ag_feature(int index){ 116 if (index > HFP_AG_FEATURES_SIZE){ 117 return hfp_ag_features[HFP_AG_FEATURES_SIZE]; 118 } 119 return hfp_ag_features[index]; 120 } 121 122 int send_str_over_rfcomm(uint16_t cid, char * command){ 123 if (!rfcomm_can_send_packet_now(cid)) return 1; 124 log_info("HFP_TX %s", command); 125 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command)); 126 if (err){ 127 log_error("rfcomm_send -> error 0x%02x \n", err); 128 } 129 return 1; 130 } 131 132 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){ 133 134 // mSBC requires support for eSCO connections 135 if (codec == HFP_CODEC_MSBC && !hci_extended_sco_link_supported()) return 0; 136 137 int i; 138 for (i = 0; i < codecs_nr; i++){ 139 if (codecs[i] != codec) continue; 140 return 1; 141 } 142 return 0; 143 } 144 145 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){ 146 if (hci_extended_sco_link_supported()) return; 147 uint8_t tmp_codecs[HFP_MAX_NUM_CODECS]; 148 int i; 149 int tmp_codec_nr = 0; 150 for (i=0; i < *codecs_nr; i++){ 151 if (codecs[i] == HFP_CODEC_MSBC) continue; 152 tmp_codecs[tmp_codec_nr++] = codecs[i]; 153 } 154 *codecs_nr = tmp_codec_nr; 155 memcpy(codecs, tmp_codecs, tmp_codec_nr); 156 } 157 158 // UTILS 159 int get_bit(uint16_t bitmap, int position){ 160 return (bitmap >> position) & 1; 161 } 162 163 int store_bit(uint32_t bitmap, int position, uint8_t value){ 164 if (value){ 165 bitmap |= 1 << position; 166 } else { 167 bitmap &= ~ (1 << position); 168 } 169 return bitmap; 170 } 171 172 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ 173 if (buffer_size < values_nr * 3) return 0; 174 int i; 175 int offset = 0; 176 for (i = 0; i < values_nr-1; i++) { 177 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer 178 } 179 if (i<values_nr){ 180 offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]); 181 } 182 return offset; 183 } 184 185 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){ 186 if (buffer_size < values_nr * 3) return 0; 187 188 int i; 189 int offset = 0; 190 for (i = 0; i < values_nr-1; i++) { 191 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer 192 } 193 194 if (i<values_nr){ 195 offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i)); 196 } 197 return offset; 198 } 199 200 void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subtype){ 201 if (!callback) return; 202 uint8_t event[3]; 203 event[0] = HCI_EVENT_HFP_META; 204 event[1] = sizeof(event) - 2; 205 event[2] = event_subtype; 206 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 207 } 208 209 void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value){ 210 if (!callback) return; 211 uint8_t event[4]; 212 event[0] = HCI_EVENT_HFP_META; 213 event[1] = sizeof(event) - 2; 214 event[2] = event_subtype; 215 event[3] = value; // status 0 == OK 216 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 217 } 218 219 void hfp_emit_slc_connection_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){ 220 if (!callback) return; 221 uint8_t event[12]; 222 int pos = 0; 223 event[pos++] = HCI_EVENT_HFP_META; 224 event[pos++] = sizeof(event) - 2; 225 event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 226 event[pos++] = status; // status 0 == OK 227 little_endian_store_16(event, pos, con_handle); 228 pos += 2; 229 reverse_bd_addr(addr,&event[pos]); 230 pos += 6; 231 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 232 } 233 234 static void hfp_emit_sco_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t negotiated_codec){ 235 if (!callback) return; 236 uint8_t event[13]; 237 int pos = 0; 238 event[pos++] = HCI_EVENT_HFP_META; 239 event[pos++] = sizeof(event) - 2; 240 event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED; 241 event[pos++] = status; // status 0 == OK 242 little_endian_store_16(event, pos, con_handle); 243 pos += 2; 244 reverse_bd_addr(addr,&event[pos]); 245 pos += 6; 246 event[pos++] = negotiated_codec; 247 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 248 } 249 250 void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subtype, const char * value){ 251 if (!callback) return; 252 uint8_t event[40]; 253 event[0] = HCI_EVENT_HFP_META; 254 event[1] = sizeof(event) - 2; 255 event[2] = event_subtype; 256 int size = (strlen(value) < sizeof(event) - 4) ? (int) strlen(value) : sizeof(event) - 4; 257 strncpy((char*)&event[3], value, size); 258 event[3 + size] = 0; 259 (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 260 } 261 262 btstack_linked_list_t * hfp_get_connections(void){ 263 return (btstack_linked_list_t *) &hfp_connections; 264 } 265 266 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){ 267 btstack_linked_list_iterator_t it; 268 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 269 while (btstack_linked_list_iterator_has_next(&it)){ 270 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 271 if (hfp_connection->rfcomm_cid == cid){ 272 return hfp_connection; 273 } 274 } 275 return NULL; 276 } 277 278 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ 279 btstack_linked_list_iterator_t it; 280 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 281 while (btstack_linked_list_iterator_has_next(&it)){ 282 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 283 if (memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) { 284 return hfp_connection; 285 } 286 } 287 return NULL; 288 } 289 290 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle){ 291 btstack_linked_list_iterator_t it; 292 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 293 while (btstack_linked_list_iterator_has_next(&it)){ 294 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 295 if (hfp_connection->sco_handle == handle){ 296 return hfp_connection; 297 } 298 } 299 return NULL; 300 } 301 302 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle){ 303 btstack_linked_list_iterator_t it; 304 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 305 while (btstack_linked_list_iterator_has_next(&it)){ 306 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); 307 if (hfp_connection->acl_handle == handle){ 308 return hfp_connection; 309 } 310 } 311 return NULL; 312 } 313 314 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){ 315 if (!hfp_connection) return; 316 hfp_connection->ok_pending = 0; 317 hfp_connection->send_error = 0; 318 319 hfp_connection->keep_byte = 0; 320 321 hfp_connection->change_status_update_for_individual_ag_indicators = 0; 322 hfp_connection->operator_name_changed = 0; 323 324 hfp_connection->enable_extended_audio_gateway_error_report = 0; 325 hfp_connection->extended_audio_gateway_error = 0; 326 327 // establish codecs hfp_connection 328 hfp_connection->suggested_codec = 0; 329 hfp_connection->negotiated_codec = 0; 330 hfp_connection->codec_confirmed = 0; 331 332 hfp_connection->establish_audio_connection = 0; 333 hfp_connection->call_waiting_notification_enabled = 0; 334 hfp_connection->command = HFP_CMD_NONE; 335 hfp_connection->enable_status_update_for_ag_indicators = 0xFF; 336 } 337 338 static hfp_connection_t * create_hfp_connection_context(void){ 339 hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get(); 340 if (!hfp_connection) return NULL; 341 // init state 342 memset(hfp_connection,0, sizeof(hfp_connection_t)); 343 344 hfp_connection->state = HFP_IDLE; 345 hfp_connection->call_state = HFP_CALL_IDLE; 346 hfp_connection->codecs_state = HFP_CODECS_IDLE; 347 348 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 349 hfp_connection->command = HFP_CMD_NONE; 350 351 hfp_reset_context_flags(hfp_connection); 352 353 btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection); 354 return hfp_connection; 355 } 356 357 static void remove_hfp_connection_context(hfp_connection_t * hfp_connection){ 358 btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection); 359 } 360 361 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ 362 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); 363 if (hfp_connection) return hfp_connection; 364 hfp_connection = create_hfp_connection_context(); 365 memcpy(hfp_connection->remote_addr, bd_addr, 6); 366 return hfp_connection; 367 } 368 369 /* @param network. 370 * 0 == no ability to reject a call. 371 * 1 == ability to reject a call. 372 */ 373 374 /* @param suported_features 375 * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no) 376 * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no) 377 * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no) 378 * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no) 379 * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no) 380 * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 381 */ 382 /* Bit position: 383 * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no) 384 * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no) 385 * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no) 386 * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no) 387 * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no) 388 * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 389 */ 390 391 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){ 392 uint8_t* attribute; 393 de_create_sequence(service); 394 395 // 0x0000 "Service Record Handle" 396 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle); 397 de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 398 399 // 0x0001 "Service Class ID List" 400 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList); 401 attribute = de_push_sequence(service); 402 { 403 // "UUID for Service" 404 de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid); 405 de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_GenericAudio); 406 } 407 de_pop_sequence(service, attribute); 408 409 // 0x0004 "Protocol Descriptor List" 410 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ProtocolDescriptorList); 411 attribute = de_push_sequence(service); 412 { 413 uint8_t* l2cpProtocol = de_push_sequence(attribute); 414 { 415 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, SDP_L2CAPProtocol); 416 } 417 de_pop_sequence(attribute, l2cpProtocol); 418 419 uint8_t* rfcomm = de_push_sequence(attribute); 420 { 421 de_add_number(rfcomm, DE_UUID, DE_SIZE_16, SDP_RFCOMMProtocol); // rfcomm_service 422 de_add_number(rfcomm, DE_UINT, DE_SIZE_8, rfcomm_channel_nr); // rfcomm channel 423 } 424 de_pop_sequence(attribute, rfcomm); 425 } 426 de_pop_sequence(service, attribute); 427 428 429 // 0x0005 "Public Browse Group" 430 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList); // public browse group 431 attribute = de_push_sequence(service); 432 { 433 de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_PublicBrowseGroup); 434 } 435 de_pop_sequence(service, attribute); 436 437 // 0x0009 "Bluetooth Profile Descriptor List" 438 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_BluetoothProfileDescriptorList); 439 attribute = de_push_sequence(service); 440 { 441 uint8_t *sppProfile = de_push_sequence(attribute); 442 { 443 de_add_number(sppProfile, DE_UUID, DE_SIZE_16, SDP_Handsfree); 444 de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7 445 } 446 de_pop_sequence(attribute, sppProfile); 447 } 448 de_pop_sequence(service, attribute); 449 450 // 0x0100 "Service Name" 451 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 452 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name); 453 } 454 455 static hfp_connection_t * connection_doing_sdp_query = NULL; 456 457 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 458 UNUSED(packet_type); 459 UNUSED(channel); 460 UNUSED(size); 461 462 hfp_connection_t * hfp_connection = connection_doing_sdp_query; 463 464 if ( hfp_connection->state != HFP_W4_SDP_QUERY_COMPLETE) return; 465 466 switch (hci_event_packet_get_type(packet)){ 467 case SDP_EVENT_QUERY_RFCOMM_SERVICE: 468 if (!hfp_connection) { 469 log_error("handle_query_rfcomm_event alloc connection for RFCOMM port %u failed", sdp_event_query_rfcomm_service_get_rfcomm_channel(packet)); 470 return; 471 } 472 hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet); 473 break; 474 case SDP_EVENT_QUERY_COMPLETE: 475 connection_doing_sdp_query = NULL; 476 if (hfp_connection->rfcomm_channel_nr > 0){ 477 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; 478 log_info("HFP: SDP_EVENT_QUERY_COMPLETE context %p, addr %s, state %d", hfp_connection, bd_addr_to_str( hfp_connection->remote_addr), hfp_connection->state); 479 rfcomm_create_channel(rfcomm_packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL); 480 break; 481 } 482 log_info("rfcomm service not found, status %u.", sdp_event_query_complete_get_status(packet)); 483 break; 484 default: 485 break; 486 } 487 } 488 489 static void hfp_handle_failed_sco_connection(uint8_t status){ 490 491 if (!sco_establishment_active){ 492 log_error("(e)SCO Connection failed but not started by us"); 493 return; 494 } 495 log_error("(e)SCO Connection failed status 0x%02x", status); 496 497 // invalid params / unspecified error 498 if (status != 0x11 && status != 0x1f) return; 499 500 switch (sco_establishment_active->link_setting){ 501 case HFP_LINK_SETTINGS_D0: 502 return; // no other option left 503 case HFP_LINK_SETTINGS_D1: 504 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D0; 505 break; 506 case HFP_LINK_SETTINGS_S1: 507 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1; 508 break; 509 case HFP_LINK_SETTINGS_S2: 510 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S1; 511 break; 512 case HFP_LINK_SETTINGS_S3: 513 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S2; 514 break; 515 case HFP_LINK_SETTINGS_S4: 516 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S3; 517 break; 518 case HFP_LINK_SETTINGS_T1: 519 log_info("T1 failed, fallback to CVSD - D1"); 520 sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD; 521 sco_establishment_active->sco_for_msbc_failed = 1; 522 sco_establishment_active->command = HFP_CMD_AG_SEND_COMMON_CODEC; 523 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1; 524 break; 525 case HFP_LINK_SETTINGS_T2: 526 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_T1; 527 break; 528 } 529 sco_establishment_active->establish_audio_connection = 1; 530 sco_establishment_active = 0; 531 } 532 533 534 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 535 UNUSED(channel); 536 537 bd_addr_t event_addr; 538 uint16_t rfcomm_cid, handle; 539 hfp_connection_t * hfp_connection = NULL; 540 uint8_t status; 541 542 log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size); 543 544 switch (hci_event_packet_get_type(packet)) { 545 case HCI_EVENT_CONNECTION_REQUEST: 546 // printf("hfp HCI_EVENT_CONNECTION_REQUEST\n"); 547 switch(hci_event_connection_request_get_link_type(packet)){ 548 case 0: // SCO 549 case 2: // eSCO 550 hci_event_connection_request_get_bd_addr(packet, event_addr); 551 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 552 if (!hfp_connection) break; 553 hfp_connection->hf_accept_sco = 1; 554 break; 555 default: 556 break; 557 } 558 break; 559 560 case RFCOMM_EVENT_INCOMING_CONNECTION: 561 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 562 rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 563 hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr); 564 if (!hfp_connection){ 565 log_info("hfp: no memory to accept incoming connection - decline"); 566 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet)); 567 return; 568 } 569 if (hfp_connection->state != HFP_IDLE) { 570 log_error("hfp: incoming connection but state != HFP_IDLE"); 571 return; 572 } 573 574 hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 575 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; 576 // printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr)); 577 rfcomm_accept_connection(hfp_connection->rfcomm_cid); 578 break; 579 580 case RFCOMM_EVENT_CHANNEL_OPENED: 581 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) 582 583 rfcomm_event_channel_opened_get_bd_addr(packet, event_addr); 584 status = rfcomm_event_channel_opened_get_status(packet); 585 586 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 587 if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return; 588 589 if (status) { 590 hfp_emit_slc_connection_event(hfp_callback, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr); 591 remove_hfp_connection_context(hfp_connection); 592 } else { 593 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet); 594 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet); 595 bd_addr_copy(hfp_connection->remote_addr, event_addr); 596 // uint16_t mtu = rfcomm_event_channel_opened_get_max_frame_size(packet); 597 // printf("RFCOMM channel open succeeded. hfp_connection %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", hfp_connection, hfp_connection->rfcomm_cid, mtu); 598 599 switch (hfp_connection->state){ 600 case HFP_W4_RFCOMM_CONNECTED: 601 hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES; 602 break; 603 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN: 604 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 605 // printf("Shutting down RFCOMM.\n"); 606 break; 607 default: 608 break; 609 } 610 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid); 611 } 612 break; 613 614 case HCI_EVENT_COMMAND_STATUS: 615 if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) { 616 status = hci_event_command_status_get_status(packet); 617 if (status) { 618 hfp_handle_failed_sco_connection(hci_event_command_status_get_status(packet)); 619 } 620 } 621 break; 622 623 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ 624 hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr); 625 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 626 if (!hfp_connection) { 627 log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr)); 628 return; 629 } 630 631 status = hci_event_synchronous_connection_complete_get_status(packet); 632 if (status != 0){ 633 hfp_connection->hf_accept_sco = 0; 634 hfp_handle_failed_sco_connection(status); 635 break; 636 } 637 638 uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet); 639 uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet); 640 uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots 641 uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots 642 uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes 643 uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes 644 uint8_t air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet); 645 646 switch (link_type){ 647 case 0x00: 648 log_info("SCO Connection established."); 649 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); 650 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); 651 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); 652 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); 653 break; 654 case 0x02: 655 log_info("eSCO Connection established. \n"); 656 break; 657 default: 658 log_error("(e)SCO reserved link_type 0x%2x", link_type); 659 break; 660 } 661 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 662 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle, 663 bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode); 664 665 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 666 667 if (!hfp_connection) { 668 log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr)); 669 break; 670 } 671 672 if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ 673 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN"); 674 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 675 break; 676 } 677 hfp_connection->sco_handle = sco_handle; 678 hfp_connection->establish_audio_connection = 0; 679 hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED; 680 hfp_emit_sco_event(hfp_callback, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec); 681 break; 682 } 683 684 case RFCOMM_EVENT_CHANNEL_CLOSED: 685 rfcomm_cid = little_endian_read_16(packet,2); 686 hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); 687 if (!hfp_connection) break; 688 if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 689 hfp_connection->state = HFP_IDLE; 690 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid); 691 break; 692 } 693 694 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 695 remove_hfp_connection_context(hfp_connection); 696 break; 697 698 case HCI_EVENT_DISCONNECTION_COMPLETE: 699 handle = little_endian_read_16(packet,3); 700 hfp_connection = get_hfp_connection_context_for_sco_handle(handle); 701 702 if (!hfp_connection) break; 703 704 if (hfp_connection->state != HFP_W4_SCO_DISCONNECTED){ 705 log_info("Received gap disconnect in wrong hfp state"); 706 } 707 log_info("Check SCO handle: incoming 0x%02x, hfp_connection 0x%02x\n", handle, hfp_connection->sco_handle); 708 709 if (handle == hfp_connection->sco_handle){ 710 log_info("SCO disconnected, w2 disconnect RFCOMM\n"); 711 hfp_connection->sco_handle = 0; 712 hfp_connection->release_audio_connection = 0; 713 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 714 hfp_emit_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0); 715 break; 716 } 717 break; 718 719 default: 720 break; 721 } 722 } 723 724 // translates command string into hfp_command_t CMD 725 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ 726 int offset = isHandsFree ? 0 : 2; 727 728 if (strncmp(line_buffer+offset, HFP_LIST_CURRENT_CALLS, strlen(HFP_LIST_CURRENT_CALLS)) == 0){ 729 return HFP_CMD_LIST_CURRENT_CALLS; 730 } 731 732 if (strncmp(line_buffer+offset, HFP_SUBSCRIBER_NUMBER_INFORMATION, strlen(HFP_SUBSCRIBER_NUMBER_INFORMATION)) == 0){ 733 return HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION; 734 } 735 736 if (strncmp(line_buffer+offset, HFP_PHONE_NUMBER_FOR_VOICE_TAG, strlen(HFP_PHONE_NUMBER_FOR_VOICE_TAG)) == 0){ 737 if (isHandsFree) return HFP_CMD_AG_SENT_PHONE_NUMBER; 738 return HFP_CMD_HF_REQUEST_PHONE_NUMBER; 739 } 740 741 if (strncmp(line_buffer+offset, HFP_TRANSMIT_DTMF_CODES, strlen(HFP_TRANSMIT_DTMF_CODES)) == 0){ 742 return HFP_CMD_TRANSMIT_DTMF_CODES; 743 } 744 745 if (strncmp(line_buffer+offset, HFP_SET_MICROPHONE_GAIN, strlen(HFP_SET_MICROPHONE_GAIN)) == 0){ 746 return HFP_CMD_SET_MICROPHONE_GAIN; 747 } 748 749 if (strncmp(line_buffer+offset, HFP_SET_SPEAKER_GAIN, strlen(HFP_SET_SPEAKER_GAIN)) == 0){ 750 return HFP_CMD_SET_SPEAKER_GAIN; 751 } 752 753 if (strncmp(line_buffer+offset, HFP_ACTIVATE_VOICE_RECOGNITION, strlen(HFP_ACTIVATE_VOICE_RECOGNITION)) == 0){ 754 if (isHandsFree) return HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; 755 return HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION; 756 } 757 758 if (strncmp(line_buffer+offset, HFP_TURN_OFF_EC_AND_NR, strlen(HFP_TURN_OFF_EC_AND_NR)) == 0){ 759 return HFP_CMD_TURN_OFF_EC_AND_NR; 760 } 761 762 if (strncmp(line_buffer, HFP_CALL_ANSWERED, strlen(HFP_CALL_ANSWERED)) == 0){ 763 return HFP_CMD_CALL_ANSWERED; 764 } 765 766 if (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 767 return HFP_CMD_CALL_PHONE_NUMBER; 768 } 769 770 if (strncmp(line_buffer+offset, HFP_REDIAL_LAST_NUMBER, strlen(HFP_REDIAL_LAST_NUMBER)) == 0){ 771 return HFP_CMD_REDIAL_LAST_NUMBER; 772 } 773 774 if (strncmp(line_buffer+offset, HFP_CHANGE_IN_BAND_RING_TONE_SETTING, strlen(HFP_CHANGE_IN_BAND_RING_TONE_SETTING)) == 0){ 775 return HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING; 776 } 777 778 if (strncmp(line_buffer+offset, HFP_HANG_UP_CALL, strlen(HFP_HANG_UP_CALL)) == 0){ 779 return HFP_CMD_HANG_UP_CALL; 780 } 781 782 if (strncmp(line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){ 783 return HFP_CMD_ERROR; 784 } 785 786 if (strncmp(line_buffer+offset, HFP_RING, strlen(HFP_RING)) == 0){ 787 return HFP_CMD_RING; 788 } 789 790 if (isHandsFree && strncmp(line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){ 791 return HFP_CMD_OK; 792 } 793 794 if (strncmp(line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ 795 return HFP_CMD_SUPPORTED_FEATURES; 796 } 797 798 if (strncmp(line_buffer+offset, HFP_TRANSFER_HF_INDICATOR_STATUS, strlen(HFP_TRANSFER_HF_INDICATOR_STATUS)) == 0){ 799 return HFP_CMD_HF_INDICATOR_STATUS; 800 } 801 802 if (strncmp(line_buffer+offset, HFP_RESPONSE_AND_HOLD, strlen(HFP_RESPONSE_AND_HOLD)) == 0){ 803 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "?", 1) == 0){ 804 return HFP_CMD_RESPONSE_AND_HOLD_QUERY; 805 } 806 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "=", 1) == 0){ 807 return HFP_CMD_RESPONSE_AND_HOLD_COMMAND; 808 } 809 return HFP_CMD_RESPONSE_AND_HOLD_STATUS; 810 } 811 812 if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ 813 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){ 814 return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 815 } 816 817 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "=?", 2) == 0){ 818 return HFP_CMD_RETRIEVE_AG_INDICATORS; 819 } 820 } 821 822 if (strncmp(line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ 823 return HFP_CMD_AVAILABLE_CODECS; 824 } 825 826 if (strncmp(line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){ 827 return HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; 828 } 829 830 if (strncmp(line_buffer+offset, HFP_ENABLE_CLIP, strlen(HFP_ENABLE_CLIP)) == 0){ 831 if (isHandsFree) return HFP_CMD_AG_SENT_CLIP_INFORMATION; 832 return HFP_CMD_ENABLE_CLIP; 833 } 834 835 if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){ 836 if (isHandsFree) return HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE; 837 return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION; 838 } 839 840 if (strncmp(line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ 841 842 if (isHandsFree) return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 843 844 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=?", 2) == 0){ 845 return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 846 } 847 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=", 1) == 0){ 848 return HFP_CMD_CALL_HOLD; 849 } 850 851 return HFP_CMD_UNKNOWN; 852 } 853 854 if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ 855 if (isHandsFree) { 856 return HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS; 857 } 858 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ 859 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 860 } 861 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ 862 return HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 863 } 864 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 865 } 866 867 if (strncmp(line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ 868 return HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; 869 } 870 871 872 if (strncmp(line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ 873 if (strncmp(line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){ 874 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT; 875 } 876 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; 877 } 878 879 if (strncmp(line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ 880 return HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; 881 } 882 883 if (isHandsFree && strncmp(line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 884 return HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; 885 } 886 887 if (!isHandsFree && strncmp(line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 888 return HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; 889 } 890 891 if (strncmp(line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){ 892 return HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; 893 } 894 895 if (strncmp(line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){ 896 if (isHandsFree){ 897 return HFP_CMD_AG_SUGGESTED_CODEC; 898 } else { 899 return HFP_CMD_HF_CONFIRMED_CODEC; 900 } 901 } 902 903 if (strncmp(line_buffer+offset, "AT+", 3) == 0){ 904 log_info("process unknown HF command %s \n", line_buffer); 905 return HFP_CMD_UNKNOWN; 906 } 907 908 if (strncmp(line_buffer+offset, "+", 1) == 0){ 909 log_info(" process unknown AG command %s \n", line_buffer); 910 return HFP_CMD_UNKNOWN; 911 } 912 913 if (strncmp(line_buffer+offset, "NOP", 3) == 0){ 914 return HFP_CMD_NONE; 915 } 916 917 return HFP_CMD_NONE; 918 } 919 920 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){ 921 // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, context->line_size); 922 // TODO: add limit 923 hfp_connection->line_buffer[hfp_connection->line_size++] = byte; 924 hfp_connection->line_buffer[hfp_connection->line_size] = 0; 925 } 926 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){ 927 return hfp_connection->line_size == 0; 928 } 929 930 static int hfp_parser_is_end_of_line(uint8_t byte){ 931 return byte == '\n' || byte == '\r'; 932 } 933 934 static int hfp_parser_is_end_of_header(uint8_t byte){ 935 return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; 936 } 937 938 static int hfp_parser_found_separator(hfp_connection_t * hfp_connection, uint8_t byte){ 939 if (hfp_connection->keep_byte == 1) return 1; 940 941 int found_separator = byte == ',' || byte == '\n'|| byte == '\r'|| 942 byte == ')' || byte == '(' || byte == ':' || 943 byte == '-' || byte == '"' || byte == '?'|| byte == '='; 944 return found_separator; 945 } 946 947 static void hfp_parser_next_state(hfp_connection_t * hfp_connection, uint8_t byte){ 948 hfp_connection->line_size = 0; 949 if (hfp_parser_is_end_of_line(byte)){ 950 hfp_connection->parser_item_index = 0; 951 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 952 return; 953 } 954 switch (hfp_connection->parser_state){ 955 case HFP_PARSER_CMD_HEADER: 956 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 957 if (hfp_connection->keep_byte == 1){ 958 hfp_parser_store_byte(hfp_connection, byte); 959 hfp_connection->keep_byte = 0; 960 } 961 break; 962 case HFP_PARSER_CMD_SEQUENCE: 963 switch (hfp_connection->command){ 964 case HFP_CMD_AG_SENT_PHONE_NUMBER: 965 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 966 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 967 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 968 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 969 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 970 case HFP_CMD_RETRIEVE_AG_INDICATORS: 971 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 972 case HFP_CMD_HF_INDICATOR_STATUS: 973 hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM; 974 break; 975 default: 976 break; 977 } 978 break; 979 case HFP_PARSER_SECOND_ITEM: 980 hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM; 981 break; 982 case HFP_PARSER_THIRD_ITEM: 983 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ 984 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 985 break; 986 } 987 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 988 break; 989 } 990 } 991 992 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){ 993 // handle ATD<dial_string>; 994 if (strncmp((const char*)hfp_connection->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 995 // check for end-of-line or ';' 996 if (byte == ';' || hfp_parser_is_end_of_line(byte)){ 997 hfp_connection->line_buffer[hfp_connection->line_size] = 0; 998 hfp_connection->line_size = 0; 999 hfp_connection->command = HFP_CMD_CALL_PHONE_NUMBER; 1000 } else { 1001 hfp_connection->line_buffer[hfp_connection->line_size++] = byte; 1002 } 1003 return; 1004 } 1005 1006 // TODO: handle space inside word 1007 if (byte == ' ' && hfp_connection->parser_state > HFP_PARSER_CMD_HEADER) return; 1008 1009 if (byte == ',' && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1010 if (hfp_connection->line_size == 0){ 1011 hfp_connection->line_buffer[0] = 0; 1012 hfp_connection->ignore_value = 1; 1013 parse_sequence(hfp_connection); 1014 return; 1015 } 1016 } 1017 1018 if (!hfp_parser_found_separator(hfp_connection, byte)){ 1019 hfp_parser_store_byte(hfp_connection, byte); 1020 return; 1021 } 1022 1023 if (hfp_parser_is_end_of_line(byte)) { 1024 if (hfp_parser_is_buffer_empty(hfp_connection)){ 1025 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 1026 } 1027 } 1028 if (hfp_parser_is_buffer_empty(hfp_connection)) return; 1029 1030 switch (hfp_connection->parser_state){ 1031 case HFP_PARSER_CMD_HEADER: // header 1032 if (byte == '='){ 1033 hfp_connection->keep_byte = 1; 1034 hfp_parser_store_byte(hfp_connection, byte); 1035 return; 1036 } 1037 1038 if (byte == '?'){ 1039 hfp_connection->keep_byte = 0; 1040 hfp_parser_store_byte(hfp_connection, byte); 1041 return; 1042 } 1043 1044 if (byte == ','){ 1045 hfp_connection->resolve_byte = 1; 1046 } 1047 1048 // printf(" parse header 2 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); 1049 if (hfp_parser_is_end_of_header(byte) || hfp_connection->keep_byte == 1){ 1050 // printf(" parse header 3 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); 1051 char * line_buffer = (char *)hfp_connection->line_buffer; 1052 hfp_connection->command = parse_command(line_buffer, isHandsFree); 1053 1054 /* resolve command name according to hfp_connection */ 1055 if (hfp_connection->command == HFP_CMD_UNKNOWN){ 1056 switch(hfp_connection->state){ 1057 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 1058 hfp_connection->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 1059 break; 1060 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 1061 hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 1062 break; 1063 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 1064 hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 1065 break; 1066 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1067 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 1068 break; 1069 case HFP_W4_RETRIEVE_INDICATORS: 1070 hfp_connection->send_ag_indicators_segment = 0; 1071 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS; 1072 break; 1073 default: 1074 break; 1075 } 1076 } 1077 } 1078 break; 1079 1080 case HFP_PARSER_CMD_SEQUENCE: 1081 parse_sequence(hfp_connection); 1082 break; 1083 case HFP_PARSER_SECOND_ITEM: 1084 switch (hfp_connection->command){ 1085 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1086 log_info("format %s, ", hfp_connection->line_buffer); 1087 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1088 break; 1089 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1090 log_info("format %s \n", hfp_connection->line_buffer); 1091 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1092 break; 1093 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1094 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1095 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1096 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1097 break; 1098 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1099 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1100 log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status); 1101 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1; 1102 break; 1103 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1104 hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer); 1105 log_info("%s, ", hfp_connection->line_buffer); 1106 break; 1107 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1108 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1109 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1110 hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1111 break; 1112 default: 1113 break; 1114 } 1115 break; 1116 1117 case HFP_PARSER_THIRD_ITEM: 1118 switch (hfp_connection->command){ 1119 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1120 strcpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer); 1121 log_info("name %s\n", hfp_connection->line_buffer); 1122 break; 1123 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1124 hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer); 1125 hfp_connection->parser_item_index++; 1126 hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index; 1127 log_info("%s)\n", hfp_connection->line_buffer); 1128 break; 1129 default: 1130 break; 1131 } 1132 break; 1133 } 1134 hfp_parser_next_state(hfp_connection, byte); 1135 1136 if (hfp_connection->resolve_byte && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1137 hfp_connection->resolve_byte = 0; 1138 hfp_connection->ignore_value = 1; 1139 parse_sequence(hfp_connection); 1140 hfp_connection->line_buffer[0] = 0; 1141 hfp_connection->line_size = 0; 1142 } 1143 } 1144 1145 static void parse_sequence(hfp_connection_t * hfp_connection){ 1146 int value; 1147 switch (hfp_connection->command){ 1148 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: 1149 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1150 int i; 1151 switch (hfp_connection->parser_item_index){ 1152 case 0: 1153 for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){ 1154 if (hfp_connection->generic_status_indicators[i].uuid == value){ 1155 hfp_connection->parser_indicator_index = i; 1156 break; 1157 } 1158 } 1159 break; 1160 case 1: 1161 if (hfp_connection->parser_indicator_index <0) break; 1162 hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value; 1163 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", 1164 hfp_connection->parser_item_index, value); 1165 break; 1166 default: 1167 break; 1168 } 1169 hfp_connection->parser_item_index++; 1170 break; 1171 1172 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1173 switch(hfp_connection->parser_item_index){ 1174 case 0: 1175 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1176 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1177 break; 1178 case 1: 1179 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1180 hfp_connection->bnip_type = value; 1181 break; 1182 default: 1183 break; 1184 } 1185 hfp_connection->parser_item_index++; 1186 break; 1187 case HFP_CMD_LIST_CURRENT_CALLS: 1188 switch(hfp_connection->parser_item_index){ 1189 case 0: 1190 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1191 hfp_connection->clcc_idx = value; 1192 break; 1193 case 1: 1194 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1195 hfp_connection->clcc_dir = value; 1196 break; 1197 case 2: 1198 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1199 hfp_connection->clcc_status = value; 1200 break; 1201 case 3: 1202 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1203 hfp_connection->clcc_mpty = value; 1204 break; 1205 case 4: 1206 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1207 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1208 break; 1209 case 5: 1210 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1211 hfp_connection->bnip_type = value; 1212 break; 1213 default: 1214 break; 1215 } 1216 hfp_connection->parser_item_index++; 1217 break; 1218 case HFP_CMD_SET_MICROPHONE_GAIN: 1219 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1220 hfp_connection->microphone_gain = value; 1221 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); 1222 break; 1223 case HFP_CMD_SET_SPEAKER_GAIN: 1224 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1225 hfp_connection->speaker_gain = value; 1226 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); 1227 break; 1228 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: 1229 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1230 hfp_connection->ag_activate_voice_recognition = value; 1231 log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); 1232 break; 1233 case HFP_CMD_TURN_OFF_EC_AND_NR: 1234 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1235 hfp_connection->ag_echo_and_noise_reduction = value; 1236 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); 1237 break; 1238 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1239 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1240 hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); 1241 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); 1242 break; 1243 case HFP_CMD_HF_CONFIRMED_CODEC: 1244 hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer); 1245 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed); 1246 break; 1247 case HFP_CMD_AG_SUGGESTED_CODEC: 1248 hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer); 1249 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec); 1250 break; 1251 case HFP_CMD_SUPPORTED_FEATURES: 1252 hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer); 1253 log_info("Parsed supported feature %d\n", hfp_connection->remote_supported_features); 1254 break; 1255 case HFP_CMD_AVAILABLE_CODECS: 1256 log_info("Parsed codec %s\n", hfp_connection->line_buffer); 1257 hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1258 hfp_connection->parser_item_index++; 1259 hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index; 1260 break; 1261 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1262 strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, (char *)hfp_connection->line_buffer); 1263 hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1; 1264 log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer); 1265 break; 1266 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1267 log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer); 1268 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer); 1269 hfp_connection->parser_item_index++; 1270 break; 1271 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 1272 hfp_connection->parser_item_index++; 1273 if (hfp_connection->parser_item_index != 4) break; 1274 log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer); 1275 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1276 hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value; 1277 break; 1278 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 1279 log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer); 1280 if (hfp_connection->line_size > 2 ) break; 1281 strcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name, (char *)hfp_connection->line_buffer); 1282 hfp_connection->remote_call_services_nr++; 1283 break; 1284 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1285 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1286 log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer); 1287 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1288 hfp_connection->parser_item_index++; 1289 hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index; 1290 break; 1291 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1292 // HF parses inital AG gen. ind. state 1293 log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer); 1294 hfp_connection->parser_item_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1295 break; 1296 case HFP_CMD_HF_INDICATOR_STATUS: 1297 hfp_connection->parser_indicator_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1298 log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index); 1299 break; 1300 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 1301 // AG parses new gen. ind. state 1302 if (hfp_connection->ignore_value){ 1303 hfp_connection->ignore_value = 0; 1304 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index, 1305 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled); 1306 } 1307 else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){ 1308 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", 1309 hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name); 1310 } else { 1311 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1312 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value; 1313 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index, 1314 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value); 1315 } 1316 hfp_connection->parser_item_index++; 1317 break; 1318 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1319 // indicators are indexed starting with 1 1320 hfp_connection->parser_item_index = btstack_atoi((char *)&hfp_connection->line_buffer[0]) - 1; 1321 log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index); 1322 break; 1323 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1324 hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1325 log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode); 1326 break; 1327 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1328 if (hfp_connection->line_buffer[0] == '3'){ 1329 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer); 1330 break; 1331 } 1332 // TODO emit ERROR, wrong format 1333 log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer); 1334 break; 1335 case HFP_CMD_ERROR: 1336 break; 1337 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1338 hfp_connection->extended_audio_gateway_error = 1; 1339 hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1340 break; 1341 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 1342 hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1343 hfp_connection->ok_pending = 1; 1344 hfp_connection->extended_audio_gateway_error = 0; 1345 break; 1346 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1347 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1348 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1349 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1350 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1351 break; 1352 default: 1353 break; 1354 } 1355 } 1356 1357 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ 1358 hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr); 1359 log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection); 1360 1361 if (!hfp_connection) { 1362 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1363 return; 1364 } 1365 1366 switch (hfp_connection->state){ 1367 case HFP_W2_DISCONNECT_RFCOMM: 1368 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1369 return; 1370 case HFP_W4_RFCOMM_DISCONNECTED: 1371 hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1372 return; 1373 case HFP_IDLE: 1374 memcpy(hfp_connection->remote_addr, bd_addr, 6); 1375 hfp_connection->state = HFP_W4_SDP_QUERY_COMPLETE; 1376 connection_doing_sdp_query = hfp_connection; 1377 hfp_connection->service_uuid = service_uuid; 1378 sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, hfp_connection->remote_addr, service_uuid); 1379 break; 1380 default: 1381 break; 1382 } 1383 } 1384 1385 void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){ 1386 if (!hfp_connection) return; 1387 hfp_release_audio_connection(hfp_connection); 1388 1389 if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){ 1390 hfp_connection->state = HFP_IDLE; 1391 return; 1392 } 1393 1394 if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){ 1395 hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1396 return; 1397 } 1398 1399 if (hfp_connection->state < HFP_W4_SCO_CONNECTED){ 1400 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 1401 return; 1402 } 1403 1404 if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){ 1405 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 1406 return; 1407 } 1408 1409 return; 1410 } 1411 1412 void hfp_release_audio_connection(hfp_connection_t * hfp_connection){ 1413 if (!hfp_connection) return; 1414 if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; 1415 hfp_connection->release_audio_connection = 1; 1416 } 1417 1418 static const struct link_settings { 1419 const uint16_t max_latency; 1420 const uint8_t retransmission_effort; 1421 const uint16_t packet_types; 1422 } hfp_link_settings [] = { 1423 { 0xffff, 0xff, 0x03c1 }, // HFP_LINK_SETTINGS_D0, HV1 1424 { 0xffff, 0xff, 0x03c4 }, // HFP_LINK_SETTINGS_D1, HV3 1425 { 0x0007, 0x01, 0x03c8 }, // HFP_LINK_SETTINGS_S1, EV3 1426 { 0x0007, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S2, 2-EV3 1427 { 0x000a, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S3, 2-EV3 1428 { 0x000c, 0x02, 0x0380 }, // HFP_LINK_SETTINGS_S4, 2-EV3 1429 { 0x0008, 0x02, 0x03c8 }, // HFP_LINK_SETTINGS_T1, EV3 1430 { 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3 1431 }; 1432 1433 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){ 1434 // all packet types, fixed bandwidth 1435 int setting = hfp_connection->link_setting; 1436 log_info("hfp_setup_synchronous_connection using setting nr %u", setting); 1437 sco_establishment_active = hfp_connection; 1438 uint16_t sco_voice_setting = hci_get_sco_voice_setting(); 1439 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1440 sco_voice_setting = 0x0043; // Transparent data 1441 } 1442 hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency, 1443 sco_voice_setting, hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380 1444 } 1445 1446 void hfp_set_packet_handler_for_rfcomm_connections(btstack_packet_handler_t handler){ 1447 rfcomm_packet_handler = handler; 1448 } 1449 1450