xref: /btstack/example/hsp_hs_demo.c (revision 3d50b4ba508ee9a63dad46affe576c15b254cc01)
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.
926a7f493aSMatthias Ringwald  * To send and receive an audio signal, ENABLE_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 
193d057580eSMatthias Ringwald static void send_sco_data(void){
194cd87ea12SMatthias Ringwald     if (!sco_handle) return;
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);
213d057580eSMatthias Ringwald 
214d057580eSMatthias Ringwald     // request another send event
215d057580eSMatthias Ringwald     hci_request_sco_can_send_now_event();
216d057580eSMatthias Ringwald 
217cd87ea12SMatthias Ringwald     static int count = 0;
218*3d50b4baSMatthias Ringwald     if ((count & SCO_REPORT_PERIOD)) return;
219*3d50b4baSMatthias Ringwald     printf("SCO packets sent: %u\n", count);
220cd87ea12SMatthias Ringwald }
221cd87ea12SMatthias Ringwald 
222*3d50b4baSMatthias Ringwald static void sco_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){
223cd87ea12SMatthias Ringwald     static int count = 0;
224*3d50b4baSMatthias Ringwald     switch (packet_type){
225*3d50b4baSMatthias Ringwald         case HCI_EVENT_PACKET:
226*3d50b4baSMatthias Ringwald             if (packet[0] == HCI_EVENT_SCO_CAN_SEND_NOW){
227*3d50b4baSMatthias Ringwald                 send_sco_data();
228*3d50b4baSMatthias Ringwald             }
229*3d50b4baSMatthias Ringwald             break;
230*3d50b4baSMatthias Ringwald         default:
231cd87ea12SMatthias Ringwald             count++;
232fffdd288SMatthias Ringwald             if ((count & SCO_REPORT_PERIOD)) return;
233*3d50b4baSMatthias Ringwald             printf("SCO packets received: %u\n", count);
234*3d50b4baSMatthias Ringwald             break;
235*3d50b4baSMatthias Ringwald     }
236cd87ea12SMatthias Ringwald }
237cd87ea12SMatthias Ringwald 
238cd87ea12SMatthias Ringwald static void packet_handler(uint8_t * event, uint16_t event_size){
239cd87ea12SMatthias Ringwald     switch (event[0]) {
240cd87ea12SMatthias Ringwald         case BTSTACK_EVENT_STATE:
241cd87ea12SMatthias Ringwald             if (btstack_event_state_get_state(event) != HCI_STATE_WORKING) break;
242fffdd288SMatthias Ringwald             show_usage();
243cd87ea12SMatthias Ringwald             break;
244cd87ea12SMatthias Ringwald         case HCI_EVENT_SCO_CAN_SEND_NOW:
245d057580eSMatthias Ringwald             send_sco_data();
246cd87ea12SMatthias Ringwald             break;
247cd87ea12SMatthias Ringwald         case HCI_EVENT_HSP_META:
248cd87ea12SMatthias Ringwald             switch (event[2]) {
249fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE:
250206531d8SMilanka Ringwald                     if (hsp_subevent_rfcomm_connection_complete_get_status(event)){
251206531d8SMilanka Ringwald                         printf("RFCOMM connection establishement failed with status %u\n", hsp_subevent_audio_connection_complete_get_handle(event));
252fffdd288SMatthias Ringwald                     } else {
253206531d8SMilanka Ringwald                         printf("RFCOMM connection established.\n");
254fffdd288SMatthias Ringwald                     }
255fffdd288SMatthias Ringwald                     break;
256fffdd288SMatthias Ringwald                 case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE:
257206531d8SMilanka Ringwald                     if (hsp_subevent_rfcomm_disconnection_complete_get_status(event)){
258206531d8SMilanka Ringwald                         printf("RFCOMM disconnection failed with status %u.\n", hsp_subevent_rfcomm_disconnection_complete_get_status(event));
259fffdd288SMatthias Ringwald                     } else {
260206531d8SMilanka Ringwald                         printf("RFCOMM disconnected.\n");
261fffdd288SMatthias Ringwald                     }
262fffdd288SMatthias Ringwald                     break;
263cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE:
264206531d8SMilanka Ringwald                     if (hsp_subevent_audio_connection_complete_get_status(event)){
265cd87ea12SMatthias Ringwald                         printf("Audio connection establishment failed with status %u\n", hsp_subevent_audio_connection_complete_get_status(event));
266cd87ea12SMatthias Ringwald                         sco_handle = 0;
267206531d8SMilanka Ringwald                     } else {
268206531d8SMilanka Ringwald                         sco_handle = hsp_subevent_audio_connection_complete_get_handle(event);
269206531d8SMilanka Ringwald                         printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
270d057580eSMatthias Ringwald                         hci_request_sco_can_send_now_event();
271cd87ea12SMatthias Ringwald                     }
272cd87ea12SMatthias Ringwald                     break;
273cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE:
274206531d8SMilanka Ringwald                     if (hsp_subevent_audio_disconnection_complete_get_status(event)){
275206531d8SMilanka Ringwald                         printf("Audio connection releasing failed with status %u\n", hsp_subevent_audio_disconnection_complete_get_status(event));
276206531d8SMilanka Ringwald                     } else {
277cd87ea12SMatthias Ringwald                         printf("Audio connection released.\n\n");
278cd87ea12SMatthias Ringwald                         sco_handle = 0;
279fffdd288SMatthias Ringwald                     }
280cd87ea12SMatthias Ringwald                     break;
281cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED:
282cd87ea12SMatthias Ringwald                     printf("Received microphone gain change %d\n", hsp_subevent_microphone_gain_changed_get_gain(event));
283cd87ea12SMatthias Ringwald                     break;
284cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED:
285cd87ea12SMatthias Ringwald                     printf("Received speaker gain change %d\n", hsp_subevent_speaker_gain_changed_get_gain(event));
286cd87ea12SMatthias Ringwald                     break;
287cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_RING:
288cd87ea12SMatthias Ringwald                     printf("HS: RING RING!\n");
289cd87ea12SMatthias Ringwald                     break;
290cd87ea12SMatthias Ringwald                 case HSP_SUBEVENT_AG_INDICATION: {
291cd87ea12SMatthias Ringwald                     memset(hs_cmd_buffer, 0, sizeof(hs_cmd_buffer));
292cd87ea12SMatthias Ringwald                     int size = hsp_subevent_ag_indication_get_value_length(event);
293cd87ea12SMatthias Ringwald                     if (size >= sizeof(hs_cmd_buffer)-1){
294cd87ea12SMatthias Ringwald                         size =  sizeof(hs_cmd_buffer)-1;
295cd87ea12SMatthias Ringwald                     }
296cd87ea12SMatthias Ringwald                     memcpy(hs_cmd_buffer, hsp_subevent_ag_indication_get_value(event), size);
297cd87ea12SMatthias Ringwald                     printf("Received custom indication: \"%s\". \nExit code or call hsp_hs_send_result.\n", hs_cmd_buffer);
298cd87ea12SMatthias Ringwald 
299cd87ea12SMatthias Ringwald                 }
300cd87ea12SMatthias Ringwald                     break;
301cd87ea12SMatthias Ringwald                 default:
302cd87ea12SMatthias Ringwald                     printf("event not handled %u\n", event[2]);
303cd87ea12SMatthias Ringwald                     break;
304cd87ea12SMatthias Ringwald             }
305cd87ea12SMatthias Ringwald             break;
306cd87ea12SMatthias Ringwald         default:
307cd87ea12SMatthias Ringwald             break;
308cd87ea12SMatthias Ringwald     }
309cd87ea12SMatthias Ringwald }
310cd87ea12SMatthias Ringwald 
311cd87ea12SMatthias Ringwald static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){
312cd87ea12SMatthias Ringwald     packet_handler(packet, size);
313cd87ea12SMatthias Ringwald }
314cd87ea12SMatthias Ringwald 
315fffdd288SMatthias Ringwald /* @section Main Application Setup
316fffdd288SMatthias Ringwald  *
317fffdd288SMatthias Ringwald  * @text Listing MainConfiguration shows main application code.
318fffdd288SMatthias Ringwald  * To run a HSP Headset service you need to initialize the SDP, and to create and register HSP HS record with it.
319fffdd288SMatthias Ringwald  * In this example, the SCO over HCI is used to receive and send an audio signal.
320fffdd288SMatthias Ringwald  *
321fffdd288SMatthias Ringwald  * Two packet handlers are registered:
322fffdd288SMatthias Ringwald  * - The HCI SCO packet handler receives audio data.
323fffdd288SMatthias 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.
324fffdd288SMatthias Ringwald  *
325fffdd288SMatthias Ringwald  * The stdin_process callback allows for sending commands to the AG.
326fffdd288SMatthias Ringwald  * At the end the Bluetooth stack is started.
327fffdd288SMatthias Ringwald  */
328fffdd288SMatthias Ringwald 
329fffdd288SMatthias Ringwald /* LISTING_START(MainConfiguration): Setup HSP Headset */
330cd87ea12SMatthias Ringwald int btstack_main(int argc, const char * argv[]);
331cd87ea12SMatthias Ringwald int btstack_main(int argc, const char * argv[]){
332cd87ea12SMatthias Ringwald 
333cd87ea12SMatthias Ringwald     // register for HCI events
334cd87ea12SMatthias Ringwald     hci_event_callback_registration.callback = &handle_hci_event;
335cd87ea12SMatthias Ringwald     hci_add_event_handler(&hci_event_callback_registration);
336cd87ea12SMatthias Ringwald     hci_register_sco_packet_handler(&sco_packet_handler);
337cd87ea12SMatthias Ringwald 
338fffdd288SMatthias Ringwald     l2cap_init();
339cd87ea12SMatthias Ringwald 
340cd87ea12SMatthias Ringwald     sdp_init();
341cd87ea12SMatthias Ringwald     memset(hsp_service_buffer, 0, sizeof(hsp_service_buffer));
342cd87ea12SMatthias Ringwald     hsp_hs_create_sdp_record(hsp_service_buffer, 0x10001, rfcomm_channel_nr, hsp_hs_service_name, 0);
343cd87ea12SMatthias Ringwald     sdp_register_service(hsp_service_buffer);
344cd87ea12SMatthias Ringwald 
345fffdd288SMatthias Ringwald     rfcomm_init();
346fffdd288SMatthias Ringwald 
347fffdd288SMatthias Ringwald     hsp_hs_init(rfcomm_channel_nr);
348fffdd288SMatthias Ringwald     hsp_hs_register_packet_handler(packet_handler);
349fffdd288SMatthias Ringwald 
350d0755cd6SMatthias Ringwald #ifdef HAVE_POSIX_STDIN
351fffdd288SMatthias Ringwald     btstack_stdin_setup(stdin_process);
352fffdd288SMatthias Ringwald #endif
353fffdd288SMatthias Ringwald 
354fffdd288SMatthias Ringwald     gap_set_local_name("BTstack HSP HS");
355fffdd288SMatthias Ringwald     gap_discoverable_control(1);
356fffdd288SMatthias Ringwald     gap_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);
35760b9e82fSMatthias Ringwald     gap_set_class_of_device(0x240404);
358fffdd288SMatthias Ringwald 
359cd87ea12SMatthias Ringwald     // turn on!
360cd87ea12SMatthias Ringwald     hci_power_control(HCI_POWER_ON);
361cd87ea12SMatthias Ringwald     return 0;
362cd87ea12SMatthias Ringwald }
363fffdd288SMatthias Ringwald /* LISTING_END */
3642b6b8c15SMilanka Ringwald /* EXAMPLE_END */
365