xref: /btstack/example/hsp_ag_demo.c (revision 60b9e82fcb0aff32ef16935452828adc179b2cf3)
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  * hsp_ag_demo.c
40fffdd288SMatthias Ringwald  */
41fffdd288SMatthias Ringwald 
42fffdd288SMatthias Ringwald // *****************************************************************************
43fffdd288SMatthias Ringwald /* EXAMPLE_START(hsp_ag_demo): HSP Audio Gateway Demo
44fffdd288SMatthias Ringwald  *
45fffdd288SMatthias Ringwald  * @text This example implements a HSP Audio Gateway device that sends and receives
46fffdd288SMatthias Ringwald  * audio signal over HCI SCO. It demonstrates how to receive
47fffdd288SMatthias Ringwald  * an output from a remote headset (HS), and,
48fffdd288SMatthias Ringwald  * if HAVE_STDIO is defined, how to control the HS.
49fffdd288SMatthias Ringwald  */
50fffdd288SMatthias Ringwald // *****************************************************************************
51fffdd288SMatthias Ringwald 
52fffdd288SMatthias Ringwald 
53fffdd288SMatthias Ringwald 
54fffdd288SMatthias Ringwald #include <stdint.h>
55fffdd288SMatthias Ringwald #include <stdio.h>
56fffdd288SMatthias Ringwald #include <stdlib.h>
57fffdd288SMatthias Ringwald #include <string.h>
58fffdd288SMatthias Ringwald #include <math.h>
59fffdd288SMatthias Ringwald #include <unistd.h>
60fffdd288SMatthias Ringwald 
61fffdd288SMatthias Ringwald #include "btstack.h"
62fffdd288SMatthias Ringwald 
63fffdd288SMatthias Ringwald #define SCO_REPORT_PERIOD 255
64fffdd288SMatthias Ringwald 
65fffdd288SMatthias Ringwald static uint8_t       hsp_service_buffer[150];
66fffdd288SMatthias Ringwald static const uint8_t rfcomm_channel_nr = 1;
67fffdd288SMatthias Ringwald static const char    hsp_ag_service_name[] = "Audio Gateway Test";
68fffdd288SMatthias Ringwald static uint16_t      sco_handle = 0;
69fffdd288SMatthias Ringwald 
70fffdd288SMatthias Ringwald static char hs_cmd_buffer[100];
71fffdd288SMatthias Ringwald 
72fffdd288SMatthias Ringwald static bd_addr_t device_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF};
73fffdd288SMatthias Ringwald 
74fffdd288SMatthias Ringwald static int phase = 0;
75fffdd288SMatthias Ringwald 
76fffdd288SMatthias Ringwald // input signal: pre-computed sine wave, 160 Hz
77fffdd288SMatthias Ringwald static const uint8_t sine[] = {
78fffdd288SMatthias Ringwald       0,  15,  31,  46,  61,  74,  86,  97, 107, 114,
79fffdd288SMatthias Ringwald     120, 124, 126, 126, 124, 120, 114, 107,  97,  86,
80fffdd288SMatthias Ringwald      74,  61,  46,  31,  15,   0, 241, 225, 210, 195,
81fffdd288SMatthias Ringwald     182, 170, 159, 149, 142, 136, 132, 130, 130, 132,
82fffdd288SMatthias Ringwald     136, 142, 149, 159, 170, 182, 195, 210, 225, 241,
83fffdd288SMatthias Ringwald };
84fffdd288SMatthias Ringwald 
85fffdd288SMatthias Ringwald /* @section Audio Transfer Setup
86fffdd288SMatthias Ringwald  *
87fffdd288SMatthias Ringwald  * @text A pre-computed sine wave (160Hz) is used as the input audio signal. 160 Hz.
88fffdd288SMatthias Ringwald  * To send and receive an audio signal, HAVE_SCO_OVER_HCI has to be defined.
89fffdd288SMatthias Ringwald  *
90fffdd288SMatthias Ringwald  * Tested working setups:
91fffdd288SMatthias Ringwald  * - Ubuntu 14 64-bit, CC2564B connected via FTDI USB-2-UART adapter, 921600 baud
92fffdd288SMatthias Ringwald  * - Ubuntu 14 64-bit, CSR USB dongle
93fffdd288SMatthias Ringwald  * - OS X 10.11, CSR USB dongle
94fffdd288SMatthias Ringwald  *
95fffdd288SMatthias Ringwald  * Broken setups:
96fffdd288SMatthias Ringwald  * - OS X 10.11, CC2564B connected via FDTI USB-2-UART adapter, 921600 baud
97fffdd288SMatthias Ringwald  * - select(..) blocks > 400 ms -> num completed is received to late -> gaps between audio
98fffdd288SMatthias Ringwald  * - looks like bug in select->FTDI driver as it works correct on Linux
99fffdd288SMatthias Ringwald  *
100fffdd288SMatthias Ringwald  * SCO not routed over HCI yet:
101fffdd288SMatthias Ringwald  * - CSR UART dongle
102fffdd288SMatthias Ringwald  * - Broadcom USB dongle
103fffdd288SMatthias Ringwald  * - Broadcom UART chipset
104fffdd288SMatthias Ringwald  * - ..
105fffdd288SMatthias Ringwald  *
106fffdd288SMatthias Ringwald  */
107fffdd288SMatthias Ringwald 
108fffdd288SMatthias Ringwald 
109fffdd288SMatthias Ringwald static void show_usage(void){
110fffdd288SMatthias Ringwald     bd_addr_t iut_address;
111fffdd288SMatthias Ringwald     gap_local_bd_addr(iut_address);
112fffdd288SMatthias Ringwald 
113fffdd288SMatthias Ringwald     printf("\n--- Bluetooth HSP Audio Gateway Test Console %s ---\n", bd_addr_to_str(iut_address));
114fffdd288SMatthias Ringwald 
115fffdd288SMatthias Ringwald     printf("---\n");
116fffdd288SMatthias Ringwald     printf("c - Connect to %s\n", bd_addr_to_str(device_addr));
117fffdd288SMatthias Ringwald     printf("C - Disconnect\n");
118fffdd288SMatthias Ringwald     printf("a - establish audio connection\n");
119fffdd288SMatthias Ringwald     printf("A - release audio connection\n");
120fffdd288SMatthias Ringwald     printf("m - set microphone gain 8\n");
121fffdd288SMatthias Ringwald     printf("M - set microphone gain 15\n");
122fffdd288SMatthias Ringwald     printf("o - set speaker gain 0\n");
123fffdd288SMatthias Ringwald     printf("s - set speaker gain 8\n");
124fffdd288SMatthias Ringwald     printf("S - set speaker gain 15\n");
125fffdd288SMatthias Ringwald     printf("r - start ringing\n");
126fffdd288SMatthias Ringwald     printf("t - stop ringing\n");
127fffdd288SMatthias Ringwald     printf("---\n");
128fffdd288SMatthias Ringwald     printf("Ctrl-c - exit\n");
129fffdd288SMatthias Ringwald     printf("---\n");
130fffdd288SMatthias Ringwald }
131fffdd288SMatthias Ringwald 
132fffdd288SMatthias Ringwald #ifdef HAVE_STDIO
133fffdd288SMatthias Ringwald static int stdin_process(struct data_source *ds){
134fffdd288SMatthias Ringwald     char buffer;
135fffdd288SMatthias Ringwald     read(ds->fd, &buffer, 1);
136fffdd288SMatthias Ringwald 
137fffdd288SMatthias Ringwald     switch (buffer){
138fffdd288SMatthias Ringwald         case 'c':
139fffdd288SMatthias Ringwald             printf("Connect to %s\n", bd_addr_to_str(device_addr));
140fffdd288SMatthias Ringwald             hsp_ag_connect(device_addr);
141fffdd288SMatthias Ringwald             break;
142fffdd288SMatthias Ringwald         case 'C':
143fffdd288SMatthias Ringwald             printf("Disconnect.\n");
144fffdd288SMatthias Ringwald             hsp_ag_disconnect();
145fffdd288SMatthias Ringwald             break;
146fffdd288SMatthias Ringwald         case 'a':
147fffdd288SMatthias Ringwald             printf("Establish audio connection\n");
148fffdd288SMatthias Ringwald             hsp_ag_establish_audio_connection();
149fffdd288SMatthias Ringwald             break;
150fffdd288SMatthias Ringwald         case 'A':
151fffdd288SMatthias Ringwald             printf("Release audio connection\n");
152fffdd288SMatthias Ringwald             hsp_ag_release_audio_connection();
153fffdd288SMatthias Ringwald             break;
154fffdd288SMatthias Ringwald         case 'm':
155fffdd288SMatthias Ringwald             printf("Setting microphone gain 8\n");
156fffdd288SMatthias Ringwald             hsp_ag_set_microphone_gain(8);
157fffdd288SMatthias Ringwald             break;
158fffdd288SMatthias Ringwald         case 'M':
159fffdd288SMatthias Ringwald             printf("Setting microphone gain 15\n");
160fffdd288SMatthias Ringwald             hsp_ag_set_microphone_gain(15);
161fffdd288SMatthias Ringwald             break;
162fffdd288SMatthias Ringwald         case 'o':
163fffdd288SMatthias Ringwald             printf("Setting speaker gain 0\n");
164fffdd288SMatthias Ringwald             hsp_ag_set_speaker_gain(0);
165fffdd288SMatthias Ringwald             break;
166fffdd288SMatthias Ringwald         case 's':
167fffdd288SMatthias Ringwald             printf("Setting speaker gain 8\n");
168fffdd288SMatthias Ringwald             hsp_ag_set_speaker_gain(8);
169fffdd288SMatthias Ringwald             break;
170fffdd288SMatthias Ringwald         case 'S':
171fffdd288SMatthias Ringwald             printf("Setting speaker gain 15\n");
172fffdd288SMatthias Ringwald             hsp_ag_set_speaker_gain(15);
173fffdd288SMatthias Ringwald             break;
174fffdd288SMatthias Ringwald         case 'r':
175fffdd288SMatthias Ringwald             printf("Start ringing\n");
176fffdd288SMatthias Ringwald             hsp_ag_start_ringing();
177fffdd288SMatthias Ringwald             break;
178fffdd288SMatthias Ringwald         case 't':
179fffdd288SMatthias Ringwald             printf("Stop ringing\n");
180fffdd288SMatthias Ringwald             hsp_ag_stop_ringing();
181fffdd288SMatthias Ringwald             break;
182fffdd288SMatthias Ringwald         default:
183fffdd288SMatthias Ringwald             show_usage();
184fffdd288SMatthias Ringwald             break;
185fffdd288SMatthias Ringwald 
186fffdd288SMatthias Ringwald     }
187fffdd288SMatthias Ringwald     return 0;
188fffdd288SMatthias Ringwald }
189fffdd288SMatthias Ringwald #endif
190fffdd288SMatthias Ringwald 
191fffdd288SMatthias Ringwald static void try_send_sco(void){
192fffdd288SMatthias Ringwald     return;
193fffdd288SMatthias Ringwald     if (!sco_handle) return;
194fffdd288SMatthias Ringwald     if (!hci_can_send_sco_packet_now()) {
195fffdd288SMatthias Ringwald         // printf("try_send_sco, cannot send now\n");
196fffdd288SMatthias Ringwald         return;
197fffdd288SMatthias Ringwald     }
198fffdd288SMatthias Ringwald 
199fffdd288SMatthias Ringwald     const int sco_packet_length = hci_get_sco_packet_length();
200fffdd288SMatthias Ringwald     const int sco_payload_length = sco_packet_length - 3;
201fffdd288SMatthias Ringwald     const int frames_per_packet = sco_payload_length;    // for 8-bit data. for 16-bit data it's /2
202fffdd288SMatthias Ringwald 
203fffdd288SMatthias Ringwald     hci_reserve_packet_buffer();
204fffdd288SMatthias Ringwald     uint8_t * sco_packet = hci_get_outgoing_packet_buffer();
205fffdd288SMatthias Ringwald     // set handle + flags
206fffdd288SMatthias Ringwald     little_endian_store_16(sco_packet, 0, sco_handle);
207fffdd288SMatthias Ringwald     // set len
208fffdd288SMatthias Ringwald     sco_packet[2] = sco_payload_length;
209fffdd288SMatthias Ringwald     int i;
210fffdd288SMatthias Ringwald     for (i=0;i<frames_per_packet;i++){
211fffdd288SMatthias Ringwald         sco_packet[3+i] = sine[phase];
212fffdd288SMatthias Ringwald         phase++;
213fffdd288SMatthias Ringwald         if (phase >= sizeof(sine)) phase = 0;
214fffdd288SMatthias Ringwald     }
215fffdd288SMatthias Ringwald     hci_send_sco_packet_buffer(sco_packet_length);
216fffdd288SMatthias Ringwald     static int count = 0;
217fffdd288SMatthias Ringwald     count++;
218fffdd288SMatthias Ringwald     if ((count & SCO_REPORT_PERIOD) == 0) printf("Sent %u\n", count);
219fffdd288SMatthias Ringwald }
220fffdd288SMatthias Ringwald 
221fffdd288SMatthias Ringwald static void sco_packet_handler(uint8_t packet_type, uint8_t * packet, uint16_t size){
222fffdd288SMatthias Ringwald     return;
223fffdd288SMatthias Ringwald     static int count = 0;
224fffdd288SMatthias Ringwald     count++;
225fffdd288SMatthias Ringwald     if ((count & SCO_REPORT_PERIOD)) return;
226fffdd288SMatthias Ringwald     printf("SCO packets %u\n", count);
227fffdd288SMatthias Ringwald }
228fffdd288SMatthias Ringwald 
229fffdd288SMatthias Ringwald static void packet_handler(uint8_t * event, uint16_t event_size){
230fffdd288SMatthias Ringwald     switch (event[0]) {
231fffdd288SMatthias Ringwald         case BTSTACK_EVENT_STATE:
232fffdd288SMatthias Ringwald             if (event[2] != HCI_STATE_WORKING) break;
233fffdd288SMatthias Ringwald             printf("HCI_STATE_WORKING\n");
234fffdd288SMatthias Ringwald             show_usage();
235fffdd288SMatthias Ringwald             break;
236fffdd288SMatthias Ringwald         case HCI_EVENT_SCO_CAN_SEND_NOW:
237fffdd288SMatthias Ringwald             try_send_sco();
238fffdd288SMatthias Ringwald             break;
239fffdd288SMatthias Ringwald         case HCI_EVENT_HSP_META:
240fffdd288SMatthias Ringwald             switch (event[2]) {
241fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE:
242fffdd288SMatthias Ringwald                     if (event[3] == 0){
243fffdd288SMatthias Ringwald                         printf("RFCOMM connection established.\n");
244fffdd288SMatthias Ringwald                     } else {
245fffdd288SMatthias Ringwald                         printf("RFCOMM connection establishement failed.\n");
246fffdd288SMatthias Ringwald                     }
247fffdd288SMatthias Ringwald                     break;
248fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE:
249fffdd288SMatthias Ringwald                     if (event[3] == 0){
250fffdd288SMatthias Ringwald                         printf("RFCOMM disconnected.\n");
251fffdd288SMatthias Ringwald                     } else {
252fffdd288SMatthias Ringwald                         printf("RFCOMM disconnection failed.\n");
253fffdd288SMatthias Ringwald                     }
254fffdd288SMatthias Ringwald                     break;
255fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
256fffdd288SMatthias Ringwald                     if (event[3] == 0){
257fffdd288SMatthias Ringwald                         sco_handle = little_endian_read_16(event, 4);
258fffdd288SMatthias Ringwald                         printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
259fffdd288SMatthias Ringwald                         try_send_sco();
260fffdd288SMatthias Ringwald                     } else {
261fffdd288SMatthias Ringwald                         printf("Audio connection establishment failed with status %u\n", event[3]);
262fffdd288SMatthias Ringwald                         sco_handle = 0;
263fffdd288SMatthias Ringwald                     }
264fffdd288SMatthias Ringwald                     break;
265fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
266fffdd288SMatthias Ringwald                     if (event[3] == 0){
267fffdd288SMatthias Ringwald                         printf("Audio connection released.\n\n");
268fffdd288SMatthias Ringwald                         sco_handle = 0;
269fffdd288SMatthias Ringwald                     } else {
270fffdd288SMatthias Ringwald                         printf("Audio connection releasing failed with status %u\n", event[3]);
271fffdd288SMatthias Ringwald                     }
272fffdd288SMatthias Ringwald                     break;
273fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED:
274fffdd288SMatthias Ringwald                     printf("Received microphone gain change %d\n", event[3]);
275fffdd288SMatthias Ringwald                     break;
276fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED:
277fffdd288SMatthias Ringwald                     printf("Received speaker gain change %d\n", event[3]);
278fffdd288SMatthias Ringwald                     break;
279fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_HS_COMMAND:{
280fffdd288SMatthias Ringwald                     memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
281fffdd288SMatthias Ringwald                     int size = event[3] <= sizeof(hs_cmd_buffer)? event[3] : sizeof(hs_cmd_buffer);
282fffdd288SMatthias Ringwald                     memcpy(hs_cmd_buffer, &event[4], size - 1);
283fffdd288SMatthias Ringwald                     printf("Received custom command: \"%s\". \nExit code or call hsp_ag_send_result.\n", hs_cmd_buffer);
284fffdd288SMatthias Ringwald                     break;
285fffdd288SMatthias Ringwald                 }
286fffdd288SMatthias Ringwald                 default:
287fffdd288SMatthias Ringwald                     printf("event not handled %u\n", event[2]);
288fffdd288SMatthias Ringwald                     break;
289fffdd288SMatthias Ringwald             }
290fffdd288SMatthias Ringwald             break;
291fffdd288SMatthias Ringwald         default:
292fffdd288SMatthias Ringwald             break;
293fffdd288SMatthias Ringwald     }
294fffdd288SMatthias Ringwald }
295fffdd288SMatthias Ringwald 
296fffdd288SMatthias Ringwald /* @section Main Application Setup
297fffdd288SMatthias Ringwald  *
298fffdd288SMatthias Ringwald  * @text Listing MainConfiguration shows main application code.
299fffdd288SMatthias Ringwald  * To run a HSP Audio Gateway service you need to initialize the SDP, and to create and register HSP AG record with it.
300fffdd288SMatthias Ringwald  * In this example, the SCO over HCI is used to receive and send an audio signal.
301fffdd288SMatthias Ringwald  *
302fffdd288SMatthias Ringwald  * Two packet handlers are registered:
303fffdd288SMatthias Ringwald  * - The HCI SCO packet handler receives audio data.
304fffdd288SMatthias Ringwald  * - The HSP AG packet handler is used to trigger sending of audio data and commands to the HS. It also receives the AG's answers.
305fffdd288SMatthias Ringwald  *
306fffdd288SMatthias Ringwald  * The stdin_process callback allows for sending commands to the AG.
307fffdd288SMatthias Ringwald  * At the end the Bluetooth stack is started.
308fffdd288SMatthias Ringwald  */
309fffdd288SMatthias Ringwald 
310fffdd288SMatthias Ringwald /* LISTING_START(MainConfiguration): Setup HSP Audio Gateway */
311fffdd288SMatthias Ringwald int btstack_main(int argc, const char * argv[]);
312fffdd288SMatthias Ringwald int btstack_main(int argc, const char * argv[]){
313fffdd288SMatthias Ringwald 
314fffdd288SMatthias Ringwald     hci_register_sco_packet_handler(&sco_packet_handler);
315fffdd288SMatthias Ringwald 
316fffdd288SMatthias Ringwald     l2cap_init();
317fffdd288SMatthias Ringwald 
318fffdd288SMatthias Ringwald     sdp_init();
319fffdd288SMatthias Ringwald 
320fffdd288SMatthias Ringwald     memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer));
321fffdd288SMatthias Ringwald     hsp_ag_create_sdp_record(hsp_service_buffer, 0x10001, rfcomm_channel_nr, hsp_ag_service_name);
322fffdd288SMatthias Ringwald     printf("SDP service record size: %u\n", de_get_len(hsp_service_buffer));
323fffdd288SMatthias Ringwald     sdp_register_service(hsp_service_buffer);
324fffdd288SMatthias Ringwald 
325fffdd288SMatthias Ringwald     rfcomm_init();
326fffdd288SMatthias Ringwald 
327fffdd288SMatthias Ringwald     hsp_ag_init(rfcomm_channel_nr);
328fffdd288SMatthias Ringwald     hsp_ag_register_packet_handler(packet_handler);
329fffdd288SMatthias Ringwald 
330fffdd288SMatthias Ringwald #ifdef HAVE_STDIO
331fffdd288SMatthias Ringwald     btstack_stdin_setup(stdin_process);
332fffdd288SMatthias Ringwald #endif
333fffdd288SMatthias Ringwald 
334fffdd288SMatthias Ringwald     gap_set_local_name("BTstack HSP AG");
335fffdd288SMatthias Ringwald     gap_discoverable_control(1);
336fffdd288SMatthias Ringwald     gap_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);
337*60b9e82fSMatthias Ringwald     gap_set_class_of_device(0x400204);
338fffdd288SMatthias Ringwald 
339fffdd288SMatthias Ringwald     // turn on!
340fffdd288SMatthias Ringwald     hci_power_control(HCI_POWER_ON);
341fffdd288SMatthias Ringwald     return 0;
342fffdd288SMatthias Ringwald }
343fffdd288SMatthias Ringwald /* LISTING_END */
344