• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <memory>
17 #include <unordered_map>
18 
19 #include "hci/acl_manager/classic_acl_connection.h"
20 #include "hci/address.h"
21 #include "hci/class_of_device.h"
22 #include "l2cap/classic/internal/link.h"
23 #include "l2cap/internal/scheduler_fifo.h"
24 #include "os/log.h"
25 
26 #include "l2cap/classic/internal/link_manager.h"
27 
28 namespace bluetooth {
29 namespace l2cap {
30 namespace classic {
31 namespace internal {
32 
ConnectFixedChannelServices(hci::Address device,PendingFixedChannelConnection pending_fixed_channel_connection)33 void LinkManager::ConnectFixedChannelServices(hci::Address device,
34                                               PendingFixedChannelConnection pending_fixed_channel_connection) {
35   // Check if there is any service registered
36   auto fixed_channel_services = fixed_channel_service_manager_->GetRegisteredServices();
37   if (fixed_channel_services.empty()) {
38     // If so, return error
39     pending_fixed_channel_connection.handler_->Post(common::BindOnce(
40         std::move(pending_fixed_channel_connection.on_fail_callback_),
41         FixedChannelManager::ConnectionResult{
42             .connection_result_code = FixedChannelManager::ConnectionResultCode::FAIL_NO_SERVICE_REGISTERED}));
43     return;
44   }
45   // Otherwise, check if device has an ACL connection
46   auto* link = GetLink(device);
47   if (link != nullptr) {
48     // If device already have an ACL connection
49     // Check if all registered services have an allocated channel and allocate one if not already allocated
50     int num_new_channels = 0;
51     for (auto& fixed_channel_service : fixed_channel_services) {
52       if (link->IsFixedChannelAllocated(fixed_channel_service.first)) {
53         // This channel is already allocated for this link, do not allocated twice
54         continue;
55       }
56       // Allocate channel for newly registered fixed channels
57       auto fixed_channel_impl = link->AllocateFixedChannel(fixed_channel_service.first);
58       fixed_channel_service.second->NotifyChannelCreation(
59           std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
60       num_new_channels++;
61     }
62     // Declare connection failure if no new channels are created
63     if (num_new_channels == 0) {
64       pending_fixed_channel_connection.handler_->Post(common::BindOnce(
65           std::move(pending_fixed_channel_connection.on_fail_callback_),
66           FixedChannelManager::ConnectionResult{
67               .connection_result_code = FixedChannelManager::ConnectionResultCode::FAIL_ALL_SERVICES_HAVE_CHANNEL}));
68     }
69     // No need to create ACL connection, return without saving any pending connections
70     return;
71   }
72   // If not, create new ACL connection
73   // Add request to pending link list first
74   auto pending_link = pending_links_.find(device);
75   if (pending_link == pending_links_.end()) {
76     // Create pending link if not exist
77     pending_links_.try_emplace(device);
78     pending_link = pending_links_.find(device);
79   }
80   pending_link->second.pending_fixed_channel_connections_.push_back(std::move(pending_fixed_channel_connection));
81   // Then create new ACL connection
82   acl_manager_->CreateConnection(device);
83 }
84 
ConnectDynamicChannelServices(hci::Address device,Link::PendingDynamicChannelConnection pending_dynamic_channel_connection,Psm psm)85 void LinkManager::ConnectDynamicChannelServices(
86     hci::Address device, Link::PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) {
87   if (!IsPsmValid(psm)) {
88     return;
89   }
90   auto* link = GetLink(device);
91   if (link == nullptr) {
92     acl_manager_->CreateConnection(device);
93     if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) {
94       pending_dynamic_channels_[device].push_back(psm);
95       pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection));
96     } else {
97       pending_dynamic_channels_[device] = {psm};
98       pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection));
99     }
100     return;
101   }
102   link->SendConnectionRequest(psm, link->ReserveDynamicChannel(), std::move(pending_dynamic_channel_connection));
103 }
104 
InitiateConnectionForSecurity(hci::Address remote)105 void LinkManager::InitiateConnectionForSecurity(hci::Address remote) {
106   auto* link = GetLink(remote);
107   if (link != nullptr) {
108     LOG_ERROR("Link already exists for %s", ADDRESS_TO_LOGGABLE_CSTR(remote));
109   }
110   acl_manager_->CreateConnection(remote);
111 }
112 
RegisterLinkSecurityInterfaceListener(os::Handler * handler,LinkSecurityInterfaceListener * listener)113 void LinkManager::RegisterLinkSecurityInterfaceListener(os::Handler* handler, LinkSecurityInterfaceListener* listener) {
114   link_security_interface_listener_handler_ = handler;
115   link_security_interface_listener_ = listener;
116 }
117 
GetLinkSecurityInterfaceListener()118 LinkSecurityInterfaceListener* LinkManager::GetLinkSecurityInterfaceListener() {
119   return link_security_interface_listener_;
120 }
121 
RegisterLinkPropertyListener(os::Handler * handler,LinkPropertyListener * listener)122 void LinkManager::RegisterLinkPropertyListener(os::Handler* handler, LinkPropertyListener* listener) {
123   link_property_callback_handler_ = handler;
124   link_property_listener_ = listener;
125 }
126 
OnPendingPacketChange(hci::Address remote,int num_packets)127 void LinkManager::OnPendingPacketChange(hci::Address remote, int num_packets) {
128   if (disconnected_links_.count(remote) != 0 && num_packets == 0) {
129     links_.erase(remote);
130     links_with_pending_packets_.erase(remote);
131   } else if (num_packets != 0) {
132     links_with_pending_packets_.emplace(remote);
133   } else {
134     links_with_pending_packets_.erase(remote);
135   }
136 }
137 
GetLink(const hci::Address device)138 Link* LinkManager::GetLink(const hci::Address device) {
139   if (links_.find(device) == links_.end()) {
140     return nullptr;
141   }
142   return &links_.find(device)->second;
143 }
144 
handle_link_security_hold(hci::Address remote)145 void LinkManager::handle_link_security_hold(hci::Address remote) {
146   auto link = GetLink(remote);
147   if (link == nullptr) {
148     LOG_WARN("Remote is disconnected");
149     return;
150   }
151   link->AcquireSecurityHold();
152 }
153 
handle_link_security_release(hci::Address remote)154 void LinkManager::handle_link_security_release(hci::Address remote) {
155   auto link = GetLink(remote);
156   if (link == nullptr) {
157     LOG_WARN("Remote is disconnected");
158     return;
159   }
160   link->ReleaseSecurityHold();
161 }
162 
handle_link_security_disconnect(hci::Address remote)163 void LinkManager::handle_link_security_disconnect(hci::Address remote) {
164   auto link = GetLink(remote);
165   if (link == nullptr) {
166     LOG_WARN("Remote is disconnected");
167     return;
168   }
169   link->Disconnect();
170 }
171 
handle_link_security_ensure_authenticated(hci::Address remote)172 void LinkManager::handle_link_security_ensure_authenticated(hci::Address remote) {
173   auto link = GetLink(remote);
174   if (link == nullptr) {
175     LOG_WARN("Remote is disconnected");
176     return;
177   }
178   link->Authenticate();
179 }
180 
handle_link_security_ensure_encrypted(hci::Address remote)181 void LinkManager::handle_link_security_ensure_encrypted(hci::Address remote) {
182   auto link = GetLink(remote);
183   if (link == nullptr) {
184     LOG_WARN("Remote is disconnected");
185     return;
186   }
187   link->Encrypt();
188 }
189 
190 /**
191  * The implementation for LinkSecurityInterface, which allows the SecurityModule to access some link functionalities.
192  * Note: All public methods implementing this interface are invoked from external context.
193  */
194 class LinkSecurityInterfaceImpl : public LinkSecurityInterface {
195  public:
LinkSecurityInterfaceImpl(os::Handler * handler,LinkManager * link_manager,Link * link)196   LinkSecurityInterfaceImpl(os::Handler* handler, LinkManager* link_manager, Link* link)
197       : handler_(handler),
198         link_manager_(link_manager),
199         remote_(link->GetDevice().GetAddress()),
200         acl_handle_(link->GetAclHandle()) {}
201 
GetRemoteAddress()202   hci::Address GetRemoteAddress() override {
203     return remote_;
204   }
205 
Hold()206   void Hold() override {
207     handler_->CallOn(link_manager_, &LinkManager::handle_link_security_hold, remote_);
208   }
209 
Release()210   void Release() override {
211     handler_->CallOn(link_manager_, &LinkManager::handle_link_security_release, remote_);
212   }
213 
Disconnect()214   void Disconnect() override {
215     handler_->CallOn(link_manager_, &LinkManager::handle_link_security_disconnect, remote_);
216   }
217 
EnsureAuthenticated()218   void EnsureAuthenticated() override {
219     handler_->CallOn(link_manager_, &LinkManager::handle_link_security_ensure_authenticated, remote_);
220   }
221 
EnsureEncrypted()222   void EnsureEncrypted() override {
223     handler_->CallOn(link_manager_, &LinkManager::handle_link_security_ensure_encrypted, remote_);
224   }
225 
GetAclHandle()226   uint16_t GetAclHandle() override {
227     return acl_handle_;
228   }
229 
GetRole()230   hci::Role GetRole() override {
231     return link_manager_->GetLink(remote_)->GetRole();
232   }
233 
234   os::Handler* handler_;
235   LinkManager* link_manager_;
236   hci::Address remote_;
237   uint16_t acl_handle_;
238 };
239 
OnConnectSuccess(std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection)240 void LinkManager::OnConnectSuccess(std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection) {
241   // Same link should not be connected twice
242   hci::Address device = acl_connection->GetAddress();
243   ASSERT_LOG(
244       GetLink(device) == nullptr,
245       "%s is connected twice without disconnection",
246       ADDRESS_TO_LOGGABLE_CSTR(acl_connection->GetAddress()));
247   links_.try_emplace(device, l2cap_handler_, std::move(acl_connection), parameter_provider_,
248                      dynamic_channel_service_manager_, fixed_channel_service_manager_, this);
249   auto* link = GetLink(device);
250   ASSERT(link != nullptr);
251   link->SendInformationRequest(InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED);
252   link->SendInformationRequest(InformationRequestInfoType::FIXED_CHANNELS_SUPPORTED);
253   link->ReadRemoteVersionInformation();
254   link->ReadRemoteSupportedFeatures();
255   link->ReadRemoteExtendedFeatures(1);
256 
257   // Allocate and distribute channels for all registered fixed channel services
258   auto fixed_channel_services = fixed_channel_service_manager_->GetRegisteredServices();
259   for (auto& fixed_channel_service : fixed_channel_services) {
260     auto fixed_channel_impl = link->AllocateFixedChannel(fixed_channel_service.first);
261     fixed_channel_service.second->NotifyChannelCreation(
262         std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
263   }
264   if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) {
265     auto psm_list = pending_dynamic_channels_[device];
266     auto& callback_list = pending_dynamic_channels_callbacks_[device];
267     link->SetPendingDynamicChannels(psm_list, std::move(callback_list));
268     pending_dynamic_channels_.erase(device);
269     pending_dynamic_channels_callbacks_.erase(device);
270   }
271   // Notify link property listener
272   if (link_property_callback_handler_ != nullptr) {
273     link_property_callback_handler_->CallOn(
274         link_property_listener_, &LinkPropertyListener::OnLinkConnected, device, link->GetAclHandle());
275   }
276 
277   // Notify security manager
278   if (link_security_interface_listener_handler_ != nullptr) {
279     link_security_interface_listener_handler_->CallOn(
280         link_security_interface_listener_,
281         &LinkSecurityInterfaceListener::OnLinkConnected,
282         std::make_unique<LinkSecurityInterfaceImpl>(l2cap_handler_, this, link));
283   }
284 
285   // Remove device from pending links list, if any
286   pending_links_.erase(device);
287 }
288 
OnConnectRequest(hci::Address device,hci::ClassOfDevice cod)289 void LinkManager::OnConnectRequest(hci::Address device, hci::ClassOfDevice cod) {
290   LOG_ERROR("Remote connect request unimplemented");
291 }
292 
OnConnectFail(hci::Address device,hci::ErrorCode reason,bool locally_initiated)293 void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason, bool locally_initiated) {
294   // Notify all pending links for this device
295   auto pending_link = pending_links_.find(device);
296   if (pending_link == pending_links_.end()) {
297     // There is no pending link, exit
298     LOG_INFO(
299         "Connection to %s failed without a pending link; reason: %s",
300         ADDRESS_TO_LOGGABLE_CSTR(device),
301         hci::ErrorCodeText(reason).c_str());
302     if (pending_dynamic_channels_callbacks_.find(device) != pending_dynamic_channels_callbacks_.end()) {
303       for (Link::PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) {
304         callbacks.on_fail_callback_.Invoke(DynamicChannelManager::ConnectionResult{
305             .hci_error = hci::ErrorCode::CONNECTION_TIMEOUT,
306         });
307       }
308       pending_dynamic_channels_.erase(device);
309       pending_dynamic_channels_callbacks_.erase(device);
310     }
311     return;
312   }
313   for (auto& pending_fixed_channel_connection : pending_link->second.pending_fixed_channel_connections_) {
314     pending_fixed_channel_connection.handler_->Post(common::BindOnce(
315         std::move(pending_fixed_channel_connection.on_fail_callback_),
316         FixedChannelManager::ConnectionResult{
317             .connection_result_code = FixedChannelManager::ConnectionResultCode::FAIL_HCI_ERROR, .hci_error = reason}));
318   }
319   // Remove entry in pending link list
320   pending_links_.erase(pending_link);
321 }
322 
HACK_OnEscoConnectRequest(hci::Address device,hci::ClassOfDevice cod)323 void LinkManager::HACK_OnEscoConnectRequest(hci::Address device, hci::ClassOfDevice cod) {
324   LOG_ERROR("Remote ESCO connect request unimplemented");
325 }
326 
HACK_OnScoConnectRequest(hci::Address device,hci::ClassOfDevice cod)327 void LinkManager::HACK_OnScoConnectRequest(hci::Address device, hci::ClassOfDevice cod) {
328   LOG_ERROR("Remote SCO connect request unimplemented");
329 }
330 
OnDisconnect(hci::Address device,hci::ErrorCode status)331 void LinkManager::OnDisconnect(hci::Address device, hci::ErrorCode status) {
332   auto* link = GetLink(device);
333   ASSERT_LOG(
334       link != nullptr,
335       "Device %s is disconnected with reason 0x%x, but not in local database",
336       ADDRESS_TO_LOGGABLE_CSTR(device),
337       static_cast<uint8_t>(status));
338   if (link_security_interface_listener_handler_ != nullptr) {
339     link_security_interface_listener_handler_->CallOn(
340         link_security_interface_listener_, &LinkSecurityInterfaceListener::OnLinkDisconnected, device);
341   }
342   if (link_property_callback_handler_ != nullptr) {
343     link_property_callback_handler_->CallOn(link_property_listener_, &LinkPropertyListener::OnLinkDisconnected, device);
344   }
345 
346   if (links_with_pending_packets_.count(device) != 0) {
347     disconnected_links_.emplace(device);
348   } else {
349     links_.erase(device);
350   }
351 }
352 
OnAuthenticationComplete(hci::ErrorCode hci_status,hci::Address device)353 void LinkManager::OnAuthenticationComplete(hci::ErrorCode hci_status, hci::Address device) {
354   if (link_security_interface_listener_handler_ != nullptr) {
355     link_security_interface_listener_handler_->CallOn(
356         link_security_interface_listener_,
357         &LinkSecurityInterfaceListener::OnAuthenticationComplete,
358         hci_status,
359         device);
360   }
361 }
362 
OnEncryptionChange(hci::Address device,hci::EncryptionEnabled enabled)363 void LinkManager::OnEncryptionChange(hci::Address device, hci::EncryptionEnabled enabled) {
364   if (link_security_interface_listener_handler_ != nullptr) {
365     link_security_interface_listener_handler_->CallOn(
366         link_security_interface_listener_,
367         &LinkSecurityInterfaceListener::OnEncryptionChange,
368         device,
369         enabled == hci::EncryptionEnabled::ON || enabled == hci::EncryptionEnabled::BR_EDR_AES_CCM);
370   }
371 }
372 
OnReadRemoteVersionInformation(hci::ErrorCode hci_status,hci::Address device,uint8_t lmp_version,uint16_t manufacturer_name,uint16_t sub_version)373 void LinkManager::OnReadRemoteVersionInformation(
374     hci::ErrorCode hci_status,
375     hci::Address device,
376     uint8_t lmp_version,
377     uint16_t manufacturer_name,
378     uint16_t sub_version) {
379   if (link_property_callback_handler_ != nullptr) {
380     link_property_callback_handler_->CallOn(
381         link_property_listener_,
382         &LinkPropertyListener::OnReadRemoteVersionInformation,
383         hci_status,
384         device,
385         lmp_version,
386         manufacturer_name,
387         sub_version);
388   }
389 }
390 
OnReadRemoteSupportedFeatures(hci::Address device,uint64_t features)391 void LinkManager::OnReadRemoteSupportedFeatures(hci::Address device, uint64_t features) {
392   if (link_property_callback_handler_ != nullptr) {
393     link_property_callback_handler_->CallOn(
394         link_property_listener_, &LinkPropertyListener::OnReadRemoteSupportedFeatures, device, features);
395   }
396 }
397 
OnReadRemoteExtendedFeatures(hci::Address device,uint8_t page_number,uint8_t max_page_number,uint64_t features)398 void LinkManager::OnReadRemoteExtendedFeatures(
399     hci::Address device, uint8_t page_number, uint8_t max_page_number, uint64_t features) {
400   if (link_property_callback_handler_ != nullptr) {
401     link_property_callback_handler_->CallOn(
402         link_property_listener_,
403         &LinkPropertyListener::OnReadRemoteExtendedFeatures,
404         device,
405         page_number,
406         max_page_number,
407         features);
408   }
409 }
410 
OnRoleChange(hci::ErrorCode hci_status,hci::Address remote,hci::Role role)411 void LinkManager::OnRoleChange(hci::ErrorCode hci_status, hci::Address remote, hci::Role role) {
412   if (link_property_callback_handler_ != nullptr) {
413     link_property_callback_handler_->CallOn(
414         link_property_listener_, &LinkPropertyListener::OnRoleChange, hci_status, remote, role);
415   }
416 }
417 
OnReadClockOffset(hci::Address remote,uint16_t clock_offset)418 void LinkManager::OnReadClockOffset(hci::Address remote, uint16_t clock_offset) {
419   if (link_property_callback_handler_ != nullptr) {
420     link_property_callback_handler_->CallOn(
421         link_property_listener_, &LinkPropertyListener::OnReadClockOffset, remote, clock_offset);
422   }
423 }
424 
OnModeChange(hci::ErrorCode hci_status,hci::Address remote,hci::Mode mode,uint16_t interval)425 void LinkManager::OnModeChange(hci::ErrorCode hci_status, hci::Address remote, hci::Mode mode, uint16_t interval) {
426   if (link_property_callback_handler_ != nullptr) {
427     link_property_callback_handler_->CallOn(
428         link_property_listener_, &LinkPropertyListener::OnModeChange, hci_status, remote, mode, interval);
429   }
430 }
431 
OnSniffSubrating(hci::ErrorCode hci_status,hci::Address remote,uint16_t max_tx_lat,uint16_t max_rx_lat,uint16_t min_remote_timeout,uint16_t min_local_timeout)432 void LinkManager::OnSniffSubrating(
433     hci::ErrorCode hci_status,
434     hci::Address remote,
435     uint16_t max_tx_lat,
436     uint16_t max_rx_lat,
437     uint16_t min_remote_timeout,
438     uint16_t min_local_timeout) {
439   if (link_property_callback_handler_ != nullptr) {
440     link_property_callback_handler_->CallOn(
441         link_property_listener_,
442         &LinkPropertyListener::OnSniffSubrating,
443         hci_status,
444         remote,
445         max_tx_lat,
446         max_rx_lat,
447         min_remote_timeout,
448         min_local_timeout);
449   }
450 }
451 
452 }  // namespace internal
453 }  // namespace classic
454 }  // namespace l2cap
455 }  // namespace bluetooth
456