• 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 "neighbor/facade/facade.h"
18 
19 #include <memory>
20 
21 #include "common/bind.h"
22 #include "grpc/grpc_event_queue.h"
23 #include "hci/hci_packets.h"
24 #include "neighbor/facade/facade.grpc.pb.h"
25 
26 using ::grpc::ServerAsyncResponseWriter;
27 using ::grpc::ServerAsyncWriter;
28 using ::grpc::ServerContext;
29 
30 namespace bluetooth {
31 namespace neighbor {
32 namespace facade {
33 
34 class NeighborFacadeService : public NeighborFacade::Service {
35  public:
NeighborFacadeService(ConnectabilityModule * connectability_module,DiscoverabilityModule * discoverability_module,InquiryModule * inquiry_module,NameModule * name_module,PageModule *,ScanModule * scan_module,::bluetooth::os::Handler * facade_handler)36   NeighborFacadeService(ConnectabilityModule* connectability_module, DiscoverabilityModule* discoverability_module,
37                         InquiryModule* inquiry_module, NameModule* name_module, PageModule*, ScanModule* scan_module,
38                         ::bluetooth::os::Handler* facade_handler)
39       : connectability_module_(connectability_module), discoverability_module_(discoverability_module),
40         inquiry_module_(inquiry_module), name_module_(name_module), scan_module_(scan_module),
41         facade_handler_(facade_handler) {}
42 
SetConnectability(::grpc::ServerContext * context,const::bluetooth::neighbor::EnableMsg * request,::google::protobuf::Empty * response)43   ::grpc::Status SetConnectability(::grpc::ServerContext* context, const ::bluetooth::neighbor::EnableMsg* request,
44                                    ::google::protobuf::Empty* response) override {
45     if (request->enabled()) {
46       connectability_module_->StartConnectability();
47     } else {
48       connectability_module_->StopConnectability();
49     }
50     return ::grpc::Status::OK;
51   }
52 
SetDiscoverability(::grpc::ServerContext * context,const::bluetooth::neighbor::DiscoverabilitiyMsg * request,::google::protobuf::Empty * response)53   ::grpc::Status SetDiscoverability(::grpc::ServerContext* context,
54                                     const ::bluetooth::neighbor::DiscoverabilitiyMsg* request,
55                                     ::google::protobuf::Empty* response) override {
56     switch (request->mode()) {
57       case DiscoverabilityMode::OFF:
58         discoverability_module_->StopDiscoverability();
59         break;
60       case DiscoverabilityMode::LIMITED:
61         discoverability_module_->StartLimitedDiscoverability();
62         break;
63       case DiscoverabilityMode::GENERAL:
64         discoverability_module_->StartGeneralDiscoverability();
65         break;
66       default:
67         LOG_ALWAYS_FATAL("Unknown discoverability mode %d", static_cast<int>(request->mode()));
68     }
69     return ::grpc::Status::OK;
70   }
71 
SetInquiryMode(::grpc::ServerContext * context,const::bluetooth::neighbor::InquiryMsg * request,::grpc::ServerWriter<InquiryResultMsg> * writer)72   ::grpc::Status SetInquiryMode(::grpc::ServerContext* context, const ::bluetooth::neighbor::InquiryMsg* request,
73                                 ::grpc::ServerWriter<InquiryResultMsg>* writer) override {
74     inquiry_module_->RegisterCallbacks(inquiry_callbacks_);
75     switch (request->result_mode()) {
76       case ResultMode::STANDARD:
77         inquiry_module_->SetStandardInquiryResultMode();
78         break;
79       case ResultMode::RSSI:
80         inquiry_module_->SetInquiryWithRssiResultMode();
81         break;
82       case ResultMode::EXTENDED:
83         inquiry_module_->SetExtendedInquiryResultMode();
84         break;
85       default:
86         LOG_ALWAYS_FATAL("Unknown result mode %d", static_cast<int>(request->result_mode()));
87     }
88     switch (request->inquiry_mode()) {
89       case DiscoverabilityMode::OFF:
90         inquiry_module_->StopInquiry();
91         break;
92       case DiscoverabilityMode::LIMITED:
93         inquiry_module_->StartLimitedInquiry(request->length_1_28s(), request->max_results());
94         break;
95       case DiscoverabilityMode::GENERAL:
96         inquiry_module_->StartGeneralInquiry(request->length_1_28s(), request->max_results());
97         break;
98       default:
99         LOG_ALWAYS_FATAL("Unknown discoverability mode %d", static_cast<int>(request->inquiry_mode()));
100     }
101     return pending_events_.RunLoop(context, writer);
102   }
103 
ReadRemoteName(::grpc::ServerContext * context,const::bluetooth::neighbor::RemoteNameRequestMsg * request,::google::protobuf::Empty * response)104   ::grpc::Status ReadRemoteName(::grpc::ServerContext* context,
105                                 const ::bluetooth::neighbor::RemoteNameRequestMsg* request,
106                                 ::google::protobuf::Empty* response) override {
107     hci::Address remote;
108     ASSERT(hci::Address::FromString(request->address(), remote));
109     hci::PageScanRepetitionMode mode;
110     switch (request->page_scan_repetition_mode()) {
111       case 0:
112         mode = hci::PageScanRepetitionMode::R0;
113         break;
114       case 1:
115         mode = hci::PageScanRepetitionMode::R1;
116         break;
117       case 2:
118         mode = hci::PageScanRepetitionMode::R2;
119         break;
120       default:
121         LOG_ALWAYS_FATAL("Unknown PageScanRepetition mode %d", static_cast<int>(request->page_scan_repetition_mode()));
122     }
123     name_module_->ReadRemoteNameRequest(
124         remote, mode, request->clock_offset(),
125         (request->clock_offset() != 0 ? hci::ClockOffsetValid::VALID : hci::ClockOffsetValid::INVALID),
126         common::Bind(&NeighborFacadeService::on_remote_name, common::Unretained(this)), facade_handler_);
127     return ::grpc::Status::OK;
128   }
129 
GetRemoteNameEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<RemoteNameResponseMsg> * writer)130   ::grpc::Status GetRemoteNameEvents(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
131                                      ::grpc::ServerWriter<RemoteNameResponseMsg>* writer) override {
132     return pending_remote_names_.RunLoop(context, writer);
133   }
134 
EnableInquiryScan(::grpc::ServerContext * context,const::bluetooth::neighbor::EnableMsg * request,::google::protobuf::Empty * response)135   ::grpc::Status EnableInquiryScan(::grpc::ServerContext* context, const ::bluetooth::neighbor::EnableMsg* request,
136                                    ::google::protobuf::Empty* response) override {
137     if (request->enabled()) {
138       scan_module_->SetInquiryScan();
139     } else {
140       scan_module_->ClearInquiryScan();
141     }
142     return ::grpc::Status::OK;
143   }
144 
EnablePageScan(::grpc::ServerContext * context,const::bluetooth::neighbor::EnableMsg * request,::google::protobuf::Empty * response)145   ::grpc::Status EnablePageScan(::grpc::ServerContext* context, const ::bluetooth::neighbor::EnableMsg* request,
146                                 ::google::protobuf::Empty* response) override {
147     if (request->enabled()) {
148       scan_module_->SetPageScan();
149     } else {
150       scan_module_->ClearPageScan();
151     }
152     return ::grpc::Status::OK;
153   }
154 
155  private:
on_incoming_inquiry_result(hci::EventPacketView view)156   void on_incoming_inquiry_result(hci::EventPacketView view) {
157     InquiryResultMsg inquiry_result_msg;
158     inquiry_result_msg.set_packet(std::string(view.begin(), view.end()));
159     pending_events_.OnIncomingEvent(std::move(inquiry_result_msg));
160   }
161 
on_incoming_inquiry_complete(hci::ErrorCode status)162   void on_incoming_inquiry_complete(hci::ErrorCode status) {
163     InquiryResultMsg inquiry_result_msg;
164     inquiry_result_msg.set_packet(hci::ErrorCodeText(status));
165     pending_events_.OnIncomingEvent(std::move(inquiry_result_msg));
166   }
167 
168   InquiryCallbacks inquiry_callbacks_{
__anonbeed73650102() 169       .result = [this](hci::InquiryResultView view) { on_incoming_inquiry_result(view); },
__anonbeed73650202() 170       .result_with_rssi = [this](hci::InquiryResultWithRssiView view) { on_incoming_inquiry_result(view); },
__anonbeed73650302() 171       .extended_result = [this](hci::ExtendedInquiryResultView view) { on_incoming_inquiry_result(view); },
__anonbeed73650402() 172       .complete = [this](hci::ErrorCode status) { on_incoming_inquiry_complete(status); }};
173 
on_remote_name(hci::ErrorCode status,hci::Address address,std::array<uint8_t,248> name)174   void on_remote_name(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name) {
175     RemoteNameResponseMsg response;
176     response.set_status(static_cast<int>(status));
177     response.set_address(address.ToString());
178     response.set_name(name.begin(), name.size());
179     pending_remote_names_.OnIncomingEvent(response);
180   }
181 
182   ConnectabilityModule* connectability_module_;
183   DiscoverabilityModule* discoverability_module_;
184   InquiryModule* inquiry_module_;
185   NameModule* name_module_;
186   ScanModule* scan_module_;
187   ::bluetooth::os::Handler* facade_handler_;
188   ::bluetooth::grpc::GrpcEventQueue<InquiryResultMsg> pending_events_{"InquiryResponses"};
189   ::bluetooth::grpc::GrpcEventQueue<RemoteNameResponseMsg> pending_remote_names_{"RemoteNameResponses"};
190 };
191 
ListDependencies(ModuleList * list)192 void NeighborFacadeModule::ListDependencies(ModuleList* list) {
193   ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
194   list->add<ConnectabilityModule>();
195   list->add<DiscoverabilityModule>();
196   list->add<InquiryModule>();
197   list->add<NameModule>();
198   list->add<PageModule>();
199   list->add<ScanModule>();
200 }
201 
Start()202 void NeighborFacadeModule::Start() {
203   ::bluetooth::grpc::GrpcFacadeModule::Start();
204   service_ = new NeighborFacadeService(GetDependency<ConnectabilityModule>(), GetDependency<DiscoverabilityModule>(),
205                                        GetDependency<InquiryModule>(), GetDependency<NameModule>(),
206                                        GetDependency<PageModule>(), GetDependency<ScanModule>(), GetHandler());
207 }
208 
Stop()209 void NeighborFacadeModule::Stop() {
210   delete service_;
211   ::bluetooth::grpc::GrpcFacadeModule::Stop();
212 }
213 
GetService() const214 ::grpc::Service* NeighborFacadeModule::GetService() const {
215   return service_;
216 }
217 
218 const ModuleFactory NeighborFacadeModule::Factory =
__anonbeed73650502() 219     ::bluetooth::ModuleFactory([]() { return new NeighborFacadeModule(); });
220 
221 }  // namespace facade
222 }  // namespace neighbor
223 }  // namespace bluetooth
224