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 static K_FIFO_DEFINE(tx_queue); 39 static K_FIFO_DEFINE(rx_queue); 40 41 // 42 // hci_transport_zephyr.c 43 // 44 45 static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 46 47 /** 48 * init transport 49 * @param transport_config 50 */ 51 static void transport_init(const void *transport_config){ 52 /* startup Controller */ 53 bt_enable_raw(&rx_queue); 54 bt_hci_raw_set_mode( BT_HCI_RAW_MODE_PASSTHROUGH ); 55 } 56 57 /** 58 * open transport connection 59 */ 60 static int transport_open(void){ 61 return 0; 62 } 63 64 /** 65 * close transport connection 66 */ 67 static int transport_close(void){ 68 return 0; 69 } 70 71 /** 72 * register packet handler for HCI packets: ACL, SCO, and Events 73 */ 74 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 75 transport_packet_handler = handler; 76 } 77 78 static void send_hardware_error(uint8_t error_code){ 79 // hci_outgoing_event[0] = HCI_EVENT_HARDWARE_ERROR; 80 // hci_outgoing_event[1] = 1; 81 // hci_outgoing_event[2] = error_code; 82 // hci_outgoing_event_ready = 1; 83 } 84 85 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 86 struct net_buf *buf; 87 switch (packet_type){ 88 case HCI_COMMAND_DATA_PACKET: 89 buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, packet, size); 90 if (!buf) { 91 log_error("No available command buffers!\n"); 92 break; 93 } 94 95 bt_send(buf); 96 break; 97 case HCI_ACL_DATA_PACKET: 98 buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, packet, size); 99 if (!buf) { 100 log_error("No available ACL buffers!\n"); 101 break; 102 } 103 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; */ "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 static 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 local_addr; 212 213 void nrf_get_static_random_addr( bd_addr_t addr ) { 214 // nRF5 chipsets don't have an official public address 215 // Instead, a Static Random Address is assigned during manufacturing 216 // let's use it as well 217 #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) 218 big_endian_store_16(addr, 0, NRF_FICR->DEVICEADDR[1] | 0xc000); 219 big_endian_store_32(addr, 2, NRF_FICR->DEVICEADDR[0]); 220 #elif defined(CONFIG_SOC_SERIES_NRF53X) 221 // Using TrustZone this will only work in secure mode 222 big_endian_store_16(addr, 0, NRF_FICR_S->INFO.DEVICEID[1] | 0xc000 ); 223 big_endian_store_32(addr, 2, NRF_FICR_S->INFO.DEVICEID[0]); 224 #endif 225 } 226 227 static void local_version_information_handler(uint8_t * packet){ 228 printf("Local version information:\n"); 229 uint16_t hci_version = packet[6]; 230 uint16_t hci_revision = little_endian_read_16(packet, 7); 231 uint16_t lmp_version = packet[9]; 232 uint16_t manufacturer = little_endian_read_16(packet, 10); 233 uint16_t lmp_subversion = little_endian_read_16(packet, 12); 234 printf("- HCI Version %#04x\n", hci_version); 235 printf("- HCI Revision %#04x\n", hci_revision); 236 printf("- LMP Version %#04x\n", lmp_version); 237 printf("- LMP Subversion %#04x\n", lmp_subversion); 238 printf("- Manufacturer %#04x\n", manufacturer); 239 switch (manufacturer){ 240 case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA: 241 case BLUETOOTH_COMPANY_ID_THE_LINUX_FOUNDATION: 242 printf("Nordic Semiconductor nRF5 chipset.\n"); 243 hci_set_chipset(btstack_chipset_zephyr_instance()); 244 break; 245 case BLUETOOTH_COMPANY_ID_PACKETCRAFT_INC: 246 printf("PacketCraft HCI Controller\n"); 247 nrf_get_static_random_addr( local_addr ); 248 gap_random_address_set( local_addr ); 249 break; 250 default: 251 printf("Unknown manufacturer.\n"); 252 nrf_get_static_random_addr( local_addr ); 253 gap_random_address_set( local_addr ); 254 break; 255 } 256 } 257 258 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 259 const uint8_t *params; 260 if (packet_type != HCI_EVENT_PACKET) return; 261 switch (hci_event_packet_get_type(packet)){ 262 case BTSTACK_EVENT_STATE: 263 switch(btstack_event_state_get_state(packet)){ 264 case HCI_STATE_WORKING: 265 printf("BTstack up and running on %s.\n", bd_addr_to_str(local_addr)); 266 break; 267 case HCI_STATE_OFF: 268 log_info("Good bye, see you.\n"); 269 break; 270 default: 271 break; 272 } 273 break; 274 case HCI_EVENT_COMMAND_COMPLETE: 275 switch (hci_event_command_complete_get_command_opcode(packet)){ 276 case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION: 277 local_version_information_handler(packet); 278 break; 279 case HCI_OPCODE_HCI_ZEPHYR_READ_STATIC_ADDRESS: 280 params = hci_event_command_complete_get_return_parameters(packet); 281 if(params[0] != 0) 282 break; 283 if(size < 13) 284 break; 285 reverse_48(¶ms[2], local_addr); 286 gap_random_address_set(local_addr); 287 break; 288 default: 289 break; 290 } 291 break; 292 default: 293 break; 294 } 295 } 296 297 int btstack_main(void); 298 299 #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) 300 void bt_ctlr_assert_handle(char *file, uint32_t line) 301 { 302 printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); 303 while (1) { 304 } 305 } 306 #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ 307 308 int main(void) 309 { 310 printf("BTstack booting up..\n"); 311 312 // start with BTstack init - especially configure HCI Transport 313 btstack_memory_init(); 314 btstack_run_loop_init(btstack_run_loop_zephyr_get_instance()); 315 316 #ifdef ENABLE_HCI_DUMP 317 // enable full log output while porting 318 hci_dump_init(hci_dump_embedded_stdout_get_instance()); 319 #endif 320 321 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance(); 322 // setup global tlv 323 btstack_tlv_set_instance(btstack_tlv_impl, NULL); 324 325 // setup LE Device DB using TLV 326 le_device_db_tlv_configure(btstack_tlv_impl, NULL); 327 328 // init HCI 329 hci_init(transport_get_instance(), NULL); 330 331 // inform about BTstack state 332 hci_event_callback_registration.callback = &packet_handler; 333 hci_add_event_handler(&hci_event_callback_registration); 334 335 // hand over to btstack embedded code 336 btstack_main(); 337 338 // go 339 btstack_run_loop_execute(); 340 341 while (1){}; 342 return 0; 343 } 344