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