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 BLUEKITCHEN 24 * GMBH 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, sizeof(hci_outgoing_event), 84 &hci_event_command_complete, /* num commands */ 1, opcode, status, len, result); 85 hci_outgoing_event_ready = true; 86 btstack_run_loop_poll_data_sources_from_irq(); 87 } 88 89 static void fake_command_complete(uint16_t opcode){ 90 hci_event_create_from_template_and_arguments(hci_outgoing_event, sizeof(hci_outgoing_event), 91 &hci_event_command_complete, /* num commands */ 1, opcode, ERROR_CODE_SUCCESS, 0, NULL); 92 hci_outgoing_event_ready = true; 93 btstack_run_loop_poll_data_sources_from_irq(); 94 } 95 96 static void controller_handle_hci_command(uint8_t * packet, uint16_t size){ 97 98 btstack_assert(hci_outgoing_event_ready == false); 99 100 const uint8_t local_supported_features[] = { 0, 0, 0, 0, 0x40, 0, 0, 0}; 101 const uint8_t read_buffer_size_result[] = { 0x1b, 0, HCI_NUM_TX_BUFFERS_STACK }; 102 uint8_t status; 103 104 uint16_t opcode = little_endian_read_16(packet, 0); 105 switch (opcode){ 106 case HCI_OPCODE_HCI_RESET: 107 fake_command_complete(opcode); 108 break; 109 case HCI_OPCODE_HCI_READ_LOCAL_SUPPORTED_FEATURES: 110 // No. 37, byte 4, bit 6 = LE Supported (Controller) 111 send_command_complete(opcode, 0, local_supported_features, 8); 112 break; 113 case HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE: 114 send_command_complete(opcode, 0, read_buffer_size_result, 8); 115 break; 116 case HCI_OPCODE_HCI_LE_SET_ADVERTISING_PARAMETERS: 117 status = ll_set_advertising_parameters( 118 little_endian_read_16(packet,3), 119 little_endian_read_16(packet,5), 120 packet[7], 121 packet[8], 122 packet[9], 123 &packet[10], 124 packet[16], 125 packet[17]); 126 send_command_complete(opcode, status, NULL, 0); 127 break; 128 case HCI_OPCODE_HCI_LE_SET_ADVERTISING_DATA: 129 status = ll_set_advertising_data(packet[3], &packet[4]); 130 send_command_complete(opcode, status, NULL, 0); 131 break; 132 case HCI_OPCODE_HCI_LE_SET_ADVERTISE_ENABLE: 133 status = ll_set_advertise_enable(packet[3]); 134 send_command_complete(opcode, status, NULL, 0); 135 break; 136 case HCI_OPCODE_HCI_LE_SET_SCAN_ENABLE: 137 ll_set_scan_enable(packet[3], packet[4]); 138 fake_command_complete(opcode); 139 break; 140 case HCI_OPCODE_HCI_LE_SET_SCAN_PARAMETERS: 141 ll_set_scan_parameters(packet[3], little_endian_read_16(packet, 4), little_endian_read_16(packet, 6), packet[8], packet[9]); 142 fake_command_complete(opcode); 143 break; 144 default: 145 log_debug("CMD opcode %02x not handled yet", opcode); 146 // try with "OK" 147 fake_command_complete(opcode); 148 break; 149 } 150 } 151 152 // ACL handler 153 static void controller_handle_acl_data(uint8_t * packet, uint16_t size){ 154 // so far, only single connection supported with fixed con handle 155 hci_con_handle_t con_handle = little_endian_read_16(packet, 0) & 0xfff; 156 btstack_assert(con_handle == HCI_CON_HANDLE); 157 btstack_assert( size > 4); 158 159 // just queue up 160 btstack_assert(controller_ll_acl_reserved); 161 controller_ll_acl_reserved = false; 162 ll_queue_acl_packet(packet, size); 163 } 164 165 static void transport_emit_hci_event(const hci_event_t * event, ...){ 166 va_list argptr; 167 va_start(argptr, event); 168 uint16_t length = hci_event_create_from_template_and_arglist(hci_outgoing_event, sizeof(hci_outgoing_event), event, argptr); 169 va_end(argptr); 170 hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, length); 171 } 172 173 static void transport_run(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 174 175 // deliver command complete events caused by command processor 176 if (hci_outgoing_event_ready){ 177 hci_outgoing_event_ready = false; 178 hci_packet_handler(HCI_EVENT_PACKET, hci_outgoing_event, hci_outgoing_event[1]+2); 179 } 180 181 if (send_hardware_error != 0){ 182 uint8_t error_code = send_hardware_error; 183 send_hardware_error = 0; 184 transport_emit_hci_event(&hci_event_hardware_error, error_code); 185 } 186 187 if (send_transport_sent){ 188 send_transport_sent = false; 189 // notify upper stack that it might be possible to send again 190 transport_emit_hci_event(&hci_event_transport_packet_sent); 191 } 192 193 ll_execute_once(); 194 } 195 196 static void transport_packet_handler(uint8_t packet_type, uint8_t * packet, uint16_t size){ 197 // just forward to hci 198 (*hci_packet_handler)(packet_type, packet, size); 199 } 200 201 /** 202 * init transport 203 * @param transport_config 204 */ 205 static void transport_init(const void *transport_config){ 206 UNUSED(transport_config); 207 ll_register_packet_handler(&transport_packet_handler); 208 } 209 210 /** 211 * open transport connection 212 */ 213 static int transport_open(void){ 214 btstack_run_loop_set_data_source_handler(&hci_transport_data_source, &transport_run); 215 btstack_run_loop_enable_data_source_callbacks(&hci_transport_data_source, DATA_SOURCE_CALLBACK_POLL); 216 btstack_run_loop_add_data_source(&hci_transport_data_source); 217 218 ll_init(); 219 ll_radio_on(); 220 221 return 0; 222 } 223 224 /** 225 * close transport connection 226 */ 227 static int transport_close(void){ 228 btstack_run_loop_remove_data_source(&hci_transport_data_source); 229 230 // TODO 231 232 return 0; 233 } 234 235 /** 236 * register packet handler for HCI packets: ACL, SCO, and Events 237 */ 238 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 239 hci_packet_handler = handler; 240 } 241 242 static int transport_can_send_packet_now(uint8_t packet_type){ 243 if (send_transport_sent) return 0; 244 switch (packet_type){ 245 case HCI_COMMAND_DATA_PACKET: 246 return hci_outgoing_event_ready ? 0 : 1; 247 case HCI_ACL_DATA_PACKET: 248 if (controller_ll_acl_reserved == false){ 249 controller_ll_acl_reserved = ll_reserve_acl_packet(); 250 } 251 return controller_ll_acl_reserved ? 1 : 0; 252 default: 253 btstack_assert(false); 254 break; 255 } 256 return 0; 257 } 258 259 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 260 switch (packet_type){ 261 case HCI_COMMAND_DATA_PACKET: 262 controller_handle_hci_command(packet, size); 263 send_transport_sent = true; 264 break; 265 case HCI_ACL_DATA_PACKET: 266 controller_handle_acl_data(packet, size); 267 send_transport_sent = true; 268 break; 269 default: 270 send_hardware_error = 0x01; // invalid HCI packet 271 break; 272 } 273 return 0; 274 } 275 276 void controller_init(void){ 277 } 278 279 static const hci_transport_t controller_transport = { 280 "sx1280-vhci", 281 &transport_init, 282 &transport_open, 283 &transport_close, 284 &transport_register_packet_handler, 285 &transport_can_send_packet_now, 286 &transport_send_packet, 287 NULL, // set baud rate 288 NULL, // reset link 289 NULL, // set SCO config 290 }; 291 292 const hci_transport_t * controller_get_hci_transport(void){ 293 return &controller_transport; 294 } 295