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