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