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 <condition_variable>
18 #include <cstdint>
19 #include <unordered_map>
20
21 #include "common/bidi_queue.h"
22 #include "common/bind.h"
23 #include "common/callback.h"
24 #include "grpc/grpc_event_queue.h"
25 #include "hci/address.h"
26 #include "l2cap/classic/facade.grpc.pb.h"
27 #include "l2cap/classic/facade.h"
28 #include "l2cap/classic/l2cap_classic_module.h"
29 #include "os/log.h"
30 #include "packet/raw_builder.h"
31
32 using ::grpc::ServerAsyncResponseWriter;
33 using ::grpc::ServerAsyncWriter;
34 using ::grpc::ServerContext;
35
36 using ::bluetooth::packet::RawBuilder;
37
38 namespace bluetooth {
39 namespace l2cap {
40 namespace classic {
41
42 class L2capClassicModuleFacadeService : public L2capClassicModuleFacade::Service, public LinkSecurityInterfaceListener {
43 public:
L2capClassicModuleFacadeService(L2capClassicModule * l2cap_layer,os::Handler * facade_handler)44 L2capClassicModuleFacadeService(L2capClassicModule* l2cap_layer, os::Handler* facade_handler)
45 : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler), security_interface_(nullptr) {
46 ASSERT(l2cap_layer_ != nullptr);
47 ASSERT(facade_handler_ != nullptr);
48 }
49
FetchConnectionComplete(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<classic::ConnectionCompleteEvent> * writer)50 ::grpc::Status FetchConnectionComplete(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
51 ::grpc::ServerWriter<classic::ConnectionCompleteEvent>* writer) override {
52 return pending_connection_complete_.RunLoop(context, writer);
53 }
54
FetchConnectionClose(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<classic::ConnectionCloseEvent> * writer)55 ::grpc::Status FetchConnectionClose(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
56 ::grpc::ServerWriter<classic::ConnectionCloseEvent>* writer) override {
57 return pending_connection_close_.RunLoop(context, writer);
58 }
59
SendDynamicChannelPacket(::grpc::ServerContext * context,const DynamicChannelPacket * request,::google::protobuf::Empty * response)60 ::grpc::Status SendDynamicChannelPacket(::grpc::ServerContext* context, const DynamicChannelPacket* request,
61 ::google::protobuf::Empty* response) override {
62 std::unique_lock<std::mutex> lock(channel_map_mutex_);
63 if (dynamic_channel_helper_map_.find(request->psm()) == dynamic_channel_helper_map_.end()) {
64 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
65 }
66 std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
67 if (!dynamic_channel_helper_map_[request->psm()]->SendPacket(packet)) {
68 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Channel not open");
69 }
70 return ::grpc::Status::OK;
71 }
72
OpenChannel(::grpc::ServerContext * context,const::bluetooth::l2cap::classic::OpenChannelRequest * request,::google::protobuf::Empty * response)73 ::grpc::Status OpenChannel(::grpc::ServerContext* context,
74 const ::bluetooth::l2cap::classic::OpenChannelRequest* request,
75 ::google::protobuf::Empty* response) override {
76 auto service_helper = dynamic_channel_helper_map_.find(request->psm());
77 if (service_helper == dynamic_channel_helper_map_.end()) {
78 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
79 }
80 hci::Address peer;
81 ASSERT(hci::Address::FromString(request->remote().address(), peer));
82 dynamic_channel_helper_map_[request->psm()]->Connect(peer);
83 return ::grpc::Status::OK;
84 }
85
CloseChannel(::grpc::ServerContext * context,const::bluetooth::l2cap::classic::CloseChannelRequest * request,::google::protobuf::Empty * response)86 ::grpc::Status CloseChannel(::grpc::ServerContext* context,
87 const ::bluetooth::l2cap::classic::CloseChannelRequest* request,
88 ::google::protobuf::Empty* response) override {
89 auto psm = request->psm();
90 if (dynamic_channel_helper_map_.find(request->psm()) == dynamic_channel_helper_map_.end()) {
91 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
92 }
93 dynamic_channel_helper_map_[psm]->Disconnect();
94 return ::grpc::Status::OK;
95 }
96
FetchL2capData(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<classic::L2capPacket> * writer)97 ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
98 ::grpc::ServerWriter<classic::L2capPacket>* writer) override {
99 auto status = pending_l2cap_data_.RunLoop(context, writer);
100
101 return status;
102 }
103
SetDynamicChannel(::grpc::ServerContext * context,const SetEnableDynamicChannelRequest * request,google::protobuf::Empty * response)104 ::grpc::Status SetDynamicChannel(::grpc::ServerContext* context, const SetEnableDynamicChannelRequest* request,
105 google::protobuf::Empty* response) override {
106 dynamic_channel_helper_map_.emplace(
107 request->psm(), std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, request->psm(),
108 request->retransmission_mode()));
109 return ::grpc::Status::OK;
110 }
111
SetTrafficPaused(::grpc::ServerContext * context,const SetTrafficPausedRequest * request,::google::protobuf::Empty * response)112 ::grpc::Status SetTrafficPaused(::grpc::ServerContext* context, const SetTrafficPausedRequest* request,
113 ::google::protobuf::Empty* response) override {
114 auto psm = request->psm();
115 if (dynamic_channel_helper_map_.find(request->psm()) == dynamic_channel_helper_map_.end()) {
116 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
117 }
118 if (request->paused()) {
119 dynamic_channel_helper_map_[psm]->SuspendDequeue();
120 } else {
121 dynamic_channel_helper_map_[psm]->ResumeDequeue();
122 }
123 return ::grpc::Status::OK;
124 }
125
GetChannelQueueDepth(::grpc::ServerContext * context,const::google::protobuf::Empty * request,GetChannelQueueDepthResponse * response)126 ::grpc::Status GetChannelQueueDepth(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
127 GetChannelQueueDepthResponse* response) override {
128 // Use the value kChannelQueueSize (5) in internal/dynamic_channel_impl.h
129 response->set_size(5);
130 return ::grpc::Status::OK;
131 }
132
InitiateConnectionForSecurity(::grpc::ServerContext * context,const facade::BluetoothAddress * request,::google::protobuf::Empty * response)133 ::grpc::Status InitiateConnectionForSecurity(
134 ::grpc::ServerContext* context,
135 const facade::BluetoothAddress* request,
136 ::google::protobuf::Empty* response) override {
137 hci::Address peer;
138 ASSERT(hci::Address::FromString(request->address(), peer));
139 outgoing_pairing_remote_devices_.insert(peer);
140 security_interface_->InitiateConnectionForSecurity(peer);
141 return ::grpc::Status::OK;
142 }
143
SecurityConnectionEventOccurred(hci::ErrorCode hci_status,hci::Address remote,LinkSecurityInterfaceCallbackEventType event_type)144 void SecurityConnectionEventOccurred(
145 hci::ErrorCode hci_status, hci::Address remote, LinkSecurityInterfaceCallbackEventType event_type) {
146 LinkSecurityInterfaceCallbackEvent msg;
147 msg.mutable_address()->set_address(remote.ToString());
148 msg.set_event_type(event_type);
149 security_connection_events_.OnIncomingEvent(msg);
150 }
151
FetchSecurityConnectionEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<LinkSecurityInterfaceCallbackEvent> * writer)152 ::grpc::Status FetchSecurityConnectionEvents(
153 ::grpc::ServerContext* context,
154 const ::google::protobuf::Empty* request,
155 ::grpc::ServerWriter<LinkSecurityInterfaceCallbackEvent>* writer) override {
156 security_interface_ = l2cap_layer_->GetSecurityInterface(facade_handler_, this);
157 return security_connection_events_.RunLoop(context, writer);
158 }
159
SecurityLinkHold(::grpc::ServerContext * context,const facade::BluetoothAddress * request,::google::protobuf::Empty * response)160 ::grpc::Status SecurityLinkHold(
161 ::grpc::ServerContext* context,
162 const facade::BluetoothAddress* request,
163 ::google::protobuf::Empty* response) override {
164 hci::Address peer;
165 ASSERT(hci::Address::FromString(request->address(), peer));
166 auto entry = security_link_map_.find(peer);
167 if (entry == security_link_map_.end()) {
168 LOG_WARN("Unknown address '%s'", peer.ToString().c_str());
169 } else {
170 entry->second->Hold();
171 }
172 return ::grpc::Status::OK;
173 }
174
SecurityLinkEnsureAuthenticated(::grpc::ServerContext * context,const facade::BluetoothAddress * request,::google::protobuf::Empty * response)175 ::grpc::Status SecurityLinkEnsureAuthenticated(
176 ::grpc::ServerContext* context,
177 const facade::BluetoothAddress* request,
178 ::google::protobuf::Empty* response) override {
179 hci::Address peer;
180 ASSERT(hci::Address::FromString(request->address(), peer));
181 auto entry = security_link_map_.find(peer);
182 if (entry == security_link_map_.end()) {
183 LOG_WARN("Unknown address '%s'", peer.ToString().c_str());
184 } else {
185 entry->second->EnsureAuthenticated();
186 }
187 return ::grpc::Status::OK;
188 }
189
SecurityLinkRelease(::grpc::ServerContext * context,const facade::BluetoothAddress * request,::google::protobuf::Empty * response)190 ::grpc::Status SecurityLinkRelease(
191 ::grpc::ServerContext* context,
192 const facade::BluetoothAddress* request,
193 ::google::protobuf::Empty* response) override {
194 hci::Address peer;
195 ASSERT(hci::Address::FromString(request->address(), peer));
196 outgoing_pairing_remote_devices_.erase(peer);
197 auto entry = security_link_map_.find(peer);
198 if (entry == security_link_map_.end()) {
199 LOG_WARN("Unknown address '%s'", peer.ToString().c_str());
200 } else {
201 entry->second->Release();
202 }
203 return ::grpc::Status::OK;
204 }
205
SecurityLinkDisconnect(::grpc::ServerContext * context,const facade::BluetoothAddress * request,::google::protobuf::Empty * response)206 ::grpc::Status SecurityLinkDisconnect(
207 ::grpc::ServerContext* context,
208 const facade::BluetoothAddress* request,
209 ::google::protobuf::Empty* response) override {
210 hci::Address peer;
211 ASSERT(hci::Address::FromString(request->address(), peer));
212 outgoing_pairing_remote_devices_.erase(peer);
213 auto entry = security_link_map_.find(peer);
214 if (entry == security_link_map_.end()) {
215 LOG_WARN("Unknown address '%s'", peer.ToString().c_str());
216 } else {
217 entry->second->Disconnect();
218 }
219 return ::grpc::Status::OK;
220 }
221
OnLinkConnected(std::unique_ptr<LinkSecurityInterface> link)222 void OnLinkConnected(std::unique_ptr<LinkSecurityInterface> link) override {
223 auto remote = link->GetRemoteAddress();
224 if (outgoing_pairing_remote_devices_.count(remote) == 1) {
225 link->Hold();
226 link->EnsureAuthenticated();
227 outgoing_pairing_remote_devices_.erase(remote);
228 }
229 security_link_map_.emplace(remote, std::move(link));
230 SecurityConnectionEventOccurred(
231 hci::ErrorCode::SUCCESS, remote, LinkSecurityInterfaceCallbackEventType::ON_CONNECTED);
232 }
233
OnLinkDisconnected(hci::Address remote)234 void OnLinkDisconnected(hci::Address remote) override {
235 auto entry = security_link_map_.find(remote);
236 if (entry == security_link_map_.end()) {
237 LOG_WARN("Unknown address '%s'", remote.ToString().c_str());
238 return;
239 }
240 entry->second.reset();
241 security_link_map_.erase(entry);
242 SecurityConnectionEventOccurred(
243 hci::ErrorCode::SUCCESS, remote, LinkSecurityInterfaceCallbackEventType::ON_DISCONNECTED);
244 }
245
OnAuthenticationComplete(hci::ErrorCode hci_status,hci::Address remote)246 void OnAuthenticationComplete(hci::ErrorCode hci_status, hci::Address remote) override {
247 auto entry = security_link_map_.find(remote);
248 if (entry != security_link_map_.end()) {
249 entry->second->EnsureEncrypted();
250 return;
251 }
252 SecurityConnectionEventOccurred(
253 hci_status, remote, LinkSecurityInterfaceCallbackEventType::ON_AUTHENTICATION_COMPLETE);
254 }
255
OnEncryptionChange(hci::Address remote,bool encrypted)256 void OnEncryptionChange(hci::Address remote, bool encrypted) override {
257 SecurityConnectionEventOccurred(
258 hci::ErrorCode::SUCCESS, remote, LinkSecurityInterfaceCallbackEventType::ON_ENCRYPTION_CHANGE);
259 }
260
261 class L2capDynamicChannelHelper {
262 public:
L2capDynamicChannelHelper(L2capClassicModuleFacadeService * service,L2capClassicModule * l2cap_layer,os::Handler * handler,Psm psm,RetransmissionFlowControlMode mode)263 L2capDynamicChannelHelper(L2capClassicModuleFacadeService* service, L2capClassicModule* l2cap_layer,
264 os::Handler* handler, Psm psm, RetransmissionFlowControlMode mode)
265 : facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), psm_(psm), mode_(mode) {
266 dynamic_channel_manager_ = l2cap_layer_->GetDynamicChannelManager();
267 DynamicChannelConfigurationOption configuration_option = {};
268 configuration_option.channel_mode = (DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode)mode;
269 dynamic_channel_manager_->RegisterService(
270 psm,
271 configuration_option,
272 SecurityPolicy::_SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK,
273 handler_->BindOnceOn(this, &L2capDynamicChannelHelper::on_l2cap_service_registration_complete),
274 handler_->BindOn(this, &L2capDynamicChannelHelper::on_connection_open));
275 }
276
~L2capDynamicChannelHelper()277 ~L2capDynamicChannelHelper() {
278 if (dequeue_registered_) {
279 channel_->GetQueueUpEnd()->UnregisterDequeue();
280 channel_ = nullptr;
281 }
282 enqueue_buffer_.reset();
283 }
284
Connect(hci::Address address)285 void Connect(hci::Address address) {
286 DynamicChannelConfigurationOption configuration_option = l2cap::classic::DynamicChannelConfigurationOption();
287 configuration_option.channel_mode = (DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode)mode_;
288
289 dynamic_channel_manager_->ConnectChannel(
290 address,
291 configuration_option,
292 psm_,
293 handler_->BindOn(this, &L2capDynamicChannelHelper::on_connection_open),
294 handler_->BindOnceOn(this, &L2capDynamicChannelHelper::on_connect_fail));
295 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
296 if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
297 LOG_WARN("Channel is not open for psm %d", psm_);
298 }
299 }
300
Disconnect()301 void Disconnect() {
302 if (channel_ == nullptr) {
303 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
304 if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
305 LOG_WARN("Channel is not open for psm %d", psm_);
306 return;
307 }
308 }
309 channel_->Close();
310 }
311
on_l2cap_service_registration_complete(DynamicChannelManager::RegistrationResult registration_result,std::unique_ptr<DynamicChannelService> service)312 void on_l2cap_service_registration_complete(DynamicChannelManager::RegistrationResult registration_result,
313 std::unique_ptr<DynamicChannelService> service) {}
314
315 // invoked from Facade Handler
on_connection_open(std::unique_ptr<DynamicChannel> channel)316 void on_connection_open(std::unique_ptr<DynamicChannel> channel) {
317 ConnectionCompleteEvent event;
318 event.mutable_remote()->set_address(channel->GetDevice().GetAddress().ToString());
319 facade_service_->pending_connection_complete_.OnIncomingEvent(event);
320 {
321 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
322 channel_ = std::move(channel);
323 enqueue_buffer_ = std::make_unique<os::EnqueueBuffer<BasePacketBuilder>>(channel_->GetQueueUpEnd());
324 }
325 channel_open_cv_.notify_all();
326 channel_->RegisterOnCloseCallback(
327 facade_service_->facade_handler_->BindOnceOn(this, &L2capDynamicChannelHelper::on_close_callback));
328 dequeue_registered_ = true;
329 channel_->GetQueueUpEnd()->RegisterDequeue(
330 facade_service_->facade_handler_,
331 common::Bind(&L2capDynamicChannelHelper::on_incoming_packet, common::Unretained(this)));
332 }
333
on_close_callback(hci::ErrorCode error_code)334 void on_close_callback(hci::ErrorCode error_code) {
335 {
336 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
337 if (dequeue_registered_.exchange(false)) {
338 channel_->GetQueueUpEnd()->UnregisterDequeue();
339 }
340 }
341 classic::ConnectionCloseEvent event;
342 event.mutable_remote()->set_address(channel_->GetDevice().GetAddress().ToString());
343 event.set_reason(static_cast<uint32_t>(error_code));
344 facade_service_->pending_connection_close_.OnIncomingEvent(event);
345 channel_ = nullptr;
346 enqueue_buffer_.reset();
347 }
348
SuspendDequeue()349 void SuspendDequeue() {
350 if (dequeue_registered_.exchange(false)) {
351 channel_->GetQueueUpEnd()->UnregisterDequeue();
352 }
353 }
354
ResumeDequeue()355 void ResumeDequeue() {
356 if (!dequeue_registered_.exchange(true)) {
357 channel_->GetQueueUpEnd()->RegisterDequeue(
358 facade_service_->facade_handler_,
359 common::Bind(&L2capDynamicChannelHelper::on_incoming_packet, common::Unretained(this)));
360 }
361 }
362
on_connect_fail(DynamicChannelManager::ConnectionResult result)363 void on_connect_fail(DynamicChannelManager::ConnectionResult result) {}
364
on_incoming_packet()365 void on_incoming_packet() {
366 auto packet = channel_->GetQueueUpEnd()->TryDequeue();
367 std::string data = std::string(packet->begin(), packet->end());
368 L2capPacket l2cap_data;
369 l2cap_data.set_psm(psm_);
370 l2cap_data.set_payload(data);
371 facade_service_->pending_l2cap_data_.OnIncomingEvent(l2cap_data);
372 }
373
SendPacket(std::vector<uint8_t> packet)374 bool SendPacket(std::vector<uint8_t> packet) {
375 if (channel_ == nullptr) {
376 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
377 if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
378 LOG_WARN("Channel is not open");
379 return false;
380 }
381 }
382 auto packet_one = std::make_unique<packet::RawBuilder>(2000);
383 packet_one->AddOctets(packet);
384 enqueue_buffer_->Enqueue(std::move(packet_one), handler_);
385 return true;
386 }
387 L2capClassicModuleFacadeService* facade_service_;
388 L2capClassicModule* l2cap_layer_;
389 os::Handler* handler_;
390 std::unique_ptr<DynamicChannelManager> dynamic_channel_manager_;
391 std::unique_ptr<DynamicChannelService> service_;
392 std::unique_ptr<DynamicChannel> channel_ = nullptr;
393 std::unique_ptr<os::EnqueueBuffer<BasePacketBuilder>> enqueue_buffer_ = nullptr;
394 Psm psm_;
395 RetransmissionFlowControlMode mode_ = RetransmissionFlowControlMode::BASIC;
396 std::atomic_bool dequeue_registered_ = false;
397 std::condition_variable channel_open_cv_;
398 std::mutex channel_open_cv_mutex_;
399 };
400
401 L2capClassicModule* l2cap_layer_;
402 ::bluetooth::os::Handler* facade_handler_;
403 std::mutex channel_map_mutex_;
404 std::map<Psm, std::unique_ptr<L2capDynamicChannelHelper>> dynamic_channel_helper_map_;
405 ::bluetooth::grpc::GrpcEventQueue<classic::ConnectionCompleteEvent> pending_connection_complete_{
406 "FetchConnectionComplete"};
407 ::bluetooth::grpc::GrpcEventQueue<classic::ConnectionCloseEvent> pending_connection_close_{"FetchConnectionClose"};
408 ::bluetooth::grpc::GrpcEventQueue<L2capPacket> pending_l2cap_data_{"FetchL2capData"};
409 ::bluetooth::grpc::GrpcEventQueue<LinkSecurityInterfaceCallbackEvent> security_connection_events_{
410 "Security Connection Events"};
411 SecurityInterface* security_interface_;
412 std::unordered_map<hci::Address, std::unique_ptr<l2cap::classic::LinkSecurityInterface>> security_link_map_;
413 std::set<hci::Address> outgoing_pairing_remote_devices_;
414 };
415
ListDependencies(ModuleList * list)416 void L2capClassicModuleFacadeModule::ListDependencies(ModuleList* list) {
417 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
418 list->add<l2cap::classic::L2capClassicModule>();
419 }
420
Start()421 void L2capClassicModuleFacadeModule::Start() {
422 ::bluetooth::grpc::GrpcFacadeModule::Start();
423 service_ = new L2capClassicModuleFacadeService(GetDependency<l2cap::classic::L2capClassicModule>(), GetHandler());
424 }
425
Stop()426 void L2capClassicModuleFacadeModule::Stop() {
427 delete service_;
428 ::bluetooth::grpc::GrpcFacadeModule::Stop();
429 }
430
GetService() const431 ::grpc::Service* L2capClassicModuleFacadeModule::GetService() const {
432 return service_;
433 }
434
435 const ModuleFactory L2capClassicModuleFacadeModule::Factory =
__anonc89ef3780402() 436 ::bluetooth::ModuleFactory([]() { return new L2capClassicModuleFacadeModule(); });
437
438 } // namespace classic
439 } // namespace l2cap
440 } // namespace bluetooth
441