blob: e802dfebfca9929b925f7e6fdf8874810216f0fe [file] [log] [blame]
Hansong Zhang30bf8692019-05-02 15:25:54 -07001/*
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
Hansong Zhange0a997f2019-08-29 14:27:11 -070021#include "facade/read_only_property_server.h"
Hansong Zhang30bf8692019-05-02 15:25:54 -070022#include "facade/rootservice.grpc.pb.h"
23#include "grpc/grpc_module.h"
24#include "hal/facade.h"
Hansong Zhangc5ec8f92019-06-19 17:22:21 -070025#include "hci/facade.h"
Jack Heff38d892019-10-03 17:11:07 -070026#include "l2cap/classic/facade.h"
Hansong Zhang30bf8692019-05-02 15:25:54 -070027#include "os/log.h"
28#include "os/thread.h"
29#include "stack_manager.h"
30
31namespace bluetooth {
32namespace facade {
33
34using ::bluetooth::grpc::GrpcModule;
35using ::bluetooth::os::Thread;
36
37namespace {
38class RootFacadeService : public ::bluetooth::facade::RootFacade::Service {
39 public:
40 RootFacadeService(int grpc_port) : grpc_port_(grpc_port) {}
41
42 ::grpc::Status StartStack(::grpc::ServerContext* context, const ::bluetooth::facade::StartStackRequest* request,
43 ::bluetooth::facade::StartStackResponse* response) override {
44 if (is_running_) {
45 return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "stack is running");
46 }
47
48 ModuleList modules;
49 modules.add<::bluetooth::grpc::GrpcModule>();
50
51 BluetoothModule module_under_test = request->module_under_test();
52 switch (module_under_test) {
53 case BluetoothModule::HAL:
54 modules.add<::bluetooth::hal::HciHalFacadeModule>();
55 break;
Hansong Zhangc5ec8f92019-06-19 17:22:21 -070056 case BluetoothModule::HCI:
Hansong Zhange0a997f2019-08-29 14:27:11 -070057 modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
Hansong Zhangc5ec8f92019-06-19 17:22:21 -070058 modules.add<::bluetooth::hci::AclManagerFacadeModule>();
Chienyuan4d7cc812019-07-12 18:00:12 +080059 modules.add<::bluetooth::hci::ClassicSecurityManagerFacadeModule>();
Hansong Zhangc5ec8f92019-06-19 17:22:21 -070060 break;
Jack Hefcb2bbf2019-07-31 15:44:05 -070061 case BluetoothModule::L2CAP:
Hansong Zhange0a997f2019-08-29 14:27:11 -070062 modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
Jack He0aca2b22019-11-21 15:27:19 -080063 modules.add<::bluetooth::l2cap::classic::L2capClassicModuleFacadeModule>();
Jack Hefcb2bbf2019-07-31 15:44:05 -070064 break;
Hansong Zhang30bf8692019-05-02 15:25:54 -070065 default:
66 return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "invalid module under test");
67 }
68
69 stack_thread_ = new Thread("stack_thread", Thread::Priority::NORMAL);
70 stack_manager_.StartUp(&modules, stack_thread_);
71
72 GrpcModule* grpc_module = stack_manager_.GetInstance<GrpcModule>();
73 grpc_module->StartServer("0.0.0.0", grpc_port_);
74
75 grpc_loop_thread_ = new std::thread([grpc_module] { grpc_module->RunGrpcLoop(); });
76 is_running_ = true;
77
78 return ::grpc::Status::OK;
79 }
80
81 ::grpc::Status StopStack(::grpc::ServerContext* context, const ::bluetooth::facade::StopStackRequest* request,
82 ::bluetooth::facade::StopStackResponse* response) override {
83 if (!is_running_) {
84 return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "stack is not running");
85 }
86
87 stack_manager_.GetInstance<GrpcModule>()->StopServer();
88 grpc_loop_thread_->join();
Hansong Zhang2f1bf0b2019-10-31 09:50:08 -070089 delete grpc_loop_thread_;
Hansong Zhang30bf8692019-05-02 15:25:54 -070090
91 stack_manager_.ShutDown();
92 delete stack_thread_;
93 is_running_ = false;
94 return ::grpc::Status::OK;
95 }
96
97 private:
98 Thread* stack_thread_ = nullptr;
99 bool is_running_ = false;
100 std::thread* grpc_loop_thread_ = nullptr;
101 StackManager stack_manager_;
102 int grpc_port_ = 8898;
103};
104
105RootFacadeService* root_facade_service;
106} // namespace
107
108void GrpcRootServer::StartServer(const std::string& address, int grpc_root_server_port, int grpc_port) {
109 ASSERT(!started_);
110 started_ = true;
111
112 std::string listening_port = address + ":" + std::to_string(grpc_root_server_port);
113 ::grpc::ServerBuilder builder;
114 root_facade_service = new RootFacadeService(grpc_port);
115 builder.RegisterService(root_facade_service);
116 builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
117 server_ = builder.BuildAndStart();
118
119 ASSERT(server_ != nullptr);
120}
121
122void GrpcRootServer::StopServer() {
123 ASSERT(started_);
124 server_->Shutdown();
125 started_ = false;
126 server_.reset();
127 delete root_facade_service;
128}
129
130void GrpcRootServer::RunGrpcLoop() {
131 ASSERT(started_);
132 server_->Wait();
133}
134
135} // namespace facade
136} // namespace bluetooth