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

Commit 1a7196e4 authored by David Duarte's avatar David Duarte
Browse files

RootCanal: Split HciSocketDevice into HciDevice + HciSocketTransport

This is done by introducing a new HciTransport pure virtual class
used by HciDevice and implemented by HciSocketTransport

This make it possible to create other transport than the
HciSocketTransport

All the hci related code is also moved into a new model/hci
folder

Test: gd/cert/run
Change-Id: I7f5259aa87c51d58fc4c7c7c666e62060491f30f
parent c403466b
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -25,8 +25,9 @@

#include "hci_internals.h"
#include "log/log.h"
#include "model/devices/hci_socket_device.h"
#include "model/devices/hci_device.h"
#include "model/devices/link_layer_socket_device.h"
#include "model/hci/hci_socket_transport.h"

namespace android {
namespace hardware {
@@ -37,7 +38,8 @@ namespace sim {
using android::hardware::hidl_vec;
using rootcanal::AsyncTaskId;
using rootcanal::DualModeController;
using rootcanal::HciSocketDevice;
using rootcanal::HciDevice;
using rootcanal::HciSocketTransport;
using rootcanal::LinkLayerSocketDevice;
using rootcanal::TaskCallback;

@@ -205,7 +207,8 @@ Return<void> BluetoothHci::initialize_impl(
    SetUpTestChannel();
    SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket,
                          AsyncDataChannelServer* srv) {
      test_model_.AddHciConnection(HciSocketDevice::Create(socket, ""));
      auto transport = HciSocketTransport::Create(socket);
      test_model_.AddHciConnection(HciDevice::Create(transport, ""));
      srv->StartListening();
    });
    SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket,
+9 −8
Original line number Diff line number Diff line
@@ -80,13 +80,14 @@ cc_library_static {
        "model/controller/security_manager.cc",
        "model/devices/device.cc",
        "model/devices/device_properties.cc",
        "model/devices/h4_data_channel_packetizer.cc",
        "model/devices/h4_packetizer.cc",
        "model/devices/h4_parser.cc",
        "model/devices/hci_protocol.cc",
        "model/devices/hci_socket_device.cc",
        "model/devices/hci_device.cc",
        "model/devices/link_layer_socket_device.cc",
        "model/devices/remote_loopback_device.cc",
        "model/hci/h4_data_channel_packetizer.cc",
        "model/hci/h4_packetizer.cc",
        "model/hci/h4_parser.cc",
        "model/hci/hci_protocol.cc",
        "model/hci/hci_socket_transport.cc",
        "model/setup/async_manager.cc",
        "model/setup/phy_layer_factory.cc",
        "model/setup/test_channel_transport.cc",
@@ -230,9 +231,9 @@ cc_library_static {
        "gd_defaults",
    ],
    srcs: [
        "model/devices/h4_packetizer.cc",
        "model/devices/h4_parser.cc",
        "model/devices/hci_protocol.cc",
        "model/hci/h4_packetizer.cc",
        "model/hci/h4_parser.cc",
        "model/hci/hci_protocol.cc",
    ],

    local_include_dirs: [
+5 −3
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@
#include <utility>      // for move
#include <vector>       // for vector

#include "model/devices/hci_socket_device.h"         // for HciSocketDevice
#include "model/devices/link_layer_socket_device.h"  // for LinkLayerSocketDevice
#include "model/hci/hci_socket_transport.h"          // for HciSocketTransport
#include "net/async_data_channel.h"                  // for AsyncDataChannel
#include "net/async_data_channel_connector.h"  // for AsyncDataChannelConnector
#include "os/log.h"  // for LOG_INFO, LOG_ERROR, LOG_WARN
@@ -31,7 +31,8 @@ namespace bluetooth {
namespace root_canal {

using rootcanal::AsyncTaskId;
using rootcanal::HciSocketDevice;
using rootcanal::HciDevice;
using rootcanal::HciSocketTransport;
using rootcanal::LinkLayerSocketDevice;
using rootcanal::TaskCallback;

@@ -57,8 +58,9 @@ void TestEnvironment::initialize(std::promise<void> barrier) {
  SetUpTestChannel();
  SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket,
                        AsyncDataChannelServer* srv) {
    auto transport = HciSocketTransport::Create(socket);
    test_model_.AddHciConnection(
        HciSocketDevice::Create(socket, controller_properties_file_));
        HciDevice::Create(transport, controller_properties_file_));
    srv->StartListening();
  });
  SetUpLinkLayerServer();
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 The Android Open Source Project
 * Copyright 2022 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.
@@ -14,21 +14,15 @@
 * limitations under the License.
 */

#include "hci_socket_device.h"
#include "hci_device.h"

#include <chrono>       // for milliseconds
#include <type_traits>  // for remove_extent_t

#include "model/devices/device_properties.h"  // for DeviceProperties
#include "os/log.h"                           // for LOG_INFO, LOG_ALWAYS_FATAL

using std::vector;
#include "os/log.h"

namespace rootcanal {

HciSocketDevice::HciSocketDevice(std::shared_ptr<AsyncDataChannel> socket,
HciDevice::HciDevice(std::shared_ptr<HciTransport> transport,
                     const std::string& properties_filename)
    : DualModeController(properties_filename), socket_(socket) {
    : DualModeController(properties_filename), transport_(transport) {
  advertising_interval_ms_ = std::chrono::milliseconds(1000);

  page_scan_delay_ms_ = std::chrono::milliseconds(600);
@@ -36,7 +30,7 @@ HciSocketDevice::HciSocketDevice(std::shared_ptr<AsyncDataChannel> socket,
  properties_.SetPageScanRepetitionMode(0);
  properties_.SetClassOfDevice(0x600420);
  properties_.SetExtendedInquiryData({
      16,  // length
      12,  // length
      9,   // Type: Device Name
      'g',
      'D',
@@ -49,10 +43,7 @@ HciSocketDevice::HciSocketDevice(std::shared_ptr<AsyncDataChannel> socket,
      'h',
      'c',
      'i',
      '_',
      'n',
      'e',
      't',

  });
  properties_.SetName({
      'g',
@@ -66,77 +57,47 @@ HciSocketDevice::HciSocketDevice(std::shared_ptr<AsyncDataChannel> socket,
      'H',
      'C',
      'I',
      '_',
      'N',
      'e',
      't',
  });

  h4_ = H4DataChannelPacketizer(
      socket,
      [this](const std::vector<uint8_t>& raw_command) {
        std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::make_shared<std::vector<uint8_t>>(raw_command);
        HandleCommand(packet_copy);
      },
      [](const std::vector<uint8_t>&) {
        LOG_ALWAYS_FATAL("Unexpected Event in HciSocketDevice!");
      },
      [this](const std::vector<uint8_t>& raw_acl) {
        std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::make_shared<std::vector<uint8_t>>(raw_acl);
        HandleAcl(packet_copy);
      },
      [this](const std::vector<uint8_t>& raw_sco) {
        std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::make_shared<std::vector<uint8_t>>(raw_sco);
        HandleSco(packet_copy);
      },
      [this](const std::vector<uint8_t>& raw_iso) {
        std::shared_ptr<std::vector<uint8_t>> packet_copy =
            std::make_shared<std::vector<uint8_t>>(raw_iso);
        HandleIso(packet_copy);
      },
      [this]() {
        LOG_INFO("HCI socket device disconnected");
        Close();
  });

  RegisterEventChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
    SendHci(PacketType::EVENT, packet);
    transport_->SendEvent(*packet);
  });
  RegisterAclChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
    SendHci(PacketType::ACL, packet);
    transport_->SendAcl(*packet);
  });
  RegisterScoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
    SendHci(PacketType::SCO, packet);
    transport_->SendSco(*packet);
  });
  RegisterIsoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
    SendHci(PacketType::ISO, packet);
    transport_->SendIso(*packet);
  });
}

void HciSocketDevice::TimerTick() {
  h4_.OnDataReady(socket_);
  DualModeController::TimerTick();
  transport_->RegisterCallbacks(
      [this](const std::shared_ptr<std::vector<uint8_t>> command) {
        HandleCommand(command);
      },
      [this](const std::shared_ptr<std::vector<uint8_t>> acl) {
        HandleAcl(acl);
      },
      [this](const std::shared_ptr<std::vector<uint8_t>> sco) {
        HandleSco(sco);
      },
      [this](const std::shared_ptr<std::vector<uint8_t>> iso) {
        HandleIso(iso);
      },
      [this]() {
        LOG_INFO("HCI transport closed");
        Close();
      });
}

void HciSocketDevice::SendHci(
    PacketType packet_type,
    const std::shared_ptr<std::vector<uint8_t>> packet) {
  if (!socket_ || !socket_->Connected()) {
    LOG_INFO("Closed socket. Dropping packet of type %d",
             static_cast<int>(packet_type));
    return;
  }
  uint8_t type = static_cast<uint8_t>(packet_type);
  h4_.Send(type, packet->data(), packet->size());
void HciDevice::TimerTick() {
  transport_->TimerTick();
  DualModeController::TimerTick();
}

void HciSocketDevice::Close() {
  if (socket_) {
    socket_->Close();
  }
void HciDevice::Close() {
  transport_->Close();
  DualModeController::Close();
}

+49 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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 <memory>  // for shared_ptr, make_...
#include <string>  // for string

#include "model/controller/dual_mode_controller.h"  // for DualModeController
#include "model/hci/hci_transport.h"                // for HciTransport

namespace rootcanal {

class HciDevice : public DualModeController {
 public:
  HciDevice(std::shared_ptr<HciTransport> transport,
            const std::string& properties_filename);
  ~HciDevice() = default;

  static std::shared_ptr<HciDevice> Create(
      std::shared_ptr<HciTransport> transport,
      const std::string& properties_filename) {
    return std::make_shared<HciDevice>(transport, properties_filename);
  }

  std::string GetTypeString() const override { return "hci_device"; }

  void TimerTick() override;

  void Close() override;

 private:
  std::shared_ptr<HciTransport> transport_;
};

}  // namespace rootcanal
Loading