1cd87ea12SMatthias Ringwald /* 2cd87ea12SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3cd87ea12SMatthias Ringwald * 4cd87ea12SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5cd87ea12SMatthias Ringwald * modification, are permitted provided that the following conditions 6cd87ea12SMatthias Ringwald * are met: 7cd87ea12SMatthias Ringwald * 8cd87ea12SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9cd87ea12SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10cd87ea12SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11cd87ea12SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12cd87ea12SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13cd87ea12SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14cd87ea12SMatthias Ringwald * contributors may be used to endorse or promote products derived 15cd87ea12SMatthias Ringwald * from this software without specific prior written permission. 16cd87ea12SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17cd87ea12SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18cd87ea12SMatthias Ringwald * monetary gain. 19cd87ea12SMatthias Ringwald * 20cd87ea12SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21cd87ea12SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22cd87ea12SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23cd87ea12SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24cd87ea12SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25cd87ea12SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26cd87ea12SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27cd87ea12SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28cd87ea12SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29cd87ea12SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30cd87ea12SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31cd87ea12SMatthias Ringwald * SUCH DAMAGE. 32cd87ea12SMatthias Ringwald * 33cd87ea12SMatthias Ringwald * Please inquire about commercial licensing options at 34cd87ea12SMatthias Ringwald * [email protected] 35cd87ea12SMatthias Ringwald * 36cd87ea12SMatthias Ringwald */ 37cd87ea12SMatthias Ringwald 38fffdd288SMatthias Ringwald /* 39fffdd288SMatthias Ringwald * hsp_hs_demo.c 40fffdd288SMatthias Ringwald */ 41cd87ea12SMatthias Ringwald 42fffdd288SMatthias Ringwald // ***************************************************************************** 43fffdd288SMatthias Ringwald /* EXAMPLE_START(hsp_hs_demo): HSP Headset Demo 44fffdd288SMatthias Ringwald * 45fffdd288SMatthias Ringwald * @text This example implements a HSP Headset device that sends and receives 46fffdd288SMatthias Ringwald * audio signal over HCI SCO. It demonstrates how to receive 47fffdd288SMatthias Ringwald * an output from a remote audio gateway (AG), and, 48d0755cd6SMatthias Ringwald * if HAVE_POSIX_STDIN is defined, how to control the AG. 49fffdd288SMatthias Ringwald */ 50cd87ea12SMatthias Ringwald // ***************************************************************************** 51cd87ea12SMatthias Ringwald 52cd87ea12SMatthias Ringwald #include "btstack_config.h" 53cd87ea12SMatthias Ringwald 54cd87ea12SMatthias Ringwald #include <stdint.h> 55cd87ea12SMatthias Ringwald #include <stdio.h> 56cd87ea12SMatthias Ringwald #include <stdlib.h> 57cd87ea12SMatthias Ringwald #include <string.h> 58cd87ea12SMatthias Ringwald #include <math.h> 59fffdd288SMatthias Ringwald #include <unistd.h> 60cd87ea12SMatthias Ringwald 61cd87ea12SMatthias Ringwald #include "btstack.h" 62d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 634af4141bSMatthias Ringwald #include "stdin_support.h" 644af4141bSMatthias Ringwald #endif 65cd87ea12SMatthias Ringwald 66fffdd288SMatthias Ringwald #define SCO_REPORT_PERIOD 255 67fffdd288SMatthias Ringwald 68cd87ea12SMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 69cd87ea12SMatthias Ringwald 70cd87ea12SMatthias Ringwald static uint8_t hsp_service_buffer[150]; 71cd87ea12SMatthias Ringwald static const uint8_t rfcomm_channel_nr = 1; 72cd87ea12SMatthias Ringwald static const char hsp_hs_service_name[] = "Headset Test"; 73cd87ea12SMatthias Ringwald static hci_con_handle_t sco_handle = 0; 74cd87ea12SMatthias Ringwald 75cd87ea12SMatthias Ringwald static char hs_cmd_buffer[100]; 76fffdd288SMatthias Ringwald static bd_addr_t device_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; 77cd87ea12SMatthias Ringwald 78cd87ea12SMatthias Ringwald static int phase = 0; 79cd87ea12SMatthias Ringwald 80cd87ea12SMatthias Ringwald // input signal: pre-computed sine wave, 160 Hz 81cd87ea12SMatthias Ringwald static const uint8_t sine[] = { 82cd87ea12SMatthias Ringwald 0, 15, 31, 46, 61, 74, 86, 97, 107, 114, 83cd87ea12SMatthias Ringwald 120, 124, 126, 126, 124, 120, 114, 107, 97, 86, 84cd87ea12SMatthias Ringwald 74, 61, 46, 31, 15, 0, 241, 225, 210, 195, 85cd87ea12SMatthias Ringwald 182, 170, 159, 149, 142, 136, 132, 130, 130, 132, 86cd87ea12SMatthias Ringwald 136, 142, 149, 159, 170, 182, 195, 210, 225, 241, 87cd87ea12SMatthias Ringwald }; 88cd87ea12SMatthias Ringwald 89fffdd288SMatthias Ringwald /* @section Audio Transfer Setup 90fffdd288SMatthias Ringwald * 91fffdd288SMatthias Ringwald * @text A pre-computed sine wave (160Hz) is used as the input audio signal. 160 Hz. 92fffdd288SMatthias Ringwald * To send and receive an audio signal, HAVE_SCO_OVER_HCI has to be defined. 93fffdd288SMatthias Ringwald * 94fffdd288SMatthias Ringwald * Tested working setups: 95fffdd288SMatthias Ringwald * - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 921600 baud 96fffdd288SMatthias Ringwald * - Ubuntu 14 64-bit, CSR USB dongle 97fffdd288SMatthias Ringwald * - OS X 10.11, CSR USB dongle 98fffdd288SMatthias Ringwald * 99fffdd288SMatthias Ringwald * Broken setups: 100fffdd288SMatthias Ringwald * - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 921600 baud 101fffdd288SMatthias Ringwald * - select(..) blocks > 400 ms -> num completed is received to late -> gaps between audio 102fffdd288SMatthias Ringwald * - looks like bug in select->FTDI driver as it works correct on Linux 103fffdd288SMatthias Ringwald * 104fffdd288SMatthias Ringwald * SCO not routed over HCI yet: 105fffdd288SMatthias Ringwald * - CSR UART dongle 106fffdd288SMatthias Ringwald * - Broadcom USB dongle 107fffdd288SMatthias Ringwald * - Broadcom UART chipset 108fffdd288SMatthias Ringwald * - .. 109fffdd288SMatthias Ringwald * 110fffdd288SMatthias Ringwald */ 111fffdd288SMatthias Ringwald 112fffdd288SMatthias Ringwald 113fffdd288SMatthias Ringwald static void show_usage(void){ 114fffdd288SMatthias Ringwald bd_addr_t iut_address; 115fffdd288SMatthias Ringwald gap_local_bd_addr(iut_address); 116fffdd288SMatthias Ringwald 117fffdd288SMatthias Ringwald printf("\n--- Bluetooth HSP Headset Test Console %s ---\n", bd_addr_to_str(iut_address)); 118fffdd288SMatthias Ringwald printf("---\n"); 119fffdd288SMatthias Ringwald printf("c - Connect to %s\n", bd_addr_to_str(device_addr)); 120fffdd288SMatthias Ringwald printf("C - Disconnect\n"); 121fffdd288SMatthias Ringwald printf("a - establish audio connection\n"); 122fffdd288SMatthias Ringwald printf("A - release audio connection\n"); 123fffdd288SMatthias Ringwald printf("b - press user button\n"); 124fffdd288SMatthias Ringwald printf("z - set microphone gain 0\n"); 125fffdd288SMatthias Ringwald printf("m - set microphone gain 8\n"); 126fffdd288SMatthias Ringwald printf("M - set microphone gain 15\n"); 127fffdd288SMatthias Ringwald printf("o - set speaker gain 0\n"); 128fffdd288SMatthias Ringwald printf("s - set speaker gain 8\n"); 129fffdd288SMatthias Ringwald printf("S - set speaker gain 15\n"); 130fffdd288SMatthias Ringwald printf("---\n"); 131fffdd288SMatthias Ringwald printf("Ctrl-c - exit\n"); 132fffdd288SMatthias Ringwald printf("---\n"); 133cd87ea12SMatthias Ringwald } 134fffdd288SMatthias Ringwald 135d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 1364af4141bSMatthias Ringwald static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 137fffdd288SMatthias Ringwald char buffer; 138fffdd288SMatthias Ringwald read(ds->fd, &buffer, 1); 139fffdd288SMatthias Ringwald 140fffdd288SMatthias Ringwald switch (buffer){ 141fffdd288SMatthias Ringwald case 'c': 142fffdd288SMatthias Ringwald printf("Connect to %s\n", bd_addr_to_str(device_addr)); 143fffdd288SMatthias Ringwald hsp_hs_connect(device_addr); 144fffdd288SMatthias Ringwald break; 145fffdd288SMatthias Ringwald case 'C': 146fffdd288SMatthias Ringwald printf("Disconnect.\n"); 147fffdd288SMatthias Ringwald hsp_hs_disconnect(); 148fffdd288SMatthias Ringwald break; 149fffdd288SMatthias Ringwald case 'a': 150fffdd288SMatthias Ringwald printf("Establish audio connection\n"); 151fffdd288SMatthias Ringwald hsp_hs_establish_audio_connection(); 152fffdd288SMatthias Ringwald break; 153fffdd288SMatthias Ringwald case 'A': 154fffdd288SMatthias Ringwald printf("Release audio connection\n"); 155fffdd288SMatthias Ringwald hsp_hs_release_audio_connection(); 156fffdd288SMatthias Ringwald break; 157fffdd288SMatthias Ringwald 158fffdd288SMatthias Ringwald case 'z': 159fffdd288SMatthias Ringwald printf("Setting microphone gain 0\n"); 160fffdd288SMatthias Ringwald hsp_hs_set_microphone_gain(0); 161fffdd288SMatthias Ringwald break; 162fffdd288SMatthias Ringwald case 'm': 163fffdd288SMatthias Ringwald printf("Setting microphone gain 8\n"); 164fffdd288SMatthias Ringwald hsp_hs_set_microphone_gain(8); 165fffdd288SMatthias Ringwald break; 166fffdd288SMatthias Ringwald case 'M': 167fffdd288SMatthias Ringwald printf("Setting microphone gain 15\n"); 168fffdd288SMatthias Ringwald hsp_hs_set_microphone_gain(15); 169fffdd288SMatthias Ringwald break; 170fffdd288SMatthias Ringwald case 'o': 171fffdd288SMatthias Ringwald printf("Setting speaker gain 0\n"); 172fffdd288SMatthias Ringwald hsp_hs_set_speaker_gain(0); 173fffdd288SMatthias Ringwald break; 174fffdd288SMatthias Ringwald case 's': 175fffdd288SMatthias Ringwald printf("Setting speaker gain 8\n"); 176fffdd288SMatthias Ringwald hsp_hs_set_speaker_gain(8); 177fffdd288SMatthias Ringwald break; 178fffdd288SMatthias Ringwald case 'S': 179fffdd288SMatthias Ringwald printf("Setting speaker gain 15\n"); 180fffdd288SMatthias Ringwald hsp_hs_set_speaker_gain(15); 181fffdd288SMatthias Ringwald break; 182fffdd288SMatthias Ringwald case 'b': 183fffdd288SMatthias Ringwald printf("Press user button\n"); 184fffdd288SMatthias Ringwald hsp_hs_send_button_press(); 185fffdd288SMatthias Ringwald break; 186fffdd288SMatthias Ringwald default: 187fffdd288SMatthias Ringwald show_usage(); 188fffdd288SMatthias Ringwald break; 189fffdd288SMatthias Ringwald } 190cd87ea12SMatthias Ringwald } 191cd87ea12SMatthias Ringwald #endif 192cd87ea12SMatthias Ringwald 193cd87ea12SMatthias Ringwald static void try_send_sco(void){ 194cd87ea12SMatthias Ringwald if (!sco_handle) return; 195cd87ea12SMatthias Ringwald 196cd87ea12SMatthias Ringwald while (hci_can_send_sco_packet_now()) { 197cd87ea12SMatthias Ringwald 198cd87ea12SMatthias Ringwald const int sco_packet_length = hci_get_sco_packet_length(); 199cd87ea12SMatthias Ringwald const int sco_payload_length = sco_packet_length - 3; 200cd87ea12SMatthias Ringwald const int frames_per_packet = sco_payload_length; // for 8-bit data. for 16-bit data it's /2 201cd87ea12SMatthias Ringwald 202cd87ea12SMatthias Ringwald hci_reserve_packet_buffer(); 203cd87ea12SMatthias Ringwald uint8_t * sco_packet = hci_get_outgoing_packet_buffer(); 204cd87ea12SMatthias Ringwald // set handle + flags 205cd87ea12SMatthias Ringwald little_endian_store_16(sco_packet, 0, sco_handle); 206cd87ea12SMatthias Ringwald // set len 207cd87ea12SMatthias Ringwald sco_packet[2] = sco_payload_length; 208cd87ea12SMatthias Ringwald int i; 209cd87ea12SMatthias Ringwald for (i=0;i<frames_per_packet;i++){ 210cd87ea12SMatthias Ringwald sco_packet[3+i] = sine[phase]; 211cd87ea12SMatthias Ringwald phase++; 212cd87ea12SMatthias Ringwald if (phase >= sizeof(sine)) phase = 0; 213cd87ea12SMatthias Ringwald } 214cd87ea12SMatthias Ringwald hci_send_sco_packet_buffer(sco_packet_length); 215cd87ea12SMatthias Ringwald static int count = 0; 216cd87ea12SMatthias Ringwald count++; 217cd87ea12SMatthias Ringwald if ((count & 15) == 0) printf("Sent %u\n", count); 218cd87ea12SMatthias Ringwald } 219cd87ea12SMatthias Ringwald } 220cd87ea12SMatthias Ringwald 221cd87ea12SMatthias Ringwald static void sco_packet_handler(uint8_t packet_type, uint8_t * packet, uint16_t size){ 222cd87ea12SMatthias Ringwald static int count = 0; 223fffdd288SMatthias Ringwald // hexdumpf(packet, size); 224cd87ea12SMatthias Ringwald count++; 225fffdd288SMatthias Ringwald if ((count & SCO_REPORT_PERIOD)) return; 226cd87ea12SMatthias Ringwald printf("SCO packets %u\n", count); 227cd87ea12SMatthias Ringwald } 228cd87ea12SMatthias Ringwald 229cd87ea12SMatthias Ringwald static void packet_handler(uint8_t * event, uint16_t event_size){ 230cd87ea12SMatthias Ringwald switch (event[0]) { 231cd87ea12SMatthias Ringwald case BTSTACK_EVENT_STATE: 232cd87ea12SMatthias Ringwald if (btstack_event_state_get_state(event) != HCI_STATE_WORKING) break; 233fffdd288SMatthias Ringwald show_usage(); 234cd87ea12SMatthias Ringwald break; 235cd87ea12SMatthias Ringwald case HCI_EVENT_SCO_CAN_SEND_NOW: 236cd87ea12SMatthias Ringwald try_send_sco(); 237cd87ea12SMatthias Ringwald break; 238cd87ea12SMatthias Ringwald case HCI_EVENT_HSP_META: 239cd87ea12SMatthias Ringwald switch (event[2]) { 240fffdd288SMatthias Ringwald case HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE: 241fffdd288SMatthias Ringwald if (hsp_subevent_audio_connection_complete_get_handle(event) == 0){ 242fffdd288SMatthias Ringwald printf("RFCOMM connection established.\n"); 243fffdd288SMatthias Ringwald } else { 244fffdd288SMatthias Ringwald printf("RFCOMM connection establishement failed.\n"); 245fffdd288SMatthias Ringwald } 246fffdd288SMatthias Ringwald break; 247fffdd288SMatthias Ringwald case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE: 248fffdd288SMatthias Ringwald if (hsp_subevent_audio_connection_complete_get_handle(event) == 0){ 249fffdd288SMatthias Ringwald printf("RFCOMM disconnected.\n"); 250fffdd288SMatthias Ringwald } else { 251fffdd288SMatthias Ringwald printf("RFCOMM disconnection failed.\n"); 252fffdd288SMatthias Ringwald } 253fffdd288SMatthias Ringwald break; 254cd87ea12SMatthias Ringwald case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE: 255fffdd288SMatthias Ringwald if (hsp_subevent_audio_connection_complete_get_handle(event) == 0){ 256fffdd288SMatthias Ringwald sco_handle = little_endian_read_16(event, 4); 257cd87ea12SMatthias Ringwald printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle); 258cd87ea12SMatthias Ringwald try_send_sco(); 259cd87ea12SMatthias Ringwald } else { 260cd87ea12SMatthias Ringwald printf("Audio connection establishment failed with status %u\n", hsp_subevent_audio_connection_complete_get_status(event)); 261cd87ea12SMatthias Ringwald sco_handle = 0; 262cd87ea12SMatthias Ringwald } 263cd87ea12SMatthias Ringwald break; 264cd87ea12SMatthias Ringwald case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE: 265fffdd288SMatthias Ringwald if (event[3] == 0){ 266cd87ea12SMatthias Ringwald printf("Audio connection released.\n\n"); 267cd87ea12SMatthias Ringwald sco_handle = 0; 268fffdd288SMatthias Ringwald } else { 269fffdd288SMatthias Ringwald printf("Audio connection releasing failed with status %u\n", event[3]); 270fffdd288SMatthias Ringwald } 271cd87ea12SMatthias Ringwald break; 272cd87ea12SMatthias Ringwald case HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED: 273cd87ea12SMatthias Ringwald printf("Received microphone gain change %d\n", hsp_subevent_microphone_gain_changed_get_gain(event)); 274cd87ea12SMatthias Ringwald break; 275cd87ea12SMatthias Ringwald case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED: 276cd87ea12SMatthias Ringwald printf("Received speaker gain change %d\n", hsp_subevent_speaker_gain_changed_get_gain(event)); 277cd87ea12SMatthias Ringwald break; 278cd87ea12SMatthias Ringwald case HSP_SUBEVENT_RING: 279cd87ea12SMatthias Ringwald printf("HS: RING RING!\n"); 280cd87ea12SMatthias Ringwald break; 281cd87ea12SMatthias Ringwald case HSP_SUBEVENT_AG_INDICATION: { 282cd87ea12SMatthias Ringwald memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer)); 283cd87ea12SMatthias Ringwald int size = hsp_subevent_ag_indication_get_value_length(event); 284cd87ea12SMatthias Ringwald if (size >= sizeof(hs_cmd_buffer)-1){ 285cd87ea12SMatthias Ringwald size = sizeof(hs_cmd_buffer)-1; 286cd87ea12SMatthias Ringwald } 287cd87ea12SMatthias Ringwald memcpy(hs_cmd_buffer, hsp_subevent_ag_indication_get_value(event), size); 288cd87ea12SMatthias Ringwald printf("Received custom indication: \"%s\". \nExit code or call hsp_hs_send_result.\n", hs_cmd_buffer); 289cd87ea12SMatthias Ringwald 290cd87ea12SMatthias Ringwald } 291cd87ea12SMatthias Ringwald break; 292cd87ea12SMatthias Ringwald default: 293cd87ea12SMatthias Ringwald printf("event not handled %u\n", event[2]); 294cd87ea12SMatthias Ringwald break; 295cd87ea12SMatthias Ringwald } 296cd87ea12SMatthias Ringwald break; 297cd87ea12SMatthias Ringwald default: 298cd87ea12SMatthias Ringwald break; 299cd87ea12SMatthias Ringwald } 300cd87ea12SMatthias Ringwald } 301cd87ea12SMatthias Ringwald 302cd87ea12SMatthias Ringwald static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){ 303cd87ea12SMatthias Ringwald packet_handler(packet, size); 304cd87ea12SMatthias Ringwald } 305cd87ea12SMatthias Ringwald 306fffdd288SMatthias Ringwald /* @section Main Application Setup 307fffdd288SMatthias Ringwald * 308fffdd288SMatthias Ringwald * @text Listing MainConfiguration shows main application code. 309fffdd288SMatthias Ringwald * To run a HSP Headset service you need to initialize the SDP, and to create and register HSP HS record with it. 310fffdd288SMatthias Ringwald * In this example, the SCO over HCI is used to receive and send an audio signal. 311fffdd288SMatthias Ringwald * 312fffdd288SMatthias Ringwald * Two packet handlers are registered: 313fffdd288SMatthias Ringwald * - The HCI SCO packet handler receives audio data. 314fffdd288SMatthias Ringwald * - The HSP HS packet handler is used to trigger sending of audio data and commands to the AG. It also receives the AG's answers. 315fffdd288SMatthias Ringwald * 316fffdd288SMatthias Ringwald * The stdin_process callback allows for sending commands to the AG. 317fffdd288SMatthias Ringwald * At the end the Bluetooth stack is started. 318fffdd288SMatthias Ringwald */ 319fffdd288SMatthias Ringwald 320fffdd288SMatthias Ringwald /* LISTING_START(MainConfiguration): Setup HSP Headset */ 321cd87ea12SMatthias Ringwald int btstack_main(int argc, const char * argv[]); 322cd87ea12SMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 323cd87ea12SMatthias Ringwald 324cd87ea12SMatthias Ringwald // register for HCI events 325cd87ea12SMatthias Ringwald hci_event_callback_registration.callback = &handle_hci_event; 326cd87ea12SMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 327cd87ea12SMatthias Ringwald hci_register_sco_packet_handler(&sco_packet_handler); 328cd87ea12SMatthias Ringwald 329fffdd288SMatthias Ringwald l2cap_init(); 330cd87ea12SMatthias Ringwald 331cd87ea12SMatthias Ringwald sdp_init(); 332cd87ea12SMatthias Ringwald memset(hsp_service_buffer, 0, sizeof(hsp_service_buffer)); 333cd87ea12SMatthias Ringwald hsp_hs_create_sdp_record(hsp_service_buffer, 0x10001, rfcomm_channel_nr, hsp_hs_service_name, 0); 334cd87ea12SMatthias Ringwald sdp_register_service(hsp_service_buffer); 335cd87ea12SMatthias Ringwald 336fffdd288SMatthias Ringwald rfcomm_init(); 337fffdd288SMatthias Ringwald 338fffdd288SMatthias Ringwald hsp_hs_init(rfcomm_channel_nr); 339fffdd288SMatthias Ringwald hsp_hs_register_packet_handler(packet_handler); 340fffdd288SMatthias Ringwald 341d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN 342fffdd288SMatthias Ringwald btstack_stdin_setup(stdin_process); 343fffdd288SMatthias Ringwald #endif 344fffdd288SMatthias Ringwald 345fffdd288SMatthias Ringwald gap_set_local_name("BTstack HSP HS"); 346fffdd288SMatthias Ringwald gap_discoverable_control(1); 347fffdd288SMatthias Ringwald gap_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO); 34860b9e82fSMatthias Ringwald gap_set_class_of_device(0x240404); 349fffdd288SMatthias Ringwald 350cd87ea12SMatthias Ringwald // turn on! 351cd87ea12SMatthias Ringwald hci_power_control(HCI_POWER_ON); 352cd87ea12SMatthias Ringwald return 0; 353cd87ea12SMatthias Ringwald } 354fffdd288SMatthias Ringwald /* LISTING_END */ 355*2b6b8c15SMilanka Ringwald /* EXAMPLE_END */ 356