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 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 "classic/sdp_query_rfcomm.h" 59 #include "classic/sdp.h" 60 #include "debug.h" 61 #include "classic/hfp.h" 62 #include "classic/hfp_ag.h" 63 64 static const char default_hfp_ag_service_name[] = "Voice gateway"; 65 static uint16_t hfp_supported_features = HFP_DEFAULT_AG_SUPPORTED_FEATURES; 66 static uint8_t hfp_codecs_nr = 0; 67 static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; 68 69 static int hfp_ag_indicators_nr = 0; 70 static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_AG_INDICATORS]; 71 72 static int hfp_ag_call_hold_services_nr = 0; 73 static char *hfp_ag_call_hold_services[6]; 74 static hfp_callback_t hfp_callback; 75 76 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 77 78 hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(); 79 int get_hfp_generic_status_indicators_nr(); 80 void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr); 81 void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr); 82 int get_hfp_ag_indicators_nr(hfp_connection_t * context); 83 hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context); 84 85 86 hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context){ 87 // TODO: save only value, and value changed in the context? 88 if (context->ag_indicators_nr != hfp_ag_indicators_nr){ 89 context->ag_indicators_nr = hfp_ag_indicators_nr; 90 memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 91 } 92 return (hfp_ag_indicator_t *)&(context->ag_indicators); 93 } 94 95 void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr){ 96 memcpy(hfp_ag_indicators, indicators, indicator_nr * sizeof(hfp_ag_indicator_t)); 97 hfp_ag_indicators_nr = indicator_nr; 98 } 99 100 int get_hfp_ag_indicators_nr(hfp_connection_t * context){ 101 if (context->ag_indicators_nr != hfp_ag_indicators_nr){ 102 context->ag_indicators_nr = hfp_ag_indicators_nr; 103 memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 104 } 105 return context->ag_indicators_nr; 106 } 107 108 109 void hfp_ag_register_packet_handler(hfp_callback_t callback){ 110 if (callback == NULL){ 111 log_error("hfp_ag_register_packet_handler called with NULL callback"); 112 return; 113 } 114 hfp_callback = callback; 115 } 116 117 static uint8_t hfp_get_indicator_index_by_name(hfp_connection_t * context, const char * name){ 118 int i; 119 for (i=0; i<context->ag_indicators_nr; i++){ 120 if (strcmp(context->ag_indicators[i].name, name) == 0){ 121 return i; 122 } 123 } 124 return 0xFF; 125 } 126 127 static void hfp_ag_update_indicator_status(hfp_connection_t * context, const char * indicator_name, uint8_t status){ 128 int index = hfp_get_indicator_index_by_name(context, indicator_name); 129 if (index == 0xFF) return; 130 if (context->ag_indicators[index].status == status) return; 131 context->ag_indicators[index].status = status; 132 context->ag_indicators[index].status_changed = 1; 133 } 134 135 static int has_codec_negotiation_feature(hfp_connection_t * connection){ 136 int hf = get_bit(connection->remote_supported_features, HFP_HFSF_CODEC_NEGOTIATION); 137 int ag = get_bit(hfp_supported_features, HFP_AGSF_CODEC_NEGOTIATION); 138 return hf && ag; 139 } 140 141 static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){ 142 int hf = get_bit(connection->remote_supported_features, HFP_HFSF_THREE_WAY_CALLING); 143 int ag = get_bit(hfp_supported_features, HFP_AGSF_THREE_WAY_CALLING); 144 return hf && ag; 145 } 146 147 static int has_hf_indicators_feature(hfp_connection_t * connection){ 148 int hf = get_bit(connection->remote_supported_features, HFP_HFSF_HF_INDICATORS); 149 int ag = get_bit(hfp_supported_features, HFP_AGSF_HF_INDICATORS); 150 return hf && ag; 151 } 152 153 void hfp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features){ 154 if (!name){ 155 name = default_hfp_ag_service_name; 156 } 157 hfp_create_sdp_record(service, SDP_HandsfreeAudioGateway, rfcomm_channel_nr, name, supported_features); 158 159 // Network 160 de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call); 161 /* 162 * 0x01 – Ability to reject a call 163 * 0x00 – No ability to reject a call 164 */ 165 } 166 167 static int hfp_ag_exchange_supported_features_cmd(uint16_t cid){ 168 char buffer[40]; 169 sprintf(buffer, "\r\n%s:%d\r\n\r\nOK\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features); 170 return send_str_over_rfcomm(cid, buffer); 171 } 172 173 static int hfp_ag_ok(uint16_t cid){ 174 char buffer[10]; 175 sprintf(buffer, "\r\nOK\r\n"); 176 return send_str_over_rfcomm(cid, buffer); 177 } 178 179 static int hfp_ag_error(uint16_t cid){ 180 char buffer[10]; 181 sprintf(buffer, "\r\nERROR\r\n"); 182 return send_str_over_rfcomm(cid, buffer); 183 } 184 185 static int hfp_ag_report_extended_audio_gateway_error(uint16_t cid, uint8_t error){ 186 char buffer[20]; 187 sprintf(buffer, "\r\n%s=%d\r\n", HFP_EXTENDED_AUDIO_GATEWAY_ERROR, error); 188 return send_str_over_rfcomm(cid, buffer); 189 } 190 191 static int hfp_ag_retrieve_codec_cmd(uint16_t cid){ 192 return hfp_ag_ok(cid); 193 } 194 195 static int hfp_ag_indicators_join(char * buffer, int buffer_size, hfp_connection_t * context){ 196 if (buffer_size < get_hfp_ag_indicators_nr(context) * (1 + sizeof(hfp_ag_indicator_t))) return 0; 197 int i; 198 int offset = 0; 199 for (i = 0; i < get_hfp_ag_indicators_nr(context)-1; i++) { 200 offset += snprintf(buffer+offset, buffer_size-offset, "(\"%s\",(%d,%d)),", 201 get_hfp_ag_indicators(context)[i].name, 202 get_hfp_ag_indicators(context)[i].min_range, 203 get_hfp_ag_indicators(context)[i].max_range); 204 } 205 if ( i < get_hfp_ag_indicators_nr(context)){ 206 offset += snprintf(buffer+offset, buffer_size-offset, "(\"%s\",(%d,%d))", 207 get_hfp_ag_indicators(context)[i].name, 208 get_hfp_ag_indicators(context)[i].min_range, 209 get_hfp_ag_indicators(context)[i].max_range); 210 } 211 return offset; 212 } 213 214 static int hfp_hf_indicators_join(char * buffer, int buffer_size){ 215 if (buffer_size < hfp_ag_indicators_nr * 3) return 0; 216 int i; 217 int offset = 0; 218 for (i = 0; i < get_hfp_generic_status_indicators_nr()-1; i++) { 219 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid); 220 } 221 if (i < get_hfp_generic_status_indicators_nr()){ 222 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid); 223 } 224 return offset; 225 } 226 227 static int hfp_hf_indicators_initial_status_join(char * buffer, int buffer_size){ 228 if (buffer_size < get_hfp_generic_status_indicators_nr() * 3) return 0; 229 int i; 230 int offset = 0; 231 for (i = 0; i < get_hfp_generic_status_indicators_nr(); i++) { 232 offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, get_hfp_generic_status_indicators()[i].uuid, get_hfp_generic_status_indicators()[i].state); 233 } 234 return offset; 235 } 236 237 static int hfp_ag_indicators_status_join(char * buffer, int buffer_size){ 238 if (buffer_size < hfp_ag_indicators_nr * 3) return 0; 239 int i; 240 int offset = 0; 241 for (i = 0; i < hfp_ag_indicators_nr-1; i++) { 242 offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_ag_indicators[i].status); 243 } 244 if (i<hfp_ag_indicators_nr){ 245 offset += snprintf(buffer+offset, buffer_size-offset, "%d", hfp_ag_indicators[i].status); 246 } 247 return offset; 248 } 249 250 static int hfp_ag_call_services_join(char * buffer, int buffer_size){ 251 if (buffer_size < hfp_ag_call_hold_services_nr * 3) return 0; 252 int i; 253 int offset = snprintf(buffer, buffer_size, "("); 254 for (i = 0; i < hfp_ag_call_hold_services_nr-1; i++) { 255 offset += snprintf(buffer+offset, buffer_size-offset, "%s,", hfp_ag_call_hold_services[i]); 256 } 257 if (i<hfp_ag_call_hold_services_nr){ 258 offset += snprintf(buffer+offset, buffer_size-offset, "%s)", hfp_ag_call_hold_services[i]); 259 } 260 return offset; 261 } 262 263 static int hfp_ag_retrieve_indicators_cmd(uint16_t cid, hfp_connection_t * context){ 264 char buffer[250]; 265 int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR); 266 offset += hfp_ag_indicators_join(buffer+offset, sizeof(buffer)-offset, context); 267 268 buffer[offset] = 0; 269 270 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n"); 271 buffer[offset] = 0; 272 return send_str_over_rfcomm(cid, buffer); 273 } 274 275 static int hfp_ag_retrieve_indicators_status_cmd(uint16_t cid){ 276 char buffer[40]; 277 int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR); 278 offset += hfp_ag_indicators_status_join(buffer+offset, sizeof(buffer)-offset); 279 280 buffer[offset] = 0; 281 282 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n"); 283 buffer[offset] = 0; 284 return send_str_over_rfcomm(cid, buffer); 285 } 286 287 static int hfp_ag_set_indicator_status_update_cmd(uint16_t cid, uint8_t activate){ 288 // AT\r\n%s:3,0,0,%d\r\n 289 return hfp_ag_ok(cid); 290 } 291 292 293 static int hfp_ag_retrieve_can_hold_call_cmd(uint16_t cid){ 294 char buffer[100]; 295 int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); 296 offset += hfp_ag_call_services_join(buffer+offset, sizeof(buffer)-offset); 297 298 buffer[offset] = 0; 299 300 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n"); 301 buffer[offset] = 0; 302 return send_str_over_rfcomm(cid, buffer); 303 } 304 305 306 static int hfp_ag_list_supported_generic_status_indicators_cmd(uint16_t cid){ 307 return hfp_ag_ok(cid); 308 } 309 310 static int hfp_ag_retrieve_supported_generic_status_indicators_cmd(uint16_t cid){ 311 char buffer[40]; 312 int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_GENERIC_STATUS_INDICATOR); 313 offset += hfp_hf_indicators_join(buffer+offset, sizeof(buffer)-offset); 314 315 buffer[offset] = 0; 316 317 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n"); 318 buffer[offset] = 0; 319 return send_str_over_rfcomm(cid, buffer); 320 } 321 322 static int hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(uint16_t cid){ 323 char buffer[40]; 324 int offset = hfp_hf_indicators_initial_status_join(buffer, sizeof(buffer)); 325 326 buffer[offset] = 0; 327 offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n"); 328 buffer[offset] = 0; 329 return send_str_over_rfcomm(cid, buffer); 330 } 331 332 static int hfp_ag_transfer_ag_indicators_status_cmd(uint16_t cid, hfp_ag_indicator_t indicator){ 333 char buffer[20]; 334 sprintf(buffer, "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, indicator.index, indicator.status); 335 return send_str_over_rfcomm(cid, buffer); 336 } 337 338 static int hfp_ag_report_network_operator_name_cmd(uint16_t cid, hfp_network_opearator_t op){ 339 char buffer[40]; 340 if (strlen(op.name) == 0){ 341 sprintf(buffer, "\r\n%s:%d,,\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION, op.mode); 342 } else { 343 sprintf(buffer, "\r\n%s:%d,%d,%s\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION, op.mode, op.format, op.name); 344 } 345 return send_str_over_rfcomm(cid, buffer); 346 } 347 348 349 static int hfp_ag_cmd_suggest_codec(uint16_t cid, uint8_t codec){ 350 char buffer[30]; 351 sprintf(buffer, "\r\n%s:%d\r\n", HFP_CONFIRM_COMMON_CODEC, codec); 352 return send_str_over_rfcomm(cid, buffer); 353 } 354 355 static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){ 356 int i,j; 357 uint8_t codec = 0; 358 for (i = 0; i < hfp_codecs_nr; i++){ 359 for (j = 0; j < context->remote_codecs_nr; j++){ 360 if (context->remote_codecs[j] == hfp_codecs[i]){ 361 codec = context->remote_codecs[j]; 362 continue; 363 } 364 } 365 } 366 return codec; 367 } 368 369 370 static int hfp_ag_run_for_context_service_level_connection(hfp_connection_t * context){ 371 if (context->state >= HFP_CODECS_CONNECTION_ESTABLISHED) return 0; 372 //printf(" AG run for context_service_level_connection \n"); 373 int done = 0; 374 375 switch(context->command){ 376 case HFP_CMD_SUPPORTED_FEATURES: 377 switch(context->state){ 378 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: 379 hfp_ag_exchange_supported_features_cmd(context->rfcomm_cid); 380 done = 1; 381 if (has_codec_negotiation_feature(context)){ 382 context->state = HFP_W4_NOTIFY_ON_CODECS; 383 break; 384 } 385 context->state = HFP_W4_RETRIEVE_INDICATORS; 386 break; 387 default: 388 break; 389 } 390 break; 391 case HFP_CMD_AVAILABLE_CODECS: 392 switch(context->state){ 393 case HFP_W4_NOTIFY_ON_CODECS: 394 hfp_ag_retrieve_codec_cmd(context->rfcomm_cid); 395 done = 1; 396 context->state = HFP_W4_RETRIEVE_INDICATORS; 397 break; 398 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 399 context->suggested_codec = hfp_ag_suggest_codec(context); 400 //printf("received BAC == new HF codecs, suggested codec %d\n", context->suggested_codec); 401 hfp_ag_ok(context->rfcomm_cid); 402 done = 1; 403 break; 404 405 default: 406 break; 407 } 408 break; 409 case HFP_CMD_INDICATOR: 410 switch(context->state){ 411 case HFP_W4_RETRIEVE_INDICATORS: 412 if (context->retrieve_ag_indicators == 0) break; 413 hfp_ag_retrieve_indicators_cmd(context->rfcomm_cid, context); 414 done = 1; 415 context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; 416 break; 417 case HFP_W4_RETRIEVE_INDICATORS_STATUS: 418 if (context->retrieve_ag_indicators_status == 0) break; 419 hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid); 420 done = 1; 421 context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE; 422 break; 423 default: 424 break; 425 } 426 break; 427 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 428 switch(context->state){ 429 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE: 430 hfp_ag_set_indicator_status_update_cmd(context->rfcomm_cid, 1); 431 done = 1; 432 if (has_call_waiting_and_3way_calling_feature(context)){ 433 context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL; 434 break; 435 } 436 if (has_hf_indicators_feature(context)){ 437 context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; 438 break; 439 } 440 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 441 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 442 break; 443 default: 444 break; 445 } 446 break; 447 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: 448 switch(context->state){ 449 case HFP_W4_RETRIEVE_CAN_HOLD_CALL: 450 hfp_ag_retrieve_can_hold_call_cmd(context->rfcomm_cid); 451 done = 1; 452 if (has_hf_indicators_feature(context)){ 453 context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; 454 break; 455 } 456 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 457 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 458 break; 459 default: 460 break; 461 } 462 break; 463 case HFP_CMD_GENERIC_STATUS_INDICATOR: 464 switch(context->state){ 465 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: 466 if (context->list_generic_status_indicators == 0) break; 467 hfp_ag_list_supported_generic_status_indicators_cmd(context->rfcomm_cid); 468 done = 1; 469 context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; 470 context->list_generic_status_indicators = 0; 471 break; 472 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: 473 if (context->retrieve_generic_status_indicators == 0) break; 474 hfp_ag_retrieve_supported_generic_status_indicators_cmd(context->rfcomm_cid); 475 done = 1; 476 context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; 477 context->retrieve_generic_status_indicators = 0; 478 break; 479 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: 480 if (context->retrieve_generic_status_indicators_state == 0) break; 481 hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(context->rfcomm_cid); 482 done = 1; 483 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 484 context->retrieve_generic_status_indicators_state = 0; 485 hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0); 486 break; 487 default: 488 break; 489 } 490 break; 491 492 default: 493 break; 494 } 495 return done; 496 } 497 498 static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * context){ 499 if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; 500 int done = 0; 501 //printf(" SLC queries: "); 502 503 switch(context->command){ 504 case HFP_CMD_AVAILABLE_CODECS: 505 context->suggested_codec = hfp_ag_suggest_codec(context); 506 //printf("received BAC == new HF codecs, suggested codec %d\n", context->suggested_codec); 507 hfp_ag_ok(context->rfcomm_cid); 508 done = 1; 509 break; 510 511 case HFP_CMD_QUERY_OPERATOR_SELECTION: 512 if (context->operator_name_format == 1){ 513 if (context->network_operator.format != 0){ 514 hfp_ag_error(context->rfcomm_cid); 515 done = 1; 516 break; 517 } 518 hfp_ag_ok(context->rfcomm_cid); 519 done = 1; 520 context->operator_name_format = 0; 521 break; 522 } 523 if (context->operator_name == 1){ 524 hfp_ag_report_network_operator_name_cmd(context->rfcomm_cid, context->network_operator); 525 context->operator_name = 0; 526 done = 1; 527 break; 528 } 529 break; 530 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:{ 531 int i; 532 for (i = 0; i < context->ag_indicators_nr; i++){ 533 if (context->ag_indicators[i].enabled == 0) continue; 534 if (context->ag_indicators[i].status_changed == 0) continue; 535 hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]); 536 done = 1; 537 context->ag_indicators[i].status_changed = 0; 538 return done; 539 } 540 break; 541 } 542 case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP: 543 if (context->hf_trigger_codec_connection_setup){ // received BCC 544 //printf(" received BCC \n"); 545 context->hf_trigger_codec_connection_setup = 0; 546 context->ag_trigger_codec_connection_setup = 1; 547 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; 548 hfp_ag_ok(context->rfcomm_cid); 549 done = 1; 550 return done; 551 } 552 553 if (context->ag_trigger_codec_connection_setup){ // received BCS 554 //printf(" send BCS \n"); 555 context->ag_trigger_codec_connection_setup = 0; 556 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 557 context->suggested_codec = hfp_ag_suggest_codec(context); 558 hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); 559 done = 1; 560 return done; 561 } 562 break; 563 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR: 564 if (context->extended_audio_gateway_error){ 565 hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error); 566 context->extended_audio_gateway_error = 0; 567 done = 1; 568 break; 569 } 570 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: 571 printf("TODO\n"); 572 break; 573 default: 574 break; 575 } 576 return done; 577 } 578 579 580 static int hfp_ag_run_for_context_codecs_connection(hfp_connection_t * context){ 581 if (context->state <= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || 582 context->state > HFP_CODECS_CONNECTION_ESTABLISHED) return 0; 583 584 int done = 0; 585 //printf(" AG run for context_codecs_connection: "); 586 switch (context->state){ 587 case HFP_SLE_W2_EXCHANGE_COMMON_CODEC: 588 if (context->ag_trigger_codec_connection_setup){ // received BCS 589 //printf(" send BCS \n"); 590 context->ag_trigger_codec_connection_setup = 0; 591 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 592 context->suggested_codec = hfp_ag_suggest_codec(context); 593 hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); 594 done = 1; 595 break; 596 } 597 break; 598 case HFP_SLE_W4_EXCHANGE_COMMON_CODEC: 599 switch(context->command){ 600 case HFP_CMD_AVAILABLE_CODECS: 601 if (context->notify_ag_on_new_codecs){ // received BAC 602 //printf(" received BAC\n"); 603 context->notify_ag_on_new_codecs = 0; 604 if (context->suggested_codec != hfp_ag_suggest_codec(context)){ 605 context->suggested_codec = hfp_ag_suggest_codec(context); 606 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC; 607 context->ag_trigger_codec_connection_setup = 1; 608 } 609 hfp_ag_ok(context->rfcomm_cid); 610 done = 1; 611 break; 612 } 613 break; 614 case HFP_CMD_HF_CONFIRMED_CODEC: 615 //printf(" received AT+BCS\n"); 616 if (context->codec_confirmed != context->suggested_codec){ 617 context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; 618 hfp_ag_error(context->rfcomm_cid); 619 done = 1; 620 break; 621 } 622 context->negotiated_codec = context->codec_confirmed; 623 context->state = HFP_CODECS_CONNECTION_ESTABLISHED; 624 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0); 625 hfp_ag_ok(context->rfcomm_cid); 626 done = 1; 627 break; 628 default: 629 break; 630 } 631 break; 632 633 case HFP_CODECS_CONNECTION_ESTABLISHED: 634 switch(context->command){ 635 case HFP_CMD_AVAILABLE_CODECS: 636 637 if (context->notify_ag_on_new_codecs){ // received BAC 638 context->notify_ag_on_new_codecs = 0; 639 if (context->suggested_codec != hfp_ag_suggest_codec(context)){ 640 context->suggested_codec = hfp_ag_suggest_codec(context); 641 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 642 } 643 hfp_ag_ok(context->rfcomm_cid); 644 done = 1; 645 break; 646 } 647 break; 648 case HFP_CMD_AG_SUGGESTED_CODEC: 649 if (context->ag_trigger_codec_connection_setup){ 650 context->ag_trigger_codec_connection_setup = 0; 651 if (context->negotiated_codec != hfp_ag_suggest_codec(context)){ 652 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC; 653 context->suggested_codec = hfp_ag_suggest_codec(context); 654 hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec); 655 done = 1; 656 break; 657 } 658 } 659 break; 660 default: 661 break; 662 } 663 664 default: 665 break; 666 } 667 return done; 668 } 669 670 static void hfp_run_for_context(hfp_connection_t *context){ 671 if (!context) return; 672 673 if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; 674 675 // printf("AG hfp_run_for_context 1 state %d, command %d\n", context->state, context->command); 676 if (context->send_ok){ 677 hfp_ag_ok(context->rfcomm_cid); 678 context->send_ok = 0; 679 context->command = HFP_CMD_NONE; 680 return; 681 } 682 683 if (context->send_error){ 684 hfp_ag_error(context->rfcomm_cid); 685 context->send_error = 0; 686 context->command = HFP_CMD_NONE; 687 return; 688 } 689 690 int done = hfp_ag_run_for_context_service_level_connection(context); 691 692 if (rfcomm_can_send_packet_now(context->rfcomm_cid) && !done){ 693 done = hfp_ag_run_for_context_service_level_connection_queries(context); 694 if (rfcomm_can_send_packet_now(context->rfcomm_cid) && !done){ 695 done = hfp_ag_run_for_context_codecs_connection(context); 696 } 697 } 698 699 700 if (context->command == HFP_CMD_NONE && !done){ 701 switch(context->state){ 702 case HFP_W2_DISCONNECT_RFCOMM: 703 context->state = HFP_W4_RFCOMM_DISCONNECTED; 704 rfcomm_disconnect_internal(context->rfcomm_cid); 705 break; 706 default: 707 break; 708 } 709 } 710 if (done){ 711 context->command = HFP_CMD_NONE; 712 } 713 } 714 715 static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 716 hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel); 717 if (!context) return; 718 719 if (context->state == HFP_EXCHANGE_SUPPORTED_FEATURES){ 720 context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES; 721 } 722 723 packet[size] = 0; 724 int pos; 725 for (pos = 0; pos < size ; pos++){ 726 hfp_parse(context, packet[pos]); 727 728 // trigger next action after CMD received 729 if (context->command == HFP_CMD_NONE) continue; 730 //hfp_run_for_context(context); 731 } 732 } 733 734 static void hfp_run(){ 735 linked_list_iterator_t it; 736 linked_list_iterator_init(&it, hfp_get_connections()); 737 while (linked_list_iterator_has_next(&it)){ 738 hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it); 739 hfp_run_for_context(connection); 740 } 741 } 742 743 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 744 switch (packet_type){ 745 case RFCOMM_DATA_PACKET: 746 hfp_handle_rfcomm_event(packet_type, channel, packet, size); 747 break; 748 case HCI_EVENT_PACKET: 749 hfp_handle_hci_event(hfp_callback, packet_type, packet, size); 750 return; 751 default: 752 break; 753 } 754 755 hfp_run(); 756 } 757 758 void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, 759 uint8_t * codecs, int codecs_nr, 760 hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr, 761 hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr, 762 const char *call_hold_services[], int call_hold_services_nr){ 763 if (codecs_nr > HFP_MAX_NUM_CODECS){ 764 log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS); 765 return; 766 } 767 rfcomm_register_packet_handler(packet_handler); 768 hfp_init(rfcomm_channel_nr); 769 770 hfp_supported_features = supported_features; 771 hfp_codecs_nr = codecs_nr; 772 773 int i; 774 for (i=0; i<codecs_nr; i++){ 775 hfp_codecs[i] = codecs[i]; 776 } 777 778 hfp_ag_indicators_nr = ag_indicators_nr; 779 memcpy(hfp_ag_indicators, ag_indicators, ag_indicators_nr * sizeof(hfp_ag_indicator_t)); 780 for (i=0; i<hfp_ag_indicators_nr; i++){ 781 printf("ag ind %s\n", hfp_ag_indicators[i].name); 782 } 783 784 set_hfp_generic_status_indicators(hf_indicators, hf_indicators_nr); 785 786 hfp_ag_call_hold_services_nr = call_hold_services_nr; 787 memcpy(hfp_ag_call_hold_services, call_hold_services, call_hold_services_nr * sizeof(char *)); 788 } 789 790 void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){ 791 hfp_establish_service_level_connection(bd_addr, SDP_Handsfree); 792 } 793 794 void hfp_ag_release_service_level_connection(bd_addr_t bd_addr){ 795 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 796 hfp_release_service_level_connection(connection); 797 hfp_run_for_context(connection); 798 } 799 800 void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error){ 801 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 802 if (!connection){ 803 log_error("HFP HF: connection doesn't exist."); 804 return; 805 } 806 connection->extended_audio_gateway_error = 0; 807 if (!connection->enable_extended_audio_gateway_error_report){ 808 return; 809 } 810 connection->extended_audio_gateway_error = error; 811 hfp_run_for_context(connection); 812 } 813 814 void hfp_ag_transfer_call_status(bd_addr_t bd_addr, hfp_call_status_t status){ 815 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 816 if (!connection){ 817 log_error("HFP HF: connection doesn't exist."); 818 return; 819 } 820 if (!connection->enable_status_update_for_ag_indicators) return; 821 hfp_ag_update_indicator_status(connection, (char *)"call", status); 822 } 823 824 void hfp_ag_transfer_callsetup_status(bd_addr_t bd_addr, hfp_callsetup_status_t status){ 825 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 826 if (!connection){ 827 log_error("HFP HF: connection doesn't exist."); 828 return; 829 } 830 if (!connection->enable_status_update_for_ag_indicators) return; 831 hfp_ag_update_indicator_status(connection, (char *)"callsetup", status); 832 } 833 834 void hfp_ag_transfer_callheld_status(bd_addr_t bd_addr, hfp_callheld_status_t status){ 835 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 836 if (!connection){ 837 log_error("HFP AG: connection doesn't exist."); 838 return; 839 } 840 if (!connection->enable_status_update_for_ag_indicators) return; 841 hfp_ag_update_indicator_status(connection, (char *)"callheld", status); 842 hfp_run_for_context(connection); 843 } 844 845 #if 0 846 static void hfp_ag_codec_connection_setup(hfp_connection_t * connection){ 847 if (!connection){ 848 log_error("HFP AG: connection doesn't exist."); 849 return; 850 } 851 // TODO: 852 hfp_run_for_context(connection); 853 } 854 #endif 855 856 /** 857 * @param handle 858 * @param transmit_bandwidth 8000(64kbps) 859 * @param receive_bandwidth 8000(64kbps) 860 * @param max_latency >= 7ms for eSCO, 0xFFFF do not care 861 * @param voice_settings e.g. CVSD, Input Coding: Linear, Input Data Format: 2’s complement, data 16bit: 00011000000 == 0x60 862 * @param retransmission_effort e.g. 0xFF do not care 863 * @param packet_type at least EV3 for eSCO 864 865 hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, 0x0060, 0xFF, 0x003F); 866 867 */ 868 869 #if 0 870 static void hfp_ag_negotiate_codecs(bd_addr_t bd_addr){ 871 hfp_ag_establish_service_level_connection(bd_addr); 872 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 873 if (!has_codec_negotiation_feature(connection)) return; 874 if (connection->remote_codecs_nr == 0) return; 875 876 if (connection->state >= HFP_W2_DISCONNECT_SCO) return; 877 878 if (connection->state != HFP_SLE_W2_EXCHANGE_COMMON_CODEC && 879 connection->state != HFP_SLE_W4_EXCHANGE_COMMON_CODEC){ 880 connection->ag_trigger_codec_connection_setup = 1; 881 } 882 883 hfp_run_for_context(connection); 884 } 885 #endif 886 887 void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){ 888 hfp_ag_establish_service_level_connection(bd_addr); 889 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 890 if (!has_codec_negotiation_feature(connection)) return; 891 connection->establish_audio_connection = 0; 892 if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; 893 if (connection->state >= HFP_W2_DISCONNECT_SCO) return; 894 895 connection->establish_audio_connection = 1; 896 if (connection->state < HFP_SLE_W4_EXCHANGE_COMMON_CODEC){ 897 connection->ag_trigger_codec_connection_setup = 1; 898 } 899 hfp_run_for_context(connection); 900 } 901 902 void hfp_ag_release_audio_connection(bd_addr_t bd_addr){ 903 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); 904 hfp_release_audio_connection(connection); 905 hfp_run_for_context(connection); 906 } 907