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 (packet[0]){ 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, packet[0] %x, size %u\n", packet_type, packet[0], size); 462 463 switch (packet[0]) { 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, packet[0] %x, size %u\n", packet_type, packet[0], 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->con_handle = little_endian_read_16(packet, 9); 491 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", context->con_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 // forward event to app, to learn about con_handle 509 (*hfp_callback)(packet, size); 510 } 511 break; 512 513 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ 514 515 reverse_bd_addr(&packet[5], event_addr); 516 int index = 2; 517 uint8_t status = packet[index++]; 518 519 if (status != 0){ 520 log_error("(e)SCO Connection failed status %u", status); 521 // if outgoing && link_setting != d0 && appropriate error 522 if (status != 0x11 && status != 0x1f) break; // invalid params / unspecified error 523 context = get_hfp_connection_context_for_bd_addr(event_addr); 524 if (!context) break; 525 switch (context->link_setting){ 526 case HFP_LINK_SETTINGS_D0: 527 return; // no other option left 528 case HFP_LINK_SETTINGS_D1: 529 // context->link_setting = HFP_LINK_SETTINGS_D0; 530 // break; 531 case HFP_LINK_SETTINGS_S1: 532 // context->link_setting = HFP_LINK_SETTINGS_D1; 533 // break; 534 case HFP_LINK_SETTINGS_S2: 535 case HFP_LINK_SETTINGS_S3: 536 case HFP_LINK_SETTINGS_S4: 537 // context->link_setting = HFP_LINK_SETTINGS_S1; 538 // break; 539 case HFP_LINK_SETTINGS_T1: 540 case HFP_LINK_SETTINGS_T2: 541 // context->link_setting = HFP_LINK_SETTINGS_S3; 542 context->link_setting = HFP_LINK_SETTINGS_D0; 543 break; 544 } 545 context->establish_audio_connection = 1; 546 break; 547 } 548 549 uint16_t sco_handle = little_endian_read_16(packet, index); 550 index+=2; 551 552 reverse_bd_addr(&packet[index], event_addr); 553 index+=6; 554 555 uint8_t link_type = packet[index++]; 556 uint8_t transmission_interval = packet[index++]; // measured in slots 557 uint8_t retransmission_interval = packet[index++];// measured in slots 558 uint16_t rx_packet_length = little_endian_read_16(packet, index); // measured in bytes 559 index+=2; 560 uint16_t tx_packet_length = little_endian_read_16(packet, index); // measured in bytes 561 index+=2; 562 uint8_t air_mode = packet[index]; 563 564 switch (link_type){ 565 case 0x00: 566 log_info("SCO Connection established."); 567 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); 568 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); 569 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); 570 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); 571 break; 572 case 0x02: 573 log_info("eSCO Connection established. \n"); 574 break; 575 default: 576 log_error("(e)SCO reserved link_type 0x%2x", link_type); 577 break; 578 } 579 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 580 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle, 581 bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode); 582 583 context = get_hfp_connection_context_for_bd_addr(event_addr); 584 585 if (!context) { 586 log_error("SCO link created, context for address %s not found.", bd_addr_to_str(event_addr)); 587 break; 588 } 589 590 if (context->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ 591 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN"); 592 context->state = HFP_W2_DISCONNECT_SCO; 593 break; 594 } 595 context->sco_handle = sco_handle; 596 context->establish_audio_connection = 0; 597 context->state = HFP_AUDIO_CONNECTION_ESTABLISHED; 598 hfp_emit_audio_connection_established_event(hfp_callback, packet[2], sco_handle); 599 break; 600 } 601 602 case RFCOMM_EVENT_CHANNEL_CLOSED: 603 rfcomm_cid = little_endian_read_16(packet,2); 604 context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); 605 if (!context) break; 606 if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 607 context->state = HFP_IDLE; 608 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid); 609 break; 610 } 611 612 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 613 remove_hfp_connection_context(context); 614 break; 615 616 case HCI_EVENT_DISCONNECTION_COMPLETE: 617 handle = little_endian_read_16(packet,3); 618 context = get_hfp_connection_context_for_sco_handle(handle); 619 620 if (!context) break; 621 622 if (context->state != HFP_W4_SCO_DISCONNECTED){ 623 log_info("Received gap disconnect in wrong hfp state"); 624 } 625 log_info("Check SCO handle: incoming 0x%02x, context 0x%02x\n", handle,context->sco_handle); 626 627 if (handle == context->sco_handle){ 628 log_info("SCO disconnected, w2 disconnect RFCOMM\n"); 629 context->sco_handle = 0; 630 context->release_audio_connection = 0; 631 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 632 hfp_emit_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0); 633 break; 634 } 635 break; 636 637 case HCI_EVENT_INQUIRY_RESULT: 638 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 639 case HCI_EVENT_INQUIRY_COMPLETE: 640 case DAEMON_EVENT_REMOTE_NAME_CACHED: 641 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 642 // forward inquiry events to app - TODO: replace with new event handler architecture 643 (*hfp_callback)(packet, size); 644 break; 645 } 646 } 647 648 // translates command string into hfp_command_t CMD 649 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ 650 int offset = isHandsFree ? 0 : 2; 651 652 if (strncmp(line_buffer+offset, HFP_LIST_CURRENT_CALLS, strlen(HFP_LIST_CURRENT_CALLS)) == 0){ 653 return HFP_CMD_LIST_CURRENT_CALLS; 654 } 655 656 if (strncmp(line_buffer+offset, HFP_SUBSCRIBER_NUMBER_INFORMATION, strlen(HFP_SUBSCRIBER_NUMBER_INFORMATION)) == 0){ 657 return HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION; 658 } 659 660 if (strncmp(line_buffer+offset, HFP_PHONE_NUMBER_FOR_VOICE_TAG, strlen(HFP_PHONE_NUMBER_FOR_VOICE_TAG)) == 0){ 661 if (isHandsFree) return HFP_CMD_AG_SENT_PHONE_NUMBER; 662 return HFP_CMD_HF_REQUEST_PHONE_NUMBER; 663 } 664 665 if (strncmp(line_buffer+offset, HFP_TRANSMIT_DTMF_CODES, strlen(HFP_TRANSMIT_DTMF_CODES)) == 0){ 666 return HFP_CMD_TRANSMIT_DTMF_CODES; 667 } 668 669 if (strncmp(line_buffer+offset, HFP_SET_MICROPHONE_GAIN, strlen(HFP_SET_MICROPHONE_GAIN)) == 0){ 670 return HFP_CMD_SET_MICROPHONE_GAIN; 671 } 672 673 if (strncmp(line_buffer+offset, HFP_SET_SPEAKER_GAIN, strlen(HFP_SET_SPEAKER_GAIN)) == 0){ 674 return HFP_CMD_SET_SPEAKER_GAIN; 675 } 676 677 if (strncmp(line_buffer+offset, HFP_ACTIVATE_VOICE_RECOGNITION, strlen(HFP_ACTIVATE_VOICE_RECOGNITION)) == 0){ 678 if (isHandsFree) return HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; 679 return HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION; 680 } 681 682 if (strncmp(line_buffer+offset, HFP_TURN_OFF_EC_AND_NR, strlen(HFP_TURN_OFF_EC_AND_NR)) == 0){ 683 return HFP_CMD_TURN_OFF_EC_AND_NR; 684 } 685 686 if (strncmp(line_buffer, HFP_CALL_ANSWERED, strlen(HFP_CALL_ANSWERED)) == 0){ 687 return HFP_CMD_CALL_ANSWERED; 688 } 689 690 if (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 691 return HFP_CMD_CALL_PHONE_NUMBER; 692 } 693 694 if (strncmp(line_buffer+offset, HFP_REDIAL_LAST_NUMBER, strlen(HFP_REDIAL_LAST_NUMBER)) == 0){ 695 return HFP_CMD_REDIAL_LAST_NUMBER; 696 } 697 698 if (strncmp(line_buffer+offset, HFP_CHANGE_IN_BAND_RING_TONE_SETTING, strlen(HFP_CHANGE_IN_BAND_RING_TONE_SETTING)) == 0){ 699 return HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING; 700 } 701 702 if (strncmp(line_buffer+offset, HFP_HANG_UP_CALL, strlen(HFP_HANG_UP_CALL)) == 0){ 703 return HFP_CMD_HANG_UP_CALL; 704 } 705 706 if (strncmp(line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){ 707 return HFP_CMD_ERROR; 708 } 709 710 if (strncmp(line_buffer+offset, HFP_RING, strlen(HFP_RING)) == 0){ 711 return HFP_CMD_RING; 712 } 713 714 if (isHandsFree && strncmp(line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){ 715 return HFP_CMD_OK; 716 } 717 718 if (strncmp(line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ 719 return HFP_CMD_SUPPORTED_FEATURES; 720 } 721 722 if (strncmp(line_buffer+offset, HFP_TRANSFER_HF_INDICATOR_STATUS, strlen(HFP_TRANSFER_HF_INDICATOR_STATUS)) == 0){ 723 return HFP_CMD_HF_INDICATOR_STATUS; 724 } 725 726 if (strncmp(line_buffer+offset, HFP_RESPONSE_AND_HOLD, strlen(HFP_RESPONSE_AND_HOLD)) == 0){ 727 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "?", 1) == 0){ 728 return HFP_CMD_RESPONSE_AND_HOLD_QUERY; 729 } 730 if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "=", 1) == 0){ 731 return HFP_CMD_RESPONSE_AND_HOLD_COMMAND; 732 } 733 return HFP_CMD_RESPONSE_AND_HOLD_STATUS; 734 } 735 736 if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ 737 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){ 738 return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 739 } 740 741 if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "=?", 2) == 0){ 742 return HFP_CMD_RETRIEVE_AG_INDICATORS; 743 } 744 } 745 746 if (strncmp(line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ 747 return HFP_CMD_AVAILABLE_CODECS; 748 } 749 750 if (strncmp(line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){ 751 return HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; 752 } 753 754 if (strncmp(line_buffer+offset, HFP_ENABLE_CLIP, strlen(HFP_ENABLE_CLIP)) == 0){ 755 return HFP_CMD_ENABLE_CLIP; 756 } 757 758 if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){ 759 return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION; 760 } 761 762 if (strncmp(line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ 763 764 if (isHandsFree) return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 765 766 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=?", 2) == 0){ 767 return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 768 } 769 if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=", 1) == 0){ 770 return HFP_CMD_CALL_HOLD; 771 } 772 773 return HFP_CMD_UNKNOWN; 774 } 775 776 if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ 777 if (isHandsFree) { 778 return HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS; 779 } 780 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ 781 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 782 } 783 if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ 784 return HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 785 } 786 return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 787 } 788 789 if (strncmp(line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ 790 return HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; 791 } 792 793 794 if (strncmp(line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ 795 if (strncmp(line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){ 796 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT; 797 } 798 return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; 799 } 800 801 if (strncmp(line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ 802 return HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; 803 } 804 805 if (isHandsFree && strncmp(line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 806 return HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; 807 } 808 809 if (!isHandsFree && strncmp(line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 810 return HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; 811 } 812 813 if (strncmp(line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){ 814 return HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; 815 } 816 817 if (strncmp(line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){ 818 if (isHandsFree){ 819 return HFP_CMD_AG_SUGGESTED_CODEC; 820 } else { 821 return HFP_CMD_HF_CONFIRMED_CODEC; 822 } 823 } 824 825 if (strncmp(line_buffer+offset, "AT+", 3) == 0){ 826 log_info("process unknown HF command %s \n", line_buffer); 827 return HFP_CMD_UNKNOWN; 828 } 829 830 if (strncmp(line_buffer+offset, "+", 1) == 0){ 831 log_info(" process unknown AG command %s \n", line_buffer); 832 return HFP_CMD_UNKNOWN; 833 } 834 835 if (strncmp(line_buffer+offset, "NOP", 3) == 0){ 836 return HFP_CMD_NONE; 837 } 838 839 return HFP_CMD_NONE; 840 } 841 842 static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){ 843 // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, context->line_size); 844 // TODO: add limit 845 context->line_buffer[context->line_size++] = byte; 846 context->line_buffer[context->line_size] = 0; 847 } 848 static int hfp_parser_is_buffer_empty(hfp_connection_t * context){ 849 return context->line_size == 0; 850 } 851 852 static int hfp_parser_is_end_of_line(uint8_t byte){ 853 return byte == '\n' || byte == '\r'; 854 } 855 856 static int hfp_parser_is_end_of_header(uint8_t byte){ 857 return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; 858 } 859 860 static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ 861 if (context->keep_byte == 1) return 1; 862 863 int found_separator = byte == ',' || byte == '\n'|| byte == '\r'|| 864 byte == ')' || byte == '(' || byte == ':' || 865 byte == '-' || byte == '"' || byte == '?'|| byte == '='; 866 return found_separator; 867 } 868 869 static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ 870 context->line_size = 0; 871 if (hfp_parser_is_end_of_line(byte)){ 872 context->parser_item_index = 0; 873 context->parser_state = HFP_PARSER_CMD_HEADER; 874 return; 875 } 876 switch (context->parser_state){ 877 case HFP_PARSER_CMD_HEADER: 878 context->parser_state = HFP_PARSER_CMD_SEQUENCE; 879 if (context->keep_byte == 1){ 880 hfp_parser_store_byte(context, byte); 881 context->keep_byte = 0; 882 } 883 break; 884 case HFP_PARSER_CMD_SEQUENCE: 885 switch (context->command){ 886 case HFP_CMD_AG_SENT_PHONE_NUMBER: 887 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 888 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 889 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 890 case HFP_CMD_RETRIEVE_AG_INDICATORS: 891 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 892 case HFP_CMD_HF_INDICATOR_STATUS: 893 context->parser_state = HFP_PARSER_SECOND_ITEM; 894 break; 895 default: 896 break; 897 } 898 break; 899 case HFP_PARSER_SECOND_ITEM: 900 context->parser_state = HFP_PARSER_THIRD_ITEM; 901 break; 902 case HFP_PARSER_THIRD_ITEM: 903 if (context->command == HFP_CMD_RETRIEVE_AG_INDICATORS){ 904 context->parser_state = HFP_PARSER_CMD_SEQUENCE; 905 break; 906 } 907 context->parser_state = HFP_PARSER_CMD_HEADER; 908 break; 909 } 910 } 911 912 void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ 913 // handle ATD<dial_string>; 914 if (strncmp((const char*)context->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){ 915 // check for end-of-line or ';' 916 if (byte == ';' || hfp_parser_is_end_of_line(byte)){ 917 context->line_buffer[context->line_size] = 0; 918 context->line_size = 0; 919 context->command = HFP_CMD_CALL_PHONE_NUMBER; 920 } else { 921 context->line_buffer[context->line_size++] = byte; 922 } 923 return; 924 } 925 926 // TODO: handle space inside word 927 if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return; 928 929 if (byte == ',' && context->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 930 if (context->line_size == 0){ 931 context->line_buffer[0] = 0; 932 context->ignore_value = 1; 933 parse_sequence(context); 934 return; 935 } 936 } 937 938 if (!hfp_parser_found_separator(context, byte)){ 939 hfp_parser_store_byte(context, byte); 940 return; 941 } 942 943 if (hfp_parser_is_end_of_line(byte)) { 944 if (hfp_parser_is_buffer_empty(context)){ 945 context->parser_state = HFP_PARSER_CMD_HEADER; 946 } 947 } 948 if (hfp_parser_is_buffer_empty(context)) return; 949 950 switch (context->parser_state){ 951 case HFP_PARSER_CMD_HEADER: // header 952 if (byte == '='){ 953 context->keep_byte = 1; 954 hfp_parser_store_byte(context, byte); 955 return; 956 } 957 958 if (byte == '?'){ 959 context->keep_byte = 0; 960 hfp_parser_store_byte(context, byte); 961 return; 962 } 963 964 if (byte == ','){ 965 context->resolve_byte = 1; 966 } 967 968 // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_byte); 969 if (hfp_parser_is_end_of_header(byte) || context->keep_byte == 1){ 970 // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_byte); 971 char * line_buffer = (char *)context->line_buffer; 972 context->command = parse_command(line_buffer, isHandsFree); 973 974 /* resolve command name according to context */ 975 if (context->command == HFP_CMD_UNKNOWN){ 976 switch(context->state){ 977 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 978 context->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; 979 break; 980 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 981 context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; 982 break; 983 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 984 context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; 985 break; 986 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 987 context->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; 988 break; 989 case HFP_W4_RETRIEVE_INDICATORS: 990 context->send_ag_indicators_segment = 0; 991 context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; 992 break; 993 default: 994 break; 995 } 996 } 997 } 998 break; 999 1000 case HFP_PARSER_CMD_SEQUENCE: 1001 parse_sequence(context); 1002 break; 1003 case HFP_PARSER_SECOND_ITEM: 1004 switch (context->command){ 1005 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1006 log_info("format %s, ", context->line_buffer); 1007 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 1008 break; 1009 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1010 log_info("format %s \n", context->line_buffer); 1011 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 1012 break; 1013 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1014 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1015 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1016 context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); 1017 break; 1018 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1019 context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); 1020 log_info("%d \n", context->ag_indicators[context->parser_item_index].status); 1021 context->ag_indicators[context->parser_item_index].status_changed = 1; 1022 break; 1023 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1024 context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); 1025 log_info("%s, ", context->line_buffer); 1026 break; 1027 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1028 context->bnip_type = (uint8_t)atoi((char*)context->line_buffer); 1029 break; 1030 default: 1031 break; 1032 } 1033 break; 1034 1035 case HFP_PARSER_THIRD_ITEM: 1036 switch (context->command){ 1037 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1038 strcpy(context->network_operator.name, (char *)context->line_buffer); 1039 log_info("name %s\n", context->line_buffer); 1040 break; 1041 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1042 context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); 1043 context->parser_item_index++; 1044 context->ag_indicators_nr = context->parser_item_index; 1045 log_info("%s)\n", context->line_buffer); 1046 break; 1047 default: 1048 break; 1049 } 1050 break; 1051 } 1052 hfp_parser_next_state(context, byte); 1053 1054 if (context->resolve_byte && context->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1055 context->resolve_byte = 0; 1056 context->ignore_value = 1; 1057 parse_sequence(context); 1058 context->line_buffer[0] = 0; 1059 context->line_size = 0; 1060 } 1061 } 1062 1063 static void parse_sequence(hfp_connection_t * context){ 1064 int value; 1065 switch (context->command){ 1066 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: 1067 value = atoi((char *)&context->line_buffer[0]); 1068 int i; 1069 switch (context->parser_item_index){ 1070 case 0: 1071 for (i=0;i<context->generic_status_indicators_nr;i++){ 1072 if (context->generic_status_indicators[i].uuid == value){ 1073 context->parser_indicator_index = i; 1074 break; 1075 } 1076 } 1077 break; 1078 case 1: 1079 if (context->parser_indicator_index <0) break; 1080 context->generic_status_indicators[context->parser_indicator_index].state = value; 1081 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", 1082 context->parser_item_index, value); 1083 break; 1084 default: 1085 break; 1086 } 1087 context->parser_item_index++; 1088 break; 1089 1090 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1091 switch(context->parser_item_index){ 1092 case 0: 1093 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1094 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1095 break; 1096 case 1: 1097 value = atoi((char *)&context->line_buffer[0]); 1098 context->bnip_type = value; 1099 break; 1100 default: 1101 break; 1102 } 1103 context->parser_item_index++; 1104 break; 1105 case HFP_CMD_LIST_CURRENT_CALLS: 1106 switch(context->parser_item_index){ 1107 case 0: 1108 value = atoi((char *)&context->line_buffer[0]); 1109 context->clcc_idx = value; 1110 break; 1111 case 1: 1112 value = atoi((char *)&context->line_buffer[0]); 1113 context->clcc_dir = value; 1114 break; 1115 case 2: 1116 value = atoi((char *)&context->line_buffer[0]); 1117 context->clcc_status = value; 1118 break; 1119 case 3: 1120 value = atoi((char *)&context->line_buffer[0]); 1121 context->clcc_mpty = value; 1122 break; 1123 case 4: 1124 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1125 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1126 break; 1127 case 5: 1128 value = atoi((char *)&context->line_buffer[0]); 1129 context->bnip_type = value; 1130 break; 1131 default: 1132 break; 1133 } 1134 context->parser_item_index++; 1135 break; 1136 case HFP_CMD_SET_MICROPHONE_GAIN: 1137 value = atoi((char *)&context->line_buffer[0]); 1138 context->microphone_gain = value; 1139 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); 1140 break; 1141 case HFP_CMD_SET_SPEAKER_GAIN: 1142 value = atoi((char *)&context->line_buffer[0]); 1143 context->speaker_gain = value; 1144 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); 1145 break; 1146 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: 1147 value = atoi((char *)&context->line_buffer[0]); 1148 context->ag_activate_voice_recognition = value; 1149 log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); 1150 break; 1151 case HFP_CMD_TURN_OFF_EC_AND_NR: 1152 value = atoi((char *)&context->line_buffer[0]); 1153 context->ag_echo_and_noise_reduction = value; 1154 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); 1155 break; 1156 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1157 value = atoi((char *)&context->line_buffer[0]); 1158 context->remote_supported_features = store_bit(context->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); 1159 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); 1160 break; 1161 case HFP_CMD_HF_CONFIRMED_CODEC: 1162 context->codec_confirmed = atoi((char*)context->line_buffer); 1163 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed); 1164 break; 1165 case HFP_CMD_AG_SUGGESTED_CODEC: 1166 context->suggested_codec = atoi((char*)context->line_buffer); 1167 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec); 1168 break; 1169 case HFP_CMD_SUPPORTED_FEATURES: 1170 context->remote_supported_features = atoi((char*)context->line_buffer); 1171 log_info("Parsed supported feature %d\n", context->remote_supported_features); 1172 break; 1173 case HFP_CMD_AVAILABLE_CODECS: 1174 log_info("Parsed codec %s\n", context->line_buffer); 1175 context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); 1176 context->parser_item_index++; 1177 context->remote_codecs_nr = context->parser_item_index; 1178 break; 1179 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1180 strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); 1181 context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; 1182 log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); 1183 break; 1184 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1185 log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); 1186 context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); 1187 context->parser_item_index++; 1188 break; 1189 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 1190 context->parser_item_index++; 1191 if (context->parser_item_index != 4) break; 1192 log_info("Parsed Enable indicators: %s\n", context->line_buffer); 1193 value = atoi((char *)&context->line_buffer[0]); 1194 context->enable_status_update_for_ag_indicators = (uint8_t) value; 1195 break; 1196 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 1197 log_info("Parsed Support call hold: %s\n", context->line_buffer); 1198 if (context->line_size > 2 ) break; 1199 strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); 1200 context->remote_call_services_nr++; 1201 break; 1202 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1203 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1204 log_info("Parsed Generic status indicator: %s\n", context->line_buffer); 1205 context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); 1206 context->parser_item_index++; 1207 context->generic_status_indicators_nr = context->parser_item_index; 1208 break; 1209 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1210 // HF parses inital AG gen. ind. state 1211 log_info("Parsed List generic status indicator %s state: ", context->line_buffer); 1212 context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); 1213 break; 1214 case HFP_CMD_HF_INDICATOR_STATUS: 1215 context->parser_indicator_index = (uint8_t)atoi((char*)context->line_buffer); 1216 log_info("Parsed HF indicator index %u", context->parser_indicator_index); 1217 break; 1218 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 1219 // AG parses new gen. ind. state 1220 if (context->ignore_value){ 1221 context->ignore_value = 0; 1222 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", context->parser_item_index, 1223 context->ag_indicators[context->parser_item_index].name, context->ag_indicators[context->parser_item_index].enabled); 1224 } 1225 else if (context->ag_indicators[context->parser_item_index].mandatory){ 1226 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", 1227 context->parser_item_index, context->ag_indicators[context->parser_item_index].name); 1228 } else { 1229 value = atoi((char *)&context->line_buffer[0]); 1230 context->ag_indicators[context->parser_item_index].enabled = value; 1231 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", context->parser_item_index, 1232 context->ag_indicators[context->parser_item_index].name, value); 1233 } 1234 context->parser_item_index++; 1235 break; 1236 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1237 // indicators are indexed starting with 1 1238 context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; 1239 log_info("Parsed status of the AG indicator %d, status ", context->parser_item_index); 1240 break; 1241 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1242 context->network_operator.mode = atoi((char *)&context->line_buffer[0]); 1243 log_info("Parsed network operator mode: %d, ", context->network_operator.mode); 1244 break; 1245 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1246 if (context->line_buffer[0] == '3'){ 1247 log_info("Parsed Set network operator format : %s, ", context->line_buffer); 1248 break; 1249 } 1250 // TODO emit ERROR, wrong format 1251 log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer); 1252 break; 1253 case HFP_CMD_ERROR: 1254 break; 1255 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1256 context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer); 1257 break; 1258 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 1259 context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer); 1260 context->ok_pending = 1; 1261 context->extended_audio_gateway_error = 0; 1262 break; 1263 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1264 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1265 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1266 break; 1267 default: 1268 break; 1269 } 1270 } 1271 1272 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ 1273 hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr); 1274 log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context); 1275 1276 if (!context) { 1277 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1278 return; 1279 } 1280 1281 switch (context->state){ 1282 case HFP_W2_DISCONNECT_RFCOMM: 1283 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1284 return; 1285 case HFP_W4_RFCOMM_DISCONNECTED: 1286 context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1287 return; 1288 case HFP_IDLE: 1289 memcpy(context->remote_addr, bd_addr, 6); 1290 context->state = HFP_W4_SDP_EVENT_QUERY_COMPLETE; 1291 connection_doing_sdp_query = context; 1292 context->service_uuid = service_uuid; 1293 sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, context->remote_addr, service_uuid); 1294 break; 1295 default: 1296 break; 1297 } 1298 } 1299 1300 void hfp_release_service_level_connection(hfp_connection_t * context){ 1301 if (!context) return; 1302 1303 if (context->state < HFP_W4_RFCOMM_CONNECTED){ 1304 context->state = HFP_IDLE; 1305 return; 1306 } 1307 1308 if (context->state == HFP_W4_RFCOMM_CONNECTED){ 1309 context->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1310 return; 1311 } 1312 1313 if (context->state < HFP_W4_SCO_CONNECTED){ 1314 context->state = HFP_W2_DISCONNECT_RFCOMM; 1315 return; 1316 } 1317 1318 if (context->state < HFP_W4_SCO_DISCONNECTED){ 1319 context->state = HFP_W2_DISCONNECT_SCO; 1320 return; 1321 } 1322 1323 return; 1324 } 1325 1326 void hfp_release_audio_connection(hfp_connection_t * context){ 1327 if (!context) return; 1328 if (context->state >= HFP_W2_DISCONNECT_SCO) return; 1329 context->release_audio_connection = 1; 1330 } 1331 1332 static const struct link_settings { 1333 const uint16_t max_latency; 1334 const uint8_t retransmission_effort; 1335 const uint16_t packet_types; 1336 } hfp_link_settings [] = { 1337 { 0xffff, 0xff, 0x03c1 }, // HFP_LINK_SETTINGS_D0, HV1 1338 { 0xffff, 0xff, 0x03c4 }, // HFP_LINK_SETTINGS_D1, HV3 1339 { 0x0007, 0x01, 0x03c8 }, // HFP_LINK_SETTINGS_S1, EV3 1340 { 0x0007, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S2, 2-EV3 1341 { 0x000a, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S3, 2-EV3 1342 { 0x000c, 0x02, 0x0380 }, // HFP_LINK_SETTINGS_S4, 2-EV3 1343 { 0x0008, 0x02, 0x03c8 }, // HFP_LINK_SETTINGS_T1, EV3 1344 { 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3 1345 }; 1346 1347 void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t setting){ 1348 // all packet types, fixed bandwidth 1349 log_info("hfp_setup_synchronous_connection using setting nr %u", setting); 1350 hci_send_cmd(&hci_setup_synchronous_connection, handle, 8000, 8000, hfp_link_settings[setting].max_latency, 1351 hci_get_sco_voice_setting(), hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380 1352 } 1353