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 "btstack_run_loop.h" 54 55 #include "hci.h" 56 #include "btstack_memory.h" 57 #include "hci_dump.h" 58 #include "l2cap.h" 59 #include "classic/sdp_query_rfcomm.h" 60 #include "classic/sdp.h" 61 #include "btstack_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 btstack_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 if (!rfcomm_can_send_packet_now(cid)) return 1; 134 log_info("HFP_TX %s", command); 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 btstack_linked_list_t * hfp_get_connections(){ 233 return (btstack_linked_list_t *) &hfp_connections; 234 } 235 236 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){ 237 btstack_linked_list_iterator_t it; 238 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 239 while (btstack_linked_list_iterator_has_next(&it)){ 240 hfp_connection_t * connection = (hfp_connection_t *)btstack_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 btstack_linked_list_iterator_t it; 250 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 251 while (btstack_linked_list_iterator_has_next(&it)){ 252 hfp_connection_t * connection = (hfp_connection_t *)btstack_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 btstack_linked_list_iterator_t it; 262 btstack_linked_list_iterator_init(&it, hfp_get_connections()); 263 while (btstack_linked_list_iterator_has_next(&it)){ 264 hfp_connection_t * connection = (hfp_connection_t *)btstack_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 btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)context); 313 return context; 314 } 315 316 static void remove_hfp_connection_context(hfp_connection_t * context){ 317 btstack_linked_list_remove(&hfp_connections, (btstack_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->send_ag_indicators_segment = 0; 997 context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; 998 break; 999 default: 1000 break; 1001 } 1002 } 1003 } 1004 break; 1005 1006 case HFP_PARSER_CMD_SEQUENCE: 1007 parse_sequence(context); 1008 break; 1009 case HFP_PARSER_SECOND_ITEM: 1010 switch (context->command){ 1011 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1012 log_info("format %s, ", context->line_buffer); 1013 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 1014 break; 1015 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1016 log_info("format %s \n", context->line_buffer); 1017 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 1018 break; 1019 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1020 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1021 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1022 context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); 1023 break; 1024 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1025 context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); 1026 log_info("%d \n", context->ag_indicators[context->parser_item_index].status); 1027 context->ag_indicators[context->parser_item_index].status_changed = 1; 1028 break; 1029 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1030 context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); 1031 log_info("%s, ", context->line_buffer); 1032 break; 1033 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1034 context->bnip_type = (uint8_t)atoi((char*)context->line_buffer); 1035 break; 1036 default: 1037 break; 1038 } 1039 break; 1040 1041 case HFP_PARSER_THIRD_ITEM: 1042 switch (context->command){ 1043 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1044 strcpy(context->network_operator.name, (char *)context->line_buffer); 1045 log_info("name %s\n", context->line_buffer); 1046 break; 1047 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1048 context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); 1049 context->parser_item_index++; 1050 context->ag_indicators_nr = context->parser_item_index; 1051 log_info("%s)\n", context->line_buffer); 1052 break; 1053 default: 1054 break; 1055 } 1056 break; 1057 } 1058 hfp_parser_next_state(context, byte); 1059 1060 if (context->resolve_byte && context->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){ 1061 context->resolve_byte = 0; 1062 context->ignore_value = 1; 1063 parse_sequence(context); 1064 context->line_buffer[0] = 0; 1065 context->line_size = 0; 1066 } 1067 } 1068 1069 static void parse_sequence(hfp_connection_t * context){ 1070 int value; 1071 switch (context->command){ 1072 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: 1073 value = atoi((char *)&context->line_buffer[0]); 1074 int i; 1075 switch (context->parser_item_index){ 1076 case 0: 1077 for (i=0;i<context->generic_status_indicators_nr;i++){ 1078 if (context->generic_status_indicators[i].uuid == value){ 1079 context->parser_indicator_index = i; 1080 break; 1081 } 1082 } 1083 break; 1084 case 1: 1085 if (context->parser_indicator_index <0) break; 1086 context->generic_status_indicators[context->parser_indicator_index].state = value; 1087 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", 1088 context->parser_item_index, value); 1089 break; 1090 default: 1091 break; 1092 } 1093 context->parser_item_index++; 1094 break; 1095 1096 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: 1097 switch(context->parser_item_index){ 1098 case 0: 1099 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1100 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1101 break; 1102 case 1: 1103 value = atoi((char *)&context->line_buffer[0]); 1104 context->bnip_type = value; 1105 break; 1106 default: 1107 break; 1108 } 1109 context->parser_item_index++; 1110 break; 1111 case HFP_CMD_LIST_CURRENT_CALLS: 1112 switch(context->parser_item_index){ 1113 case 0: 1114 value = atoi((char *)&context->line_buffer[0]); 1115 context->clcc_idx = value; 1116 break; 1117 case 1: 1118 value = atoi((char *)&context->line_buffer[0]); 1119 context->clcc_dir = value; 1120 break; 1121 case 2: 1122 value = atoi((char *)&context->line_buffer[0]); 1123 context->clcc_status = value; 1124 break; 1125 case 3: 1126 value = atoi((char *)&context->line_buffer[0]); 1127 context->clcc_mpty = value; 1128 break; 1129 case 4: 1130 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1131 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1132 break; 1133 case 5: 1134 value = atoi((char *)&context->line_buffer[0]); 1135 context->bnip_type = value; 1136 break; 1137 default: 1138 break; 1139 } 1140 context->parser_item_index++; 1141 break; 1142 case HFP_CMD_SET_MICROPHONE_GAIN: 1143 value = atoi((char *)&context->line_buffer[0]); 1144 context->microphone_gain = value; 1145 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value); 1146 break; 1147 case HFP_CMD_SET_SPEAKER_GAIN: 1148 value = atoi((char *)&context->line_buffer[0]); 1149 context->speaker_gain = value; 1150 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value); 1151 break; 1152 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: 1153 value = atoi((char *)&context->line_buffer[0]); 1154 context->ag_activate_voice_recognition = value; 1155 log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); 1156 break; 1157 case HFP_CMD_TURN_OFF_EC_AND_NR: 1158 value = atoi((char *)&context->line_buffer[0]); 1159 context->ag_echo_and_noise_reduction = value; 1160 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value); 1161 break; 1162 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: 1163 value = atoi((char *)&context->line_buffer[0]); 1164 context->remote_supported_features = store_bit(context->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value); 1165 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value); 1166 break; 1167 case HFP_CMD_HF_CONFIRMED_CODEC: 1168 context->codec_confirmed = atoi((char*)context->line_buffer); 1169 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed); 1170 break; 1171 case HFP_CMD_AG_SUGGESTED_CODEC: 1172 context->suggested_codec = atoi((char*)context->line_buffer); 1173 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec); 1174 break; 1175 case HFP_CMD_SUPPORTED_FEATURES: 1176 context->remote_supported_features = atoi((char*)context->line_buffer); 1177 log_info("Parsed supported feature %d\n", context->remote_supported_features); 1178 break; 1179 case HFP_CMD_AVAILABLE_CODECS: 1180 log_info("Parsed codec %s\n", context->line_buffer); 1181 context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); 1182 context->parser_item_index++; 1183 context->remote_codecs_nr = context->parser_item_index; 1184 break; 1185 case HFP_CMD_RETRIEVE_AG_INDICATORS: 1186 strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); 1187 context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; 1188 log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); 1189 break; 1190 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: 1191 log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); 1192 context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); 1193 context->parser_item_index++; 1194 break; 1195 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 1196 context->parser_item_index++; 1197 if (context->parser_item_index != 4) break; 1198 log_info("Parsed Enable indicators: %s\n", context->line_buffer); 1199 value = atoi((char *)&context->line_buffer[0]); 1200 context->enable_status_update_for_ag_indicators = (uint8_t) value; 1201 break; 1202 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 1203 log_info("Parsed Support call hold: %s\n", context->line_buffer); 1204 if (context->line_size > 2 ) break; 1205 strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); 1206 context->remote_call_services_nr++; 1207 break; 1208 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: 1209 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: 1210 log_info("Parsed Generic status indicator: %s\n", context->line_buffer); 1211 context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); 1212 context->parser_item_index++; 1213 context->generic_status_indicators_nr = context->parser_item_index; 1214 break; 1215 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: 1216 // HF parses inital AG gen. ind. state 1217 log_info("Parsed List generic status indicator %s state: ", context->line_buffer); 1218 context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); 1219 break; 1220 case HFP_CMD_HF_INDICATOR_STATUS: 1221 context->parser_indicator_index = (uint8_t)atoi((char*)context->line_buffer); 1222 log_info("Parsed HF indicator index %u", context->parser_indicator_index); 1223 break; 1224 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 1225 // AG parses new gen. ind. state 1226 if (context->ignore_value){ 1227 context->ignore_value = 0; 1228 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", context->parser_item_index, 1229 context->ag_indicators[context->parser_item_index].name, context->ag_indicators[context->parser_item_index].enabled); 1230 } 1231 else if (context->ag_indicators[context->parser_item_index].mandatory){ 1232 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n", 1233 context->parser_item_index, context->ag_indicators[context->parser_item_index].name); 1234 } else { 1235 value = atoi((char *)&context->line_buffer[0]); 1236 context->ag_indicators[context->parser_item_index].enabled = value; 1237 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", context->parser_item_index, 1238 context->ag_indicators[context->parser_item_index].name, value); 1239 } 1240 context->parser_item_index++; 1241 break; 1242 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 1243 // indicators are indexed starting with 1 1244 context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; 1245 log_info("Parsed status of the AG indicator %d, status ", context->parser_item_index); 1246 break; 1247 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: 1248 context->network_operator.mode = atoi((char *)&context->line_buffer[0]); 1249 log_info("Parsed network operator mode: %d, ", context->network_operator.mode); 1250 break; 1251 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: 1252 if (context->line_buffer[0] == '3'){ 1253 log_info("Parsed Set network operator format : %s, ", context->line_buffer); 1254 break; 1255 } 1256 // TODO emit ERROR, wrong format 1257 log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer); 1258 break; 1259 case HFP_CMD_ERROR: 1260 break; 1261 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 1262 context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer); 1263 break; 1264 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 1265 context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer); 1266 context->ok_pending = 1; 1267 context->extended_audio_gateway_error = 0; 1268 break; 1269 case HFP_CMD_AG_SENT_PHONE_NUMBER: 1270 strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); 1271 context->bnip_number[sizeof(context->bnip_number)-1] = 0; 1272 break; 1273 default: 1274 break; 1275 } 1276 } 1277 1278 void hfp_init(uint16_t rfcomm_channel_nr){ 1279 rfcomm_register_service(rfcomm_channel_nr, 0xffff); 1280 sdp_query_rfcomm_register_callback(handle_query_rfcomm_event, NULL); 1281 } 1282 1283 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ 1284 hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr); 1285 log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context); 1286 1287 if (!context) { 1288 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1289 return; 1290 } 1291 1292 switch (context->state){ 1293 case HFP_W2_DISCONNECT_RFCOMM: 1294 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1295 return; 1296 case HFP_W4_RFCOMM_DISCONNECTED: 1297 context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1298 return; 1299 case HFP_IDLE: 1300 memcpy(context->remote_addr, bd_addr, 6); 1301 context->state = HFP_W4_SDP_QUERY_COMPLETE; 1302 connection_doing_sdp_query = context; 1303 context->service_uuid = service_uuid; 1304 sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid); 1305 break; 1306 default: 1307 break; 1308 } 1309 } 1310 1311 void hfp_release_service_level_connection(hfp_connection_t * context){ 1312 if (!context) return; 1313 1314 if (context->state < HFP_W4_RFCOMM_CONNECTED){ 1315 context->state = HFP_IDLE; 1316 return; 1317 } 1318 1319 if (context->state == HFP_W4_RFCOMM_CONNECTED){ 1320 context->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1321 return; 1322 } 1323 1324 if (context->state < HFP_W4_SCO_CONNECTED){ 1325 context->state = HFP_W2_DISCONNECT_RFCOMM; 1326 return; 1327 } 1328 1329 if (context->state < HFP_W4_SCO_DISCONNECTED){ 1330 context->state = HFP_W2_DISCONNECT_SCO; 1331 return; 1332 } 1333 1334 return; 1335 } 1336 1337 void hfp_release_audio_connection(hfp_connection_t * context){ 1338 if (!context) return; 1339 if (context->state >= HFP_W2_DISCONNECT_SCO) return; 1340 context->release_audio_connection = 1; 1341 } 1342 1343 static const struct link_settings { 1344 const uint16_t max_latency; 1345 const uint8_t retransmission_effort; 1346 const uint16_t packet_types; 1347 } hfp_link_settings [] = { 1348 { 0xffff, 0xff, 0x03c1 }, // HFP_LINK_SETTINGS_D0, HV1 1349 { 0xffff, 0xff, 0x03c4 }, // HFP_LINK_SETTINGS_D1, HV3 1350 { 0x0007, 0x01, 0x03c8 }, // HFP_LINK_SETTINGS_S1, EV3 1351 { 0x0007, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S2, 2-EV3 1352 { 0x000a, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S3, 2-EV3 1353 { 0x000c, 0x02, 0x0380 }, // HFP_LINK_SETTINGS_S4, 2-EV3 1354 { 0x0008, 0x02, 0x03c8 }, // HFP_LINK_SETTINGS_T1, EV3 1355 { 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3 1356 }; 1357 1358 void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t setting){ 1359 // all packet types, fixed bandwidth 1360 log_info("hfp_setup_synchronous_connection using setting nr %u", setting); 1361 hci_send_cmd(&hci_setup_synchronous_connection, handle, 8000, 8000, hfp_link_settings[setting].max_latency, 1362 hci_get_sco_voice_setting(), hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380 1363 } 1364