1 /*
2 * Copyright 2020 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 "l2cap/le/facade.h"
18
19 #include "grpc/grpc_event_queue.h"
20 #include "l2cap/le/dynamic_channel.h"
21 #include "l2cap/le/dynamic_channel_manager.h"
22 #include "l2cap/le/dynamic_channel_service.h"
23 #include "l2cap/le/facade.grpc.pb.h"
24 #include "l2cap/le/l2cap_le_module.h"
25 #include "l2cap/le/security_policy.h"
26 #include "l2cap/psm.h"
27 #include "packet/raw_builder.h"
28
29 namespace bluetooth {
30 namespace l2cap {
31 namespace le {
32
SecurityLevelToPolicy(SecurityLevel level)33 SecurityPolicy SecurityLevelToPolicy(SecurityLevel level) {
34 switch (level) {
35 case SecurityLevel::NO_SECURITY:
36 return SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK;
37 case SecurityLevel::UNAUTHENTICATED_PAIRING_WITH_ENCRYPTION:
38 return SecurityPolicy::ENCRYPTED_TRANSPORT;
39 case SecurityLevel::AUTHENTICATED_PAIRING_WITH_ENCRYPTION:
40 return SecurityPolicy::AUTHENTICATED_ENCRYPTED_TRANSPORT;
41 case SecurityLevel::AUTHENTICATED_PAIRING_WITH_128_BIT_KEY:
42 return SecurityPolicy::_NOT_FOR_YOU__AUTHENTICATED_PAIRING_WITH_128_BIT_KEY;
43 case SecurityLevel::AUTHORIZATION:
44 return SecurityPolicy::_NOT_FOR_YOU__AUTHORIZATION;
45 default:
46 return SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK;
47 }
48 }
49
50 static constexpr auto kChannelOpenTimeout = std::chrono::seconds(4);
51
52 class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
53 public:
L2capLeModuleFacadeService(L2capLeModule * l2cap_layer,os::Handler * facade_handler)54 L2capLeModuleFacadeService(L2capLeModule* l2cap_layer, os::Handler* facade_handler)
55 : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) {
56 ASSERT(l2cap_layer_ != nullptr);
57 ASSERT(facade_handler_ != nullptr);
58 }
59
FetchL2capData(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::l2cap::le::L2capPacket> * writer)60 ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
61 ::grpc::ServerWriter<::bluetooth::l2cap::le::L2capPacket>* writer) override {
62 return pending_l2cap_data_.RunLoop(context, writer);
63 }
64
OpenDynamicChannel(::grpc::ServerContext * context,const OpenDynamicChannelRequest * request,OpenDynamicChannelResponse * response)65 ::grpc::Status OpenDynamicChannel(::grpc::ServerContext* context, const OpenDynamicChannelRequest* request,
66 OpenDynamicChannelResponse* response) override {
67 auto service_helper = dynamic_channel_helper_map_.find(request->psm());
68 if (service_helper == dynamic_channel_helper_map_.end()) {
69 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
70 }
71 hci::Address peer_address;
72 ASSERT(hci::Address::FromString(request->remote().address().address(), peer_address));
73 // TODO: Support different address type
74 hci::AddressWithType peer(peer_address, hci::AddressType::RANDOM_DEVICE_ADDRESS);
75 service_helper->second->Connect(peer);
76 response->set_status(
77 static_cast<int>(service_helper->second->channel_open_fail_reason_.l2cap_connection_response_result));
78 return ::grpc::Status::OK;
79 }
80
CloseDynamicChannel(::grpc::ServerContext * context,const CloseDynamicChannelRequest * request,::google::protobuf::Empty * response)81 ::grpc::Status CloseDynamicChannel(::grpc::ServerContext* context, const CloseDynamicChannelRequest* request,
82 ::google::protobuf::Empty* response) override {
83 auto service_helper = dynamic_channel_helper_map_.find(request->psm());
84 if (service_helper == dynamic_channel_helper_map_.end()) {
85 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
86 }
87 if (service_helper->second->channel_ == nullptr) {
88 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Channel not open");
89 }
90 auto address = service_helper->second->channel_->GetDevice().GetAddress();
91 hci::Address peer_address;
92 ASSERT(hci::Address::FromString(request->remote().address().address(), peer_address));
93 if (address != peer_address) {
94 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Remote address doesn't match");
95 }
96 service_helper->second->channel_->Close();
97 return ::grpc::Status::OK;
98 }
99
SetDynamicChannel(::grpc::ServerContext * context,const::bluetooth::l2cap::le::SetEnableDynamicChannelRequest * request,::google::protobuf::Empty * response)100 ::grpc::Status SetDynamicChannel(::grpc::ServerContext* context,
101 const ::bluetooth::l2cap::le::SetEnableDynamicChannelRequest* request,
102 ::google::protobuf::Empty* response) override {
103 if (request->enable()) {
104 dynamic_channel_helper_map_.emplace(request->psm(), std::make_unique<L2capDynamicChannelHelper>(
105 this, l2cap_layer_, facade_handler_, request->psm(),
106 SecurityLevelToPolicy(request->security_level())));
107 return ::grpc::Status::OK;
108 } else {
109 auto service_helper = dynamic_channel_helper_map_.find(request->psm());
110 if (service_helper == dynamic_channel_helper_map_.end()) {
111 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
112 }
113 service_helper->second->service_->Unregister(common::BindOnce([] {}), facade_handler_);
114 return ::grpc::Status::OK;
115 }
116 }
117
SendDynamicChannelPacket(::grpc::ServerContext * context,const::bluetooth::l2cap::le::DynamicChannelPacket * request,::google::protobuf::Empty * response)118 ::grpc::Status SendDynamicChannelPacket(::grpc::ServerContext* context,
119 const ::bluetooth::l2cap::le::DynamicChannelPacket* request,
120 ::google::protobuf::Empty* response) override {
121 std::unique_lock<std::mutex> lock(channel_map_mutex_);
122 if (dynamic_channel_helper_map_.find(request->psm()) == dynamic_channel_helper_map_.end()) {
123 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
124 }
125 std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
126 if (!dynamic_channel_helper_map_[request->psm()]->SendPacket(packet)) {
127 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Channel not open");
128 }
129 return ::grpc::Status::OK;
130 }
131
132 class L2capDynamicChannelHelper {
133 public:
L2capDynamicChannelHelper(L2capLeModuleFacadeService * service,L2capLeModule * l2cap_layer,os::Handler * handler,Psm psm,SecurityPolicy security_policy)134 L2capDynamicChannelHelper(L2capLeModuleFacadeService* service, L2capLeModule* l2cap_layer, os::Handler* handler,
135 Psm psm, SecurityPolicy security_policy)
136 : facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), psm_(psm) {
137 dynamic_channel_manager_ = l2cap_layer_->GetDynamicChannelManager();
138 dynamic_channel_manager_->RegisterService(
139 psm, {}, security_policy,
140 common::BindOnce(&L2capDynamicChannelHelper::on_l2cap_service_registration_complete,
141 common::Unretained(this)),
142 common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)), handler_);
143 }
144
~L2capDynamicChannelHelper()145 ~L2capDynamicChannelHelper() {
146 if (channel_ != nullptr) {
147 channel_->GetQueueUpEnd()->UnregisterDequeue();
148 channel_ = nullptr;
149 }
150 }
151
Connect(hci::AddressWithType address)152 void Connect(hci::AddressWithType address) {
153 dynamic_channel_manager_->ConnectChannel(
154 address, {}, psm_, common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)),
155 common::Bind(&L2capDynamicChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
156 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
157 if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
158 LOG_WARN("Channel is not open for psm %d", psm_);
159 }
160 }
161
on_l2cap_service_registration_complete(DynamicChannelManager::RegistrationResult registration_result,std::unique_ptr<DynamicChannelService> service)162 void on_l2cap_service_registration_complete(DynamicChannelManager::RegistrationResult registration_result,
163 std::unique_ptr<DynamicChannelService> service) {
164 if (registration_result != DynamicChannelManager::RegistrationResult::SUCCESS) {
165 LOG_ERROR("Service registration failed");
166 } else {
167 service_ = std::move(service);
168 }
169 }
170
171 // invoked from Facade Handler
on_connection_open(std::unique_ptr<DynamicChannel> channel)172 void on_connection_open(std::unique_ptr<DynamicChannel> channel) {
173 {
174 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
175 channel_ = std::move(channel);
176 }
177 channel_open_cv_.notify_all();
178 channel_->RegisterOnCloseCallback(
179 facade_service_->facade_handler_->BindOnceOn(this, &L2capDynamicChannelHelper::on_close_callback));
180 channel_->GetQueueUpEnd()->RegisterDequeue(
181 facade_service_->facade_handler_,
182 common::Bind(&L2capDynamicChannelHelper::on_incoming_packet, common::Unretained(this)));
183 }
184
on_close_callback(hci::ErrorCode error_code)185 void on_close_callback(hci::ErrorCode error_code) {
186 {
187 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
188 channel_->GetQueueUpEnd()->UnregisterDequeue();
189 }
190 channel_ = nullptr;
191 }
192
on_connect_fail(DynamicChannelManager::ConnectionResult result)193 void on_connect_fail(DynamicChannelManager::ConnectionResult result) {
194 {
195 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
196 channel_ = nullptr;
197 channel_open_fail_reason_ = result;
198 }
199 channel_open_cv_.notify_all();
200 }
201
on_incoming_packet()202 void on_incoming_packet() {
203 auto packet = channel_->GetQueueUpEnd()->TryDequeue();
204 std::string data = std::string(packet->begin(), packet->end());
205 L2capPacket l2cap_data;
206 l2cap_data.set_psm(psm_);
207 l2cap_data.set_payload(data);
208 facade_service_->pending_l2cap_data_.OnIncomingEvent(l2cap_data);
209 }
210
SendPacket(std::vector<uint8_t> packet)211 bool SendPacket(std::vector<uint8_t> packet) {
212 if (channel_ == nullptr) {
213 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
214 if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
215 LOG_WARN("Channel is not open for psm %d", psm_);
216 return false;
217 }
218 }
219 std::promise<void> promise;
220 auto future = promise.get_future();
221 channel_->GetQueueUpEnd()->RegisterEnqueue(
222 handler_, common::Bind(&L2capDynamicChannelHelper::enqueue_callback, common::Unretained(this), packet,
223 common::Passed(std::move(promise))));
224 auto status = future.wait_for(std::chrono::milliseconds(500));
225 if (status != std::future_status::ready) {
226 LOG_ERROR("Can't send packet because the previous packet wasn't sent yet");
227 return false;
228 }
229 return true;
230 }
231
enqueue_callback(std::vector<uint8_t> packet,std::promise<void> promise)232 std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(std::vector<uint8_t> packet,
233 std::promise<void> promise) {
234 auto packet_one = std::make_unique<packet::RawBuilder>(2000);
235 packet_one->AddOctets(packet);
236 channel_->GetQueueUpEnd()->UnregisterEnqueue();
237 promise.set_value();
238 return packet_one;
239 }
240
241 L2capLeModuleFacadeService* facade_service_;
242 L2capLeModule* l2cap_layer_;
243 os::Handler* handler_;
244 std::unique_ptr<DynamicChannelManager> dynamic_channel_manager_;
245 std::unique_ptr<DynamicChannelService> service_;
246 std::unique_ptr<DynamicChannel> channel_ = nullptr;
247 Psm psm_;
248 DynamicChannelManager::ConnectionResult channel_open_fail_reason_;
249 std::condition_variable channel_open_cv_;
250 std::mutex channel_open_cv_mutex_;
251 };
252
SetFixedChannel(::grpc::ServerContext * context,const SetEnableFixedChannelRequest * request,::google::protobuf::Empty * response)253 ::grpc::Status SetFixedChannel(::grpc::ServerContext* context, const SetEnableFixedChannelRequest* request,
254 ::google::protobuf::Empty* response) override {
255 if (request->enable()) {
256 fixed_channel_helper_map_.emplace(request->cid(), std::make_unique<L2capFixedChannelHelper>(
257 this, l2cap_layer_, facade_handler_, request->cid()));
258 return ::grpc::Status::OK;
259 } else {
260 auto service_helper = fixed_channel_helper_map_.find(request->cid());
261 if (service_helper == fixed_channel_helper_map_.end()) {
262 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Cid not registered");
263 }
264 service_helper->second->channel_->Release();
265 service_helper->second->service_->Unregister(common::BindOnce([] {}), facade_handler_);
266 return ::grpc::Status::OK;
267 }
268 }
269
SendFixedChannelPacket(::grpc::ServerContext * context,const FixedChannelPacket * request,::google::protobuf::Empty * response)270 ::grpc::Status SendFixedChannelPacket(::grpc::ServerContext* context, const FixedChannelPacket* request,
271 ::google::protobuf::Empty* response) override {
272 std::unique_lock<std::mutex> lock(channel_map_mutex_);
273 if (fixed_channel_helper_map_.find(request->cid()) == fixed_channel_helper_map_.end()) {
274 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Cid not registered");
275 }
276 std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
277 if (!fixed_channel_helper_map_[request->cid()]->SendPacket(packet)) {
278 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Channel not open");
279 }
280 return ::grpc::Status::OK;
281 }
282
283 class L2capFixedChannelHelper {
284 public:
L2capFixedChannelHelper(L2capLeModuleFacadeService * service,L2capLeModule * l2cap_layer,os::Handler * handler,Cid cid)285 L2capFixedChannelHelper(L2capLeModuleFacadeService* service, L2capLeModule* l2cap_layer, os::Handler* handler,
286 Cid cid)
287 : facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), cid_(cid) {
288 fixed_channel_manager_ = l2cap_layer_->GetFixedChannelManager();
289 fixed_channel_manager_->RegisterService(
290 cid_,
291 common::BindOnce(&L2capFixedChannelHelper::on_l2cap_service_registration_complete, common::Unretained(this)),
292 common::Bind(&L2capFixedChannelHelper::on_connection_open, common::Unretained(this)), handler_);
293 }
294
~L2capFixedChannelHelper()295 ~L2capFixedChannelHelper() {
296 if (channel_ != nullptr) {
297 channel_->GetQueueUpEnd()->UnregisterDequeue();
298 channel_->Release();
299 channel_ = nullptr;
300 }
301 }
302
Connect(hci::AddressWithType address)303 void Connect(hci::AddressWithType address) {
304 fixed_channel_manager_->ConnectServices(
305 address, common::BindOnce(&L2capFixedChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
306 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
307 if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
308 LOG_WARN("Channel is not open for cid %d", cid_);
309 }
310 }
311
on_l2cap_service_registration_complete(FixedChannelManager::RegistrationResult registration_result,std::unique_ptr<FixedChannelService> service)312 void on_l2cap_service_registration_complete(FixedChannelManager::RegistrationResult registration_result,
313 std::unique_ptr<FixedChannelService> service) {
314 if (registration_result != FixedChannelManager::RegistrationResult::SUCCESS) {
315 LOG_ERROR("Service registration failed");
316 } else {
317 service_ = std::move(service);
318 }
319 }
320
321 // invoked from Facade Handler
on_connection_open(std::unique_ptr<FixedChannel> channel)322 void on_connection_open(std::unique_ptr<FixedChannel> channel) {
323 {
324 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
325 channel_ = std::move(channel);
326 channel_->RegisterOnCloseCallback(
327 handler_, common::BindOnce(&L2capFixedChannelHelper::on_close_callback, common::Unretained(this)));
328 channel_->Acquire();
329 }
330 channel_open_cv_.notify_all();
331 channel_->GetQueueUpEnd()->RegisterDequeue(
332 facade_service_->facade_handler_,
333 common::Bind(&L2capFixedChannelHelper::on_incoming_packet, common::Unretained(this)));
334 }
335
on_close_callback(hci::ErrorCode error_code)336 void on_close_callback(hci::ErrorCode error_code) {
337 {
338 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
339 channel_->GetQueueUpEnd()->UnregisterDequeue();
340 }
341 channel_ = nullptr;
342 }
343
on_connect_fail(FixedChannelManager::ConnectionResult result)344 void on_connect_fail(FixedChannelManager::ConnectionResult result) {
345 {
346 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
347 channel_ = nullptr;
348 }
349 channel_open_cv_.notify_all();
350 }
351
on_incoming_packet()352 void on_incoming_packet() {
353 auto packet = channel_->GetQueueUpEnd()->TryDequeue();
354 std::string data = std::string(packet->begin(), packet->end());
355 L2capPacket l2cap_data;
356 l2cap_data.set_fixed_cid(cid_);
357 l2cap_data.set_payload(data);
358 facade_service_->pending_l2cap_data_.OnIncomingEvent(l2cap_data);
359 }
360
SendPacket(std::vector<uint8_t> packet)361 bool SendPacket(std::vector<uint8_t> packet) {
362 if (channel_ == nullptr) {
363 std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
364 if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
365 LOG_WARN("Channel is not open for cid %d", cid_);
366 return false;
367 }
368 }
369 std::promise<void> promise;
370 auto future = promise.get_future();
371 channel_->GetQueueUpEnd()->RegisterEnqueue(
372 handler_, common::Bind(&L2capFixedChannelHelper::enqueue_callback, common::Unretained(this), packet,
373 common::Passed(std::move(promise))));
374 auto status = future.wait_for(std::chrono::milliseconds(500));
375 if (status != std::future_status::ready) {
376 LOG_ERROR("Can't send packet because the previous packet wasn't sent yet");
377 return false;
378 }
379 return true;
380 }
381
enqueue_callback(std::vector<uint8_t> packet,std::promise<void> promise)382 std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(std::vector<uint8_t> packet,
383 std::promise<void> promise) {
384 auto packet_one = std::make_unique<packet::RawBuilder>(2000);
385 packet_one->AddOctets(packet);
386 channel_->GetQueueUpEnd()->UnregisterEnqueue();
387 promise.set_value();
388 return packet_one;
389 }
390
391 L2capLeModuleFacadeService* facade_service_;
392 L2capLeModule* l2cap_layer_;
393 os::Handler* handler_;
394 std::unique_ptr<FixedChannelManager> fixed_channel_manager_;
395 std::unique_ptr<FixedChannelService> service_;
396 std::unique_ptr<FixedChannel> channel_ = nullptr;
397 Cid cid_;
398 std::condition_variable channel_open_cv_;
399 std::mutex channel_open_cv_mutex_;
400 };
401
SendConnectionParameterUpdate(::grpc::ServerContext * context,const ConnectionParameter * request,::google::protobuf::Empty * response)402 ::grpc::Status SendConnectionParameterUpdate(::grpc::ServerContext* context, const ConnectionParameter* request,
403 ::google::protobuf::Empty* response) override {
404 if (dynamic_channel_helper_map_.empty()) {
405 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Need to open at least one dynamic channel first");
406 }
407 auto& dynamic_channel_helper = dynamic_channel_helper_map_.begin()->second;
408 dynamic_channel_helper->channel_->GetLinkOptions()->UpdateConnectionParameter(
409 request->conn_interval_min(), request->conn_interval_max(), request->conn_latency(),
410 request->supervision_timeout(), request->min_ce_length(), request->max_ce_length());
411
412 return ::grpc::Status::OK;
413 }
414
415 L2capLeModule* l2cap_layer_;
416 os::Handler* facade_handler_;
417 std::mutex channel_map_mutex_;
418 std::map<Psm, std::unique_ptr<L2capDynamicChannelHelper>> dynamic_channel_helper_map_;
419 std::map<Cid, std::unique_ptr<L2capFixedChannelHelper>> fixed_channel_helper_map_;
420 ::bluetooth::grpc::GrpcEventQueue<L2capPacket> pending_l2cap_data_{"FetchL2capData"};
421 };
422
ListDependencies(ModuleList * list)423 void L2capLeModuleFacadeModule::ListDependencies(ModuleList* list) {
424 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
425 list->add<l2cap::le::L2capLeModule>();
426 }
427
Start()428 void L2capLeModuleFacadeModule::Start() {
429 ::bluetooth::grpc::GrpcFacadeModule::Start();
430 service_ = new L2capLeModuleFacadeService(GetDependency<l2cap::le::L2capLeModule>(), GetHandler());
431 }
432
Stop()433 void L2capLeModuleFacadeModule::Stop() {
434 delete service_;
435 ::bluetooth::grpc::GrpcFacadeModule::Stop();
436 }
437
GetService() const438 ::grpc::Service* L2capLeModuleFacadeModule::GetService() const {
439 return service_;
440 }
441
442 const ModuleFactory L2capLeModuleFacadeModule::Factory =
__anonc78efb070702() 443 ::bluetooth::ModuleFactory([]() { return new L2capLeModuleFacadeModule(); });
444
445 } // namespace le
446 } // namespace l2cap
447 } // namespace bluetooth
448