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

Commit 6d75bd0c authored by Zach Johnson's avatar Zach Johnson
Browse files

Migrate GD code to module

Test: atest --host bluetooth_test_gd
Change-Id: Ibcb219666ff5552efc602bf063e69a6e6b7e4bd8
parent 538dd9b1
Loading
Loading
Loading
Loading
+4 −17
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ cc_defaults {
        "-fvisibility=hidden",
        "-DLOG_NDEBUG=1",
        "-DGOOGLE_PROTOBUF_NO_RTTI",
        "-Wno-unused-parameter",
        "-Wno-implicit-fallthrough",
        "-Wno-unused-result",
    ],
    conlyflags: [
        "-std=c99",
@@ -116,9 +119,8 @@ cc_binary {
    ],
    host_supported: true,
    srcs: [
        "stack_manager.cc",
        "facade/stack_with_grpc_main.cc",
        "facade/facade_manager.cc",
        "grpc/grpc_module.cc",
        ":BluetoothCertFacade_hci_hal",
    ],
    generated_headers: [
@@ -146,11 +148,6 @@ cc_binary {
            ],
        },
    },
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-implicit-fallthrough",
        "-Wno-unused-result",
    ],
    sanitize: {
        address: true,
    },
@@ -182,11 +179,6 @@ cc_test {
    sanitize: {
        address: true,
    },
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-implicit-fallthrough",
        "-Wno-unused-result",
    ],
}

cc_test {
@@ -228,11 +220,6 @@ cc_test {
        ":BluetoothL2capTestSources",
        ":BluetoothPacketTestSources",
    ],
    cflags: [
        "-Wno-unused-parameter",
        "-Wno-implicit-fallthrough",
        "-Wno-unused-result",
    ],
    generated_headers : [
        "BluetoothGeneratedPackets_h",
    ],
+27 −11
Original line number Diff line number Diff line
@@ -14,26 +14,33 @@
 * limitations under the License.
 */

#include "facade/facade_manager.h"
#include "grpc/grpc_module.h"
#include "hal/hci_hal_host_rootcanal.h"
#include "hal/facade/facade.h"

#include <csignal>
#include <string>
#include <thread>

using ::bluetooth::facade::FacadeConfig;
using ::bluetooth::facade::FacadeManager;
#include "stack_manager.h"

using ::bluetooth::hal::HciHalHostRootcanalConfig;
using ::bluetooth::StackManager;
using ::bluetooth::grpc::GrpcModule;
using ::bluetooth::ModuleList;

namespace {
static StackManager* stack;

void interrupt_handler(int) {
  FacadeManager::Get()->ShutDown();
  stack->GetInstance<GrpcModule>()->StopServer();
}
}  // namespace

// The entry point for the binary with libbluetooth + facades
int main(int argc, const char** argv) {
  signal(SIGINT, interrupt_handler);

  int port = 8899;

  const std::string arg_grpc_port = "--port=";
  const std::string arg_rootcanal_port = "--rootcanal-port=";
@@ -41,7 +48,7 @@ int main(int argc, const char** argv) {
    std::string arg = argv[i];
    if (arg.find(arg_grpc_port) == 0) {
      auto port_number = arg.substr(arg_grpc_port.size());
      FacadeConfig::Get()->SetGrpcPort(std::stoi(port_number));
      port = std::stoi(port_number);
    }
    if (arg.find(arg_rootcanal_port) == 0) {
      auto port_number = arg.substr(arg_rootcanal_port.size());
@@ -49,13 +56,22 @@ int main(int argc, const char** argv) {
    }
  }

  // TODO: This should be run-time configurable
  FacadeManager::Get()->EnableModule(FacadeManager::Module::HciHal);
  ModuleList modules;
  modules.add<::bluetooth::hal::facade::HalFacadeModule>();

  FacadeManager::Get()->StartUp();
  auto wait_thread = std::thread([] { FacadeManager::Get()->GrpcMainLoop(); });
  stack = new StackManager();
  stack->StartUp(&modules);

  GrpcModule* grpc_module = stack->GetInstance<GrpcModule>();
  grpc_module->StartServer("0.0.0.0", port);

  signal(SIGINT, interrupt_handler);
  auto wait_thread = std::thread([grpc_module] { grpc_module->RunGrpcLoop(); });
  wait_thread.join();
  FacadeManager::Get()->ShutDown();

  grpc_module->StopServer();
  stack->ShutDown();
  delete stack;

  return 0;
}
+122 −0
Original line number Diff line number Diff line
@@ -14,95 +14,109 @@
 * limitations under the License.
 */

#include "facade/facade_manager.h"
#include "grpc/grpc_module.h"

#include "grpc/async_grpc.h"
#include "hal/facade/facade.h"
#include "os/log.h"
#include "stack_manager.h"

using ::bluetooth::hal::HciPacket;
#include "grpc/async_grpc.h"

using ::grpc::Server;
using ::grpc::ServerBuilder;

namespace {

::bluetooth::facade::CertFacade* module_enum_to_module(const ::bluetooth::facade::FacadeManager::Module& module) {
  switch (module) {
    case ::bluetooth::facade::FacadeManager::Module::HciHal:
      return ::bluetooth::hal::facade::GetFacadeModule();
  }
  return nullptr;
}
}  // namespace

namespace bluetooth {
namespace facade {
namespace grpc {

void FacadeManager::EnableModule(Module module) {
  enabled_modules_.push_back(module);
void GrpcModule::ListDependencies(ModuleList* list) {
}

void FacadeManager::StartUp() {
  StackManager::Get()->StartUp();
  LOG_INFO("%d", FacadeConfig::Get()->GetGrpcPort());
  start_server("0.0.0.0", FacadeConfig::Get()->GetGrpcPort());

  for (const auto& enabled_module : enabled_modules_) {
    auto* module = module_enum_to_module(enabled_module);
    module->StartUp(get_grpc_completion_queue());
void GrpcModule::Start(const ModuleRegistry* registry) {
  ASSERT(!started_);
}

void GrpcModule::Stop(const ModuleRegistry* registry) {
  ASSERT(!started_);
}

void FacadeManager::start_server(const std::string& address, int port) {
void GrpcModule::StartServer(const std::string& address, int port) {
  ASSERT(!started_);
  started_ = true;

  std::string listening_port = address + ":" + std::to_string(port);
  ServerBuilder builder;
  builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());

  grpc_completion_queue_ = builder.AddCompletionQueue();
  for (const auto& enabled_module : enabled_modules_) {
    auto* module = module_enum_to_module(enabled_module);
    builder.RegisterService(module->GetModuleGrpcService());
  for (const auto& facade : facades_) {
    builder.RegisterService(facade->GetService());
  }

  builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
  completion_queue_ = builder.AddCompletionQueue();
  server_ = builder.BuildAndStart();

  for (const auto& facade : facades_) {
    facade->OnServerStarted(completion_queue_.get());
  }
}

void FacadeManager::ShutDown() {
  stop_server();
void GrpcModule::StopServer() {
  ASSERT(started_);

  server_->Shutdown();
  completion_queue_->Shutdown();

  for (const auto& enabled_module : enabled_modules_) {
    auto* module = module_enum_to_module(enabled_module);
    module->ShutDown();
  for (const auto& facade : facades_) {
    facade->OnServerStopped();
  }

  StackManager::Get()->ShutDown();
  started_ = false;
}

void FacadeManager::stop_server() {
  server_->Shutdown();
  grpc_completion_queue_->Shutdown();
void GrpcModule::Register(GrpcFacadeModule* facade) {
  ASSERT(!started_);

  facades_.push_back(facade);
}

void GrpcModule::Unregister(GrpcFacadeModule* facade) {
  ASSERT(!started_);

  for (auto it = facades_.begin(); it != facades_.end(); it++) {
    if (*it == facade) {
      facades_.erase(it);
      return;
    }
  }

::grpc::ServerCompletionQueue* FacadeManager::get_grpc_completion_queue() {
  auto* queue = grpc_completion_queue_.get();
  ASSERT(queue != nullptr);
  return queue;
  ASSERT(false);
}

void FacadeManager::GrpcMainLoop() {
void GrpcModule::RunGrpcLoop() {
  void* tag;
  bool ok;
  while (true) {
    if (!grpc_completion_queue_->Next(&tag, &ok)) {
    if (!completion_queue_->Next(&tag, &ok)) {
      LOG_INFO("gRPC is shutdown");
      break;
    }
    auto* data = static_cast<grpc::GrpcAsyncEventCallback*>(tag);
    auto* data = static_cast<GrpcAsyncEventCallback*>(tag);
    (*data)(ok);
  }
}

}  // namespace facade
const ::bluetooth::ModuleFactory GrpcModule::Factory = ::bluetooth::ModuleFactory([]() {
  return new GrpcModule();
});


void GrpcFacadeModule::ListDependencies(ModuleList* list) {
  list->add<GrpcModule>();
}

void GrpcFacadeModule::Start(const ModuleRegistry* registry) {
  registry->GetInstance<GrpcModule>()->Register(this);
}

void GrpcFacadeModule::Stop(const ModuleRegistry* registry) {
  registry->GetInstance<GrpcModule>()->Unregister(this);
}

}  // namespace grpc
}  // namespace bluetooth
+76 −0
Original line number Diff line number Diff line
@@ -17,81 +17,60 @@
#pragma once

#include <functional>
#include <list>
#include <vector>

#include <grpc++/grpc++.h>

#include "hal/hci_hal.h"
#include <module.h>

namespace bluetooth {
namespace facade {
namespace grpc {

class FacadeConfig {
 public:
  static FacadeConfig* Get() {
    static FacadeConfig instance;
    return &instance;
  }
class GrpcFacadeModule;

  void SetGrpcPort(int port) {
    grpc_port_ = port;
  }
class GrpcModule : public ::bluetooth::Module {
 public:
  static const ModuleFactory Factory;

  int GetGrpcPort() {
    return grpc_port_;
  }
  void StartServer(const std::string& address, int port);

 private:
  FacadeConfig() = default;
  int grpc_port_ = 8899;
};
  void StopServer();

class FacadeManager {
 public:
  enum class Module {
    HciHal,
  };
  void Register(GrpcFacadeModule* facade);

  static FacadeManager* Get() {
    static FacadeManager instance;
    return &instance;
  }
  void Unregister(GrpcFacadeModule* facade);

  void EnableModule(Module module);
  // Blocks for incoming gRPC requests
  void RunGrpcLoop();

  void StartUp();
 protected:
  void ListDependencies(ModuleList* list) override;

  void ShutDown();
  void Start(const ModuleRegistry* registry) override;

  // Blocks for incoming gRPC requests
  void GrpcMainLoop();
  void Stop(const ModuleRegistry* registry) override;

 private:
  bool started_;
  std::unique_ptr<::grpc::Server> server_ = nullptr;
  std::unique_ptr<::grpc::ServerCompletionQueue> grpc_completion_queue_ = nullptr;
  std::list<Module> enabled_modules_;
  void start_server(const std::string& address, int port);
  void stop_server();
  ::grpc::ServerCompletionQueue* get_grpc_completion_queue();
  std::unique_ptr<::grpc::ServerCompletionQueue> completion_queue_ = nullptr;
  std::vector<GrpcFacadeModule*> facades_;
};

// Cert facade for each layer
class CertFacade {
 public:
  virtual ~CertFacade() = default;
class GrpcFacadeModule : public ::bluetooth::Module {
 friend GrpcModule;
 protected:
  void ListDependencies(ModuleList* list) override;

  void Start(const ModuleRegistry* registry) override;

  void Stop(const ModuleRegistry* registry) override;

  // Initialize gRPC service, asynchronous request handlers, and other resources here.
  // This should be invoked after CompletionQueue is started.
  virtual void StartUp(::grpc::ServerCompletionQueue* cq) {}
  virtual ::grpc::Service* GetService() const = 0;

  // Do the clean up here
  // This should be invoked before CompletionQueue is shutdown.
  virtual void ShutDown() {}
  virtual void OnServerStarted(::grpc::ServerCompletionQueue* cq) {}

  // Each facade has a gRPC service that implements stubs from its api proto. The service instance should exist all
  // the time, so static storage is recommended.
  virtual ::grpc::Service* GetModuleGrpcService() const = 0;
  virtual void OnServerStopped() {}
};

}  // namespace facade
}  // namespace grpc
}  // namespace bluetooth
+1 −2
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
#include <string>
#include <thread>

#include "facade/facade_manager.h"
#include "hal/facade/api.grpc.pb.h"
#include "hci/hci_packets.h"
#include "os/log.h"
@@ -40,7 +39,7 @@ using ::bluetooth::hal::facade::LoopbackModeSettings;
class HalAdapterCertTest : public ::testing::Test {
 protected:
  void SetUp() override {
    int port = ::bluetooth::facade::FacadeConfig::Get()->GetGrpcPort();
    int port = 8899;
    std::string channel = "localhost:" + std::to_string(port);
    stub_ = HciTransportation::NewStub(grpc::CreateChannel(channel, grpc::InsecureChannelCredentials()));
  }
Loading