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 105 hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void){ 106 return (hfp_generic_status_indicator_t *) &hfp_generic_status_indicators; 107 } 108 int get_hfp_generic_status_indicators_nr(void){ 109 return hfp_generic_status_indicators_nr; 110 } 111 void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr){ 112 if (indicator_nr > HFP_MAX_NUM_HF_INDICATORS) return; 113 hfp_generic_status_indicators_nr = indicator_nr; 114 memcpy(hfp_generic_status_indicators, indicators, indicator_nr * sizeof(hfp_generic_status_indicator_t)); 115 } 116 117 const char * hfp_hf_feature(int index){ 118 if (index > HFP_HF_FEATURES_SIZE){ 119 return hfp_hf_features[HFP_HF_FEATURES_SIZE]; 120 } 121 return hfp_hf_features[index]; 122 } 123 124 const char * hfp_ag_feature(int index){ 125 if (index > HFP_AG_FEATURES_SIZE){ 126 return hfp_ag_features[HFP_AG_FEATURES_SIZE]; 127 } 128 return hfp_ag_features[index]; 129 } 130 131 int send_str_over_rfcomm(uint16_t cid, char * command){ 132 if (!rfcomm_can_send_packet_now(cid)) return 1; 133 int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command)); 134 if (err){ 135 log_error("rfcomm_send_internal -> error 0x%02x \n", err); 136 } 137 return 1; 138 } 139 140 #if 0 141 void hfp_set_codec(hfp_connection_t * context, uint8_t *packet, uint16_t size){ 142 // parse available codecs 143 int pos = 0; 144 int i; 145 for (i=0; i<size; i++){ 146 pos+=8; 147 if (packet[pos] > context->negotiated_codec){ 148 context->negotiated_codec = packet[pos]; 149 } 150 } 151 printf("Negotiated Codec 0x%02x\n", context->negotiated_codec); 152 } 153 #endif 154 155 // UTILS 156 int get_bit(uint16_t bitmap, int position){ 157 return (bitmap >> position) & 1; 158 } 159 160 int store_bit(uint32_t bitmap, int position, uint8_t value){ 161 if (value){ 162 bitmap |= 1 << position; 163 } else { 164 bitmap &= ~ (1 << position); 165 } 166 return bitmap; 167 } 168 169 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){ 170 if (buffer_size < values_nr * 3) return 0; 171 int i; 172 int offset = 0; 173 for (i = 0; i < values_nr-1; i++) { 174 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer 175 } 176 if (i<values_nr){ 177 offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]); 178 } 179 return offset; 180 } 181 182 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){ 183 if (buffer_size < values_nr * 3) return 0; 184 185 int i; 186 int offset = 0; 187 for (i = 0; i < values_nr-1; i++) { 188 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer 189 } 190 191 if (i<values_nr){ 192 offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i)); 193 } 194 return offset; 195 } 196 197 void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8_t value){ 198 if (!callback) return; 199 uint8_t event[4]; 200 event[0] = HCI_EVENT_HFP_META; 201 event[1] = sizeof(event) - 2; 202 event[2] = event_subtype; 203 event[3] = value; // status 0 == OK 204 (*callback)(event, sizeof(event)); 205 } 206 207 208 linked_list_t * hfp_get_connections(){ 209 return (linked_list_t *) &hfp_connections; 210 } 211 212 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){ 213 linked_list_iterator_t it; 214 linked_list_iterator_init(&it, hfp_get_connections()); 215 while (linked_list_iterator_has_next(&it)){ 216 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); 217 if (connection->rfcomm_cid == cid){ 218 return connection; 219 } 220 } 221 return NULL; 222 } 223 224 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ 225 linked_list_iterator_t it; 226 linked_list_iterator_init(&it, hfp_get_connections()); 227 while (linked_list_iterator_has_next(&it)){ 228 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); 229 if (memcmp(connection->remote_addr, bd_addr, 6) == 0) { 230 return connection; 231 } 232 } 233 return NULL; 234 } 235 236 static hfp_connection_t * get_hfp_connection_context_for_handle(uint16_t handle){ 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->con_handle == handle){ 242 return connection; 243 } 244 } 245 return NULL; 246 } 247 248 void hfp_reset_context_flags(hfp_connection_t * context){ 249 if (!context) return; 250 context->wait_ok = 0; 251 context->send_ok = 0; 252 context->send_error = 0; 253 254 context->keep_separator = 0; 255 256 context->retrieve_ag_indicators = 0; // HFP_CMD_INDICATOR, check if needed 257 context->retrieve_ag_indicators_status = 0; 258 259 context->list_generic_status_indicators = 0; // HFP_CMD_LIST_GENERIC_STATUS_INDICATOR 260 context->retrieve_generic_status_indicators = 0; // HFP_CMD_GENERIC_STATUS_INDICATOR 261 context->retrieve_generic_status_indicators_state = 0; // HFP_CMD_GENERIC_STATUS_INDICATOR_STATE 262 263 context->change_status_update_for_individual_ag_indicators = 0; 264 265 context->operator_name_format = 0; 266 context->operator_name = 0; 267 context->operator_name_changed = 0; 268 269 context->enable_extended_audio_gateway_error_report = 0; 270 context->extended_audio_gateway_error = 0; 271 272 // can come any time (here taken into account only after SLE), 273 // if codec negotiation feature is set 274 context->notify_ag_on_new_codecs = 0; 275 276 // establish codecs connection 277 context->ag_trigger_codec_connection_setup = 0; 278 context->hf_trigger_codec_connection_setup = 0; 279 context->suggested_codec = 0; 280 context->negotiated_codec = 0; 281 context->codec_confirmed = 0; 282 283 context->establish_audio_connection = 0; 284 } 285 286 static hfp_connection_t * create_hfp_connection_context(){ 287 hfp_connection_t * context = btstack_memory_hfp_connection_get(); 288 if (!context) return NULL; 289 // init state 290 memset(context,0, sizeof(hfp_connection_t)); 291 292 context->state = HFP_IDLE; 293 context->parser_state = HFP_PARSER_CMD_HEADER; 294 context->command = HFP_CMD_NONE; 295 context->negotiated_codec = 0; 296 297 context->enable_status_update_for_ag_indicators = 0xFF; 298 299 context->generic_status_indicators_nr = hfp_generic_status_indicators_nr; 300 memcpy(context->generic_status_indicators, hfp_generic_status_indicators, hfp_generic_status_indicators_nr * sizeof(hfp_generic_status_indicator_t)); 301 302 linked_list_add(&hfp_connections, (linked_item_t*)context); 303 return context; 304 } 305 306 static void remove_hfp_connection_context(hfp_connection_t * context){ 307 linked_list_remove(&hfp_connections, (linked_item_t*)context); 308 } 309 310 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){ 311 hfp_connection_t * context = get_hfp_connection_context_for_bd_addr(bd_addr); 312 if (context) return context; 313 context = create_hfp_connection_context(); 314 memcpy(context->remote_addr, bd_addr, 6); 315 return context; 316 } 317 318 319 /* @param suported_features 320 * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no) 321 * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no) 322 * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no) 323 * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no) 324 * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no) 325 * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 326 */ 327 /* Bit position: 328 * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no) 329 * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no) 330 * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no) 331 * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no) 332 * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no) 333 * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no) 334 */ 335 336 337 void hfp_create_sdp_record(uint8_t * service, uint16_t service_uuid, int rfcomm_channel_nr, const char * name, uint16_t supported_features){ 338 uint8_t* attribute; 339 de_create_sequence(service); 340 341 // 0x0000 "Service Record Handle" 342 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle); 343 de_add_number(service, DE_UINT, DE_SIZE_32, 0x10001); 344 345 // 0x0001 "Service Class ID List" 346 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList); 347 attribute = de_push_sequence(service); 348 { 349 // "UUID for Service" 350 de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid); 351 de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_GenericAudio); 352 } 353 de_pop_sequence(service, attribute); 354 355 // 0x0004 "Protocol Descriptor List" 356 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ProtocolDescriptorList); 357 attribute = de_push_sequence(service); 358 { 359 uint8_t* l2cpProtocol = de_push_sequence(attribute); 360 { 361 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, SDP_L2CAPProtocol); 362 } 363 de_pop_sequence(attribute, l2cpProtocol); 364 365 uint8_t* rfcomm = de_push_sequence(attribute); 366 { 367 de_add_number(rfcomm, DE_UUID, DE_SIZE_16, SDP_RFCOMMProtocol); // rfcomm_service 368 de_add_number(rfcomm, DE_UINT, DE_SIZE_8, rfcomm_channel_nr); // rfcomm channel 369 } 370 de_pop_sequence(attribute, rfcomm); 371 } 372 de_pop_sequence(service, attribute); 373 374 375 // 0x0005 "Public Browse Group" 376 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_BrowseGroupList); // public browse group 377 attribute = de_push_sequence(service); 378 { 379 de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_PublicBrowseGroup); 380 } 381 de_pop_sequence(service, attribute); 382 383 // 0x0009 "Bluetooth Profile Descriptor List" 384 de_add_number(service, DE_UINT, DE_SIZE_16, SDP_BluetoothProfileDescriptorList); 385 attribute = de_push_sequence(service); 386 { 387 uint8_t *sppProfile = de_push_sequence(attribute); 388 { 389 de_add_number(sppProfile, DE_UUID, DE_SIZE_16, SDP_Handsfree); 390 de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7 391 } 392 de_pop_sequence(attribute, sppProfile); 393 } 394 de_pop_sequence(service, attribute); 395 396 // 0x0100 "Service Name" 397 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 398 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name); 399 400 de_add_number(service, DE_UINT, DE_SIZE_16, supported_features); 401 } 402 403 static hfp_connection_t * connection_doing_sdp_query = NULL; 404 static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context){ 405 sdp_query_rfcomm_service_event_t * ve; 406 sdp_query_complete_event_t * ce; 407 hfp_connection_t * connection = connection_doing_sdp_query; 408 409 if ( connection->state != HFP_W4_SDP_QUERY_COMPLETE) return; 410 411 switch (event->type){ 412 case SDP_QUERY_RFCOMM_SERVICE: 413 ve = (sdp_query_rfcomm_service_event_t*) event; 414 if (!connection) { 415 log_error("handle_query_rfcomm_event alloc connection for RFCOMM port %u failed", ve->channel_nr); 416 return; 417 } 418 connection->rfcomm_channel_nr = ve->channel_nr; 419 break; 420 case SDP_QUERY_COMPLETE: 421 connection_doing_sdp_query = NULL; 422 ce = (sdp_query_complete_event_t*) event; 423 424 if (connection->rfcomm_channel_nr > 0){ 425 connection->state = HFP_W4_RFCOMM_CONNECTED; 426 log_info("HFP: SDP_QUERY_COMPLETE context %p, addr %s, state %d", connection, bd_addr_to_str( connection->remote_addr), connection->state); 427 rfcomm_create_channel(connection->remote_addr, connection->rfcomm_channel_nr, NULL); 428 break; 429 } 430 log_info("rfcomm service not found, status %u.", ce->status); 431 break; 432 default: 433 break; 434 } 435 } 436 437 void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t *packet, uint16_t size){ 438 bd_addr_t event_addr; 439 uint16_t rfcomm_cid, handle; 440 hfp_connection_t * context = NULL; 441 442 switch (packet[0]) { 443 case BTSTACK_EVENT_STATE: 444 // bt stack activated, get started 445 if (packet[2] == HCI_STATE_WORKING){ 446 printf("BTstack activated, get started .\n"); 447 } 448 break; 449 450 case HCI_EVENT_PIN_CODE_REQUEST: 451 // inform about pin code request 452 printf("Pin code request - using '0000'\n\r"); 453 bt_flip_addr(event_addr, &packet[2]); 454 hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); 455 break; 456 457 case RFCOMM_EVENT_INCOMING_CONNECTION: 458 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) 459 bt_flip_addr(event_addr, &packet[2]); 460 context = get_hfp_connection_context_for_bd_addr(event_addr); 461 462 if (!context || context->state != HFP_IDLE) return; 463 464 context->rfcomm_cid = READ_BT_16(packet, 9); 465 context->state = HFP_W4_RFCOMM_CONNECTED; 466 printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr)); 467 rfcomm_accept_connection_internal(context->rfcomm_cid); 468 break; 469 470 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: 471 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) 472 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x\n", packet_type, packet[0]); 473 bt_flip_addr(event_addr, &packet[3]); 474 context = get_hfp_connection_context_for_bd_addr(event_addr); 475 if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return; 476 477 if (packet[2]) { 478 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]); 479 remove_hfp_connection_context(context); 480 } else { 481 context->con_handle = READ_BT_16(packet, 9); 482 context->rfcomm_cid = READ_BT_16(packet, 12); 483 uint16_t mtu = READ_BT_16(packet, 14); 484 printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu); 485 486 switch (context->state){ 487 case HFP_W4_RFCOMM_CONNECTED: 488 context->state = HFP_EXCHANGE_SUPPORTED_FEATURES; 489 break; 490 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN: 491 context->state = HFP_W2_DISCONNECT_RFCOMM; 492 printf("Shutting down RFCOMM.\n"); 493 break; 494 default: 495 break; 496 } 497 } 498 break; 499 500 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{ 501 int index = 2; 502 uint8_t status = packet[index++]; 503 uint16_t sco_handle = READ_BT_16(packet, index); 504 index+=2; 505 bd_addr_t address; 506 memcpy(address, &packet[index], 6); 507 index+=6; 508 uint8_t link_type = packet[index++]; 509 uint8_t transmission_interval = packet[index++]; // measured in slots 510 uint8_t retransmission_interval = packet[index++];// measured in slots 511 uint16_t rx_packet_length = READ_BT_16(packet, index); // measured in bytes 512 index+=2; 513 uint16_t tx_packet_length = READ_BT_16(packet, index); // measured in bytes 514 index+=2; 515 uint8_t air_mode = packet[index]; 516 517 if (status != 0){ 518 log_error("(e)SCO Connection is not established, status %u", status); 519 break; 520 } 521 switch (link_type){ 522 case 0x00: 523 printf("SCO Connection established. \n"); 524 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval); 525 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval); 526 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length); 527 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length); 528 break; 529 case 0x02: 530 printf("eSCO Connection established. \n"); 531 break; 532 default: 533 log_error("(e)SCO reserved link_type 0x%2x", link_type); 534 break; 535 } 536 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 537 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle, 538 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode); 539 540 context = get_hfp_connection_context_for_bd_addr(address); 541 542 if (context->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){ 543 context->state = HFP_W2_DISCONNECT_SCO; 544 break; 545 } 546 547 context->sco_handle = sco_handle; 548 context->state = HFP_AUDIO_CONNECTION_ESTABLISHED; 549 hfp_emit_event(callback, HFP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]); 550 break; 551 } 552 553 case RFCOMM_EVENT_CHANNEL_CLOSED: 554 rfcomm_cid = READ_BT_16(packet,2); 555 context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid); 556 if (!context) break; 557 if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 558 context->state = HFP_IDLE; 559 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid); 560 break; 561 } 562 563 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0); 564 remove_hfp_connection_context(context); 565 break; 566 567 case HCI_EVENT_DISCONNECTION_COMPLETE: 568 handle = READ_BT_16(packet,3); 569 context = get_hfp_connection_context_for_handle(handle); 570 if (!context) break; 571 if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){ 572 context->state = HFP_IDLE; 573 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid); 574 break; 575 } 576 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, packet[2]); 577 remove_hfp_connection_context(context); 578 break; 579 580 default: 581 break; 582 } 583 } 584 585 // translates command string into hfp_command_t CMD and flags to distinguish between CMD=, CMD?, CMD=? 586 static void process_command(hfp_connection_t * context){ 587 if (context->line_size < 2) return; 588 // printf("process_command %s\n", context->line_buffer); 589 context->command = HFP_CMD_NONE; 590 int offset = 0; 591 int isHandsFree = 1; 592 593 if (strncmp((char *)context->line_buffer, "AT", 2) == 0){ 594 offset = 2; 595 isHandsFree = 0; 596 } 597 598 if (strncmp((char *)context->line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){ 599 context->command = HFP_CMD_ERROR; 600 return; 601 } 602 603 if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){ 604 //printf("parsed HFP_CMD_OK \n"); 605 context->command = HFP_CMD_OK; 606 return; 607 } 608 609 if (strncmp((char *)context->line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ 610 context->command = HFP_CMD_SUPPORTED_FEATURES; 611 return; 612 } 613 614 if (strncmp((char *)context->line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ 615 //printf("parsed HFP_INDICATOR \n"); 616 context->command = HFP_CMD_INDICATOR; 617 if (isHandsFree) return; 618 619 if (strncmp((char *)context->line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){ 620 context->retrieve_ag_indicators_status = 1; 621 context->retrieve_ag_indicators = 0; 622 } else { 623 context->retrieve_ag_indicators = 1; 624 context->retrieve_ag_indicators_status = 0; 625 } 626 return; 627 } 628 629 if (strncmp((char *)context->line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ 630 context->command = HFP_CMD_AVAILABLE_CODECS; 631 context->notify_ag_on_new_codecs = 1; 632 return; 633 } 634 635 if (strncmp((char *)context->line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){ 636 context->command = HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; 637 return; 638 } 639 640 if (strncmp((char *)context->line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ 641 context->command = HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; 642 return; 643 } 644 645 if (strncmp((char *)context->line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ 646 context->command = HFP_CMD_GENERIC_STATUS_INDICATOR; 647 if (isHandsFree) return; 648 649 if (strncmp((char *)context->line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ 650 context->list_generic_status_indicators = 0; 651 context->retrieve_generic_status_indicators = 1; 652 context->retrieve_generic_status_indicators_state = 0; 653 } else if (strncmp((char *)context->line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ 654 context->list_generic_status_indicators = 1; 655 context->retrieve_generic_status_indicators = 0; 656 context->retrieve_generic_status_indicators_state = 0; 657 } else { 658 context->list_generic_status_indicators = 0; 659 context->retrieve_generic_status_indicators = 0; 660 context->retrieve_generic_status_indicators_state = 1; 661 } 662 return; 663 } 664 665 if (strncmp((char *)context->line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ 666 context->command = HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; 667 return; 668 } 669 670 671 if (strncmp((char *)context->line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ 672 context->command = HFP_CMD_QUERY_OPERATOR_SELECTION; 673 context->operator_name = 1; 674 context->operator_name_format = 0; 675 if (isHandsFree) return; 676 677 context->operator_name = 0; 678 if (strncmp((char *)context->line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){ 679 context->operator_name_format = 1; 680 } 681 return; 682 } 683 684 if (strncmp((char *)context->line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ 685 context->command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; 686 return; 687 } 688 689 if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 690 context->command = HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; 691 return; 692 } 693 694 if (!isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ 695 context->command = HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; 696 return; 697 } 698 699 if (strncmp((char *)context->line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){ 700 context->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; 701 // printf("HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP update command\n"); 702 if (isHandsFree){ 703 context->hf_trigger_codec_connection_setup = 1; 704 printf("update command: hf_trigger_codec_connection_setup = 1\n"); 705 } else { 706 context->hf_trigger_codec_connection_setup = 1; 707 printf("update command: hf_trigger_codec_connection_setup = 1\n"); 708 } 709 return; 710 } 711 712 if (strncmp((char *)context->line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){ 713 if (!isHandsFree){ 714 context->command = HFP_CMD_HF_CONFIRMED_CODEC; 715 } else { 716 context->command = HFP_CMD_AG_SUGGESTED_CODEC; 717 } 718 return; 719 } 720 721 if (strncmp((char *)context->line_buffer+offset, "NOP", 3) == 0) return; 722 723 printf(" process unknown command 3 %s \n", context->line_buffer); 724 } 725 726 #if 0 727 uint32_t fromBinary(char *s) { 728 return (uint32_t) strtol(s, NULL, 2); 729 } 730 #endif 731 732 static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){ 733 // TODO: add limit 734 context->line_buffer[context->line_size++] = byte; 735 context->line_buffer[context->line_size] = 0; 736 } 737 static int hfp_parser_is_buffer_empty(hfp_connection_t * context){ 738 return context->line_size == 0; 739 } 740 741 static int hfp_parser_is_end_of_line(uint8_t byte){ 742 return byte == '\n' || byte == '\r'; 743 } 744 745 static int hfp_parser_is_end_of_header(uint8_t byte){ 746 return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; 747 } 748 749 static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ 750 if (context->keep_separator == 1) return 1; 751 752 int found_separator = byte == ',' || byte == '\n'|| byte == '\r'|| 753 byte == ')' || byte == '(' || byte == ':' || 754 byte == '-' || byte == '"' || byte == '?'|| byte == '='; 755 return found_separator; 756 } 757 758 static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ 759 context->line_size = 0; 760 if (hfp_parser_is_end_of_line(byte)){ 761 context->parser_item_index = 0; 762 context->parser_state = HFP_PARSER_CMD_HEADER; 763 return; 764 } 765 switch (context->parser_state){ 766 case HFP_PARSER_CMD_HEADER: 767 context->parser_state = HFP_PARSER_CMD_SEQUENCE; 768 if (context->keep_separator == 1){ 769 hfp_parser_store_byte(context, byte); 770 context->keep_separator = 0; 771 } 772 break; 773 case HFP_PARSER_CMD_SEQUENCE: 774 switch (context->command){ 775 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 776 case HFP_CMD_QUERY_OPERATOR_SELECTION: 777 context->parser_state = HFP_PARSER_SECOND_ITEM; 778 break; 779 case HFP_CMD_INDICATOR: 780 if (context->retrieve_ag_indicators == 1){ 781 context->parser_state = HFP_PARSER_SECOND_ITEM; 782 break; 783 } 784 break; 785 case HFP_CMD_GENERIC_STATUS_INDICATOR: 786 if (context->retrieve_generic_status_indicators_state == 1){ 787 context->parser_state = HFP_PARSER_SECOND_ITEM; 788 break; 789 } 790 break; 791 default: 792 break; 793 } 794 break; 795 case HFP_PARSER_SECOND_ITEM: 796 context->parser_state = HFP_PARSER_THIRD_ITEM; 797 break; 798 case HFP_PARSER_THIRD_ITEM: 799 if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ 800 context->parser_state = HFP_PARSER_CMD_SEQUENCE; 801 break; 802 } 803 context->parser_state = HFP_PARSER_CMD_HEADER; 804 break; 805 } 806 } 807 808 void hfp_parse(hfp_connection_t * context, uint8_t byte){ 809 int value; 810 811 // TODO: handle space inside word 812 if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return; 813 814 if (!hfp_parser_found_separator(context, byte)){ 815 hfp_parser_store_byte(context, byte); 816 return; 817 } 818 if (hfp_parser_is_end_of_line(byte)) { 819 if (hfp_parser_is_buffer_empty(context)){ 820 context->parser_state = HFP_PARSER_CMD_HEADER; 821 } 822 } 823 if (hfp_parser_is_buffer_empty(context)) return; 824 825 826 switch (context->parser_state){ 827 case HFP_PARSER_CMD_HEADER: // header 828 if (byte == '='){ 829 context->keep_separator = 1; 830 hfp_parser_store_byte(context, byte); 831 return; 832 } 833 834 if (byte == '?'){ 835 context->keep_separator = 0; 836 hfp_parser_store_byte(context, byte); 837 return; 838 } 839 // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator); 840 if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){ 841 // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator); 842 process_command(context); 843 } 844 break; 845 846 case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes 847 switch (context->command){ 848 case HFP_CMD_HF_CONFIRMED_CODEC: 849 context->codec_confirmed = atoi((char*)context->line_buffer); 850 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed); 851 break; 852 case HFP_CMD_AG_SUGGESTED_CODEC: 853 context->suggested_codec = atoi((char*)context->line_buffer); 854 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec); 855 break; 856 case HFP_CMD_SUPPORTED_FEATURES: 857 context->remote_supported_features = atoi((char*)context->line_buffer); 858 log_info("Parsed supported feature %d\n", context->remote_supported_features); 859 break; 860 case HFP_CMD_AVAILABLE_CODECS: 861 log_info("Parsed codec %s\n", context->line_buffer); 862 context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); 863 context->parser_item_index++; 864 context->remote_codecs_nr = context->parser_item_index; 865 break; 866 case HFP_CMD_INDICATOR: 867 if (context->retrieve_ag_indicators == 1){ 868 strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); 869 context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; 870 log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); 871 } 872 873 if (context->retrieve_ag_indicators_status == 1){ 874 log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); 875 context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); 876 context->parser_item_index++; 877 break; 878 } 879 break; 880 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 881 context->parser_item_index++; 882 if (context->parser_item_index != 4) break; 883 log_info("Parsed Enable indicators: %s\n", context->line_buffer); 884 value = atoi((char *)&context->line_buffer[0]); 885 context->enable_status_update_for_ag_indicators = (uint8_t) value; 886 break; 887 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 888 log_info("Parsed Support call hold: %s\n", context->line_buffer); 889 if (context->line_size > 2 ) break; 890 strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); 891 context->remote_call_services_nr++; 892 break; 893 case HFP_CMD_GENERIC_STATUS_INDICATOR: 894 log_info("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n", 895 context->list_generic_status_indicators, 896 context->retrieve_generic_status_indicators, 897 context->retrieve_generic_status_indicators_state); 898 if (context->retrieve_generic_status_indicators == 1 || context->list_generic_status_indicators == 1){ 899 log_info("Parsed Generic status indicator: %s\n", context->line_buffer); 900 context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); 901 context->parser_item_index++; 902 context->generic_status_indicators_nr = context->parser_item_index; 903 break; 904 } 905 log_info("parser HFP_CMD_GENERIC_STATUS_INDICATOR 2\n"); 906 if (context->retrieve_generic_status_indicators_state == 1){ 907 // HF parses inital AG gen. ind. state 908 log_info("Parsed List generic status indicator %s state: ", context->line_buffer); 909 context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); 910 break; 911 } 912 break; 913 914 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: 915 // AG parses new gen. ind. state 916 log_info("Parsed Enable ag indicator state: %s\n", context->line_buffer); 917 value = atoi((char *)&context->line_buffer[0]); 918 if (!context->ag_indicators[context->parser_item_index].mandatory){ 919 context->ag_indicators[context->parser_item_index].enabled = value; 920 } 921 context->parser_item_index++; 922 break; 923 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 924 // indicators are indexed starting with 1 925 context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; 926 log_info("Parsed status of the AG indicator %d, status ", context->parser_item_index); 927 break; 928 case HFP_CMD_QUERY_OPERATOR_SELECTION: 929 if (context->operator_name_format == 1){ 930 if (context->line_buffer[0] == '3'){ 931 log_info("Parsed Set network operator format : %s, ", context->line_buffer); 932 break; 933 } 934 // TODO emit ERROR, wrong format 935 log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer); 936 break; 937 } 938 939 if (context->operator_name == 1) { 940 context->network_operator.mode = atoi((char *)&context->line_buffer[0]); 941 log_info("Parsed network operator mode: %d, ", context->network_operator.mode); 942 break; 943 } 944 break; 945 case HFP_CMD_ERROR: 946 break; 947 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: 948 context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer); 949 break; 950 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 951 context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer); 952 context->send_ok = 1; 953 context->extended_audio_gateway_error = 0; 954 break; 955 default: 956 break; 957 } 958 break; 959 960 case HFP_PARSER_SECOND_ITEM: 961 switch (context->command){ 962 case HFP_CMD_QUERY_OPERATOR_SELECTION: 963 if (context->operator_name_format == 1) { 964 log_info("format %s \n", context->line_buffer); 965 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 966 break; 967 } 968 if (context->operator_name == 1){ 969 log_info("format %s, ", context->line_buffer); 970 context->network_operator.format = atoi((char *)&context->line_buffer[0]); 971 } 972 break; 973 case HFP_CMD_GENERIC_STATUS_INDICATOR: 974 context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); 975 break; 976 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: 977 context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); 978 context->ag_indicators[context->parser_item_index].status_changed = 1; 979 break; 980 case HFP_CMD_INDICATOR: 981 if (context->retrieve_ag_indicators == 1){ 982 context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); 983 log_info("%s, ", context->line_buffer); 984 } 985 break; 986 default: 987 break; 988 } 989 break; 990 991 case HFP_PARSER_THIRD_ITEM: 992 switch (context->command){ 993 case HFP_CMD_QUERY_OPERATOR_SELECTION: 994 if (context->operator_name == 1){ 995 strcpy(context->network_operator.name, (char *)context->line_buffer); 996 log_info("name %s\n", context->line_buffer); 997 } 998 break; 999 case HFP_CMD_INDICATOR: 1000 if (context->retrieve_ag_indicators == 1){ 1001 context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); 1002 context->parser_item_index++; 1003 context->ag_indicators_nr = context->parser_item_index; 1004 log_info("%s)\n", context->line_buffer); 1005 } 1006 break; 1007 default: 1008 break; 1009 } 1010 break; 1011 } 1012 hfp_parser_next_state(context, byte); 1013 } 1014 1015 void hfp_init(uint16_t rfcomm_channel_nr){ 1016 rfcomm_register_service(rfcomm_channel_nr, 0xffff); 1017 sdp_query_rfcomm_register_callback(handle_query_rfcomm_event, NULL); 1018 } 1019 1020 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){ 1021 hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr); 1022 log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context); 1023 1024 if (!context) { 1025 log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); 1026 return; 1027 } 1028 switch (context->state){ 1029 case HFP_W2_DISCONNECT_RFCOMM: 1030 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 1031 return; 1032 case HFP_W4_RFCOMM_DISCONNECTED: 1033 context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; 1034 return; 1035 case HFP_IDLE: 1036 memcpy(context->remote_addr, bd_addr, 6); 1037 context->state = HFP_W4_SDP_QUERY_COMPLETE; 1038 connection_doing_sdp_query = context; 1039 context->service_uuid = service_uuid; 1040 sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid); 1041 break; 1042 default: 1043 break; 1044 } 1045 } 1046 1047 void hfp_release_service_level_connection(hfp_connection_t * context){ 1048 if (!context) return; 1049 1050 if (context->state < HFP_W4_RFCOMM_CONNECTED){ 1051 context->state = HFP_IDLE; 1052 return; 1053 } 1054 1055 if (context->state == HFP_W4_RFCOMM_CONNECTED){ 1056 context->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN; 1057 return; 1058 } 1059 1060 if (context->state < HFP_CCE_W4_SCO_CONNECTION_ESTABLISHED){ 1061 context->state = HFP_W2_DISCONNECT_RFCOMM; 1062 return; 1063 } 1064 1065 if (context->state < HFP_W4_SCO_DISCONNECTED){ 1066 context->state = HFP_W2_DISCONNECT_SCO; 1067 return; 1068 } 1069 1070 return; 1071 } 1072 1073 void hfp_release_audio_connection(hfp_connection_t * connection){ 1074 if (!connection) return; 1075 if (connection->state >= HFP_W2_DISCONNECT_SCO) return; 1076 connection->release_audio_connection = 1; 1077 } 1078 1079 1080