• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "facade/grpc_root_server.h"
18 
19 #include <string>
20 
21 #include "blueberry/facade/rootservice.grpc.pb.h"
22 #include "facade/read_only_property_server.h"
23 #include "grpc/grpc_module.h"
24 #include "hal/facade.h"
25 #include "hci/facade/acl_manager_facade.h"
26 #include "hci/facade/controller_facade.h"
27 #include "hci/facade/facade.h"
28 #include "hci/facade/le_acl_manager_facade.h"
29 #include "hci/facade/le_advertising_manager_facade.h"
30 #include "hci/facade/le_initiator_address_facade.h"
31 #include "hci/facade/le_scanning_manager_facade.h"
32 #include "iso/facade.h"
33 #include "l2cap/classic/facade.h"
34 #include "l2cap/le/facade.h"
35 #include "neighbor/facade/facade.h"
36 #include "os/log.h"
37 #include "os/thread.h"
38 #include "security/facade.h"
39 #include "shim/facade/facade.h"
40 #include "stack_manager.h"
41 
42 namespace bluetooth {
43 namespace facade {
44 
45 using ::blueberry::facade::BluetoothModule;
46 using ::bluetooth::grpc::GrpcModule;
47 using ::bluetooth::os::Thread;
48 
49 class RootFacadeService : public ::blueberry::facade::RootFacade::Service {
50  public:
RootFacadeService(int grpc_port)51   explicit RootFacadeService(int grpc_port) : grpc_port_(grpc_port) {}
52 
StartStack(::grpc::ServerContext * context,const::blueberry::facade::StartStackRequest * request,::blueberry::facade::StartStackResponse * response)53   ::grpc::Status StartStack(
54       ::grpc::ServerContext* context,
55       const ::blueberry::facade::StartStackRequest* request,
56       ::blueberry::facade::StartStackResponse* response) override {
57     if (is_running_) {
58       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "stack is running");
59     }
60 
61     ModuleList modules;
62     modules.add<::bluetooth::grpc::GrpcModule>();
63 
64     BluetoothModule module_under_test = request->module_under_test();
65     switch (module_under_test) {
66       case BluetoothModule::HAL:
67         modules.add<::bluetooth::hal::HciHalFacadeModule>();
68         break;
69       case BluetoothModule::HCI:
70         modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
71         modules.add<::bluetooth::hci::facade::HciFacadeModule>();
72         break;
73       case BluetoothModule::HCI_INTERFACES:
74         modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
75         modules.add<::bluetooth::hci::facade::HciFacadeModule>();
76         modules.add<::bluetooth::hci::facade::AclManagerFacadeModule>();
77         modules.add<::bluetooth::hci::facade::ControllerFacadeModule>();
78         modules.add<::bluetooth::hci::facade::LeAclManagerFacadeModule>();
79         modules.add<::bluetooth::hci::facade::LeAdvertisingManagerFacadeModule>();
80         modules.add<::bluetooth::hci::facade::LeInitiatorAddressFacadeModule>();
81         modules.add<::bluetooth::hci::facade::LeScanningManagerFacadeModule>();
82         modules.add<::bluetooth::neighbor::facade::NeighborFacadeModule>();
83         modules.add<::bluetooth::iso::IsoModuleFacadeModule>();
84         break;
85       case BluetoothModule::L2CAP:
86         modules.add<::bluetooth::hci::facade::ControllerFacadeModule>();
87         modules.add<::bluetooth::hci::facade::LeAdvertisingManagerFacadeModule>();
88         modules.add<::bluetooth::hci::facade::LeInitiatorAddressFacadeModule>();
89         modules.add<::bluetooth::neighbor::facade::NeighborFacadeModule>();
90         modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
91         modules.add<::bluetooth::l2cap::classic::L2capClassicModuleFacadeModule>();
92         modules.add<::bluetooth::l2cap::le::L2capLeModuleFacadeModule>();
93         modules.add<::bluetooth::hci::facade::HciFacadeModule>();
94         modules.add<::bluetooth::iso::IsoModuleFacadeModule>();
95         break;
96       case BluetoothModule::SECURITY:
97         modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
98         modules.add<::bluetooth::hci::facade::ControllerFacadeModule>();
99         modules.add<::bluetooth::security::SecurityModuleFacadeModule>();
100         modules.add<::bluetooth::neighbor::facade::NeighborFacadeModule>();
101         modules.add<::bluetooth::l2cap::classic::L2capClassicModuleFacadeModule>();
102         modules.add<::bluetooth::hci::facade::HciFacadeModule>();
103         modules.add<::bluetooth::hci::facade::ControllerFacadeModule>();
104         modules.add<::bluetooth::hci::facade::LeAdvertisingManagerFacadeModule>();
105         modules.add<::bluetooth::hci::facade::LeScanningManagerFacadeModule>();
106         break;
107       case BluetoothModule::SHIM:
108         modules.add<::bluetooth::shim::facade::ShimFacadeModule>();
109         break;
110       default:
111         return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "invalid module under test");
112     }
113 
114     stack_thread_ = std::make_unique<Thread>("stack_thread", Thread::Priority::NORMAL);
115     stack_manager_.StartUp(&modules, stack_thread_.get());
116 
117     GrpcModule* grpc_module = stack_manager_.GetInstance<GrpcModule>();
118     grpc_module->StartServer("0.0.0.0", grpc_port_);
119 
120     grpc_loop_thread_ = std::make_unique<std::thread>([grpc_module] { grpc_module->RunGrpcLoop(); });
121     is_running_ = true;
122 
123     return ::grpc::Status::OK;
124   }
125 
StopStack(::grpc::ServerContext * context,const::blueberry::facade::StopStackRequest * request,::blueberry::facade::StopStackResponse * response)126   ::grpc::Status StopStack(
127       ::grpc::ServerContext* context,
128       const ::blueberry::facade::StopStackRequest* request,
129       ::blueberry::facade::StopStackResponse* response) override {
130     if (!is_running_) {
131       return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "stack is not running");
132     }
133 
134     stack_manager_.GetInstance<GrpcModule>()->StopServer();
135     grpc_loop_thread_->join();
136     grpc_loop_thread_.reset();
137 
138     stack_manager_.ShutDown();
139     stack_thread_.reset();
140     is_running_ = false;
141     return ::grpc::Status::OK;
142   }
143 
144  private:
145   std::unique_ptr<Thread> stack_thread_ = nullptr;
146   bool is_running_ = false;
147   std::unique_ptr<std::thread> grpc_loop_thread_ = nullptr;
148   StackManager stack_manager_;
149   int grpc_port_ = 8898;
150 };
151 
152 struct GrpcRootServer::impl {
153   bool started_ = false;
154   std::unique_ptr<RootFacadeService> root_facade_service_ = nullptr;
155   std::unique_ptr<::grpc::Server> server_ = nullptr;
156 };
157 
GrpcRootServer()158 GrpcRootServer::GrpcRootServer() : pimpl_(new impl()) {}
159 
160 GrpcRootServer::~GrpcRootServer() = default;
161 
StartServer(const std::string & address,int grpc_root_server_port,int grpc_port)162 void GrpcRootServer::StartServer(const std::string& address, int grpc_root_server_port, int grpc_port) {
163   ASSERT(!pimpl_->started_);
164   pimpl_->started_ = true;
165 
166   std::string listening_port = address + ":" + std::to_string(grpc_root_server_port);
167   ::grpc::ServerBuilder builder;
168 
169   pimpl_->root_facade_service_ = std::make_unique<RootFacadeService>(grpc_port);
170   builder.RegisterService(pimpl_->root_facade_service_.get());
171   builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
172   pimpl_->server_ = builder.BuildAndStart();
173 
174   ASSERT(pimpl_->server_ != nullptr);
175 }
176 
StopServer()177 void GrpcRootServer::StopServer() {
178   ASSERT(pimpl_->started_);
179   pimpl_->server_->Shutdown();
180   pimpl_->started_ = false;
181 }
182 
RunGrpcLoop()183 void GrpcRootServer::RunGrpcLoop() {
184   ASSERT(pimpl_->started_);
185   pimpl_->server_->Wait();
186 }
187 
188 }  // namespace facade
189 }  // namespace bluetooth
190