1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #define LOG_TAG "bt_hci_h4" 20 21 #include <assert.h> 22 #include <errno.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #include "hci_hal.h" 27 #include "osi/include/eager_reader.h" 28 #include "osi/include/log.h" 29 #include "osi/include/osi.h" 30 #include "osi/include/reactor.h" 31 #include "osi/include/thread.h" 32 #include "vendor.h" 33 34 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026 35 #define HCI_BLE_EVENT 0x3e 36 37 // Increased HCI thread priority to keep up with the audio sub-system 38 // when streaming time sensitive data (A2DP). 39 #define HCI_THREAD_PRIORITY -19 40 41 // Our interface and modules we import 42 static const hci_hal_t interface; 43 static const hci_hal_callbacks_t *callbacks; 44 static const vendor_t *vendor; 45 46 static thread_t *thread; // Not owned by us 47 48 static int uart_fd; 49 static eager_reader_t *uart_stream; 50 static serial_data_type_t current_data_type; 51 static bool stream_has_interpretation; 52 static bool stream_corruption_detected; 53 static uint8_t stream_corruption_bytes_to_ignore; 54 55 static void event_uart_has_bytes(eager_reader_t *reader, void *context); 56 57 // Interface functions 58 hal_init(const hci_hal_callbacks_t * upper_callbacks,thread_t * upper_thread)59 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) { 60 assert(upper_callbacks != NULL); 61 assert(upper_thread != NULL); 62 63 callbacks = upper_callbacks; 64 thread = upper_thread; 65 return true; 66 } 67 hal_open()68 static bool hal_open() { 69 LOG_INFO(LOG_TAG, "%s", __func__); 70 // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level) 71 72 int fd_array[CH_MAX]; 73 int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array); 74 75 if (number_of_ports != 1) { 76 LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports); 77 goto error; 78 } 79 80 uart_fd = fd_array[0]; 81 if (uart_fd == INVALID_FD) { 82 LOG_ERROR(LOG_TAG, "%s unable to open the uart serial port.", __func__); 83 goto error; 84 } 85 86 uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel"); 87 if (!uart_stream) { 88 LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the uart serial port.", __func__); 89 goto error; 90 } 91 92 stream_has_interpretation = false; 93 stream_corruption_detected = false; 94 stream_corruption_bytes_to_ignore = 0; 95 eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL); 96 97 // Raise thread priorities to keep up with audio 98 thread_set_priority(thread, HCI_THREAD_PRIORITY); 99 thread_set_priority(eager_reader_get_read_thread(uart_stream), HCI_THREAD_PRIORITY); 100 101 return true; 102 103 error: 104 interface.close(); 105 return false; 106 } 107 hal_close()108 static void hal_close() { 109 LOG_INFO(LOG_TAG, "%s", __func__); 110 111 eager_reader_free(uart_stream); 112 vendor->send_command(VENDOR_CLOSE_USERIAL, NULL); 113 uart_fd = INVALID_FD; 114 } 115 read_data(serial_data_type_t type,uint8_t * buffer,size_t max_size)116 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) { 117 if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) { 118 LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type); 119 return 0; 120 } else if (!stream_has_interpretation) { 121 LOG_ERROR(LOG_TAG, "%s with no valid stream intepretation.", __func__); 122 return 0; 123 } else if (current_data_type != type) { 124 LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__); 125 return 0; 126 } 127 128 return eager_reader_read(uart_stream, buffer, max_size); 129 } 130 packet_finished(serial_data_type_t type)131 static void packet_finished(serial_data_type_t type) { 132 if (!stream_has_interpretation) 133 LOG_ERROR(LOG_TAG, "%s with no existing stream interpretation.", __func__); 134 else if (current_data_type != type) 135 LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__); 136 137 stream_has_interpretation = false; 138 } 139 transmit_data(serial_data_type_t type,uint8_t * data,uint16_t length)140 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) { 141 assert(data != NULL); 142 assert(length > 0); 143 144 if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) { 145 LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type); 146 return 0; 147 } 148 149 // Write the signal byte right before the data 150 --data; 151 uint8_t previous_byte = *data; 152 *(data) = type; 153 ++length; 154 155 uint16_t transmitted_length = 0; 156 while (length > 0) { 157 ssize_t ret; 158 OSI_NO_INTR(ret = write(uart_fd, data + transmitted_length, length)); 159 switch (ret) { 160 case -1: 161 LOG_ERROR(LOG_TAG, "In %s, error writing to the uart serial port: %s", __func__, strerror(errno)); 162 goto done; 163 case 0: 164 // If we wrote nothing, don't loop more because we 165 // can't go to infinity or beyond 166 goto done; 167 default: 168 transmitted_length += ret; 169 length -= ret; 170 break; 171 } 172 } 173 174 done:; 175 // Be nice and restore the old value of that byte 176 *(data) = previous_byte; 177 178 // Remove the signal byte from our transmitted length, if it was actually written 179 if (transmitted_length > 0) 180 --transmitted_length; 181 182 return transmitted_length; 183 } 184 185 // Internal functions 186 187 // WORKAROUND: 188 // As exhibited by b/23934838, during result-heavy LE scans, the UART byte 189 // stream can get corrupted, leading to assertions caused by mis-interpreting 190 // the bytes following the corruption. 191 // This workaround looks for tell-tale signs of a BLE event and attempts to 192 // skip the correct amount of bytes in the stream to re-synchronize onto 193 // a packet boundary. 194 // Function returns true if |byte_read| has been processed by the workaround. stream_corrupted_during_le_scan_workaround(const uint8_t byte_read)195 static bool stream_corrupted_during_le_scan_workaround(const uint8_t byte_read) 196 { 197 if (!stream_corruption_detected && byte_read == HCI_BLE_EVENT) { 198 LOG_ERROR(LOG_TAG, "%s HCI stream corrupted (message type 0x3E)!", __func__); 199 stream_corruption_detected = true; 200 return true; 201 } 202 203 if (stream_corruption_detected) { 204 if (stream_corruption_bytes_to_ignore == 0) { 205 stream_corruption_bytes_to_ignore = byte_read; 206 LOG_ERROR(LOG_TAG, "%s About to skip %d bytes...", __func__, stream_corruption_bytes_to_ignore); 207 } else { 208 --stream_corruption_bytes_to_ignore; 209 } 210 211 if (stream_corruption_bytes_to_ignore == 0) { 212 LOG_ERROR(LOG_TAG, "%s Back to our regularly scheduled program...", __func__); 213 stream_corruption_detected = false; 214 } 215 return true; 216 } 217 218 return false; 219 } 220 221 // See what data is waiting, and notify the upper layer event_uart_has_bytes(eager_reader_t * reader,UNUSED_ATTR void * context)222 static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) { 223 if (stream_has_interpretation) { 224 callbacks->data_ready(current_data_type); 225 } else { 226 uint8_t type_byte; 227 if (eager_reader_read(reader, &type_byte, 1) == 0) { 228 LOG_ERROR(LOG_TAG, "%s could not read HCI message type", __func__); 229 return; 230 } 231 232 if (stream_corrupted_during_le_scan_workaround(type_byte)) 233 return; 234 235 if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) { 236 LOG_ERROR(LOG_TAG, "%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT); 237 return; 238 } 239 240 stream_has_interpretation = true; 241 current_data_type = type_byte; 242 } 243 } 244 245 static const hci_hal_t interface = { 246 hal_init, 247 248 hal_open, 249 hal_close, 250 251 read_data, 252 packet_finished, 253 transmit_data, 254 }; 255 hci_hal_h4_get_interface()256 const hci_hal_t *hci_hal_h4_get_interface() { 257 vendor = vendor_get_interface(); 258 return &interface; 259 } 260 hci_hal_h4_get_test_interface(vendor_t * vendor_interface)261 const hci_hal_t *hci_hal_h4_get_test_interface(vendor_t *vendor_interface) { 262 vendor = vendor_interface; 263 return &interface; 264 } 265