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 * hfp_ag_demo.c 40 */ 41 42 // ***************************************************************************** 43 /* EXAMPLE_START(hfp_ag_demo): HFP Audio Gateway (AG) Demo 44 * 45 * @text This HFP Audio Gateway example demonstrates how to receive 46 * an output from a remote HFP Hands-Free (HF) unit, and, 47 * if HAVE_STDIO is defined, how to control the HFP HF. 48 */ 49 // ***************************************************************************** 50 51 52 #include <stdint.h> 53 #include <stdio.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.h> 57 58 #include "btstack.h" 59 #include "stdin_support.h" 60 61 62 uint8_t hfp_service_buffer[150]; 63 const uint8_t rfcomm_channel_nr = 1; 64 const char hfp_ag_service_name[] = "BTstack HFP AG Test"; 65 66 static bd_addr_t device_addr = {0x00,0x15,0x83,0x5F,0x9D,0x46}; 67 68 static uint8_t codecs[1] = {HFP_CODEC_CVSD}; 69 static uint16_t handle = -1; 70 static int memory_1_enabled = 1; 71 72 static int ag_indicators_nr = 7; 73 static hfp_ag_indicator_t ag_indicators[] = { 74 // index, name, min range, max range, status, mandatory, enabled, status changed 75 {1, "service", 0, 1, 1, 0, 0, 0}, 76 {2, "call", 0, 1, 0, 1, 1, 0}, 77 {3, "callsetup", 0, 3, 0, 1, 1, 0}, 78 {4, "battchg", 0, 5, 3, 0, 0, 0}, 79 {5, "signal", 0, 5, 5, 0, 1, 0}, 80 {6, "roam", 0, 1, 0, 0, 1, 0}, 81 {7, "callheld", 0, 2, 0, 1, 1, 0} 82 }; 83 84 static int call_hold_services_nr = 5; 85 static const char* call_hold_services[] = {"1", "1x", "2", "2x", "3"}; 86 87 static int hf_indicators_nr = 2; 88 static hfp_generic_status_indicator_t hf_indicators[] = { 89 {1, 1}, 90 {2, 1}, 91 }; 92 93 char cmd; 94 95 // GAP INQUIRY 96 97 #define MAX_DEVICES 10 98 enum DEVICE_STATE { REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, REMOTE_NAME_FETCHED }; 99 struct device { 100 bd_addr_t address; 101 uint16_t clockOffset; 102 uint32_t classOfDevice; 103 uint8_t pageScanRepetitionMode; 104 uint8_t rssi; 105 enum DEVICE_STATE state; 106 }; 107 108 #define INQUIRY_INTERVAL 5 109 struct device devices[MAX_DEVICES]; 110 int deviceCount = 0; 111 112 113 enum STATE {INIT, W4_INQUIRY_MODE_COMPLETE, ACTIVE} ; 114 enum STATE state = INIT; 115 116 117 static int getDeviceIndexForAddress( bd_addr_t addr){ 118 int j; 119 for (j=0; j< deviceCount; j++){ 120 if (bd_addr_cmp(addr, devices[j].address) == 0){ 121 return j; 122 } 123 } 124 return -1; 125 } 126 127 #ifdef HAVE_STDIO 128 static void start_scan(void){ 129 printf("Starting inquiry scan..\n"); 130 hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); 131 } 132 #endif 133 134 static int has_more_remote_name_requests(void){ 135 int i; 136 for (i=0;i<deviceCount;i++) { 137 if (devices[i].state == REMOTE_NAME_REQUEST) return 1; 138 } 139 return 0; 140 } 141 142 static void do_next_remote_name_request(void){ 143 int i; 144 for (i=0;i<deviceCount;i++) { 145 // remote name request 146 if (devices[i].state == REMOTE_NAME_REQUEST){ 147 devices[i].state = REMOTE_NAME_INQUIRED; 148 printf("Get remote name of %s...\n", bd_addr_to_str(devices[i].address)); 149 hci_send_cmd(&hci_remote_name_request, devices[i].address, 150 devices[i].pageScanRepetitionMode, 0, devices[i].clockOffset | 0x8000); 151 return; 152 } 153 } 154 } 155 156 static void continue_remote_names(void){ 157 // don't get remote names for testing 158 if (has_more_remote_name_requests()){ 159 do_next_remote_name_request(); 160 return; 161 } 162 // try to find PTS 163 int i; 164 for (i=0;i<deviceCount;i++){ 165 if (memcmp(devices[i].address, device_addr, 6) == 0){ 166 printf("Inquiry scan over, successfully found PTS at index %u\nReady to connect to it.\n", i); 167 return; 168 } 169 } 170 printf("Inquiry scan over but PTS not found :(\n"); 171 } 172 173 static void inquiry_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 174 bd_addr_t addr; 175 int i; 176 int numResponses; 177 int index; 178 179 // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); 180 if (packet_type != HCI_EVENT_PACKET) return; 181 182 uint8_t event = packet[0]; 183 184 switch(event){ 185 case HCI_EVENT_INQUIRY_RESULT: 186 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{ 187 numResponses = packet[2]; 188 int offset = 3; 189 for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ 190 reverse_bd_addr(addr, &packet[offset]); 191 offset += 6; 192 index = getDeviceIndexForAddress(addr); 193 if (index >= 0) continue; // already in our list 194 memcpy(devices[deviceCount].address, addr, 6); 195 196 devices[deviceCount].pageScanRepetitionMode = packet[offset]; 197 offset += 1; 198 199 if (event == HCI_EVENT_INQUIRY_RESULT){ 200 offset += 2; // Reserved + Reserved 201 devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); 202 offset += 3; 203 devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; 204 offset += 2; 205 devices[deviceCount].rssi = 0; 206 } else { 207 offset += 1; // Reserved 208 devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); 209 offset += 3; 210 devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; 211 offset += 2; 212 devices[deviceCount].rssi = packet[offset]; 213 offset += 1; 214 } 215 devices[deviceCount].state = REMOTE_NAME_REQUEST; 216 printf("Device #%u found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", 217 deviceCount, bd_addr_to_str(addr), 218 devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, 219 devices[deviceCount].clockOffset, devices[deviceCount].rssi); 220 deviceCount++; 221 } 222 223 break; 224 } 225 case HCI_EVENT_INQUIRY_COMPLETE: 226 for (i=0;i<deviceCount;i++) { 227 // retry remote name request 228 if (devices[i].state == REMOTE_NAME_INQUIRED) 229 devices[i].state = REMOTE_NAME_REQUEST; 230 } 231 continue_remote_names(); 232 break; 233 234 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 235 reverse_bd_addr(addr, &packet[3]); 236 index = getDeviceIndexForAddress(addr); 237 if (index >= 0) { 238 if (packet[2] == 0) { 239 printf("Name: '%s'\n", &packet[9]); 240 devices[index].state = REMOTE_NAME_FETCHED; 241 } else { 242 printf("Failed to get name: page timeout\n"); 243 } 244 } 245 continue_remote_names(); 246 break; 247 248 default: 249 break; 250 } 251 } 252 // GAP INQUIRY END 253 #ifdef HAVE_STDIO 254 255 // prototypes 256 static void show_usage(); 257 258 // Testig User Interface 259 static void show_usage(void){ 260 printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n"); 261 printf("---\n"); 262 263 printf("a - establish HFP connection to PTS module\n"); 264 // printf("A - release HFP connection to PTS module\n"); 265 266 printf("b - establish AUDIO connection\n"); 267 printf("B - release AUDIO connection\n"); 268 269 printf("c - simulate incoming call from 1234567\n"); 270 printf("C - simulate call from 1234567 dropped\n"); 271 272 printf("d - report AG failure\n"); 273 274 printf("e - answer call on AG\n"); 275 printf("E - reject call on AG\n"); 276 277 printf("r - disable in-band ring tone\n"); 278 printf("R - enable in-band ring tone\n"); 279 280 printf("f - Disable cellular network\n"); 281 printf("F - Enable cellular network\n"); 282 283 printf("g - Set signal strength to 0\n"); 284 printf("G - Set signal strength to 5\n"); 285 286 printf("h - Disable roaming\n"); 287 printf("H - Enable roaming\n"); 288 289 printf("i - Set battery level to 3\n"); 290 printf("I - Set battery level to 5\n"); 291 292 printf("j - Answering call on remote side\n"); 293 294 printf("k - Clear memory #1\n"); 295 printf("K - Set memory #1\n"); 296 297 printf("l - Clear last number\n"); 298 printf("L - Set last number\n"); 299 300 printf("m - simulate incoming call from 7654321\n"); 301 // printf("M - simulate call from 7654321 dropped\n"); 302 303 printf("n - Disable Voice Regocnition\n"); 304 printf("N - Enable Voice Recognition\n"); 305 306 printf("o - Set speaker volume to 0 (minimum)\n"); 307 printf("O - Set speaker volume to 9 (default)\n"); 308 printf("p - Set speaker volume to 12 (higher)\n"); 309 printf("P - Set speaker volume to 15 (maximum)\n"); 310 311 printf("q - Set microphone gain to 0 (minimum)\n"); 312 printf("Q - Set microphone gain to 9 (default)\n"); 313 printf("s - Set microphone gain to 12 (higher)\n"); 314 printf("S - Set microphone gain to 15 (maximum)\n"); 315 316 printf("t - terminate connection\n"); 317 printf("u - join held call\n"); 318 printf("v - discover nearby HF units\n"); 319 printf("w - put incoming call on hold (Response and Hold)\n"); 320 printf("x - accept held incoming call (Response and Hold)\n"); 321 printf("X - reject held incoming call (Response and Hold)\n"); 322 323 printf("---\n"); 324 printf("Ctrl-c - exit\n"); 325 printf("---\n"); 326 } 327 328 static int stdin_process(struct data_source *ds){ 329 read(ds->fd, &cmd, 1); 330 switch (cmd){ 331 case 'a': 332 log_info("USER:\'%c\'", cmd); 333 printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr)); 334 hfp_ag_establish_service_level_connection(device_addr); 335 break; 336 case 'A': 337 log_info("USER:\'%c\'", cmd); 338 printf("Release HFP service level connection.\n"); 339 hfp_ag_release_service_level_connection(device_addr); 340 break; 341 case 'Z': 342 log_info("USER:\'%c\'", cmd); 343 printf("Release HFP service level connection to %s...\n", bd_addr_to_str(device_addr)); 344 hfp_ag_release_service_level_connection(device_addr); 345 break; 346 case 'b': 347 log_info("USER:\'%c\'", cmd); 348 printf("Establish Audio connection %s...\n", bd_addr_to_str(device_addr)); 349 hfp_ag_establish_audio_connection(device_addr); 350 break; 351 case 'B': 352 log_info("USER:\'%c\'", cmd); 353 printf("Release Audio connection.\n"); 354 hfp_ag_release_audio_connection(device_addr); 355 break; 356 case 'c': 357 log_info("USER:\'%c\'", cmd); 358 printf("Simulate incoming call from 1234567\n"); 359 hfp_ag_set_clip(129, "1234567"); 360 hfp_ag_incoming_call(); 361 break; 362 case 'm': 363 log_info("USER:\'%c\'", cmd); 364 printf("Simulate incoming call from 7654321\n"); 365 hfp_ag_set_clip(129, "7654321"); 366 hfp_ag_incoming_call(); 367 break; 368 case 'C': 369 log_info("USER:\'%c\'", cmd); 370 printf("Simulate terminate call\n"); 371 hfp_ag_call_dropped(); 372 break; 373 case 'd': 374 log_info("USER:\'%c\'", cmd); 375 printf("Report AG failure\n"); 376 hfp_ag_report_extended_audio_gateway_error_result_code(device_addr, HFP_CME_ERROR_AG_FAILURE); 377 break; 378 case 'e': 379 log_info("USER:\'%c\'", cmd); 380 printf("Answer call on AG\n"); 381 hfp_ag_answer_incoming_call(); 382 break; 383 case 'E': 384 log_info("USER:\'%c\'", cmd); 385 printf("Reject call on AG\n"); 386 hfp_ag_terminate_call(); 387 break; 388 case 'f': 389 log_info("USER:\'%c\'", cmd); 390 printf("Disable cellular network\n"); 391 hfp_ag_set_registration_status(0); 392 break; 393 case 'F': 394 log_info("USER:\'%c\'", cmd); 395 printf("Enable cellular network\n"); 396 hfp_ag_set_registration_status(1); 397 break; 398 case 'g': 399 log_info("USER:\'%c\'", cmd); 400 printf("Set signal strength to 0\n"); 401 hfp_ag_set_signal_strength(0); 402 break; 403 case 'G': 404 log_info("USER:\'%c\'", cmd); 405 printf("Set signal strength to 5\n"); 406 hfp_ag_set_signal_strength(5); 407 break; 408 case 'h': 409 log_info("USER:\'%c\'", cmd); 410 printf("Disable roaming\n"); 411 hfp_ag_set_roaming_status(0); 412 break; 413 case 'H': 414 log_info("USER:\'%c\'", cmd); 415 printf("Enable roaming\n"); 416 hfp_ag_set_roaming_status(1); 417 break; 418 case 'i': 419 log_info("USER:\'%c\'", cmd); 420 printf("Set battery level to 3\n"); 421 hfp_ag_set_battery_level(3); 422 break; 423 case 'I': 424 log_info("USER:\'%c\'", cmd); 425 printf("Set battery level to 5\n"); 426 hfp_ag_set_battery_level(5); 427 break; 428 case 'j': 429 log_info("USER:\'%c\'", cmd); 430 printf("Answering call on remote side\n"); 431 hfp_ag_outgoing_call_established(); 432 break; 433 case 'r': 434 log_info("USER:\'%c\'", cmd); 435 printf("Disable in-band ring tone\n"); 436 hfp_ag_set_use_in_band_ring_tone(0); 437 break; 438 case 'k': 439 log_info("USER:\'%c\'", cmd); 440 printf("Memory 1 cleared\n"); 441 memory_1_enabled = 0; 442 break; 443 case 'K': 444 log_info("USER:\'%c\'", cmd); 445 printf("Memory 1 set\n"); 446 memory_1_enabled = 1; 447 break; 448 case 'l': 449 log_info("USER:\'%c\'", cmd); 450 printf("Last dialed number cleared\n"); 451 hfp_ag_clear_last_dialed_number(); 452 break; 453 case 'L': 454 log_info("USER:\'%c\'", cmd); 455 printf("Outgoing call connected, ringing\n"); 456 hfp_ag_outgoing_call_ringing(); 457 break; 458 case 'n': 459 log_info("USER:\'%c\'", cmd); 460 printf("Disable Voice Recognition\n"); 461 hfp_ag_activate_voice_recognition(device_addr, 0); 462 break; 463 case 'N': 464 log_info("USER:\'%c\'", cmd); 465 printf("Enable Voice Recognition\n"); 466 hfp_ag_activate_voice_recognition(device_addr, 1); 467 break; 468 case 'o': 469 log_info("USER:\'%c\'", cmd); 470 printf("Set speaker gain to 0 (minimum)\n"); 471 hfp_ag_set_speaker_gain(device_addr, 0); 472 break; 473 case 'O': 474 log_info("USER:\'%c\'", cmd); 475 printf("Set speaker gain to 9 (default)\n"); 476 hfp_ag_set_speaker_gain(device_addr, 9); 477 break; 478 case 'p': 479 log_info("USER:\'%c\'", cmd); 480 printf("Set speaker gain to 12 (higher)\n"); 481 hfp_ag_set_speaker_gain(device_addr, 12); 482 break; 483 case 'P': 484 log_info("USER:\'%c\'", cmd); 485 printf("Set speaker gain to 15 (maximum)\n"); 486 hfp_ag_set_speaker_gain(device_addr, 15); 487 break; 488 case 'q': 489 log_info("USER:\'%c\'", cmd); 490 printf("Set microphone gain to 0\n"); 491 hfp_ag_set_microphone_gain(device_addr, 0); 492 break; 493 case 'Q': 494 log_info("USER:\'%c\'", cmd); 495 printf("Set microphone gain to 9\n"); 496 hfp_ag_set_microphone_gain(device_addr, 9); 497 break; 498 case 's': 499 log_info("USER:\'%c\'", cmd); 500 printf("Set microphone gain to 12\n"); 501 hfp_ag_set_microphone_gain(device_addr, 12); 502 break; 503 case 'S': 504 log_info("USER:\'%c\'", cmd); 505 printf("Set microphone gain to 15\n"); 506 hfp_ag_set_microphone_gain(device_addr, 15); 507 break; 508 case 'R': 509 log_info("USER:\'%c\'", cmd); 510 printf("Enable in-band ring tone\n"); 511 hfp_ag_set_use_in_band_ring_tone(1); 512 break; 513 case 't': 514 log_info("USER:\'%c\'", cmd); 515 printf("Terminate HCI connection.\n"); 516 gap_disconnect(handle); 517 break; 518 case 'u': 519 log_info("USER:\'%c\'", cmd); 520 printf("Join held call\n"); 521 hfp_ag_join_held_call(); 522 break; 523 case 'v': 524 start_scan(); 525 break; 526 case 'w': 527 log_info("USER:\'%c\'", cmd); 528 printf("AG: Put incoming call on hold (Response and Hold)\n"); 529 hfp_ag_hold_incoming_call(); 530 break; 531 case 'x': 532 log_info("USER:\'%c\'", cmd); 533 printf("AG: Accept held incoming call (Response and Hold)\n"); 534 hfp_ag_accept_held_incoming_call(); 535 break; 536 case 'X': 537 log_info("USER:\'%c\'", cmd); 538 printf("AG: Reject held incoming call (Response and Hold)\n"); 539 hfp_ag_reject_held_incoming_call(); 540 break; 541 default: 542 show_usage(); 543 break; 544 } 545 546 return 0; 547 } 548 #endif 549 550 static void packet_handler(uint8_t * event, uint16_t event_size){ 551 552 if (event[0] == RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE){ 553 handle = little_endian_read_16(event, 9); 554 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE received for handle 0x%04x\n", handle); 555 return; 556 } 557 558 switch (event[0]){ 559 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: 560 handle = little_endian_read_16(event, 9); 561 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE received for handle 0x%04x\n", handle); 562 return; 563 564 case HCI_EVENT_INQUIRY_RESULT: 565 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 566 case HCI_EVENT_INQUIRY_COMPLETE: 567 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 568 inquiry_packet_handler(HCI_EVENT_PACKET, event, event_size); 569 break; 570 571 default: 572 break; 573 } 574 575 576 if (event[0] != HCI_EVENT_HFP_META) return; 577 578 if (event[3] 579 && event[2] != HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 580 && event[2] != HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 581 && event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES){ 582 printf("ERROR, status: %u\n", event[3]); 583 return; 584 } 585 586 switch (event[2]) { 587 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 588 printf("Service level connection established.\n"); 589 break; 590 case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED: 591 printf("Service level connection released.\n"); 592 break; 593 case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED: 594 printf("\n** Audio connection established **\n"); 595 break; 596 case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED: 597 printf("\n** Audio connection released **\n"); 598 break; 599 case HFP_SUBEVENT_START_RINGINIG: 600 printf("\n** Start Ringing **\n"); 601 break; 602 case HFP_SUBEVENT_STOP_RINGINIG: 603 printf("\n** Stop Ringing **\n"); 604 break; 605 case HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER: 606 printf("\n** Outgoing call '%s' **\n", &event[3]); 607 // validate number 608 if ( strcmp("1234567", (char*) &event[3]) == 0 609 || strcmp("7654321", (char*) &event[3]) == 0 610 || (memory_1_enabled && strcmp(">1", (char*) &event[3]) == 0)){ 611 printf("Dialstring valid: accept call\n"); 612 hfp_ag_outgoing_call_accepted(); 613 } else { 614 printf("Dialstring invalid: reject call\n"); 615 hfp_ag_outgoing_call_rejected(); 616 } 617 break; 618 619 case HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG: 620 printf("\n** Attach number to voice tag. Sending '1234567\n"); 621 hfp_ag_send_phone_number_for_voice_tag(device_addr, "1234567"); 622 break; 623 case HFP_SUBEVENT_TRANSMIT_DTMF_CODES: 624 printf("\n** Send DTMF Codes: '%s'\n", &event[3]); 625 hfp_ag_send_dtmf_code_done(device_addr); 626 break; 627 case HFP_CMD_CALL_ANSWERED: 628 printf("Call answered by HF\n"); 629 break; 630 default: 631 printf("Event not handled %u\n", event[2]); 632 break; 633 } 634 } 635 636 static hfp_phone_number_t subscriber_number = { 637 129, "225577" 638 }; 639 640 /* @section Main Application Setup 641 * 642 * @text Listing MainConfiguration shows main application code. 643 * To run a HFP AG service you need to initialize the SDP, and to create and register HFP AG record with it. 644 * The packet_handler is used for sending commands to the HFP HF. It also receives the HFP HF's answers. 645 * The stdin_process callback allows for sending commands to the HFP HF. 646 * At the end the Bluetooth stack is started. 647 */ 648 649 /* LISTING_START(MainConfiguration): Setup HFP Audio Gateway */ 650 651 int btstack_main(int argc, const char * argv[]); 652 int btstack_main(int argc, const char * argv[]){ 653 // HFP HS address is hardcoded, please change it 654 // init L2CAP 655 l2cap_init(); 656 rfcomm_init(); 657 sdp_init(); 658 659 hfp_ag_init(rfcomm_channel_nr); 660 hfp_ag_init_supported_features(0x3ef | (1<<HFP_AGSF_HF_INDICATORS) | (1<<HFP_AGSF_ESCO_S4)); 661 hfp_ag_init_codecs(sizeof(codecs), codecs); 662 hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators); 663 hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators); 664 hfp_ag_init_call_hold_services(call_hold_services_nr, call_hold_services); 665 666 hfp_ag_set_subcriber_number_information(&subscriber_number, 1); 667 hfp_ag_register_packet_handler(packet_handler); 668 669 memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer)); 670 hfp_ag_create_sdp_record( hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_ag_service_name, 0, 0); 671 printf("SDP service record size: %u\n", de_get_len( hfp_service_buffer)); 672 sdp_register_service(hfp_service_buffer); 673 674 #ifdef HAVE_STDIO 675 btstack_stdin_setup(stdin_process); 676 #endif 677 // turn on! 678 hci_power_control(HCI_POWER_ON); 679 return 0; 680 } 681 /* LISTING_END */ 682