xref: /btstack/example/hfp_hf_demo.c (revision 1bf28f67a5f7e94bb05e16aae80e8013e969eac0)
1 
2 /*
3  * Copyright (C) 2014 BlueKitchen GmbH
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific prior written permission.
17  * 4. Any redistribution, use, or modification is done solely for
18  *    personal benefit and not for any commercial purpose or for
19  *    monetary gain.
20  *
21  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
25  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * Please inquire about commercial licensing options at
35  * [email protected]
36  *
37  */
38 
39 /*
40  * hfp_hs_demo.c
41  */
42 
43 // *****************************************************************************
44 /* EXAMPLE_START(hfp_hs_demo): HFP Hands-Free (HF) Demo
45  *
46  * @text This  HFP Hands-Free example demonstrates how to receive
47  * an output from a remote HFP audio gateway (AG), and,
48  * if HAVE_POSIX_STDIN is defined, how to control the HFP AG.
49  */
50 // *****************************************************************************
51 
52 
53 #include "btstack_config.h"
54 
55 #include <stdint.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <unistd.h>
60 
61 #include "btstack.h"
62 #include "sco_demo_util.h"
63 #ifdef HAVE_POSIX_STDIN
64 #include "stdin_support.h"
65 #endif
66 
67 
68 uint8_t hfp_service_buffer[150];
69 const uint8_t   rfcomm_channel_nr = 1;
70 const char hfp_hf_service_name[] = "BTstack HFP HF Demo";
71 
72 #ifdef HAVE_POSIX_STDIN
73 static bd_addr_t device_addr = {0x80,0xbe,0x05,0xd5,0x28,0x48};
74 // 80:BE:05:D5:28:48
75 // prototypes
76 static void show_usage(void);
77 #endif
78 static uint16_t handle = -1;
79 static hci_con_handle_t sco_handle;
80 static uint8_t codecs[] = {HFP_CODEC_CVSD, HFP_CODEC_MSBC};
81 static uint16_t indicators[1] = {0x01};
82 
83 char cmd;
84 
85 #ifdef HAVE_POSIX_STDIN
86 
87 // Testig User Interface
88 static void show_usage(void){
89     printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n");
90     printf("---\n");
91 
92     printf("a - establish SLC connection to device %s\n", bd_addr_to_str(device_addr));
93     printf("A - release SLC connection to device\n");
94 
95     printf("b - establish Audio connection\n");
96     printf("B - release Audio connection\n");
97 
98     printf("c - disable registration status update for all AG indicators\n");
99     printf("C - enable registration status update for all AG indicators\n");
100 
101     printf("d - query network operator.\n");
102     printf("D - set HFP AG registration status update for individual indicators (IIA)\n");
103 
104     printf("e - disable reporting of the extended AG error result code\n");
105     printf("E - enable reporting of the extended AG error result code\n");
106 
107     printf("f - answer incoming call\n");
108     printf("F - Hangup call\n");
109 
110     printf("g - query network operator name\n");
111     printf("G - reject incoming call\n");
112 
113     printf("i - dial 1234567\n");
114     printf("I - dial 7654321\n");
115 
116     printf("j - dial #1\n");
117     printf("J - dial #99\n");
118 
119     printf("k - deactivate call waiting notification\n");
120     printf("K - activate call waiting notification\n");
121 
122     printf("l - deactivate calling line notification\n");
123     printf("L - activate calling line notification\n");
124 
125     printf("m - deactivate echo canceling and noise reduction\n");
126     printf("M - activate echo canceling and noise reduction\n");
127 
128     printf("n - deactivate voice recognition\n");
129     printf("N - activate voice recognition\n");
130 
131     printf("o - Set speaker volume to 0  (minimum)\n");
132     printf("O - Set speaker volume to 9  (default)\n");
133     printf("p - Set speaker volume to 12 (higher)\n");
134     printf("P - Set speaker volume to 15 (maximum)\n");
135 
136     printf("q - Set microphone gain to 0  (minimum)\n");
137     printf("Q - Set microphone gain to 9  (default)\n");
138     printf("s - Set microphone gain to 12 (higher)\n");
139     printf("S - Set microphone gain to 15 (maximum)\n");
140 
141     printf("t - terminate connection\n");
142 
143     printf("u - send 'user busy' (TWC 0)\n");
144     printf("U - end active call and accept other call' (TWC 1)\n");
145     printf("v - Swap active call and hold/waiting call (TWC 2)\n");
146     printf("V - Join held call (TWC 3)\n");
147     printf("w - Connect calls (TWC 4)\n");
148     printf("W - redial\n");
149 
150     printf("0123456789#*-+ - send DTMF dial tones\n");
151 
152     printf("x - request phone number for voice tag\n");
153     printf("X - current call status (ECS)\n");
154     printf("y - release call with index 2 (ECC)\n");
155     printf("Y - private consulation with call 2(ECC)\n");
156 
157     printf("[ - Query Response and Hold status (RHH ?)\n");
158     printf("] - Place call in a response and held state(RHH 0)\n");
159     printf("{ - Accept held call(RHH 1)\n");
160     printf("} - Reject held call(RHH 2)\n");
161 
162     printf("? - Query Subscriber Number (NUM)\n");
163 
164     printf("! - Update HF indicator with assigned number 1 (HFI)\n");
165 
166     printf("---\n");
167     printf("Ctrl-c - exit\n");
168     printf("---\n");
169 }
170 
171 static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){
172     read(ds->fd, &cmd, 1);
173 
174     if (cmd >= '0' && cmd <= '9'){
175         printf("DTMF Code: %c\n", cmd);
176         hfp_hf_send_dtmf_code(device_addr, cmd);
177         return;
178     }
179 
180     switch (cmd){
181         case '#':
182         case '-':
183         case '+':
184         case '*':
185             log_info("USER:\'%c\'", cmd);
186             printf("DTMF Code: %c\n", cmd);
187             hfp_hf_send_dtmf_code(device_addr, cmd);
188             break;
189         case 'a':
190             log_info("USER:\'%c\'", cmd);
191             printf("Establish Service level connection to device with Bluetooth address %s...\n", bd_addr_to_str(device_addr));
192             hfp_hf_establish_service_level_connection(device_addr);
193             break;
194         case 'A':
195             log_info("USER:\'%c\'", cmd);
196             printf("Release Service level connection.\n");
197             hfp_hf_release_service_level_connection(device_addr);
198             break;
199         case 'b':
200             log_info("USER:\'%c\'", cmd);
201             printf("Establish Audio connection to device with Bluetooth address %s...\n", bd_addr_to_str(device_addr));
202             hfp_hf_establish_audio_connection(device_addr);
203             break;
204         case 'B':
205             log_info("USER:\'%c\'", cmd);
206             printf("Release Audio service level connection.\n");
207             hfp_hf_release_audio_connection(device_addr);
208             break;
209         case 'C':
210             log_info("USER:\'%c\'", cmd);
211             printf("Enable registration status update for all AG indicators.\n");
212             hfp_hf_enable_status_update_for_all_ag_indicators(device_addr);
213         case 'c':
214             log_info("USER:\'%c\'", cmd);
215             printf("Disable registration status update for all AG indicators.\n");
216             hfp_hf_disable_status_update_for_all_ag_indicators(device_addr);
217             break;
218         case 'D':
219             log_info("USER:\'%c\'", cmd);
220             printf("Set HFP AG registration status update for individual indicators (0111111).\n");
221             hfp_hf_set_status_update_for_individual_ag_indicators(device_addr, 63);
222             break;
223         case 'd':
224             log_info("USER:\'%c\'", cmd);
225             printf("Query network operator.\n");
226             hfp_hf_query_operator_selection(device_addr);
227             break;
228         case 'E':
229             log_info("USER:\'%c\'", cmd);
230             printf("Enable reporting of the extended AG error result code.\n");
231             hfp_hf_enable_report_extended_audio_gateway_error_result_code(device_addr);
232             break;
233         case 'e':
234             log_info("USER:\'%c\'", cmd);
235             printf("Disable reporting of the extended AG error result code.\n");
236             hfp_hf_disable_report_extended_audio_gateway_error_result_code(device_addr);
237             break;
238         case 'f':
239             log_info("USER:\'%c\'", cmd);
240             printf("Answer incoming call.\n");
241             hfp_hf_answer_incoming_call(device_addr);
242             break;
243         case 'F':
244             log_info("USER:\'%c\'", cmd);
245             printf("Hangup call.\n");
246             hfp_hf_terminate_call(device_addr);
247             break;
248         case 'G':
249             log_info("USER:\'%c\'", cmd);
250             printf("Reject incoming call.\n");
251             hfp_hf_reject_incoming_call(device_addr);
252             break;
253         case 'g':
254             log_info("USER:\'%c\'", cmd);
255             printf("Query operator.\n");
256             hfp_hf_query_operator_selection(device_addr);
257             break;
258         case 't':
259             log_info("USER:\'%c\'", cmd);
260             printf("Terminate HCI connection.\n");
261             gap_disconnect(handle);
262             break;
263         case 'i':
264             log_info("USER:\'%c\'", cmd);
265             printf("Dial 1234567\n");
266             hfp_hf_dial_number(device_addr, "1234567");
267             break;
268         case 'I':
269             log_info("USER:\'%c\'", cmd);
270             printf("Dial 7654321\n");
271             hfp_hf_dial_number(device_addr, "7654321");
272             break;
273         case 'j':
274             log_info("USER:\'%c\'", cmd);
275             printf("Dial #1\n");
276             hfp_hf_dial_memory(device_addr,1);
277             break;
278         case 'J':
279             log_info("USER:\'%c\'", cmd);
280             printf("Dial #99\n");
281             hfp_hf_dial_memory(device_addr,99);
282             break;
283         case 'k':
284             log_info("USER:\'%c\'", cmd);
285             printf("Deactivate call waiting notification\n");
286             hfp_hf_deactivate_call_waiting_notification(device_addr);
287             break;
288         case 'K':
289             log_info("USER:\'%c\'", cmd);
290             printf("Activate call waiting notification\n");
291             hfp_hf_activate_call_waiting_notification(device_addr);
292             break;
293         case 'l':
294             log_info("USER:\'%c\'", cmd);
295             printf("Deactivate calling line notification\n");
296             hfp_hf_deactivate_calling_line_notification(device_addr);
297             break;
298         case 'L':
299             log_info("USER:\'%c\'", cmd);
300             printf("Activate calling line notification\n");
301             hfp_hf_activate_calling_line_notification(device_addr);
302             break;
303         case 'm':
304             log_info("USER:\'%c\'", cmd);
305             printf("Deactivate echo canceling and noise reduction\n");
306             hfp_hf_deactivate_echo_canceling_and_noise_reduction(device_addr);
307             break;
308         case 'M':
309             log_info("USER:\'%c\'", cmd);
310             printf("Activate echo canceling and noise reduction\n");
311             hfp_hf_activate_echo_canceling_and_noise_reduction(device_addr);
312             break;
313         case 'n':
314             log_info("USER:\'%c\'", cmd);
315             printf("Deactivate voice recognition\n");
316             hfp_hf_deactivate_voice_recognition_notification(device_addr);
317             break;
318         case 'N':
319             log_info("USER:\'%c\'", cmd);
320             printf("Activate voice recognition\n");
321             hfp_hf_activate_voice_recognition_notification(device_addr);
322             break;
323         case 'o':
324             log_info("USER:\'%c\'", cmd);
325             printf("Set speaker gain to 0 (minimum)\n");
326             hfp_hf_set_speaker_gain(device_addr, 0);
327             break;
328         case 'O':
329             log_info("USER:\'%c\'", cmd);
330             printf("Set speaker gain to 9 (default)\n");
331             hfp_hf_set_speaker_gain(device_addr, 9);
332             break;
333         case 'p':
334             log_info("USER:\'%c\'", cmd);
335             printf("Set speaker gain to 12 (higher)\n");
336             hfp_hf_set_speaker_gain(device_addr, 12);
337             break;
338         case 'P':
339             log_info("USER:\'%c\'", cmd);
340             printf("Set speaker gain to 15 (maximum)\n");
341             hfp_hf_set_speaker_gain(device_addr, 15);
342             break;
343         case 'q':
344             log_info("USER:\'%c\'", cmd);
345             printf("Set microphone gain to 0\n");
346             hfp_hf_set_microphone_gain(device_addr, 0);
347             break;
348         case 'Q':
349             log_info("USER:\'%c\'", cmd);
350             printf("Set microphone gain to 9\n");
351             hfp_hf_set_microphone_gain(device_addr, 9);
352             break;
353         case 's':
354             log_info("USER:\'%c\'", cmd);
355             printf("Set microphone gain to 12\n");
356             hfp_hf_set_microphone_gain(device_addr, 12);
357             break;
358         case 'S':
359             log_info("USER:\'%c\'", cmd);
360             printf("Set microphone gain to 15\n");
361             hfp_hf_set_microphone_gain(device_addr, 15);
362             break;
363         case 'u':
364             log_info("USER:\'%c\'", cmd);
365             printf("Send 'user busy' (Three-Way Call 0)\n");
366             hfp_hf_user_busy(device_addr);
367             break;
368         case 'U':
369             log_info("USER:\'%c\'", cmd);
370             printf("End active call and accept waiting/held call (Three-Way Call 1)\n");
371             hfp_hf_end_active_and_accept_other(device_addr);
372             break;
373         case 'v':
374             log_info("USER:\'%c\'", cmd);
375             printf("Swap active call and hold/waiting call (Three-Way Call 2)\n");
376             hfp_hf_swap_calls(device_addr);
377             break;
378         case 'V':
379             log_info("USER:\'%c\'", cmd);
380             printf("Join hold call (Three-Way Call 3)\n");
381             hfp_hf_join_held_call(device_addr);
382             break;
383         case 'w':
384             log_info("USER:\'%c\'", cmd);
385             printf("Connect calls (Three-Way Call 4)\n");
386             hfp_hf_connect_calls(device_addr);
387             break;
388         case 'W':
389             log_info("USER:\'%c\'", cmd);
390             printf("Redial\n");
391             hfp_hf_redial_last_number(device_addr);
392             break;
393         case 'x':
394             log_info("USER:\'%c\'", cmd);
395             printf("Request phone number for voice tag\n");
396             hfp_hf_request_phone_number_for_voice_tag(device_addr);
397             break;
398         case 'X':
399             log_info("USER:\'%c\'", cmd);
400             printf("Query current call status\n");
401             hfp_hf_query_current_call_status(device_addr);
402             break;
403         case 'y':
404             log_info("USER:\'%c\'", cmd);
405             printf("Release call with index 2\n");
406             hfp_hf_release_call_with_index(device_addr, 2);
407             break;
408         case 'Y':
409             log_info("USER:\'%c\'", cmd);
410             printf("Private consulation with call 2\n");
411             hfp_hf_private_consultation_with_call(device_addr, 2);
412             break;
413         case '[':
414             log_info("USER:\'%c\'", cmd);
415             printf("Query Response and Hold status (RHH ?)\n");
416             hfp_hf_rrh_query_status(device_addr);
417             break;
418         case ']':
419             log_info("USER:\'%c\'", cmd);
420             printf("Place call in a response and held state (RHH 0)\n");
421             hfp_hf_rrh_hold_call(device_addr);
422            break;
423         case '{':
424             log_info("USER:\'%c\'", cmd);
425             printf("Accept held call (RHH 1)\n");
426             hfp_hf_rrh_accept_held_call(device_addr);
427             break;
428         case '}':
429             log_info("USER:\'%c\'", cmd);
430             printf("Reject held call (RHH 2)\n");
431             hfp_hf_rrh_reject_held_call(device_addr);
432             break;
433         case '?':
434             log_info("USER:\'%c\'", cmd);
435             printf("Query Subscriber Number\n");
436             hfp_hf_query_subscriber_number(device_addr);
437             break;
438         case '!':
439             log_info("USER:\'%c\'", cmd);
440             printf("Update HF indicator with assigned number 1 (HFI)\n");
441             hfp_hf_set_hf_indicator(device_addr, 1, 1);
442             break;
443 
444         default:
445             show_usage();
446             break;
447     }
448 }
449 #endif
450 
451 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size){
452 
453     switch (packet_type){
454 
455         case HCI_SCO_DATA_PACKET:
456             sco_demo_receive(event, event_size);
457             break;
458 
459         case HCI_EVENT_PACKET:
460             switch (event[0]){
461 
462                 case HCI_EVENT_SCO_CAN_SEND_NOW:
463                     sco_demo_send(sco_handle);
464                     break;
465 
466                 case HCI_EVENT_HFP_META:
467                     switch (event[2]) {
468                         case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
469                             handle = hfp_subevent_service_level_connection_established_get_con_handle(event);
470                             printf("Service level connection established.\n\n");
471                             break;
472                         case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
473                             printf("Service level connection released.\n\n");
474                             break;
475                         case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED:
476                             if (hfp_subevent_audio_connection_established_get_status(event)){
477                                 sco_handle = 0;
478                                 printf("Audio connection establishment failed with status %u\n", hfp_subevent_audio_connection_established_get_status(event));
479                             } else {
480                                 sco_handle = hfp_subevent_audio_connection_established_get_handle(event);
481                                 printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
482                                 hci_request_sco_can_send_now_event();
483                             }
484                             break;
485                         case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED:
486                             sco_handle = 0;
487                             printf("Audio connection released\n");
488                             break;
489                         case HFP_SUBEVENT_COMPLETE:
490                             switch (cmd){
491                                 case 'd':
492                                     printf("HFP AG registration status update enabled.\n");
493                                     break;
494                                 case 'e':
495                                     printf("HFP AG registration status update for individual indicators set.\n");
496                                 default:
497                                     break;
498                             }
499                             break;
500                         case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
501                             printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[5], event[3], event[4]);
502                             break;
503                         case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
504                             printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[3], event[4], (char *) &event[5]);
505                             break;
506                         case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
507                             if (event[4])
508                             printf("EXTENDED_AUDIO_GATEWAY_ERROR_REPORT, status : %d\n", event[3]);
509                             break;
510                         case HFP_SUBEVENT_RING:
511                             printf("** Ring **\n");
512                             break;
513                         case HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG:
514                             printf("Phone number for voice tag: %s\n", (const char *) &event[3]);
515                             break;
516                         case HFP_SUBEVENT_SPEAKER_VOLUME:
517                             printf("Speaker volume: %u\n", event[3]);
518                             break;
519                         case HFP_SUBEVENT_MICROPHONE_VOLUME:
520                             printf("Microphone volume: %u\n", event[3]);
521                             break;
522                         default:
523                             printf("event not handled %u\n", event[2]);
524                             break;
525                     }
526                     break;
527 
528                 default:
529                     break;
530             }
531             break;
532 
533         default:
534             break;
535     }
536 
537 
538     if (event[0] != HCI_EVENT_HFP_META) return;
539 
540     switch (event[2]) {
541         case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
542             handle = hfp_subevent_service_level_connection_established_get_con_handle(event);
543             printf("Service level connection established.\n\n");
544             break;
545         case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
546             printf("Service level connection released.\n\n");
547             break;
548         case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED:
549             if (hfp_subevent_audio_connection_established_get_status(event)){
550                 sco_handle = 0;
551                 printf("Audio connection establishment failed with status %u\n", hfp_subevent_audio_connection_established_get_status(event));
552             } else {
553                 sco_handle = hfp_subevent_audio_connection_established_get_handle(event);
554                 printf("Audio connection established with SCO handle 0x%04x.\n", sco_handle);
555                 hci_request_sco_can_send_now_event();
556             }
557             break;
558         case HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED:
559             sco_handle = 0;
560             printf("Audio connection released\n");
561             break;
562         case HFP_SUBEVENT_COMPLETE:
563             switch (cmd){
564                 case 'd':
565                     printf("HFP AG registration status update enabled.\n");
566                     break;
567                 case 'e':
568                     printf("HFP AG registration status update for individual indicators set.\n");
569                 default:
570                     break;
571             }
572             break;
573         case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
574             printf("AG_INDICATOR_STATUS_CHANGED, AG indicator '%s' (index: %d) to: %d\n", (const char*) &event[5], event[3], event[4]);
575             break;
576         case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
577             printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[3], event[4], (char *) &event[5]);
578             break;
579         case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
580             if (event[4])
581             printf("EXTENDED_AUDIO_GATEWAY_ERROR_REPORT, status : %d\n", event[3]);
582             break;
583         case HFP_SUBEVENT_RING:
584             printf("** Ring **\n");
585             break;
586         case HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG:
587             printf("Phone number for voice tag: %s\n", (const char *) &event[3]);
588             break;
589         case HFP_SUBEVENT_SPEAKER_VOLUME:
590             printf("Speaker volume: %u\n", event[3]);
591             break;
592         case HFP_SUBEVENT_MICROPHONE_VOLUME:
593             printf("Microphone volume: %u\n", event[3]);
594             break;
595         default:
596             printf("event not handled %u\n", event[2]);
597             break;
598     }
599 }
600 
601 /* @section Main Application Setup
602  *
603  * @text Listing MainConfiguration shows main application code.
604  * To run a HFP HF service you need to initialize the SDP, and to create and register HFP HF record with it.
605  * The packet_handler is used for sending commands to the HFP AG. It also receives the HFP AG's answers.
606  * The stdin_process callback allows for sending commands to the HFP AG.
607  * At the end the Bluetooth stack is started.
608  */
609 
610 /* LISTING_START(MainConfiguration): Setup HFP Hands-Free unit */
611 int btstack_main(int argc, const char * argv[]);
612 int btstack_main(int argc, const char * argv[]){
613 
614     sco_demo_init();
615 
616     gap_discoverable_control(1);
617 
618     // HFP AG address is hardcoded, please change it
619     // init L2CAP
620     l2cap_init();
621     rfcomm_init();
622     sdp_init();
623 
624     hfp_hf_init(rfcomm_channel_nr);
625     hfp_hf_init_supported_features(438 | (1<<HFP_HFSF_ESCO_S4) | (1<<HFP_HFSF_EC_NR_FUNCTION));
626     hfp_hf_init_hf_indicators(sizeof(indicators)/sizeof(uint16_t), indicators);
627     hfp_hf_init_codecs(sizeof(codecs), codecs);
628 
629     hfp_hf_register_packet_handler(packet_handler);
630     hci_register_sco_packet_handler(&packet_handler);
631 
632     memset(hfp_service_buffer, 0, sizeof(hfp_service_buffer));
633     hfp_hf_create_sdp_record(hfp_service_buffer, 0x10001, rfcomm_channel_nr, hfp_hf_service_name, 0);
634     printf("SDP service record size: %u\n", de_get_len(hfp_service_buffer));
635     sdp_register_service(hfp_service_buffer);
636 
637 #ifdef HAVE_POSIX_STDIN
638     btstack_stdin_setup(stdin_process);
639 #endif
640     // turn on!
641     hci_power_control(HCI_POWER_ON);
642     return 0;
643 }
644 /* LISTING_END */
645 /* EXAMPLE_END */
646