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