Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36d02457 authored by Zach Johnson's avatar Zach Johnson Committed by android-build-merger
Browse files

Merge "Bring multi-channel transport into the glorious new age" am: a15a9bba am: 2296cfbe

am: 4e504164

Change-Id: I761476877343bf16816298c2a75ee386e6ba83a2
parents d0fbfd8e 4e504164
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -56,6 +56,9 @@ cc_library_static {
    name: "android.hardware.bluetooth-hci",
    srcs: [
        "hci_packetizer.cc",
        "hci_protocol.cc",
        "h4_protocol.cc",
        "mct_protocol.cc",
    ],
    export_include_dirs: ["."],
    shared_libs: [
@@ -71,16 +74,21 @@ cc_test {
    name: "bluetooth-vendor-interface-unit-tests",
    srcs: [
        "test/async_fd_watcher_unittest.cc",
        "test/h4_protocol_unittest.cc",
        "test/mct_protocol_unittest.cc",
    ],
    local_include_dirs: [
        "test",
    ],
    shared_libs: [
        "libbase",
        "libhidlbase",
        "liblog",
    ],
    static_libs: [
        "android.hardware.bluetooth-async",
        "android.hardware.bluetooth-hci",
        "libgmock",
    ],
}

+8 −15
Original line number Diff line number Diff line
@@ -44,21 +44,14 @@ Return<void> BluetoothHci::initialize(
        event_cb_->initializationComplete(
            status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
      },
      [this](HciPacketType type, const hidl_vec<uint8_t>& packet) {
        switch (type) {
          case HCI_PACKET_TYPE_EVENT:
      [this](const hidl_vec<uint8_t>& packet) {
        event_cb_->hciEventReceived(packet);
            break;
          case HCI_PACKET_TYPE_ACL_DATA:
      },
      [this](const hidl_vec<uint8_t>& packet) {
        event_cb_->aclDataReceived(packet);
            break;
          case HCI_PACKET_TYPE_SCO_DATA:
      },
      [this](const hidl_vec<uint8_t>& packet) {
        event_cb_->scoDataReceived(packet);
            break;
          default:
            ALOGE("%s Unexpected event type %d", __func__, type);
            break;
        }
      });
  if (!rc) event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
  return Void();
+71 −0
Original line number Diff line number Diff line
//
// Copyright 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "h4_protocol.h"

#define LOG_TAG "android.hardware.bluetooth-hci-h4"
#include <android-base/logging.h>
#include <assert.h>
#include <fcntl.h>

namespace android {
namespace hardware {
namespace bluetooth {
namespace hci {

size_t H4Protocol::Send(uint8_t type, const uint8_t* data, size_t length) {
  int rv = WriteSafely(uart_fd_, &type, sizeof(type));
  if (rv == sizeof(type)) {
    rv = WriteSafely(uart_fd_, data, length);
  }
  return rv;
}

void H4Protocol::OnPacketReady() {
  switch (hci_packet_type_) {
    case HCI_PACKET_TYPE_EVENT:
      event_cb_(hci_packetizer_.GetPacket());
      break;
    case HCI_PACKET_TYPE_ACL_DATA:
      acl_cb_(hci_packetizer_.GetPacket());
      break;
    case HCI_PACKET_TYPE_SCO_DATA:
      sco_cb_(hci_packetizer_.GetPacket());
      break;
    default: {
      bool bad_packet_type = true;
      CHECK(!bad_packet_type);
    }
  }
  // Get ready for the next type byte.
  hci_packet_type_ = HCI_PACKET_TYPE_UNKNOWN;
}

void H4Protocol::OnDataReady(int fd) {
  if (hci_packet_type_ == HCI_PACKET_TYPE_UNKNOWN) {
    uint8_t buffer[1] = {0};
    size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
    CHECK(bytes_read == 1);
    hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
  } else {
    hci_packetizer_.OnDataReady(fd, hci_packet_type_);
  }
}

}  // namespace hci
}  // namespace bluetooth
}  // namespace hardware
}  // namespace android
+61 −0
Original line number Diff line number Diff line
//
// Copyright 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#pragma once

#include <hidl/HidlSupport.h>

#include "async_fd_watcher.h"
#include "bt_vendor_lib.h"
#include "hci_internals.h"
#include "hci_protocol.h"

namespace android {
namespace hardware {
namespace bluetooth {
namespace hci {

class H4Protocol : public HciProtocol {
 public:
  H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb,
             PacketReadCallback sco_cb)
      : uart_fd_(fd),
        event_cb_(event_cb),
        acl_cb_(acl_cb),
        sco_cb_(sco_cb),
        hci_packetizer_([this]() { OnPacketReady(); }) {}

  size_t Send(uint8_t type, const uint8_t* data, size_t length);

  void OnPacketReady();

  void OnDataReady(int fd);

 private:
  int uart_fd_;

  PacketReadCallback event_cb_;
  PacketReadCallback acl_cb_;
  PacketReadCallback sco_cb_;

  HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
  hci::HciPacketizer hci_packetizer_;
};

}  // namespace hci
}  // namespace bluetooth
}  // namespace hardware
}  // namespace android
+24 −48
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
#include <android-base/logging.h>
#include <cutils/properties.h>
#include <utils/Log.h>

#include <dlfcn.h>
@@ -46,63 +45,40 @@ namespace hardware {
namespace bluetooth {
namespace hci {

HciPacketType HciPacketizer::GetPacketType() const {
  return hci_packet_type_;
}

const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const {
  return hci_packet_;
}
const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }

void HciPacketizer::OnDataReady(int fd) {
  switch (hci_parser_state_) {
    case HCI_IDLE: {
      uint8_t buffer[1] = {0};
      size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, 1));
      CHECK(bytes_read == 1);
      hci_packet_type_ = static_cast<HciPacketType>(buffer[0]);
      CHECK(hci_packet_type_ >= HCI_PACKET_TYPE_ACL_DATA &&
            hci_packet_type_ <= HCI_PACKET_TYPE_EVENT)
          << "buffer[0] = " << static_cast<unsigned int>(buffer[0]);
      hci_parser_state_ = HCI_TYPE_READY;
      hci_packet_bytes_remaining_ = preamble_size_for_type[hci_packet_type_];
      hci_packet_bytes_read_ = 0;
      break;
    }

    case HCI_TYPE_READY: {
void HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) {
  switch (state_) {
    case HCI_PREAMBLE: {
      size_t bytes_read = TEMP_FAILURE_RETRY(
          read(fd, hci_packet_preamble_ + hci_packet_bytes_read_,
               hci_packet_bytes_remaining_));
          read(fd, preamble_ + bytes_read_,
               preamble_size_for_type[packet_type] - bytes_read_));
      CHECK(bytes_read > 0);
      hci_packet_bytes_remaining_ -= bytes_read;
      hci_packet_bytes_read_ += bytes_read;
      if (hci_packet_bytes_remaining_ == 0) {
      bytes_read_ += bytes_read;
      if (bytes_read_ == preamble_size_for_type[packet_type]) {
        size_t packet_length =
            HciGetPacketLengthForType(hci_packet_type_, hci_packet_preamble_);
        hci_packet_.resize(preamble_size_for_type[hci_packet_type_] +
                           packet_length);
        memcpy(hci_packet_.data(), hci_packet_preamble_,
               preamble_size_for_type[hci_packet_type_]);
        hci_packet_bytes_remaining_ = packet_length;
        hci_parser_state_ = HCI_PAYLOAD;
        hci_packet_bytes_read_ = 0;
            HciGetPacketLengthForType(packet_type, preamble_);
        packet_.resize(preamble_size_for_type[packet_type] + packet_length);
        memcpy(packet_.data(), preamble_, preamble_size_for_type[packet_type]);
        bytes_remaining_ = packet_length;
        state_ = HCI_PAYLOAD;
        bytes_read_ = 0;
      }
      break;
    }

    case HCI_PAYLOAD: {
      size_t bytes_read = TEMP_FAILURE_RETRY(
          read(fd,
               hci_packet_.data() + preamble_size_for_type[hci_packet_type_] +
                   hci_packet_bytes_read_,
               hci_packet_bytes_remaining_));
      size_t bytes_read = TEMP_FAILURE_RETRY(read(
          fd,
          packet_.data() + preamble_size_for_type[packet_type] + bytes_read_,
          bytes_remaining_));
      CHECK(bytes_read > 0);
      hci_packet_bytes_remaining_ -= bytes_read;
      hci_packet_bytes_read_ += bytes_read;
      if (hci_packet_bytes_remaining_ == 0) {
        hci_packet_ready_cb_();
        hci_parser_state_ = HCI_IDLE;
      bytes_remaining_ -= bytes_read;
      bytes_read_ += bytes_read;
      if (bytes_remaining_ == 0) {
        packet_ready_cb_();
        state_ = HCI_PREAMBLE;
        bytes_read_ = 0;
      }
      break;
    }
Loading