blob: a23f5eca3bade9a0138f905a58bd01ee591df293 [file] [log] [blame]
Hansong Zhang80bbfc32019-09-10 16:12:05 -07001/*
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
Hansong Zhang80bbfc32019-09-10 16:12:05 -070017#include <chrono>
18#include <memory>
19
20#include "hci/acl_manager.h"
Chris Manton6230a6f2019-11-13 18:37:33 -080021#include "l2cap/classic/dynamic_channel_manager.h"
Jack Heff38d892019-10-03 17:11:07 -070022#include "l2cap/classic/internal/fixed_channel_impl.h"
23#include "l2cap/classic/internal/link.h"
Hansong Zhang80bbfc32019-09-10 16:12:05 -070024#include "l2cap/internal/parameter_provider.h"
Hansong Zhang80bbfc32019-09-10 16:12:05 -070025#include "os/alarm.h"
26
27namespace bluetooth {
28namespace l2cap {
Jack Heff38d892019-10-03 17:11:07 -070029namespace classic {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070030namespace internal {
31
Jack Heff38d892019-10-03 17:11:07 -070032Link::Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
Hansong Zhangcd0c3192019-09-20 15:50:42 -070033 l2cap::internal::ParameterProvider* parameter_provider,
34 DynamicChannelServiceManagerImpl* dynamic_service_manager,
35 FixedChannelServiceManagerImpl* fixed_service_manager)
Hansong Zhang90603b32019-11-22 15:11:12 -080036 : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)),
37 data_pipeline_manager_(l2cap_handler, acl_connection_->GetAclQueueEnd()), parameter_provider_(parameter_provider),
38 dynamic_service_manager_(dynamic_service_manager), fixed_service_manager_(fixed_service_manager),
Hansong Zhangf0a16922019-11-22 21:27:08 -080039 signalling_manager_(l2cap_handler_, this, &data_pipeline_manager_, dynamic_service_manager_,
40 &dynamic_channel_allocator_, fixed_service_manager_) {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070041 ASSERT(l2cap_handler_ != nullptr);
42 ASSERT(acl_connection_ != nullptr);
Hansong Zhang80bbfc32019-09-10 16:12:05 -070043 ASSERT(parameter_provider_ != nullptr);
Jack Heff38d892019-10-03 17:11:07 -070044 link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
Hansong Zhang80bbfc32019-09-10 16:12:05 -070045 parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
46}
47
Jack Heff38d892019-10-03 17:11:07 -070048void Link::OnAclDisconnected(hci::ErrorCode status) {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070049 fixed_channel_allocator_.OnAclDisconnected(status);
Hansong Zhangcd0c3192019-09-20 15:50:42 -070050 dynamic_channel_allocator_.OnAclDisconnected(status);
Hansong Zhang80bbfc32019-09-10 16:12:05 -070051}
52
Jack Heff38d892019-10-03 17:11:07 -070053void Link::Disconnect() {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070054 acl_connection_->Disconnect(hci::DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
55}
56
Jack Heff38d892019-10-03 17:11:07 -070057std::shared_ptr<FixedChannelImpl> Link::AllocateFixedChannel(Cid cid, SecurityPolicy security_policy) {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070058 auto channel = fixed_channel_allocator_.AllocateChannel(cid, security_policy);
Hansong Zhang90603b32019-11-22 15:11:12 -080059 data_pipeline_manager_.AttachChannel(cid, channel);
Hansong Zhang80bbfc32019-09-10 16:12:05 -070060 return channel;
61}
62
Jack Heff38d892019-10-03 17:11:07 -070063bool Link::IsFixedChannelAllocated(Cid cid) {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070064 return fixed_channel_allocator_.IsChannelAllocated(cid);
65}
66
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -070067Cid Link::ReserveDynamicChannel() {
68 return dynamic_channel_allocator_.ReserveChannel();
69}
70
Hansong Zhangcd0c3192019-09-20 15:50:42 -070071void Link::SendConnectionRequest(Psm psm, Cid local_cid) {
72 signalling_manager_.SendConnectionRequest(psm, local_cid);
73}
74
Chris Manton6230a6f2019-11-13 18:37:33 -080075void Link::SendConnectionRequest(Psm psm, Cid local_cid,
76 PendingDynamicChannelConnection pending_dynamic_channel_connection) {
77 local_cid_to_pending_dynamic_channel_connection_map_[local_cid] = std::move(pending_dynamic_channel_connection);
78 signalling_manager_.SendConnectionRequest(psm, local_cid);
79}
80
Hansong Zhangcd0c3192019-09-20 15:50:42 -070081void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
82 signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid);
83}
84
Chris Manton24809602019-10-31 14:36:02 -070085void Link::SendInformationRequest(InformationRequestInfoType type) {
86 signalling_manager_.SendInformationRequest(type);
87}
88
Hansong Zhang47dec642019-11-25 12:01:15 -080089std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid remote_cid,
90 SecurityPolicy security_policy) {
Hansong Zhang80bbfc32019-09-10 16:12:05 -070091 auto channel = dynamic_channel_allocator_.AllocateChannel(psm, remote_cid, security_policy);
Hansong Zhangcd0c3192019-09-20 15:50:42 -070092 if (channel != nullptr) {
Hansong Zhang90603b32019-11-22 15:11:12 -080093 data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
Hansong Zhangcd0c3192019-09-20 15:50:42 -070094 }
Chris Manton6230a6f2019-11-13 18:37:33 -080095 channel->local_initiated_ = false;
Hansong Zhang80bbfc32019-09-10 16:12:05 -070096 return channel;
97}
98
Hansong Zhang47dec642019-11-25 12:01:15 -080099std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateReservedDynamicChannel(
100 Cid reserved_cid, Psm psm, Cid remote_cid, SecurityPolicy security_policy) {
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700101 auto channel = dynamic_channel_allocator_.AllocateReservedChannel(reserved_cid, psm, remote_cid, security_policy);
102 if (channel != nullptr) {
Hansong Zhang90603b32019-11-22 15:11:12 -0800103 data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700104 }
Chris Manton6230a6f2019-11-13 18:37:33 -0800105 channel->local_initiated_ = true;
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700106 return channel;
107}
108
Hansong Zhanga6312532019-11-19 14:01:36 -0800109classic::DynamicChannelConfigurationOption Link::GetConfigurationForInitialConfiguration(Cid cid) {
110 ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
111 local_cid_to_pending_dynamic_channel_connection_map_.end());
112 return local_cid_to_pending_dynamic_channel_connection_map_[cid].configuration_;
Hansong Zhangb0960762019-11-14 17:57:10 -0800113}
114
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700115void Link::FreeDynamicChannel(Cid cid) {
116 if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) {
117 return;
118 }
Hansong Zhang90603b32019-11-22 15:11:12 -0800119 data_pipeline_manager_.DetachChannel(cid);
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700120 dynamic_channel_allocator_.FreeChannel(cid);
121}
Hansong Zhang80bbfc32019-09-10 16:12:05 -0700122
Jack Heff38d892019-10-03 17:11:07 -0700123void Link::RefreshRefCount() {
Hansong Zhang80bbfc32019-09-10 16:12:05 -0700124 int ref_count = 0;
125 ref_count += fixed_channel_allocator_.GetRefCount();
126 ref_count += dynamic_channel_allocator_.NumberOfChannels();
127 ASSERT_LOG(ref_count >= 0, "ref_count %d is less than 0", ref_count);
128 if (ref_count > 0) {
129 link_idle_disconnect_alarm_.Cancel();
130 } else {
Jack Heff38d892019-10-03 17:11:07 -0700131 link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
Hansong Zhang80bbfc32019-09-10 16:12:05 -0700132 parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
133 }
134}
135
Hansong Zhanga6312532019-11-19 14:01:36 -0800136void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> user_channel) {
Chris Manton6230a6f2019-11-13 18:37:33 -0800137 ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
138 local_cid_to_pending_dynamic_channel_connection_map_.end());
139 auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid];
140 pending_dynamic_channel_connection.handler_->Post(
Hansong Zhanga6312532019-11-19 14:01:36 -0800141 common::BindOnce(std::move(pending_dynamic_channel_connection.on_open_callback_), std::move(user_channel)));
Chris Manton6230a6f2019-11-13 18:37:33 -0800142 local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
143}
144
145void Link::NotifyChannelFail(Cid cid) {
146 ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
147 local_cid_to_pending_dynamic_channel_connection_map_.end());
148 auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid];
149 // TODO(cmanton) Pass proper connection falure result to user
150 DynamicChannelManager::ConnectionResult result;
151 pending_dynamic_channel_connection.handler_->Post(
152 common::BindOnce(std::move(pending_dynamic_channel_connection.on_fail_callback_), result));
153 local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
154}
155
Hansong Zhang70fb4642019-11-20 17:33:06 -0800156void Link::SetRemoteConnectionlessMtu(Mtu mtu) {
157 remote_mtu_ = mtu;
158}
159
160Mtu Link::GetRemoteConnectionlessMtu() const {
161 return remote_mtu_;
162}
163
164void Link::SetRemoteSupportsErtm(bool supported) {
165 remote_supports_ertm_ = supported;
166}
167
168bool Link::GetRemoteSupportsErtm() const {
169 return remote_supports_ertm_;
170}
171
172void Link::SetRemoteSupportsFcs(bool supported) {
173 remote_supports_fcs_ = supported;
174}
175
176bool Link::GetRemoteSupportsFcs() const {
177 return remote_supports_fcs_;
178}
179
Hansong Zhang80bbfc32019-09-10 16:12:05 -0700180} // namespace internal
Jack Heff38d892019-10-03 17:11:07 -0700181} // namespace classic
Hansong Zhang80bbfc32019-09-10 16:12:05 -0700182} // namespace l2cap
183} // namespace bluetooth