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