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 "grpc/grpc_module.h"
18 
19 #include <bluetooth/log.h>
20 
21 using ::grpc::Server;
22 using ::grpc::ServerBuilder;
23 
24 namespace bluetooth {
25 namespace grpc {
26 
ListDependencies(ModuleList *) const27 void GrpcModule::ListDependencies(ModuleList* /* list */) const {}
28 
Start()29 void GrpcModule::Start() { log::assert_that(!started_, "assert failed: !started_"); }
30 
Stop()31 void GrpcModule::Stop() { log::assert_that(!started_, "assert failed: !started_"); }
32 
StartServer(const std::string & address,int port)33 void GrpcModule::StartServer(const std::string& address, int port) {
34   log::assert_that(!started_, "assert failed: !started_");
35   started_ = true;
36 
37   std::string listening_port = address + ":" + std::to_string(port);
38   ServerBuilder builder;
39 
40   for (const auto& facade : facades_) {
41     builder.RegisterService(facade->GetService());
42   }
43 
44   builder.AddListeningPort(listening_port, ::grpc::InsecureServerCredentials());
45   completion_queue_ = builder.AddCompletionQueue();
46   server_ = builder.BuildAndStart();
47   log::assert_that(server_ != nullptr, "assert failed: server_ != nullptr");
48   log::info("gRPC server started on {}", listening_port);
49 
50   for (const auto& facade : facades_) {
51     facade->OnServerStarted();
52   }
53 }
54 
StopServer()55 void GrpcModule::StopServer() {
56   log::assert_that(started_, "assert failed: started_");
57 
58   server_->Shutdown();
59   completion_queue_->Shutdown();
60 
61   for (const auto& facade : facades_) {
62     facade->OnServerStopped();
63   }
64 
65   started_ = false;
66 }
67 
Register(GrpcFacadeModule * facade)68 void GrpcModule::Register(GrpcFacadeModule* facade) {
69   log::assert_that(!started_, "assert failed: !started_");
70 
71   facades_.push_back(facade);
72 }
73 
Unregister(GrpcFacadeModule * facade)74 void GrpcModule::Unregister(GrpcFacadeModule* facade) {
75   log::assert_that(!started_, "assert failed: !started_");
76 
77   for (auto it = facades_.begin(); it != facades_.end(); it++) {
78     if (*it == facade) {
79       facades_.erase(it);
80       return;
81     }
82   }
83 
84   log::fatal("module not found");
85 }
86 
RunGrpcLoop()87 void GrpcModule::RunGrpcLoop() {
88   void* tag;
89   bool ok;
90   while (true) {
91     if (!completion_queue_->Next(&tag, &ok)) {
92       log::info("gRPC is shutdown");
93       break;
94     }
95   }
96 }
97 
ToString() const98 std::string GrpcModule::ToString() const { return "Grpc Module"; }
99 
100 const ::bluetooth::ModuleFactory GrpcModule::Factory =
__anon7d8e599e0102() 101         ::bluetooth::ModuleFactory([]() { return new GrpcModule(); });
102 
ListDependencies(ModuleList * list) const103 void GrpcFacadeModule::ListDependencies(ModuleList* list) const { list->add<GrpcModule>(); }
104 
Start()105 void GrpcFacadeModule::Start() { GetDependency<GrpcModule>()->Register(this); }
106 
Stop()107 void GrpcFacadeModule::Stop() { GetDependency<GrpcModule>()->Unregister(this); }
108 
ToString() const109 std::string GrpcFacadeModule::ToString() const { return "Grpc Facade Module"; }
110 
111 }  // namespace grpc
112 }  // namespace bluetooth
113