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 "hci.h" 28 #include "hci_dump.h" 29 #include "hci_dump_embedded_stdout.h" 30 #include "hci_transport.h" 31 #include "bluetooth_company_id.h" 32 #include "btstack_chipset_zephyr.h" 33 34 #include "btstack_tlv.h" 35 #include "btstack_tlv_none.h" 36 #include "ble/le_device_db_tlv.h" 37 38 #define HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS 0xFC09 39 const hci_cmd_t hci_zephyr_read_static_address = { 40 HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS, "" 41 }; 42 static K_FIFO_DEFINE(tx_queue); 43 static K_FIFO_DEFINE(rx_queue); 44 45 // 46 // hci_transport_zephyr.c 47 // 48 49 static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 50 51 /** 52 * init transport 53 * @param transport_config 54 */ 55 static void transport_init(const void *transport_config){ 56 /* startup Controller */ 57 bt_enable_raw(&rx_queue); 58 bt_hci_raw_set_mode( BT_HCI_RAW_MODE_PASSTHROUGH ); 59 } 60 61 /** 62 * open transport connection 63 */ 64 static int transport_open(void){ 65 return 0; 66 } 67 68 /** 69 * close transport connection 70 */ 71 static int transport_close(void){ 72 return 0; 73 } 74 75 /** 76 * register packet handler for HCI packets: ACL, SCO, and Events 77 */ 78 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 79 transport_packet_handler = handler; 80 } 81 82 static void send_hardware_error(uint8_t error_code){ 83 // hci_outgoing_event[0] = HCI_EVENT_HARDWARE_ERROR; 84 // hci_outgoing_event[1] = 1; 85 // hci_outgoing_event[2] = error_code; 86 // hci_outgoing_event_ready = 1; 87 } 88 89 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 90 struct net_buf *buf; 91 switch (packet_type){ 92 case HCI_COMMAND_DATA_PACKET: 93 buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, packet, size); 94 if (!buf) { 95 log_error("No available command buffers!\n"); 96 break; 97 } 98 99 bt_send(buf); 100 break; 101 case HCI_ACL_DATA_PACKET: 102 buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, packet, size); 103 if (!buf) { 104 log_error("No available ACL buffers!\n"); 105 break; 106 } 107 108 bt_send(buf); 109 break; 110 default: 111 send_hardware_error(0x01); // invalid HCI packet 112 break; 113 } 114 115 return 0; 116 } 117 118 static const hci_transport_t transport = { 119 /* const char * name; */ "zephyr", 120 /* void (*init) (const void *transport_config); */ &transport_init, 121 /* int (*open)(void); */ &transport_open, 122 /* int (*close)(void); */ &transport_close, 123 /* void (*register_packet_handler)(void (*handler)(...); */ &transport_register_packet_handler, 124 /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL, 125 /* int (*send_packet)(...); */ &transport_send_packet, 126 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 127 /* void (*reset_link)(void); */ NULL, 128 }; 129 130 static const hci_transport_t * transport_get_instance(void){ 131 return &transport; 132 } 133 134 static void transport_deliver_controller_packet(struct net_buf * buf){ 135 uint16_t size = buf->len; 136 uint8_t * packet = buf->data; 137 switch (bt_buf_get_type(buf)) { 138 case BT_BUF_ACL_IN: 139 transport_packet_handler(HCI_ACL_DATA_PACKET, packet, size); 140 break; 141 case BT_BUF_EVT: 142 transport_packet_handler(HCI_EVENT_PACKET, packet, size); 143 break; 144 default: 145 log_error("Unknown type %u\n", bt_buf_get_type(buf)); 146 break; 147 } 148 net_buf_unref(buf); 149 } 150 151 // btstack_run_loop_zephry.c 152 153 // the run loop 154 //static btstack_linked_list_t timers; 155 156 // TODO: handle 32 bit ms time overrun 157 static uint32_t btstack_run_loop_zephyr_get_time_ms(void){ 158 return k_uptime_get_32(); 159 } 160 161 static void btstack_run_loop_zephyr_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ 162 ts->timeout = k_uptime_get_32() + 1 + timeout_in_ms; 163 } 164 165 /** 166 * Execute run_loop 167 */ 168 static void btstack_run_loop_zephyr_execute(void) { 169 while (1) { 170 // process timers 171 uint32_t now = k_uptime_get_32(); 172 btstack_run_loop_base_process_timers(now); 173 174 // get time until next timer expires 175 k_timeout_t timeout; 176 timeout.ticks = btstack_run_loop_base_get_time_until_timeout(now); 177 if (timeout.ticks < 0){ 178 timeout.ticks = K_TICKS_FOREVER; 179 } 180 181 // process RX fifo only 182 struct net_buf *buf = net_buf_get(&rx_queue, timeout); 183 if (buf){ 184 transport_deliver_controller_packet(buf); 185 } 186 } 187 } 188 189 static void btstack_run_loop_zephyr_btstack_run_loop_init(void){ 190 btstack_run_loop_base_init(); 191 } 192 193 static const btstack_run_loop_t btstack_run_loop_zephyr = { 194 &btstack_run_loop_zephyr_btstack_run_loop_init, 195 NULL, 196 NULL, 197 NULL, 198 NULL, 199 &btstack_run_loop_zephyr_set_timer, 200 &btstack_run_loop_base_add_timer, 201 &btstack_run_loop_base_remove_timer, 202 &btstack_run_loop_zephyr_execute, 203 &btstack_run_loop_base_dump_timer, 204 &btstack_run_loop_zephyr_get_time_ms, 205 }; 206 /** 207 * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init 208 */ 209 const btstack_run_loop_t * btstack_run_loop_zephyr_get_instance(void){ 210 return &btstack_run_loop_zephyr; 211 } 212 213 static btstack_packet_callback_registration_t hci_event_callback_registration; 214 215 static bd_addr_t local_addr; 216 217 void nrf_get_static_random_addr( bd_addr_t addr ) { 218 // nRF5 chipsets don't have an official public address 219 // Instead, a Static Random Address is assigned during manufacturing 220 // let's use it as well 221 #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) 222 big_endian_store_16(addr, 0, NRF_FICR->DEVICEADDR[1] | 0xc000); 223 big_endian_store_32(addr, 2, NRF_FICR->DEVICEADDR[0]); 224 #elif defined(CONFIG_SOC_SERIES_NRF53X) 225 // Using TrustZone this will only work in secure mode 226 big_endian_store_16(addr, 0, NRF_FICR_S->INFO.DEVICEID[1] | 0xc000 ); 227 big_endian_store_32(addr, 2, NRF_FICR_S->INFO.DEVICEID[0]); 228 #endif 229 } 230 231 static void local_version_information_handler(uint8_t * packet){ 232 printf("Local version information:\n"); 233 uint16_t hci_version = packet[6]; 234 uint16_t hci_revision = little_endian_read_16(packet, 7); 235 uint16_t lmp_version = packet[9]; 236 uint16_t manufacturer = little_endian_read_16(packet, 10); 237 uint16_t lmp_subversion = little_endian_read_16(packet, 12); 238 printf("- HCI Version %#04x\n", hci_version); 239 printf("- HCI Revision %#04x\n", hci_revision); 240 printf("- LMP Version %#04x\n", lmp_version); 241 printf("- LMP Subversion %#04x\n", lmp_subversion); 242 printf("- Manufacturer %#04x\n", manufacturer); 243 switch (manufacturer){ 244 case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA: 245 case BLUETOOTH_COMPANY_ID_THE_LINUX_FOUNDATION: 246 printf("Nordic Semiconductor nRF5 chipset.\n"); 247 hci_set_chipset(btstack_chipset_zephyr_instance()); 248 break; 249 case BLUETOOTH_COMPANY_ID_PACKETCRAFT_INC: 250 printf("PacketCraft HCI Controller\n"); 251 nrf_get_static_random_addr( local_addr ); 252 gap_random_address_set( local_addr ); 253 break; 254 default: 255 printf("Unknown manufacturer.\n"); 256 nrf_get_static_random_addr( local_addr ); 257 gap_random_address_set( local_addr ); 258 break; 259 } 260 } 261 262 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 263 if (packet_type != HCI_EVENT_PACKET) return; 264 switch (hci_event_packet_get_type(packet)){ 265 case BTSTACK_EVENT_STATE: 266 switch(btstack_event_state_get_state(packet)){ 267 case HCI_STATE_WORKING: 268 printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); 269 break; 270 case HCI_STATE_OFF: 271 log_info("Good bye, see you.\n"); 272 break; 273 default: 274 break; 275 } 276 break; 277 case HCI_EVENT_COMMAND_COMPLETE: 278 switch (hci_event_command_complete_get_command_opcode(packet)){ 279 case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION: 280 local_version_information_handler(packet); 281 break; 282 case HCI_OPCODE_ZEPHYR_READ_STATIC_ADDRESS: 283 reverse_48(&packet[7], local_addr); 284 gap_random_address_set(local_addr); 285 break; 286 default: 287 break; 288 } 289 break; 290 default: 291 break; 292 } 293 } 294 295 int btstack_main(void); 296 297 #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) 298 void bt_ctlr_assert_handle(char *file, uint32_t line) 299 { 300 printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); 301 while (1) { 302 } 303 } 304 #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ 305 306 int main(void) 307 { 308 printf("BTstack booting up..\n"); 309 310 // start with BTstack init - especially configure HCI Transport 311 btstack_memory_init(); 312 btstack_run_loop_init(btstack_run_loop_zephyr_get_instance()); 313 314 #ifdef ENABLE_HCI_DUMP 315 // enable full log output while porting 316 hci_dump_init(hci_dump_embedded_stdout_get_instance()); 317 #endif 318 319 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance(); 320 // setup global tlv 321 btstack_tlv_set_instance(btstack_tlv_impl, NULL); 322 323 // setup LE Device DB using TLV 324 le_device_db_tlv_configure(btstack_tlv_impl, NULL); 325 326 // init HCI 327 hci_init(transport_get_instance(), NULL); 328 329 // inform about BTstack state 330 hci_event_callback_registration.callback = &packet_handler; 331 hci_add_event_handler(&hci_event_callback_registration); 332 333 // hand over to btstack embedded code 334 btstack_main(); 335 336 // go 337 btstack_run_loop_execute(); 338 339 while (1){}; 340 return 0; 341 } 342