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