1 //
2 // Copyright 2017 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "h4_packetizer.h"
18
19 #define LOG_TAG "h4_packetizer"
20
21 #include <dlfcn.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <log/log.h>
25 #include <sys/uio.h>
26 #include <unistd.h>
27
28 namespace test_vendor_lib {
29 namespace hci {
30 constexpr size_t H4Packetizer::COMMAND_PREAMBLE_SIZE;
31 constexpr size_t H4Packetizer::COMMAND_LENGTH_OFFSET;
32 constexpr size_t H4Packetizer::ACL_PREAMBLE_SIZE;
33 constexpr size_t H4Packetizer::ACL_LENGTH_OFFSET;
34 constexpr size_t H4Packetizer::SCO_PREAMBLE_SIZE;
35 constexpr size_t H4Packetizer::SCO_LENGTH_OFFSET;
36 constexpr size_t H4Packetizer::EVENT_PREAMBLE_SIZE;
37 constexpr size_t H4Packetizer::EVENT_LENGTH_OFFSET;
38
39 constexpr size_t H4Packetizer::PREAMBLE_SIZE_MAX;
40
HciGetPacketLengthForType(hci::PacketType type,const uint8_t * preamble)41 size_t H4Packetizer::HciGetPacketLengthForType(hci::PacketType type, const uint8_t* preamble) {
42 static const size_t packet_length_offset[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
43 0,
44 H4Packetizer::COMMAND_LENGTH_OFFSET,
45 H4Packetizer::ACL_LENGTH_OFFSET,
46 H4Packetizer::SCO_LENGTH_OFFSET,
47 H4Packetizer::EVENT_LENGTH_OFFSET,
48 };
49
50 size_t offset = packet_length_offset[static_cast<size_t>(type)];
51 if (type != hci::PacketType::ACL) return preamble[offset];
52 return (((preamble[offset + 1]) << 8) | preamble[offset]);
53 }
54
H4Packetizer(int fd,PacketReadCallback command_cb,PacketReadCallback event_cb,PacketReadCallback acl_cb,PacketReadCallback sco_cb)55 H4Packetizer::H4Packetizer(int fd, PacketReadCallback command_cb, PacketReadCallback event_cb,
56 PacketReadCallback acl_cb, PacketReadCallback sco_cb)
57 : uart_fd_(fd), command_cb_(command_cb), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb) {}
58
Send(uint8_t type,const uint8_t * data,size_t length)59 size_t H4Packetizer::Send(uint8_t type, const uint8_t* data, size_t length) {
60 struct iovec iov[] = {{&type, sizeof(type)}, {const_cast<uint8_t*>(data), length}};
61 ssize_t ret = 0;
62 do {
63 ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0])));
64 } while (-1 == ret && EAGAIN == errno);
65
66 if (ret == -1) {
67 ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
68 } else if (ret < static_cast<ssize_t>(length + 1)) {
69 ALOGE("%s: %d / %d bytes written - something went wrong...", __func__, static_cast<int>(ret),
70 static_cast<int>(length + 1));
71 }
72 return ret;
73 }
74
OnPacketReady()75 void H4Packetizer::OnPacketReady() {
76 ALOGE("%s: before switch", __func__);
77 switch (hci_packet_type_) {
78 case hci::PacketType::COMMAND:
79 command_cb_(packet_);
80 break;
81 case hci::PacketType::ACL:
82 acl_cb_(packet_);
83 break;
84 case hci::PacketType::SCO:
85 sco_cb_(packet_);
86 break;
87 case hci::PacketType::EVENT:
88 event_cb_(packet_);
89 break;
90 default:
91 LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
92 }
93 // Get ready for the next type byte.
94 hci_packet_type_ = hci::PacketType::UNKNOWN;
95 }
96
OnDataReady(int fd)97 void H4Packetizer::OnDataReady(int fd) {
98 if (hci_packet_type_ == hci::PacketType::UNKNOWN) {
99 uint8_t buffer[1] = {0};
100 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
101 if (bytes_read != 1) {
102 if (bytes_read == 0) {
103 ALOGI("%s: Nothing ready, will retry!", __func__);
104 return;
105 } else if (bytes_read < 0) {
106 if (errno == EAGAIN) {
107 // No data, try again later.
108 return;
109 } else {
110 LOG_ALWAYS_FATAL("%s: Read packet type error: %s", __func__, strerror(errno));
111 }
112 } else {
113 LOG_ALWAYS_FATAL("%s: More bytes read than expected (%u)!", __func__, static_cast<unsigned int>(bytes_read));
114 }
115 }
116 hci_packet_type_ = static_cast<hci::PacketType>(buffer[0]);
117 if (hci_packet_type_ != hci::PacketType::ACL && hci_packet_type_ != hci::PacketType::SCO &&
118 hci_packet_type_ != hci::PacketType::COMMAND && hci_packet_type_ != hci::PacketType::EVENT) {
119 LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_));
120 }
121 } else {
122 static const size_t preamble_size[static_cast<size_t>(hci::PacketType::EVENT) + 1] = {
123 0,
124 H4Packetizer::COMMAND_PREAMBLE_SIZE,
125 H4Packetizer::ACL_PREAMBLE_SIZE,
126 H4Packetizer::SCO_PREAMBLE_SIZE,
127 H4Packetizer::EVENT_PREAMBLE_SIZE,
128 };
129
130 switch (state_) {
131 case HCI_PREAMBLE: {
132 size_t preamble_bytes = preamble_size[static_cast<size_t>(hci_packet_type_)];
133 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, preamble_ + bytes_read_, preamble_bytes - bytes_read_));
134 if (bytes_read == 0) {
135 ALOGE("%s: Will try again to read the header!", __func__);
136 return;
137 }
138 if (bytes_read < 0) {
139 // Ignore temporary failures.
140 if (errno == EAGAIN) {
141 return;
142 }
143 LOG_ALWAYS_FATAL("%s: Read header error: %s", __func__, strerror(errno));
144 }
145 bytes_read_ += bytes_read;
146 if (bytes_read_ == preamble_bytes) {
147 size_t packet_length = HciGetPacketLengthForType(hci_packet_type_, preamble_);
148 packet_.resize(preamble_bytes + packet_length);
149 memcpy(packet_.data(), preamble_, preamble_bytes);
150 ALOGI("%s: Read a preamble of size %d length %d %0x %0x %0x", __func__, static_cast<int>(bytes_read_),
151 static_cast<int>(packet_length), preamble_[0], preamble_[1], preamble_[2]);
152 bytes_remaining_ = packet_length;
153 if (bytes_remaining_ == 0) {
154 OnPacketReady();
155 state_ = HCI_PREAMBLE;
156 bytes_read_ = 0;
157 } else {
158 state_ = HCI_PAYLOAD;
159 bytes_read_ = 0;
160 }
161 }
162 break;
163 }
164
165 case HCI_PAYLOAD: {
166 size_t preamble_bytes = preamble_size[static_cast<size_t>(hci_packet_type_)];
167 ssize_t bytes_read =
168 TEMP_FAILURE_RETRY(read(fd, packet_.data() + preamble_bytes + bytes_read_, bytes_remaining_));
169 if (bytes_read == 0) {
170 ALOGI("%s: Will try again to read the payload!", __func__);
171 return;
172 }
173 if (bytes_read < 0) {
174 // Ignore temporary failures.
175 if (errno == EAGAIN) {
176 return;
177 }
178 LOG_ALWAYS_FATAL("%s: Read payload error: %s", __func__, strerror(errno));
179 }
180 bytes_remaining_ -= bytes_read;
181 bytes_read_ += bytes_read;
182 if (bytes_remaining_ == 0) {
183 OnPacketReady();
184 state_ = HCI_PREAMBLE;
185 bytes_read_ = 0;
186 }
187 break;
188 }
189 }
190 }
191 }
192
193 } // namespace hci
194 } // namespace test_vendor_lib
195