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 Hands-Free (HF) 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 51 #include "hci_cmds.h" 52 #include "run_loop.h" 53 54 #include "hci.h" 55 #include "btstack_memory.h" 56 #include "hci_dump.h" 57 #include "l2cap.h" 58 #include "sdp_query_rfcomm.h" 59 #include "sdp.h" 60 #include "debug.h" 61 #include "hfp.h" 62 #include "hfp_hf.h" 63 64 65 static const char default_hfp_hf_service_name[] = "Hands-Free unit"; 66 static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES; 67 static uint8_t hfp_codecs_nr = 0; 68 static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; 69 70 static uint8_t hfp_indicators_nr = 0; 71 static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS]; 72 static uint8_t hfp_indicators_status; 73 74 static hfp_callback_t hfp_callback; 75 76 void hfp_hf_register_packet_handler(hfp_callback_t callback){ 77 hfp_callback = callback; 78 if (callback == NULL){ 79 log_error("hfp_hf_register_packet_handler called with NULL callback"); 80 return; 81 } 82 hfp_callback = callback; 83 } 84 85 static int hfp_hf_supports_codec(uint8_t codec){ 86 int i; 87 for (i = 0; i < hfp_codecs_nr; i++){ 88 if (hfp_codecs[i] == codec) return 1; 89 } 90 return 0; 91 } 92 static int has_codec_negotiation_feature(hfp_connection_t * connection){ 93 int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION); 94 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); 95 return hf && ag; 96 } 97 98 static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){ 99 int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING); 100 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); 101 return hf && ag; 102 } 103 104 105 static int has_hf_indicators_feature(hfp_connection_t * connection){ 106 int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS); 107 int ag = get_bit(connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); 108 return hf && ag; 109 } 110 111 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 112 113 void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint16_t supported_features){ 114 if (!name){ 115 name = default_hfp_hf_service_name; 116 } 117 hfp_create_sdp_record(service, SDP_Handsfree, rfcomm_channel_nr, name, supported_features); 118 } 119 120 121 static int hfp_hf_cmd_exchange_supported_features(uint16_t cid){ 122 char buffer[20]; 123 sprintf(buffer, "AT%s=%d\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features); 124 // printf("exchange_supported_features %s\n", buffer); 125 return send_str_over_rfcomm(cid, buffer); 126 } 127 128 static int hfp_hf_cmd_notify_on_codecs(uint16_t cid){ 129 char buffer[30]; 130 int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_AVAILABLE_CODECS); 131 offset += join(buffer+offset, sizeof(buffer)-offset, hfp_codecs, hfp_codecs_nr); 132 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); 133 buffer[offset] = 0; 134 return send_str_over_rfcomm(cid, buffer); 135 } 136 137 static int hfp_hf_cmd_retrieve_indicators(uint16_t cid){ 138 char buffer[20]; 139 sprintf(buffer, "AT%s=?\r\n", HFP_INDICATOR); 140 // printf("retrieve_indicators %s\n", buffer); 141 return send_str_over_rfcomm(cid, buffer); 142 } 143 144 static int hfp_hf_cmd_retrieve_indicators_status(uint16_t cid){ 145 char buffer[20]; 146 sprintf(buffer, "AT%s?\r\n", HFP_INDICATOR); 147 // printf("retrieve_indicators_status %s\n", buffer); 148 return send_str_over_rfcomm(cid, buffer); 149 } 150 151 static int hfp_hf_cmd_activate_status_update_for_all_ag_indicators(uint16_t cid, uint8_t activate){ 152 char buffer[20]; 153 sprintf(buffer, "AT%s=3,0,0,%d\r\n", HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, activate); 154 // printf("toggle_indicator_status_update %s\n", buffer); 155 return send_str_over_rfcomm(cid, buffer); 156 } 157 158 static int hfp_hf_cmd_activate_status_update_for_ag_indicator(uint16_t cid, uint32_t indicators_status, int indicators_nr){ 159 char buffer[50]; 160 int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS); 161 offset += join_bitmap(buffer+offset, sizeof(buffer)-offset, indicators_status, indicators_nr); 162 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); 163 buffer[offset] = 0; 164 return send_str_over_rfcomm(cid, buffer); 165 } 166 167 static int hfp_hf_cmd_retrieve_can_hold_call(uint16_t cid){ 168 char buffer[20]; 169 sprintf(buffer, "AT%s=?\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); 170 // printf("retrieve_can_hold_call %s\n", buffer); 171 return send_str_over_rfcomm(cid, buffer); 172 } 173 174 static int hfp_hf_cmd_list_supported_generic_status_indicators(uint16_t cid){ 175 char buffer[30]; 176 int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_GENERIC_STATUS_INDICATOR); 177 offset += join(buffer+offset, sizeof(buffer)-offset, hfp_indicators, hfp_indicators_nr); 178 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n"); 179 buffer[offset] = 0; 180 return send_str_over_rfcomm(cid, buffer); 181 } 182 183 static int hfp_hf_cmd_retrieve_supported_generic_status_indicators(uint16_t cid){ 184 char buffer[20]; 185 sprintf(buffer, "AT%s=?\r\n", HFP_GENERIC_STATUS_INDICATOR); 186 // printf("retrieve_supported_generic_status_indicators %s\n", buffer); 187 return send_str_over_rfcomm(cid, buffer); 188 } 189 190 static int hfp_hf_cmd_list_initital_supported_generic_status_indicators(uint16_t cid){ 191 char buffer[20]; 192 sprintf(buffer, "AT%s?\r\n", HFP_GENERIC_STATUS_INDICATOR); 193 // printf("list_initital_supported_generic_status_indicators %s\n", buffer); 194 return send_str_over_rfcomm(cid, buffer); 195 } 196 197 static int hfp_hf_cmd_query_operator_name_format(uint16_t cid){ 198 char buffer[20]; 199 sprintf(buffer, "AT%s=3,0\r\n", HFP_QUERY_OPERATOR_SELECTION); 200 return send_str_over_rfcomm(cid, buffer); 201 } 202 203 static int hfp_hf_cmd_query_operator_name(uint16_t cid){ 204 char buffer[20]; 205 sprintf(buffer, "AT%s?\r\n", HFP_QUERY_OPERATOR_SELECTION); 206 return send_str_over_rfcomm(cid, buffer); 207 } 208 209 static int hfp_hf_cmd_enable_extended_audio_gateway_error_report(uint16_t cid, uint8_t enable){ 210 char buffer[20]; 211 sprintf(buffer, "AT%s=%d\r\n", HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, enable); 212 return send_str_over_rfcomm(cid, buffer); 213 } 214 215 static int hfp_hf_cmd_trigger_codec_connection_setup(uint16_t cid){ 216 char buffer[20]; 217 sprintf(buffer, "AT%s\r\n", HFP_TRIGGER_CODEC_CONNECTION_SETUP); 218 return send_str_over_rfcomm(cid, buffer); 219 } 220 221 static int hfp_hf_cmd_confirm_codec(uint16_t cid, uint8_t codec){ 222 char buffer[20]; 223 sprintf(buffer, "AT%s=%d\r\n", HFP_CONFIRM_COMMON_CODEC, codec); 224 return send_str_over_rfcomm(cid, buffer); 225 } 226 227 static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){ 228 if (!callback) return; 229 uint8_t event[6]; 230 event[0] = HCI_EVENT_HFP_META; 231 event[1] = sizeof(event) - 2; 232 event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; 233 event[3] = status; 234 event[4] = indicator.index; 235 event[5] = indicator.status; 236 (*callback)(event, sizeof(event)); 237 } 238 239 static void hfp_emit_network_operator_event(hfp_callback_t callback, int status, hfp_network_opearator_t network_operator){ 240 if (!callback) return; 241 uint8_t event[24]; 242 event[0] = HCI_EVENT_HFP_META; 243 event[1] = sizeof(event) - 2; 244 event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; 245 event[3] = status; 246 event[4] = network_operator.mode; 247 event[5] = network_operator.format; 248 strcpy((char*)&event[6], network_operator.name); 249 (*callback)(event, sizeof(event)); 250 } 251 252 static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * context){ 253 if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; 254 int done = 0; 255 if (context->wait_ok) return done; 256 257 switch (context->state){ 258 case HFP_EXCHANGE_SUPPORTED_FEATURES: 259 hfp_hf_cmd_exchange_supported_features(context->rfcomm_cid); 260 context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; 261 break; 262 case HFP_NOTIFY_ON_CODECS: 263 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); 264 context->state = HFP_W4_NOTIFY_ON_CODECS; 265 break; 266 case HFP_RETRIEVE_INDICATORS: 267 hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid); 268 context->state = HFP_W4_RETRIEVE_INDICATORS; 269 context->retrieve_ag_indicators = 1; 270 context->retrieve_ag_indicators_status = 0; 271 break; 272 case HFP_RETRIEVE_INDICATORS_STATUS: 273 hfp_hf_cmd_retrieve_indicators_status(context->rfcomm_cid); 274 context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; 275 context->retrieve_ag_indicators_status = 1; 276 context->retrieve_ag_indicators = 0; 277 break; 278 case HFP_ENABLE_INDICATORS_STATUS_UPDATE: 279 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, 1); 280 context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; 281 break; 282 case HFP_RETRIEVE_CAN_HOLD_CALL: 283 hfp_hf_cmd_retrieve_can_hold_call(context->rfcomm_cid); 284 context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; 285 break; 286 case HFP_LIST_GENERIC_STATUS_INDICATORS: 287 hfp_hf_cmd_list_supported_generic_status_indicators(context->rfcomm_cid); 288 context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; 289 context->list_generic_status_indicators = 1; 290 context->retrieve_generic_status_indicators = 0; 291 context->retrieve_generic_status_indicators_state = 0; 292 break; 293 case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS: 294 hfp_hf_cmd_retrieve_supported_generic_status_indicators(context->rfcomm_cid); 295 context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; 296 context->list_generic_status_indicators = 0; 297 context->retrieve_generic_status_indicators = 1; 298 context->retrieve_generic_status_indicators_state = 0; 299 break; 300 case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 301 hfp_hf_cmd_list_initital_supported_generic_status_indicators(context->rfcomm_cid); 302 context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 303 context->list_generic_status_indicators = 0; 304 context->retrieve_generic_status_indicators = 0; 305 context->retrieve_generic_status_indicators_state = 1; 306 break; 307 default: 308 break; 309 } 310 return done; 311 } 312 313 static void hfp_hf_handle_ok_service_level_connection_establishment(hfp_connection_t *context){ 314 if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; 315 switch (context->state){ 316 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: 317 if (has_codec_negotiation_feature(context)){ 318 context->state = HFP_NOTIFY_ON_CODECS; 319 break; 320 } 321 context->state = HFP_RETRIEVE_INDICATORS; 322 break; 323 324 case HFP_W4_NOTIFY_ON_CODECS: 325 context->state = HFP_RETRIEVE_INDICATORS; 326 break; 327 328 case HFP_W4_RETRIEVE_INDICATORS: 329 context->state = HFP_RETRIEVE_INDICATORS_STATUS; 330 context->retrieve_ag_indicators = 0; 331 break; 332 333 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 334 context->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE; 335 context->retrieve_ag_indicators_status = 0; 336 break; 337 338 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: 339 if (has_call_waiting_and_3way_calling_feature(context)){ 340 context->state = HFP_RETRIEVE_CAN_HOLD_CALL; 341 break; 342 } 343 if (has_hf_indicators_feature(context)){ 344 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 345 break; 346 } 347 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 348 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 349 break; 350 351 case HFP_W4_RETRIEVE_CAN_HOLD_CALL: 352 if (has_hf_indicators_feature(context)){ 353 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS; 354 break; 355 } 356 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 357 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 358 break; 359 360 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 361 context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS; 362 context->retrieve_generic_status_indicators = 0; 363 break; 364 365 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 366 context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 367 context->retrieve_generic_status_indicators = 0; 368 break; 369 370 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 371 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 372 context->retrieve_generic_status_indicators_state = 0; 373 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 374 break; 375 default: 376 break; 377 } 378 } 379 380 static void hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * context){ 381 if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; 382 if (context->wait_ok) return; 383 384 if (context->enable_status_update_for_ag_indicators != 0xFF){ 385 hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, context->enable_status_update_for_ag_indicators); 386 context->wait_ok = 1; 387 return; 388 }; 389 if (context->change_status_update_for_individual_ag_indicators){ 390 hfp_hf_cmd_activate_status_update_for_ag_indicator(context->rfcomm_cid, 391 context->ag_indicators_status_update_bitmap, 392 context->ag_indicators_nr); 393 context->wait_ok = 1; 394 return; 395 } 396 397 if (context->operator_name_format){ 398 hfp_hf_cmd_query_operator_name_format(context->rfcomm_cid); 399 context->wait_ok = 1; 400 return; 401 } 402 if (context->operator_name){ 403 hfp_hf_cmd_query_operator_name(context->rfcomm_cid); 404 context->wait_ok = 1; 405 return; 406 } 407 408 if (context->enable_extended_audio_gateway_error_report){ 409 hfp_hf_cmd_enable_extended_audio_gateway_error_report(context->rfcomm_cid, context->enable_extended_audio_gateway_error_report); 410 context->wait_ok = 1; 411 return; 412 } 413 } 414 415 static void hfp_hf_handle_ok_service_level_connection_queries(hfp_connection_t * context){ 416 if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return; 417 418 if (context->enable_status_update_for_ag_indicators != 0xFF){ 419 context->enable_status_update_for_ag_indicators = 0xFF; 420 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0); 421 return; 422 }; 423 424 if (context->change_status_update_for_individual_ag_indicators == 1){ 425 context->change_status_update_for_individual_ag_indicators = 0; 426 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0); 427 return; 428 } 429 430 if (context->operator_name_format){ 431 context->operator_name_format = 0; 432 context->operator_name = 1; 433 return; 434 } 435 436 if (context->operator_name){ 437 context->operator_name = 0; 438 hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator); 439 return; 440 } 441 if (context->enable_extended_audio_gateway_error_report){ 442 context->enable_extended_audio_gateway_error_report = 0; 443 return; 444 } 445 } 446 447 448 static void hfp_hf_run_for_context_codecs_connection(hfp_connection_t * context){ 449 // if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED && context->state <= HFP_AUDIO_CONNECTION_ESTABLISHED){ 450 451 // handle audio connection setup 452 // printf("hfp_run_for_context state %d \n", context->state); 453 if (context->wait_ok) return; 454 455 switch (context->state){ 456 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 457 if (context->notify_ag_on_new_codecs){ 458 context->wait_ok = 1; 459 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); 460 break; 461 } 462 463 if (context->hf_trigger_codec_connection_setup){ 464 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; 465 context->wait_ok = 1; 466 hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid); 467 break; 468 } 469 470 if (context->suggested_codec){ 471 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 472 context->codec_confirmed = 1; 473 context->wait_ok = 1; 474 hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec); 475 break; 476 } 477 break; 478 479 case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: 480 if (context->notify_ag_on_new_codecs){ 481 context->wait_ok = 1; 482 context->codec_confirmed = 0; 483 context->suggested_codec = 0; 484 context->negotiated_codec = 0; 485 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); 486 break; 487 } 488 if (context->suggested_codec){ 489 if (hfp_hf_supports_codec(context->suggested_codec)){ 490 context->codec_confirmed = context->suggested_codec; 491 context->wait_ok = 1; 492 hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec); 493 } else { 494 context->notify_ag_on_new_codecs = 1; 495 context->wait_ok = 1; 496 context->codec_confirmed = 0; 497 context->suggested_codec = 0; 498 context->negotiated_codec = 0; 499 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); 500 } 501 502 break; 503 } 504 505 break; 506 507 case HFP_CODECS_CONNECTION_ESTABLISHED: 508 if (context->notify_ag_on_new_codecs){ 509 context->negotiated_codec = 0; 510 context->wait_ok = 1; 511 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 512 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); 513 break; 514 } 515 516 if (context->hf_trigger_codec_connection_setup){ 517 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; 518 context->wait_ok = 1; 519 hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid); 520 break; 521 } 522 523 if (context->establish_audio_connection){ 524 // TODO AUDIO CONNECTION 525 } 526 break; 527 default: 528 break; 529 } 530 } 531 532 static void hfp_hf_handle_ok_codecs_connection(hfp_connection_t * context){ 533 // handle audio connection setup 534 switch (context->state){ 535 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 536 if (context->notify_ag_on_new_codecs){ 537 context->notify_ag_on_new_codecs = 0; 538 break; 539 } 540 case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: 541 if (context->hf_trigger_codec_connection_setup){ 542 context->hf_trigger_codec_connection_setup = 0; 543 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 544 break; 545 } 546 break; 547 case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: 548 if (context->notify_ag_on_new_codecs){ 549 context->codec_confirmed = 0; 550 context->suggested_codec = 0; 551 context->notify_ag_on_new_codecs = 0; 552 break; 553 } 554 if (context->codec_confirmed && context->suggested_codec){ 555 context->negotiated_codec = context->suggested_codec; 556 context->codec_confirmed = 0; 557 context->suggested_codec = 0; 558 context->state = HFP_CODECS_CONNECTION_ESTABLISHED; 559 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0); 560 break; 561 } 562 break; 563 564 case HFP_AUDIO_CONNECTION_ESTABLISHED: 565 printf("HFP_AUDIO_CONNECTION_ESTABLISHED \n"); 566 break; 567 568 default: 569 break; 570 } 571 } 572 573 static void hfp_run_for_context(hfp_connection_t * context){ 574 575 if (!context) return; 576 if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; 577 578 hfp_hf_run_for_context_service_level_connection(context); 579 hfp_hf_run_for_context_service_level_connection_queries(context); 580 hfp_hf_run_for_context_codecs_connection(context); 581 582 // deal with disconnect 583 switch (context->state){ 584 case HFP_W2_DISCONNECT_RFCOMM: 585 context->state = HFP_W4_RFCOMM_DISCONNECTED; 586 rfcomm_disconnect_internal(context->rfcomm_cid); 587 break; 588 589 default: 590 break; 591 } 592 } 593 594 static void hfp_hf_switch_on_ok(hfp_connection_t *context){ 595 // printf("switch on ok\n"); 596 context->wait_ok = 0; 597 598 hfp_hf_handle_ok_service_level_connection_establishment(context); 599 hfp_hf_handle_ok_service_level_connection_queries(context); 600 hfp_hf_handle_ok_codecs_connection(context); 601 602 // done 603 context->command = HFP_CMD_NONE; 604 } 605 606 607 static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 608 hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel); 609 if (!context) return; 610 611 packet[size] = 0; 612 int pos, i; 613 //printf("\nHF received: %s", packet+2); 614 for (pos = 0; pos < size ; pos++){ 615 hfp_parse(context, packet[pos]); 616 617 // emit indicators status changed 618 for (i = 0; i < context->ag_indicators_nr; i++){ 619 if (context->ag_indicators[i].status_changed) { 620 hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]); 621 context->ag_indicators[i].status_changed = 0; 622 break; 623 } 624 } 625 626 if (context->command == HFP_CMD_ERROR){ 627 context->wait_ok = 0; 628 hfp_reset_context_flags(context); 629 hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1); 630 return; 631 } 632 if (context->command == HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR){ 633 context->wait_ok = 0; 634 hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error); 635 context->extended_audio_gateway_error = 0; 636 return; 637 } 638 639 if (context->command != HFP_CMD_OK) continue; 640 hfp_hf_switch_on_ok(context); 641 } 642 } 643 644 static void hfp_run(){ 645 linked_list_iterator_t it; 646 linked_list_iterator_init(&it, hfp_get_connections()); 647 while (linked_list_iterator_has_next(&it)){ 648 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); 649 hfp_run_for_context(connection); 650 } 651 } 652 653 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 654 switch (packet_type){ 655 case RFCOMM_DATA_PACKET: 656 hfp_handle_rfcomm_event(packet_type, channel, packet, size); 657 break; 658 case HCI_EVENT_PACKET: 659 hfp_handle_hci_event(hfp_callback, packet_type, packet, size); 660 default: 661 break; 662 } 663 hfp_run(); 664 } 665 666 void hfp_hf_set_codecs(uint8_t * codecs, int codecs_nr){ 667 if (codecs_nr > HFP_MAX_NUM_CODECS){ 668 log_error("hfp_hf_set_codecs: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS); 669 return; 670 } 671 672 hfp_codecs_nr = codecs_nr; 673 int i; 674 for (i=0; i<codecs_nr; i++){ 675 hfp_codecs[i] = codecs[i]; 676 } 677 678 char buffer[30]; 679 int offset = join(buffer, sizeof(buffer), hfp_codecs, hfp_codecs_nr); 680 buffer[offset] = 0; 681 printf("set codecs %s\n", buffer); 682 683 linked_list_iterator_t it; 684 linked_list_iterator_init(&it, hfp_get_connections()); 685 while (linked_list_iterator_has_next(&it)){ 686 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); 687 if (!connection) continue; 688 connection->notify_ag_on_new_codecs = 1; 689 hfp_run_for_context(connection); 690 } 691 } 692 693 void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint16_t * indicators, int indicators_nr, uint32_t indicators_status){ 694 rfcomm_register_packet_handler(packet_handler); 695 hfp_init(rfcomm_channel_nr); 696 697 hfp_supported_features = supported_features; 698 699 hfp_indicators_nr = indicators_nr; 700 hfp_indicators_status = indicators_status; 701 int i; 702 for (i=0; i<indicators_nr; i++){ 703 hfp_indicators[i] = indicators[i]; 704 } 705 } 706 707 void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){ 708 hfp_establish_service_level_connection(bd_addr, SDP_HandsfreeAudioGateway); 709 } 710 711 void hfp_hf_release_service_level_connection(bd_addr_t bd_addr){ 712 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 713 hfp_release_service_level_connection(connection); 714 hfp_run_for_context(connection); 715 } 716 717 void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_t enable){ 718 hfp_hf_establish_service_level_connection(bd_addr); 719 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 720 if (!connection){ 721 log_error("HFP HF: connection doesn't exist."); 722 return; 723 } 724 connection->enable_status_update_for_ag_indicators = enable; 725 hfp_run_for_context(connection); 726 } 727 728 // TODO: returned ERROR - wrong format 729 void hfp_hf_enable_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap){ 730 hfp_hf_establish_service_level_connection(bd_addr); 731 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 732 if (!connection){ 733 log_error("HFP HF: connection doesn't exist."); 734 return; 735 } 736 connection->change_status_update_for_individual_ag_indicators = 1; 737 connection->ag_indicators_status_update_bitmap = indicators_status_bitmap; 738 hfp_run_for_context(connection); 739 } 740 741 void hfp_hf_query_operator_selection(bd_addr_t bd_addr){ 742 hfp_hf_establish_service_level_connection(bd_addr); 743 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 744 if (!connection){ 745 log_error("HFP HF: connection doesn't exist."); 746 return; 747 } 748 connection->operator_name_format = 1; 749 hfp_run_for_context(connection); 750 } 751 752 void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){ 753 hfp_hf_establish_service_level_connection(bd_addr); 754 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 755 if (!connection){ 756 log_error("HFP HF: connection doesn't exist."); 757 return; 758 } 759 connection->enable_extended_audio_gateway_error_report = enable; 760 hfp_run_for_context(connection); 761 } 762 763 void hfp_hf_negotiate_codecs(bd_addr_t bd_addr){ 764 hfp_hf_establish_service_level_connection(bd_addr); 765 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 766 if (!has_codec_negotiation_feature(connection)) return; 767 if (connection->remote_codecs_nr == 0) return; 768 769 if (connection->state >= HFP_W2_DISCONNECT_SCO) return; 770 771 if (connection->state != HFP_SLE_W2_EXCHANGE_COMMON_CODEC && 772 connection->state != HFP_SLE_W4_EXCHANGE_COMMON_CODEC){ 773 connection->hf_trigger_codec_connection_setup = 1; 774 } 775 hfp_run_for_context(connection); 776 } 777 778 779 void hfp_hf_establish_audio_connection(bd_addr_t bd_addr){ 780 hfp_hf_establish_service_level_connection(bd_addr); 781 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 782 if (!has_codec_negotiation_feature(connection)) return; 783 connection->establish_audio_connection = 0; 784 if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; 785 if (connection->state >= HFP_W2_DISCONNECT_SCO) return; 786 787 connection->establish_audio_connection = 1; 788 if (connection->state < HFP_SLE_W4_EXCHANGE_COMMON_CODEC){ 789 connection->hf_trigger_codec_connection_setup = 1; 790 } 791 hfp_run_for_context(connection); 792 } 793 794 void hfp_hf_release_audio_connection(bd_addr_t bd_addr){ 795 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 796 hfp_release_audio_connection(connection); 797 hfp_run_for_context(connection); 798 } 799 800 801