blob: 1a5019600f2d68e3f2b2cb590d3137c46b195da1 [file] [log] [blame]
Myles Watson274a3812017-02-23 06:29:08 -08001//
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 <android-base/logging.h>
21#include <cutils/properties.h>
22#include <utils/Log.h>
23
24#include <dlfcn.h>
25#include <fcntl.h>
26
27namespace {
28
29const size_t preamble_size_for_type[] = {
30 0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE,
31 HCI_EVENT_PREAMBLE_SIZE};
32const size_t packet_length_offset_for_type[] = {
33 0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
34 HCI_LENGTH_OFFSET_EVT};
35
36size_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
37 size_t offset = packet_length_offset_for_type[type];
38 if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
39 return (((preamble[offset + 1]) << 8) | preamble[offset]);
40}
41
42} // namespace
43
44namespace android {
45namespace hardware {
46namespace bluetooth {
47namespace hci {
48
49HciPacketType HciPacketizer::GetPacketType() const {
50 return hci_packet_type_;
51}
52
53const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const {
54 return hci_packet_;
55}
56
57void HciPacketizer::OnDataReady(int fd) {
58 switch (hci_parser_state_) {
59 case HCI_IDLE: {
60 uint8_t buffer[1] = {0};
61 size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
62 CHECK(bytes_read == 1);
63 hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
64 CHECK(hci_packet_type_ >= HCI_PACKET_TYPE_ACL_DATA &&
65 hci_packet_type_ <= HCI_PACKET_TYPE_EVENT)
66 << "buffer[0] = " << static_cast<unsigned int>(buffer[0]);
67 hci_parser_state_ = HCI_TYPE_READY;
68 hci_packet_bytes_remaining_ = preamble_size_for_type[hci_packet_type_];
69 hci_packet_bytes_read_ = 0;
70 break;
71 }
72
73 case HCI_TYPE_READY: {
74 size_t bytes_read = TEMP_FAILURE_RETRY(
75 read(fd, hci_packet_preamble_ + hci_packet_bytes_read_,
76 hci_packet_bytes_remaining_));
77 CHECK(bytes_read > 0);
78 hci_packet_bytes_remaining_ -= bytes_read;
79 hci_packet_bytes_read_ += bytes_read;
80 if (hci_packet_bytes_remaining_ == 0) {
81 size_t packet_length =
82 HciGetPacketLengthForType(hci_packet_type_, hci_packet_preamble_);
83 hci_packet_.resize(preamble_size_for_type[hci_packet_type_] +
84 packet_length);
85 memcpy(hci_packet_.data(), hci_packet_preamble_,
86 preamble_size_for_type[hci_packet_type_]);
87 hci_packet_bytes_remaining_ = packet_length;
88 hci_parser_state_ = HCI_PAYLOAD;
89 hci_packet_bytes_read_ = 0;
90 }
91 break;
92 }
93
94 case HCI_PAYLOAD: {
95 size_t bytes_read = TEMP_FAILURE_RETRY(
96 read(fd,
97 hci_packet_.data() + preamble_size_for_type[hci_packet_type_] +
98 hci_packet_bytes_read_,
99 hci_packet_bytes_remaining_));
100 CHECK(bytes_read > 0);
101 hci_packet_bytes_remaining_ -= bytes_read;
102 hci_packet_bytes_read_ += bytes_read;
103 if (hci_packet_bytes_remaining_ == 0) {
104 hci_packet_ready_cb_();
105 hci_parser_state_ = HCI_IDLE;
106 }
107 break;
108 }
109 }
110}
111
112} // namespace hci
113} // namespace bluetooth
114} // namespace hardware
115} // namespace android