1 /******************************************************************************
3 * Copyright (C) 2014 Google, Inc.
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 #define LOG_TAG "bt_hci_mct"
25 #include "bt_vendor_lib.h"
26 #include "osi/include/eager_reader.h"
28 #include "osi/include/osi.h"
29 #include "osi/include/log.h"
30 #include "osi/include/reactor.h"
33 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
35 // Our interface and modules we import
36 static const hci_hal_t interface;
37 static const hci_hal_callbacks_t *callbacks;
38 static const vendor_t *vendor;
40 static thread_t *thread; // Not owned by us
42 static int uart_fds[CH_MAX];
43 static eager_reader_t *event_stream;
44 static eager_reader_t *acl_stream;
46 static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length);
47 static void event_event_stream_has_bytes(eager_reader_t *reader, void *context);
48 static void event_acl_stream_has_bytes(eager_reader_t *reader, void *context);
50 // Interface functions
52 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
53 assert(upper_callbacks != NULL);
54 assert(upper_thread != NULL);
56 callbacks = upper_callbacks;
57 thread = upper_thread;
61 static bool hal_open() {
62 LOG_INFO("%s", __func__);
63 // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
65 int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &uart_fds);
67 if (number_of_ports != 2 && number_of_ports != 4) {
68 LOG_ERROR("%s opened the wrong number of ports: got %d, expected 2 or 4.", __func__, number_of_ports);
72 LOG_INFO("%s got uart fds: CMD=%d, EVT=%d, ACL_OUT=%d, ACL_IN=%d",
73 __func__, uart_fds[CH_CMD], uart_fds[CH_EVT], uart_fds[CH_ACL_OUT], uart_fds[CH_ACL_IN]);
75 if (uart_fds[CH_CMD] == INVALID_FD) {
76 LOG_ERROR("%s unable to open the command uart serial port.", __func__);
80 if (uart_fds[CH_EVT] == INVALID_FD) {
81 LOG_ERROR("%s unable to open the event uart serial port.", __func__);
85 if (uart_fds[CH_ACL_OUT] == INVALID_FD) {
86 LOG_ERROR("%s unable to open the acl-out uart serial port.", __func__);
90 if (uart_fds[CH_ACL_IN] == INVALID_FD) {
91 LOG_ERROR("%s unable to open the acl-in uart serial port.", __func__);
95 event_stream = eager_reader_new(uart_fds[CH_EVT], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
97 LOG_ERROR("%s unable to create eager reader for the event uart serial port.", __func__);
101 acl_stream = eager_reader_new(uart_fds[CH_ACL_IN], &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_mct");
103 LOG_ERROR("%s unable to create eager reader for the acl-in uart serial port.", __func__);
107 eager_reader_register(event_stream, thread_get_reactor(thread), event_event_stream_has_bytes, NULL);
108 eager_reader_register(acl_stream, thread_get_reactor(thread), event_acl_stream_has_bytes, NULL);
117 static void hal_close() {
118 LOG_INFO("%s", __func__);
120 eager_reader_free(event_stream);
121 eager_reader_free(acl_stream);
122 vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
124 for (int i = 0; i < CH_MAX; i++)
125 uart_fds[i] = INVALID_FD;
128 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size, bool block) {
129 if (type == DATA_TYPE_ACL) {
130 return eager_reader_read(acl_stream, buffer, max_size, block);
131 } else if (type == DATA_TYPE_EVENT) {
132 return eager_reader_read(event_stream, buffer, max_size, block);
135 LOG_ERROR("%s invalid data type: %d", __func__, type);
139 static void packet_finished(UNUSED_ATTR serial_data_type_t type) {
140 // not needed by this protocol
143 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
144 if (type == DATA_TYPE_ACL) {
145 return transmit_data_on(uart_fds[CH_ACL_OUT], data, length);
146 } else if (type == DATA_TYPE_COMMAND) {
147 return transmit_data_on(uart_fds[CH_CMD], data, length);
150 LOG_ERROR("%s invalid data type: %d", __func__, type);
154 // Internal functions
156 static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
157 assert(data != NULL);
160 uint16_t transmitted_length = 0;
162 ssize_t ret = write(fd, data + transmitted_length, length);
165 LOG_ERROR("In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
166 return transmitted_length;
168 // If we wrote nothing, don't loop more because we
169 // can't go to infinity or beyond
170 return transmitted_length;
172 transmitted_length += ret;
178 return transmitted_length;
181 static void event_event_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
182 callbacks->data_ready(DATA_TYPE_EVENT);
185 static void event_acl_stream_has_bytes(UNUSED_ATTR eager_reader_t *reader, UNUSED_ATTR void *context) {
186 // No real concept of incoming SCO typed data, just ACL
187 callbacks->data_ready(DATA_TYPE_ACL);
190 static const hci_hal_t interface = {
201 const hci_hal_t *hci_hal_mct_get_interface() {
202 vendor = vendor_get_interface();
206 const hci_hal_t *hci_hal_mct_get_test_interface(vendor_t *vendor_interface) {
207 vendor = vendor_interface;