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