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