1 /* 2 * Copyright (C) 2020 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "controller.c" 39 40 #define DEBUG 41 42 #include <string.h> 43 44 #include "controller.h" 45 46 #include "ll.h" 47 48 #include "btstack_config.h" 49 #include "btstack_debug.h" 50 #include "btstack_util.h" 51 #include "btstack_run_loop.h" 52 #include "btstack_run_loop_embedded.h" 53 #include "bluetooth_company_id.h" 54 #include "hci_event.h" 55 #include "hci_transport.h" 56 #include "btstack_tlv.h" 57 #include "btstack_tlv_none.h" 58 #include "ble/le_device_db_tlv.h" 59 #include "hci_cmd.h" 60 61 // HCI Connection Handle used for all HCI events/connections 62 #define HCI_CON_HANDLE 0x0001 63 64 // 65 // Controller 66 // 67 static uint8_t send_hardware_error; 68 static bool send_transport_sent; 69 70 static btstack_data_source_t hci_transport_data_source; 71 72 static uint8_t hci_outgoing_event[258]; 73 static bool hci_outgoing_event_ready; 74 75 static void (*hci_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 76 77 /** BTstack Controller Implementation */ 78 79 // Controller State 80 static bool controller_ll_acl_reserved; 81 82 static void send_command_complete(uint16_t opcode, uint8_t status, const uint8_t * result, uint16_t len){ 83 hci_event_create_from_template_and_arguments(hci_outgoing_event, &hci_event_command_complete, 84 /* num commands */ 1, opcode, status, len, result); 85 hci_outgoing_event_ready = true; 86 } 87 88 static void fake_command_complete(uint16_t opcode){ 89 hci_event_create_from_template_and_arguments(hci_outgoing_event, &hci_event_command_complete, 90 /* num commands */ 1, opcode, ERROR_CODE_SUCCESS, 0, NULL); 91 hci_outgoing_event_ready = true; 92 } 93 94 static void controller_handle_hci_command(uint8_t * packet, uint16_t size){ 95 96 btstack_assert(hci_outgoing_event_ready == false); 97 98 const uint8_t local_supported_features[] = { 0, 0, 0, 0, 0x40, 0, 0, 0}; 99 const uint8_t read_buffer_size_result[] = { 0x1b, 0, HCI_NUM_TX_BUFFERS_STACK }; 100 uint8_t status; 101 102 uint16_t opcode = little_endian_read_16(packet, 0); 103 switch (opcode){ 104 case HCI_OPCODE_HCI_RESET: 105 fake_command_complete(opcode); 106 break; 107 case HCI_OPCODE_HCI_READ_LOCAL_SUPPORTED_FEATURES: 108 // No. 37, byte 4, bit 6 = LE Supported (Controller) 109 send_command_complete(opcode, 0, local_supported_features, 8); 110 break; 111 case HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE: 112 send_command_complete(opcode, 0, read_buffer_size_result, 8); 113 break; 114 case HCI_OPCODE_HCI_LE_SET_ADVERTISING_PARAMETERS: 115 status = ll_set_advertising_parameters( 116 little_endian_read_16(packet,3), 117 little_endian_read_16(packet,5), 118 packet[7], 119 packet[8], 120 packet[9], 121 &packet[10], 122 packet[16], 123 packet[17]); 124 send_command_complete(opcode, status, NULL, 0); 125 break; 126 case HCI_OPCODE_HCI_LE_SET_ADVERTISING_DATA: 127 status = ll_set_advertising_data(packet[3], &packet[4]); 128 send_command_complete(opcode, status, NULL, 0); 129 break; 130 case HCI_OPCODE_HCI_LE_SET_ADVERTISE_ENABLE: 131 status = ll_set_advertise_enable(packet[3]); 132 send_command_complete(opcode, status, NULL, 0); 133 break; 134 case HCI_OPCODE_HCI_LE_SET_SCAN_ENABLE: 135 ll_set_scan_enable(packet[3], packet[4]); 136 fake_command_complete(opcode); 137 break; 138 case HCI_OPCODE_HCI_LE_SET_SCAN_PARAMETERS: 139 ll_set_scan_parameters(packet[3], little_endian_read_16(packet, 4), little_endian_read_16(packet, 6), packet[8], packet[9]); 140 fake_command_complete(opcode); 141 break; 142 default: 143 log_debug("CMD opcode %02x not handled yet", opcode); 144 // try with "OK" 145 fake_command_complete(opcode); 146 break; 147 } 148 } 149 150 // ACL handler 151 static void controller_handle_acl_data(uint8_t * packet, uint16_t size){ 152 // so far, only single connection supported with fixed con handle 153 hci_con_handle_t con_handle = little_endian_read_16(packet, 0) & 0xfff; 154 btstack_assert(con_handle == HCI_CON_HANDLE); 155 btstack_assert( size > 4); 156 157 // just queue up 158 btstack_assert(controller_ll_acl_reserved); 159 controller_ll_acl_reserved = false; 160 ll_queue_acl_packet(packet, size); 161 } 162 163 static void transport_emit_hci_event(const hci_event_t * event, ...){ 164 va_list argptr; 165 va_start(argptr, event); 166 uint16_t length = hci_event_create_from_template_and_arglist(hci_outgoing_event, event, argptr); 167 va_end(argptr); 168 hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, length); 169 } 170 171 static void transport_run(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 172 173 // deliver command complete events caused by command processor 174 if (hci_outgoing_event_ready){ 175 hci_outgoing_event_ready = false; 176 hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, hci_outgoing_event[1]+2); 177 } 178 179 if (send_hardware_error != 0){ 180 uint8_t error_code = send_hardware_error; 181 send_hardware_error = 0; 182 transport_emit_hci_event(&hci_event_hardware_error, error_code); 183 } 184 185 if (send_transport_sent){ 186 send_transport_sent = false; 187 // notify upper stack that it might be possible to send again 188 transport_emit_hci_event(&hci_event_transport_packet_sent); 189 } 190 191 ll_execute_once(); 192 } 193 194 static void transport_packet_handler(uint8_t packet_type, uint8_t * packet, uint16_t size){ 195 // just forward to hci 196 (*hci_packet_handler)(packet_type, packet, size); 197 } 198 199 /** 200 * init transport 201 * @param transport_config 202 */ 203 static void transport_init(const void *transport_config){ 204 UNUSED(transport_config); 205 ll_register_packet_handler(&transport_packet_handler); 206 } 207 208 /** 209 * open transport connection 210 */ 211 static int transport_open(void){ 212 btstack_run_loop_set_data_source_handler(&hci_transport_data_source, &transport_run); 213 btstack_run_loop_enable_data_source_callbacks(&hci_transport_data_source, DATA_SOURCE_CALLBACK_POLL); 214 btstack_run_loop_add_data_source(&hci_transport_data_source); 215 216 ll_init(); 217 ll_radio_on(); 218 219 return 0; 220 } 221 222 /** 223 * close transport connection 224 */ 225 static int transport_close(void){ 226 btstack_run_loop_remove_data_source(&hci_transport_data_source); 227 228 // TODO 229 230 return 0; 231 } 232 233 /** 234 * register packet handler for HCI packets: ACL, SCO, and Events 235 */ 236 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 237 hci_packet_handler = handler; 238 } 239 240 static int transport_can_send_packet_now(uint8_t packet_type){ 241 if (send_transport_sent) return 0; 242 switch (packet_type){ 243 case HCI_COMMAND_DATA_PACKET: 244 return hci_outgoing_event_ready ? 0 : 1; 245 case HCI_ACL_DATA_PACKET: 246 if (controller_ll_acl_reserved == false){ 247 controller_ll_acl_reserved = ll_reserve_acl_packet(); 248 } 249 return controller_ll_acl_reserved ? 1 : 0; 250 default: 251 btstack_assert(false); 252 break; 253 } 254 return 0; 255 } 256 257 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 258 switch (packet_type){ 259 case HCI_COMMAND_DATA_PACKET: 260 controller_handle_hci_command(packet, size); 261 send_transport_sent = true; 262 break; 263 case HCI_ACL_DATA_PACKET: 264 controller_handle_acl_data(packet, size); 265 send_transport_sent = true; 266 break; 267 default: 268 send_hardware_error = 0x01; // invalid HCI packet 269 break; 270 } 271 return 0; 272 } 273 274 void controller_init(void){ 275 } 276 277 static const hci_transport_t controller_transport = { 278 "sx1280-vhci", 279 &transport_init, 280 &transport_open, 281 &transport_close, 282 &transport_register_packet_handler, 283 &transport_can_send_packet_now, 284 &transport_send_packet, 285 NULL, // set baud rate 286 NULL, // reset link 287 NULL, // set SCO config 288 }; 289 290 const hci_transport_t * controller_get_hci_transport(void){ 291 return &controller_transport; 292 } 293