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