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

Commit 90c3437b authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5892445 from fbc2d07b to rvc-release

Change-Id: Icb92b44a1dd88df29397d7a877c9ddd5967529ab
parents cb27edb9 fbc2d07b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@
#include "common/address_obfuscator.h"
#include "common/metrics.h"
#include "device/include/interop.h"
#include "main/shim/shim.h"
#include "osi/include/alarm.h"
#include "osi/include/allocation_tracker.h"
#include "osi/include/log.h"
@@ -138,6 +139,12 @@ static int init(bt_callbacks_t* callbacks, bool start_restricted,
  LOG_INFO(LOG_TAG, "%s: start restricted = %d ; single user = %d", __func__,
           start_restricted, is_single_user_mode);

  if (bluetooth::shim::is_gd_shim_enabled()) {
    LOG_INFO(LOG_TAG, "%s Enable Gd bluetooth functionality", __func__);
  } else {
    LOG_INFO(LOG_TAG, "%s Preserving legacy bluetooth functionality", __func__);
  }

  if (interface_ready()) return BT_STATUS_DONE;

#ifdef BLUEDROID_DEBUG
+6 −0
Original line number Diff line number Diff line
@@ -89,6 +89,12 @@ typedef struct controller_t {

} controller_t;

namespace bluetooth {
namespace legacy {
const controller_t* controller_get_interface();
}  // namespace legacy
}  // namespace bluetooth

const controller_t* controller_get_interface();

const controller_t* controller_get_test_interface(
+11 −1
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include "btcore/include/module.h"
#include "btcore/include/version.h"
#include "hcimsgs.h"
#include "main/shim/controller.h"
#include "main/shim/shim.h"
#include "osi/include/future.h"
#include "stack/include/btm_ble_api.h"

@@ -582,7 +584,7 @@ static const controller_t interface = {
    get_local_supported_codecs,
    get_le_all_initiating_phys};

const controller_t* controller_get_interface() {
const controller_t* bluetooth::legacy::controller_get_interface() {
  static bool loaded = false;
  if (!loaded) {
    loaded = true;
@@ -595,6 +597,14 @@ const controller_t* controller_get_interface() {
  return &interface;
}

const controller_t* controller_get_interface() {
  if (bluetooth::shim::is_gd_shim_enabled()) {
    return bluetooth::shim::controller_get_interface();
  } else {
    return bluetooth::legacy::controller_get_interface();
  }
}

const controller_t* controller_get_test_interface(
    const hci_t* hci_interface,
    const hci_packet_factory_t* packet_factory_interface,
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ filegroup {
    name: "BluetoothShimSources",
    srcs: [
            "controller.cc",
            "hci_layer.cc",
            "stack.cc",
    ],
}
+233 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 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.
 */
#define LOG_TAG "bt_gd_shim"

#include <cstdint>
#include <memory>
#include <queue>
#include <unordered_map>
#include <vector>

#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
#include "module.h"
#include "os/handler.h"
#include "os/log.h"
#include "packet/raw_builder.h"
#include "shim/hci_layer.h"

namespace bluetooth {
namespace shim {

using TokenQueue = std::queue<const void*>;
using OpCodeTokenQueueMap = std::unordered_map<hci::OpCode, TokenQueue>;

const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); });

struct HciLayer::impl {
  impl(os::Handler* handler, hci::HciLayer* hci_layer) : handler_(handler), hci_layer_(hci_layer) {}

  void OnTransmitPacketCommandComplete(hci::CommandCompleteView view) {
    if (command_complete_callback_ == nullptr) {
      LOG_WARN("%s Received packet complete with no complete callback registered", __func__);
      return;
    }

    uint16_t command_op_code = static_cast<uint16_t>(view.GetCommandOpCode());
    std::vector<const uint8_t> data(view.begin(), view.end());

    if (op_code_token_queue_map_.count(view.GetCommandOpCode()) == 0) {
      LOG_WARN("%s Received unexpected command complete for opcode:0x%04x", __func__, command_op_code);
      return;
    }
    const void* token = op_code_token_queue_map_[view.GetCommandOpCode()].front();
    if (token == nullptr) {
      LOG_WARN("%s Received expected command status but no token for opcode:0x%04x", __func__, command_op_code);
      return;
    }

    op_code_token_queue_map_[view.GetCommandOpCode()].pop();
    command_complete_callback_(command_op_code, data, token);
  }

  void OnTransmitPacketStatus(hci::CommandStatusView view) {
    if (command_status_callback_ == nullptr) {
      LOG_WARN("%s Received packet complete with no status callback registered", __func__);
      return;
    }

    uint16_t command_op_code = static_cast<uint16_t>(view.GetCommandOpCode());
    std::vector<const uint8_t> data(view.begin(), view.end());

    if (op_code_token_queue_map_.count(view.GetCommandOpCode()) == 0) {
      LOG_WARN("%s Received unexpected command status for opcode:0x%04x", __func__, command_op_code);
      return;
    }
    const void* token = op_code_token_queue_map_[view.GetCommandOpCode()].front();
    if (token == nullptr) {
      LOG_WARN("%s Received expected command status but no token for opcode:0x%04x", __func__, command_op_code);
      return;
    }

    op_code_token_queue_map_[view.GetCommandOpCode()].pop();
    uint8_t status = static_cast<uint8_t>(view.GetStatus());
    command_status_callback_(command_op_code, data, token, status);
  }

  void TransmitCommand(uint16_t command, const uint8_t* data, size_t len, const void* token) {
    ASSERT(data != nullptr);
    ASSERT(token != nullptr);

    const hci::OpCode op_code = static_cast<const hci::OpCode>(command);

    auto payload = MakeUniquePacket(data, len);
    auto packet = hci::CommandPacketBuilder::Create(op_code, std::move(payload));

    op_code_token_queue_map_[op_code].push(token);
    if (IsCommandStatusOpcode(op_code)) {
      hci_layer_->EnqueueCommand(std::move(packet),
                                 common::BindOnce(&impl::OnTransmitPacketStatus, common::Unretained(this)), handler_);
    } else {
      hci_layer_->EnqueueCommand(std::move(packet),
                                 common::BindOnce(&impl::OnTransmitPacketCommandComplete, common::Unretained(this)),
                                 handler_);
    }
  }

  void RegisterCommandComplete(CommandCompleteCallback callback) {
    ASSERT(command_complete_callback_ == nullptr);
    command_complete_callback_ = callback;
  }

  void UnregisterCommandComplete() {
    ASSERT(command_complete_callback_ != nullptr);
    command_complete_callback_ = nullptr;
  }

  void RegisterCommandStatus(CommandStatusCallback callback) {
    ASSERT(command_status_callback_ == nullptr);
    command_status_callback_ = callback;
  }

  void UnregisterCommandStatus() {
    ASSERT(command_status_callback_ != nullptr);
    command_status_callback_ = nullptr;
  }

 private:
  os::Handler* handler_{nullptr};
  hci::HciLayer* hci_layer_{nullptr};

  CommandCompleteCallback command_complete_callback_;
  CommandStatusCallback command_status_callback_;

  OpCodeTokenQueueMap op_code_token_queue_map_;

  /**
   * Returns true if expecting command complete, false otherwise
   */
  bool IsCommandStatusOpcode(hci::OpCode op_code) {
    switch (op_code) {
      case hci::OpCode::INQUIRY:
      case hci::OpCode::CREATE_CONNECTION:
      case hci::OpCode::DISCONNECT:
      case hci::OpCode::ACCEPT_CONNECTION_REQUEST:
      case hci::OpCode::REJECT_CONNECTION_REQUEST:
      case hci::OpCode::CHANGE_CONNECTION_PACKET_TYPE:
      case hci::OpCode::AUTHENTICATION_REQUESTED:
      case hci::OpCode::SET_CONNECTION_ENCRYPTION:
      case hci::OpCode::CHANGE_CONNECTION_LINK_KEY:
      case hci::OpCode::MASTER_LINK_KEY:
      case hci::OpCode::REMOTE_NAME_REQUEST:
      case hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES:
      case hci::OpCode::READ_REMOTE_EXTENDED_FEATURES:
      case hci::OpCode::READ_REMOTE_VERSION_INFORMATION:
      case hci::OpCode::READ_CLOCK_OFFSET:
      case hci::OpCode::SETUP_SYNCHRONOUS_CONNECTION:
      case hci::OpCode::ACCEPT_SYNCHRONOUS_CONNECTION:
      case hci::OpCode::REJECT_SYNCHRONOUS_CONNECTION:
      case hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION:
      case hci::OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION:
      case hci::OpCode::HOLD_MODE:
      case hci::OpCode::SNIFF_MODE:
      case hci::OpCode::EXIT_SNIFF_MODE:
      case hci::OpCode::QOS_SETUP:
      case hci::OpCode::SWITCH_ROLE:
      case hci::OpCode::FLOW_SPECIFICATION:
      case hci::OpCode::REFRESH_ENCRYPTION_KEY:
      case hci::OpCode::LE_CREATE_CONNECTION:
      case hci::OpCode::LE_CONNECTION_UPDATE:
      case hci::OpCode::LE_READ_REMOTE_FEATURES:
      case hci::OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND:
      case hci::OpCode::LE_GENERATE_DHKEY_COMMAND:
      case hci::OpCode::LE_SET_PHY:
      case hci::OpCode::LE_EXTENDED_CREATE_CONNECTION:
      case hci::OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC:
        return true;
      default:
        return false;
    }
  }

  std::unique_ptr<packet::RawBuilder> MakeUniquePacket(const uint8_t* data, size_t len) {
    packet::RawBuilder builder;
    std::vector<uint8_t> bytes(data, data + len);

    auto payload = std::make_unique<packet::RawBuilder>();
    payload->AddOctets(bytes);

    return payload;
  }
};

void HciLayer::TransmitCommand(uint16_t op_code, const uint8_t* data, size_t len, const void* token) {
  pimpl_->TransmitCommand(op_code, data, len, std::move(token));
}

void HciLayer::RegisterCommandComplete(CommandCompleteCallback callback) {
  pimpl_->RegisterCommandComplete(callback);
}

void HciLayer::UnregisterCommandComplete() {
  pimpl_->UnregisterCommandComplete();
}

void HciLayer::RegisterCommandStatus(CommandStatusCallback callback) {
  pimpl_->RegisterCommandStatus(callback);
}

void HciLayer::UnregisterCommandStatus() {
  pimpl_->UnregisterCommandStatus();
}

/**
 * Module methods
 */
void HciLayer::ListDependencies(ModuleList* list) {
  list->add<hci::HciLayer>();
}

void HciLayer::Start() {
  LOG_INFO("%s Starting controller shim layer", __func__);
  pimpl_ = std::make_unique<impl>(GetHandler(), GetDependency<hci::HciLayer>());
}

void HciLayer::Stop() {
  pimpl_.reset();
}

}  // namespace shim
}  // namespace bluetooth
Loading