1277e512cSDirk Helbig /* 2277e512cSDirk Helbig * Copyright (c) 2016 Nordic Semiconductor ASA 3277e512cSDirk Helbig * Copyright (c) 2015-2016 Intel Corporation 4277e512cSDirk Helbig * 5277e512cSDirk Helbig * SPDX-License-Identifier: Apache-2.0 6277e512cSDirk Helbig */ 7277e512cSDirk Helbig 8277e512cSDirk Helbig #include <errno.h> 9277e512cSDirk Helbig #include <stddef.h> 10277e512cSDirk Helbig #include <stdio.h> 11277e512cSDirk Helbig #include <string.h> 12277e512cSDirk Helbig 13277e512cSDirk Helbig #include <zephyr/kernel.h> 14277e512cSDirk Helbig #include <zephyr/bluetooth/bluetooth.h> 15277e512cSDirk Helbig #include <zephyr/bluetooth/l2cap.h> 16277e512cSDirk Helbig #include <zephyr/bluetooth/hci.h> 17277e512cSDirk Helbig #include <zephyr/bluetooth/buf.h> 18277e512cSDirk Helbig #include <zephyr/bluetooth/hci_raw.h> 19277e512cSDirk Helbig 20277e512cSDirk Helbig // Nordic NDK 21277e512cSDirk Helbig #include "nrf.h" 22277e512cSDirk Helbig 23277e512cSDirk Helbig // BTstack 24277e512cSDirk Helbig #include "btstack_debug.h" 25277e512cSDirk Helbig #include "btstack_event.h" 26277e512cSDirk Helbig #include "btstack_memory.h" 27277e512cSDirk Helbig #include "hci.h" 28277e512cSDirk Helbig #include "hci_dump.h" 29277e512cSDirk Helbig #include "hci_dump_embedded_stdout.h" 30277e512cSDirk Helbig #include "hci_transport.h" 31*b7898607SDirk Helbig #include "bluetooth_company_id.h" 32*b7898607SDirk Helbig #include "btstack_chipset_zephyr.h" 33277e512cSDirk Helbig 34277e512cSDirk Helbig #include "btstack_tlv.h" 35277e512cSDirk Helbig #include "btstack_tlv_none.h" 36277e512cSDirk Helbig #include "ble/le_device_db_tlv.h" 37277e512cSDirk Helbig 38*b7898607SDirk Helbig #define HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS 0xFC09 39*b7898607SDirk Helbig const hci_cmd_t hci_zephyr_read_static_address = { 40*b7898607SDirk Helbig HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS, "" 41*b7898607SDirk Helbig }; 42277e512cSDirk Helbig static K_FIFO_DEFINE(tx_queue); 43277e512cSDirk Helbig static K_FIFO_DEFINE(rx_queue); 44277e512cSDirk Helbig 45277e512cSDirk Helbig // 46277e512cSDirk Helbig // hci_transport_zephyr.c 47277e512cSDirk Helbig // 48277e512cSDirk Helbig 49277e512cSDirk Helbig static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 50277e512cSDirk Helbig 51277e512cSDirk Helbig /** 52277e512cSDirk Helbig * init transport 53277e512cSDirk Helbig * @param transport_config 54277e512cSDirk Helbig */ 55277e512cSDirk Helbig static void transport_init(const void *transport_config){ 56277e512cSDirk Helbig /* startup Controller */ 57277e512cSDirk Helbig bt_enable_raw(&rx_queue); 58*b7898607SDirk Helbig bt_hci_raw_set_mode( BT_HCI_RAW_MODE_PASSTHROUGH ); 59277e512cSDirk Helbig } 60277e512cSDirk Helbig 61277e512cSDirk Helbig /** 62277e512cSDirk Helbig * open transport connection 63277e512cSDirk Helbig */ 64277e512cSDirk Helbig static int transport_open(void){ 65277e512cSDirk Helbig return 0; 66277e512cSDirk Helbig } 67277e512cSDirk Helbig 68277e512cSDirk Helbig /** 69277e512cSDirk Helbig * close transport connection 70277e512cSDirk Helbig */ 71277e512cSDirk Helbig static int transport_close(void){ 72277e512cSDirk Helbig return 0; 73277e512cSDirk Helbig } 74277e512cSDirk Helbig 75277e512cSDirk Helbig /** 76277e512cSDirk Helbig * register packet handler for HCI packets: ACL, SCO, and Events 77277e512cSDirk Helbig */ 78277e512cSDirk Helbig static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 79277e512cSDirk Helbig transport_packet_handler = handler; 80277e512cSDirk Helbig } 81277e512cSDirk Helbig 82277e512cSDirk Helbig static void send_hardware_error(uint8_t error_code){ 83277e512cSDirk Helbig // hci_outgoing_event[0] = HCI_EVENT_HARDWARE_ERROR; 84277e512cSDirk Helbig // hci_outgoing_event[1] = 1; 85277e512cSDirk Helbig // hci_outgoing_event[2] = error_code; 86277e512cSDirk Helbig // hci_outgoing_event_ready = 1; 87277e512cSDirk Helbig } 88277e512cSDirk Helbig 89277e512cSDirk Helbig static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 90277e512cSDirk Helbig struct net_buf *buf; 91277e512cSDirk Helbig switch (packet_type){ 92277e512cSDirk Helbig case HCI_COMMAND_DATA_PACKET: 93277e512cSDirk Helbig buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, packet, size); 94277e512cSDirk Helbig if (!buf) { 95277e512cSDirk Helbig log_error("No available command buffers!\n"); 96277e512cSDirk Helbig break; 97277e512cSDirk Helbig } 98277e512cSDirk Helbig 99277e512cSDirk Helbig bt_send(buf); 100277e512cSDirk Helbig break; 101277e512cSDirk Helbig case HCI_ACL_DATA_PACKET: 102277e512cSDirk Helbig buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, packet, size); 103277e512cSDirk Helbig if (!buf) { 104277e512cSDirk Helbig log_error("No available ACL buffers!\n"); 105277e512cSDirk Helbig break; 106277e512cSDirk Helbig } 107277e512cSDirk Helbig 108277e512cSDirk Helbig bt_send(buf); 109277e512cSDirk Helbig break; 110277e512cSDirk Helbig default: 111277e512cSDirk Helbig send_hardware_error(0x01); // invalid HCI packet 112277e512cSDirk Helbig break; 113277e512cSDirk Helbig } 114277e512cSDirk Helbig 115277e512cSDirk Helbig return 0; 116277e512cSDirk Helbig } 117277e512cSDirk Helbig 118277e512cSDirk Helbig static const hci_transport_t transport = { 119fba2f984SMatthias Ringwald /* const char * name; */ "zephyr", 120277e512cSDirk Helbig /* void (*init) (const void *transport_config); */ &transport_init, 121277e512cSDirk Helbig /* int (*open)(void); */ &transport_open, 122277e512cSDirk Helbig /* int (*close)(void); */ &transport_close, 123277e512cSDirk Helbig /* void (*register_packet_handler)(void (*handler)(...); */ &transport_register_packet_handler, 124277e512cSDirk Helbig /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL, 125277e512cSDirk Helbig /* int (*send_packet)(...); */ &transport_send_packet, 126277e512cSDirk Helbig /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 127277e512cSDirk Helbig /* void (*reset_link)(void); */ NULL, 128277e512cSDirk Helbig }; 129277e512cSDirk Helbig 130277e512cSDirk Helbig static const hci_transport_t * transport_get_instance(void){ 131277e512cSDirk Helbig return &transport; 132277e512cSDirk Helbig } 133277e512cSDirk Helbig 134277e512cSDirk Helbig static void transport_deliver_controller_packet(struct net_buf * buf){ 135277e512cSDirk Helbig uint16_t size = buf->len; 136277e512cSDirk Helbig uint8_t * packet = buf->data; 137277e512cSDirk Helbig switch (bt_buf_get_type(buf)) { 138277e512cSDirk Helbig case BT_BUF_ACL_IN: 139277e512cSDirk Helbig transport_packet_handler(HCI_ACL_DATA_PACKET, packet, size); 140277e512cSDirk Helbig break; 141277e512cSDirk Helbig case BT_BUF_EVT: 142277e512cSDirk Helbig transport_packet_handler(HCI_EVENT_PACKET, packet, size); 143277e512cSDirk Helbig break; 144277e512cSDirk Helbig default: 145277e512cSDirk Helbig log_error("Unknown type %u\n", bt_buf_get_type(buf)); 146277e512cSDirk Helbig break; 147277e512cSDirk Helbig } 148277e512cSDirk Helbig net_buf_unref(buf); 149277e512cSDirk Helbig } 150277e512cSDirk Helbig 151277e512cSDirk Helbig // btstack_run_loop_zephry.c 152277e512cSDirk Helbig 153277e512cSDirk Helbig // the run loop 154277e512cSDirk Helbig //static btstack_linked_list_t timers; 155277e512cSDirk Helbig 156277e512cSDirk Helbig // TODO: handle 32 bit ms time overrun 157277e512cSDirk Helbig static uint32_t btstack_run_loop_zephyr_get_time_ms(void){ 158277e512cSDirk Helbig return k_uptime_get_32(); 159277e512cSDirk Helbig } 160277e512cSDirk Helbig 161277e512cSDirk Helbig static void btstack_run_loop_zephyr_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ 162277e512cSDirk Helbig ts->timeout = k_uptime_get_32() + 1 + timeout_in_ms; 163277e512cSDirk Helbig } 164277e512cSDirk Helbig 165277e512cSDirk Helbig /** 166277e512cSDirk Helbig * Execute run_loop 167277e512cSDirk Helbig */ 168277e512cSDirk Helbig static void btstack_run_loop_zephyr_execute(void) { 169277e512cSDirk Helbig while (1) { 170277e512cSDirk Helbig // process timers 171277e512cSDirk Helbig uint32_t now = k_uptime_get_32(); 172277e512cSDirk Helbig btstack_run_loop_base_process_timers(now); 173277e512cSDirk Helbig 174277e512cSDirk Helbig // get time until next timer expires 175277e512cSDirk Helbig k_timeout_t timeout; 176277e512cSDirk Helbig timeout.ticks = btstack_run_loop_base_get_time_until_timeout(now); 177277e512cSDirk Helbig if (timeout.ticks < 0){ 178277e512cSDirk Helbig timeout.ticks = K_TICKS_FOREVER; 179277e512cSDirk Helbig } 180277e512cSDirk Helbig 181277e512cSDirk Helbig // process RX fifo only 182277e512cSDirk Helbig struct net_buf *buf = net_buf_get(&rx_queue, timeout); 183277e512cSDirk Helbig if (buf){ 184277e512cSDirk Helbig transport_deliver_controller_packet(buf); 185277e512cSDirk Helbig } 186277e512cSDirk Helbig } 187277e512cSDirk Helbig } 188277e512cSDirk Helbig 189277e512cSDirk Helbig static void btstack_run_loop_zephyr_btstack_run_loop_init(void){ 190277e512cSDirk Helbig btstack_run_loop_base_init(); 191277e512cSDirk Helbig } 192277e512cSDirk Helbig 193277e512cSDirk Helbig static const btstack_run_loop_t btstack_run_loop_zephyr = { 194277e512cSDirk Helbig &btstack_run_loop_zephyr_btstack_run_loop_init, 195277e512cSDirk Helbig NULL, 196277e512cSDirk Helbig NULL, 197277e512cSDirk Helbig NULL, 198277e512cSDirk Helbig NULL, 199277e512cSDirk Helbig &btstack_run_loop_zephyr_set_timer, 200277e512cSDirk Helbig &btstack_run_loop_base_add_timer, 201277e512cSDirk Helbig &btstack_run_loop_base_remove_timer, 202277e512cSDirk Helbig &btstack_run_loop_zephyr_execute, 203277e512cSDirk Helbig &btstack_run_loop_base_dump_timer, 204277e512cSDirk Helbig &btstack_run_loop_zephyr_get_time_ms, 205277e512cSDirk Helbig }; 206277e512cSDirk Helbig /** 207277e512cSDirk Helbig * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init 208277e512cSDirk Helbig */ 209277e512cSDirk Helbig const btstack_run_loop_t * btstack_run_loop_zephyr_get_instance(void){ 210277e512cSDirk Helbig return &btstack_run_loop_zephyr; 211277e512cSDirk Helbig } 212277e512cSDirk Helbig 213277e512cSDirk Helbig static btstack_packet_callback_registration_t hci_event_callback_registration; 214277e512cSDirk Helbig 215*b7898607SDirk Helbig static bd_addr_t local_addr; 216*b7898607SDirk Helbig 217*b7898607SDirk Helbig void nrf_get_static_random_addr( bd_addr_t addr ) { 218*b7898607SDirk Helbig // nRF5 chipsets don't have an official public address 219*b7898607SDirk Helbig // Instead, a Static Random Address is assigned during manufacturing 220*b7898607SDirk Helbig // let's use it as well 221*b7898607SDirk Helbig #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) 222*b7898607SDirk Helbig big_endian_store_16(addr, 0, NRF_FICR->DEVICEADDR[1] | 0xc000); 223*b7898607SDirk Helbig big_endian_store_32(addr, 2, NRF_FICR->DEVICEADDR[0]); 224*b7898607SDirk Helbig #elif defined(CONFIG_SOC_SERIES_NRF53X) 225*b7898607SDirk Helbig // Using TrustZone this will only work in secure mode 226*b7898607SDirk Helbig big_endian_store_16(addr, 0, NRF_FICR_S->INFO.DEVICEID[1] | 0xc000 ); 227*b7898607SDirk Helbig big_endian_store_32(addr, 2, NRF_FICR_S->INFO.DEVICEID[0]); 228*b7898607SDirk Helbig #endif 229*b7898607SDirk Helbig } 230*b7898607SDirk Helbig 231*b7898607SDirk Helbig static void local_version_information_handler(uint8_t * packet){ 232*b7898607SDirk Helbig printf("Local version information:\n"); 233*b7898607SDirk Helbig uint16_t hci_version = packet[6]; 234*b7898607SDirk Helbig uint16_t hci_revision = little_endian_read_16(packet, 7); 235*b7898607SDirk Helbig uint16_t lmp_version = packet[9]; 236*b7898607SDirk Helbig uint16_t manufacturer = little_endian_read_16(packet, 10); 237*b7898607SDirk Helbig uint16_t lmp_subversion = little_endian_read_16(packet, 12); 238*b7898607SDirk Helbig printf("- HCI Version %#04x\n", hci_version); 239*b7898607SDirk Helbig printf("- HCI Revision %#04x\n", hci_revision); 240*b7898607SDirk Helbig printf("- LMP Version %#04x\n", lmp_version); 241*b7898607SDirk Helbig printf("- LMP Subversion %#04x\n", lmp_subversion); 242*b7898607SDirk Helbig printf("- Manufacturer %#04x\n", manufacturer); 243*b7898607SDirk Helbig switch (manufacturer){ 244*b7898607SDirk Helbig case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA: 245*b7898607SDirk Helbig case BLUETOOTH_COMPANY_ID_THE_LINUX_FOUNDATION: 246*b7898607SDirk Helbig printf("Nordic Semiconductor nRF5 chipset.\n"); 247*b7898607SDirk Helbig hci_set_chipset(btstack_chipset_zephyr_instance()); 248*b7898607SDirk Helbig break; 249*b7898607SDirk Helbig case BLUETOOTH_COMPANY_ID_PACKETCRAFT_INC: 250*b7898607SDirk Helbig printf("PacketCraft HCI Controller\n"); 251*b7898607SDirk Helbig nrf_get_static_random_addr( local_addr ); 252*b7898607SDirk Helbig gap_random_address_set( local_addr ); 253*b7898607SDirk Helbig break; 254*b7898607SDirk Helbig default: 255*b7898607SDirk Helbig printf("Unknown manufacturer.\n"); 256*b7898607SDirk Helbig nrf_get_static_random_addr( local_addr ); 257*b7898607SDirk Helbig gap_random_address_set( local_addr ); 258*b7898607SDirk Helbig break; 259*b7898607SDirk Helbig } 260*b7898607SDirk Helbig } 261277e512cSDirk Helbig 262277e512cSDirk Helbig static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 263277e512cSDirk Helbig if (packet_type != HCI_EVENT_PACKET) return; 264*b7898607SDirk Helbig switch (hci_event_packet_get_type(packet)){ 265*b7898607SDirk Helbig case BTSTACK_EVENT_STATE: 266*b7898607SDirk Helbig switch(btstack_event_state_get_state(packet)){ 267*b7898607SDirk Helbig case HCI_STATE_WORKING: 268*b7898607SDirk Helbig printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); 269*b7898607SDirk Helbig break; 270*b7898607SDirk Helbig case HCI_STATE_OFF: 271*b7898607SDirk Helbig log_info("Good bye, see you.\n"); 272*b7898607SDirk Helbig break; 273*b7898607SDirk Helbig default: 274*b7898607SDirk Helbig break; 275*b7898607SDirk Helbig } 276*b7898607SDirk Helbig break; 277*b7898607SDirk Helbig case HCI_EVENT_COMMAND_COMPLETE: 278*b7898607SDirk Helbig switch (hci_event_command_complete_get_command_opcode(packet)){ 279*b7898607SDirk Helbig case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION: 280*b7898607SDirk Helbig local_version_information_handler(packet); 281*b7898607SDirk Helbig break; 282*b7898607SDirk Helbig case HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS: 283*b7898607SDirk Helbig reverse_48(&packet[7], local_addr); 284*b7898607SDirk Helbig gap_random_address_set(local_addr); 285*b7898607SDirk Helbig break; 286*b7898607SDirk Helbig default: 287*b7898607SDirk Helbig break; 288*b7898607SDirk Helbig } 289*b7898607SDirk Helbig break; 290*b7898607SDirk Helbig default: 291*b7898607SDirk Helbig break; 292*b7898607SDirk Helbig } 293277e512cSDirk Helbig } 294277e512cSDirk Helbig 295277e512cSDirk Helbig int btstack_main(void); 296277e512cSDirk Helbig 297277e512cSDirk Helbig #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) 298277e512cSDirk Helbig void bt_ctlr_assert_handle(char *file, uint32_t line) 299277e512cSDirk Helbig { 300277e512cSDirk Helbig printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); 301277e512cSDirk Helbig while (1) { 302277e512cSDirk Helbig } 303277e512cSDirk Helbig } 304277e512cSDirk Helbig #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ 305277e512cSDirk Helbig 306b51b065cSDirk Helbig int main(void) 307277e512cSDirk Helbig { 308277e512cSDirk Helbig printf("BTstack booting up..\n"); 309277e512cSDirk Helbig 310277e512cSDirk Helbig // start with BTstack init - especially configure HCI Transport 311277e512cSDirk Helbig btstack_memory_init(); 312277e512cSDirk Helbig btstack_run_loop_init(btstack_run_loop_zephyr_get_instance()); 313277e512cSDirk Helbig 314*b7898607SDirk Helbig #ifdef ENABLE_HCI_DUMP 315277e512cSDirk Helbig // enable full log output while porting 316277e512cSDirk Helbig hci_dump_init(hci_dump_embedded_stdout_get_instance()); 317*b7898607SDirk Helbig #endif 318277e512cSDirk Helbig 319277e512cSDirk Helbig const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance(); 320277e512cSDirk Helbig // setup global tlv 321277e512cSDirk Helbig btstack_tlv_set_instance(btstack_tlv_impl, NULL); 322277e512cSDirk Helbig 323277e512cSDirk Helbig // setup LE Device DB using TLV 324277e512cSDirk Helbig le_device_db_tlv_configure(btstack_tlv_impl, NULL); 325277e512cSDirk Helbig 326277e512cSDirk Helbig // init HCI 327277e512cSDirk Helbig hci_init(transport_get_instance(), NULL); 328277e512cSDirk Helbig 329277e512cSDirk Helbig // inform about BTstack state 330277e512cSDirk Helbig hci_event_callback_registration.callback = &packet_handler; 331277e512cSDirk Helbig hci_add_event_handler(&hci_event_callback_registration); 332277e512cSDirk Helbig 333277e512cSDirk Helbig // hand over to btstack embedded code 334277e512cSDirk Helbig btstack_main(); 335277e512cSDirk Helbig 336277e512cSDirk Helbig // go 337277e512cSDirk Helbig btstack_run_loop_execute(); 338277e512cSDirk Helbig 339277e512cSDirk Helbig while (1){}; 340b51b065cSDirk Helbig return 0; 341277e512cSDirk Helbig } 342