xref: /btstack/test/security_manager_sc/main.c (revision bc6a318f2177319997f3b7da7b6f161b4ec94fed)
1a921db49SMatthias Ringwald /*
2a921db49SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3a921db49SMatthias Ringwald  *
4a921db49SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5a921db49SMatthias Ringwald  * modification, are permitted provided that the following conditions
6a921db49SMatthias Ringwald  * are met:
7a921db49SMatthias Ringwald  *
8a921db49SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9a921db49SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10a921db49SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11a921db49SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12a921db49SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13a921db49SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14a921db49SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15a921db49SMatthias Ringwald  *    from this software without specific prior written permission.
16a921db49SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17a921db49SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18a921db49SMatthias Ringwald  *    monetary gain.
19a921db49SMatthias Ringwald  *
20a921db49SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21a921db49SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22a921db49SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23a921db49SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24a921db49SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25a921db49SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26a921db49SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27a921db49SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28a921db49SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29a921db49SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30a921db49SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31a921db49SMatthias Ringwald  * SUCH DAMAGE.
32a921db49SMatthias Ringwald  *
33a921db49SMatthias Ringwald  * Please inquire about commercial licensing options at
34a921db49SMatthias Ringwald  * [email protected]
35a921db49SMatthias Ringwald  *
36a921db49SMatthias Ringwald  */
37a921db49SMatthias Ringwald 
38*bc6a318fSMatthias Ringwald #define BTSTACK_FILE__ "main.c"
39a921db49SMatthias Ringwald 
40a921db49SMatthias Ringwald // *****************************************************************************
41a921db49SMatthias Ringwald //
42a921db49SMatthias Ringwald // minimal setup for HCI code
43a921db49SMatthias Ringwald //
44a921db49SMatthias Ringwald // *****************************************************************************
45169aa879SDirk Helbig #include <getopt.h>
46169aa879SDirk Helbig #include <errno.h>
47a921db49SMatthias Ringwald #include <stdint.h>
48a921db49SMatthias Ringwald #include <stdio.h>
49a921db49SMatthias Ringwald #include <stdlib.h>
50a921db49SMatthias Ringwald #include <string.h>
51a921db49SMatthias Ringwald #include <signal.h>
52713e3f72SDirk Helbig #include <unistd.h>
53a921db49SMatthias Ringwald 
54a921db49SMatthias Ringwald #include "btstack_config.h"
55a921db49SMatthias Ringwald 
56a921db49SMatthias Ringwald #include "bluetooth_company_id.h"
57a921db49SMatthias Ringwald #include "btstack_debug.h"
58a921db49SMatthias Ringwald #include "btstack_event.h"
59a921db49SMatthias Ringwald #include "ble/le_device_db_tlv.h"
60a921db49SMatthias Ringwald #include "classic/btstack_link_key_db_tlv.h"
61a921db49SMatthias Ringwald #include "btstack_memory.h"
62a921db49SMatthias Ringwald #include "btstack_run_loop.h"
63a921db49SMatthias Ringwald #include "btstack_run_loop_posix.h"
64a921db49SMatthias Ringwald #include "hal_led.h"
65a921db49SMatthias Ringwald #include "hci.h"
6614dd5758SMatthias Ringwald #include "hci_transport.h"
6714dd5758SMatthias Ringwald #include "hci_transport_usb.h"
68a921db49SMatthias Ringwald #include "hci_dump.h"
6914dd5758SMatthias Ringwald #include "hci_dump_posix_fs.h"
70a921db49SMatthias Ringwald #include "btstack_stdin.h"
71a921db49SMatthias Ringwald #include "btstack_audio.h"
72a921db49SMatthias Ringwald #include "btstack_tlv_posix.h"
73a921db49SMatthias Ringwald #include "btstack_chipset_zephyr.h"
74a921db49SMatthias Ringwald 
75a921db49SMatthias Ringwald #define TLV_DB_PATH_PREFIX "/tmp/btstack_"
76a921db49SMatthias Ringwald #define TLV_DB_PATH_POSTFIX ".tlv"
77a921db49SMatthias Ringwald static char tlv_db_path[100];
78169aa879SDirk Helbig static bool tlv_clear = false;
79a921db49SMatthias Ringwald static const btstack_tlv_t * tlv_impl;
80a921db49SMatthias Ringwald static btstack_tlv_posix_t   tlv_context;
81a921db49SMatthias Ringwald static bd_addr_t             local_addr;
82a921db49SMatthias Ringwald 
83713e3f72SDirk Helbig #define MAX_CMD_LINE_ITEMS  100
84713e3f72SDirk Helbig static int app_argc = 0;
85713e3f72SDirk Helbig static const char *app_argv[MAX_CMD_LINE_ITEMS] = { NULL };
86713e3f72SDirk Helbig 
87a921db49SMatthias Ringwald int btstack_main(int argc, const char * argv[]);
88a921db49SMatthias Ringwald 
89a921db49SMatthias Ringwald static bd_addr_t static_address;
90a921db49SMatthias Ringwald static int using_static_address;
91a921db49SMatthias Ringwald 
92a921db49SMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration;
93a921db49SMatthias Ringwald 
local_version_information_handler(uint8_t * packet)94a921db49SMatthias Ringwald static void local_version_information_handler(uint8_t * packet){
95a921db49SMatthias Ringwald     printf("Local version information:\n");
96a921db49SMatthias Ringwald     uint16_t hci_version    = packet[6];
97a921db49SMatthias Ringwald     uint16_t hci_revision   = little_endian_read_16(packet, 7);
98a921db49SMatthias Ringwald     uint16_t lmp_version    = packet[9];
99a921db49SMatthias Ringwald     uint16_t manufacturer   = little_endian_read_16(packet, 10);
100a921db49SMatthias Ringwald     uint16_t lmp_subversion = little_endian_read_16(packet, 12);
101a921db49SMatthias Ringwald     printf("- HCI Version    0x%04x\n", hci_version);
102a921db49SMatthias Ringwald     printf("- HCI Revision   0x%04x\n", hci_revision);
103a921db49SMatthias Ringwald     printf("- LMP Version    0x%04x\n", lmp_version);
104a921db49SMatthias Ringwald     printf("- LMP Subversion 0x%04x\n", lmp_subversion);
105a921db49SMatthias Ringwald     printf("- Manufacturer 0x%04x\n", manufacturer);
106a921db49SMatthias Ringwald     switch (manufacturer){
107a921db49SMatthias Ringwald         case BLUETOOTH_COMPANY_ID_THE_LINUX_FOUNDATION:
108a921db49SMatthias Ringwald             printf("Linux Foundation - assume Zephyr hci_usb example running on nRF52xx\n");
109a921db49SMatthias Ringwald             hci_set_chipset(btstack_chipset_zephyr_instance());
110a921db49SMatthias Ringwald             break;
111a921db49SMatthias Ringwald         default:
112a921db49SMatthias Ringwald             break;
113a921db49SMatthias Ringwald     }
114a921db49SMatthias Ringwald }
115a921db49SMatthias Ringwald 
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)116a921db49SMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
117a921db49SMatthias Ringwald     UNUSED(channel);
118a921db49SMatthias Ringwald     UNUSED(size);
119bab62d70SMatthias Ringwald     uint8_t usb_path_len;
120bab62d70SMatthias Ringwald     const uint8_t * usb_path;
121bab62d70SMatthias Ringwald     uint16_t product_id;
122bab62d70SMatthias Ringwald     uint8_t i;
1239c228539SDirk Helbig     const uint8_t *params;
124bab62d70SMatthias Ringwald 
125a921db49SMatthias Ringwald     if (packet_type != HCI_EVENT_PACKET) return;
126a921db49SMatthias Ringwald     switch (hci_event_packet_get_type(packet)){
127a921db49SMatthias Ringwald         case BTSTACK_EVENT_STATE:
128a921db49SMatthias Ringwald             switch (btstack_event_state_get_state(packet)){
129a921db49SMatthias Ringwald                 case HCI_STATE_WORKING:
130a921db49SMatthias Ringwald                     gap_local_bd_addr(local_addr);
131a921db49SMatthias Ringwald                     if (using_static_address){
132a921db49SMatthias Ringwald                         memcpy(local_addr, static_address, 6);
133a921db49SMatthias Ringwald                     }
134a921db49SMatthias Ringwald                     printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr));
13554736c11SMatthias Ringwald                     btstack_strcpy(tlv_db_path, sizeof(tlv_db_path), TLV_DB_PATH_PREFIX);
13654736c11SMatthias Ringwald                     btstack_strcat(tlv_db_path, sizeof(tlv_db_path), bd_addr_to_str(local_addr));
13754736c11SMatthias Ringwald                     btstack_strcat(tlv_db_path, sizeof(tlv_db_path), TLV_DB_PATH_POSTFIX);
138169aa879SDirk Helbig                     printf("TLV path: %s", tlv_db_path);
139169aa879SDirk Helbig                     if (tlv_clear){
140169aa879SDirk Helbig                         int rc = unlink(tlv_db_path);
141bab62d70SMatthias Ringwald                         if (rc == 0) {
142bab62d70SMatthias Ringwald                             printf(", reset ok");
143169aa879SDirk Helbig                         } else {
144bab62d70SMatthias Ringwald                             printf(", reset failed with result = %d", rc);
145169aa879SDirk Helbig                         }
146169aa879SDirk Helbig                     }
147bab62d70SMatthias Ringwald                     printf("\n");
148a921db49SMatthias Ringwald                     tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path);
149a921db49SMatthias Ringwald                     btstack_tlv_set_instance(tlv_impl, &tlv_context);
150a921db49SMatthias Ringwald #ifdef ENABLE_CLASSIC
151a921db49SMatthias Ringwald                     hci_set_link_key_db(btstack_link_key_db_tlv_get_instance(tlv_impl, &tlv_context));
152a921db49SMatthias Ringwald #endif
153a921db49SMatthias Ringwald #ifdef ENABLE_BLE
154a921db49SMatthias Ringwald                     le_device_db_tlv_configure(tlv_impl, &tlv_context);
155a921db49SMatthias Ringwald #endif
156a921db49SMatthias Ringwald                     break;
157a921db49SMatthias Ringwald                 case HCI_STATE_OFF:
158a921db49SMatthias Ringwald                     btstack_tlv_posix_deinit(&tlv_context);
159a921db49SMatthias Ringwald                     break;
160a921db49SMatthias Ringwald                 default:
161a921db49SMatthias Ringwald                     break;
162a921db49SMatthias Ringwald             }
163a921db49SMatthias Ringwald             if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
164a921db49SMatthias Ringwald             break;
165a921db49SMatthias Ringwald         case HCI_EVENT_COMMAND_COMPLETE:
1669c228539SDirk Helbig             switch (hci_event_command_complete_get_command_opcode(packet)){
1679c228539SDirk Helbig                 case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION:
168a921db49SMatthias Ringwald                     local_version_information_handler(packet);
1699c228539SDirk Helbig                     break;
1709c228539SDirk Helbig                 case HCI_OPCODE_HCI_ZEPHYR_READ_STATIC_ADDRESS:
1719c228539SDirk Helbig                     params = hci_event_command_complete_get_return_parameters(packet);
1729c228539SDirk Helbig                     if(params[0] != 0)
1739c228539SDirk Helbig                         break;
1749c228539SDirk Helbig                     if(size < 13)
1759c228539SDirk Helbig                         break;
1769c228539SDirk Helbig                     reverse_48(&params[2], static_address);
177a921db49SMatthias Ringwald                     gap_random_address_set(static_address);
178a921db49SMatthias Ringwald                     using_static_address = 1;
1799c228539SDirk Helbig                     break;
1809c228539SDirk Helbig                 default:
1819c228539SDirk Helbig                     break;
182a921db49SMatthias Ringwald             }
183a921db49SMatthias Ringwald             break;
184bab62d70SMatthias Ringwald         case HCI_EVENT_TRANSPORT_USB_INFO:
185bab62d70SMatthias Ringwald             usb_path_len = hci_event_transport_usb_info_get_path_len(packet);
186bab62d70SMatthias Ringwald             usb_path = hci_event_transport_usb_info_get_path(packet);
187bab62d70SMatthias Ringwald             // print device path
188bab62d70SMatthias Ringwald             product_id = hci_event_transport_usb_info_get_product_id(packet);
189bab62d70SMatthias Ringwald             printf("USB device 0x%04x/0x%04x, path: ",
190bab62d70SMatthias Ringwald                    hci_event_transport_usb_info_get_vendor_id(packet), product_id);
191bab62d70SMatthias Ringwald             for (i=0;i<usb_path_len;i++){
192bab62d70SMatthias Ringwald                 if (i) printf("-");
193bab62d70SMatthias Ringwald                 printf("%02x", usb_path[i]);
194bab62d70SMatthias Ringwald             }
195bab62d70SMatthias Ringwald             printf("\n");
196bab62d70SMatthias Ringwald             break;
197bab62d70SMatthias Ringwald 
198a921db49SMatthias Ringwald         default:
199a921db49SMatthias Ringwald             break;
200a921db49SMatthias Ringwald     }
201a921db49SMatthias Ringwald }
202a921db49SMatthias Ringwald 
sigint_handler(int param)203a921db49SMatthias Ringwald static void sigint_handler(int param){
204a921db49SMatthias Ringwald     UNUSED(param);
205a921db49SMatthias Ringwald 
206a921db49SMatthias Ringwald     printf("CTRL-C - SIGINT received, shutting down..\n");
207a921db49SMatthias Ringwald     log_info("sigint_handler: shutting down");
208a921db49SMatthias Ringwald 
209a921db49SMatthias Ringwald     // reset anyway
210a921db49SMatthias Ringwald     btstack_stdin_reset();
211a921db49SMatthias Ringwald 
212a921db49SMatthias Ringwald     // power down
213a921db49SMatthias Ringwald     hci_power_control(HCI_POWER_OFF);
214a921db49SMatthias Ringwald     hci_close();
215a921db49SMatthias Ringwald     log_info("Good bye, see you.\n");
216a921db49SMatthias Ringwald     exit(0);
217a921db49SMatthias Ringwald }
218a921db49SMatthias Ringwald 
219a921db49SMatthias Ringwald static int led_state = 0;
hal_led_toggle(void)220a921db49SMatthias Ringwald void hal_led_toggle(void){
221a921db49SMatthias Ringwald     led_state = 1 - led_state;
222a921db49SMatthias Ringwald     printf("LED State %u\n", led_state);
223a921db49SMatthias Ringwald }
224a921db49SMatthias Ringwald 
btstack_log_cmd_line(int argc,const char * args[])225169aa879SDirk Helbig static void btstack_log_cmd_line( int argc, const char *args[] )
226169aa879SDirk Helbig {
227169aa879SDirk Helbig     char buf[2048] = "command line:";
228169aa879SDirk Helbig     char *ptr = buf+strlen(buf);
229169aa879SDirk Helbig     size_t len = sizeof(buf);
230169aa879SDirk Helbig     for( int i=0; i<argc; ++i )
231169aa879SDirk Helbig     {
232169aa879SDirk Helbig         int ret = snprintf(ptr, len, " %s", args[i]);
233169aa879SDirk Helbig         // avoid overflow
234169aa879SDirk Helbig         if((ret < 0) || ( (size_t)ret >= len ))
235169aa879SDirk Helbig         {
236169aa879SDirk Helbig             log_error("command line truncated!");
237169aa879SDirk Helbig             break;
238169aa879SDirk Helbig         }
239169aa879SDirk Helbig         // terminate string
240169aa879SDirk Helbig         ptr[ret] = 0;
241169aa879SDirk Helbig         len -= ret;
242169aa879SDirk Helbig         ptr += ret;
243169aa879SDirk Helbig     }
244169aa879SDirk Helbig     log_info("%s", buf);
245169aa879SDirk Helbig 
246169aa879SDirk Helbig }
247169aa879SDirk Helbig 
248169aa879SDirk Helbig static const char short_options[] = "-hu:l:c";
249169aa879SDirk Helbig 
250169aa879SDirk Helbig static const struct option long_options[] = {
251169aa879SDirk Helbig     {"help",       no_argument,        NULL,   'h'},
252169aa879SDirk Helbig     {"logfile",    required_argument,  NULL,   'l'},
253169aa879SDirk Helbig     {"clear-tlv",  no_argument,        NULL,   'c'},
254169aa879SDirk Helbig     {"usbpath",    required_argument,  NULL,   'u'},
255169aa879SDirk Helbig     {0, 0, 0, 0}
256169aa879SDirk Helbig };
257169aa879SDirk Helbig 
258169aa879SDirk Helbig static const char *help_options[] = {
259169aa879SDirk Helbig     "print (this) help.",
260169aa879SDirk Helbig     "set file to store debug output and HCI trace.",
261169aa879SDirk Helbig     "clear bonding information stored in TLV.",
262169aa879SDirk Helbig     "set USB path to Bluetooth Controller.",
263169aa879SDirk Helbig };
264169aa879SDirk Helbig 
265169aa879SDirk Helbig static const char *option_arg_name[] = {
266169aa879SDirk Helbig     "",
267169aa879SDirk Helbig     "LOGFILE",
268169aa879SDirk Helbig     "",
269169aa879SDirk Helbig     "USBPATH",
270169aa879SDirk Helbig };
271169aa879SDirk Helbig 
usage(const char * name)272169aa879SDirk Helbig static void usage(const char *name){
273169aa879SDirk Helbig     unsigned int i;
274169aa879SDirk Helbig     printf( "usage:\n\t%s [options]\n", name );
275169aa879SDirk Helbig     printf("valid options:\n");
276169aa879SDirk Helbig     for( i=0; long_options[i].name != 0; i++) {
277169aa879SDirk Helbig         printf("--%-10s| -%c  %-10s\t\t%s\n", long_options[i].name, long_options[i].val, option_arg_name[i], help_options[i] );
278169aa879SDirk Helbig     }
279169aa879SDirk Helbig }
280169aa879SDirk Helbig 
clear_argv(int idx)281713e3f72SDirk Helbig static void clear_argv(int idx){
282169aa879SDirk Helbig     app_argv[idx] = NULL;
283169aa879SDirk Helbig }
284713e3f72SDirk Helbig 
shift_argv(int idx)285713e3f72SDirk Helbig static void shift_argv(int idx){
286169aa879SDirk Helbig     for( int i=idx; i<app_argc-1; ++i )
287169aa879SDirk Helbig     {
288169aa879SDirk Helbig         app_argv[i] = app_argv[i+1];
289169aa879SDirk Helbig     }
290169aa879SDirk Helbig     app_argc--;
291169aa879SDirk Helbig }
292713e3f72SDirk Helbig 
cleanup_argv(void)293713e3f72SDirk Helbig static void cleanup_argv(void){
294713e3f72SDirk Helbig     for( int i=0; i<app_argc; ){
295169aa879SDirk Helbig         if( app_argv[i] == NULL )
296169aa879SDirk Helbig             shift_argv( i );
297713e3f72SDirk Helbig         else{
298169aa879SDirk Helbig             ++i;
299169aa879SDirk Helbig         }
300169aa879SDirk Helbig     }
301713e3f72SDirk Helbig }
302169aa879SDirk Helbig 
303a921db49SMatthias Ringwald #define USB_MAX_PATH_LEN 7
main(int argc,const char * argv[])304a921db49SMatthias Ringwald int main(int argc, const char * argv[]){
305a921db49SMatthias Ringwald 
306a921db49SMatthias Ringwald     uint8_t usb_path[USB_MAX_PATH_LEN];
307a921db49SMatthias Ringwald     int usb_path_len = 0;
308a921db49SMatthias Ringwald     const char * usb_path_string = NULL;
309169aa879SDirk Helbig     const char * log_file_path = NULL;
310169aa879SDirk Helbig 
311713e3f72SDirk Helbig     btstack_assert( argc < MAX_CMD_LINE_ITEMS );
312169aa879SDirk Helbig     app_argc = argc;
313713e3f72SDirk Helbig     for( int i=0; i<argc; ++i ){
314169aa879SDirk Helbig         app_argv[i] = argv[i];
315169aa879SDirk Helbig     }
316169aa879SDirk Helbig 
317169aa879SDirk Helbig     opterr = 0; // disable error message on unknown options
318169aa879SDirk Helbig     // parse command line parameters
319169aa879SDirk Helbig     while(true){
320169aa879SDirk Helbig         int c = getopt_long( argc, (char* const *)argv, short_options, long_options, NULL );
321169aa879SDirk Helbig         if (c < 0) {
322169aa879SDirk Helbig             break;
323169aa879SDirk Helbig         }
324169aa879SDirk Helbig         switch (c) {
325169aa879SDirk Helbig             case 'u':
326169aa879SDirk Helbig                 usb_path_string = optarg;
327169aa879SDirk Helbig                 clear_argv( optind - 1 );
328169aa879SDirk Helbig                 clear_argv( optind - 2 );
329169aa879SDirk Helbig                 break;
330169aa879SDirk Helbig             case 'l':
331169aa879SDirk Helbig                 log_file_path = optarg;
332169aa879SDirk Helbig                 clear_argv( optind - 1 );
333169aa879SDirk Helbig                 clear_argv( optind - 2 );
334169aa879SDirk Helbig                 break;
335169aa879SDirk Helbig             case 'c':
336169aa879SDirk Helbig                 tlv_clear = true;
337169aa879SDirk Helbig                 clear_argv( optind - 1 );
338169aa879SDirk Helbig                 break;
339169aa879SDirk Helbig             case '?':
340169aa879SDirk Helbig             case 1:
341169aa879SDirk Helbig                 break;
342169aa879SDirk Helbig             case 'h':
343169aa879SDirk Helbig             default:
344169aa879SDirk Helbig                 usage(argv[0]);
345169aa879SDirk Helbig                 return EXIT_FAILURE;
346169aa879SDirk Helbig         }
347169aa879SDirk Helbig     }
348169aa879SDirk Helbig 
349169aa879SDirk Helbig     if (usb_path_string != NULL){
350a921db49SMatthias Ringwald         // parse command line options for "-u 11:22:33"
351a921db49SMatthias Ringwald         printf("Specified USB Path: ");
352a921db49SMatthias Ringwald         while (1){
353a921db49SMatthias Ringwald             char * delimiter;
354a921db49SMatthias Ringwald             int port = strtol(usb_path_string, &delimiter, 16);
355a921db49SMatthias Ringwald             usb_path[usb_path_len] = port;
356a921db49SMatthias Ringwald             usb_path_len++;
357a921db49SMatthias Ringwald             printf("%02x ", port);
358a921db49SMatthias Ringwald             if (!delimiter) break;
359a921db49SMatthias Ringwald             if (*delimiter != ':' && *delimiter != '-') break;
360a921db49SMatthias Ringwald             usb_path_string = delimiter+1;
361a921db49SMatthias Ringwald         }
362a921db49SMatthias Ringwald         printf("\n");
363a921db49SMatthias Ringwald     }
364a921db49SMatthias Ringwald 
365169aa879SDirk Helbig     // remove used up command line args
366169aa879SDirk Helbig     cleanup_argv();
367169aa879SDirk Helbig 
368a921db49SMatthias Ringwald     /// GET STARTED with BTstack ///
369a921db49SMatthias Ringwald     btstack_memory_init();
370a921db49SMatthias Ringwald     btstack_run_loop_init(btstack_run_loop_posix_get_instance());
371a921db49SMatthias Ringwald 
372a921db49SMatthias Ringwald     if (usb_path_len){
373a921db49SMatthias Ringwald         hci_transport_usb_set_path(usb_path_len, usb_path);
374a921db49SMatthias Ringwald     }
375a921db49SMatthias Ringwald 
376a921db49SMatthias Ringwald     // use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT
377a921db49SMatthias Ringwald     char pklg_path[100];
37854736c11SMatthias Ringwald     btstack_strcpy(pklg_path, sizeof(pklg_path),  "/tmp/hci_dump");
379a921db49SMatthias Ringwald     if (usb_path_len){
38054736c11SMatthias Ringwald         btstack_strcat(pklg_path, sizeof(pklg_path), "_");
38154736c11SMatthias Ringwald         btstack_strcat(pklg_path, sizeof(pklg_path), usb_path_string);
382a921db49SMatthias Ringwald     }
38354736c11SMatthias Ringwald     btstack_strcat(pklg_path, sizeof(pklg_path), ".pklg");
38431437b52SMatthias Ringwald 
385169aa879SDirk Helbig     // use path from command line if given
386713e3f72SDirk Helbig     if( log_file_path != NULL ){
387169aa879SDirk Helbig         btstack_strcpy(pklg_path, sizeof(pklg_path), log_file_path );
388713e3f72SDirk Helbig     }
389169aa879SDirk Helbig 
39031437b52SMatthias Ringwald     // log into file using HCI_DUMP_PACKETLOGGER format
39131437b52SMatthias Ringwald     hci_dump_posix_fs_open(pklg_path, HCI_DUMP_PACKETLOGGER);
39231437b52SMatthias Ringwald     hci_dump_init(hci_dump_posix_fs_get_instance());
393a921db49SMatthias Ringwald     printf("Packet Log: %s\n", pklg_path);
394a921db49SMatthias Ringwald 
395169aa879SDirk Helbig     // let the log contain the calling parameters
396169aa879SDirk Helbig     btstack_log_cmd_line( app_argc, app_argv );
397169aa879SDirk Helbig 
398a921db49SMatthias Ringwald     // init HCI
399a921db49SMatthias Ringwald     hci_init(hci_transport_usb_instance(), NULL);
400a921db49SMatthias Ringwald 
401a921db49SMatthias Ringwald #ifdef HAVE_PORTAUDIO
402a921db49SMatthias Ringwald     btstack_audio_sink_set_instance(btstack_audio_portaudio_sink_get_instance());
403a921db49SMatthias Ringwald     btstack_audio_source_set_instance(btstack_audio_portaudio_source_get_instance());
404a921db49SMatthias Ringwald #endif
405a921db49SMatthias Ringwald 
406a921db49SMatthias Ringwald     // inform about BTstack state
407a921db49SMatthias Ringwald     hci_event_callback_registration.callback = &packet_handler;
408a921db49SMatthias Ringwald     hci_add_event_handler(&hci_event_callback_registration);
409a921db49SMatthias Ringwald 
410a921db49SMatthias Ringwald     // handle CTRL-c
411a921db49SMatthias Ringwald     signal(SIGINT, sigint_handler);
412a921db49SMatthias Ringwald 
413a921db49SMatthias Ringwald     // setup app
414169aa879SDirk Helbig     btstack_main(app_argc, app_argv);
415a921db49SMatthias Ringwald 
416a921db49SMatthias Ringwald     // go
417a921db49SMatthias Ringwald     btstack_run_loop_execute();
418a921db49SMatthias Ringwald 
419a921db49SMatthias Ringwald     return 0;
420a921db49SMatthias Ringwald }
421