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

Commit 46e84bf1 authored by Erwin Jansen's avatar Erwin Jansen Committed by Connor O'Brien
Browse files

Revert "Use abstract datachannels in Root Canal."

This reverts commit a3ae33f0.

Reason for revert: This breaks sdk, sdk_arm64,sdk_x86,sdk_x86_64

Bug: 194421341
Change-Id: I47ac59c0a76e83edfb35924b0bc0a00f27828368
parent a3ae33f0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ cc_library_static {
        "model/devices/keyboard.cc",
        "model/devices/link_layer_socket_device.cc",
        "model/devices/loopback.cc",
        "model/devices/polled_socket.cc",
        "model/devices/remote_loopback_device.cc",
        "model/devices/scripted_beacon.cc",
        "model/devices/sniffer.cc",
+10 −16
Original line number Diff line number Diff line
@@ -13,24 +13,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "test_environment.h"

#include <future>

#include <client/linux/handler/exception_handler.h>

#include <backtrace/Backtrace.h>
#include <backtrace/backtrace_constants.h>
#include <client/linux/handler/exception_handler.h>
#include <gflags/gflags.h>

#include <future>
#include <gflags/gflags.h>

#include "model/setup/async_manager.h"
#include "net/posix/posix_async_socket_connector.h"
#include "net/posix/posix_async_socket_server.h"
#include "os/log.h"

using ::android::bluetooth::root_canal::TestEnvironment;
using ::android::net::PosixAsyncSocketConnector;
using ::android::net::PosixAsyncSocketServer;
using test_vendor_lib::AsyncManager;

DEFINE_string(controller_properties_file, "",
              "controller_properties.json file path");
@@ -114,13 +111,10 @@ int main(int argc, char** argv) {
      }
    }
  }
  AsyncManager am;
  TestEnvironment root_canal(
      std::make_shared<PosixAsyncSocketServer>(test_port, &am),
      std::make_shared<PosixAsyncSocketServer>(hci_server_port, &am),
      std::make_shared<PosixAsyncSocketServer>(link_server_port, &am),
      std::make_shared<PosixAsyncSocketConnector>(&am),
      FLAGS_controller_properties_file, FLAGS_default_commands_file);

  TestEnvironment root_canal(test_port, hci_server_port, link_server_port,
                             FLAGS_controller_properties_file,
                             FLAGS_default_commands_file);
  std::promise<void> barrier;
  std::future<void> barrier_future = barrier.get_future();
  root_canal.initialize(std::move(barrier));
+117 −53
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

#include "test_environment.h"

#include <type_traits>  // for remove_extent_t
#include <utility>      // for move
#include <vector>       // for vector
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include "net/async_data_channel.h"  // for AsyncDataChannel
#include "os/log.h"                  // for LOG_INFO, LOG_ERROR, LOG_WARN
#include "os/log.h"

namespace android {
namespace bluetooth {
@@ -50,16 +52,13 @@ void TestEnvironment::initialize(std::promise<void> barrier) {
      });

  SetUpTestChannel();
  SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket,
                        AsyncDataChannelServer* srv) {
    test_model_.IncomingHciConnection(socket);
    srv->StartListening();
  });
  SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket,
                              AsyncDataChannelServer* srv) {
    test_model_.IncomingLinkLayerConnection(socket);
    srv->StartListening();
  });
  SetUpHciServer([this](int fd) { test_model_.IncomingHciConnection(fd); });
  SetUpLinkLayerServer([this](int fd) { test_model_.IncomingLinkLayerConnection(fd); });

  // In case the client socket is closed, and rootcanal doesn't detect it due to
  // TimerTick not fired, writing to the socket causes a SIGPIPE and we need to
  // catch it to prevent rootcanal from crash
  signal(SIGPIPE, SIG_IGN);

  LOG_INFO("%s: Finished", __func__);
}
@@ -69,54 +68,92 @@ void TestEnvironment::close() {
  test_model_.Reset();
}

void TestEnvironment::SetUpHciServer(ConnectCallback connection_callback) {
  test_channel_.RegisterSendResponse([](const std::string& response) {
    LOG_INFO("No HCI Response channel: %s", response.c_str());
  });
void TestEnvironment::SetUpHciServer(const std::function<void(int)>& connection_callback) {
  int socket_fd = remote_hci_transport_.SetUp(hci_server_port_);

  test_channel_.RegisterSendResponse(
      [](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); });

  if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) {
    LOG_ERROR("Remote HCI channel SetUp failed.");
  if (socket_fd == -1) {
    LOG_ERROR("Remote HCI channel SetUp(%d) failed.", hci_server_port_);
    return;
  }
}

void TestEnvironment::SetUpLinkLayerServer(
    ConnectCallback connection_callback) {
  remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback);
  async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
    int conn_fd = remote_hci_transport_.Accept(socket_fd);
    if (conn_fd < 0) {
      LOG_ERROR("Error watching remote HCI channel fd.");
      return;
    }
    int flags = fcntl(conn_fd, F_GETFL, NULL);
    int ret;
    ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
    ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno));

  test_channel_.RegisterSendResponse([](const std::string& response) {
    LOG_INFO("No LinkLayer Response channel: %s", response.c_str());
    connection_callback(conn_fd);
  });
}

std::shared_ptr<AsyncDataChannel> TestEnvironment::ConnectToRemoteServer(
    const std::string& server, int port) {
  return connector_->ConnectToRemoteServer(server, port);
void TestEnvironment::SetUpLinkLayerServer(const std::function<void(int)>& connection_callback) {
  int socket_fd = remote_link_layer_transport_.SetUp(link_server_port_);

  test_channel_.RegisterSendResponse(
      [](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); });

  if (socket_fd == -1) {
    LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", link_server_port_);
    return;
  }

void TestEnvironment::SetUpTestChannel() {
  bool transport_configured = test_channel_transport_.SetUp(
      test_socket_server_, [this](std::shared_ptr<AsyncDataChannel> conn_fd,
                                  AsyncDataChannelServer*) {
        LOG_INFO("Test channel connection accepted.");
        if (test_channel_open_) {
          LOG_WARN("Only one connection at a time is supported");
          test_channel_transport_.SendResponse(conn_fd,
                                               "The connection is broken");
          return false;
  async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
    int conn_fd = remote_link_layer_transport_.Accept(socket_fd);
    if (conn_fd < 0) {
      LOG_ERROR("Error watching remote LinkLayer channel fd.");
      return;
    }
        test_channel_open_ = true;
        test_channel_.RegisterSendResponse(
            [this, conn_fd](const std::string& response) {
              test_channel_transport_.SendResponse(conn_fd, response);
            });
    int flags = fcntl(conn_fd, F_GETFL, NULL);
    int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
    ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno));

        conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) {
          test_channel_transport_.OnCommandReady(
              conn_fd, [this]() { test_channel_open_ = false; });
        });
        return false;
    connection_callback(conn_fd);
  });
}

int TestEnvironment::ConnectToRemoteServer(const std::string& server, int port) {
  int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (socket_fd < 1) {
    LOG_INFO("socket() call failed: %s", strerror(errno));
    return -1;
  }

  struct hostent* host;
  host = gethostbyname(server.c_str());
  if (host == NULL) {
    LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno));
    return -1;
  }

  struct sockaddr_in serv_addr {};
  memset((void*)&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port);

  int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
  if (result < 0) {
    LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno));
    return -1;
  }

  int flags = fcntl(socket_fd, F_GETFL, NULL);
  int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
  ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno));

  return socket_fd;
}

void TestEnvironment::SetUpTestChannel() {
  int socket_fd = test_channel_transport_.SetUp(test_port_);
  test_channel_.RegisterSendResponse([](const std::string& response) {
    LOG_INFO("No test channel: %s", response.c_str());
  });
@@ -127,12 +164,39 @@ void TestEnvironment::SetUpTestChannel() {

  test_channel_.FromFile(default_commands_file_);

  if (!transport_configured) {
    LOG_ERROR("Test channel SetUp failed.");
  if (socket_fd == -1) {
    LOG_ERROR("Test channel SetUp(%d) failed.", test_port_);
    return;
  }

  LOG_INFO("Test channel SetUp() successful");
  async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
    int conn_fd = test_channel_transport_.Accept(socket_fd);
    if (conn_fd < 0) {
      LOG_ERROR("Error watching test channel fd.");
      barrier_.set_value();
      return;
    }
    LOG_INFO("Test channel connection accepted.");
    if (test_channel_open_) {
      LOG_WARN("Only one connection at a time is supported");
      async_manager_.StopWatchingFileDescriptor(conn_fd);
      test_channel_transport_.SendResponse(conn_fd, "The connection is broken");
      return;
    }
    test_channel_open_ = true;
    test_channel_.RegisterSendResponse(
        [this, conn_fd](const std::string& response) {
          test_channel_transport_.SendResponse(conn_fd, response);
        });

    async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
      test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() {
        async_manager_.StopWatchingFileDescriptor(conn_fd);
        test_channel_open_ = false;
      });
    });
  });
}

}  // namespace root_canal
+20 −39
Original line number Diff line number Diff line
@@ -16,45 +16,27 @@

#pragma once

#include <chrono>      // for milliseconds
#include <functional>  // for __base, function
#include <future>      // for promise
#include <memory>      // for shared_ptr, make_...
#include <string>      // for string

#include "model/controller/dual_mode_controller.h"  // for DualModeController
#include "model/setup/async_manager.h"              // for AsyncTaskId, Asyn...
#include "model/setup/test_channel_transport.h"     // for TestChannelTransport
#include "model/setup/test_command_handler.h"       // for TestCommandHandler
#include "model/setup/test_model.h"                 // for TestModel
#include "net/async_data_channel_server.h"          // for AsyncDataChannelS...
#include <future>

namespace android {
namespace net {
class AsyncDataChannel;
class AsyncDataChannelConnector;
}  // namespace net
#include "model/controller/dual_mode_controller.h"
#include "model/setup/async_manager.h"
#include "model/setup/test_channel_transport.h"
#include "model/setup/test_command_handler.h"
#include "model/setup/test_model.h"

namespace android {
namespace bluetooth {
namespace root_canal {

using android::net::AsyncDataChannel;
using android::net::AsyncDataChannelConnector;
using android::net::AsyncDataChannelServer;
using android::net::ConnectCallback;

class TestEnvironment {
 public:
  TestEnvironment(std::shared_ptr<AsyncDataChannelServer> test_port,
                  std::shared_ptr<AsyncDataChannelServer> hci_server_port,
                  std::shared_ptr<AsyncDataChannelServer> link_server_port,
                  std::shared_ptr<AsyncDataChannelConnector> connector,
  TestEnvironment(uint16_t test_port, uint16_t hci_server_port,
                  uint16_t link_server_port,
                  const std::string& controller_properties_file = "",
                  const std::string& default_commands_file = "")
      : test_socket_server_(test_port),
        hci_socket_server_(hci_server_port),
        link_socket_server_(link_server_port),
        connector_(connector),
      : test_port_(test_port),
        hci_server_port_(hci_server_port),
        link_server_port_(link_server_port),
        default_commands_file_(default_commands_file),
        controller_(std::make_shared<test_vendor_lib::DualModeController>(
            controller_properties_file)) {}
@@ -64,10 +46,9 @@ class TestEnvironment {
  void close();

 private:
  std::shared_ptr<AsyncDataChannelServer> test_socket_server_;
  std::shared_ptr<AsyncDataChannelServer> hci_socket_server_;
  std::shared_ptr<AsyncDataChannelServer> link_socket_server_;
  std::shared_ptr<AsyncDataChannelConnector> connector_;
  uint16_t test_port_;
  uint16_t hci_server_port_;
  uint16_t link_server_port_;
  std::string default_commands_file_;
  bool test_channel_open_{false};
  std::promise<void> barrier_;
@@ -75,10 +56,9 @@ class TestEnvironment {
  test_vendor_lib::AsyncManager async_manager_;

  void SetUpTestChannel();
  void SetUpHciServer(ConnectCallback on_connect);
  void SetUpLinkLayerServer(ConnectCallback on_connect);
  std::shared_ptr<AsyncDataChannel> ConnectToRemoteServer(
      const std::string& server, int port);
  void SetUpHciServer(const std::function<void(int)>& on_connect);
  void SetUpLinkLayerServer(const std::function<void(int)>& on_connect);
  int ConnectToRemoteServer(const std::string& server, int port);

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

@@ -115,6 +95,7 @@ class TestEnvironment {

  test_vendor_lib::TestCommandHandler test_channel_{test_model_};
};

}  // namespace root_canal
}  // namespace bluetooth
}  // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ size_t H4DataChannelPacketizer::Send(uint8_t type, const uint8_t* data,

void H4DataChannelPacketizer::OnDataReady(
    std::shared_ptr<AsyncDataChannel> socket) {
  if (!socket->Connected()) return;
  ssize_t bytes_to_read = h4_parser_.BytesRequested();
  std::vector<uint8_t> buffer(bytes_to_read);

Loading