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