OSDN Git Service

368b1aa944b287a61ac470c13c9e781727936891
[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
23 #include "osi/include/eager_reader.h"
24 #include "hci_hal.h"
25 #include "osi/include/osi.h"
26 #include "osi/include/log.h"
27 #include "osi/include/reactor.h"
28 #include "vendor.h"
29
30 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
31
32 // Our interface and modules we import
33 static const hci_hal_t interface;
34 static const hci_hal_callbacks_t *callbacks;
35 static const vendor_t *vendor;
36
37 static thread_t *thread; // Not owned by us
38
39 static int uart_fd;
40 static eager_reader_t *uart_stream;
41 static serial_data_type_t current_data_type;
42 static bool stream_has_interpretation;
43
44 static void event_uart_has_bytes(eager_reader_t *reader, void *context);
45
46 // Interface functions
47
48 static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
49   assert(upper_callbacks != NULL);
50   assert(upper_thread != NULL);
51
52   callbacks = upper_callbacks;
53   thread = upper_thread;
54   return true;
55 }
56
57 static bool hal_open() {
58   LOG_INFO("%s", __func__);
59   // TODO(zachoverflow): close if already open / or don't reopen (maybe at the hci layer level)
60
61   int fd_array[CH_MAX];
62   int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array);
63
64   if (number_of_ports != 1) {
65     LOG_ERROR("%s opened the wrong number of ports: got %d, expected 1.", __func__, number_of_ports);
66     goto error;
67   }
68
69   uart_fd = fd_array[0];
70   if (uart_fd == INVALID_FD) {
71     LOG_ERROR("%s unable to open the uart serial port.", __func__);
72     goto error;
73   }
74
75   uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel");
76   if (!uart_stream) {
77     LOG_ERROR("%s unable to create eager reader for the uart serial port.", __func__);
78     goto error;
79   }
80
81   stream_has_interpretation = false;
82   eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL);
83
84   return true;
85
86 error:
87   interface.close();
88   return false;
89 }
90
91 static void hal_close() {
92   LOG_INFO("%s", __func__);
93
94   eager_reader_free(uart_stream);
95   vendor->send_command(VENDOR_CLOSE_USERIAL, NULL);
96   uart_fd = INVALID_FD;
97 }
98
99 static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size, bool block) {
100   if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
101     LOG_ERROR("%s invalid data type: %d", __func__, type);
102     return 0;
103   } else if (!stream_has_interpretation) {
104     LOG_ERROR("%s with no valid stream intepretation.", __func__);
105     return 0;
106   } else if (current_data_type != type) {
107     LOG_ERROR("%s with different type than existing interpretation.", __func__);
108     return 0;
109   }
110
111   return eager_reader_read(uart_stream, buffer, max_size, block);
112 }
113
114 static void packet_finished(serial_data_type_t type) {
115   if (!stream_has_interpretation)
116     LOG_ERROR("%s with no existing stream interpretation.", __func__);
117   else if (current_data_type != type)
118     LOG_ERROR("%s with different type than existing interpretation.", __func__);
119
120   stream_has_interpretation = false;
121 }
122
123 static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t length) {
124   assert(data != NULL);
125   assert(length > 0);
126
127   if (type < DATA_TYPE_COMMAND || type > DATA_TYPE_SCO) {
128     LOG_ERROR("%s invalid data type: %d", __func__, type);
129     return 0;
130   }
131
132   // Write the signal byte right before the data
133   --data;
134   uint8_t previous_byte = *data;
135   *(data) = type;
136   ++length;
137
138   uint16_t transmitted_length = 0;
139   while (length > 0) {
140     ssize_t ret = write(uart_fd, data + transmitted_length, length);
141     switch (ret) {
142       case -1:
143         LOG_ERROR("In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
144         goto done;
145       case 0:
146         // If we wrote nothing, don't loop more because we
147         // can't go to infinity or beyond
148         goto done;
149       default:
150         transmitted_length += ret;
151         length -= ret;
152         break;
153     }
154   }
155
156 done:;
157   // Be nice and restore the old value of that byte
158   *(data) = previous_byte;
159
160   // Remove the signal byte from our transmitted length, if it was actually written
161   if (transmitted_length > 0)
162     --transmitted_length;
163
164   return transmitted_length;
165 }
166
167 // Internal functions
168
169 // See what data is waiting, and notify the upper layer
170 static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) {
171   if (stream_has_interpretation) {
172     callbacks->data_ready(current_data_type);
173   } else {
174     uint8_t type_byte;
175     eager_reader_read(reader, &type_byte, 1, true);
176     if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) {
177       LOG_ERROR("[h4] Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT);
178       return;
179     }
180
181     stream_has_interpretation = true;
182     current_data_type = type_byte;
183   }
184 }
185
186 static const hci_hal_t interface = {
187   hal_init,
188
189   hal_open,
190   hal_close,
191
192   read_data,
193   packet_finished,
194   transmit_data,
195 };
196
197 const hci_hal_t *hci_hal_h4_get_interface() {
198   vendor = vendor_get_interface();
199   return &interface;
200 }
201
202 const hci_hal_t *hci_hal_h4_get_test_interface(vendor_t *vendor_interface) {
203   vendor = vendor_interface;
204   return &interface;
205 }