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 "hci_packetizer.h"
18
19 #define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
20 #include <dlfcn.h>
21 #include <fcntl.h>
22 #include <log/log.h>
23
24 namespace {
25
26 const size_t header_size_for_type[] = {0,
27 HCI_COMMAND_PREAMBLE_SIZE,
28 HCI_ACL_PREAMBLE_SIZE,
29 HCI_SCO_PREAMBLE_SIZE,
30 HCI_EVENT_PREAMBLE_SIZE,
31 HCI_ISO_PREAMBLE_SIZE};
32 const size_t packet_length_offset_for_type[] = {0,
33 HCI_LENGTH_OFFSET_CMD,
34 HCI_LENGTH_OFFSET_ACL,
35 HCI_LENGTH_OFFSET_SCO,
36 HCI_LENGTH_OFFSET_EVT,
37 HCI_LENGTH_OFFSET_ISO};
38
HciGetPacketLengthForType(HciPacketType type,const std::vector<uint8_t> & preamble)39 size_t HciGetPacketLengthForType(HciPacketType type,
40 const std::vector<uint8_t>& preamble) {
41 size_t offset = packet_length_offset_for_type[type];
42 if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
43 return (((preamble[offset + 1]) << 8) | preamble[offset]);
44 }
45
46 } // namespace
47
48 namespace android {
49 namespace hardware {
50 namespace bluetooth {
51 namespace hci {
52
GetPacket() const53 const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
54
fill_header(HciPacketType packet_type,const std::vector<uint8_t> & buffer,size_t offset)55 size_t HciPacketizer::fill_header(HciPacketType packet_type,
56 const std::vector<uint8_t>& buffer,
57 size_t offset) {
58 size_t header_size = header_size_for_type[static_cast<size_t>(packet_type)];
59 if (bytes_remaining_ == 0) {
60 bytes_remaining_ = header_size;
61 packet_buffer_.clear();
62 }
63 // Add as much of the header as is available to the packet.
64 size_t bytes_to_copy = std::min(bytes_remaining_, buffer.size() - offset);
65 packet_buffer_.insert(packet_buffer_.end(), buffer.begin() + offset,
66 buffer.begin() + offset + bytes_to_copy);
67 bytes_remaining_ -= bytes_to_copy;
68
69 // If the header is complete, find the payload size and transition.
70 if (bytes_remaining_ == 0) {
71 bytes_remaining_ = HciGetPacketLengthForType(packet_type, packet_buffer_);
72 // If there are no bytes remaining, this is a completed packet.
73 if (bytes_remaining_ > 0) {
74 state_ = HCI_PAYLOAD;
75 }
76 }
77 return bytes_to_copy;
78 }
79
fill_payload(const std::vector<uint8_t> & buffer,size_t offset)80 void HciPacketizer::fill_payload(const std::vector<uint8_t>& buffer,
81 size_t offset) {
82 // Add as much of the payload as is available to the end of the packet.
83 size_t bytes_to_copy = std::min(bytes_remaining_, buffer.size() - offset);
84 packet_buffer_.insert(packet_buffer_.end(), buffer.begin() + offset,
85 buffer.begin() + offset + bytes_to_copy);
86 bytes_remaining_ -= bytes_to_copy;
87
88 // If there are no bytes remaining, this is a completed packet.
89 if (bytes_remaining_ == 0) {
90 state_ = HCI_HEADER;
91 }
92 }
93
OnDataReady(HciPacketType packet_type,const std::vector<uint8_t> & buffer,size_t offset)94 bool HciPacketizer::OnDataReady(HciPacketType packet_type,
95 const std::vector<uint8_t>& buffer,
96 size_t offset) {
97 // Start with the header.
98 size_t header_bytes = 0;
99 if (state_ == HCI_HEADER) {
100 header_bytes = fill_header(packet_type, buffer, offset);
101 }
102 // If there are bytes left in this packet, fill the payload.
103 if (state_ == HCI_PAYLOAD && bytes_remaining_ > 0) {
104 if (offset + header_bytes < buffer.size()) {
105 fill_payload(buffer, offset + header_bytes);
106 }
107 }
108 // If there are no bytes remaining, this is a completed packet.
109 if (bytes_remaining_ == 0) {
110 packet_.setToExternal(packet_buffer_.data(), packet_buffer_.size());
111 }
112 return bytes_remaining_ == 0;
113 }
114
115 } // namespace hci
116 } // namespace bluetooth
117 } // namespace hardware
118 } // namespace android
119