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) : (int) 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 btstack_memory_hfp_connection_free(hfp_connection); 363 } 364 365 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ 366 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr); 367 if (hfp_connection) return hfp_connection; 368 hfp_connection = create_hfp_connection_context(); 369 memcpy(hfp_connection->remote_addr, bd_addr, 6); 370 return hfp_connection; 371 } 372 373 /* @param network. 374 * 0 == no ability to reject a call. 375 * 1 == ability to reject a call. 376 */ 377 378 /* @param suported_features 379 * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no) 380 * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no) 381 * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no) 382 * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no) 383 * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no) 384 * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 385 */ 386 /* Bit position: 387 * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no) 388 * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no) 389 * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no) 390 * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no) 391 * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no) 392 * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 393 */ 394 395 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){ 396 uint8_t* attribute; 397 de_create_sequence(service); 398 399 // 0x0000 "Service Record Handle" 400 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE); 401 de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 402 403 // 0x0001 "Service Class ID List" 404 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST); 405 attribute = de_push_sequence(service); 406 { 407 // "UUID for Service" 408 de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid); 409 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO); 410 } 411 de_pop_sequence(service, attribute); 412 413 // 0x0004 "Protocol Descriptor List" 414 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 415 attribute = de_push_sequence(service); 416 { 417 uint8_t* l2cpProtocol = de_push_sequence(attribute); 418 { 419 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 420 } 421 de_pop_sequence(attribute, l2cpProtocol); 422 423 uint8_t* rfcomm = de_push_sequence(attribute); 424 { 425 de_add_number(rfcomm, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM); // rfcomm_service 426 de_add_number(rfcomm, DE_UINT, DE_SIZE_8, rfcomm_channel_nr); // rfcomm channel 427 } 428 de_pop_sequence(attribute, rfcomm); 429 } 430 de_pop_sequence(service, attribute); 431 432 433 // 0x0005 "Public Browse Group" 434 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group 435 attribute = de_push_sequence(service); 436 { 437 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT); 438 } 439 de_pop_sequence(service, attribute); 440 441 // 0x0009 "Bluetooth Profile Descriptor List" 442 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); 443 attribute = de_push_sequence(service); 444 { 445 uint8_t *sppProfile = de_push_sequence(attribute); 446 { 447 de_add_number(sppProfile, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HANDSFREE); 448 de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7 449 } 450 de_pop_sequence(attribute, sppProfile); 451 } 452 de_pop_sequence(service, attribute); 453 454 // 0x0100 "Service Name" 455 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 456 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name); 457 } 458 459 static hfp_connection_t * connection_doing_sdp_query = NULL; 460 461 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 462 UNUSED(packet_type); // ok: handling own sdp events 463 UNUSED(channel); // ok: no channel 464 UNUSED(size); // ok: handling own sdp events 465 466 hfp_connection_t * hfp_connection = connection_doing_sdp_query; 467 if (!hfp_connection) { 468 log_error("handle_query_rfcomm_event, no connection"); 469 return; 470 } 471 472 switch (hci_event_packet_get_type(packet)){ 473 case SDP_EVENT_QUERY_RFCOMM_SERVICE: 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 hfp_connection->state = HFP_IDLE; 485 hfp_emit_slc_connection_event(hfp_callback, sdp_event_query_complete_get_status(packet), HCI_CON_HANDLE_INVALID, hfp_connection->remote_addr); 486 log_info("rfcomm service not found, status %u.", sdp_event_query_complete_get_status(packet)); 487 break; 488 default: 489 break; 490 } 491 } 492 493 static void hfp_handle_failed_sco_connection(uint8_t status){ 494 495 if (!sco_establishment_active){ 496 log_error("(e)SCO Connection failed but not started by us"); 497 return; 498 } 499 log_error("(e)SCO Connection failed status 0x%02x", status); 500 501 // invalid params / unspecified error 502 if (status != 0x11 && status != 0x1f) return; 503 504 switch (sco_establishment_active->link_setting){ 505 case HFP_LINK_SETTINGS_D0: 506 return; // no other option left 507 case HFP_LINK_SETTINGS_D1: 508 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D0; 509 break; 510 case HFP_LINK_SETTINGS_S1: 511 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1; 512 break; 513 case HFP_LINK_SETTINGS_S2: 514 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S1; 515 break; 516 case HFP_LINK_SETTINGS_S3: 517 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S2; 518 break; 519 case HFP_LINK_SETTINGS_S4: 520 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S3; 521 break; 522 case HFP_LINK_SETTINGS_T1: 523 log_info("T1 failed, fallback to CVSD - D1"); 524 sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD; 525 sco_establishment_active->sco_for_msbc_failed = 1; 526 sco_establishment_active->command = HFP_CMD_AG_SEND_COMMON_CODEC; 527 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1; 528 break; 529 case HFP_LINK_SETTINGS_T2: 530 sco_establishment_active->link_setting = HFP_LINK_SETTINGS_T1; 531 break; 532 } 533 sco_establishment_active->establish_audio_connection = 1; 534 sco_establishment_active = 0; 535 } 536 537 538 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 539 UNUSED(channel); // ok: no channel 540 541 bd_addr_t event_addr; 542 uint16_t rfcomm_cid, handle; 543 hfp_connection_t * hfp_connection = NULL; 544 uint8_t status; 545 546 log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size); 547 548 switch (hci_event_packet_get_type(packet)) { 549 case HCI_EVENT_CONNECTION_REQUEST: 550 // printf("hfp HCI_EVENT_CONNECTION_REQUEST\n"); 551 switch(hci_event_connection_request_get_link_type(packet)){ 552 case 0: // SCO 553 case 2: // eSCO 554 hci_event_connection_request_get_bd_addr(packet, event_addr); 555 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 556 if (!hfp_connection) break; 557 hfp_connection->hf_accept_sco = 1; 558 break; 559 default: 560 break; 561 } 562 break; 563 564 case RFCOMM_EVENT_INCOMING_CONNECTION: 565 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 566 rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 567 hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr); 568 if (!hfp_connection){ 569 log_info("hfp: no memory to accept incoming connection - decline"); 570 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet)); 571 return; 572 } 573 if (hfp_connection->state != HFP_IDLE) { 574 log_error("hfp: incoming connection but state != HFP_IDLE"); 575 return; 576 } 577 578 hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 579 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED; 580 // printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr)); 581 rfcomm_accept_connection(hfp_connection->rfcomm_cid); 582 break; 583 584 case RFCOMM_EVENT_CHANNEL_OPENED: 585 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) 586 587 rfcomm_event_channel_opened_get_bd_addr(packet, event_addr); 588 status = rfcomm_event_channel_opened_get_status(packet); 589 590 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 591 if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return; 592 593 if (status) { 594 hfp_emit_slc_connection_event(hfp_callback, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr); 595 remove_hfp_connection_context(hfp_connection); 596 } else { 597 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet); 598 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet); 599 bd_addr_copy(hfp_connection->remote_addr, event_addr); 600 // uint16_t mtu = rfcomm_event_channel_opened_get_max_frame_size(packet); 601 // 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); 602 603 switch (hfp_connection->state){ 604 case HFP_W4_RFCOMM_CONNECTED: 605 hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES; 606 break; 607 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN: 608 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 609 // printf("Shutting down RFCOMM.\n"); 610 break; 611 default: 612 break; 613 } 614 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid); 615 } 616 break; 617 618 case HCI_EVENT_COMMAND_STATUS: 619 if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) { 620 status = hci_event_command_status_get_status(packet); 621 if (status) { 622 hfp_handle_failed_sco_connection(hci_event_command_status_get_status(packet)); 623 } 624 } 625 break; 626 627 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ 628 hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr); 629 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 630 if (!hfp_connection) { 631 log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr)); 632 return; 633 } 634 635 status = hci_event_synchronous_connection_complete_get_status(packet); 636 if (status != 0){ 637 hfp_connection->hf_accept_sco = 0; 638 hfp_handle_failed_sco_connection(status); 639 break; 640 } 641 642 uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet); 643 uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet); 644 uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots 645 uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots 646 uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes 647 uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes 648 uint8_t air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet); 649 650 switch (link_type){ 651 case 0x00: 652 log_info("SCO Connection established."); 653 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); 654 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); 655 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); 656 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); 657 break; 658 case 0x02: 659 log_info("eSCO Connection established. \n"); 660 break; 661 default: 662 log_error("(e)SCO reserved link_type 0x%2x", link_type); 663 break; 664 } 665 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 666 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle, 667 bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode); 668 669 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr); 670 671 if (!hfp_connection) { 672 log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr)); 673 break; 674 } 675 676 if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ 677 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN"); 678 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 679 break; 680 } 681 hfp_connection->sco_handle = sco_handle; 682 hfp_connection->establish_audio_connection = 0; 683 hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED; 684 hfp_emit_sco_event(hfp_callback, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec); 685 break; 686 } 687 688 case RFCOMM_EVENT_CHANNEL_CLOSED: 689 rfcomm_cid = little_endian_read_16(packet,2); 690 hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); 691 if (!hfp_connection) break; 692 if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 693 hfp_connection->state = HFP_IDLE; 694 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid); 695 break; 696 } 697 698 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 699 remove_hfp_connection_context(hfp_connection); 700 break; 701 702 case HCI_EVENT_DISCONNECTION_COMPLETE: 703 handle = little_endian_read_16(packet,3); 704 hfp_connection = get_hfp_connection_context_for_sco_handle(handle); 705 706 if (!hfp_connection) break; 707 708 if (hfp_connection->state != HFP_W4_SCO_DISCONNECTED){ 709 log_info("Received gap disconnect in wrong hfp state"); 710 } 711 log_info("Check SCO handle: incoming 0x%02x, hfp_connection 0x%02x\n", handle, hfp_connection->sco_handle); 712 713 if (handle == hfp_connection->sco_handle){ 714 log_info("SCO disconnected, w2 disconnect RFCOMM\n"); 715 hfp_connection->sco_handle = 0; 716 hfp_connection->release_audio_connection = 0; 717 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 718 hfp_emit_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0); 719 break; 720 } 721 break; 722 723 default: 724 break; 725 } 726 } 727 728 // translates command string into hfp_command_t CMD 729 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ 730 int offset = isHandsFree ? 0 : 2; 731 732 if (strncmp(line_buffer+offset, HFP_LIST_CURRENT_CALLS, strlen(HFP_LIST_CURRENT_CALLS)) == 0){ 733 return HFP_CMD_LIST_CURRENT_CALLS; 734 } 735 736 if (strncmp(line_buffer+offset, HFP_SUBSCRIBER_NUMBER_INFORMATION, strlen(HFP_SUBSCRIBER_NUMBER_INFORMATION)) == 0){ 737 return HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION; 738 } 739 740 if (strncmp(line_buffer+offset, HFP_PHONE_NUMBER_FOR_VOICE_TAG, strlen(HFP_PHONE_NUMBER_FOR_VOICE_TAG)) == 0){ 741 if (isHandsFree) return HFP_CMD_AG_SENT_PHONE_NUMBER; 742 return HFP_CMD_HF_REQUEST_PHONE_NUMBER; 743 } 744 745 if (strncmp(line_buffer+offset, HFP_TRANSMIT_DTMF_CODES, strlen(HFP_TRANSMIT_DTMF_CODES)) == 0){ 746 return HFP_CMD_TRANSMIT_DTMF_CODES; 747 } 748 749 if (strncmp(line_buffer+offset, HFP_SET_MICROPHONE_GAIN, strlen(HFP_SET_MICROPHONE_GAIN)) == 0){ 750 return HFP_CMD_SET_MICROPHONE_GAIN; 751 } 752 753 if (strncmp(line_buffer+offset, HFP_SET_SPEAKER_GAIN, strlen(HFP_SET_SPEAKER_GAIN)) == 0){ 754 return HFP_CMD_SET_SPEAKER_GAIN; 755 } 756 757 if (strncmp(line_buffer+offset, HFP_ACTIVATE_VOICE_RECOGNITION, strlen(HFP_ACTIVATE_VOICE_RECOGNITION)) == 0){ 758 if (isHandsFree) return HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; 759 return HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION; 760 } 761 762 if (strncmp(line_buffer+offset, HFP_TURN_OFF_EC_AND_NR, strlen(HFP_TURN_OFF_EC_AND_NR)) == 0){ 763 return HFP_CMD_TURN_OFF_EC_AND_NR; 764 } 765 766 if (strncmp(line_buffer, HFP_CALL_ANSWERED, strlen(HFP_CALL_ANSWERED)) == 0){ 767 return HFP_CMD_CALL_ANSWERED; 768 } 769 770 if (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 771 return HFP_CMD_CALL_PHONE_NUMBER; 772 } 773 774 if (strncmp(line_buffer+offset, HFP_REDIAL_LAST_NUMBER, strlen(HFP_REDIAL_LAST_NUMBER)) == 0){ 775 return HFP_CMD_REDIAL_LAST_NUMBER; 776 } 777 778 if (strncmp(line_buffer+offset, HFP_CHANGE_IN_BAND_RING_TONE_SETTING, strlen(HFP_CHANGE_IN_BAND_RING_TONE_SETTING)) == 0){ 779 return HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING; 780 } 781 782 if (strncmp(line_buffer+offset, HFP_HANG_UP_CALL, strlen(HFP_HANG_UP_CALL)) == 0){ 783 return HFP_CMD_HANG_UP_CALL; 784 } 785 786 if (strncmp(line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){ 787 return HFP_CMD_ERROR; 788 } 789 790 if (strncmp(line_buffer+offset, HFP_RING, strlen(HFP_RING)) == 0){ 791 return HFP_CMD_RING; 792 } 793 794 if (isHandsFree && strncmp(line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){ 795 return HFP_CMD_OK; 796 } 797 798 if (strncmp(line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ 799 return HFP_CMD_SUPPORTED_FEATURES; 800 } 801 802 if (strncmp(line_buffer+offset, HFP_TRANSFER_HF_INDICATOR_STATUS, strlen(HFP_TRANSFER_HF_INDICATOR_STATUS)) == 0){ 803 return HFP_CMD_HF_INDICATOR_STATUS; 804 } 805 806 if (strncmp(line_buffer+offset, HFP_RESPONSE_AND_HOLD, strlen(HFP_RESPONSE_AND_HOLD)) == 0){ 807 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "?", 1) == 0){ 808 return HFP_CMD_RESPONSE_AND_HOLD_QUERY; 809 } 810 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "=", 1) == 0){ 811 return HFP_CMD_RESPONSE_AND_HOLD_COMMAND; 812 } 813 return HFP_CMD_RESPONSE_AND_HOLD_STATUS; 814 } 815 816 if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ 817 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){ 818 return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 819 } 820 821 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "=?", 2) == 0){ 822 return HFP_CMD_RETRIEVE_AG_INDICATORS; 823 } 824 } 825 826 if (strncmp(line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ 827 return HFP_CMD_AVAILABLE_CODECS; 828 } 829 830 if (strncmp(line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){ 831 return HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; 832 } 833 834 if (strncmp(line_buffer+offset, HFP_ENABLE_CLIP, strlen(HFP_ENABLE_CLIP)) == 0){ 835 if (isHandsFree) return HFP_CMD_AG_SENT_CLIP_INFORMATION; 836 return HFP_CMD_ENABLE_CLIP; 837 } 838 839 if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){ 840 if (isHandsFree) return HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE; 841 return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION; 842 } 843 844 if (strncmp(line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ 845 846 if (isHandsFree) return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 847 848 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=?", 2) == 0){ 849 return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 850 } 851 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=", 1) == 0){ 852 return HFP_CMD_CALL_HOLD; 853 } 854 855 return HFP_CMD_UNKNOWN; 856 } 857 858 if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ 859 if (isHandsFree) { 860 return HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS; 861 } 862 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ 863 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 864 } 865 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ 866 return HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 867 } 868 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 869 } 870 871 if (strncmp(line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ 872 return HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; 873 } 874 875 876 if (strncmp(line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ 877 if (strncmp(line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){ 878 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT; 879 } 880 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; 881 } 882 883 if (strncmp(line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ 884 return HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; 885 } 886 887 if (isHandsFree && strncmp(line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 888 return HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; 889 } 890 891 if (!isHandsFree && strncmp(line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 892 return HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; 893 } 894 895 if (strncmp(line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){ 896 return HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; 897 } 898 899 if (strncmp(line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){ 900 if (isHandsFree){ 901 return HFP_CMD_AG_SUGGESTED_CODEC; 902 } else { 903 return HFP_CMD_HF_CONFIRMED_CODEC; 904 } 905 } 906 907 if (strncmp(line_buffer+offset, "AT+", 3) == 0){ 908 log_info("process unknown HF command %s \n", line_buffer); 909 return HFP_CMD_UNKNOWN; 910 } 911 912 if (strncmp(line_buffer+offset, "+", 1) == 0){ 913 log_info(" process unknown AG command %s \n", line_buffer); 914 return HFP_CMD_UNKNOWN; 915 } 916 917 if (strncmp(line_buffer+offset, "NOP", 3) == 0){ 918 return HFP_CMD_NONE; 919 } 920 921 return HFP_CMD_NONE; 922 } 923 924 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){ 925 // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, context->line_size); 926 // TODO: add limit 927 hfp_connection->line_buffer[hfp_connection->line_size++] = byte; 928 hfp_connection->line_buffer[hfp_connection->line_size] = 0; 929 } 930 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){ 931 return hfp_connection->line_size == 0; 932 } 933 934 static int hfp_parser_is_end_of_line(uint8_t byte){ 935 return byte == '\n' || byte == '\r'; 936 } 937 938 static int hfp_parser_is_end_of_header(uint8_t byte){ 939 return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; 940 } 941 942 static int hfp_parser_found_separator(hfp_connection_t * hfp_connection, uint8_t byte){ 943 if (hfp_connection->keep_byte == 1) return 1; 944 945 int found_separator = byte == ',' || byte == '\n'|| byte == '\r'|| 946 byte == ')' || byte == '(' || byte == ':' || 947 byte == '-' || byte == '"' || byte == '?'|| byte == '='; 948 return found_separator; 949 } 950 951 static void hfp_parser_next_state(hfp_connection_t * hfp_connection, uint8_t byte){ 952 hfp_connection->line_size = 0; 953 if (hfp_parser_is_end_of_line(byte)){ 954 hfp_connection->parser_item_index = 0; 955 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 956 return; 957 } 958 switch (hfp_connection->parser_state){ 959 case HFP_PARSER_CMD_HEADER: 960 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 961 if (hfp_connection->keep_byte == 1){ 962 hfp_parser_store_byte(hfp_connection, byte); 963 hfp_connection->keep_byte = 0; 964 } 965 break; 966 case HFP_PARSER_CMD_SEQUENCE: 967 switch (hfp_connection->command){ 968 case HFP_CMD_AG_SENT_PHONE_NUMBER: 969 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 970 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 971 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 972 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 973 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 974 case HFP_CMD_RETRIEVE_AG_INDICATORS: 975 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 976 case HFP_CMD_HF_INDICATOR_STATUS: 977 hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM; 978 break; 979 default: 980 break; 981 } 982 break; 983 case HFP_PARSER_SECOND_ITEM: 984 hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM; 985 break; 986 case HFP_PARSER_THIRD_ITEM: 987 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ 988 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE; 989 break; 990 } 991 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 992 break; 993 } 994 } 995 996 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){ 997 // handle ATD<dial_string>; 998 if (strncmp((const char*)hfp_connection->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 999 // check for end-of-line or ';' 1000 if (byte == ';' || hfp_parser_is_end_of_line(byte)){ 1001 hfp_connection->line_buffer[hfp_connection->line_size] = 0; 1002 hfp_connection->line_size = 0; 1003 hfp_connection->command = HFP_CMD_CALL_PHONE_NUMBER; 1004 } else { 1005 hfp_connection->line_buffer[hfp_connection->line_size++] = byte; 1006 } 1007 return; 1008 } 1009 1010 // TODO: handle space inside word 1011 if (byte == ' ' && hfp_connection->parser_state > HFP_PARSER_CMD_HEADER) return; 1012 1013 if (byte == ',' && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1014 if (hfp_connection->line_size == 0){ 1015 hfp_connection->line_buffer[0] = 0; 1016 hfp_connection->ignore_value = 1; 1017 parse_sequence(hfp_connection); 1018 return; 1019 } 1020 } 1021 1022 if (!hfp_parser_found_separator(hfp_connection, byte)){ 1023 hfp_parser_store_byte(hfp_connection, byte); 1024 return; 1025 } 1026 1027 if (hfp_parser_is_end_of_line(byte)) { 1028 if (hfp_parser_is_buffer_empty(hfp_connection)){ 1029 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER; 1030 } 1031 } 1032 if (hfp_parser_is_buffer_empty(hfp_connection)) return; 1033 1034 switch (hfp_connection->parser_state){ 1035 case HFP_PARSER_CMD_HEADER: // header 1036 if (byte == '='){ 1037 hfp_connection->keep_byte = 1; 1038 hfp_parser_store_byte(hfp_connection, byte); 1039 return; 1040 } 1041 1042 if (byte == '?'){ 1043 hfp_connection->keep_byte = 0; 1044 hfp_parser_store_byte(hfp_connection, byte); 1045 return; 1046 } 1047 1048 if (byte == ','){ 1049 hfp_connection->resolve_byte = 1; 1050 } 1051 1052 // printf(" parse header 2 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); 1053 if (hfp_parser_is_end_of_header(byte) || hfp_connection->keep_byte == 1){ 1054 // printf(" parse header 3 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte); 1055 char * line_buffer = (char *)hfp_connection->line_buffer; 1056 hfp_connection->command = parse_command(line_buffer, isHandsFree); 1057 1058 /* resolve command name according to hfp_connection */ 1059 if (hfp_connection->command == HFP_CMD_UNKNOWN){ 1060 switch(hfp_connection->state){ 1061 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 1062 hfp_connection->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 1063 break; 1064 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 1065 hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 1066 break; 1067 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 1068 hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 1069 break; 1070 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 1071 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 1072 break; 1073 case HFP_W4_RETRIEVE_INDICATORS: 1074 hfp_connection->send_ag_indicators_segment = 0; 1075 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS; 1076 break; 1077 default: 1078 break; 1079 } 1080 } 1081 } 1082 break; 1083 1084 case HFP_PARSER_CMD_SEQUENCE: 1085 parse_sequence(hfp_connection); 1086 break; 1087 case HFP_PARSER_SECOND_ITEM: 1088 switch (hfp_connection->command){ 1089 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1090 log_info("format %s, ", hfp_connection->line_buffer); 1091 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1092 break; 1093 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1094 log_info("format %s \n", hfp_connection->line_buffer); 1095 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1096 break; 1097 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1098 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1099 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1100 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1101 break; 1102 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1103 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1104 log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status); 1105 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1; 1106 break; 1107 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1108 hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer); 1109 log_info("%s, ", hfp_connection->line_buffer); 1110 break; 1111 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1112 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1113 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1114 hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1115 break; 1116 default: 1117 break; 1118 } 1119 break; 1120 1121 case HFP_PARSER_THIRD_ITEM: 1122 switch (hfp_connection->command){ 1123 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1124 strcpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer); 1125 log_info("name %s\n", hfp_connection->line_buffer); 1126 break; 1127 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1128 hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer); 1129 hfp_connection->parser_item_index++; 1130 hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index; 1131 log_info("%s)\n", hfp_connection->line_buffer); 1132 break; 1133 default: 1134 break; 1135 } 1136 break; 1137 } 1138 hfp_parser_next_state(hfp_connection, byte); 1139 1140 if (hfp_connection->resolve_byte && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1141 hfp_connection->resolve_byte = 0; 1142 hfp_connection->ignore_value = 1; 1143 parse_sequence(hfp_connection); 1144 hfp_connection->line_buffer[0] = 0; 1145 hfp_connection->line_size = 0; 1146 } 1147 } 1148 1149 static void parse_sequence(hfp_connection_t * hfp_connection){ 1150 int value; 1151 switch (hfp_connection->command){ 1152 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: 1153 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1154 int i; 1155 switch (hfp_connection->parser_item_index){ 1156 case 0: 1157 for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){ 1158 if (hfp_connection->generic_status_indicators[i].uuid == value){ 1159 hfp_connection->parser_indicator_index = i; 1160 break; 1161 } 1162 } 1163 break; 1164 case 1: 1165 if (hfp_connection->parser_indicator_index <0) break; 1166 hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value; 1167 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", 1168 hfp_connection->parser_item_index, value); 1169 break; 1170 default: 1171 break; 1172 } 1173 hfp_connection->parser_item_index++; 1174 break; 1175 1176 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1177 switch(hfp_connection->parser_item_index){ 1178 case 0: 1179 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1180 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1181 break; 1182 case 1: 1183 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1184 hfp_connection->bnip_type = value; 1185 break; 1186 default: 1187 break; 1188 } 1189 hfp_connection->parser_item_index++; 1190 break; 1191 case HFP_CMD_LIST_CURRENT_CALLS: 1192 switch(hfp_connection->parser_item_index){ 1193 case 0: 1194 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1195 hfp_connection->clcc_idx = value; 1196 break; 1197 case 1: 1198 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1199 hfp_connection->clcc_dir = value; 1200 break; 1201 case 2: 1202 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1203 hfp_connection->clcc_status = value; 1204 break; 1205 case 3: 1206 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1207 hfp_connection->clcc_mpty = value; 1208 break; 1209 case 4: 1210 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1211 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1212 break; 1213 case 5: 1214 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1215 hfp_connection->bnip_type = value; 1216 break; 1217 default: 1218 break; 1219 } 1220 hfp_connection->parser_item_index++; 1221 break; 1222 case HFP_CMD_SET_MICROPHONE_GAIN: 1223 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1224 hfp_connection->microphone_gain = value; 1225 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); 1226 break; 1227 case HFP_CMD_SET_SPEAKER_GAIN: 1228 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1229 hfp_connection->speaker_gain = value; 1230 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); 1231 break; 1232 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: 1233 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1234 hfp_connection->ag_activate_voice_recognition = value; 1235 log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); 1236 break; 1237 case HFP_CMD_TURN_OFF_EC_AND_NR: 1238 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1239 hfp_connection->ag_echo_and_noise_reduction = value; 1240 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); 1241 break; 1242 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1243 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1244 hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); 1245 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); 1246 break; 1247 case HFP_CMD_HF_CONFIRMED_CODEC: 1248 hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer); 1249 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed); 1250 break; 1251 case HFP_CMD_AG_SUGGESTED_CODEC: 1252 hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer); 1253 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec); 1254 break; 1255 case HFP_CMD_SUPPORTED_FEATURES: 1256 hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer); 1257 log_info("Parsed supported feature %d\n", (int) hfp_connection->remote_supported_features); 1258 break; 1259 case HFP_CMD_AVAILABLE_CODECS: 1260 log_info("Parsed codec %s\n", hfp_connection->line_buffer); 1261 hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1262 hfp_connection->parser_item_index++; 1263 hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index; 1264 break; 1265 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1266 strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, (char *)hfp_connection->line_buffer); 1267 hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1; 1268 log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer); 1269 break; 1270 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1271 log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer); 1272 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer); 1273 hfp_connection->parser_item_index++; 1274 break; 1275 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 1276 hfp_connection->parser_item_index++; 1277 if (hfp_connection->parser_item_index != 4) break; 1278 log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer); 1279 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1280 hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value; 1281 break; 1282 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 1283 log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer); 1284 if (hfp_connection->line_size > 2 ) break; 1285 strcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name, (char *)hfp_connection->line_buffer); 1286 hfp_connection->remote_call_services_nr++; 1287 break; 1288 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1289 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1290 log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer); 1291 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); 1292 hfp_connection->parser_item_index++; 1293 hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index; 1294 break; 1295 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1296 // HF parses inital AG gen. ind. state 1297 log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer); 1298 hfp_connection->parser_item_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1299 break; 1300 case HFP_CMD_HF_INDICATOR_STATUS: 1301 hfp_connection->parser_indicator_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1302 log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index); 1303 break; 1304 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 1305 // AG parses new gen. ind. state 1306 if (hfp_connection->ignore_value){ 1307 hfp_connection->ignore_value = 0; 1308 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index, 1309 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled); 1310 } 1311 else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){ 1312 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", 1313 hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name); 1314 } else { 1315 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1316 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value; 1317 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index, 1318 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value); 1319 } 1320 hfp_connection->parser_item_index++; 1321 break; 1322 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1323 // indicators are indexed starting with 1 1324 hfp_connection->parser_item_index = btstack_atoi((char *)&hfp_connection->line_buffer[0]) - 1; 1325 log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index); 1326 break; 1327 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1328 hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]); 1329 log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode); 1330 break; 1331 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1332 if (hfp_connection->line_buffer[0] == '3'){ 1333 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer); 1334 break; 1335 } 1336 // TODO emit ERROR, wrong format 1337 log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer); 1338 break; 1339 case HFP_CMD_ERROR: 1340 break; 1341 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1342 hfp_connection->extended_audio_gateway_error = 1; 1343 hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1344 break; 1345 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 1346 hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); 1347 hfp_connection->ok_pending = 1; 1348 hfp_connection->extended_audio_gateway_error = 0; 1349 break; 1350 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1351 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: 1352 case HFP_CMD_AG_SENT_CLIP_INFORMATION: 1353 strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); 1354 hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; 1355 break; 1356 default: 1357 break; 1358 } 1359 } 1360 1361 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ 1362 hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr); 1363 log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection); 1364 1365 if (!hfp_connection) { 1366 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1367 return; 1368 } 1369 1370 switch (hfp_connection->state){ 1371 case HFP_W2_DISCONNECT_RFCOMM: 1372 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1373 return; 1374 case HFP_W4_RFCOMM_DISCONNECTED: 1375 hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1376 return; 1377 case HFP_IDLE: 1378 memcpy(hfp_connection->remote_addr, bd_addr, 6); 1379 hfp_connection->state = HFP_W4_SDP_QUERY_COMPLETE; 1380 connection_doing_sdp_query = hfp_connection; 1381 hfp_connection->service_uuid = service_uuid; 1382 sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, hfp_connection->remote_addr, service_uuid); 1383 break; 1384 default: 1385 break; 1386 } 1387 } 1388 1389 void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){ 1390 if (!hfp_connection) return; 1391 hfp_release_audio_connection(hfp_connection); 1392 1393 if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){ 1394 hfp_connection->state = HFP_IDLE; 1395 return; 1396 } 1397 1398 if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){ 1399 hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1400 return; 1401 } 1402 1403 if (hfp_connection->state < HFP_W4_SCO_CONNECTED){ 1404 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM; 1405 return; 1406 } 1407 1408 if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){ 1409 hfp_connection->state = HFP_W2_DISCONNECT_SCO; 1410 return; 1411 } 1412 1413 return; 1414 } 1415 1416 void hfp_release_audio_connection(hfp_connection_t * hfp_connection){ 1417 if (!hfp_connection) return; 1418 if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return; 1419 hfp_connection->release_audio_connection = 1; 1420 } 1421 1422 static const struct link_settings { 1423 const uint16_t max_latency; 1424 const uint8_t retransmission_effort; 1425 const uint16_t packet_types; 1426 } hfp_link_settings [] = { 1427 { 0xffff, 0xff, 0x03c1 }, // HFP_LINK_SETTINGS_D0, HV1 1428 { 0xffff, 0xff, 0x03c4 }, // HFP_LINK_SETTINGS_D1, HV3 1429 { 0x0007, 0x01, 0x03c8 }, // HFP_LINK_SETTINGS_S1, EV3 1430 { 0x0007, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S2, 2-EV3 1431 { 0x000a, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S3, 2-EV3 1432 { 0x000c, 0x02, 0x0380 }, // HFP_LINK_SETTINGS_S4, 2-EV3 1433 { 0x0008, 0x02, 0x03c8 }, // HFP_LINK_SETTINGS_T1, EV3 1434 { 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3 1435 }; 1436 1437 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){ 1438 // all packet types, fixed bandwidth 1439 int setting = hfp_connection->link_setting; 1440 log_info("hfp_setup_synchronous_connection using setting nr %u", setting); 1441 sco_establishment_active = hfp_connection; 1442 uint16_t sco_voice_setting = hci_get_sco_voice_setting(); 1443 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){ 1444 sco_voice_setting = 0x0043; // Transparent data 1445 } 1446 hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency, 1447 sco_voice_setting, hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380 1448 } 1449 1450 void hfp_set_packet_handler_for_rfcomm_connections(btstack_packet_handler_t handler){ 1451 rfcomm_packet_handler = handler; 1452 } 1453 1454