1*1182cb7eSMatthias Ringwald /* 2*1182cb7eSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*1182cb7eSMatthias Ringwald * 4*1182cb7eSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*1182cb7eSMatthias Ringwald * modification, are permitted provided that the following conditions 6*1182cb7eSMatthias Ringwald * are met: 7*1182cb7eSMatthias Ringwald * 8*1182cb7eSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*1182cb7eSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*1182cb7eSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*1182cb7eSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*1182cb7eSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*1182cb7eSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*1182cb7eSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*1182cb7eSMatthias Ringwald * from this software without specific prior written permission. 16*1182cb7eSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*1182cb7eSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*1182cb7eSMatthias Ringwald * monetary gain. 19*1182cb7eSMatthias Ringwald * 20*1182cb7eSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*1182cb7eSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*1182cb7eSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*1182cb7eSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*1182cb7eSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*1182cb7eSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*1182cb7eSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*1182cb7eSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*1182cb7eSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*1182cb7eSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*1182cb7eSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*1182cb7eSMatthias Ringwald * SUCH DAMAGE. 32*1182cb7eSMatthias Ringwald * 33*1182cb7eSMatthias Ringwald * Please inquire about commercial licensing options at 34*1182cb7eSMatthias Ringwald * [email protected] 35*1182cb7eSMatthias Ringwald * 36*1182cb7eSMatthias Ringwald */ 37*1182cb7eSMatthias Ringwald 38*1182cb7eSMatthias Ringwald #define __BTSTACK_FILE__ "main.c" 39*1182cb7eSMatthias Ringwald 40*1182cb7eSMatthias Ringwald // ***************************************************************************** 41*1182cb7eSMatthias Ringwald // 42*1182cb7eSMatthias Ringwald // minimal setup for HCI code 43*1182cb7eSMatthias Ringwald // 44*1182cb7eSMatthias Ringwald // ***************************************************************************** 45*1182cb7eSMatthias Ringwald 46*1182cb7eSMatthias Ringwald #include <stdint.h> 47*1182cb7eSMatthias Ringwald #include <stdio.h> 48*1182cb7eSMatthias Ringwald #include <stdlib.h> 49*1182cb7eSMatthias Ringwald #include <string.h> 50*1182cb7eSMatthias Ringwald #include <signal.h> 51*1182cb7eSMatthias Ringwald 52*1182cb7eSMatthias Ringwald #include "btstack_config.h" 53*1182cb7eSMatthias Ringwald 54*1182cb7eSMatthias Ringwald #include "bluetooth_company_id.h" 55*1182cb7eSMatthias Ringwald #include "ble/le_device_db_tlv.h" 56*1182cb7eSMatthias Ringwald #include "btstack_chipset_bcm.h" 57*1182cb7eSMatthias Ringwald #include "btstack_chipset_bcm_download_firmware.h" 58*1182cb7eSMatthias Ringwald #include "btstack_debug.h" 59*1182cb7eSMatthias Ringwald #include "btstack_event.h" 60*1182cb7eSMatthias Ringwald #include "btstack_memory.h" 61*1182cb7eSMatthias Ringwald #include "btstack_run_loop.h" 62*1182cb7eSMatthias Ringwald #include "btstack_run_loop_posix.h" 63*1182cb7eSMatthias Ringwald #include "btstack_stdin.h" 64*1182cb7eSMatthias Ringwald #include "btstack_uart.h" 65*1182cb7eSMatthias Ringwald #include "btstack_tlv_posix.h" 66*1182cb7eSMatthias Ringwald #include "classic/btstack_link_key_db_tlv.h" 67*1182cb7eSMatthias Ringwald #include "hci.h" 68*1182cb7eSMatthias Ringwald #include "hci_dump.h" 69*1182cb7eSMatthias Ringwald 70*1182cb7eSMatthias Ringwald 71*1182cb7eSMatthias Ringwald int btstack_main(int argc, const char * argv[]); 72*1182cb7eSMatthias Ringwald 73*1182cb7eSMatthias Ringwald #define TLV_DB_PATH_PREFIX "/tmp/btstack_" 74*1182cb7eSMatthias Ringwald #define TLV_DB_PATH_POSTFIX ".tlv" 75*1182cb7eSMatthias Ringwald static char tlv_db_path[100]; 76*1182cb7eSMatthias Ringwald static const btstack_tlv_t * tlv_impl; 77*1182cb7eSMatthias Ringwald static btstack_tlv_posix_t tlv_context; 78*1182cb7eSMatthias Ringwald 79*1182cb7eSMatthias Ringwald static hci_transport_config_uart_t transport_config = { 80*1182cb7eSMatthias Ringwald HCI_TRANSPORT_CONFIG_UART, 81*1182cb7eSMatthias Ringwald 115200, 82*1182cb7eSMatthias Ringwald 921600, // main baudrate 83*1182cb7eSMatthias Ringwald 0, // flow control 84*1182cb7eSMatthias Ringwald NULL, 85*1182cb7eSMatthias Ringwald BTSTACK_UART_PARITY_EVEN, // parity 86*1182cb7eSMatthias Ringwald }; 87*1182cb7eSMatthias Ringwald static btstack_uart_config_t uart_config; 88*1182cb7eSMatthias Ringwald 89*1182cb7eSMatthias Ringwald static int main_argc; 90*1182cb7eSMatthias Ringwald static const char ** main_argv; 91*1182cb7eSMatthias Ringwald 92*1182cb7eSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 93*1182cb7eSMatthias Ringwald 94*1182cb7eSMatthias Ringwald static void sigint_handler(int param){ 95*1182cb7eSMatthias Ringwald UNUSED(param); 96*1182cb7eSMatthias Ringwald 97*1182cb7eSMatthias Ringwald printf("CTRL-C - SIGINT received, shutting down..\n"); 98*1182cb7eSMatthias Ringwald log_info("sigint_handler: shutting down"); 99*1182cb7eSMatthias Ringwald 100*1182cb7eSMatthias Ringwald // reset anyway 101*1182cb7eSMatthias Ringwald btstack_stdin_reset(); 102*1182cb7eSMatthias Ringwald 103*1182cb7eSMatthias Ringwald // power down 104*1182cb7eSMatthias Ringwald hci_power_control(HCI_POWER_OFF); 105*1182cb7eSMatthias Ringwald hci_close(); 106*1182cb7eSMatthias Ringwald log_info("Good bye, see you.\n"); 107*1182cb7eSMatthias Ringwald exit(0); 108*1182cb7eSMatthias Ringwald } 109*1182cb7eSMatthias Ringwald 110*1182cb7eSMatthias Ringwald static int led_state = 0; 111*1182cb7eSMatthias Ringwald void hal_led_toggle(void){ 112*1182cb7eSMatthias Ringwald led_state = 1 - led_state; 113*1182cb7eSMatthias Ringwald printf("LED State %u\n", led_state); 114*1182cb7eSMatthias Ringwald } 115*1182cb7eSMatthias Ringwald 116*1182cb7eSMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 117*1182cb7eSMatthias Ringwald bd_addr_t addr; 118*1182cb7eSMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 119*1182cb7eSMatthias Ringwald switch (hci_event_packet_get_type(packet)){ 120*1182cb7eSMatthias Ringwald case BTSTACK_EVENT_STATE: 121*1182cb7eSMatthias Ringwald if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break; 122*1182cb7eSMatthias Ringwald gap_local_bd_addr(addr); 123*1182cb7eSMatthias Ringwald printf("BTstack up and running at %s\n", bd_addr_to_str(addr)); 124*1182cb7eSMatthias Ringwald // setup TLV 125*1182cb7eSMatthias Ringwald strcpy(tlv_db_path, TLV_DB_PATH_PREFIX); 126*1182cb7eSMatthias Ringwald strcat(tlv_db_path, bd_addr_to_str(addr)); 127*1182cb7eSMatthias Ringwald strcat(tlv_db_path, TLV_DB_PATH_POSTFIX); 128*1182cb7eSMatthias Ringwald tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path); 129*1182cb7eSMatthias Ringwald btstack_tlv_set_instance(tlv_impl, &tlv_context); 130*1182cb7eSMatthias Ringwald #ifdef ENABLE_CLASSIC 131*1182cb7eSMatthias Ringwald hci_set_link_key_db(btstack_link_key_db_tlv_get_instance(tlv_impl, &tlv_context)); 132*1182cb7eSMatthias Ringwald #endif 133*1182cb7eSMatthias Ringwald #ifdef ENABLE_BLE 134*1182cb7eSMatthias Ringwald le_device_db_tlv_configure(tlv_impl, &tlv_context); 135*1182cb7eSMatthias Ringwald #endif 136*1182cb7eSMatthias Ringwald break; 137*1182cb7eSMatthias Ringwald default: 138*1182cb7eSMatthias Ringwald break; 139*1182cb7eSMatthias Ringwald } 140*1182cb7eSMatthias Ringwald } 141*1182cb7eSMatthias Ringwald 142*1182cb7eSMatthias Ringwald static void phase2(int status); 143*1182cb7eSMatthias Ringwald int main(int argc, const char * argv[]){ 144*1182cb7eSMatthias Ringwald 145*1182cb7eSMatthias Ringwald /// GET STARTED with BTstack /// 146*1182cb7eSMatthias Ringwald btstack_memory_init(); 147*1182cb7eSMatthias Ringwald 148*1182cb7eSMatthias Ringwald // use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT 149*1182cb7eSMatthias Ringwald const char * pklg_path = "/tmp/hci_dump.pklg"; 150*1182cb7eSMatthias Ringwald hci_dump_open(pklg_path, HCI_DUMP_PACKETLOGGER); 151*1182cb7eSMatthias Ringwald printf("Packet Log: %s\n", pklg_path); 152*1182cb7eSMatthias Ringwald 153*1182cb7eSMatthias Ringwald // setup run loop 154*1182cb7eSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance()); 155*1182cb7eSMatthias Ringwald 156*1182cb7eSMatthias Ringwald // pick serial port and configure uart block driver 157*1182cb7eSMatthias Ringwald transport_config.device_name = "/dev/tty.usbserial-A9OVNX5P"; // RedBear IoT pHAT breakout board 158*1182cb7eSMatthias Ringwald 159*1182cb7eSMatthias Ringwald // get BCM chipset driver 160*1182cb7eSMatthias Ringwald const btstack_chipset_t * chipset = btstack_chipset_bcm_instance(); 161*1182cb7eSMatthias Ringwald chipset->init(&transport_config); 162*1182cb7eSMatthias Ringwald 163*1182cb7eSMatthias Ringwald // set chipset name 164*1182cb7eSMatthias Ringwald btstack_chipset_bcm_set_device_name("BCM43430A1"); 165*1182cb7eSMatthias Ringwald 166*1182cb7eSMatthias Ringwald // setup UART driver 167*1182cb7eSMatthias Ringwald const btstack_uart_t * uart_driver = (const btstack_uart_t *) btstack_uart_posix_instance(); 168*1182cb7eSMatthias Ringwald 169*1182cb7eSMatthias Ringwald // extract UART config from transport config 170*1182cb7eSMatthias Ringwald uart_config.baudrate = transport_config.baudrate_init; 171*1182cb7eSMatthias Ringwald uart_config.flowcontrol = transport_config.flowcontrol; 172*1182cb7eSMatthias Ringwald uart_config.device_name = transport_config.device_name; 173*1182cb7eSMatthias Ringwald uart_driver->init(&uart_config); 174*1182cb7eSMatthias Ringwald 175*1182cb7eSMatthias Ringwald 176*1182cb7eSMatthias Ringwald // setup HCI (to be able to use bcm chipset driver) 177*1182cb7eSMatthias Ringwald // init HCI 178*1182cb7eSMatthias Ringwald const hci_transport_t * transport = hci_transport_h5_instance(uart_driver); 179*1182cb7eSMatthias Ringwald hci_init(transport, (void*) &transport_config); 180*1182cb7eSMatthias Ringwald hci_set_chipset(btstack_chipset_bcm_instance()); 181*1182cb7eSMatthias Ringwald 182*1182cb7eSMatthias Ringwald // inform about BTstack state 183*1182cb7eSMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 184*1182cb7eSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 185*1182cb7eSMatthias Ringwald 186*1182cb7eSMatthias Ringwald // handle CTRL-c 187*1182cb7eSMatthias Ringwald signal(SIGINT, sigint_handler); 188*1182cb7eSMatthias Ringwald 189*1182cb7eSMatthias Ringwald main_argc = argc; 190*1182cb7eSMatthias Ringwald main_argv = argv; 191*1182cb7eSMatthias Ringwald 192*1182cb7eSMatthias Ringwald // phase #1 download firmware 193*1182cb7eSMatthias Ringwald printf("Phase 1: Download firmware\n"); 194*1182cb7eSMatthias Ringwald 195*1182cb7eSMatthias Ringwald // phase #2 start main app 196*1182cb7eSMatthias Ringwald btstack_chipset_bcm_download_firmware_with_uart(uart_driver, transport_config.baudrate_main, &phase2); 197*1182cb7eSMatthias Ringwald 198*1182cb7eSMatthias Ringwald // go 199*1182cb7eSMatthias Ringwald btstack_run_loop_execute(); 200*1182cb7eSMatthias Ringwald return 0; 201*1182cb7eSMatthias Ringwald } 202*1182cb7eSMatthias Ringwald 203*1182cb7eSMatthias Ringwald static void phase2(int status){ 204*1182cb7eSMatthias Ringwald 205*1182cb7eSMatthias Ringwald if (status){ 206*1182cb7eSMatthias Ringwald printf("Download firmware failed\n"); 207*1182cb7eSMatthias Ringwald return; 208*1182cb7eSMatthias Ringwald } 209*1182cb7eSMatthias Ringwald 210*1182cb7eSMatthias Ringwald printf("Phase 2: Main app\n"); 211*1182cb7eSMatthias Ringwald 212*1182cb7eSMatthias Ringwald // setup app 213*1182cb7eSMatthias Ringwald btstack_main(main_argc, main_argv); 214*1182cb7eSMatthias Ringwald } 215*1182cb7eSMatthias Ringwald 216