12c4f9bbbSMatthias Ringwald /* 22c4f9bbbSMatthias Ringwald * Copyright (C) 2020 BlueKitchen GmbH 32c4f9bbbSMatthias Ringwald * 42c4f9bbbSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 52c4f9bbbSMatthias Ringwald * modification, are permitted provided that the following conditions 62c4f9bbbSMatthias Ringwald * are met: 72c4f9bbbSMatthias Ringwald * 82c4f9bbbSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 92c4f9bbbSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 102c4f9bbbSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 112c4f9bbbSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 122c4f9bbbSMatthias Ringwald * documentation and/or other materials provided with the distribution. 132c4f9bbbSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 142c4f9bbbSMatthias Ringwald * contributors may be used to endorse or promote products derived 152c4f9bbbSMatthias Ringwald * from this software without specific prior written permission. 162c4f9bbbSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 172c4f9bbbSMatthias Ringwald * personal benefit and not for any commercial purpose or for 182c4f9bbbSMatthias Ringwald * monetary gain. 192c4f9bbbSMatthias Ringwald * 202c4f9bbbSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 212c4f9bbbSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 222c4f9bbbSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 252c4f9bbbSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 262c4f9bbbSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 272c4f9bbbSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 282c4f9bbbSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 292c4f9bbbSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 302c4f9bbbSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 312c4f9bbbSMatthias Ringwald * SUCH DAMAGE. 322c4f9bbbSMatthias Ringwald * 332c4f9bbbSMatthias Ringwald * Please inquire about commercial licensing options at 342c4f9bbbSMatthias Ringwald * [email protected] 352c4f9bbbSMatthias Ringwald * 362c4f9bbbSMatthias Ringwald */ 372c4f9bbbSMatthias Ringwald 382c4f9bbbSMatthias Ringwald #define BTSTACK_FILE__ "controller.c" 392c4f9bbbSMatthias Ringwald 402c4f9bbbSMatthias Ringwald #define DEBUG 412c4f9bbbSMatthias Ringwald 422c4f9bbbSMatthias Ringwald #include <string.h> 432c4f9bbbSMatthias Ringwald 442c4f9bbbSMatthias Ringwald #include "controller.h" 452c4f9bbbSMatthias Ringwald 462c4f9bbbSMatthias Ringwald #include "ll.h" 472c4f9bbbSMatthias Ringwald 482c4f9bbbSMatthias Ringwald #include "btstack_config.h" 492c4f9bbbSMatthias Ringwald #include "btstack_debug.h" 502c4f9bbbSMatthias Ringwald #include "btstack_util.h" 512c4f9bbbSMatthias Ringwald #include "btstack_run_loop.h" 522c4f9bbbSMatthias Ringwald #include "btstack_run_loop_embedded.h" 532c4f9bbbSMatthias Ringwald #include "bluetooth_company_id.h" 542c4f9bbbSMatthias Ringwald #include "hci_event.h" 552c4f9bbbSMatthias Ringwald #include "hci_transport.h" 562c4f9bbbSMatthias Ringwald #include "btstack_tlv.h" 572c4f9bbbSMatthias Ringwald #include "btstack_tlv_none.h" 582c4f9bbbSMatthias Ringwald #include "ble/le_device_db_tlv.h" 592c4f9bbbSMatthias Ringwald #include "hci_cmd.h" 602c4f9bbbSMatthias Ringwald 612c4f9bbbSMatthias Ringwald // HCI Connection Handle used for all HCI events/connections 622c4f9bbbSMatthias Ringwald #define HCI_CON_HANDLE 0x0001 632c4f9bbbSMatthias Ringwald 642c4f9bbbSMatthias Ringwald // 652c4f9bbbSMatthias Ringwald // Controller 662c4f9bbbSMatthias Ringwald // 672c4f9bbbSMatthias Ringwald static uint8_t send_hardware_error; 682c4f9bbbSMatthias Ringwald static bool send_transport_sent; 692c4f9bbbSMatthias Ringwald 702c4f9bbbSMatthias Ringwald static btstack_data_source_t hci_transport_data_source; 712c4f9bbbSMatthias Ringwald 722c4f9bbbSMatthias Ringwald static uint8_t hci_outgoing_event[258]; 732c4f9bbbSMatthias Ringwald static bool hci_outgoing_event_ready; 742c4f9bbbSMatthias Ringwald 752c4f9bbbSMatthias Ringwald static void (*hci_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 762c4f9bbbSMatthias Ringwald 772c4f9bbbSMatthias Ringwald /** BTstack Controller Implementation */ 782c4f9bbbSMatthias Ringwald 792c4f9bbbSMatthias Ringwald // Controller State 802c4f9bbbSMatthias Ringwald static bool controller_ll_acl_reserved; 812c4f9bbbSMatthias Ringwald 822c4f9bbbSMatthias Ringwald static void send_command_complete(uint16_t opcode, uint8_t status, const uint8_t * result, uint16_t len){ 832c4f9bbbSMatthias Ringwald hci_event_create_from_template_and_arguments(hci_outgoing_event, &hci_event_command_complete, 842c4f9bbbSMatthias Ringwald /* num commands */ 1, opcode, status, len, result); 852c4f9bbbSMatthias Ringwald hci_outgoing_event_ready = true; 86fb5f22f2SMatthias Ringwald btstack_run_loop_poll_data_sources_from_irq(); 872c4f9bbbSMatthias Ringwald } 882c4f9bbbSMatthias Ringwald 892c4f9bbbSMatthias Ringwald static void fake_command_complete(uint16_t opcode){ 902c4f9bbbSMatthias Ringwald hci_event_create_from_template_and_arguments(hci_outgoing_event, &hci_event_command_complete, 912c4f9bbbSMatthias Ringwald /* num commands */ 1, opcode, ERROR_CODE_SUCCESS, 0, NULL); 922c4f9bbbSMatthias Ringwald hci_outgoing_event_ready = true; 93fb5f22f2SMatthias Ringwald btstack_run_loop_poll_data_sources_from_irq(); 942c4f9bbbSMatthias Ringwald } 952c4f9bbbSMatthias Ringwald 962c4f9bbbSMatthias Ringwald static void controller_handle_hci_command(uint8_t * packet, uint16_t size){ 972c4f9bbbSMatthias Ringwald 982c4f9bbbSMatthias Ringwald btstack_assert(hci_outgoing_event_ready == false); 992c4f9bbbSMatthias Ringwald 1002c4f9bbbSMatthias Ringwald const uint8_t local_supported_features[] = { 0, 0, 0, 0, 0x40, 0, 0, 0}; 1012c4f9bbbSMatthias Ringwald const uint8_t read_buffer_size_result[] = { 0x1b, 0, HCI_NUM_TX_BUFFERS_STACK }; 1022c4f9bbbSMatthias Ringwald uint8_t status; 1032c4f9bbbSMatthias Ringwald 1042c4f9bbbSMatthias Ringwald uint16_t opcode = little_endian_read_16(packet, 0); 1052c4f9bbbSMatthias Ringwald switch (opcode){ 1062c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_RESET: 1072c4f9bbbSMatthias Ringwald fake_command_complete(opcode); 1082c4f9bbbSMatthias Ringwald break; 1092c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_READ_LOCAL_SUPPORTED_FEATURES: 1102c4f9bbbSMatthias Ringwald // No. 37, byte 4, bit 6 = LE Supported (Controller) 1112c4f9bbbSMatthias Ringwald send_command_complete(opcode, 0, local_supported_features, 8); 1122c4f9bbbSMatthias Ringwald break; 1132c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE: 1142c4f9bbbSMatthias Ringwald send_command_complete(opcode, 0, read_buffer_size_result, 8); 1152c4f9bbbSMatthias Ringwald break; 1162c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_SET_ADVERTISING_PARAMETERS: 1172c4f9bbbSMatthias Ringwald status = ll_set_advertising_parameters( 1182c4f9bbbSMatthias Ringwald little_endian_read_16(packet,3), 1192c4f9bbbSMatthias Ringwald little_endian_read_16(packet,5), 1202c4f9bbbSMatthias Ringwald packet[7], 1212c4f9bbbSMatthias Ringwald packet[8], 1222c4f9bbbSMatthias Ringwald packet[9], 1232c4f9bbbSMatthias Ringwald &packet[10], 1242c4f9bbbSMatthias Ringwald packet[16], 1252c4f9bbbSMatthias Ringwald packet[17]); 1262c4f9bbbSMatthias Ringwald send_command_complete(opcode, status, NULL, 0); 1272c4f9bbbSMatthias Ringwald break; 1282c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_SET_ADVERTISING_DATA: 1292c4f9bbbSMatthias Ringwald status = ll_set_advertising_data(packet[3], &packet[4]); 1302c4f9bbbSMatthias Ringwald send_command_complete(opcode, status, NULL, 0); 1312c4f9bbbSMatthias Ringwald break; 1322c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_SET_ADVERTISE_ENABLE: 1332c4f9bbbSMatthias Ringwald status = ll_set_advertise_enable(packet[3]); 1342c4f9bbbSMatthias Ringwald send_command_complete(opcode, status, NULL, 0); 1352c4f9bbbSMatthias Ringwald break; 1362c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_SET_SCAN_ENABLE: 1372c4f9bbbSMatthias Ringwald ll_set_scan_enable(packet[3], packet[4]); 1382c4f9bbbSMatthias Ringwald fake_command_complete(opcode); 1392c4f9bbbSMatthias Ringwald break; 1402c4f9bbbSMatthias Ringwald case HCI_OPCODE_HCI_LE_SET_SCAN_PARAMETERS: 1412c4f9bbbSMatthias Ringwald ll_set_scan_parameters(packet[3], little_endian_read_16(packet, 4), little_endian_read_16(packet, 6), packet[8], packet[9]); 1422c4f9bbbSMatthias Ringwald fake_command_complete(opcode); 1432c4f9bbbSMatthias Ringwald break; 1442c4f9bbbSMatthias Ringwald default: 1452c4f9bbbSMatthias Ringwald log_debug("CMD opcode %02x not handled yet", opcode); 1462c4f9bbbSMatthias Ringwald // try with "OK" 1472c4f9bbbSMatthias Ringwald fake_command_complete(opcode); 1482c4f9bbbSMatthias Ringwald break; 1492c4f9bbbSMatthias Ringwald } 1502c4f9bbbSMatthias Ringwald } 1512c4f9bbbSMatthias Ringwald 1522c4f9bbbSMatthias Ringwald // ACL handler 1532c4f9bbbSMatthias Ringwald static void controller_handle_acl_data(uint8_t * packet, uint16_t size){ 1542c4f9bbbSMatthias Ringwald // so far, only single connection supported with fixed con handle 1552c4f9bbbSMatthias Ringwald hci_con_handle_t con_handle = little_endian_read_16(packet, 0) & 0xfff; 1562c4f9bbbSMatthias Ringwald btstack_assert(con_handle == HCI_CON_HANDLE); 1572c4f9bbbSMatthias Ringwald btstack_assert( size > 4); 1582c4f9bbbSMatthias Ringwald 1592c4f9bbbSMatthias Ringwald // just queue up 1602c4f9bbbSMatthias Ringwald btstack_assert(controller_ll_acl_reserved); 1612c4f9bbbSMatthias Ringwald controller_ll_acl_reserved = false; 1622c4f9bbbSMatthias Ringwald ll_queue_acl_packet(packet, size); 1632c4f9bbbSMatthias Ringwald } 1642c4f9bbbSMatthias Ringwald 1652c4f9bbbSMatthias Ringwald static void transport_emit_hci_event(const hci_event_t * event, ...){ 1662c4f9bbbSMatthias Ringwald va_list argptr; 1672c4f9bbbSMatthias Ringwald va_start(argptr, event); 1682c4f9bbbSMatthias Ringwald uint16_t length = hci_event_create_from_template_and_arglist(hci_outgoing_event, event, argptr); 1692c4f9bbbSMatthias Ringwald va_end(argptr); 1702c4f9bbbSMatthias Ringwald hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, length); 1712c4f9bbbSMatthias Ringwald } 1722c4f9bbbSMatthias Ringwald 1732c4f9bbbSMatthias Ringwald static void transport_run(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 1742c4f9bbbSMatthias Ringwald 1752c4f9bbbSMatthias Ringwald // deliver command complete events caused by command processor 1762c4f9bbbSMatthias Ringwald if (hci_outgoing_event_ready){ 1772c4f9bbbSMatthias Ringwald hci_outgoing_event_ready = false; 1782c4f9bbbSMatthias Ringwald hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, hci_outgoing_event[1]+2); 1792c4f9bbbSMatthias Ringwald } 1802c4f9bbbSMatthias Ringwald 1812c4f9bbbSMatthias Ringwald if (send_hardware_error != 0){ 1822c4f9bbbSMatthias Ringwald uint8_t error_code = send_hardware_error; 1832c4f9bbbSMatthias Ringwald send_hardware_error = 0; 1842c4f9bbbSMatthias Ringwald transport_emit_hci_event(&hci_event_hardware_error, error_code); 1852c4f9bbbSMatthias Ringwald } 1862c4f9bbbSMatthias Ringwald 1872c4f9bbbSMatthias Ringwald if (send_transport_sent){ 1882c4f9bbbSMatthias Ringwald send_transport_sent = false; 1892c4f9bbbSMatthias Ringwald // notify upper stack that it might be possible to send again 1902c4f9bbbSMatthias Ringwald transport_emit_hci_event(&hci_event_transport_packet_sent); 1912c4f9bbbSMatthias Ringwald } 1922c4f9bbbSMatthias Ringwald 1932c4f9bbbSMatthias Ringwald ll_execute_once(); 1942c4f9bbbSMatthias Ringwald } 1952c4f9bbbSMatthias Ringwald 1962c4f9bbbSMatthias Ringwald static void transport_packet_handler(uint8_t packet_type, uint8_t * packet, uint16_t size){ 1972c4f9bbbSMatthias Ringwald // just forward to hci 1982c4f9bbbSMatthias Ringwald (*hci_packet_handler)(packet_type, packet, size); 1992c4f9bbbSMatthias Ringwald } 2002c4f9bbbSMatthias Ringwald 2012c4f9bbbSMatthias Ringwald /** 2022c4f9bbbSMatthias Ringwald * init transport 2032c4f9bbbSMatthias Ringwald * @param transport_config 2042c4f9bbbSMatthias Ringwald */ 2052c4f9bbbSMatthias Ringwald static void transport_init(const void *transport_config){ 2062c4f9bbbSMatthias Ringwald UNUSED(transport_config); 2072c4f9bbbSMatthias Ringwald ll_register_packet_handler(&transport_packet_handler); 2082c4f9bbbSMatthias Ringwald } 2092c4f9bbbSMatthias Ringwald 2102c4f9bbbSMatthias Ringwald /** 2112c4f9bbbSMatthias Ringwald * open transport connection 2122c4f9bbbSMatthias Ringwald */ 2132c4f9bbbSMatthias Ringwald static int transport_open(void){ 2142c4f9bbbSMatthias Ringwald btstack_run_loop_set_data_source_handler(&hci_transport_data_source, &transport_run); 2152c4f9bbbSMatthias Ringwald btstack_run_loop_enable_data_source_callbacks(&hci_transport_data_source, DATA_SOURCE_CALLBACK_POLL); 2162c4f9bbbSMatthias Ringwald btstack_run_loop_add_data_source(&hci_transport_data_source); 2172c4f9bbbSMatthias Ringwald 2182c4f9bbbSMatthias Ringwald ll_init(); 2192c4f9bbbSMatthias Ringwald ll_radio_on(); 2202c4f9bbbSMatthias Ringwald 2212c4f9bbbSMatthias Ringwald return 0; 2222c4f9bbbSMatthias Ringwald } 2232c4f9bbbSMatthias Ringwald 2242c4f9bbbSMatthias Ringwald /** 2252c4f9bbbSMatthias Ringwald * close transport connection 2262c4f9bbbSMatthias Ringwald */ 2272c4f9bbbSMatthias Ringwald static int transport_close(void){ 2282c4f9bbbSMatthias Ringwald btstack_run_loop_remove_data_source(&hci_transport_data_source); 2292c4f9bbbSMatthias Ringwald 2302c4f9bbbSMatthias Ringwald // TODO 2312c4f9bbbSMatthias Ringwald 2322c4f9bbbSMatthias Ringwald return 0; 2332c4f9bbbSMatthias Ringwald } 2342c4f9bbbSMatthias Ringwald 2352c4f9bbbSMatthias Ringwald /** 2362c4f9bbbSMatthias Ringwald * register packet handler for HCI packets: ACL, SCO, and Events 2372c4f9bbbSMatthias Ringwald */ 2382c4f9bbbSMatthias Ringwald static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 2392c4f9bbbSMatthias Ringwald hci_packet_handler = handler; 2402c4f9bbbSMatthias Ringwald } 2412c4f9bbbSMatthias Ringwald 2422c4f9bbbSMatthias Ringwald static int transport_can_send_packet_now(uint8_t packet_type){ 2432c4f9bbbSMatthias Ringwald if (send_transport_sent) return 0; 2442c4f9bbbSMatthias Ringwald switch (packet_type){ 2452c4f9bbbSMatthias Ringwald case HCI_COMMAND_DATA_PACKET: 2462c4f9bbbSMatthias Ringwald return hci_outgoing_event_ready ? 0 : 1; 2472c4f9bbbSMatthias Ringwald case HCI_ACL_DATA_PACKET: 2482c4f9bbbSMatthias Ringwald if (controller_ll_acl_reserved == false){ 2492c4f9bbbSMatthias Ringwald controller_ll_acl_reserved = ll_reserve_acl_packet(); 2502c4f9bbbSMatthias Ringwald } 2512c4f9bbbSMatthias Ringwald return controller_ll_acl_reserved ? 1 : 0; 2522c4f9bbbSMatthias Ringwald default: 2532c4f9bbbSMatthias Ringwald btstack_assert(false); 2542c4f9bbbSMatthias Ringwald break; 2552c4f9bbbSMatthias Ringwald } 2562c4f9bbbSMatthias Ringwald return 0; 2572c4f9bbbSMatthias Ringwald } 2582c4f9bbbSMatthias Ringwald 2592c4f9bbbSMatthias Ringwald static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 2602c4f9bbbSMatthias Ringwald switch (packet_type){ 2612c4f9bbbSMatthias Ringwald case HCI_COMMAND_DATA_PACKET: 2622c4f9bbbSMatthias Ringwald controller_handle_hci_command(packet, size); 2632c4f9bbbSMatthias Ringwald send_transport_sent = true; 2642c4f9bbbSMatthias Ringwald break; 2652c4f9bbbSMatthias Ringwald case HCI_ACL_DATA_PACKET: 2662c4f9bbbSMatthias Ringwald controller_handle_acl_data(packet, size); 2672c4f9bbbSMatthias Ringwald send_transport_sent = true; 2682c4f9bbbSMatthias Ringwald break; 2692c4f9bbbSMatthias Ringwald default: 2702c4f9bbbSMatthias Ringwald send_hardware_error = 0x01; // invalid HCI packet 2712c4f9bbbSMatthias Ringwald break; 2722c4f9bbbSMatthias Ringwald } 2732c4f9bbbSMatthias Ringwald return 0; 2742c4f9bbbSMatthias Ringwald } 2752c4f9bbbSMatthias Ringwald 2762c4f9bbbSMatthias Ringwald void controller_init(void){ 2772c4f9bbbSMatthias Ringwald } 2782c4f9bbbSMatthias Ringwald 2792c4f9bbbSMatthias Ringwald static const hci_transport_t controller_transport = { 2802c4f9bbbSMatthias Ringwald "sx1280-vhci", 2812c4f9bbbSMatthias Ringwald &transport_init, 2822c4f9bbbSMatthias Ringwald &transport_open, 2832c4f9bbbSMatthias Ringwald &transport_close, 2842c4f9bbbSMatthias Ringwald &transport_register_packet_handler, 2852c4f9bbbSMatthias Ringwald &transport_can_send_packet_now, 2862c4f9bbbSMatthias Ringwald &transport_send_packet, 2872c4f9bbbSMatthias Ringwald NULL, // set baud rate 2882c4f9bbbSMatthias Ringwald NULL, // reset link 2892c4f9bbbSMatthias Ringwald NULL, // set SCO config 2902c4f9bbbSMatthias Ringwald }; 2912c4f9bbbSMatthias Ringwald 2922c4f9bbbSMatthias Ringwald const hci_transport_t * controller_get_hci_transport(void){ 2932c4f9bbbSMatthias Ringwald return &controller_transport; 2942c4f9bbbSMatthias Ringwald } 295