1 /* 2 * Copyright (c) 2016 Nordic Semiconductor ASA 3 * Copyright (c) 2015-2016 Intel Corporation 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <errno.h> 9 #include <stddef.h> 10 #include <stdio.h> 11 #include <string.h> 12 13 #include <zephyr/kernel.h> 14 #include <zephyr/bluetooth/bluetooth.h> 15 #include <zephyr/bluetooth/l2cap.h> 16 #include <zephyr/bluetooth/hci.h> 17 #include <zephyr/bluetooth/buf.h> 18 #include <zephyr/bluetooth/hci_raw.h> 19 20 // Nordic NDK 21 #include "nrf.h" 22 23 // BTstack 24 #include "btstack_debug.h" 25 #include "btstack_event.h" 26 #include "btstack_memory.h" 27 #include "btstack_run_loop_zephyr.h" 28 #include "hci.h" 29 #include "hci_dump.h" 30 #include "hci_dump_embedded_stdout.h" 31 #include "hci_transport.h" 32 33 #include "btstack_tlv.h" 34 #include "btstack_tlv_none.h" 35 #include "ble/le_device_db_tlv.h" 36 37 static K_FIFO_DEFINE(tx_queue); 38 static K_FIFO_DEFINE(rx_queue); 39 40 // 41 // hci_transport_zephyr.c 42 // 43 44 static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 45 46 /** 47 * init transport 48 * @param transport_config 49 */ 50 static void transport_init(const void *transport_config){ 51 /* startup Controller */ 52 bt_enable_raw(&rx_queue); 53 } 54 55 /** 56 * open transport connection 57 */ 58 static int transport_open(void){ 59 return 0; 60 } 61 62 /** 63 * close transport connection 64 */ 65 static int transport_close(void){ 66 return 0; 67 } 68 69 /** 70 * register packet handler for HCI packets: ACL, SCO, and Events 71 */ 72 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 73 transport_packet_handler = handler; 74 } 75 76 static void send_hardware_error(uint8_t error_code){ 77 // hci_outgoing_event[0] = HCI_EVENT_HARDWARE_ERROR; 78 // hci_outgoing_event[1] = 1; 79 // hci_outgoing_event[2] = error_code; 80 // hci_outgoing_event_ready = 1; 81 } 82 83 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 84 struct net_buf *buf; 85 switch (packet_type){ 86 case HCI_COMMAND_DATA_PACKET: 87 buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, packet, size); 88 if (!buf) { 89 log_error("No available command buffers!\n"); 90 break; 91 } 92 93 memcpy(net_buf_add(buf, size), packet, size); 94 bt_send(buf); 95 break; 96 case HCI_ACL_DATA_PACKET: 97 buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, packet, size); 98 if (!buf) { 99 log_error("No available ACL buffers!\n"); 100 break; 101 } 102 103 memcpy(net_buf_add(buf, size), packet, size); 104 bt_send(buf); 105 break; 106 default: 107 send_hardware_error(0x01); // invalid HCI packet 108 break; 109 } 110 111 return 0; 112 } 113 114 static const hci_transport_t transport = { 115 /* const char * name; */ "nRF5-Zephyr", 116 /* void (*init) (const void *transport_config); */ &transport_init, 117 /* int (*open)(void); */ &transport_open, 118 /* int (*close)(void); */ &transport_close, 119 /* void (*register_packet_handler)(void (*handler)(...); */ &transport_register_packet_handler, 120 /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL, 121 /* int (*send_packet)(...); */ &transport_send_packet, 122 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 123 /* void (*reset_link)(void); */ NULL, 124 }; 125 126 static const hci_transport_t * transport_get_instance(void){ 127 return &transport; 128 } 129 130 static void transport_deliver_controller_packet(struct net_buf * buf){ 131 uint16_t size = buf->len; 132 uint8_t * packet = buf->data; 133 switch (bt_buf_get_type(buf)) { 134 case BT_BUF_ACL_IN: 135 transport_packet_handler(HCI_ACL_DATA_PACKET, packet, size); 136 break; 137 case BT_BUF_EVT: 138 transport_packet_handler(HCI_EVENT_PACKET, packet, size); 139 break; 140 default: 141 log_error("Unknown type %u\n", bt_buf_get_type(buf)); 142 break; 143 } 144 net_buf_unref(buf); 145 } 146 147 // btstack_run_loop_zephry.c 148 149 // the run loop 150 //static btstack_linked_list_t timers; 151 152 // TODO: handle 32 bit ms time overrun 153 static uint32_t btstack_run_loop_zephyr_get_time_ms(void){ 154 return k_uptime_get_32(); 155 } 156 157 static void btstack_run_loop_zephyr_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ 158 ts->timeout = k_uptime_get_32() + 1 + timeout_in_ms; 159 } 160 161 /** 162 * Execute run_loop 163 */ 164 static void btstack_run_loop_zephyr_execute(void) { 165 while (1) { 166 // process timers 167 uint32_t now = k_uptime_get_32(); 168 btstack_run_loop_base_process_timers(now); 169 170 // get time until next timer expires 171 k_timeout_t timeout; 172 timeout.ticks = btstack_run_loop_base_get_time_until_timeout(now); 173 if (timeout.ticks < 0){ 174 timeout.ticks = K_TICKS_FOREVER; 175 } 176 177 // process RX fifo only 178 struct net_buf *buf = net_buf_get(&rx_queue, timeout); 179 if (buf){ 180 transport_deliver_controller_packet(buf); 181 } 182 } 183 } 184 185 static void btstack_run_loop_zephyr_btstack_run_loop_init(void){ 186 btstack_run_loop_base_init(); 187 } 188 189 static const btstack_run_loop_t btstack_run_loop_zephyr = { 190 &btstack_run_loop_zephyr_btstack_run_loop_init, 191 NULL, 192 NULL, 193 NULL, 194 NULL, 195 &btstack_run_loop_zephyr_set_timer, 196 &btstack_run_loop_base_add_timer, 197 &btstack_run_loop_base_remove_timer, 198 &btstack_run_loop_zephyr_execute, 199 &btstack_run_loop_base_dump_timer, 200 &btstack_run_loop_zephyr_get_time_ms, 201 }; 202 /** 203 * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init 204 */ 205 const btstack_run_loop_t * btstack_run_loop_zephyr_get_instance(void){ 206 return &btstack_run_loop_zephyr; 207 } 208 209 static btstack_packet_callback_registration_t hci_event_callback_registration; 210 211 static bd_addr_t static_address; 212 213 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 214 if (packet_type != HCI_EVENT_PACKET) return; 215 if (hci_event_packet_get_type(packet) != BTSTACK_EVENT_STATE) return; 216 if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; 217 printf("BTstack up and running as %s.\n", bd_addr_to_str(static_address)); 218 } 219 220 int btstack_main(void); 221 222 #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) 223 void bt_ctlr_assert_handle(char *file, uint32_t line) 224 { 225 printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); 226 while (1) { 227 } 228 } 229 #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ 230 231 void main(void) 232 { 233 // configure console UART by replacing CONFIG_UART_NRF5_BAUD_RATE with 115200 in uart_console.c 234 235 printf("BTstack booting up..\n"); 236 237 // start with BTstack init - especially configure HCI Transport 238 btstack_memory_init(); 239 btstack_run_loop_init(btstack_run_loop_zephyr_get_instance()); 240 241 // enable full log output while porting 242 hci_dump_init(hci_dump_embedded_stdout_get_instance()); 243 244 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance(); 245 // setup global tlv 246 btstack_tlv_set_instance(btstack_tlv_impl, NULL); 247 248 // setup LE Device DB using TLV 249 le_device_db_tlv_configure(btstack_tlv_impl, NULL); 250 251 // init HCI 252 hci_init(transport_get_instance(), NULL); 253 254 // nRF5 chipsets don't have an official public address 255 // Instead, a Static Random Address is assigned during manufacturing 256 // let's use it as well 257 big_endian_store_16(static_address, 0, NRF_FICR->DEVICEADDR[1] | 0xc000); 258 big_endian_store_32(static_address, 2, NRF_FICR->DEVICEADDR[0]); 259 gap_random_address_set(static_address); 260 261 // inform about BTstack state 262 hci_event_callback_registration.callback = &packet_handler; 263 hci_add_event_handler(&hci_event_callback_registration); 264 265 // hand over to btstack embedded code 266 btstack_main(); 267 268 // go 269 btstack_run_loop_execute(); 270 271 while (1){}; 272 } 273