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