1*10277393SMatthias Ringwald /* 2*10277393SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*10277393SMatthias Ringwald * 4*10277393SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*10277393SMatthias Ringwald * modification, are permitted provided that the following conditions 6*10277393SMatthias Ringwald * are met: 7*10277393SMatthias Ringwald * 8*10277393SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*10277393SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*10277393SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*10277393SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*10277393SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*10277393SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*10277393SMatthias Ringwald * contributors may be used to endorse or promote products derived 15*10277393SMatthias Ringwald * from this software without specific prior written permission. 16*10277393SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*10277393SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*10277393SMatthias Ringwald * monetary gain. 19*10277393SMatthias Ringwald * 20*10277393SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*10277393SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*10277393SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*10277393SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*10277393SMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*10277393SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*10277393SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*10277393SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*10277393SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*10277393SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*10277393SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*10277393SMatthias Ringwald * SUCH DAMAGE. 32*10277393SMatthias Ringwald * 33*10277393SMatthias Ringwald * Please inquire about commercial licensing options at 34*10277393SMatthias Ringwald * [email protected] 35*10277393SMatthias Ringwald * 36*10277393SMatthias Ringwald */ 37*10277393SMatthias Ringwald 38*10277393SMatthias Ringwald #define BTSTACK_FILE__ "main.c" 39*10277393SMatthias Ringwald 40*10277393SMatthias Ringwald // ***************************************************************************** 41*10277393SMatthias Ringwald // 42*10277393SMatthias Ringwald // minimal setup for HCI code 43*10277393SMatthias Ringwald // 44*10277393SMatthias Ringwald // ***************************************************************************** 45*10277393SMatthias Ringwald 46*10277393SMatthias Ringwald #include <stdint.h> 47*10277393SMatthias Ringwald #include <stdio.h> 48*10277393SMatthias Ringwald #include <stdlib.h> 49*10277393SMatthias Ringwald #include <string.h> 50*10277393SMatthias Ringwald #include <signal.h> 51*10277393SMatthias Ringwald 52*10277393SMatthias Ringwald #include "btstack_config.h" 53*10277393SMatthias Ringwald 54*10277393SMatthias Ringwald #include "ble/le_device_db_tlv.h" 55*10277393SMatthias Ringwald #include "bluetooth_company_id.h" 56*10277393SMatthias Ringwald #include "btstack_audio.h" 57*10277393SMatthias Ringwald #include "btstack_debug.h" 58*10277393SMatthias Ringwald #include "btstack_event.h" 59*10277393SMatthias Ringwald #include "btstack_memory.h" 60*10277393SMatthias Ringwald #include "btstack_run_loop.h" 61*10277393SMatthias Ringwald #include "btstack_run_loop_posix.h" 62*10277393SMatthias Ringwald #include "btstack_signal.h" 63*10277393SMatthias Ringwald #include "btstack_stdin.h" 64*10277393SMatthias Ringwald #include "btstack_tlv_posix.h" 65*10277393SMatthias Ringwald #include "btstack_uart.h" 66*10277393SMatthias Ringwald #include "classic/btstack_link_key_db_tlv.h" 67*10277393SMatthias Ringwald #include "hci.h" 68*10277393SMatthias Ringwald #include "hci_dump.h" 69*10277393SMatthias Ringwald #include "hci_dump_posix_fs.h" 70*10277393SMatthias Ringwald #include "hci_transport.h" 71*10277393SMatthias Ringwald #include "hci_transport_h4.h" 72*10277393SMatthias Ringwald 73*10277393SMatthias Ringwald 74*10277393SMatthias Ringwald #define TLV_DB_PATH_PREFIX "/tmp/btstack_" 75*10277393SMatthias Ringwald #define TLV_DB_PATH_POSTFIX ".tlv" 76*10277393SMatthias Ringwald static char tlv_db_path[100]; 77*10277393SMatthias Ringwald static const btstack_tlv_t * tlv_impl; 78*10277393SMatthias Ringwald static btstack_tlv_posix_t tlv_context; 79*10277393SMatthias Ringwald static bd_addr_t local_addr; 80*10277393SMatthias Ringwald 81*10277393SMatthias Ringwald static int is_bcm; 82*10277393SMatthias Ringwald // shutdown 83*10277393SMatthias Ringwald static bool shutdown_triggered; 84*10277393SMatthias Ringwald 85*10277393SMatthias Ringwald int btstack_main(int argc, const char * argv[]); 86*10277393SMatthias Ringwald static void local_version_information_handler(uint8_t * packet); 87*10277393SMatthias Ringwald 88*10277393SMatthias Ringwald static hci_transport_config_uart_t config = { 89*10277393SMatthias Ringwald HCI_TRANSPORT_CONFIG_UART, 90*10277393SMatthias Ringwald 115200, 91*10277393SMatthias Ringwald 0, // main baudrate 92*10277393SMatthias Ringwald 1, // flow control 93*10277393SMatthias Ringwald NULL, 94*10277393SMatthias Ringwald }; 95*10277393SMatthias Ringwald 96*10277393SMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 97*10277393SMatthias Ringwald 98*10277393SMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 99*10277393SMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 100*10277393SMatthias Ringwald switch (hci_event_packet_get_type(packet)){ 101*10277393SMatthias Ringwald case BTSTACK_EVENT_STATE: 102*10277393SMatthias Ringwald switch(btstack_event_state_get_state(packet)){ 103*10277393SMatthias Ringwald case HCI_STATE_WORKING: 104*10277393SMatthias Ringwald gap_local_bd_addr(local_addr); 105*10277393SMatthias Ringwald printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); 106*10277393SMatthias Ringwald strcpy(tlv_db_path, TLV_DB_PATH_PREFIX); 107*10277393SMatthias Ringwald strcat(tlv_db_path, bd_addr_to_str(local_addr)); 108*10277393SMatthias Ringwald strcat(tlv_db_path, TLV_DB_PATH_POSTFIX); 109*10277393SMatthias Ringwald tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path); 110*10277393SMatthias Ringwald btstack_tlv_set_instance(tlv_impl, &tlv_context); 111*10277393SMatthias Ringwald #ifdef ENABLE_CLASSIC 112*10277393SMatthias Ringwald hci_set_link_key_db(btstack_link_key_db_tlv_get_instance(tlv_impl, &tlv_context)); 113*10277393SMatthias Ringwald #endif 114*10277393SMatthias Ringwald #ifdef ENABLE_BLE 115*10277393SMatthias Ringwald le_device_db_tlv_configure(tlv_impl, &tlv_context); 116*10277393SMatthias Ringwald #endif 117*10277393SMatthias Ringwald break; 118*10277393SMatthias Ringwald case HCI_STATE_OFF: 119*10277393SMatthias Ringwald btstack_tlv_posix_deinit(&tlv_context); 120*10277393SMatthias Ringwald if (!shutdown_triggered) break; 121*10277393SMatthias Ringwald // reset stdin 122*10277393SMatthias Ringwald btstack_stdin_reset(); 123*10277393SMatthias Ringwald log_info("Good bye, see you.\n"); 124*10277393SMatthias Ringwald exit(0); 125*10277393SMatthias Ringwald break; 126*10277393SMatthias Ringwald default: 127*10277393SMatthias Ringwald break; 128*10277393SMatthias Ringwald } 129*10277393SMatthias Ringwald break; 130*10277393SMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 131*10277393SMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)){ 132*10277393SMatthias Ringwald if (hci_event_command_complete_get_return_parameters(packet)[0]) break; 133*10277393SMatthias Ringwald // terminate, name 248 chars 134*10277393SMatthias Ringwald packet[6+248] = 0; 135*10277393SMatthias Ringwald printf("Local name: %s\n", &packet[6]); 136*10277393SMatthias Ringwald } 137*10277393SMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)){ 138*10277393SMatthias Ringwald local_version_information_handler(packet); 139*10277393SMatthias Ringwald } 140*10277393SMatthias Ringwald break; 141*10277393SMatthias Ringwald default: 142*10277393SMatthias Ringwald break; 143*10277393SMatthias Ringwald } 144*10277393SMatthias Ringwald } 145*10277393SMatthias Ringwald 146*10277393SMatthias Ringwald static void trigger_shutdown(void){ 147*10277393SMatthias Ringwald printf("CTRL-C - SIGINT received, shutting down..\n"); 148*10277393SMatthias Ringwald log_info("sigint_handler: shutting down"); 149*10277393SMatthias Ringwald shutdown_triggered = true; 150*10277393SMatthias Ringwald hci_power_control(HCI_POWER_OFF); 151*10277393SMatthias Ringwald } 152*10277393SMatthias Ringwald 153*10277393SMatthias Ringwald static int led_state = 0; 154*10277393SMatthias Ringwald void hal_led_toggle(void){ 155*10277393SMatthias Ringwald led_state = 1 - led_state; 156*10277393SMatthias Ringwald printf("LED State %u\n", led_state); 157*10277393SMatthias Ringwald } 158*10277393SMatthias Ringwald 159*10277393SMatthias Ringwald static void local_version_information_handler(uint8_t * packet){ 160*10277393SMatthias Ringwald printf("Local version information:\n"); 161*10277393SMatthias Ringwald uint16_t hci_version = packet[6]; 162*10277393SMatthias Ringwald uint16_t hci_revision = little_endian_read_16(packet, 7); 163*10277393SMatthias Ringwald uint16_t lmp_version = packet[9]; 164*10277393SMatthias Ringwald uint16_t manufacturer = little_endian_read_16(packet, 10); 165*10277393SMatthias Ringwald uint16_t lmp_subversion = little_endian_read_16(packet, 12); 166*10277393SMatthias Ringwald printf("- HCI Version 0x%04x\n", hci_version); 167*10277393SMatthias Ringwald printf("- HCI Revision 0x%04x\n", hci_revision); 168*10277393SMatthias Ringwald printf("- LMP Version 0x%04x\n", lmp_version); 169*10277393SMatthias Ringwald printf("- LMP Subversion 0x%04x\n", lmp_subversion); 170*10277393SMatthias Ringwald printf("- Manufacturer 0x%04x\n", manufacturer); 171*10277393SMatthias Ringwald switch (manufacturer){ 172*10277393SMatthias Ringwald case BLUETOOTH_COMPANY_ID_PACKETCRAFT_INC: 173*10277393SMatthias Ringwald printf("PacketCraft HCI Controller\n"); 174*10277393SMatthias Ringwald break; 175*10277393SMatthias Ringwald default: 176*10277393SMatthias Ringwald printf("Unknown manufacturer / manufacturer not supported yet.\n"); 177*10277393SMatthias Ringwald break; 178*10277393SMatthias Ringwald } 179*10277393SMatthias Ringwald } 180*10277393SMatthias Ringwald 181*10277393SMatthias Ringwald int main(int argc, const char * argv[]){ 182*10277393SMatthias Ringwald 183*10277393SMatthias Ringwald /// GET STARTED with BTstack /// 184*10277393SMatthias Ringwald btstack_memory_init(); 185*10277393SMatthias Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance()); 186*10277393SMatthias Ringwald 187*10277393SMatthias Ringwald 188*10277393SMatthias Ringwald // pre-select serial device 189*10277393SMatthias Ringwald config.device_name = "/dev/tty.usbmodemD5D5237DC25B1"; // BL654 with PTS Firmware 190*10277393SMatthias Ringwald 191*10277393SMatthias Ringwald // accept path from command line 192*10277393SMatthias Ringwald bool second_device = false; 193*10277393SMatthias Ringwald if (argc >= 3 && strcmp(argv[1], "-u") == 0){ 194*10277393SMatthias Ringwald config.device_name = argv[2]; 195*10277393SMatthias Ringwald second_device = true; 196*10277393SMatthias Ringwald argc -= 2; 197*10277393SMatthias Ringwald memmove(&argv[1], &argv[3], (argc-1) * sizeof(char *)); 198*10277393SMatthias Ringwald } 199*10277393SMatthias Ringwald printf("H4 device: %s\n", config.device_name); 200*10277393SMatthias Ringwald 201*10277393SMatthias Ringwald // log into file using HCI_DUMP_BTSNOOP format 202*10277393SMatthias Ringwald char * pklg_path = "/tmp/hci_dump.btsnoop"; 203*10277393SMatthias Ringwald if (second_device){ 204*10277393SMatthias Ringwald pklg_path = "/tmp/hci_dump2.btsnoop"; 205*10277393SMatthias Ringwald } 206*10277393SMatthias Ringwald hci_dump_posix_fs_open(pklg_path, HCI_DUMP_BTSNOOP); 207*10277393SMatthias Ringwald const hci_dump_t * hci_dump_impl = hci_dump_posix_fs_get_instance(); 208*10277393SMatthias Ringwald hci_dump_init(hci_dump_impl); 209*10277393SMatthias Ringwald printf("Packet Log: %s\n", pklg_path); 210*10277393SMatthias Ringwald 211*10277393SMatthias Ringwald // init HCI 212*10277393SMatthias Ringwald const btstack_uart_t * uart_driver = btstack_uart_posix_instance(); 213*10277393SMatthias Ringwald const hci_transport_t * transport = hci_transport_h4_instance_for_uart(uart_driver); 214*10277393SMatthias Ringwald hci_init(transport, (void*) &config); 215*10277393SMatthias Ringwald 216*10277393SMatthias Ringwald #ifdef HAVE_PORTAUDIO 217*10277393SMatthias Ringwald btstack_audio_sink_set_instance(btstack_audio_portaudio_sink_get_instance()); 218*10277393SMatthias Ringwald btstack_audio_source_set_instance(btstack_audio_portaudio_source_get_instance()); 219*10277393SMatthias Ringwald #endif 220*10277393SMatthias Ringwald 221*10277393SMatthias Ringwald // inform about BTstack state 222*10277393SMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 223*10277393SMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 224*10277393SMatthias Ringwald 225*10277393SMatthias Ringwald // register callback for CTRL-c 226*10277393SMatthias Ringwald btstack_signal_register_callback(SIGINT, &trigger_shutdown); 227*10277393SMatthias Ringwald 228*10277393SMatthias Ringwald // setup app 229*10277393SMatthias Ringwald btstack_main(argc, argv); 230*10277393SMatthias Ringwald 231*10277393SMatthias Ringwald // go 232*10277393SMatthias Ringwald btstack_run_loop_execute(); 233*10277393SMatthias Ringwald 234*10277393SMatthias Ringwald return 0; 235*10277393SMatthias Ringwald } 236