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
17 #include "l2cap/classic/internal/link.h"
18
19 #include <bluetooth/log.h>
20
21 #include <chrono>
22 #include <memory>
23
24 #include "common/bind.h"
25 #include "hci/acl_manager/classic_acl_connection.h"
26 #include "l2cap/classic/dynamic_channel_manager.h"
27 #include "l2cap/classic/internal/fixed_channel_impl.h"
28 #include "l2cap/classic/internal/link_manager.h"
29 #include "l2cap/internal/parameter_provider.h"
30 #include "os/alarm.h"
31
32 namespace bluetooth {
33 namespace l2cap {
34 namespace classic {
35 namespace internal {
36
37 using RetransmissionAndFlowControlMode = DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode;
38 using ConnectionResult = DynamicChannelManager::ConnectionResult;
39 using ConnectionResultCode = DynamicChannelManager::ConnectionResultCode;
40
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)41 Link::Link(
42 os::Handler* l2cap_handler,
43 std::unique_ptr<hci::acl_manager::ClassicAclConnection> acl_connection,
44 l2cap::internal::ParameterProvider* parameter_provider,
45 DynamicChannelServiceManagerImpl* dynamic_service_manager,
46 FixedChannelServiceManagerImpl* fixed_service_manager,
47 LinkManager* link_manager)
48 : l2cap_handler_(l2cap_handler),
49 acl_connection_(std::move(acl_connection)),
50 data_pipeline_manager_(l2cap_handler, this, acl_connection_->GetAclQueueEnd()),
51 parameter_provider_(parameter_provider),
52 dynamic_service_manager_(dynamic_service_manager),
53 fixed_service_manager_(fixed_service_manager),
54 link_manager_(link_manager),
55 signalling_manager_(
56 l2cap_handler_,
57 this,
58 &data_pipeline_manager_,
59 dynamic_service_manager_,
60 &dynamic_channel_allocator_,
61 fixed_service_manager_),
62 acl_handle_(acl_connection_->GetHandle()) {
63 log::assert_that(l2cap_handler_ != nullptr, "assert failed: l2cap_handler_ != nullptr");
64 log::assert_that(acl_connection_ != nullptr, "assert failed: acl_connection_ != nullptr");
65 log::assert_that(parameter_provider_ != nullptr, "assert failed: parameter_provider_ != nullptr");
66 link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
67 parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
68 acl_connection_->RegisterCallbacks(this, l2cap_handler_);
69 }
70
OnAclDisconnected(hci::ErrorCode status)71 void Link::OnAclDisconnected(hci::ErrorCode status) {
72 signalling_manager_.CancelAlarm();
73 fixed_channel_allocator_.OnAclDisconnected(status);
74 dynamic_channel_allocator_.OnAclDisconnected(status);
75 ConnectionResult result{
76 .connection_result_code = ConnectionResultCode::FAIL_HCI_ERROR,
77 .hci_error = status,
78 .l2cap_connection_response_result = ConnectionResponseResult::SUCCESS,
79 };
80 while (!local_cid_to_pending_dynamic_channel_connection_map_.empty()) {
81 auto entry = local_cid_to_pending_dynamic_channel_connection_map_.begin();
82 NotifyChannelFail(entry->first, result);
83 }
84 }
85
Disconnect()86 void Link::Disconnect() {
87 acl_connection_->Disconnect(hci::DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
88 }
89
Encrypt()90 void Link::Encrypt() {
91 if (encryption_enabled_ == hci::EncryptionEnabled::OFF) {
92 acl_connection_->SetConnectionEncryption(hci::Enable::ENABLED);
93 }
94 }
95
Authenticate()96 void Link::Authenticate() {
97 if (!IsAuthenticated() && !has_requested_authentication_) {
98 has_requested_authentication_ = true;
99 acl_connection_->AuthenticationRequested();
100 }
101 }
102
IsAuthenticated() const103 bool Link::IsAuthenticated() const {
104 return encryption_enabled_ != hci::EncryptionEnabled::OFF;
105 }
106
ReadRemoteVersionInformation()107 void Link::ReadRemoteVersionInformation() {
108 acl_connection_->ReadRemoteVersionInformation();
109 }
110
ReadRemoteSupportedFeatures()111 void Link::ReadRemoteSupportedFeatures() {
112 acl_connection_->ReadRemoteSupportedFeatures();
113 }
114
ReadRemoteExtendedFeatures(uint8_t page_number)115 void Link::ReadRemoteExtendedFeatures(uint8_t page_number) {
116 acl_connection_->ReadRemoteExtendedFeatures(page_number);
117 }
118
ReadClockOffset()119 void Link::ReadClockOffset() {
120 acl_connection_->ReadClockOffset();
121 }
122
AcquireSecurityHold()123 void Link::AcquireSecurityHold() {
124 used_by_security_module_ = true;
125 RefreshRefCount();
126 }
ReleaseSecurityHold()127 void Link::ReleaseSecurityHold() {
128 used_by_security_module_ = false;
129 RefreshRefCount();
130 }
131
AllocateFixedChannel(Cid cid)132 std::shared_ptr<FixedChannelImpl> Link::AllocateFixedChannel(Cid cid) {
133 auto channel = fixed_channel_allocator_.AllocateChannel(cid);
134 data_pipeline_manager_.AttachChannel(cid, channel, l2cap::internal::DataPipelineManager::ChannelMode::BASIC);
135 return channel;
136 }
137
IsFixedChannelAllocated(Cid cid)138 bool Link::IsFixedChannelAllocated(Cid cid) {
139 return fixed_channel_allocator_.IsChannelAllocated(cid);
140 }
141
ReserveDynamicChannel()142 Cid Link::ReserveDynamicChannel() {
143 return dynamic_channel_allocator_.ReserveChannel();
144 }
145
SendConnectionRequest(Psm psm,Cid local_cid)146 void Link::SendConnectionRequest(Psm psm, Cid local_cid) {
147 signalling_manager_.SendConnectionRequest(psm, local_cid);
148 }
149
SendConnectionRequest(Psm psm,Cid local_cid,PendingDynamicChannelConnection pending_dynamic_channel_connection)150 void Link::SendConnectionRequest(Psm psm, Cid local_cid,
151 PendingDynamicChannelConnection pending_dynamic_channel_connection) {
152 if (pending_dynamic_channel_connection.configuration_.channel_mode ==
153 RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION &&
154 !remote_extended_feature_received_) {
155 pending_dynamic_psm_list_.push_back(psm);
156 pending_dynamic_channel_callback_list_.push_back(std::move(pending_dynamic_channel_connection));
157 log::info("Will connect after information response ERTM feature support is received");
158 dynamic_channel_allocator_.FreeChannel(local_cid);
159 return;
160 } else if (pending_dynamic_channel_connection.configuration_.channel_mode ==
161 RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION &&
162 !GetRemoteSupportsErtm()) {
163 log::warn("Remote doesn't support ERTM. Dropping connection request");
164 ConnectionResult result{
165 .connection_result_code = ConnectionResultCode::FAIL_REMOTE_NOT_SUPPORT,
166 };
167 pending_dynamic_channel_connection.on_fail_callback_(result);
168 dynamic_channel_allocator_.FreeChannel(local_cid);
169 return;
170 } else {
171 local_cid_to_pending_dynamic_channel_connection_map_[local_cid] = std::move(pending_dynamic_channel_connection);
172 signalling_manager_.SendConnectionRequest(psm, local_cid);
173 }
174 }
175
SetChannelTxPriority(Cid local_cid,bool high_priority)176 void Link::SetChannelTxPriority(Cid local_cid, bool high_priority) {
177 data_pipeline_manager_.SetChannelTxPriority(local_cid, high_priority);
178 }
179
SetPendingDynamicChannels(std::list<Psm> psm_list,std::list<Link::PendingDynamicChannelConnection> callback_list)180 void Link::SetPendingDynamicChannels(std::list<Psm> psm_list,
181 std::list<Link::PendingDynamicChannelConnection> callback_list) {
182 log::assert_that(
183 psm_list.size() == callback_list.size(),
184 "assert failed: psm_list.size() == callback_list.size()");
185 pending_dynamic_psm_list_ = std::move(psm_list);
186 pending_dynamic_channel_callback_list_ = std::move(callback_list);
187 }
188
connect_to_pending_dynamic_channels()189 void Link::connect_to_pending_dynamic_channels() {
190 auto psm = pending_dynamic_psm_list_.begin();
191 auto callback = pending_dynamic_channel_callback_list_.begin();
192 while (psm != pending_dynamic_psm_list_.end()) {
193 SendConnectionRequest(*psm, ReserveDynamicChannel(), std::move(*callback));
194 psm++;
195 callback++;
196 }
197 }
198
send_pending_configuration_requests()199 void Link::send_pending_configuration_requests() {
200 for (auto local_cid : pending_outgoing_configuration_request_list_) {
201 signalling_manager_.SendInitialConfigRequest(local_cid);
202 }
203 pending_outgoing_configuration_request_list_.clear();
204 }
205
OnOutgoingConnectionRequestFail(Cid local_cid,ConnectionResult result)206 void Link::OnOutgoingConnectionRequestFail(Cid local_cid, ConnectionResult result) {
207 if (local_cid_to_pending_dynamic_channel_connection_map_.find(local_cid) !=
208 local_cid_to_pending_dynamic_channel_connection_map_.end()) {
209 NotifyChannelFail(local_cid, result);
210 }
211 dynamic_channel_allocator_.FreeChannel(local_cid);
212 }
213
SendInitialConfigRequestOrQueue(Cid local_cid)214 void Link::SendInitialConfigRequestOrQueue(Cid local_cid) {
215 if (remote_extended_feature_received_) {
216 signalling_manager_.SendInitialConfigRequest(local_cid);
217 } else {
218 pending_outgoing_configuration_request_list_.push_back(local_cid);
219 }
220 }
221
SendDisconnectionRequest(Cid local_cid,Cid remote_cid)222 void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
223 signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid);
224 }
225
SendInformationRequest(InformationRequestInfoType type)226 void Link::SendInformationRequest(InformationRequestInfoType type) {
227 signalling_manager_.SendInformationRequest(type);
228 }
229
AllocateDynamicChannel(Psm psm,Cid remote_cid)230 std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid remote_cid) {
231 auto channel = dynamic_channel_allocator_.AllocateChannel(psm, remote_cid);
232 if (channel != nullptr) {
233 RefreshRefCount();
234 channel->local_initiated_ = false;
235 }
236 return channel;
237 }
238
AllocateReservedDynamicChannel(Cid reserved_cid,Psm psm,Cid remote_cid)239 std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateReservedDynamicChannel(Cid reserved_cid, Psm psm,
240 Cid remote_cid) {
241 auto channel = dynamic_channel_allocator_.AllocateReservedChannel(reserved_cid, psm, remote_cid);
242 if (channel != nullptr) {
243 RefreshRefCount();
244 }
245 channel->local_initiated_ = true;
246 return channel;
247 }
248
GetConfigurationForInitialConfiguration(Cid cid)249 classic::DynamicChannelConfigurationOption Link::GetConfigurationForInitialConfiguration(Cid cid) {
250 log::assert_that(
251 local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
252 local_cid_to_pending_dynamic_channel_connection_map_.end(),
253 "assert failed: local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != "
254 "local_cid_to_pending_dynamic_channel_connection_map_.end()");
255 return local_cid_to_pending_dynamic_channel_connection_map_[cid].configuration_;
256 }
257
FreeDynamicChannel(Cid cid)258 void Link::FreeDynamicChannel(Cid cid) {
259 if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) {
260 return;
261 }
262 dynamic_channel_allocator_.FreeChannel(cid);
263 RefreshRefCount();
264 }
265
RefreshRefCount()266 void Link::RefreshRefCount() {
267 int ref_count = 0;
268 ref_count += fixed_channel_allocator_.GetRefCount();
269 ref_count += dynamic_channel_allocator_.NumberOfChannels();
270 if (used_by_security_module_) {
271 ref_count += 1;
272 }
273 log::assert_that(ref_count >= 0, "ref_count {} is less than 0", ref_count);
274 if (ref_count > 0) {
275 link_idle_disconnect_alarm_.Cancel();
276 } else {
277 link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
278 parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
279 }
280 }
281
NotifyChannelCreation(Cid cid,std::unique_ptr<DynamicChannel> user_channel)282 void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> user_channel) {
283 log::assert_that(
284 local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
285 local_cid_to_pending_dynamic_channel_connection_map_.end(),
286 "assert failed: local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != "
287 "local_cid_to_pending_dynamic_channel_connection_map_.end()");
288 auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid];
289 pending_dynamic_channel_connection.on_open_callback_(std::move(user_channel));
290 local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
291 }
292
NotifyChannelFail(Cid cid,ConnectionResult result)293 void Link::NotifyChannelFail(Cid cid, ConnectionResult result) {
294 log::assert_that(
295 local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
296 local_cid_to_pending_dynamic_channel_connection_map_.end(),
297 "assert failed: local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != "
298 "local_cid_to_pending_dynamic_channel_connection_map_.end()");
299 auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid];
300 pending_dynamic_channel_connection.on_fail_callback_(result);
301 local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
302 }
303
SetRemoteConnectionlessMtu(Mtu mtu)304 void Link::SetRemoteConnectionlessMtu(Mtu mtu) {
305 remote_connectionless_mtu_ = mtu;
306 }
307
GetRemoteConnectionlessMtu() const308 Mtu Link::GetRemoteConnectionlessMtu() const {
309 return remote_connectionless_mtu_;
310 }
311
GetRemoteSupportsErtm() const312 bool Link::GetRemoteSupportsErtm() const {
313 return remote_supports_ertm_;
314 }
315
GetRemoteSupportsFcs() const316 bool Link::GetRemoteSupportsFcs() const {
317 return remote_supports_fcs_;
318 }
319
OnRemoteExtendedFeatureReceived(bool ertm_supported,bool fcs_supported)320 void Link::OnRemoteExtendedFeatureReceived(bool ertm_supported, bool fcs_supported) {
321 remote_supports_ertm_ = ertm_supported;
322 remote_supports_fcs_ = fcs_supported;
323 remote_extended_feature_received_ = true;
324 connect_to_pending_dynamic_channels();
325 send_pending_configuration_requests();
326 }
327
OnConnectionPacketTypeChanged(uint16_t packet_type)328 void Link::OnConnectionPacketTypeChanged(uint16_t packet_type) {
329 log::info("UNIMPLEMENTED packet_type:{:x}", packet_type);
330 }
331
OnAuthenticationComplete(hci::ErrorCode hci_status)332 void Link::OnAuthenticationComplete(hci::ErrorCode hci_status) {
333 link_manager_->OnAuthenticationComplete(hci_status, GetDevice().GetAddress());
334 }
335
OnEncryptionChange(hci::EncryptionEnabled enabled)336 void Link::OnEncryptionChange(hci::EncryptionEnabled enabled) {
337 encryption_enabled_ = enabled;
338 link_manager_->OnEncryptionChange(GetDevice().GetAddress(), enabled);
339 for (auto& listener : encryption_change_listener_) {
340 signalling_manager_.on_security_result_for_outgoing(
341 ClassicSignallingManager::SecurityEnforcementType::ENCRYPTION,
342 listener.psm,
343 listener.cid,
344 enabled != hci::EncryptionEnabled::OFF);
345 }
346 }
347
OnChangeConnectionLinkKeyComplete()348 void Link::OnChangeConnectionLinkKeyComplete() {
349 log::info("UNIMPLEMENTED");
350 }
351
OnReadClockOffsetComplete(uint16_t clock_offset)352 void Link::OnReadClockOffsetComplete(uint16_t clock_offset) {
353 link_manager_->OnReadClockOffset(GetDevice().GetAddress(), clock_offset);
354 }
355
OnModeChange(hci::ErrorCode status,hci::Mode current_mode,uint16_t interval)356 void Link::OnModeChange(hci::ErrorCode status, hci::Mode current_mode, uint16_t interval) {
357 link_manager_->OnModeChange(status, GetDevice().GetAddress(), current_mode, interval);
358 }
359
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)360 void Link::OnSniffSubrating(
361 hci::ErrorCode hci_status,
362 uint16_t maximum_transmit_latency,
363 uint16_t maximum_receive_latency,
364 uint16_t minimum_remote_timeout,
365 uint16_t minimum_local_timeout) {
366 link_manager_->OnSniffSubrating(
367 hci_status,
368 GetDevice().GetAddress(),
369 maximum_transmit_latency,
370 maximum_receive_latency,
371 minimum_remote_timeout,
372 minimum_local_timeout);
373 }
374
OnQosSetupComplete(hci::ServiceType service_type,uint32_t token_rate,uint32_t peak_bandwidth,uint32_t latency,uint32_t delay_variation)375 void Link::OnQosSetupComplete(hci::ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth,
376 uint32_t latency, uint32_t delay_variation) {
377 log::info(
378 "UNIMPLEMENTED service_type:{} token_rate:{} peak_bandwidth:{} latency:{} "
379 "delay_varitation:{}",
380 hci::ServiceTypeText(service_type),
381 token_rate,
382 peak_bandwidth,
383 latency,
384 delay_variation);
385 }
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)386 void Link::OnFlowSpecificationComplete(hci::FlowDirection flow_direction, hci::ServiceType service_type,
387 uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth,
388 uint32_t access_latency) {
389 log::info(
390 "UNIMPLEMENTED flow_direction:{} service_type:{} token_rate:{} token_bucket_size:{} "
391 "peak_bandwidth:{} access_latency:{}",
392 hci::FlowDirectionText(flow_direction),
393 hci::ServiceTypeText(service_type),
394 token_rate,
395 token_bucket_size,
396 peak_bandwidth,
397 access_latency);
398 }
OnFlushOccurred()399 void Link::OnFlushOccurred() {
400 log::info("UNIMPLEMENTED");
401 }
OnRoleDiscoveryComplete(hci::Role current_role)402 void Link::OnRoleDiscoveryComplete(hci::Role current_role) {
403 role_ = current_role;
404 }
OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings)405 void Link::OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings) {
406 log::info("UNIMPLEMENTED link_policy_settings:0x{:x}", link_policy_settings);
407 }
OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout)408 void Link::OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) {
409 log::info("UNIMPLEMENTED flush_timeout:{}", flush_timeout);
410 }
OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level)411 void Link::OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) {
412 log::info("UNIMPLEMENTED transmit_power_level:{}", transmit_power_level);
413 }
OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout)414 void Link::OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout) {
415 log::info("UNIMPLEMENTED link_supervision_timeout:{}", link_supervision_timeout);
416 }
OnReadFailedContactCounterComplete(uint16_t failed_contact_counter)417 void Link::OnReadFailedContactCounterComplete(uint16_t failed_contact_counter) {
418 log::info("UNIMPLEMENTED failed_contact_counter:{}", failed_contact_counter);
419 }
OnReadLinkQualityComplete(uint8_t link_quality)420 void Link::OnReadLinkQualityComplete(uint8_t link_quality) {
421 log::info("UNIMPLEMENTED link_quality:{}", link_quality);
422 }
OnReadAfhChannelMapComplete(hci::AfhMode afh_mode,std::array<uint8_t,10>)423 void Link::OnReadAfhChannelMapComplete(
424 hci::AfhMode afh_mode, std::array<uint8_t, 10> /* afh_channel_map */) {
425 log::info("UNIMPLEMENTED afh_mode:{}", hci::AfhModeText(afh_mode));
426 }
OnReadRssiComplete(uint8_t rssi)427 void Link::OnReadRssiComplete(uint8_t rssi) {
428 log::info("UNIMPLEMENTED rssi:{}", rssi);
429 }
OnReadClockComplete(uint32_t clock,uint16_t accuracy)430 void Link::OnReadClockComplete(uint32_t clock, uint16_t accuracy) {
431 log::info("UNIMPLEMENTED clock:{} accuracy:{}", clock, accuracy);
432 }
OnCentralLinkKeyComplete(hci::KeyFlag key_flag)433 void Link::OnCentralLinkKeyComplete(hci::KeyFlag key_flag) {
434 log::info("UNIMPLEMENTED key_flag:{}", hci::KeyFlagText(key_flag));
435 }
OnRoleChange(hci::ErrorCode hci_status,hci::Role new_role)436 void Link::OnRoleChange(hci::ErrorCode hci_status, hci::Role new_role) {
437 role_ = new_role;
438 link_manager_->OnRoleChange(hci_status, GetDevice().GetAddress(), new_role);
439 }
OnDisconnection(hci::ErrorCode reason)440 void Link::OnDisconnection(hci::ErrorCode reason) {
441 OnAclDisconnected(reason);
442 link_manager_->OnDisconnect(GetDevice().GetAddress(), reason);
443 }
OnReadRemoteVersionInformationComplete(hci::ErrorCode hci_status,uint8_t lmp_version,uint16_t manufacturer_name,uint16_t sub_version)444 void Link::OnReadRemoteVersionInformationComplete(
445 hci::ErrorCode hci_status, uint8_t lmp_version, uint16_t manufacturer_name, uint16_t sub_version) {
446 log::info(
447 "UNIMPLEMENTED hci_status:{} lmp_version:{} manufacturer_name:{} sub_version:{}",
448 ErrorCodeText(hci_status),
449 lmp_version,
450 manufacturer_name,
451 sub_version);
452 link_manager_->OnReadRemoteVersionInformation(
453 hci_status, GetDevice().GetAddress(), lmp_version, manufacturer_name, sub_version);
454 }
OnReadRemoteSupportedFeaturesComplete(uint64_t features)455 void Link::OnReadRemoteSupportedFeaturesComplete(uint64_t features) {
456 log::info(
457 "page_number:{} features:0x{:x}",
458 static_cast<uint8_t>(0),
459 static_cast<unsigned long>(features));
460 link_manager_->OnReadRemoteSupportedFeatures(GetDevice().GetAddress(), features);
461 }
462
OnReadRemoteExtendedFeaturesComplete(uint8_t page_number,uint8_t max_page_number,uint64_t features)463 void Link::OnReadRemoteExtendedFeaturesComplete(uint8_t page_number, uint8_t max_page_number, uint64_t features) {
464 log::info(
465 "page_number:{} max_page_number:{} features:0x{:x}",
466 page_number,
467 max_page_number,
468 static_cast<unsigned long>(features));
469 link_manager_->OnReadRemoteExtendedFeatures(GetDevice().GetAddress(), page_number, max_page_number, features);
470 }
471
AddEncryptionChangeListener(EncryptionChangeListener listener)472 void Link::AddEncryptionChangeListener(EncryptionChangeListener listener) {
473 encryption_change_listener_.push_back(listener);
474 }
475
OnPendingPacketChange(Cid,bool has_packet)476 void Link::OnPendingPacketChange(Cid /* local_cid */, bool has_packet) {
477 if (has_packet) {
478 remaining_packets_to_be_sent_++;
479 } else {
480 remaining_packets_to_be_sent_--;
481 }
482 if (link_manager_ != nullptr) {
483 link_manager_->OnPendingPacketChange(GetDevice().GetAddress(), remaining_packets_to_be_sent_);
484 }
485 }
486
487 } // namespace internal
488 } // namespace classic
489 } // namespace l2cap
490 } // namespace bluetooth
491