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

Commit 5b236200 authored by David Duarte's avatar David Duarte
Browse files

RootCanal: Decouple TestModel from {LinkLayer,Hci}SocketDevice

Instead of constructing the {LinkLayer,Hci}SocketDevice
inside the test model take it as a parameter and expose it
to the TestModel caller to be able to give subclasses to
the testmodel

This also remove the hard dependency of socket
for the TestModel

Test: gd/cert/run
Change-Id: Ia516a41463174baf186e0c3c4fe4da04393756cc
parent c66d849a
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@

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

namespace android {
namespace hardware {
@@ -35,6 +37,8 @@ namespace sim {
using android::hardware::hidl_vec;
using rootcanal::AsyncTaskId;
using rootcanal::DualModeController;
using rootcanal::HciSocketDevice;
using rootcanal::LinkLayerSocketDevice;
using rootcanal::TaskCallback;

namespace {
@@ -201,12 +205,14 @@ Return<void> BluetoothHci::initialize_impl(
    SetUpTestChannel();
    SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket,
                          AsyncDataChannelServer* srv) {
      test_model_.IncomingHciConnection(socket);
      test_model_.AddHciConnection(HciSocketDevice::Create(socket, ""));
      srv->StartListening();
    });
    SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket,
                                AsyncDataChannelServer* srv) {
      test_model_.IncomingLinkLayerConnection(socket);
      auto phy_type = Phy::Type::BR_EDR;
      test_model_.AddLinkLayerConnection(
          LinkLayerSocketDevice::Create(socket, phy_type), phy_type);
      srv->StartListening();
    });
  } else {
@@ -313,9 +319,11 @@ void BluetoothHci::SetUpLinkLayerServer(ConnectCallback connection_callback) {
  });
}

std::shared_ptr<AsyncDataChannel> BluetoothHci::ConnectToRemoteServer(
    const std::string& server, int port) {
  return connector_->ConnectToRemoteServer(server, port);
std::shared_ptr<Device> BluetoothHci::ConnectToRemoteServer(
    const std::string& server, int port, Phy::Type phy_type) {
  auto socket = connector_->ConnectToRemoteServer(server, port);
  if (!socket->Connected()) return nullptr;
  return LinkLayerSocketDevice::Create(socket, phy_type);
}

void BluetoothHci::SetUpTestChannel() {
+7 −4
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ using android::net::AsyncDataChannelConnector;
using android::net::AsyncDataChannelServer;
using android::net::ConnectCallback;

using rootcanal::Device;
using rootcanal::Phy;

class BluetoothHci : public IBluetoothHci {
 public:
  BluetoothHci();
@@ -89,8 +92,8 @@ class BluetoothHci : public IBluetoothHci {
  void SetUpTestChannel();
  void SetUpHciServer(ConnectCallback on_connect);
  void SetUpLinkLayerServer(ConnectCallback on_connect);
  std::shared_ptr<AsyncDataChannel> ConnectToRemoteServer(
      const std::string& server, int port);
  std::shared_ptr<Device> ConnectToRemoteServer(const std::string& server,
                                                int port, Phy::Type phy_type);

  std::shared_ptr<rootcanal::DualModeController> controller_;

@@ -121,8 +124,8 @@ class BluetoothHci : public IBluetoothHci {
        async_manager_.CancelAsyncTask(task);
      },

      [this](const std::string& server, int port) {
        return ConnectToRemoteServer(server, port);
      [this](const std::string& server, int port, Phy::Type phy_type) {
        return ConnectToRemoteServer(server, port, phy_type);
      }};
  rootcanal::TestCommandHandler test_channel_{test_model_};
};
+20 −8
Original line number Diff line number Diff line
@@ -20,7 +20,10 @@
#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 "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

namespace android {
@@ -28,6 +31,8 @@ namespace bluetooth {
namespace root_canal {

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

void TestEnvironment::initialize(std::promise<void> barrier) {
@@ -52,7 +57,8 @@ void TestEnvironment::initialize(std::promise<void> barrier) {
  SetUpTestChannel();
  SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket,
                        AsyncDataChannelServer* srv) {
    test_model_.IncomingHciConnection(socket, controller_properties_file_);
    test_model_.AddHciConnection(
        HciSocketDevice::Create(socket, controller_properties_file_));
    srv->StartListening();
  });
  SetUpLinkLayerServer();
@@ -81,7 +87,9 @@ void TestEnvironment::SetUpLinkBleLayerServer() {
  remote_link_layer_transport_.SetUp(
      link_ble_socket_server_, [this](std::shared_ptr<AsyncDataChannel> socket,
                                      AsyncDataChannelServer* srv) {
        test_model_.IncomingLinkBleLayerConnection(socket);
        auto phy_type = Phy::Type::LOW_ENERGY;
        test_model_.AddLinkLayerConnection(
            LinkLayerSocketDevice::Create(socket, phy_type), phy_type);
        srv->StartListening();
      });

@@ -94,7 +102,9 @@ void TestEnvironment::SetUpLinkLayerServer() {
  remote_link_layer_transport_.SetUp(
      link_socket_server_, [this](std::shared_ptr<AsyncDataChannel> socket,
                                  AsyncDataChannelServer* srv) {
        test_model_.IncomingLinkLayerConnection(socket);
        auto phy_type = Phy::Type::BR_EDR;
        test_model_.AddLinkLayerConnection(
            LinkLayerSocketDevice::Create(socket, phy_type), phy_type);
        srv->StartListening();
      });

@@ -103,9 +113,11 @@ void TestEnvironment::SetUpLinkLayerServer() {
  });
}

std::shared_ptr<AsyncDataChannel> TestEnvironment::ConnectToRemoteServer(
    const std::string& server, int port) {
  return connector_->ConnectToRemoteServer(server, port);
std::shared_ptr<Device> TestEnvironment::ConnectToRemoteServer(
    const std::string& server, int port, Phy::Type phy_type) {
  auto socket = connector_->ConnectToRemoteServer(server, port);
  if (!socket->Connected()) return nullptr;
  return LinkLayerSocketDevice::Create(socket, phy_type);
}

void TestEnvironment::SetUpTestChannel() {
+8 −5
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ using android::net::AsyncDataChannelConnector;
using android::net::AsyncDataChannelServer;
using android::net::ConnectCallback;

using rootcanal::Device;
using rootcanal::Phy;

class TestEnvironment {
 public:
  TestEnvironment(std::shared_ptr<AsyncDataChannelServer> test_port,
@@ -82,8 +85,8 @@ class TestEnvironment {
  void SetUpHciServer(ConnectCallback on_connect);
  void SetUpLinkLayerServer();
  void SetUpLinkBleLayerServer();
  std::shared_ptr<AsyncDataChannel> ConnectToRemoteServer(
      const std::string& server, int port);
  std::shared_ptr<Device> ConnectToRemoteServer(const std::string& server,
                                                int port, Phy::Type phy_type);

  std::shared_ptr<rootcanal::DualModeController> controller_;

@@ -114,8 +117,8 @@ class TestEnvironment {
        async_manager_.CancelAsyncTask(task);
      },

      [this](const std::string& server, int port) {
        return ConnectToRemoteServer(server, port);
      [this](const std::string& server, int port, Phy::Type phy_type) {
        return ConnectToRemoteServer(server, port, phy_type);
      }};

  rootcanal::TestCommandHandler test_channel_{test_model_};
+17 −40
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@
#include <utility>      // for move

#include "include/phy.h"  // for Phy, Phy::Type
#include "model/devices/hci_socket_device.h"         // for HciSocketDevice
#include "model/devices/link_layer_socket_device.h"  // for LinkLayerSocketDevice
#include "os/log.h"       // for LOG_WARN, LOG_INFO

namespace rootcanal {
@@ -43,7 +41,7 @@ TestModel::TestModel(

    std::function<void(AsyncUserId)> cancel_tasks_from_user,
    std::function<void(AsyncTaskId)> cancel,
    std::function<std::shared_ptr<AsyncDataChannel>(const std::string&, int)>
    std::function<std::shared_ptr<Device>(const std::string&, int, Phy::Type)>
        connect_to_remote)
    : get_user_id_(std::move(get_user_id)),
      schedule_task_(std::move(event_scheduler)),
@@ -144,12 +142,10 @@ void TestModel::DelDeviceFromPhy(size_t dev_index, size_t phy_index) {
                 });
}

void TestModel::AddLinkLayerConnection(std::shared_ptr<AsyncDataChannel> socket,
void TestModel::AddLinkLayerConnection(std::shared_ptr<Device> dev,
                                       Phy::Type phy_type) {
  LOG_INFO("Adding a new link layer connection of type: %s",
           phy_type == Phy::Type::BR_EDR ? "BR_EDR" : "LOW_ENERGY");
  std::shared_ptr<Device> dev = LinkLayerSocketDevice::Create(socket, phy_type);

  int index = Add(dev);
  AsyncUserId user_id = get_user_id_();

@@ -159,39 +155,23 @@ void TestModel::AddLinkLayerConnection(std::shared_ptr<AsyncDataChannel> socket,
    }
  }

  dev->RegisterCloseCallback([this, socket, index, user_id] {
    schedule_task_(user_id, std::chrono::milliseconds(0),
                   [this, socket, index, user_id]() {
                     OnConnectionClosed(socket, index, user_id);
                   });
  dev->RegisterCloseCallback([this, index, user_id] {
    schedule_task_(
        user_id, std::chrono::milliseconds(0),
        [this, index, user_id]() { OnConnectionClosed(index, user_id); });
  });
}

void TestModel::IncomingLinkLayerConnection(
    std::shared_ptr<AsyncDataChannel> socket) {
  LOG_INFO("A new link layer connection has arrived.");
  AddLinkLayerConnection(socket, Phy::Type::BR_EDR);
}

void TestModel::IncomingLinkBleLayerConnection(
    std::shared_ptr<AsyncDataChannel> socket) {
  LOG_INFO("A new low energery link layer (BLE) connection has arrived.");
  AddLinkLayerConnection(socket, Phy::Type::LOW_ENERGY);
}

void TestModel::AddRemote(const std::string& server, int port,
                          Phy::Type phy_type) {
  LOG_INFO("Connecting to %s:%d", server.c_str(), port);
  std::shared_ptr<AsyncDataChannel> socket = connect_to_remote_(server, port);
  if (!socket->Connected()) {
  auto dev = connect_to_remote_(server, port, phy_type);
  if (dev == nullptr) {
    return;
  }
  AddLinkLayerConnection(socket, phy_type);
  AddLinkLayerConnection(dev, phy_type);
}

void TestModel::IncomingHciConnection(std::shared_ptr<AsyncDataChannel> socket,
                                      std::string properties_filename) {
  auto dev = HciSocketDevice::Create(socket, properties_filename);
void TestModel::AddHciConnection(std::shared_ptr<HciSocketDevice> dev) {
  size_t index = Add(std::static_pointer_cast<Device>(dev));
  std::string addr = "da:4c:10:de:17:";  // Da HCI dev
  std::stringstream stream;
@@ -209,21 +189,18 @@ void TestModel::IncomingHciConnection(std::shared_ptr<AsyncDataChannel> socket,
    return schedule_task_(user_id, delay, std::move(task_callback));
  });
  dev->RegisterTaskCancel(cancel_task_);
  dev->RegisterCloseCallback([this, socket, index, user_id] {
    schedule_task_(user_id, std::chrono::milliseconds(0),
                   [this, socket, index, user_id]() {
                     OnConnectionClosed(socket, index, user_id);
                   });
  dev->RegisterCloseCallback([this, index, user_id] {
    schedule_task_(
        user_id, std::chrono::milliseconds(0),
        [this, index, user_id]() { OnConnectionClosed(index, user_id); });
  });
}

void TestModel::OnConnectionClosed(std::shared_ptr<AsyncDataChannel> socket,
                                   size_t index, AsyncUserId user_id) {
void TestModel::OnConnectionClosed(size_t index, AsyncUserId user_id) {
  if (index >= devices_.size() || devices_[index] == nullptr) {
    LOG_WARN("Unknown device %zu", index);
    return;
  }
  socket->Close();

  cancel_tasks_from_user_(user_id);
  devices_[index]->UnregisterPhyLayers();
Loading