18caefee3SMatthias Ringwald /* 28caefee3SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 38caefee3SMatthias Ringwald * 48caefee3SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 58caefee3SMatthias Ringwald * modification, are permitted provided that the following conditions 68caefee3SMatthias Ringwald * are met: 78caefee3SMatthias Ringwald * 88caefee3SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 98caefee3SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 108caefee3SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 118caefee3SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 128caefee3SMatthias Ringwald * documentation and/or other materials provided with the distribution. 138caefee3SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 148caefee3SMatthias Ringwald * contributors may be used to endorse or promote products derived 158caefee3SMatthias Ringwald * from this software without specific prior written permission. 168caefee3SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 178caefee3SMatthias Ringwald * personal benefit and not for any commercial purpose or for 188caefee3SMatthias Ringwald * monetary gain. 198caefee3SMatthias Ringwald * 208caefee3SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 218caefee3SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 228caefee3SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 258caefee3SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 268caefee3SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 278caefee3SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 288caefee3SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 298caefee3SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 308caefee3SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318caefee3SMatthias Ringwald * SUCH DAMAGE. 328caefee3SMatthias Ringwald * 338caefee3SMatthias Ringwald * Please inquire about commercial licensing options at 348caefee3SMatthias Ringwald * [email protected] 358caefee3SMatthias Ringwald * 368caefee3SMatthias Ringwald */ 378caefee3SMatthias Ringwald 38f11fd9a9SMatthias Ringwald #define BTSTACK_FILE__ "main.c" 39ab2c6ae4SMatthias Ringwald 408caefee3SMatthias Ringwald // ***************************************************************************** 418caefee3SMatthias Ringwald // 428caefee3SMatthias Ringwald // minimal setup for HCI code 438caefee3SMatthias Ringwald // 448caefee3SMatthias Ringwald // ***************************************************************************** 458caefee3SMatthias Ringwald 460ad02723SMatthias Ringwald #include <getopt.h> 478caefee3SMatthias Ringwald #include <stdint.h> 488caefee3SMatthias Ringwald #include <stdio.h> 498caefee3SMatthias Ringwald #include <stdlib.h> 508caefee3SMatthias Ringwald #include <string.h> 51dbc40e82SMatthias Ringwald #include <signal.h> 528fb9c30cSMatthias Ringwald #include <unistd.h> 53*9d506991SMatthias Ringwald #include <hci_dump_posix_stdout.h> 548caefee3SMatthias Ringwald 557907f069SMatthias Ringwald #include "btstack_config.h" 568caefee3SMatthias Ringwald 57f11fd9a9SMatthias Ringwald #include "ble/le_device_db_tlv.h" 58f9563b89SMatthias Ringwald #include "bluetooth_company_id.h" 59f11fd9a9SMatthias Ringwald #include "btstack_audio.h" 60df9a25acSMatthias Ringwald #include "btstack_chipset_realtek.h" 61f11fd9a9SMatthias Ringwald #include "btstack_chipset_zephyr.h" 62a98592bcSMatthias Ringwald #include "btstack_debug.h" 63d356a6daSMatthias Ringwald #include "btstack_event.h" 64a98592bcSMatthias Ringwald #include "btstack_memory.h" 6582636622SMatthias Ringwald #include "btstack_run_loop.h" 66b7d596c1SMatthias Ringwald #include "btstack_run_loop_posix.h" 67f11fd9a9SMatthias Ringwald #include "btstack_signal.h" 68f11fd9a9SMatthias Ringwald #include "btstack_stdin.h" 69f11fd9a9SMatthias Ringwald #include "btstack_tlv_posix.h" 70f11fd9a9SMatthias Ringwald #include "classic/btstack_link_key_db_tlv.h" 718caefee3SMatthias Ringwald #include "hal_led.h" 728caefee3SMatthias Ringwald #include "hci.h" 738caefee3SMatthias Ringwald #include "hci_dump.h" 747435ec7bSMatthias Ringwald #include "hci_dump_posix_fs.h" 75c8dfe071SMatthias Ringwald #include "hci_transport.h" 76c8dfe071SMatthias Ringwald #include "hci_transport_usb.h" 7759bdfe96SMatthias Ringwald 7859bdfe96SMatthias Ringwald #define TLV_DB_PATH_PREFIX "/tmp/btstack_" 7959bdfe96SMatthias Ringwald #define TLV_DB_PATH_POSTFIX ".tlv" 8059bdfe96SMatthias Ringwald static char tlv_db_path[100]; 819faf05e8SMatthias Ringwald static bool tlv_reset; 8259bdfe96SMatthias Ringwald static const btstack_tlv_t * tlv_impl; 8359bdfe96SMatthias Ringwald static btstack_tlv_posix_t tlv_context; 8459bdfe96SMatthias Ringwald static bd_addr_t local_addr; 858caefee3SMatthias Ringwald 868caefee3SMatthias Ringwald int btstack_main(int argc, const char * argv[]); 878caefee3SMatthias Ringwald 88f9563b89SMatthias Ringwald static const uint8_t read_static_address_command_complete_prefix[] = { 0x0e, 0x1b, 0x01, 0x09, 0xfc }; 89f9563b89SMatthias Ringwald 90f9563b89SMatthias Ringwald static bd_addr_t static_address; 91f9563b89SMatthias Ringwald static int using_static_address; 92f9563b89SMatthias Ringwald 93d356a6daSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 94d356a6daSMatthias Ringwald 95f11fd9a9SMatthias Ringwald // shutdown 96f11fd9a9SMatthias Ringwald static bool shutdown_triggered; 97f11fd9a9SMatthias Ringwald 98f9563b89SMatthias Ringwald static void local_version_information_handler(uint8_t * packet){ 99f9563b89SMatthias Ringwald printf("Local version information:\n"); 100f9563b89SMatthias Ringwald uint16_t hci_version = packet[6]; 101f9563b89SMatthias Ringwald uint16_t hci_revision = little_endian_read_16(packet, 7); 102f9563b89SMatthias Ringwald uint16_t lmp_version = packet[9]; 103f9563b89SMatthias Ringwald uint16_t manufacturer = little_endian_read_16(packet, 10); 104f9563b89SMatthias Ringwald uint16_t lmp_subversion = little_endian_read_16(packet, 12); 105f9563b89SMatthias Ringwald printf("- HCI Version 0x%04x\n", hci_version); 106f9563b89SMatthias Ringwald printf("- HCI Revision 0x%04x\n", hci_revision); 107f9563b89SMatthias Ringwald printf("- LMP Version 0x%04x\n", lmp_version); 108f9563b89SMatthias Ringwald printf("- LMP Subversion 0x%04x\n", lmp_subversion); 109f9563b89SMatthias Ringwald printf("- Manufacturer 0x%04x\n", manufacturer); 110f9563b89SMatthias Ringwald switch (manufacturer){ 111f9563b89SMatthias Ringwald case BLUETOOTH_COMPANY_ID_THE_LINUX_FOUNDATION: 112f4ab4581SMatthias Ringwald printf("- Linux Foundation - assume Zephyr hci_usb firmware running on nRF52xx\n"); 113f4ab4581SMatthias Ringwald // setup Zephyr chipset support 114f9563b89SMatthias Ringwald hci_set_chipset(btstack_chipset_zephyr_instance()); 115f4ab4581SMatthias Ringwald // sm required to setup static random Bluetooth address 116f4ab4581SMatthias Ringwald sm_init(); 117f9563b89SMatthias Ringwald break; 118df9a25acSMatthias Ringwald case BLUETOOTH_COMPANY_ID_REALTEK_SEMICONDUCTOR_CORPORATION: 119df9a25acSMatthias Ringwald printf("- Realtek controller - provide firmware and config\n"); 120df9a25acSMatthias Ringwald btstack_chipset_realtek_set_lmp_subversion(lmp_subversion); 121df9a25acSMatthias Ringwald hci_set_chipset(btstack_chipset_realtek_instance()); 122df9a25acSMatthias Ringwald break; 123f9563b89SMatthias Ringwald default: 124f9563b89SMatthias Ringwald break; 125f9563b89SMatthias Ringwald } 126f9563b89SMatthias Ringwald } 127f9563b89SMatthias Ringwald 128d356a6daSMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1299ec2630cSMatthias Ringwald UNUSED(channel); 1309ec2630cSMatthias Ringwald UNUSED(size); 13124a31dc7SMatthias Ringwald uint8_t i; 13224a31dc7SMatthias Ringwald uint8_t usb_path_len; 13324a31dc7SMatthias Ringwald const uint8_t * usb_path; 134df9a25acSMatthias Ringwald uint16_t product_id; 13524a31dc7SMatthias Ringwald 136d356a6daSMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 13724a31dc7SMatthias Ringwald 13859bdfe96SMatthias Ringwald switch (hci_event_packet_get_type(packet)){ 13924a31dc7SMatthias Ringwald case HCI_EVENT_TRANSPORT_USB_INFO: 14024a31dc7SMatthias Ringwald usb_path_len = hci_event_transport_usb_info_get_path_len(packet); 14124a31dc7SMatthias Ringwald usb_path = hci_event_transport_usb_info_get_path(packet); 14224a31dc7SMatthias Ringwald // print device path 143df9a25acSMatthias Ringwald product_id = hci_event_transport_usb_info_get_product_id(packet); 14424a31dc7SMatthias Ringwald printf("USB device 0x%04x/0x%04x, path: ", 145df9a25acSMatthias Ringwald hci_event_transport_usb_info_get_vendor_id(packet), product_id); 14624a31dc7SMatthias Ringwald for (i=0;i<usb_path_len;i++){ 14724a31dc7SMatthias Ringwald if (i) printf("-"); 14824a31dc7SMatthias Ringwald printf("%02x", usb_path[i]); 14924a31dc7SMatthias Ringwald } 15024a31dc7SMatthias Ringwald printf("\n"); 151df9a25acSMatthias Ringwald // set Product ID for Realtek Controllers 152df9a25acSMatthias Ringwald btstack_chipset_realtek_set_product_id(product_id); 15324a31dc7SMatthias Ringwald break; 15459bdfe96SMatthias Ringwald case BTSTACK_EVENT_STATE: 155d7b77a0cSMatthias Ringwald switch (btstack_event_state_get_state(packet)){ 156d7b77a0cSMatthias Ringwald case HCI_STATE_WORKING: 15759bdfe96SMatthias Ringwald gap_local_bd_addr(local_addr); 158f9563b89SMatthias Ringwald if (using_static_address){ 159f9563b89SMatthias Ringwald memcpy(local_addr, static_address, 6); 160f9563b89SMatthias Ringwald } 16154736c11SMatthias Ringwald btstack_strcpy(tlv_db_path, sizeof(tlv_db_path), TLV_DB_PATH_PREFIX); 16254736c11SMatthias Ringwald btstack_strcat(tlv_db_path, sizeof(tlv_db_path), bd_addr_to_str_with_delimiter(local_addr, '-')); 16354736c11SMatthias Ringwald btstack_strcat(tlv_db_path, sizeof(tlv_db_path), TLV_DB_PATH_POSTFIX); 1649faf05e8SMatthias Ringwald printf("TLV path: %s", tlv_db_path); 1659faf05e8SMatthias Ringwald if (tlv_reset){ 1669faf05e8SMatthias Ringwald int rc = unlink(tlv_db_path); 1679faf05e8SMatthias Ringwald if (rc == 0) { 1689faf05e8SMatthias Ringwald printf(", reset ok"); 1699faf05e8SMatthias Ringwald } else { 1709faf05e8SMatthias Ringwald printf(", reset failed with result = %d", rc); 1719faf05e8SMatthias Ringwald } 1729faf05e8SMatthias Ringwald } 1739faf05e8SMatthias Ringwald printf("\n"); 17459bdfe96SMatthias Ringwald tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path); 17559bdfe96SMatthias Ringwald btstack_tlv_set_instance(tlv_impl, &tlv_context); 17681862996SMatthias Ringwald #ifdef ENABLE_CLASSIC 17781862996SMatthias Ringwald hci_set_link_key_db(btstack_link_key_db_tlv_get_instance(tlv_impl, &tlv_context)); 17881862996SMatthias Ringwald #endif 17981862996SMatthias Ringwald #ifdef ENABLE_BLE 18081862996SMatthias Ringwald le_device_db_tlv_configure(tlv_impl, &tlv_context); 18181862996SMatthias Ringwald #endif 1829faf05e8SMatthias Ringwald printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); 18359bdfe96SMatthias Ringwald break; 184d7b77a0cSMatthias Ringwald case HCI_STATE_OFF: 185d7b77a0cSMatthias Ringwald btstack_tlv_posix_deinit(&tlv_context); 186f11fd9a9SMatthias Ringwald if (!shutdown_triggered) break; 187f11fd9a9SMatthias Ringwald // reset stdin 188f11fd9a9SMatthias Ringwald btstack_stdin_reset(); 189f11fd9a9SMatthias Ringwald log_info("Good bye, see you.\n"); 190f11fd9a9SMatthias Ringwald exit(0); 191d7b77a0cSMatthias Ringwald break; 192d7b77a0cSMatthias Ringwald default: 193d7b77a0cSMatthias Ringwald break; 194d7b77a0cSMatthias Ringwald } 195d7b77a0cSMatthias Ringwald break; 196f9563b89SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 197d39264f2SMatthias Ringwald if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION){ 198f9563b89SMatthias Ringwald local_version_information_handler(packet); 199f9563b89SMatthias Ringwald } 200f9563b89SMatthias Ringwald if (memcmp(packet, read_static_address_command_complete_prefix, sizeof(read_static_address_command_complete_prefix)) == 0){ 201f9563b89SMatthias Ringwald reverse_48(&packet[7], static_address); 202f9563b89SMatthias Ringwald gap_random_address_set(static_address); 203f9563b89SMatthias Ringwald using_static_address = 1; 204f9563b89SMatthias Ringwald } 205f9563b89SMatthias Ringwald break; 20659bdfe96SMatthias Ringwald default: 20759bdfe96SMatthias Ringwald break; 20859bdfe96SMatthias Ringwald } 209d356a6daSMatthias Ringwald } 210d356a6daSMatthias Ringwald 211f11fd9a9SMatthias Ringwald static void trigger_shutdown(void){ 212b96c8f44SMatthias Ringwald printf("CTRL-C - SIGINT received, shutting down..\n"); 213b96c8f44SMatthias Ringwald log_info("sigint_handler: shutting down"); 214f11fd9a9SMatthias Ringwald shutdown_triggered = true; 2158caefee3SMatthias Ringwald hci_power_control(HCI_POWER_OFF); 2168caefee3SMatthias Ringwald } 2178caefee3SMatthias Ringwald 2188caefee3SMatthias Ringwald static int led_state = 0; 2190ad02723SMatthias Ringwald 2208caefee3SMatthias Ringwald void hal_led_toggle(void){ 2218caefee3SMatthias Ringwald led_state = 1 - led_state; 2228caefee3SMatthias Ringwald printf("LED State %u\n", led_state); 2238caefee3SMatthias Ringwald } 2248caefee3SMatthias Ringwald 2259faf05e8SMatthias Ringwald static char short_options[] = "hu:l:r"; 2260ad02723SMatthias Ringwald 2270ad02723SMatthias Ringwald static struct option long_options[] = { 2280ad02723SMatthias Ringwald {"help", no_argument, NULL, 'h'}, 229834e96b3SMatthias Ringwald {"logfile", required_argument, NULL, 'l'}, 2309faf05e8SMatthias Ringwald {"reset-tlv", no_argument, NULL, 'r'}, 2310ad02723SMatthias Ringwald {"usbpath", required_argument, NULL, 'u'}, 2320ad02723SMatthias Ringwald {0, 0, 0, 0} 2330ad02723SMatthias Ringwald }; 2340ad02723SMatthias Ringwald 2350ad02723SMatthias Ringwald static char *help_options[] = { 2360ad02723SMatthias Ringwald "print (this) help.", 237834e96b3SMatthias Ringwald "set file to store debug output and HCI trace.", 2389faf05e8SMatthias Ringwald "reset bonding information stored in TLV.", 2390ad02723SMatthias Ringwald "set USB path to Bluetooth Controller.", 2400ad02723SMatthias Ringwald }; 2410ad02723SMatthias Ringwald 2420ad02723SMatthias Ringwald static char *option_arg_name[] = { 2430ad02723SMatthias Ringwald "", 244834e96b3SMatthias Ringwald "LOGFILE", 2459faf05e8SMatthias Ringwald "", 2460ad02723SMatthias Ringwald "USBPATH", 2470ad02723SMatthias Ringwald }; 2480ad02723SMatthias Ringwald 2490ad02723SMatthias Ringwald static void usage(const char *name){ 2500ad02723SMatthias Ringwald unsigned int i; 2510ad02723SMatthias Ringwald printf( "usage:\n\t%s [options]\n", name ); 2520ad02723SMatthias Ringwald printf("valid options:\n"); 2530ad02723SMatthias Ringwald for( i=0; long_options[i].name != 0; i++) { 2540ad02723SMatthias Ringwald printf("--%-10s| -%c %-10s\t\t%s\n", long_options[i].name, long_options[i].val, option_arg_name[i], help_options[i] ); 2550ad02723SMatthias Ringwald } 2560ad02723SMatthias Ringwald } 2570ad02723SMatthias Ringwald 258e13e7f54SMatthias Ringwald #define USB_MAX_PATH_LEN 7 2598caefee3SMatthias Ringwald int main(int argc, const char * argv[]){ 2608caefee3SMatthias Ringwald 261e13e7f54SMatthias Ringwald uint8_t usb_path[USB_MAX_PATH_LEN]; 262e13e7f54SMatthias Ringwald int usb_path_len = 0; 263fb34235aSMatthias Ringwald const char * usb_path_string = NULL; 264834e96b3SMatthias Ringwald const char * log_file_path = NULL; 2650ad02723SMatthias Ringwald 2660ad02723SMatthias Ringwald // parse command line parameters 2670ad02723SMatthias Ringwald while(true){ 2680ad02723SMatthias Ringwald int c = getopt_long( argc, (char* const *)argv, short_options, long_options, NULL ); 2690ad02723SMatthias Ringwald if (c < 0) { 2700ad02723SMatthias Ringwald break; 2710ad02723SMatthias Ringwald } 2720ad02723SMatthias Ringwald switch (c) { 2730ad02723SMatthias Ringwald case 'u': 274834e96b3SMatthias Ringwald usb_path_string = optarg; 275834e96b3SMatthias Ringwald break; 276834e96b3SMatthias Ringwald case 'l': 277834e96b3SMatthias Ringwald log_file_path = optarg; 2780ad02723SMatthias Ringwald break; 2799faf05e8SMatthias Ringwald case 'r': 2809faf05e8SMatthias Ringwald tlv_reset = true; 2819faf05e8SMatthias Ringwald break; 2820ad02723SMatthias Ringwald case '?': 2830ad02723SMatthias Ringwald case 'h': 2840ad02723SMatthias Ringwald default: 2850ad02723SMatthias Ringwald usage(argv[0]); 2860ad02723SMatthias Ringwald return EXIT_FAILURE; 2870ad02723SMatthias Ringwald } 2880ad02723SMatthias Ringwald } 2890ad02723SMatthias Ringwald 2900ad02723SMatthias Ringwald if (usb_path_string != NULL){ 2910ad02723SMatthias Ringwald // parse command line options for "-u 11:22:33" 292e13e7f54SMatthias Ringwald printf("Specified USB Path: "); 293e13e7f54SMatthias Ringwald while (1){ 294e13e7f54SMatthias Ringwald char * delimiter; 295fb34235aSMatthias Ringwald int port = strtol(usb_path_string, &delimiter, 16); 296e13e7f54SMatthias Ringwald usb_path[usb_path_len] = port; 297e13e7f54SMatthias Ringwald usb_path_len++; 298e13e7f54SMatthias Ringwald printf("%02x ", port); 299e13e7f54SMatthias Ringwald if (!delimiter) break; 300a4c4a5d6SMatthias Ringwald if (*delimiter != ':' && *delimiter != '-') break; 301fb34235aSMatthias Ringwald usb_path_string = delimiter+1; 302e13e7f54SMatthias Ringwald } 303e13e7f54SMatthias Ringwald printf("\n"); 304e13e7f54SMatthias Ringwald } 305e13e7f54SMatthias Ringwald 3068caefee3SMatthias Ringwald /// GET STARTED with BTstack /// 3078caefee3SMatthias Ringwald btstack_memory_init(); 308528a4a3bSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance()); 3098caefee3SMatthias Ringwald 310e13e7f54SMatthias Ringwald if (usb_path_len){ 311e13e7f54SMatthias Ringwald hci_transport_usb_set_path(usb_path_len, usb_path); 312e13e7f54SMatthias Ringwald } 313e13e7f54SMatthias Ringwald 3147435ec7bSMatthias Ringwald // log into file using HCI_DUMP_PACKETLOGGER format 31502065453SMatthias Ringwald char pklg_path[100]; 316a94ee701SMatthias Ringwald if (log_file_path == NULL){ 31754736c11SMatthias Ringwald btstack_strcpy(pklg_path, sizeof(pklg_path), "/tmp/hci_dump"); 31802065453SMatthias Ringwald if (usb_path_len){ 31954736c11SMatthias Ringwald btstack_strcat(pklg_path, sizeof(pklg_path), "_"); 32054736c11SMatthias Ringwald btstack_strcat(pklg_path, sizeof(pklg_path), usb_path_string); 32102065453SMatthias Ringwald } 32254736c11SMatthias Ringwald btstack_strcat(pklg_path, sizeof(pklg_path), ".pklg"); 323834e96b3SMatthias Ringwald log_file_path = pklg_path; 324834e96b3SMatthias Ringwald } 325834e96b3SMatthias Ringwald 326834e96b3SMatthias Ringwald hci_dump_posix_fs_open(log_file_path, HCI_DUMP_PACKETLOGGER); 3277435ec7bSMatthias Ringwald const hci_dump_t * hci_dump_impl = hci_dump_posix_fs_get_instance(); 3287435ec7bSMatthias Ringwald hci_dump_init(hci_dump_impl); 329834e96b3SMatthias Ringwald printf("Packet Log: %s\n", log_file_path); 3308caefee3SMatthias Ringwald 3318caefee3SMatthias Ringwald // init HCI 3322d5e09d6SMatthias Ringwald hci_init(hci_transport_usb_instance(), NULL); 33335454696SMatthias Ringwald 334e739af98SMatthias Ringwald #ifdef HAVE_PORTAUDIO 3353d3351f3SMatthias Ringwald btstack_audio_sink_set_instance(btstack_audio_portaudio_sink_get_instance()); 3363d3351f3SMatthias Ringwald btstack_audio_source_set_instance(btstack_audio_portaudio_source_get_instance()); 337e739af98SMatthias Ringwald #endif 338e739af98SMatthias Ringwald 339d356a6daSMatthias Ringwald // inform about BTstack state 340d356a6daSMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 341d356a6daSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 342d356a6daSMatthias Ringwald 343f11fd9a9SMatthias Ringwald // register callback for CTRL-c 344f11fd9a9SMatthias Ringwald btstack_signal_register_callback(SIGINT, &trigger_shutdown); 3458caefee3SMatthias Ringwald 346df9a25acSMatthias Ringwald // register known Realtek USB Controllers 347df9a25acSMatthias Ringwald uint16_t realtek_num_controllers = btstack_chipset_realtek_get_num_usb_controllers(); 348df9a25acSMatthias Ringwald uint16_t i; 349df9a25acSMatthias Ringwald for (i=0;i<realtek_num_controllers;i++){ 350df9a25acSMatthias Ringwald uint16_t vendor_id; 351df9a25acSMatthias Ringwald uint16_t product_id; 352df9a25acSMatthias Ringwald btstack_chipset_realtek_get_vendor_product_id(i, &vendor_id, &product_id); 353df9a25acSMatthias Ringwald hci_transport_usb_add_device(vendor_id, product_id); 354df9a25acSMatthias Ringwald } 355df9a25acSMatthias Ringwald 3568caefee3SMatthias Ringwald // setup app 3578caefee3SMatthias Ringwald btstack_main(argc, argv); 3588caefee3SMatthias Ringwald 3598caefee3SMatthias Ringwald // go 360528a4a3bSMatthias Ringwald btstack_run_loop_execute(); 3618caefee3SMatthias Ringwald 3628caefee3SMatthias Ringwald return 0; 3638caefee3SMatthias Ringwald } 364