1fffdd288SMatthias Ringwald /* 2fffdd288SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3fffdd288SMatthias Ringwald * 4fffdd288SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5fffdd288SMatthias Ringwald * modification, are permitted provided that the following conditions 6fffdd288SMatthias Ringwald * are met: 7fffdd288SMatthias Ringwald * 8fffdd288SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9fffdd288SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10fffdd288SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11fffdd288SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12fffdd288SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13fffdd288SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14fffdd288SMatthias Ringwald * contributors may be used to endorse or promote products derived 15fffdd288SMatthias Ringwald * from this software without specific prior written permission. 16fffdd288SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17fffdd288SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18fffdd288SMatthias Ringwald * monetary gain. 19fffdd288SMatthias Ringwald * 20fffdd288SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21fffdd288SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22fffdd288SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23fffdd288SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24fffdd288SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25fffdd288SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26fffdd288SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27fffdd288SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28fffdd288SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29fffdd288SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30fffdd288SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31fffdd288SMatthias Ringwald * SUCH DAMAGE. 32fffdd288SMatthias Ringwald * 33fffdd288SMatthias Ringwald * Please inquire about commercial licensing options at 34fffdd288SMatthias Ringwald * [email protected] 35fffdd288SMatthias Ringwald * 36fffdd288SMatthias Ringwald */ 37fffdd288SMatthias Ringwald 38fffdd288SMatthias Ringwald /* 39fffdd288SMatthias Ringwald * hfp_ag_demo.c 40fffdd288SMatthias Ringwald */ 41fffdd288SMatthias Ringwald 42fffdd288SMatthias Ringwald // ***************************************************************************** 43fffdd288SMatthias Ringwald /* EXAMPLE_START(hfp_ag_demo): HFP Audio Gateway (AG) Demo 44fffdd288SMatthias Ringwald * 45fffdd288SMatthias Ringwald * @text This HFP Audio Gateway example demonstrates how to receive 46fffdd288SMatthias Ringwald * an output from a remote HFP Hands-Free (HF) unit, and, 47d0755cd6SMatthias Ringwald * if HAVE_POSIX_STDIN is defined, how to control the HFP HF. 48fffdd288SMatthias Ringwald */ 49fffdd288SMatthias Ringwald // ***************************************************************************** 50fffdd288SMatthias Ringwald 51fffdd288SMatthias Ringwald 52fffdd288SMatthias Ringwald #include <stdint.h> 53fffdd288SMatthias Ringwald #include <stdio.h> 54fffdd288SMatthias Ringwald #include <stdlib.h> 55fffdd288SMatthias Ringwald #include <string.h> 56fffdd288SMatthias Ringwald #include <unistd.h> 57fffdd288SMatthias Ringwald 58fffdd288SMatthias Ringwald #include "btstack.h" 59d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 60fffdd288SMatthias Ringwald #include "stdin_support.h" 614af4141bSMatthias Ringwald #endif 62fffdd288SMatthias Ringwald 63fffdd288SMatthias Ringwald 643cef842bSMatthias Ringwald static int phase = 0; 653cef842bSMatthias Ringwald 663cef842bSMatthias Ringwald // input signal: pre-computed sine wave, 160 Hz 673cef842bSMatthias Ringwald static const uint8_t sine[] = { 683cef842bSMatthias Ringwald 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, 693cef842bSMatthias Ringwald 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, 703cef842bSMatthias Ringwald 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, 713cef842bSMatthias Ringwald 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, 723cef842bSMatthias Ringwald 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, 733cef842bSMatthias Ringwald }; 743cef842bSMatthias Ringwald 75fffdd288SMatthias Ringwald uint8_t hfp_service_buffer[150]; 76fffdd288SMatthias Ringwald const uint8_t rfcomm_channel_nr = 1; 77fffdd288SMatthias Ringwald const char hfp_ag_service_name[] = "BTstack HFP AG Test"; 78fffdd288SMatthias Ringwald 79e64e0086SMatthias Ringwald // PTS 80e64e0086SMatthias Ringwald // static bd_addr_t device_addr = {0x00,0x15,0x83,0x5F,0x9D,0x46}; 81e64e0086SMatthias Ringwald // BT-201 82e64e0086SMatthias Ringwald static bd_addr_t device_addr = {0x00, 0x07, 0xB0, 0x83, 0x02, 0x5E}; 83fffdd288SMatthias Ringwald 84fffdd288SMatthias Ringwald static uint8_t codecs[1] = {HFP_CODEC_CVSD}; 85fffdd288SMatthias Ringwald static uint16_t handle = -1; 863cef842bSMatthias Ringwald static hci_con_handle_t sco_handle; 87fffdd288SMatthias Ringwald static int memory_1_enabled = 1; 88fffdd288SMatthias Ringwald 89fffdd288SMatthias Ringwald static int ag_indicators_nr = 7; 90fffdd288SMatthias Ringwald static hfp_ag_indicator_t ag_indicators[] = { 91fffdd288SMatthias Ringwald // index, name, min range, max range, status, mandatory, enabled, status changed 92fffdd288SMatthias Ringwald {1, "service", 0, 1, 1, 0, 0, 0}, 93fffdd288SMatthias Ringwald {2, "call", 0, 1, 0, 1, 1, 0}, 94fffdd288SMatthias Ringwald {3, "callsetup", 0, 3, 0, 1, 1, 0}, 95fffdd288SMatthias Ringwald {4, "battchg", 0, 5, 3, 0, 0, 0}, 96fffdd288SMatthias Ringwald {5, "signal", 0, 5, 5, 0, 1, 0}, 97fffdd288SMatthias Ringwald {6, "roam", 0, 1, 0, 0, 1, 0}, 98fffdd288SMatthias Ringwald {7, "callheld", 0, 2, 0, 1, 1, 0} 99fffdd288SMatthias Ringwald }; 100fffdd288SMatthias Ringwald 101fffdd288SMatthias Ringwald static int call_hold_services_nr = 5; 102fffdd288SMatthias Ringwald static const char* call_hold_services[] = {"1", "1x", "2", "2x", "3"}; 103fffdd288SMatthias Ringwald 104fffdd288SMatthias Ringwald static int hf_indicators_nr = 2; 105fffdd288SMatthias Ringwald static hfp_generic_status_indicator_t hf_indicators[] = { 106fffdd288SMatthias Ringwald {1, 1}, 107fffdd288SMatthias Ringwald {2, 1}, 108fffdd288SMatthias Ringwald }; 109fffdd288SMatthias Ringwald 110fffdd288SMatthias Ringwald char cmd; 111fffdd288SMatthias Ringwald 112fffdd288SMatthias Ringwald // GAP INQUIRY 113fffdd288SMatthias Ringwald 114fffdd288SMatthias Ringwald #define MAX_DEVICES 10 115fffdd288SMatthias Ringwald enum DEVICE_STATE { REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, REMOTE_NAME_FETCHED }; 116fffdd288SMatthias Ringwald struct device { 117fffdd288SMatthias Ringwald bd_addr_t address; 118fffdd288SMatthias Ringwald uint16_t clockOffset; 119fffdd288SMatthias Ringwald uint32_t classOfDevice; 120fffdd288SMatthias Ringwald uint8_t pageScanRepetitionMode; 121fffdd288SMatthias Ringwald uint8_t rssi; 122fffdd288SMatthias Ringwald enum DEVICE_STATE state; 123fffdd288SMatthias Ringwald }; 124fffdd288SMatthias Ringwald 125fffdd288SMatthias Ringwald #define INQUIRY_INTERVAL 5 126fffdd288SMatthias Ringwald struct device devices[MAX_DEVICES]; 127fffdd288SMatthias Ringwald int deviceCount = 0; 128fffdd288SMatthias Ringwald 129fffdd288SMatthias Ringwald 130fffdd288SMatthias Ringwald enum STATE {INIT, W4_INQUIRY_MODE_COMPLETE, ACTIVE} ; 131fffdd288SMatthias Ringwald enum STATE state = INIT; 132fffdd288SMatthias Ringwald 133fffdd288SMatthias Ringwald 134fffdd288SMatthias Ringwald static int getDeviceIndexForAddress( bd_addr_t addr){ 135fffdd288SMatthias Ringwald int j; 136fffdd288SMatthias Ringwald for (j=0; j< deviceCount; j++){ 137fffdd288SMatthias Ringwald if (bd_addr_cmp(addr, devices[j].address) == 0){ 138fffdd288SMatthias Ringwald return j; 139fffdd288SMatthias Ringwald } 140fffdd288SMatthias Ringwald } 141fffdd288SMatthias Ringwald return -1; 142fffdd288SMatthias Ringwald } 143fffdd288SMatthias Ringwald 144d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 145fffdd288SMatthias Ringwald static void start_scan(void){ 146fffdd288SMatthias Ringwald printf("Starting inquiry scan..\n"); 147fffdd288SMatthias Ringwald hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); 148fffdd288SMatthias Ringwald } 149fffdd288SMatthias Ringwald #endif 150fffdd288SMatthias Ringwald 151fffdd288SMatthias Ringwald static int has_more_remote_name_requests(void){ 152fffdd288SMatthias Ringwald int i; 153fffdd288SMatthias Ringwald for (i=0;i<deviceCount;i++) { 154fffdd288SMatthias Ringwald if (devices[i].state == REMOTE_NAME_REQUEST) return 1; 155fffdd288SMatthias Ringwald } 156fffdd288SMatthias Ringwald return 0; 157fffdd288SMatthias Ringwald } 158fffdd288SMatthias Ringwald 159fffdd288SMatthias Ringwald static void do_next_remote_name_request(void){ 160fffdd288SMatthias Ringwald int i; 161fffdd288SMatthias Ringwald for (i=0;i<deviceCount;i++) { 162fffdd288SMatthias Ringwald // remote name request 163fffdd288SMatthias Ringwald if (devices[i].state == REMOTE_NAME_REQUEST){ 164fffdd288SMatthias Ringwald devices[i].state = REMOTE_NAME_INQUIRED; 165fffdd288SMatthias Ringwald printf("Get remote name of %s...\n", bd_addr_to_str(devices[i].address)); 166fffdd288SMatthias Ringwald hci_send_cmd(&hci_remote_name_request, devices[i].address, 167fffdd288SMatthias Ringwald devices[i].pageScanRepetitionMode, 0, devices[i].clockOffset | 0x8000); 168fffdd288SMatthias Ringwald return; 169fffdd288SMatthias Ringwald } 170fffdd288SMatthias Ringwald } 171fffdd288SMatthias Ringwald } 172fffdd288SMatthias Ringwald 173fffdd288SMatthias Ringwald static void continue_remote_names(void){ 174fffdd288SMatthias Ringwald // don't get remote names for testing 175fffdd288SMatthias Ringwald if (has_more_remote_name_requests()){ 176fffdd288SMatthias Ringwald do_next_remote_name_request(); 177fffdd288SMatthias Ringwald return; 178fffdd288SMatthias Ringwald } 179fffdd288SMatthias Ringwald // try to find PTS 180fffdd288SMatthias Ringwald int i; 181fffdd288SMatthias Ringwald for (i=0;i<deviceCount;i++){ 182fffdd288SMatthias Ringwald if (memcmp(devices[i].address, device_addr, 6) == 0){ 183fffdd288SMatthias Ringwald printf("Inquiry scan over, successfully found PTS at index %u\nReady to connect to it.\n", i); 184fffdd288SMatthias Ringwald return; 185fffdd288SMatthias Ringwald } 186fffdd288SMatthias Ringwald } 187fffdd288SMatthias Ringwald printf("Inquiry scan over but PTS not found :(\n"); 188fffdd288SMatthias Ringwald } 189fffdd288SMatthias Ringwald 190fffdd288SMatthias Ringwald static void inquiry_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 191fffdd288SMatthias Ringwald bd_addr_t addr; 192fffdd288SMatthias Ringwald int i; 193fffdd288SMatthias Ringwald int numResponses; 194fffdd288SMatthias Ringwald int index; 195fffdd288SMatthias Ringwald 196fffdd288SMatthias Ringwald // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); 197fffdd288SMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 198fffdd288SMatthias Ringwald 199fffdd288SMatthias Ringwald uint8_t event = packet[0]; 200fffdd288SMatthias Ringwald 201fffdd288SMatthias Ringwald switch(event){ 202fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_RESULT: 203fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{ 204f8744deaSMilanka Ringwald numResponses = hci_event_inquiry_result_get_num_responses(packet); 205fffdd288SMatthias Ringwald int offset = 3; 206fffdd288SMatthias Ringwald for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ 207e64e0086SMatthias Ringwald reverse_bd_addr(&packet[offset], addr); 208fffdd288SMatthias Ringwald offset += 6; 209fffdd288SMatthias Ringwald index = getDeviceIndexForAddress(addr); 210fffdd288SMatthias Ringwald if (index >= 0) continue; // already in our list 211fffdd288SMatthias Ringwald memcpy(devices[deviceCount].address, addr, 6); 212fffdd288SMatthias Ringwald 213fffdd288SMatthias Ringwald devices[deviceCount].pageScanRepetitionMode = packet[offset]; 214fffdd288SMatthias Ringwald offset += 1; 215fffdd288SMatthias Ringwald 216fffdd288SMatthias Ringwald if (event == HCI_EVENT_INQUIRY_RESULT){ 217fffdd288SMatthias Ringwald offset += 2; // Reserved + Reserved 218fffdd288SMatthias Ringwald devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); 219fffdd288SMatthias Ringwald offset += 3; 220fffdd288SMatthias Ringwald devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; 221fffdd288SMatthias Ringwald offset += 2; 222fffdd288SMatthias Ringwald devices[deviceCount].rssi = 0; 223fffdd288SMatthias Ringwald } else { 224fffdd288SMatthias Ringwald offset += 1; // Reserved 225fffdd288SMatthias Ringwald devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); 226fffdd288SMatthias Ringwald offset += 3; 227fffdd288SMatthias Ringwald devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; 228fffdd288SMatthias Ringwald offset += 2; 229fffdd288SMatthias Ringwald devices[deviceCount].rssi = packet[offset]; 230fffdd288SMatthias Ringwald offset += 1; 231fffdd288SMatthias Ringwald } 232fffdd288SMatthias Ringwald devices[deviceCount].state = REMOTE_NAME_REQUEST; 233fffdd288SMatthias Ringwald printf("Device #%u found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", 234fffdd288SMatthias Ringwald deviceCount, bd_addr_to_str(addr), 235fffdd288SMatthias Ringwald devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, 236fffdd288SMatthias Ringwald devices[deviceCount].clockOffset, devices[deviceCount].rssi); 237fffdd288SMatthias Ringwald deviceCount++; 238fffdd288SMatthias Ringwald } 239fffdd288SMatthias Ringwald 240fffdd288SMatthias Ringwald break; 241fffdd288SMatthias Ringwald } 242fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_COMPLETE: 243fffdd288SMatthias Ringwald for (i=0;i<deviceCount;i++) { 244fffdd288SMatthias Ringwald // retry remote name request 245fffdd288SMatthias Ringwald if (devices[i].state == REMOTE_NAME_INQUIRED) 246fffdd288SMatthias Ringwald devices[i].state = REMOTE_NAME_REQUEST; 247fffdd288SMatthias Ringwald } 248fffdd288SMatthias Ringwald continue_remote_names(); 249fffdd288SMatthias Ringwald break; 250fffdd288SMatthias Ringwald 251fffdd288SMatthias Ringwald case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 252e64e0086SMatthias Ringwald reverse_bd_addr(&packet[3], addr); 253fffdd288SMatthias Ringwald index = getDeviceIndexForAddress(addr); 254fffdd288SMatthias Ringwald if (index >= 0) { 255fffdd288SMatthias Ringwald if (packet[2] == 0) { 256fffdd288SMatthias Ringwald printf("Name: '%s'\n", &packet[9]); 257fffdd288SMatthias Ringwald devices[index].state = REMOTE_NAME_FETCHED; 258fffdd288SMatthias Ringwald } else { 259fffdd288SMatthias Ringwald printf("Failed to get name: page timeout\n"); 260fffdd288SMatthias Ringwald } 261fffdd288SMatthias Ringwald } 262fffdd288SMatthias Ringwald continue_remote_names(); 263fffdd288SMatthias Ringwald break; 264fffdd288SMatthias Ringwald 265fffdd288SMatthias Ringwald default: 266fffdd288SMatthias Ringwald break; 267fffdd288SMatthias Ringwald } 268fffdd288SMatthias Ringwald } 269fffdd288SMatthias Ringwald // GAP INQUIRY END 270d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 271fffdd288SMatthias Ringwald 272fffdd288SMatthias Ringwald // prototypes 27335833313SMatthias Ringwald static void show_usage(void); 274fffdd288SMatthias Ringwald 275fffdd288SMatthias Ringwald // Testig User Interface 276fffdd288SMatthias Ringwald static void show_usage(void){ 277e64e0086SMatthias Ringwald bd_addr_t iut_address; 278e64e0086SMatthias Ringwald gap_local_bd_addr(iut_address); 279e64e0086SMatthias Ringwald 280e64e0086SMatthias Ringwald printf("\n--- Bluetooth HFP Audiogateway (AG) unit Test Console %s ---\n", bd_addr_to_str(iut_address)); 281fffdd288SMatthias Ringwald printf("---\n"); 282fffdd288SMatthias Ringwald 283*bdb44bd9SMatthias Ringwald printf("a - establish HFP connection to PTS module %s\n", bd_addr_to_str(device_addr)); 284fffdd288SMatthias Ringwald // printf("A - release HFP connection to PTS module\n"); 285fffdd288SMatthias Ringwald 286fffdd288SMatthias Ringwald printf("b - establish AUDIO connection\n"); 287fffdd288SMatthias Ringwald printf("B - release AUDIO connection\n"); 288fffdd288SMatthias Ringwald 289fffdd288SMatthias Ringwald printf("c - simulate incoming call from 1234567\n"); 290fffdd288SMatthias Ringwald printf("C - simulate call from 1234567 dropped\n"); 291fffdd288SMatthias Ringwald 292fffdd288SMatthias Ringwald printf("d - report AG failure\n"); 293fffdd288SMatthias Ringwald 294fffdd288SMatthias Ringwald printf("e - answer call on AG\n"); 295fffdd288SMatthias Ringwald printf("E - reject call on AG\n"); 296fffdd288SMatthias Ringwald 297fffdd288SMatthias Ringwald printf("r - disable in-band ring tone\n"); 298fffdd288SMatthias Ringwald printf("R - enable in-band ring tone\n"); 299fffdd288SMatthias Ringwald 300fffdd288SMatthias Ringwald printf("f - Disable cellular network\n"); 301fffdd288SMatthias Ringwald printf("F - Enable cellular network\n"); 302fffdd288SMatthias Ringwald 303fffdd288SMatthias Ringwald printf("g - Set signal strength to 0\n"); 304fffdd288SMatthias Ringwald printf("G - Set signal strength to 5\n"); 305fffdd288SMatthias Ringwald 306fffdd288SMatthias Ringwald printf("h - Disable roaming\n"); 307fffdd288SMatthias Ringwald printf("H - Enable roaming\n"); 308fffdd288SMatthias Ringwald 309fffdd288SMatthias Ringwald printf("i - Set battery level to 3\n"); 310fffdd288SMatthias Ringwald printf("I - Set battery level to 5\n"); 311fffdd288SMatthias Ringwald 312fffdd288SMatthias Ringwald printf("j - Answering call on remote side\n"); 313fffdd288SMatthias Ringwald 314fffdd288SMatthias Ringwald printf("k - Clear memory #1\n"); 315fffdd288SMatthias Ringwald printf("K - Set memory #1\n"); 316fffdd288SMatthias Ringwald 317fffdd288SMatthias Ringwald printf("l - Clear last number\n"); 318fffdd288SMatthias Ringwald printf("L - Set last number\n"); 319fffdd288SMatthias Ringwald 320fffdd288SMatthias Ringwald printf("m - simulate incoming call from 7654321\n"); 321fffdd288SMatthias Ringwald // printf("M - simulate call from 7654321 dropped\n"); 322fffdd288SMatthias Ringwald 323fffdd288SMatthias Ringwald printf("n - Disable Voice Regocnition\n"); 324fffdd288SMatthias Ringwald printf("N - Enable Voice Recognition\n"); 325fffdd288SMatthias Ringwald 326fffdd288SMatthias Ringwald printf("o - Set speaker volume to 0 (minimum)\n"); 327fffdd288SMatthias Ringwald printf("O - Set speaker volume to 9 (default)\n"); 328fffdd288SMatthias Ringwald printf("p - Set speaker volume to 12 (higher)\n"); 329fffdd288SMatthias Ringwald printf("P - Set speaker volume to 15 (maximum)\n"); 330fffdd288SMatthias Ringwald 331fffdd288SMatthias Ringwald printf("q - Set microphone gain to 0 (minimum)\n"); 332fffdd288SMatthias Ringwald printf("Q - Set microphone gain to 9 (default)\n"); 333fffdd288SMatthias Ringwald printf("s - Set microphone gain to 12 (higher)\n"); 334fffdd288SMatthias Ringwald printf("S - Set microphone gain to 15 (maximum)\n"); 335fffdd288SMatthias Ringwald 336fffdd288SMatthias Ringwald printf("t - terminate connection\n"); 337fffdd288SMatthias Ringwald printf("u - join held call\n"); 338fffdd288SMatthias Ringwald printf("v - discover nearby HF units\n"); 339fffdd288SMatthias Ringwald printf("w - put incoming call on hold (Response and Hold)\n"); 340fffdd288SMatthias Ringwald printf("x - accept held incoming call (Response and Hold)\n"); 341fffdd288SMatthias Ringwald printf("X - reject held incoming call (Response and Hold)\n"); 342fffdd288SMatthias Ringwald 343fffdd288SMatthias Ringwald printf("---\n"); 344fffdd288SMatthias Ringwald printf("Ctrl-c - exit\n"); 345fffdd288SMatthias Ringwald printf("---\n"); 346fffdd288SMatthias Ringwald } 347fffdd288SMatthias Ringwald 3484af4141bSMatthias Ringwald static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 349fffdd288SMatthias Ringwald read(ds->fd, &cmd, 1); 350fffdd288SMatthias Ringwald switch (cmd){ 351fffdd288SMatthias Ringwald case 'a': 352fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 353fffdd288SMatthias Ringwald printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr)); 354fffdd288SMatthias Ringwald hfp_ag_establish_service_level_connection(device_addr); 355fffdd288SMatthias Ringwald break; 356fffdd288SMatthias Ringwald case 'A': 357fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 358fffdd288SMatthias Ringwald printf("Release HFP service level connection.\n"); 359fffdd288SMatthias Ringwald hfp_ag_release_service_level_connection(device_addr); 360fffdd288SMatthias Ringwald break; 361fffdd288SMatthias Ringwald case 'Z': 362fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 363fffdd288SMatthias Ringwald printf("Release HFP service level connection to %s...\n", bd_addr_to_str(device_addr)); 364fffdd288SMatthias Ringwald hfp_ag_release_service_level_connection(device_addr); 365fffdd288SMatthias Ringwald break; 366fffdd288SMatthias Ringwald case 'b': 367fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 368fffdd288SMatthias Ringwald printf("Establish Audio connection %s...\n", bd_addr_to_str(device_addr)); 369fffdd288SMatthias Ringwald hfp_ag_establish_audio_connection(device_addr); 370fffdd288SMatthias Ringwald break; 371fffdd288SMatthias Ringwald case 'B': 372fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 373fffdd288SMatthias Ringwald printf("Release Audio connection.\n"); 374fffdd288SMatthias Ringwald hfp_ag_release_audio_connection(device_addr); 375fffdd288SMatthias Ringwald break; 376fffdd288SMatthias Ringwald case 'c': 377fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 378fffdd288SMatthias Ringwald printf("Simulate incoming call from 1234567\n"); 379fffdd288SMatthias Ringwald hfp_ag_set_clip(129, "1234567"); 380fffdd288SMatthias Ringwald hfp_ag_incoming_call(); 381fffdd288SMatthias Ringwald break; 382fffdd288SMatthias Ringwald case 'm': 383fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 384fffdd288SMatthias Ringwald printf("Simulate incoming call from 7654321\n"); 385fffdd288SMatthias Ringwald hfp_ag_set_clip(129, "7654321"); 386fffdd288SMatthias Ringwald hfp_ag_incoming_call(); 387fffdd288SMatthias Ringwald break; 388fffdd288SMatthias Ringwald case 'C': 389fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 390fffdd288SMatthias Ringwald printf("Simulate terminate call\n"); 391fffdd288SMatthias Ringwald hfp_ag_call_dropped(); 392fffdd288SMatthias Ringwald break; 393fffdd288SMatthias Ringwald case 'd': 394fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 395fffdd288SMatthias Ringwald printf("Report AG failure\n"); 396fffdd288SMatthias Ringwald hfp_ag_report_extended_audio_gateway_error_result_code(device_addr, HFP_CME_ERROR_AG_FAILURE); 397fffdd288SMatthias Ringwald break; 398fffdd288SMatthias Ringwald case 'e': 399fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 400fffdd288SMatthias Ringwald printf("Answer call on AG\n"); 401fffdd288SMatthias Ringwald hfp_ag_answer_incoming_call(); 402fffdd288SMatthias Ringwald break; 403fffdd288SMatthias Ringwald case 'E': 404fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 405fffdd288SMatthias Ringwald printf("Reject call on AG\n"); 406fffdd288SMatthias Ringwald hfp_ag_terminate_call(); 407fffdd288SMatthias Ringwald break; 408fffdd288SMatthias Ringwald case 'f': 409fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 410fffdd288SMatthias Ringwald printf("Disable cellular network\n"); 411fffdd288SMatthias Ringwald hfp_ag_set_registration_status(0); 412fffdd288SMatthias Ringwald break; 413fffdd288SMatthias Ringwald case 'F': 414fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 415fffdd288SMatthias Ringwald printf("Enable cellular network\n"); 416fffdd288SMatthias Ringwald hfp_ag_set_registration_status(1); 417fffdd288SMatthias Ringwald break; 418fffdd288SMatthias Ringwald case 'g': 419fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 420fffdd288SMatthias Ringwald printf("Set signal strength to 0\n"); 421fffdd288SMatthias Ringwald hfp_ag_set_signal_strength(0); 422fffdd288SMatthias Ringwald break; 423fffdd288SMatthias Ringwald case 'G': 424fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 425fffdd288SMatthias Ringwald printf("Set signal strength to 5\n"); 426fffdd288SMatthias Ringwald hfp_ag_set_signal_strength(5); 427fffdd288SMatthias Ringwald break; 428fffdd288SMatthias Ringwald case 'h': 429fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 430fffdd288SMatthias Ringwald printf("Disable roaming\n"); 431fffdd288SMatthias Ringwald hfp_ag_set_roaming_status(0); 432fffdd288SMatthias Ringwald break; 433fffdd288SMatthias Ringwald case 'H': 434fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 435fffdd288SMatthias Ringwald printf("Enable roaming\n"); 436fffdd288SMatthias Ringwald hfp_ag_set_roaming_status(1); 437fffdd288SMatthias Ringwald break; 438fffdd288SMatthias Ringwald case 'i': 439fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 440fffdd288SMatthias Ringwald printf("Set battery level to 3\n"); 441fffdd288SMatthias Ringwald hfp_ag_set_battery_level(3); 442fffdd288SMatthias Ringwald break; 443fffdd288SMatthias Ringwald case 'I': 444fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 445fffdd288SMatthias Ringwald printf("Set battery level to 5\n"); 446fffdd288SMatthias Ringwald hfp_ag_set_battery_level(5); 447fffdd288SMatthias Ringwald break; 448fffdd288SMatthias Ringwald case 'j': 449fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 450fffdd288SMatthias Ringwald printf("Answering call on remote side\n"); 451fffdd288SMatthias Ringwald hfp_ag_outgoing_call_established(); 452fffdd288SMatthias Ringwald break; 453fffdd288SMatthias Ringwald case 'r': 454fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 455fffdd288SMatthias Ringwald printf("Disable in-band ring tone\n"); 456fffdd288SMatthias Ringwald hfp_ag_set_use_in_band_ring_tone(0); 457fffdd288SMatthias Ringwald break; 458fffdd288SMatthias Ringwald case 'k': 459fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 460fffdd288SMatthias Ringwald printf("Memory 1 cleared\n"); 461fffdd288SMatthias Ringwald memory_1_enabled = 0; 462fffdd288SMatthias Ringwald break; 463fffdd288SMatthias Ringwald case 'K': 464fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 465fffdd288SMatthias Ringwald printf("Memory 1 set\n"); 466fffdd288SMatthias Ringwald memory_1_enabled = 1; 467fffdd288SMatthias Ringwald break; 468fffdd288SMatthias Ringwald case 'l': 469fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 470fffdd288SMatthias Ringwald printf("Last dialed number cleared\n"); 471fffdd288SMatthias Ringwald hfp_ag_clear_last_dialed_number(); 472fffdd288SMatthias Ringwald break; 473fffdd288SMatthias Ringwald case 'L': 474fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 475fffdd288SMatthias Ringwald printf("Outgoing call connected, ringing\n"); 476fffdd288SMatthias Ringwald hfp_ag_outgoing_call_ringing(); 477fffdd288SMatthias Ringwald break; 478fffdd288SMatthias Ringwald case 'n': 479fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 480fffdd288SMatthias Ringwald printf("Disable Voice Recognition\n"); 481fffdd288SMatthias Ringwald hfp_ag_activate_voice_recognition(device_addr, 0); 482fffdd288SMatthias Ringwald break; 483fffdd288SMatthias Ringwald case 'N': 484fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 485fffdd288SMatthias Ringwald printf("Enable Voice Recognition\n"); 486fffdd288SMatthias Ringwald hfp_ag_activate_voice_recognition(device_addr, 1); 487fffdd288SMatthias Ringwald break; 488fffdd288SMatthias Ringwald case 'o': 489fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 490fffdd288SMatthias Ringwald printf("Set speaker gain to 0 (minimum)\n"); 491fffdd288SMatthias Ringwald hfp_ag_set_speaker_gain(device_addr, 0); 492fffdd288SMatthias Ringwald break; 493fffdd288SMatthias Ringwald case 'O': 494fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 495fffdd288SMatthias Ringwald printf("Set speaker gain to 9 (default)\n"); 496fffdd288SMatthias Ringwald hfp_ag_set_speaker_gain(device_addr, 9); 497fffdd288SMatthias Ringwald break; 498fffdd288SMatthias Ringwald case 'p': 499fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 500fffdd288SMatthias Ringwald printf("Set speaker gain to 12 (higher)\n"); 501fffdd288SMatthias Ringwald hfp_ag_set_speaker_gain(device_addr, 12); 502fffdd288SMatthias Ringwald break; 503fffdd288SMatthias Ringwald case 'P': 504fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 505fffdd288SMatthias Ringwald printf("Set speaker gain to 15 (maximum)\n"); 506fffdd288SMatthias Ringwald hfp_ag_set_speaker_gain(device_addr, 15); 507fffdd288SMatthias Ringwald break; 508fffdd288SMatthias Ringwald case 'q': 509fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 510fffdd288SMatthias Ringwald printf("Set microphone gain to 0\n"); 511fffdd288SMatthias Ringwald hfp_ag_set_microphone_gain(device_addr, 0); 512fffdd288SMatthias Ringwald break; 513fffdd288SMatthias Ringwald case 'Q': 514fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 515fffdd288SMatthias Ringwald printf("Set microphone gain to 9\n"); 516fffdd288SMatthias Ringwald hfp_ag_set_microphone_gain(device_addr, 9); 517fffdd288SMatthias Ringwald break; 518fffdd288SMatthias Ringwald case 's': 519fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 520fffdd288SMatthias Ringwald printf("Set microphone gain to 12\n"); 521fffdd288SMatthias Ringwald hfp_ag_set_microphone_gain(device_addr, 12); 522fffdd288SMatthias Ringwald break; 523fffdd288SMatthias Ringwald case 'S': 524fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 525fffdd288SMatthias Ringwald printf("Set microphone gain to 15\n"); 526fffdd288SMatthias Ringwald hfp_ag_set_microphone_gain(device_addr, 15); 527fffdd288SMatthias Ringwald break; 528fffdd288SMatthias Ringwald case 'R': 529fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 530fffdd288SMatthias Ringwald printf("Enable in-band ring tone\n"); 531fffdd288SMatthias Ringwald hfp_ag_set_use_in_band_ring_tone(1); 532fffdd288SMatthias Ringwald break; 533fffdd288SMatthias Ringwald case 't': 534fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 535e64e0086SMatthias Ringwald printf("Terminate HCI connection. 0x%2x\n", handle); 536fffdd288SMatthias Ringwald gap_disconnect(handle); 537fffdd288SMatthias Ringwald break; 538fffdd288SMatthias Ringwald case 'u': 539fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 540fffdd288SMatthias Ringwald printf("Join held call\n"); 541fffdd288SMatthias Ringwald hfp_ag_join_held_call(); 542fffdd288SMatthias Ringwald break; 543fffdd288SMatthias Ringwald case 'v': 544fffdd288SMatthias Ringwald start_scan(); 545fffdd288SMatthias Ringwald break; 546fffdd288SMatthias Ringwald case 'w': 547fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 548fffdd288SMatthias Ringwald printf("AG: Put incoming call on hold (Response and Hold)\n"); 549fffdd288SMatthias Ringwald hfp_ag_hold_incoming_call(); 550fffdd288SMatthias Ringwald break; 551fffdd288SMatthias Ringwald case 'x': 552fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 553fffdd288SMatthias Ringwald printf("AG: Accept held incoming call (Response and Hold)\n"); 554fffdd288SMatthias Ringwald hfp_ag_accept_held_incoming_call(); 555fffdd288SMatthias Ringwald break; 556fffdd288SMatthias Ringwald case 'X': 557fffdd288SMatthias Ringwald log_info("USER:\'%c\'", cmd); 558fffdd288SMatthias Ringwald printf("AG: Reject held incoming call (Response and Hold)\n"); 559fffdd288SMatthias Ringwald hfp_ag_reject_held_incoming_call(); 560fffdd288SMatthias Ringwald break; 561fffdd288SMatthias Ringwald default: 562fffdd288SMatthias Ringwald show_usage(); 563fffdd288SMatthias Ringwald break; 564fffdd288SMatthias Ringwald } 565fffdd288SMatthias Ringwald } 566fffdd288SMatthias Ringwald #endif 567fffdd288SMatthias Ringwald 5683cef842bSMatthias Ringwald #define SCO_REPORT_PERIOD 100 5693cef842bSMatthias Ringwald static void send_sco_data(void){ 5703cef842bSMatthias Ringwald if (!sco_handle) return; 5713cef842bSMatthias Ringwald 5723cef842bSMatthias Ringwald const int sco_packet_length = hci_get_sco_packet_length(); 5733cef842bSMatthias Ringwald const int sco_payload_length = sco_packet_length - 3; 5743cef842bSMatthias Ringwald const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 5753cef842bSMatthias Ringwald 5763cef842bSMatthias Ringwald hci_reserve_packet_buffer(); 5773cef842bSMatthias Ringwald uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); 5783cef842bSMatthias Ringwald // set handle + flags 5793cef842bSMatthias Ringwald little_endian_store_16(sco_packet, 0, sco_handle); 5803cef842bSMatthias Ringwald // set len 5813cef842bSMatthias Ringwald sco_packet[2] = sco_payload_length; 5823cef842bSMatthias Ringwald int i; 5833cef842bSMatthias Ringwald for (i=0;i<frames_per_packet;i++){ 5843cef842bSMatthias Ringwald sco_packet[3+i] = sine[phase]; 5853cef842bSMatthias Ringwald phase++; 5863cef842bSMatthias Ringwald if (phase >= sizeof(sine)) phase = 0; 5873cef842bSMatthias Ringwald } 5883cef842bSMatthias Ringwald hci_send_sco_packet_buffer(sco_packet_length); 5893cef842bSMatthias Ringwald 5903cef842bSMatthias Ringwald // request another send event 5913cef842bSMatthias Ringwald hci_request_sco_can_send_now_event(); 5923cef842bSMatthias Ringwald 5933cef842bSMatthias Ringwald static int count = 0; 5943cef842bSMatthias Ringwald count++; 595*bdb44bd9SMatthias Ringwald if ((count % SCO_REPORT_PERIOD) == 0) printf("Sent %u\n", count); 5963cef842bSMatthias Ringwald } 5973cef842bSMatthias Ringwald 59813839019SMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){ 5993cef842bSMatthias Ringwald switch (packet_type){ 6003cef842bSMatthias Ringwald case HCI_EVENT_PACKET: 601fffdd288SMatthias Ringwald switch (event[0]){ 602fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_RESULT: 603fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 604fffdd288SMatthias Ringwald case HCI_EVENT_INQUIRY_COMPLETE: 605fffdd288SMatthias Ringwald case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: 606fffdd288SMatthias Ringwald inquiry_packet_handler(HCI_EVENT_PACKET, event, event_size); 607fffdd288SMatthias Ringwald break; 60813839019SMatthias Ringwald case HCI_EVENT_SCO_CAN_SEND_NOW: 60913839019SMatthias Ringwald send_sco_data(); 61013839019SMatthias Ringwald break; 611fffdd288SMatthias Ringwald default: 612fffdd288SMatthias Ringwald break; 613fffdd288SMatthias Ringwald } 614fffdd288SMatthias Ringwald 615fffdd288SMatthias Ringwald if (event[0] != HCI_EVENT_HFP_META) return; 616fffdd288SMatthias Ringwald 617fffdd288SMatthias Ringwald if (event[3] 618fffdd288SMatthias Ringwald && event[2] != HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 619fffdd288SMatthias Ringwald && event[2] != HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 620fffdd288SMatthias Ringwald && event[2] != HFP_SUBEVENT_TRANSMIT_DTMF_CODES){ 621fffdd288SMatthias Ringwald printf("ERROR, status: %u\n", event[3]); 622fffdd288SMatthias Ringwald return; 623fffdd288SMatthias Ringwald } 624fffdd288SMatthias Ringwald 625fffdd288SMatthias Ringwald switch (event[2]) { 626fffdd288SMatthias Ringwald case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED: 627a0653c3bSMilanka Ringwald handle = hfp_subevent_service_level_connection_established_get_con_handle(event); 628fffdd288SMatthias Ringwald printf("Service level connection established.\n"); 629fffdd288SMatthias Ringwald break; 630fffdd288SMatthias Ringwald case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED: 631fffdd288SMatthias Ringwald printf("Service level connection released.\n"); 6323cef842bSMatthias Ringwald sco_handle = 0; 633fffdd288SMatthias Ringwald break; 634fffdd288SMatthias Ringwald case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED: 6353cef842bSMatthias Ringwald if (hfp_subevent_audio_connection_established_get_status(event)){ 6363cef842bSMatthias Ringwald printf("Audio connection establishment failed with status %u\n", hfp_subevent_audio_connection_established_get_status(event)); 6373cef842bSMatthias Ringwald sco_handle = 0; 6383cef842bSMatthias Ringwald } else { 6393cef842bSMatthias Ringwald sco_handle = hfp_subevent_audio_connection_established_get_handle(event); 6403cef842bSMatthias Ringwald printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle); 6413cef842bSMatthias Ringwald hci_request_sco_can_send_now_event(); 6423cef842bSMatthias Ringwald } 643fffdd288SMatthias Ringwald break; 644fffdd288SMatthias Ringwald case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED: 645fffdd288SMatthias Ringwald printf("\n** Audio connection released **\n"); 6463cef842bSMatthias Ringwald sco_handle = 0; 647fffdd288SMatthias Ringwald break; 648fffdd288SMatthias Ringwald case HFP_SUBEVENT_START_RINGINIG: 649fffdd288SMatthias Ringwald printf("\n** Start Ringing **\n"); 650fffdd288SMatthias Ringwald break; 651fffdd288SMatthias Ringwald case HFP_SUBEVENT_STOP_RINGINIG: 652fffdd288SMatthias Ringwald printf("\n** Stop Ringing **\n"); 653fffdd288SMatthias Ringwald break; 654fffdd288SMatthias Ringwald case HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER: 6550696953aSMilanka Ringwald printf("\n** Outgoing call '%s' **\n", hfp_subevent_place_call_with_number_get_number(event)); 656fffdd288SMatthias Ringwald // validate number 6570696953aSMilanka Ringwald if ( strcmp("1234567", hfp_subevent_place_call_with_number_get_number(event)) == 0 6580696953aSMilanka Ringwald || strcmp("7654321", hfp_subevent_place_call_with_number_get_number(event)) == 0 6590696953aSMilanka Ringwald || (memory_1_enabled && strcmp(">1", hfp_subevent_place_call_with_number_get_number(event)) == 0)){ 660fffdd288SMatthias Ringwald printf("Dialstring valid: accept call\n"); 661fffdd288SMatthias Ringwald hfp_ag_outgoing_call_accepted(); 662fffdd288SMatthias Ringwald } else { 663fffdd288SMatthias Ringwald printf("Dialstring invalid: reject call\n"); 664fffdd288SMatthias Ringwald hfp_ag_outgoing_call_rejected(); 665fffdd288SMatthias Ringwald } 666fffdd288SMatthias Ringwald break; 667fffdd288SMatthias Ringwald 668fffdd288SMatthias Ringwald case HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG: 669fffdd288SMatthias Ringwald printf("\n** Attach number to voice tag. Sending '1234567\n"); 670fffdd288SMatthias Ringwald hfp_ag_send_phone_number_for_voice_tag(device_addr, "1234567"); 671fffdd288SMatthias Ringwald break; 672fffdd288SMatthias Ringwald case HFP_SUBEVENT_TRANSMIT_DTMF_CODES: 6730696953aSMilanka Ringwald printf("\n** Send DTMF Codes: '%s'\n", hfp_subevent_transmit_dtmf_codes_get_dtmf(event)); 674fffdd288SMatthias Ringwald hfp_ag_send_dtmf_code_done(device_addr); 675fffdd288SMatthias Ringwald break; 6760696953aSMilanka Ringwald case HFP_SUBEVENT_CALL_ANSWERED: 677fffdd288SMatthias Ringwald printf("Call answered by HF\n"); 678fffdd288SMatthias Ringwald break; 679fffdd288SMatthias Ringwald default: 680fffdd288SMatthias Ringwald printf("Event not handled %u\n", event[2]); 681fffdd288SMatthias Ringwald break; 682fffdd288SMatthias Ringwald } 68313839019SMatthias Ringwald default: 68413839019SMatthias Ringwald break; 68513839019SMatthias Ringwald } 686fffdd288SMatthias Ringwald } 687fffdd288SMatthias Ringwald 688fffdd288SMatthias Ringwald static hfp_phone_number_t subscriber_number = { 689fffdd288SMatthias Ringwald 129, "225577" 690fffdd288SMatthias Ringwald }; 691fffdd288SMatthias Ringwald 692fffdd288SMatthias Ringwald /* @section Main Application Setup 693fffdd288SMatthias Ringwald * 694fffdd288SMatthias Ringwald * @text Listing MainConfiguration shows main application code. 695fffdd288SMatthias Ringwald * To run a HFP AG service you need to initialize the SDP, and to create and register HFP AG record with it. 696fffdd288SMatthias Ringwald * The packet_handler is used for sending commands to the HFP HF. It also receives the HFP HF's answers. 697fffdd288SMatthias Ringwald * The stdin_process callback allows for sending commands to the HFP HF. 698fffdd288SMatthias Ringwald * At the end the Bluetooth stack is started. 699fffdd288SMatthias Ringwald */ 700fffdd288SMatthias Ringwald 701fffdd288SMatthias Ringwald /* LISTING_START(MainConfiguration): Setup HFP Audio Gateway */ 702fffdd288SMatthias Ringwald 703fffdd288SMatthias Ringwald int btstack_main(int argc, const char * argv[]); 704fffdd288SMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 705fffdd288SMatthias Ringwald 706e64e0086SMatthias Ringwald gap_discoverable_control(1); 707e64e0086SMatthias Ringwald 708e64e0086SMatthias Ringwald // L2CAP 709e64e0086SMatthias Ringwald l2cap_init(); 710e64e0086SMatthias Ringwald 711e64e0086SMatthias Ringwald // HFP 712e64e0086SMatthias Ringwald rfcomm_init(); 713fffdd288SMatthias Ringwald hfp_ag_init(rfcomm_channel_nr); 714fffdd288SMatthias Ringwald hfp_ag_init_supported_features(0x3ef | (1<<HFP_AGSF_HF_INDICATORS) | (1<<HFP_AGSF_ESCO_S4)); 715fffdd288SMatthias Ringwald hfp_ag_init_codecs(sizeof(codecs), codecs); 716fffdd288SMatthias Ringwald hfp_ag_init_ag_indicators(ag_indicators_nr, ag_indicators); 717fffdd288SMatthias Ringwald hfp_ag_init_hf_indicators(hf_indicators_nr, hf_indicators); 718fffdd288SMatthias Ringwald hfp_ag_init_call_hold_services(call_hold_services_nr, call_hold_services); 719fffdd288SMatthias Ringwald hfp_ag_set_subcriber_number_information(&subscriber_number, 1); 7203cef842bSMatthias Ringwald hfp_ag_register_packet_handler(&packet_handler); 72113839019SMatthias Ringwald hci_register_sco_packet_handler(&packet_handler); 722fffdd288SMatthias Ringwald 723e64e0086SMatthias Ringwald // SDP Server 724e64e0086SMatthias Ringwald sdp_init(); 725fffdd288SMatthias Ringwald memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer)); 726fffdd288SMatthias Ringwald hfp_ag_create_sdp_record( hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_ag_service_name, 0, 0); 727fffdd288SMatthias Ringwald printf("SDP service record size: %u\n", de_get_len( hfp_service_buffer)); 728fffdd288SMatthias Ringwald sdp_register_service(hfp_service_buffer); 729fffdd288SMatthias Ringwald 730d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 731fffdd288SMatthias Ringwald btstack_stdin_setup(stdin_process); 732fffdd288SMatthias Ringwald #endif 733fffdd288SMatthias Ringwald // turn on! 734fffdd288SMatthias Ringwald hci_power_control(HCI_POWER_ON); 735fffdd288SMatthias Ringwald return 0; 736fffdd288SMatthias Ringwald } 737fffdd288SMatthias Ringwald /* LISTING_END */ 7382b6b8c15SMilanka Ringwald /* EXAMPLE_END */ 739