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