OSDN Git Service

Promotion of bt.lnx.2.1.c1-00010.
[android-x86/system-bt.git] / hci / src / hci_hal_h4.c
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 // Our interface and modules we import
42 static const hci_hal_t interface;
43 static const hci_hal_callbacks_t *callbacks;
44 static const vendor_t *vendor;
45
46 static thread_t *thread; // Not owned by us
47
48 static int uart_fd;
49 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
50 static hci_reader_t *uart_stream;
51 #else
52 static eager_reader_t *uart_stream;
53 #endif
54 static serial_data_type_t current_data_type;
55 static bool stream_has_interpretation;
56 static bool stream_corruption_detected;
57 static uint8_t stream_corruption_bytes_to_ignore;
58
59 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
60 static void event_uart_has_bytes(void *context);
61 #else
62 static void event_uart_has_bytes(eager_reader_t *reader, void *context);
63 static bool stream_corrupted_during_le_scan_workaround(const uint8_t byte_read);
64 #endif
65
66
67 // Interface functions
68
69 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
70   assert(upper_callbacks != NULL);
71   assert(upper_thread != NULL);
72
73   callbacks = upper_callbacks;
74   thread = upper_thread;
75   return true;
76 }
77
78 static bool hal_open() {
79   LOG_INFO(LOG_TAG, "%s", __func__);
80   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
81
82   int fd_array[CH_MAX];
83   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array);
84
85   if (number_of_ports != 1) {
86     LOG_ERROR(LOG_TAG, "%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports);
87     goto error;
88   }
89
90   uart_fd = fd_array[0];
91   if (uart_fd == INVALID_FD) {
92     LOG_ERROR(LOG_TAG, "%s unable to open the uart serial port.", __func__);
93     goto error;
94   }
95
96 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
97   uart_stream = hci_reader_new(uart_fd, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, thread, event_uart_has_bytes);
98   if (!uart_stream) {
99     LOG_ERROR("%s unable to create hci reader for the uart serial port.", __func__);
100     goto error;
101   }
102 #else
103   uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel");
104   if (!uart_stream) {
105     LOG_ERROR(LOG_TAG, "%s unable to create eager reader for the uart serial port.", __func__);
106     goto error;
107   }
108   eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL);
109   thread_set_priority(eager_reader_get_read_thread(uart_stream), HCI_THREAD_PRIORITY);
110 #endif
111
112   stream_has_interpretation = false;
113   stream_corruption_detected = false;
114   stream_corruption_bytes_to_ignore = 0;
115
116   // Raise thread priorities to keep up with audio
117   thread_set_priority(thread, HCI_THREAD_PRIORITY);
118
119   return true;
120
121 error:
122   interface.close();
123   return false;
124 }
125
126 static void hal_close() {
127   LOG_INFO(LOG_TAG, "%s", __func__);
128
129 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
130   hci_reader_free(uart_stream);
131 #else
132   eager_reader_free(uart_stream);
133 #endif
134   uart_stream = NULL;
135
136   vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
137   uart_fd = INVALID_FD;
138 }
139
140 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) {
141   if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
142     LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
143     return 0;
144   } else if (!stream_has_interpretation) {
145     LOG_ERROR(LOG_TAG, "%s with no valid stream intepretation.", __func__);
146     return 0;
147   } else if (current_data_type != type) {
148     LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
149     return 0;
150   }
151
152 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
153   return hci_reader_read(uart_stream, buffer, max_size);
154 #else
155   return eager_reader_read(uart_stream, buffer, max_size);
156 #endif
157 }
158
159 static void packet_finished(serial_data_type_t type) {
160   if (!stream_has_interpretation)
161     LOG_ERROR(LOG_TAG, "%s with no existing stream interpretation.", __func__);
162   else if (current_data_type != type)
163     LOG_ERROR(LOG_TAG, "%s with different type than existing interpretation.", __func__);
164
165 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
166   if (uart_stream->rd_ptr == uart_stream->wr_ptr) {
167     uart_stream->rd_ptr = uart_stream->wr_ptr = 0;
168     stream_has_interpretation = false;
169   } else {
170     uint8_t type_byte;
171     type_byte = uart_stream->data_buffer[uart_stream->rd_ptr++];
172     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
173       LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__,
174                                                     type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
175       return;
176     }
177     current_data_type = type_byte;
178     callbacks->data_ready(current_data_type);
179   }
180 #else
181   stream_has_interpretation = false;
182 #endif
183 }
184
185 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
186   assert(data != NULL);
187   assert(length > 0);
188
189   if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
190     LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
191     return 0;
192   }
193
194   // Write the signal byte right before the data
195   --data;
196   uint8_t previous_byte = *data;
197   *(data) = type;
198   ++length;
199
200   uint16_t transmitted_length = 0;
201   while (length > 0) {
202     ssize_t ret;
203     OSI_NO_INTR(ret = write(uart_fd, data + transmitted_length, length));
204     switch (ret) {
205       case -1:
206         LOG_ERROR(LOG_TAG, "In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
207         goto done;
208       case 0:
209         // If we wrote nothing, don't loop more because we
210         // can't go to infinity or beyond
211         goto done;
212       default:
213         transmitted_length += ret;
214         length -= ret;
215         break;
216     }
217   }
218
219 done:;
220   // Be nice and restore the old value of that byte
221   *(data) = previous_byte;
222
223   // Remove the signal byte from our transmitted length, if it was actually written
224   if (transmitted_length > 0)
225     --transmitted_length;
226
227   return transmitted_length;
228 }
229
230 static bool hal_dev_in_reset()
231 {
232     return false;
233 }
234
235 // Internal functions
236
237 // WORKAROUND:
238 // As exhibited by b/23934838, during result-heavy LE scans, the UART byte
239 // stream can get corrupted, leading to assertions caused by mis-interpreting
240 // the bytes following the corruption.
241 // This workaround looks for tell-tale signs of a BLE event and attempts to
242 // skip the correct amount of bytes in the stream to re-synchronize onto
243 // a packet boundary.
244 // Function returns true if |byte_read| has been processed by the workaround.
245 #if (!defined(REMOVE_EAGER_THREADS) || ((defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == FALSE))))
246 static bool stream_corrupted_during_le_scan_workaround(const uint8_t byte_read)
247 {
248   if (!stream_corruption_detected && byte_read == HCI_BLE_EVENT) {
249     LOG_ERROR(LOG_TAG, "%s HCI stream corrupted (message type 0x3E)!", __func__);
250     stream_corruption_detected = true;
251     return true;
252   }
253
254   if (stream_corruption_detected) {
255     if (stream_corruption_bytes_to_ignore == 0) {
256       stream_corruption_bytes_to_ignore = byte_read;
257       LOG_ERROR(LOG_TAG, "%s About to skip %d bytes...", __func__, stream_corruption_bytes_to_ignore);
258     } else {
259       --stream_corruption_bytes_to_ignore;
260     }
261
262     if (stream_corruption_bytes_to_ignore == 0) {
263       LOG_ERROR(LOG_TAG, "%s Back to our regularly scheduled program...", __func__);
264       stream_corruption_detected = false;
265     }
266     return true;
267   }
268
269   return false;
270 }
271 #endif
272 // See what data is waiting, and notify the upper layer
273 #if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
274 static void event_uart_has_bytes(void *context) {
275   uint8_t type_byte;
276   int bytes_read;
277   hci_reader_t *reader = (hci_reader_t *) context;
278   bytes_read = read(reader->inbound_fd, reader->data_buffer + reader->wr_ptr, reader->buffer_size - reader->wr_ptr);
279
280   if (bytes_read <= 0)  {
281     LOG_ERROR("%s could not read HCI message type", __func__);
282     return;
283   }
284   reader->wr_ptr += bytes_read;
285   if (!stream_has_interpretation) {
286     type_byte = reader->data_buffer[reader->rd_ptr++];
287
288     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
289       LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
290       return;
291     }
292
293     stream_has_interpretation = true;
294     current_data_type = type_byte;
295   }
296
297   callbacks->data_ready(current_data_type);
298 }
299 #else
300 static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) {
301   if (stream_has_interpretation) {
302     callbacks->data_ready(current_data_type);
303   } else {
304     uint8_t type_byte;
305     if (eager_reader_read(reader, &type_byte, 1) == 0) {
306       LOG_ERROR(LOG_TAG, "%s could not read HCI message type", __func__);
307       return;
308     }
309
310     if (stream_corrupted_during_le_scan_workaround(type_byte))
311       return;
312
313     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
314       LOG_ERROR(LOG_TAG, "%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
315       return;
316     }
317
318     stream_has_interpretation = true;
319     current_data_type = type_byte;
320   }
321 }
322 #endif
323
324 static const hci_hal_t interface = {
325   hal_init,
326
327   hal_open,
328   hal_close,
329
330   read_data,
331   packet_finished,
332   transmit_data,
333   hal_dev_in_reset
334 };
335
336 const hci_hal_t *hci_hal_h4_get_interface() {
337   vendor = vendor_get_interface();
338   return &interface;
339 }
340
341 const hci_hal_t *hci_hal_h4_get_test_interface(vendor_t *vendor_interface) {
342   vendor = vendor_interface;
343   return &interface;
344 }