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_mct"
     20 
     21 #include <assert.h>
     22 #include <errno.h>
     23 #include <string.h>
     24 #include <unistd.h>
     25 
     26 #include "bt_vendor_lib.h"
     27 #include "hci_hal.h"
     28 #include "osi/include/eager_reader.h"
     29 #include "osi/include/log.h"
     30 #include "osi/include/osi.h"
     31 #include "osi/include/reactor.h"
     32 #include "vendor.h"
     33 
     34 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
     35 
     36 // Our interface and modules we import
     37 static const hci_hal_t interface;
     38 static const hci_hal_callbacks_t *callbacks;
     39 static const vendor_t *vendor;
     40 
     41 static thread_t *thread; // Not owned by us
     42 
     43 static int uart_fds[CH_MAX];
     44 static eager_reader_t *event_stream;
     45 static eager_reader_t *acl_stream;
     46 
     47 static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length);
     48 static void event_event_stream_has_bytes(eager_reader_t *reader, void *context);
     49 static void event_acl_stream_has_bytes(eager_reader_t *reader, void *context);
     50 
     51 // Interface functions
     52 
     53 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
     54   assert(upper_callbacks != NULL);
     55   assert(upper_thread != NULL);
     56 
     57   callbacks = upper_callbacks;
     58   thread = upper_thread;
     59   return true;
     60 }
     61 
     62 static bool hal_open() {
     63   LOG_INFO(LOG_TAG, "%s", __func__);
     64   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
     65 
     66   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &uart_fds);
     67 
     68   if (number_of_ports != 2 && number_of_ports != 4) {
     69     LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 2 or 4.", __func__, number_of_ports);
     70     goto error;
     71   }
     72 
     73   LOG_INFO(LOG_TAG, "%s got uart fds: CMD=%d, EVT=%d, ACL_OUT=%d, ACL_IN=%d",
     74       __func__, uart_fds[CH_CMD], uart_fds[CH_EVT], uart_fds[CH_ACL_OUT], uart_fds[CH_ACL_IN]);
     75 
     76   if (uart_fds[CH_CMD] == INVALID_FD) {
     77     LOG_ERROR(LOG_TAG, "%s unable to open the command uart serial port.", __func__);
     78     goto error;
     79   }
     80 
     81   if (uart_fds[CH_EVT] == INVALID_FD) {
     82     LOG_ERROR(LOG_TAG, "%s unable to open the event uart serial port.", __func__);
     83     goto error;
     84   }
     85 
     86   if (uart_fds[CH_ACL_OUT] == INVALID_FD) {
     87     LOG_ERROR(LOG_TAG, "%s unable to open the acl-out uart serial port.", __func__);
     88     goto error;
     89   }
     90 
     91   if (uart_fds[CH_ACL_IN] == INVALID_FD) {
     92     LOG_ERROR(LOG_TAG, "%s unable to open the acl-in uart serial port.", __func__);
     93     goto error;
     94   }
     95 
     96   event_stream = eager_reader_new(uart_fds[CH_EVT], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
     97   if (!event_stream) {
     98     LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the event uart serial port.", __func__);
     99     goto error;
    100   }
    101 
    102   acl_stream = eager_reader_new(uart_fds[CH_ACL_IN], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
    103   if (!acl_stream) {
    104     LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the acl-in uart serial port.", __func__);
    105     goto error;
    106   }
    107 
    108   eager_reader_register(event_stream, thread_get_reactor(thread), event_event_stream_has_bytes, NULL);
    109   eager_reader_register(acl_stream, thread_get_reactor(thread), event_acl_stream_has_bytes, NULL);
    110 
    111   return true;
    112 
    113 error:;
    114   interface.close();
    115   return false;
    116 }
    117 
    118 static void hal_close() {
    119   LOG_INFO(LOG_TAG, "%s", __func__);
    120 
    121   eager_reader_free(event_stream);
    122   eager_reader_free(acl_stream);
    123   vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
    124 
    125   for (int i = 0; i < CH_MAX; i++)
    126     uart_fds[i] = INVALID_FD;
    127 }
    128 
    129 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) {
    130   if (type == DATA_TYPE_ACL) {
    131     return eager_reader_read(acl_stream, buffer, max_size);
    132   } else if (type == DATA_TYPE_EVENT) {
    133     return eager_reader_read(event_stream, buffer, max_size);
    134   }
    135 
    136   LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
    137   return 0;
    138 }
    139 
    140 static void packet_finished(UNUSED_ATTR serial_data_type_t type) {
    141   // not needed by this protocol
    142 }
    143 
    144 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
    145   if (type == DATA_TYPE_ACL) {
    146     return transmit_data_on(uart_fds[CH_ACL_OUT], data, length);
    147   } else if (type == DATA_TYPE_COMMAND) {
    148     return transmit_data_on(uart_fds[CH_CMD], data, length);
    149   }
    150 
    151   LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
    152   return 0;
    153 }
    154 
    155 // Internal functions
    156 
    157 static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
    158   assert(data != NULL);
    159   assert(length > 0);
    160 
    161   uint16_t transmitted_length = 0;
    162   while (length > 0) {
    163     ssize_t ret;
    164     OSI_NO_INTR(ret = write(fd, data + transmitted_length, length));
    165     switch (ret) {
    166       case -1:
    167         LOG_ERROR(LOG_TAG, "In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
    168         return transmitted_length;
    169       case 0:
    170         // If we wrote nothing, don't loop more because we
    171         // can't go to infinity or beyond
    172         return transmitted_length;
    173       default:
    174         transmitted_length += ret;
    175         length -= ret;
    176         break;
    177     }
    178   }
    179 
    180   return transmitted_length;
    181 }
    182 
    183 static void event_event_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
    184   callbacks->data_ready(DATA_TYPE_EVENT);
    185 }
    186 
    187 static void event_acl_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
    188   // No real concept of incoming SCO typed data, just ACL
    189   callbacks->data_ready(DATA_TYPE_ACL);
    190 }
    191 
    192 static const hci_hal_t interface = {
    193   hal_init,
    194 
    195   hal_open,
    196   hal_close,
    197 
    198   read_data,
    199   packet_finished,
    200   transmit_data,
    201 };
    202 
    203 const hci_hal_t *hci_hal_mct_get_interface() {
    204   vendor = vendor_get_interface();
    205   return &interface;
    206 }
    207 
    208 const hci_hal_t *hci_hal_mct_get_test_interface(vendor_t *vendor_interface) {
    209   vendor = vendor_interface;
    210   return &interface;
    211 }
    212