aboutsummaryrefslogtreecommitdiff
path: root/gd/l2cap/classic/internal/link.h
blob: a5b17a9dc84de3cacbeb13a6a0f88439589aee66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <atomic>
#include <memory>
#include <unordered_map>

#include "hci/acl_manager/classic_acl_connection.h"
#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h"
#include "l2cap/classic/internal/fixed_channel_impl.h"
#include "l2cap/classic/internal/fixed_channel_service_manager_impl.h"
#include "l2cap/classic/security_enforcement_interface.h"
#include "l2cap/internal/data_pipeline_manager.h"
#include "l2cap/internal/dynamic_channel_allocator.h"
#include "l2cap/internal/dynamic_channel_impl.h"
#include "l2cap/internal/fixed_channel_allocator.h"
#include "l2cap/internal/ilink.h"
#include "l2cap/internal/parameter_provider.h"
#include "os/alarm.h"
#include "os/handler.h"
#include "signalling_manager.h"

namespace bluetooth {
namespace l2cap {
namespace classic {
namespace internal {

class LinkManager;
class DumpsysHelper;

class Link : public l2cap::internal::ILink, public hci::acl_manager::ConnectionManagementCallbacks {
 public:
  Link(os::Handler* l2cap_handler, std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection,
       l2cap::internal::ParameterProvider* parameter_provider,
       DynamicChannelServiceManagerImpl* dynamic_service_manager, FixedChannelServiceManagerImpl* fixed_service_manager,
       LinkManager* link_manager);

  hci::AddressWithType GetDevice() const override {
    return {acl_connection_->GetAddress(), hci::AddressType::PUBLIC_DEVICE_ADDRESS};
  }

  struct PendingDynamicChannelConnection {
    os::Handler* handler_;
    DynamicChannelManager::OnConnectionOpenCallback on_open_callback_;
    DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_;
    classic::DynamicChannelConfigurationOption configuration_;
  };

  struct PendingAuthenticateDynamicChannelConnection {
    Psm psm_;
    Cid cid_;
    PendingDynamicChannelConnection pending_dynamic_channel_connection_;
  };

  // ACL methods

  virtual void OnAclDisconnected(hci::ErrorCode status);

  virtual void Disconnect();

  virtual void Encrypt();

  virtual void Authenticate();

  virtual bool IsAuthenticated() const;

  virtual void ReadRemoteVersionInformation();

  virtual void ReadRemoteSupportedFeatures();

  virtual void ReadRemoteExtendedFeatures(uint8_t page_number);

  virtual void ReadClockOffset();

  // Increase the link usage refcount to ensure the link won't be disconnected when SecurityModule needs it
  virtual void AcquireSecurityHold();

  // Decrease the link usage refcount when SecurityModule no longer needs it
  virtual void ReleaseSecurityHold();

  // FixedChannel methods

  std::shared_ptr<FixedChannelImpl> AllocateFixedChannel(Cid cid);

  virtual bool IsFixedChannelAllocated(Cid cid);

  // DynamicChannel methods

  virtual Cid ReserveDynamicChannel();

  virtual void SendConnectionRequest(Psm psm, Cid local_cid);
  virtual void SendConnectionRequest(Psm psm, Cid local_cid,
                                     PendingDynamicChannelConnection pending_dynamic_channel_connection);
  void SetChannelTxPriority(Cid local_cid, bool high_priority) override;

  // When a Link is established, LinkManager notifies pending dynamic channels to connect
  virtual void SetPendingDynamicChannels(std::list<Psm> psm_list,
                                         std::list<Link::PendingDynamicChannelConnection> callback_list);

  // Invoked by signalling manager to indicate an outgoing connection request failed and link shall free resources
  virtual void OnOutgoingConnectionRequestFail(Cid local_cid, DynamicChannelManager::ConnectionResult result);

  virtual void SendInitialConfigRequestOrQueue(Cid local_cid);

  virtual void SendInformationRequest(InformationRequestInfoType type);

  virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override;

  virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateDynamicChannel(Psm psm, Cid remote_cid);

  virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateReservedDynamicChannel(Cid reserved_cid, Psm psm,
                                                                                              Cid remote_cid);

  virtual classic::DynamicChannelConfigurationOption GetConfigurationForInitialConfiguration(Cid cid);

  virtual void FreeDynamicChannel(Cid cid);

  // Check how many channels are acquired or in use, if zero, start tear down timer, if non-zero, cancel tear down timer
  virtual void RefreshRefCount();

  virtual void NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel);
  virtual void NotifyChannelFail(Cid cid, DynamicChannelManager::ConnectionResult result);

  // Information received from signaling channel
  virtual void SetRemoteConnectionlessMtu(Mtu mtu);
  virtual Mtu GetRemoteConnectionlessMtu() const;
  virtual bool GetRemoteSupportsErtm() const;
  virtual bool GetRemoteSupportsFcs() const;
  virtual void OnRemoteExtendedFeatureReceived(bool ertm_supported, bool fcs_supported);

  virtual std::string ToString() const {
    return GetDevice().ToString();
  }

  void SendLeCredit(Cid local_cid, uint16_t credit) override {}

  // ConnectionManagementCallbacks
  void OnConnectionPacketTypeChanged(uint16_t packet_type) override;
  void OnAuthenticationComplete(hci::ErrorCode hci_status) override;
  void OnEncryptionChange(hci::EncryptionEnabled enabled) override;
  void OnChangeConnectionLinkKeyComplete() override;
  void OnReadClockOffsetComplete(uint16_t clock_offset) override;
  void OnModeChange(hci::ErrorCode status, hci::Mode current_mode, uint16_t interval) override;
  void OnSniffSubrating(
      hci::ErrorCode hci_status,
      uint16_t maximum_transmit_latency,
      uint16_t maximum_receive_latency,
      uint16_t minimum_remote_timeout,
      uint16_t minimum_local_timeout) override;
  void OnQosSetupComplete(hci::ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth, uint32_t latency,
                          uint32_t delay_variation) override;
  void OnFlowSpecificationComplete(hci::FlowDirection flow_direction, hci::ServiceType service_type,
                                   uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth,
                                   uint32_t access_latency) override;
  void OnFlushOccurred() override;
  void OnRoleDiscoveryComplete(hci::Role current_role) override;
  void OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings) override;
  void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override;
  void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override;
  void OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout) override;
  void OnReadFailedContactCounterComplete(uint16_t failed_contact_counter) override;
  void OnReadLinkQualityComplete(uint8_t link_quality) override;
  void OnReadAfhChannelMapComplete(hci::AfhMode afh_mode, std::array<uint8_t, 10> afh_channel_map) override;
  void OnReadRssiComplete(uint8_t rssi) override;
  void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override;
  void OnCentralLinkKeyComplete(hci::KeyFlag key_flag) override;
  void OnRoleChange(hci::ErrorCode hci_status, hci::Role new_role) override;
  void OnDisconnection(hci::ErrorCode reason) override;
  void OnReadRemoteVersionInformationComplete(
      hci::ErrorCode hci_status, uint8_t lmp_version, uint16_t manufacturer_name, uint16_t sub_version);
  void OnReadRemoteSupportedFeaturesComplete(uint64_t features);
  void OnReadRemoteExtendedFeaturesComplete(uint8_t page_number, uint8_t max_page_number, uint64_t features);

  struct EncryptionChangeListener {
    Cid cid;
    Psm psm;
  };
  void AddEncryptionChangeListener(EncryptionChangeListener);

  uint16_t GetAclHandle() const {
    return acl_handle_;
  }

  hci::Role GetRole() const {
    return role_;
  }

  void OnPendingPacketChange(Cid local_cid, bool has_packet) override;

 private:
  friend class DumpsysHelper;
  void connect_to_pending_dynamic_channels();
  void send_pending_configuration_requests();

  os::Handler* l2cap_handler_;
  l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_};
  l2cap::internal::DynamicChannelAllocator dynamic_channel_allocator_{this, l2cap_handler_};
  std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection_;
  l2cap::internal::DataPipelineManager data_pipeline_manager_;
  l2cap::internal::ParameterProvider* parameter_provider_;
  DynamicChannelServiceManagerImpl* dynamic_service_manager_;
  FixedChannelServiceManagerImpl* fixed_service_manager_;
  LinkManager* link_manager_;
  std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_;
  os::Alarm link_idle_disconnect_alarm_{l2cap_handler_};
  ClassicSignallingManager signalling_manager_;
  uint16_t acl_handle_;
  Mtu remote_connectionless_mtu_ = kMinimumClassicMtu;
  hci::Role role_ = hci::Role::CENTRAL;
  bool remote_extended_feature_received_ = false;
  bool remote_supports_ertm_ = false;
  bool remote_supports_fcs_ = false;
  hci::EncryptionEnabled encryption_enabled_ = hci::EncryptionEnabled::OFF;
  std::list<Psm> pending_dynamic_psm_list_;
  std::list<Link::PendingDynamicChannelConnection> pending_dynamic_channel_callback_list_;
  std::list<uint16_t> pending_outgoing_configuration_request_list_;
  bool used_by_security_module_ = false;
  bool has_requested_authentication_ = false;
  std::list<EncryptionChangeListener> encryption_change_listener_;
  std::atomic_int remaining_packets_to_be_sent_ = 0;
  DISALLOW_COPY_AND_ASSIGN(Link);
};

}  // namespace internal
}  // namespace classic
}  // namespace l2cap
}  // namespace bluetooth