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 #define LOG_TAG "bt_gd_shim"
17
18 #include "shim/l2cap.h"
19
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <queue>
24 #include <set>
25 #include <string>
26 #include <unordered_map>
27 #include <vector>
28
29 #include "common/bind.h"
30 #include "hci/address.h"
31 #include "hci/hci_packets.h"
32 #include "l2cap/classic/dynamic_channel_manager.h"
33 #include "l2cap/classic/l2cap_classic_module.h"
34 #include "l2cap/classic/security_policy.h"
35 #include "l2cap/psm.h"
36 #include "module.h"
37 #include "os/handler.h"
38 #include "os/log.h"
39 #include "packet/packet_view.h"
40 #include "packet/raw_builder.h"
41 #include "shim/dumpsys.h"
42
43 namespace bluetooth {
44 namespace shim {
45
46 namespace {
47
48 constexpr char kModuleName[] = "shim::L2cap";
49
50 constexpr bool kConnectionFailed = false;
51 constexpr bool kConnectionOpened = true;
52
53 using ConnectionInterfaceDescriptor = uint16_t;
54 constexpr ConnectionInterfaceDescriptor kInvalidConnectionInterfaceDescriptor = 0;
55 constexpr ConnectionInterfaceDescriptor kStartConnectionInterfaceDescriptor = 64;
56 constexpr ConnectionInterfaceDescriptor kMaxConnections = UINT16_MAX - kStartConnectionInterfaceDescriptor - 1;
57
58 using PendingConnectionId = int;
59
60 using ConnectionClosed = std::function<void(ConnectionInterfaceDescriptor)>;
61 using PendingConnectionOpen = std::function<void(std::unique_ptr<l2cap::classic::DynamicChannel>)>;
62 using PendingConnectionFail = std::function<void(l2cap::classic::DynamicChannelManager::ConnectionResult)>;
63 using RegisterServiceComplete = std::function<void(l2cap::Psm, bool is_registered)>;
64 using UnregisterServiceDone = std::function<void()>;
65 using ServiceConnectionOpen =
66 std::function<void(ConnectionCompleteCallback, std::unique_ptr<l2cap::classic::DynamicChannel>)>;
67
MakeUniquePacket(const uint8_t * data,size_t len)68 std::unique_ptr<packet::RawBuilder> MakeUniquePacket(const uint8_t* data, size_t len) {
69 packet::RawBuilder builder;
70 std::vector<uint8_t> bytes(data, data + len);
71 auto payload = std::make_unique<packet::RawBuilder>();
72 payload->AddOctets(bytes);
73 return payload;
74 }
75
76 } // namespace
77
78 class ConnectionInterface {
79 public:
ConnectionInterface(ConnectionInterfaceDescriptor cid,std::unique_ptr<l2cap::classic::DynamicChannel> channel,os::Handler * handler,ConnectionClosed on_closed)80 ConnectionInterface(
81 ConnectionInterfaceDescriptor cid,
82 std::unique_ptr<l2cap::classic::DynamicChannel> channel,
83 os::Handler* handler,
84 ConnectionClosed on_closed)
85 : cid_(cid),
86 channel_(std::move(channel)),
87 handler_(handler),
88 on_data_ready_callback_(nullptr),
89 on_connection_closed_callback_(nullptr),
90 address_(channel_->GetDevice().GetAddress()),
91 on_closed_(on_closed) {
92 channel_->RegisterOnCloseCallback(handler_->BindOnceOn(this, &ConnectionInterface::OnConnectionClosed));
93 channel_->GetQueueUpEnd()->RegisterDequeue(
94 handler_, common::Bind(&ConnectionInterface::OnReadReady, common::Unretained(this)));
95 dequeue_registered_ = true;
96 }
97
~ConnectionInterface()98 ~ConnectionInterface() {
99 ASSERT(!dequeue_registered_);
100 }
101
OnReadReady()102 void OnReadReady() {
103 std::unique_ptr<packet::PacketView<packet::kLittleEndian>> packet = channel_->GetQueueUpEnd()->TryDequeue();
104 if (packet == nullptr) {
105 LOG_WARN("Got read ready from gd l2cap but no packet is ready");
106 return;
107 }
108 std::vector<const uint8_t> data(packet->begin(), packet->end());
109 ASSERT(on_data_ready_callback_ != nullptr);
110 on_data_ready_callback_(cid_, data);
111 }
112
SetReadDataReadyCallback(ReadDataReadyCallback on_data_ready)113 void SetReadDataReadyCallback(ReadDataReadyCallback on_data_ready) {
114 ASSERT(on_data_ready != nullptr);
115 ASSERT(on_data_ready_callback_ == nullptr);
116 on_data_ready_callback_ = on_data_ready;
117 }
118
WriteReady()119 std::unique_ptr<packet::BasePacketBuilder> WriteReady() {
120 auto data = std::move(write_queue_.front());
121 write_queue_.pop();
122 if (write_queue_.empty()) {
123 channel_->GetQueueUpEnd()->UnregisterEnqueue();
124 enqueue_registered_ = false;
125 }
126 return data;
127 }
128
Write(std::unique_ptr<packet::RawBuilder> packet)129 void Write(std::unique_ptr<packet::RawBuilder> packet) {
130 LOG_DEBUG("Writing packet cid:%hd size:%zd", cid_, packet->size());
131 write_queue_.push(std::move(packet));
132 if (!enqueue_registered_) {
133 enqueue_registered_ = true;
134 channel_->GetQueueUpEnd()->RegisterEnqueue(
135 handler_, common::Bind(&ConnectionInterface::WriteReady, common::Unretained(this)));
136 }
137 }
138
Close()139 void Close() {
140 if (dequeue_registered_) {
141 channel_->GetQueueUpEnd()->UnregisterDequeue();
142 dequeue_registered_ = false;
143 }
144 ASSERT(write_queue_.empty());
145 channel_->Close();
146 }
147
OnConnectionClosed(hci::ErrorCode error_code)148 void OnConnectionClosed(hci::ErrorCode error_code) {
149 LOG_DEBUG(
150 "Channel interface closed reason:%s cid:%hd device:%s",
151 hci::ErrorCodeText(error_code).c_str(),
152 cid_,
153 address_.ToString().c_str());
154 if (dequeue_registered_) {
155 channel_->GetQueueUpEnd()->UnregisterDequeue();
156 dequeue_registered_ = false;
157 }
158 ASSERT(on_connection_closed_callback_ != nullptr);
159 on_connection_closed_callback_(cid_, static_cast<int>(error_code));
160 on_closed_(cid_);
161 }
162
SetConnectionClosedCallback(::bluetooth::shim::ConnectionClosedCallback on_connection_closed)163 void SetConnectionClosedCallback(::bluetooth::shim::ConnectionClosedCallback on_connection_closed) {
164 ASSERT(on_connection_closed != nullptr);
165 ASSERT(on_connection_closed_callback_ == nullptr);
166 on_connection_closed_callback_ = std::move(on_connection_closed);
167 }
168
GetRemoteAddress() const169 hci::Address GetRemoteAddress() const {
170 return address_;
171 }
172
173 private:
174 const ConnectionInterfaceDescriptor cid_;
175 const std::unique_ptr<l2cap::classic::DynamicChannel> channel_;
176 os::Handler* handler_;
177
178 ReadDataReadyCallback on_data_ready_callback_;
179 ConnectionClosedCallback on_connection_closed_callback_;
180
181 const hci::Address address_;
182
183 ConnectionClosed on_closed_{};
184
185 std::queue<std::unique_ptr<packet::PacketBuilder<hci::kLittleEndian>>> write_queue_;
186
187 bool enqueue_registered_{false};
188 bool dequeue_registered_{false};
189
190 DISALLOW_COPY_AND_ASSIGN(ConnectionInterface);
191 };
192
193 class ConnectionInterfaceManager {
194 public:
195 void AddConnection(ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel);
196 void RemoveConnection(ConnectionInterfaceDescriptor cid);
197
198 void SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready);
199 void SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid, ConnectionClosedCallback on_closed);
200
201 bool Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet);
202
NumberOfActiveConnections() const203 size_t NumberOfActiveConnections() const {
204 return cid_to_interface_map_.size();
205 }
206
ConnectionOpened(ConnectionCompleteCallback on_complete,l2cap::Psm psm,ConnectionInterfaceDescriptor cid,l2cap::Cid remote_cid)207 void ConnectionOpened(
208 ConnectionCompleteCallback on_complete,
209 l2cap::Psm psm,
210 ConnectionInterfaceDescriptor cid,
211 l2cap::Cid remote_cid) {
212 hci::Address address = cid_to_interface_map_[cid]->GetRemoteAddress();
213 LOG_DEBUG("Connection opened address:%s psm:%hd cid:%hd", address.ToString().c_str(), psm, cid);
214 on_complete(
215 address.ToString(),
216 static_cast<uint16_t>(psm),
217 static_cast<uint16_t>(cid),
218 static_cast<uint16_t>(remote_cid),
219 kConnectionOpened);
220 }
221
ConnectionFailed(ConnectionCompleteCallback on_complete,hci::Address address,l2cap::Psm psm,ConnectionInterfaceDescriptor cid)222 void ConnectionFailed(
223 ConnectionCompleteCallback on_complete, hci::Address address, l2cap::Psm psm, ConnectionInterfaceDescriptor cid) {
224 LOG_DEBUG("Connection failed address:%s psm:%hd", address.ToString().c_str(), psm);
225 on_complete(address.ToString(), static_cast<uint16_t>(psm), static_cast<uint16_t>(cid), 0, kConnectionFailed);
226 }
227
228 ConnectionInterfaceManager(os::Handler* handler);
229
230 ConnectionInterfaceDescriptor AllocateConnectionInterfaceDescriptor();
231 void FreeConnectionInterfaceDescriptor(ConnectionInterfaceDescriptor cid);
232
233 private:
234 os::Handler* handler_;
235 ConnectionInterfaceDescriptor current_connection_interface_descriptor_;
236
237 bool HasResources() const;
238 bool ConnectionExists(ConnectionInterfaceDescriptor id) const;
239 bool CidExists(ConnectionInterfaceDescriptor id) const;
240 void ConnectionClosed(ConnectionInterfaceDescriptor cid, std::unique_ptr<ConnectionInterface> connection);
241
242 std::unordered_map<ConnectionInterfaceDescriptor, std::unique_ptr<ConnectionInterface>> cid_to_interface_map_;
243 std::set<ConnectionInterfaceDescriptor> active_cid_set_;
244
245 ConnectionInterfaceManager() = delete;
246 };
247
ConnectionInterfaceManager(os::Handler * handler)248 ConnectionInterfaceManager::ConnectionInterfaceManager(os::Handler* handler)
249 : handler_(handler), current_connection_interface_descriptor_(kStartConnectionInterfaceDescriptor) {}
250
ConnectionExists(ConnectionInterfaceDescriptor cid) const251 bool ConnectionInterfaceManager::ConnectionExists(ConnectionInterfaceDescriptor cid) const {
252 return cid_to_interface_map_.find(cid) != cid_to_interface_map_.end();
253 }
254
CidExists(ConnectionInterfaceDescriptor cid) const255 bool ConnectionInterfaceManager::CidExists(ConnectionInterfaceDescriptor cid) const {
256 return active_cid_set_.find(cid) != active_cid_set_.end();
257 }
258
AllocateConnectionInterfaceDescriptor()259 ConnectionInterfaceDescriptor ConnectionInterfaceManager::AllocateConnectionInterfaceDescriptor() {
260 ASSERT(HasResources());
261 while (CidExists(current_connection_interface_descriptor_)) {
262 if (++current_connection_interface_descriptor_ == kInvalidConnectionInterfaceDescriptor) {
263 current_connection_interface_descriptor_ = kStartConnectionInterfaceDescriptor;
264 }
265 }
266 active_cid_set_.insert(current_connection_interface_descriptor_);
267 return current_connection_interface_descriptor_++;
268 }
269
FreeConnectionInterfaceDescriptor(ConnectionInterfaceDescriptor cid)270 void ConnectionInterfaceManager::FreeConnectionInterfaceDescriptor(ConnectionInterfaceDescriptor cid) {
271 ASSERT(CidExists(cid));
272 active_cid_set_.erase(cid);
273 }
274
ConnectionClosed(ConnectionInterfaceDescriptor cid,std::unique_ptr<ConnectionInterface> connection)275 void ConnectionInterfaceManager::ConnectionClosed(
276 ConnectionInterfaceDescriptor cid, std::unique_ptr<ConnectionInterface> connection) {
277 cid_to_interface_map_.erase(cid);
278 FreeConnectionInterfaceDescriptor(cid);
279 }
280
AddConnection(ConnectionInterfaceDescriptor cid,std::unique_ptr<l2cap::classic::DynamicChannel> channel)281 void ConnectionInterfaceManager::AddConnection(
282 ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
283 ASSERT(cid_to_interface_map_.count(cid) == 0);
284 cid_to_interface_map_.emplace(
285 cid,
286 std::make_unique<ConnectionInterface>(
287 cid, std::move(channel), handler_, [this](ConnectionInterfaceDescriptor cid) {
288 LOG_DEBUG("Deleting connection interface cid:%hd", cid);
289 auto connection = std::move(cid_to_interface_map_.at(cid));
290 handler_->Post(common::BindOnce(
291 &ConnectionInterfaceManager::ConnectionClosed, common::Unretained(this), cid, std::move(connection)));
292 }));
293 }
294
RemoveConnection(ConnectionInterfaceDescriptor cid)295 void ConnectionInterfaceManager::RemoveConnection(ConnectionInterfaceDescriptor cid) {
296 if (cid_to_interface_map_.count(cid) == 1) {
297 cid_to_interface_map_.find(cid)->second->Close();
298 } else {
299 LOG_WARN("Closing a pending connection cid:%hd", cid);
300 }
301 }
302
HasResources() const303 bool ConnectionInterfaceManager::HasResources() const {
304 return cid_to_interface_map_.size() < kMaxConnections;
305 }
306
SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid,ReadDataReadyCallback on_data_ready)307 void ConnectionInterfaceManager::SetReadDataReadyCallback(
308 ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready) {
309 ASSERT(ConnectionExists(cid));
310 return cid_to_interface_map_[cid]->SetReadDataReadyCallback(on_data_ready);
311 }
312
SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid,ConnectionClosedCallback on_closed)313 void ConnectionInterfaceManager::SetConnectionClosedCallback(
314 ConnectionInterfaceDescriptor cid, ConnectionClosedCallback on_closed) {
315 ASSERT(ConnectionExists(cid));
316 return cid_to_interface_map_[cid]->SetConnectionClosedCallback(on_closed);
317 }
318
Write(ConnectionInterfaceDescriptor cid,std::unique_ptr<packet::RawBuilder> packet)319 bool ConnectionInterfaceManager::Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet) {
320 if (!ConnectionExists(cid)) {
321 return false;
322 }
323 cid_to_interface_map_[cid]->Write(std::move(packet));
324 return true;
325 }
326
327 class PendingConnection {
328 public:
PendingConnection(ConnectionInterfaceDescriptor cid,l2cap::Psm psm,hci::Address address,ConnectionCompleteCallback on_complete,PendingConnectionOpen pending_open,PendingConnectionFail pending_fail)329 PendingConnection(
330 ConnectionInterfaceDescriptor cid,
331 l2cap::Psm psm,
332 hci::Address address,
333 ConnectionCompleteCallback on_complete,
334 PendingConnectionOpen pending_open,
335 PendingConnectionFail pending_fail)
336 : cid_(cid),
337 psm_(psm),
338 address_(address),
339 on_complete_(std::move(on_complete)),
340 pending_open_(pending_open),
341 pending_fail_(pending_fail) {}
342
OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel)343 void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
344 LOG_DEBUG("Local initiated connection is open to device:%s for psm:%hd", address_.ToString().c_str(), psm_);
345 ASSERT_LOG(
346 address_ == channel->GetDevice().GetAddress(), " Expected remote device does not match actual remote device");
347 pending_open_(std::move(channel));
348 }
349
OnConnectionFailure(l2cap::classic::DynamicChannelManager::ConnectionResult result)350 void OnConnectionFailure(l2cap::classic::DynamicChannelManager::ConnectionResult result) {
351 LOG_DEBUG("Connection failed to device:%s for psm:%hd", address_.ToString().c_str(), psm_);
352 switch (result.connection_result_code) {
353 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::SUCCESS:
354 LOG_WARN("Connection failed result:success hci:%s", hci::ErrorCodeText(result.hci_error).c_str());
355 break;
356 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::FAIL_NO_SERVICE_REGISTERED:
357 LOG_DEBUG(
358 "Connection failed result:no service registered hci:%s", hci::ErrorCodeText(result.hci_error).c_str());
359 break;
360 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::FAIL_HCI_ERROR:
361 LOG_DEBUG("Connection failed result:hci error hci:%s", hci::ErrorCodeText(result.hci_error).c_str());
362 break;
363 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::FAIL_L2CAP_ERROR:
364 LOG_DEBUG(
365 "Connection failed result:l2cap error hci:%s l2cap:%s",
366 hci::ErrorCodeText(result.hci_error).c_str(),
367 l2cap::ConnectionResponseResultText(result.l2cap_connection_response_result).c_str());
368 break;
369 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::FAIL_REMOTE_NOT_SUPPORT:
370 LOG_DEBUG("Connection failed result:Remote not support required retransmission and flow control mode");
371 break;
372 case l2cap::classic::DynamicChannelManager::ConnectionResultCode::FAIL_SECURITY_BLOCK:
373 LOG_DEBUG("Connection failed result:security block");
374 break;
375 }
376 pending_fail_(result);
377 }
378
ToString() const379 std::string ToString() const {
380 return address_.ToString() + "." + std::to_string(psm_);
381 }
382
383 const ConnectionInterfaceDescriptor cid_;
384 const l2cap::Psm psm_;
385 const hci::Address address_;
386 const ConnectionCompleteCallback on_complete_;
387
388 private:
389 const PendingConnectionOpen pending_open_;
390 const PendingConnectionFail pending_fail_;
391
392 DISALLOW_COPY_AND_ASSIGN(PendingConnection);
393 };
394
395 struct L2cap::impl {
396 void RegisterService(
397 l2cap::Psm psm,
398 l2cap::classic::DynamicChannelConfigurationOption option,
399 ConnectionCompleteCallback on_complete,
400 RegisterServicePromise register_promise);
401 void UnregisterService(l2cap::Psm psm, UnregisterServicePromise unregister_promise);
402
403 void CreateConnection(
404 l2cap::Psm psm,
405 hci::Address address,
406 ConnectionCompleteCallback on_complete,
407 CreateConnectionPromise create_promise);
408 void CloseConnection(ConnectionInterfaceDescriptor cid);
409
410 void SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready);
411 void SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid, ConnectionClosedCallback on_closed);
412
413 void Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet);
414
415 void SendLoopbackResponse(std::function<void()> function);
416
417 impl(L2cap& module, l2cap::classic::L2capClassicModule* l2cap_module);
418
419 private:
420 L2cap& module_;
421 l2cap::classic::L2capClassicModule* l2cap_module_;
422 os::Handler* handler_;
423 ConnectionInterfaceManager connection_interface_manager_;
424
425 std::unique_ptr<l2cap::classic::DynamicChannelManager> dynamic_channel_manager_;
426
427 std::unordered_map<l2cap::Psm, std::unique_ptr<l2cap::classic::DynamicChannelService>> psm_to_service_interface_map_;
428
429 PendingConnectionId pending_connection_id_{0};
430 std::unordered_map<PendingConnectionId, std::unique_ptr<PendingConnection>> pending_connection_map_;
431
432 void PendingConnectionOpen(
433 PendingConnectionId id,
434 std::unique_ptr<PendingConnection> connection,
435 std::unique_ptr<l2cap::classic::DynamicChannel> channel);
436 void PendingConnectionFail(
437 PendingConnectionId id,
438 std::unique_ptr<PendingConnection> connection,
439 l2cap::classic::DynamicChannelManager::ConnectionResult result);
440 l2cap::classic::SecurityPolicy GetSecurityPolicy(l2cap::Psm psm) const;
441 };
442
__anon9e0f27d80302() 443 const ModuleFactory L2cap::Factory = ModuleFactory([]() { return new L2cap(); });
444
impl(L2cap & module,l2cap::classic::L2capClassicModule * l2cap_module)445 L2cap::impl::impl(L2cap& module, l2cap::classic::L2capClassicModule* l2cap_module)
446 : module_(module),
447 l2cap_module_(l2cap_module),
448 handler_(module_.GetHandler()),
449 connection_interface_manager_(handler_) {
450 dynamic_channel_manager_ = l2cap_module_->GetDynamicChannelManager();
451 }
452
GetSecurityPolicy(l2cap::Psm psm) const453 l2cap::classic::SecurityPolicy L2cap::impl::GetSecurityPolicy(l2cap::Psm psm) const {
454 if (psm == 1) {
455 return l2cap::classic::SecurityPolicy::_SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK;
456 } else {
457 return l2cap::classic::SecurityPolicy::ENCRYPTED_TRANSPORT;
458 }
459 }
460
RegisterService(l2cap::Psm psm,l2cap::classic::DynamicChannelConfigurationOption option,ConnectionCompleteCallback on_complete,RegisterServicePromise register_promise)461 void L2cap::impl::RegisterService(
462 l2cap::Psm psm,
463 l2cap::classic::DynamicChannelConfigurationOption option,
464 ConnectionCompleteCallback on_complete,
465 RegisterServicePromise register_promise) {
466 const l2cap::classic::SecurityPolicy security_policy = GetSecurityPolicy(psm);
467
468 dynamic_channel_manager_->RegisterService(
469 psm,
470 option,
471 security_policy,
472 handler_->BindOnce(
473 [](RegisterServicePromise register_promise,
474 std::unordered_map<l2cap::Psm, std::unique_ptr<l2cap::classic::DynamicChannelService>>*
475 psm_to_service_interface_map_,
476 l2cap::classic::DynamicChannelManager::RegistrationResult result,
477 std::unique_ptr<l2cap::classic::DynamicChannelService> service) {
478 std::unique_ptr<l2cap::classic::DynamicChannelService> service_ = std::move(service);
479 switch (result) {
480 case l2cap::classic::DynamicChannelManager::RegistrationResult::SUCCESS:
481 LOG_DEBUG("Service is registered for psm:%hd", service_->GetPsm());
482 register_promise.set_value(service_->GetPsm());
483 psm_to_service_interface_map_->emplace(service_->GetPsm(), std::move(service_));
484 break;
485 case l2cap::classic::DynamicChannelManager::RegistrationResult::FAIL_DUPLICATE_SERVICE:
486 LOG_WARN("Failed to register duplicate service has psm:%hd", service_->GetPsm());
487 register_promise.set_value(l2cap::kDefaultPsm);
488 break;
489 case l2cap::classic::DynamicChannelManager::RegistrationResult::FAIL_INVALID_SERVICE:
490 LOG_WARN("Failed to register invalid service psm:%hd", service_->GetPsm());
491 register_promise.set_value(l2cap::kDefaultPsm);
492 break;
493 }
494 },
495 std::move(register_promise),
496 &psm_to_service_interface_map_),
497 handler_->Bind(
498 [](l2cap::Psm psm,
499 ConnectionCompleteCallback on_complete,
500 ConnectionInterfaceManager* connection_interface_manager_,
501 std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
502 LOG_DEBUG("Remote initiated connection is open from device:%s", channel->GetDevice().ToString().c_str());
503
504 ConnectionInterfaceDescriptor cid = connection_interface_manager_->AllocateConnectionInterfaceDescriptor();
505 uint16_t remote_cid = channel->HACK_GetRemoteCid();
506 connection_interface_manager_->AddConnection(cid, std::move(channel));
507 connection_interface_manager_->ConnectionOpened(on_complete, psm, cid, remote_cid);
508 LOG_DEBUG("connection open");
509 },
510 psm,
511 on_complete,
512 &connection_interface_manager_));
513 }
514
UnregisterService(l2cap::Psm psm,UnregisterServicePromise unregister_promise)515 void L2cap::impl::UnregisterService(l2cap::Psm psm, UnregisterServicePromise unregister_promise) {
516 ASSERT(psm_to_service_interface_map_.find(psm) != psm_to_service_interface_map_.end());
517
518 psm_to_service_interface_map_[psm]->Unregister(handler_->BindOnce(
519 [](std::unordered_map<l2cap::Psm, std::unique_ptr<l2cap::classic::DynamicChannelService>>*
520 psm_to_service_interface_map_,
521 UnregisterServicePromise unregister_promise,
522 l2cap::Psm psm) {
523 psm_to_service_interface_map_->erase(psm);
524 unregister_promise.set_value();
525 },
526 &psm_to_service_interface_map_,
527 std::move(unregister_promise),
528 psm));
529 }
530
PendingConnectionOpen(PendingConnectionId id,std::unique_ptr<PendingConnection> connection,std::unique_ptr<l2cap::classic::DynamicChannel> channel)531 void L2cap::impl::PendingConnectionOpen(
532 PendingConnectionId id,
533 std::unique_ptr<PendingConnection> connection,
534 std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
535 uint16_t remote_cid = channel->HACK_GetRemoteCid();
536 connection_interface_manager_.AddConnection(connection->cid_, std::move(channel));
537 connection_interface_manager_.ConnectionOpened(
538 std::move(connection->on_complete_), connection->psm_, connection->cid_, remote_cid);
539 pending_connection_map_.erase(id);
540 }
541
PendingConnectionFail(PendingConnectionId id,std::unique_ptr<PendingConnection> connection,l2cap::classic::DynamicChannelManager::ConnectionResult result)542 void L2cap::impl::PendingConnectionFail(
543 PendingConnectionId id,
544 std::unique_ptr<PendingConnection> connection,
545 l2cap::classic::DynamicChannelManager::ConnectionResult result) {
546 connection_interface_manager_.ConnectionFailed(
547 std::move(connection->on_complete_), connection->address_, connection->psm_, connection->cid_);
548 connection_interface_manager_.FreeConnectionInterfaceDescriptor(connection->cid_);
549 pending_connection_map_.erase(id);
550 }
551
CreateConnection(l2cap::Psm psm,hci::Address address,ConnectionCompleteCallback on_complete,CreateConnectionPromise create_promise)552 void L2cap::impl::CreateConnection(
553 l2cap::Psm psm,
554 hci::Address address,
555 ConnectionCompleteCallback on_complete,
556 CreateConnectionPromise create_promise) {
557 ConnectionInterfaceDescriptor cid = connection_interface_manager_.AllocateConnectionInterfaceDescriptor();
558 create_promise.set_value(cid);
559
560 if (cid == kInvalidConnectionInterfaceDescriptor) {
561 LOG_WARN("No resources to create a connection");
562 return;
563 }
564
565 PendingConnectionId id = ++pending_connection_id_;
566 pending_connection_map_.emplace(
567 id,
568 std::make_unique<PendingConnection>(
569 cid,
570 psm,
571 address,
572 on_complete,
573 [this, id](std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
574 auto connection = std::move(pending_connection_map_.at(id));
575 handler_->CallOn(this, &L2cap::impl::PendingConnectionOpen, id, std::move(connection), std::move(channel));
576 },
577 [this, id](l2cap::classic::DynamicChannelManager::ConnectionResult result) {
578 auto connection = std::move(pending_connection_map_.at(id));
579 handler_->CallOn(this, &L2cap::impl::PendingConnectionFail, id, std::move(connection), result);
580 }));
581
582 dynamic_channel_manager_->ConnectChannel(
583 address,
584 l2cap::classic::DynamicChannelConfigurationOption(),
585 psm,
586 handler_->BindOn(pending_connection_map_.at(id).get(), &PendingConnection::OnConnectionOpen),
587 handler_->BindOnceOn(pending_connection_map_.at(id).get(), &PendingConnection::OnConnectionFailure));
588 }
589
CloseConnection(ConnectionInterfaceDescriptor cid)590 void L2cap::impl::CloseConnection(ConnectionInterfaceDescriptor cid) {
591 connection_interface_manager_.RemoveConnection(cid);
592 }
593
SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid,ReadDataReadyCallback on_data_ready)594 void L2cap::impl::SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready) {
595 connection_interface_manager_.SetReadDataReadyCallback(cid, on_data_ready);
596 }
597
SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid,ConnectionClosedCallback on_closed)598 void L2cap::impl::SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid, ConnectionClosedCallback on_closed) {
599 connection_interface_manager_.SetConnectionClosedCallback(cid, std::move(on_closed));
600 }
601
Write(ConnectionInterfaceDescriptor cid,std::unique_ptr<packet::RawBuilder> packet)602 void L2cap::impl::Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet) {
603 connection_interface_manager_.Write(cid, std::move(packet));
604 }
605
SendLoopbackResponse(std::function<void ()> function)606 void L2cap::impl::SendLoopbackResponse(std::function<void()> function) {
607 function();
608 }
609
RegisterClassicService(uint16_t raw_psm,bool use_ertm,uint16_t mtu,ConnectionCompleteCallback on_complete,RegisterServicePromise register_promise)610 void L2cap::RegisterClassicService(
611 uint16_t raw_psm,
612 bool use_ertm,
613 uint16_t mtu,
614 ConnectionCompleteCallback on_complete,
615 RegisterServicePromise register_promise) {
616 l2cap::Psm psm{raw_psm};
617 l2cap::classic::DynamicChannelConfigurationOption option;
618 if (use_ertm) {
619 option.channel_mode =
620 l2cap::classic::DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION;
621 }
622 option.incoming_mtu = mtu;
623 GetHandler()->Post(common::BindOnce(
624 &L2cap::impl::RegisterService,
625 common::Unretained(pimpl_.get()),
626 psm,
627 option,
628 on_complete,
629 std::move(register_promise)));
630 }
631
UnregisterClassicService(uint16_t raw_psm,UnregisterServicePromise unregister_promise)632 void L2cap::UnregisterClassicService(uint16_t raw_psm, UnregisterServicePromise unregister_promise) {
633 l2cap::Psm psm{raw_psm};
634 GetHandler()->Post(common::BindOnce(
635 &L2cap::impl::UnregisterService, common::Unretained(pimpl_.get()), psm, std::move(unregister_promise)));
636 }
637
CreateClassicConnection(uint16_t raw_psm,const std::string address_string,ConnectionCompleteCallback on_complete,CreateConnectionPromise create_promise)638 void L2cap::CreateClassicConnection(
639 uint16_t raw_psm,
640 const std::string address_string,
641 ConnectionCompleteCallback on_complete,
642 CreateConnectionPromise create_promise) {
643 l2cap::Psm psm{raw_psm};
644 hci::Address address;
645 hci::Address::FromString(address_string, address);
646
647 GetHandler()->Post(common::BindOnce(
648 &L2cap::impl::CreateConnection,
649 common::Unretained(pimpl_.get()),
650 psm,
651 address,
652 on_complete,
653 std::move(create_promise)));
654 }
655
CloseClassicConnection(uint16_t raw_cid)656 void L2cap::CloseClassicConnection(uint16_t raw_cid) {
657 ConnectionInterfaceDescriptor cid(raw_cid);
658 GetHandler()->Post(common::Bind(&L2cap::impl::CloseConnection, common::Unretained(pimpl_.get()), cid));
659 }
660
SetReadDataReadyCallback(uint16_t raw_cid,ReadDataReadyCallback on_data_ready)661 void L2cap::SetReadDataReadyCallback(uint16_t raw_cid, ReadDataReadyCallback on_data_ready) {
662 ConnectionInterfaceDescriptor cid(raw_cid);
663 GetHandler()->Post(
664 common::Bind(&L2cap::impl::SetReadDataReadyCallback, common::Unretained(pimpl_.get()), cid, on_data_ready));
665 }
666
SetConnectionClosedCallback(uint16_t raw_cid,ConnectionClosedCallback on_closed)667 void L2cap::SetConnectionClosedCallback(uint16_t raw_cid, ConnectionClosedCallback on_closed) {
668 ConnectionInterfaceDescriptor cid(raw_cid);
669 GetHandler()->Post(common::Bind(
670 &L2cap::impl::SetConnectionClosedCallback, common::Unretained(pimpl_.get()), cid, std::move(on_closed)));
671 }
672
Write(uint16_t raw_cid,const uint8_t * data,size_t len)673 void L2cap::Write(uint16_t raw_cid, const uint8_t* data, size_t len) {
674 ConnectionInterfaceDescriptor cid(raw_cid);
675 auto packet = MakeUniquePacket(data, len);
676 GetHandler()->Post(common::BindOnce(&L2cap::impl::Write, common::Unretained(pimpl_.get()), cid, std::move(packet)));
677 }
678
SendLoopbackResponse(std::function<void ()> function)679 void L2cap::SendLoopbackResponse(std::function<void()> function) {
680 GetHandler()->Post(common::BindOnce(&L2cap::impl::SendLoopbackResponse, common::Unretained(pimpl_.get()), function));
681 }
682
683 /**
684 * Module methods
685 */
ListDependencies(ModuleList * list)686 void L2cap::ListDependencies(ModuleList* list) {
687 list->add<l2cap::classic::L2capClassicModule>();
688 }
689
Start()690 void L2cap::Start() {
691 pimpl_ = std::make_unique<impl>(*this, GetDependency<l2cap::classic::L2capClassicModule>());
692 }
693
Stop()694 void L2cap::Stop() {
695 pimpl_.reset();
696 }
697
ToString() const698 std::string L2cap::ToString() const {
699 return kModuleName;
700 }
701
702 } // namespace shim
703 } // namespace bluetooth
704