Loading system/gd/Android.bp +6 −12 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -99,6 +102,7 @@ cc_library { }, srcs: [ "stack_manager.cc", "module.cc", ":BluetoothCommonSources", ":BluetoothHalSources", ":BluetoothPacketSources", Loading @@ -115,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: [ Loading Loading @@ -145,11 +148,6 @@ cc_binary { ], }, }, cflags: [ "-Wno-unused-parameter", "-Wno-implicit-fallthrough", "-Wno-unused-result", ], sanitize: { address: true, }, Loading Loading @@ -181,11 +179,6 @@ cc_test { sanitize: { address: true, }, cflags: [ "-Wno-unused-parameter", "-Wno-implicit-fallthrough", "-Wno-unused-result", ], } cc_test { Loading Loading @@ -221,6 +214,7 @@ cc_test { }, }, srcs: [ "module_unittest.cc", ":BluetoothCommonTestSources", ":BluetoothHciTestSources", ":BluetoothL2capTestSources", Loading system/gd/facade/stack_with_grpc_main.cc +27 −11 Original line number Diff line number Diff line Loading @@ -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="; Loading @@ -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()); Loading @@ -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; } system/gd/facade/facade_manager.cc→system/gd/grpc/grpc_module.cc +122 −0 Original line number Diff line number Diff line Loading @@ -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 system/gd/facade/facade_manager.h→system/gd/grpc/grpc_module.h +76 −0 Original line number Diff line number Diff line Loading @@ -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 system/gd/hal/cert/simple_hal_test.cc +1 −2 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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 Loading
system/gd/Android.bp +6 −12 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -99,6 +102,7 @@ cc_library { }, srcs: [ "stack_manager.cc", "module.cc", ":BluetoothCommonSources", ":BluetoothHalSources", ":BluetoothPacketSources", Loading @@ -115,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: [ Loading Loading @@ -145,11 +148,6 @@ cc_binary { ], }, }, cflags: [ "-Wno-unused-parameter", "-Wno-implicit-fallthrough", "-Wno-unused-result", ], sanitize: { address: true, }, Loading Loading @@ -181,11 +179,6 @@ cc_test { sanitize: { address: true, }, cflags: [ "-Wno-unused-parameter", "-Wno-implicit-fallthrough", "-Wno-unused-result", ], } cc_test { Loading Loading @@ -221,6 +214,7 @@ cc_test { }, }, srcs: [ "module_unittest.cc", ":BluetoothCommonTestSources", ":BluetoothHciTestSources", ":BluetoothL2capTestSources", Loading
system/gd/facade/stack_with_grpc_main.cc +27 −11 Original line number Diff line number Diff line Loading @@ -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="; Loading @@ -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()); Loading @@ -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; }
system/gd/facade/facade_manager.cc→system/gd/grpc/grpc_module.cc +122 −0 Original line number Diff line number Diff line Loading @@ -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
system/gd/facade/facade_manager.h→system/gd/grpc/grpc_module.h +76 −0 Original line number Diff line number Diff line Loading @@ -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
system/gd/hal/cert/simple_hal_test.cc +1 −2 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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