1761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
2761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Copyright 2017 The Android Open Source Project
3761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
4761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Licensed under the Apache License, Version 2.0 (the "License");
5761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// you may not use this file except in compliance with the License.
6761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// You may obtain a copy of the License at
7761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
8761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// http://www.apache.org/licenses/LICENSE-2.0
9761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
10761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// Unless required by applicable law or agreed to in writing, software
11761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// distributed under the License is distributed on an "AS IS" BASIS,
12761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// See the License for the specific language governing permissions and
14761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson// limitations under the License.
15761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson//
16761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
17761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include "hci_packetizer.h"
18761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
19761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
20761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <android-base/logging.h>
21761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <utils/Log.h>
22761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
23761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <dlfcn.h>
24761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson#include <fcntl.h>
25761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
26761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace {
27761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
28761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t preamble_size_for_type[] = {
29761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE,
30761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    HCI_EVENT_PREAMBLE_SIZE};
31761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst size_t packet_length_offset_for_type[] = {
32761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
33761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    HCI_LENGTH_OFFSET_EVT};
34761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
35761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonsize_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
36761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  size_t offset = packet_length_offset_for_type[type];
37761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
38761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  return (((preamble[offset + 1]) << 8) | preamble[offset]);
39761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
40761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
41761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace
42761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
43761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace android {
44761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hardware {
45761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace bluetooth {
46761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonnamespace hci {
47761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
48761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonconst hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
49761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
50761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watsonvoid HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) {
51761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  switch (state_) {
52761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    case HCI_PREAMBLE: {
53761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      size_t bytes_read = TEMP_FAILURE_RETRY(
54761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson          read(fd, preamble_ + bytes_read_,
55761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson               preamble_size_for_type[packet_type] - bytes_read_));
56761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      CHECK(bytes_read > 0);
57761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      bytes_read_ += bytes_read;
58761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      if (bytes_read_ == preamble_size_for_type[packet_type]) {
59761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        size_t packet_length =
60761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson            HciGetPacketLengthForType(packet_type, preamble_);
61761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        packet_.resize(preamble_size_for_type[packet_type] + packet_length);
62761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        memcpy(packet_.data(), preamble_, preamble_size_for_type[packet_type]);
63761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        bytes_remaining_ = packet_length;
64761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        state_ = HCI_PAYLOAD;
65761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        bytes_read_ = 0;
66761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      }
67761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
68761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    }
69761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
70761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    case HCI_PAYLOAD: {
71761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      size_t bytes_read = TEMP_FAILURE_RETRY(read(
72761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson          fd,
73761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson          packet_.data() + preamble_size_for_type[packet_type] + bytes_read_,
74761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson          bytes_remaining_));
75761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      CHECK(bytes_read > 0);
76761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      bytes_remaining_ -= bytes_read;
77761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      bytes_read_ += bytes_read;
78761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      if (bytes_remaining_ == 0) {
79761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        packet_ready_cb_();
80761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        state_ = HCI_PREAMBLE;
81761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson        bytes_read_ = 0;
82761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      }
83761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson      break;
84761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson    }
85761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson  }
86761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}
87761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson
88761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hci
89761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace bluetooth
90761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace hardware
91761dc49c591d9fe6cc1a3a2e90026678af3ad41aMyles Watson}  // namespace android
92