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