• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
hal_init(const hci_hal_callbacks_t * upper_callbacks,thread_t * upper_thread)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  
hal_open()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  
hal_close()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  
read_data(serial_data_type_t type,uint8_t * buffer,size_t max_size)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  
packet_finished(UNUSED_ATTR serial_data_type_t type)140  static void packet_finished(UNUSED_ATTR serial_data_type_t type) {
141    // not needed by this protocol
142  }
143  
transmit_data(serial_data_type_t type,uint8_t * data,uint16_t length)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  
transmit_data_on(int fd,uint8_t * data,uint16_t length)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  
event_event_stream_has_bytes(UNUSED_ATTR eager_reader_t * reader,UNUSED_ATTR void * context)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  
event_acl_stream_has_bytes(UNUSED_ATTR eager_reader_t * reader,UNUSED_ATTR void * context)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  
hci_hal_mct_get_interface()203  const hci_hal_t *hci_hal_mct_get_interface() {
204    vendor = vendor_get_interface();
205    return &interface;
206  }
207  
hci_hal_mct_get_test_interface(vendor_t * vendor_interface)208  const hci_hal_t *hci_hal_mct_get_test_interface(vendor_t *vendor_interface) {
209    vendor = vendor_interface;
210    return &interface;
211  }
212