• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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