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