OSDN Git Service

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