Home | History | Annotate | Download | only in src
      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 #define BT_HCI_UNKNOWN_MESSAGE_TYPE_NUM 1010002
     42 
     43 // Our interface and modules we import
     44 static const hci_hal_t interface;
     45 static const hci_hal_callbacks_t *callbacks;
     46 static const vendor_t *vendor;
     47 
     48 static thread_t *thread; // Not owned by us
     49 
     50 static int uart_fd;
     51 static eager_reader_t *uart_stream;
     52 static serial_data_type_t current_data_type;
     53 static bool stream_has_interpretation;
     54 static bool stream_corruption_detected;
     55 static uint8_t stream_corruption_bytes_to_ignore;
     56 
     57 static void event_uart_has_bytes(eager_reader_t *reader, void *context);
     58 
     59 // Interface functions
     60 
     61 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
     62   assert(upper_callbacks != NULL);
     63   assert(upper_thread != NULL);
     64 
     65   callbacks = upper_callbacks;
     66   thread = upper_thread;
     67   return true;
     68 }
     69 
     70 static bool hal_open() {
     71   LOG_INFO(LOG_TAG, "%s", __func__);
     72   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
     73 
     74   int fd_array[CH_MAX];
     75   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array);
     76 
     77   if (number_of_ports != 1) {
     78     LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports);
     79     goto error;
     80   }
     81 
     82   uart_fd = fd_array[0];
     83   if (uart_fd == INVALID_FD) {
     84     LOG_ERROR(LOG_TAG, "%s unable to open the uart serial port.", __func__);
     85     goto error;
     86   }
     87 
     88   uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel");
     89   if (!uart_stream) {
     90     LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the uart serial port.", __func__);
     91     goto error;
     92   }
     93 
     94   stream_has_interpretation = false;
     95   stream_corruption_detected = false;
     96   stream_corruption_bytes_to_ignore = 0;
     97   eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL);
     98 
     99   // Raise thread priorities to keep up with audio
    100   thread_set_priority(thread, HCI_THREAD_PRIORITY);
    101   thread_set_priority(eager_reader_get_read_thread(uart_stream), HCI_THREAD_PRIORITY);
    102 
    103   return true;
    104 
    105 error:
    106   interface.close();
    107   return false;
    108 }
    109 
    110 static void hal_close() {
    111   LOG_INFO(LOG_TAG, "%s", __func__);
    112 
    113   eager_reader_free(uart_stream);
    114   vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
    115   uart_fd = INVALID_FD;
    116 }
    117 
    118 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) {
    119   if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
    120     LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
    121     return 0;
    122   } else if (!stream_has_interpretation) {
    123     LOG_ERROR(LOG_TAG, "%s with no valid stream intepretation.", __func__);
    124     return 0;
    125   } else if (current_data_type != type) {
    126     LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
    127     return 0;
    128   }
    129 
    130   return eager_reader_read(uart_stream, buffer, max_size);
    131 }
    132 
    133 static void packet_finished(serial_data_type_t type) {
    134   if (!stream_has_interpretation)
    135     LOG_ERROR(LOG_TAG, "%s with no existing stream interpretation.", __func__);
    136   else if (current_data_type != type)
    137     LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
    138 
    139   stream_has_interpretation = false;
    140 }
    141 
    142 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
    143   assert(data != NULL);
    144   assert(length > 0);
    145 
    146   if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
    147     LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
    148     return 0;
    149   }
    150 
    151   // Write the signal byte right before the data
    152   --data;
    153   uint8_t previous_byte = *data;
    154   *(data) = type;
    155   ++length;
    156 
    157   uint16_t transmitted_length = 0;
    158   while (length > 0) {
    159     ssize_t ret;
    160     OSI_NO_INTR(ret = write(uart_fd, data + transmitted_length, length));
    161     switch (ret) {
    162       case -1:
    163         LOG_ERROR(LOG_TAG, "In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
    164         goto done;
    165       case 0:
    166         // If we wrote nothing, don't loop more because we
    167         // can't go to infinity or beyond
    168         goto done;
    169       default:
    170         transmitted_length += ret;
    171         length -= ret;
    172         break;
    173     }
    174   }
    175 
    176 done:;
    177   // Be nice and restore the old value of that byte
    178   *(data) = previous_byte;
    179 
    180   // Remove the signal byte from our transmitted length, if it was actually written
    181   if (transmitted_length > 0)
    182     --transmitted_length;
    183 
    184   return transmitted_length;
    185 }
    186 
    187 // Internal functions
    188 
    189 // WORKAROUND:
    190 // As exhibited by b/23934838, during result-heavy LE scans, the UART byte
    191 // stream can get corrupted, leading to assertions caused by mis-interpreting
    192 // the bytes following the corruption.
    193 // This workaround looks for tell-tale signs of a BLE event and attempts to
    194 // skip the correct amount of bytes in the stream to re-synchronize onto
    195 // a packet boundary.
    196 // Function returns true if |byte_read| has been processed by the workaround.
    197 static bool stream_corrupted_during_le_scan_workaround(const uint8_t byte_read)
    198 {
    199   if (!stream_corruption_detected && byte_read == HCI_BLE_EVENT) {
    200     LOG_ERROR(LOG_TAG, "%s HCI stream corrupted (message type 0x3E)!", __func__);
    201     stream_corruption_detected = true;
    202     return true;
    203   }
    204 
    205   if (stream_corruption_detected) {
    206     if (stream_corruption_bytes_to_ignore == 0) {
    207       stream_corruption_bytes_to_ignore = byte_read;
    208       LOG_ERROR(LOG_TAG, "%s About to skip %d bytes...", __func__, stream_corruption_bytes_to_ignore);
    209     } else {
    210       --stream_corruption_bytes_to_ignore;
    211     }
    212 
    213     if (stream_corruption_bytes_to_ignore == 0) {
    214       LOG_ERROR(LOG_TAG, "%s Back to our regularly scheduled program...", __func__);
    215       stream_corruption_detected = false;
    216     }
    217     return true;
    218   }
    219 
    220   return false;
    221 }
    222 
    223 // See what data is waiting, and notify the upper layer
    224 static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) {
    225   if (stream_has_interpretation) {
    226     callbacks->data_ready(current_data_type);
    227   } else {
    228     uint8_t type_byte;
    229     if (eager_reader_read(reader, &type_byte, 1) == 0) {
    230       LOG_ERROR(LOG_TAG, "%s could not read HCI message type", __func__);
    231       return;
    232     }
    233 
    234     if (stream_corrupted_during_le_scan_workaround(type_byte))
    235       return;
    236 
    237     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
    238       LOG_ERROR(LOG_TAG, "%s Unknown HCI message type 0x%x (min=0x%x max=0x%x). Aborting...",
    239                 __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
    240       LOG_EVENT_INT(BT_HCI_UNKNOWN_MESSAGE_TYPE_NUM, type_byte);
    241       assert(false && "Unknown HCI message type");
    242       return;
    243     }
    244 
    245     stream_has_interpretation = true;
    246     current_data_type = type_byte;
    247   }
    248 }
    249 
    250 static const hci_hal_t interface = {
    251   hal_init,
    252 
    253   hal_open,
    254   hal_close,
    255 
    256   read_data,
    257   packet_finished,
    258   transmit_data,
    259 };
    260 
    261 const hci_hal_t *hci_hal_h4_get_interface() {
    262   vendor = vendor_get_interface();
    263   return &interface;
    264 }
    265 
    266 const hci_hal_t *hci_hal_h4_get_test_interface(vendor_t *vendor_interface) {
    267   vendor = vendor_interface;
    268   return &interface;
    269 }
    270