• 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_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 
hal_init(const hci_hal_callbacks_t * upper_callbacks,thread_t * upper_thread)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 
hal_open()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 
hal_close()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 
read_data(serial_data_type_t type,uint8_t * buffer,size_t max_size)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 
packet_finished(serial_data_type_t type)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 
transmit_data(serial_data_type_t type,uint8_t * data,uint16_t length)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.
stream_corrupted_during_le_scan_workaround(const uint8_t byte_read)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
event_uart_has_bytes(eager_reader_t * reader,UNUSED_ATTR void * context)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 
hci_hal_h4_get_interface()261 const hci_hal_t *hci_hal_h4_get_interface() {
262   vendor = vendor_get_interface();
263   return &interface;
264 }
265 
hci_hal_h4_get_test_interface(vendor_t * vendor_interface)266 const hci_hal_t *hci_hal_h4_get_test_interface(vendor_t *vendor_interface) {
267   vendor = vendor_interface;
268   return &interface;
269 }
270