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/le_acl_connection.h"
20 #include "hci/address.h"
21 #include "l2cap/internal/scheduler_fifo.h"
22 #include "l2cap/le/internal/link.h"
23 #include "os/handler.h"
24 #include "os/log.h"
25 
26 #include "l2cap/le/internal/link_manager.h"
27 
28 namespace bluetooth {
29 namespace l2cap {
30 namespace le {
31 namespace internal {
32 
ConnectFixedChannelServices(hci::AddressWithType address_with_type,PendingFixedChannelConnection pending_fixed_channel_connection)33 void LinkManager::ConnectFixedChannelServices(hci::AddressWithType address_with_type,
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(address_with_type);
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(
58           fixed_channel_service.first, SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK);
59       fixed_channel_service.second->NotifyChannelCreation(
60           std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
61       num_new_channels++;
62     }
63     // Declare connection failure if no new channels are created
64     if (num_new_channels == 0) {
65       pending_fixed_channel_connection.handler_->Post(common::BindOnce(
66           std::move(pending_fixed_channel_connection.on_fail_callback_),
67           FixedChannelManager::ConnectionResult{
68               .connection_result_code = FixedChannelManager::ConnectionResultCode::FAIL_ALL_SERVICES_HAVE_CHANNEL}));
69     }
70     // No need to create ACL connection, return without saving any pending connections
71     return;
72   }
73   // If not, create new ACL connection
74   // Add request to pending link list first
75   auto pending_link = pending_links_.find(address_with_type);
76   if (pending_link == pending_links_.end()) {
77     // Create pending link if not exist
78     pending_links_.try_emplace(address_with_type);
79     pending_link = pending_links_.find(address_with_type);
80   }
81   pending_link->second.pending_fixed_channel_connections_.push_back(std::move(pending_fixed_channel_connection));
82   // Then create new ACL connection
83   acl_manager_->CreateLeConnection(address_with_type, /* is_direct */ true);
84 }
85 
ConnectDynamicChannelServices(hci::AddressWithType device,Link::PendingDynamicChannelConnection pending_dynamic_channel_connection,Psm psm)86 void LinkManager::ConnectDynamicChannelServices(
87     hci::AddressWithType device, Link::PendingDynamicChannelConnection pending_dynamic_channel_connection, Psm psm) {
88   auto* link = GetLink(device);
89   if (link == nullptr) {
90     acl_manager_->CreateLeConnection(device, /* is_direct */ true);
91     pending_dynamic_channels_[device].push_back(std::make_pair(psm, std::move(pending_dynamic_channel_connection)));
92     return;
93   }
94   link->SendConnectionRequest(psm, std::move(pending_dynamic_channel_connection));
95 }
96 
GetLink(hci::AddressWithType address_with_type)97 Link* LinkManager::GetLink(hci::AddressWithType address_with_type) {
98   if (links_.find(address_with_type) == links_.end()) {
99     return nullptr;
100   }
101   return &links_.find(address_with_type)->second;
102 }
103 
OnLeConnectSuccess(hci::AddressWithType connecting_address_with_type,std::unique_ptr<hci::acl_manager::LeAclConnection> acl_connection)104 void LinkManager::OnLeConnectSuccess(hci::AddressWithType connecting_address_with_type,
105                                      std::unique_ptr<hci::acl_manager::LeAclConnection> acl_connection) {
106   // Same link should not be connected twice
107   hci::AddressWithType connected_address_with_type = acl_connection->GetRemoteAddress();
108   uint16_t handle = acl_connection->GetHandle();
109   ASSERT_LOG(GetLink(connected_address_with_type) == nullptr, "%s is connected twice without disconnection",
110              acl_connection->GetRemoteAddress().ToString().c_str());
111   links_.try_emplace(connected_address_with_type, l2cap_handler_, std::move(acl_connection), parameter_provider_,
112                      dynamic_channel_service_manager_, fixed_channel_service_manager_, this);
113   auto* link = GetLink(connected_address_with_type);
114 
115   if (link_property_callback_handler_ != nullptr) {
116     link_property_callback_handler_->CallOn(
117         link_property_listener_,
118         &LinkPropertyListener::OnLinkConnected,
119         connected_address_with_type,
120         handle,
121         link->GetRole());
122   }
123 
124   // Remove device from pending links list, if any
125   pending_links_.erase(connecting_address_with_type);
126 
127   link->ReadRemoteVersionInformation();
128 }
129 
OnLeConnectFail(hci::AddressWithType address_with_type,hci::ErrorCode reason)130 void LinkManager::OnLeConnectFail(hci::AddressWithType address_with_type, hci::ErrorCode reason) {
131   // Notify all pending links for this device
132   auto pending_link = pending_links_.find(address_with_type);
133   if (pending_link == pending_links_.end()) {
134     // There is no pending link, exit
135     LOG_INFO("Connection to %s failed without a pending link", address_with_type.ToString().c_str());
136     return;
137   }
138   for (auto& pending_fixed_channel_connection : pending_link->second.pending_fixed_channel_connections_) {
139     pending_fixed_channel_connection.handler_->Post(common::BindOnce(
140         std::move(pending_fixed_channel_connection.on_fail_callback_),
141         FixedChannelManager::ConnectionResult{
142             .connection_result_code = FixedChannelManager::ConnectionResultCode::FAIL_HCI_ERROR, .hci_error = reason}));
143   }
144   // Remove entry in pending link list
145   pending_links_.erase(pending_link);
146 }
147 
OnDisconnect(bluetooth::hci::AddressWithType address_with_type)148 void LinkManager::OnDisconnect(bluetooth::hci::AddressWithType address_with_type) {
149   auto* link = GetLink(address_with_type);
150   ASSERT_LOG(link != nullptr, "Device %s is disconnected but not in local database",
151              address_with_type.ToString().c_str());
152   if (links_with_pending_packets_.count(address_with_type) != 0) {
153     disconnected_links_.emplace(address_with_type);
154   } else {
155     links_.erase(address_with_type);
156   }
157 
158   if (link_property_callback_handler_ != nullptr) {
159     link_property_callback_handler_->CallOn(
160         link_property_listener_, &LinkPropertyListener::OnLinkDisconnected, address_with_type);
161   }
162 }
163 
RegisterLinkPropertyListener(os::Handler * handler,LinkPropertyListener * listener)164 void LinkManager::RegisterLinkPropertyListener(os::Handler* handler, LinkPropertyListener* listener) {
165   link_property_callback_handler_ = handler;
166   link_property_listener_ = listener;
167 }
168 
OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,hci::AddressWithType address_with_type,uint8_t lmp_version,uint16_t manufacturer_name,uint16_t sub_version)169 void LinkManager::OnReadRemoteVersionInformationComplete(
170     hci::ErrorCode hci_status,
171     hci::AddressWithType address_with_type,
172     uint8_t lmp_version,
173     uint16_t manufacturer_name,
174     uint16_t sub_version) {
175   if (link_property_callback_handler_ != nullptr) {
176     link_property_callback_handler_->CallOn(
177         link_property_listener_,
178         &LinkPropertyListener::OnReadRemoteVersionInformation,
179         hci_status,
180         address_with_type,
181         lmp_version,
182         manufacturer_name,
183         sub_version);
184   }
185 
186   auto* link = GetLink(address_with_type);
187   // Allocate and distribute channels for all registered fixed channel services
188   auto fixed_channel_services = fixed_channel_service_manager_->GetRegisteredServices();
189   for (auto& fixed_channel_service : fixed_channel_services) {
190     auto fixed_channel_impl = link->AllocateFixedChannel(
191         fixed_channel_service.first, SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK);
192     fixed_channel_service.second->NotifyChannelCreation(
193         std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
194   }
195   if (pending_dynamic_channels_.find(address_with_type) != pending_dynamic_channels_.end()) {
196     for (auto& psm_callback : pending_dynamic_channels_[address_with_type]) {
197       link->SendConnectionRequest(psm_callback.first, std::move(psm_callback.second));
198     }
199     pending_dynamic_channels_.erase(address_with_type);
200   }
201 }
202 
OnPendingPacketChange(hci::AddressWithType remote,int num_packets)203 void LinkManager::OnPendingPacketChange(hci::AddressWithType remote, int num_packets) {
204   if (disconnected_links_.count(remote) != 0 && num_packets == 0) {
205     links_.erase(remote);
206     links_with_pending_packets_.erase(remote);
207   } else if (num_packets != 0) {
208     links_with_pending_packets_.emplace(remote);
209   } else {
210     links_with_pending_packets_.erase(remote);
211   }
212 }
213 
214 }  // namespace internal
215 }  // namespace le
216 }  // namespace l2cap
217 }  // namespace bluetooth
218