Loading system/gd/hci/acl_manager.cc +81 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ struct AclManager::acl_connection { os::Handler* disconnect_handler_ = nullptr; ConnectionManagementCallbacks* command_complete_callbacks_; common::OnceCallback<void(ErrorCode)> on_disconnect_callback_; // For LE Connection parameter update from L2CAP common::OnceCallback<void(ErrorCode)> on_connection_update_complete_callback_; os::Handler* on_connection_update_complete_callback_handler_ = nullptr; // Round-robin: Track if dequeue is registered for this connection bool is_registered_ = false; // Credits: Track the number of packets which have been sent to the controller Loading Loading @@ -84,6 +87,9 @@ struct AclManager::impl { hci_layer_->RegisterLeEventHandler(SubeventCode::ENHANCED_CONNECTION_COMPLETE, Bind(&impl::on_le_enhanced_connection_complete, common::Unretained(this)), handler_); hci_layer_->RegisterLeEventHandler(SubeventCode::CONNECTION_UPDATE_COMPLETE, Bind(&impl::on_le_connection_update_complete, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(EventCode::CONNECTION_PACKET_TYPE_CHANGED, Bind(&impl::on_connection_packet_type_changed, common::Unretained(this)), handler_); Loading Loading @@ -864,6 +870,34 @@ struct AclManager::impl { } } void on_le_connection_update_complete(LeMetaEventView view) { auto complete_view = LeConnectionUpdateCompleteView::Create(view); if (!complete_view.IsValid()) { LOG_ERROR("Received on_le_connection_update_complete with invalid packet"); return; } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { auto status = complete_view.GetStatus(); std::string error_code = ErrorCodeText(status); LOG_ERROR("Received on_le_connection_update_complete with error code %s", error_code.c_str()); return; } auto handle = complete_view.GetConnectionHandle(); if (acl_connections_.find(handle) == acl_connections_.end()) { LOG_WARN("Can't find connection"); return; } auto& connection = acl_connections_.find(handle)->second; if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); return; } if (!connection.on_connection_update_complete_callback_.is_null()) { connection.on_connection_update_complete_callback_handler_->Post( common::BindOnce(std::move(connection.on_connection_update_complete_callback_), complete_view.GetStatus())); connection.on_connection_update_complete_callback_handler_ = nullptr; } } bool is_classic_link_already_connected(Address address) { for (const auto& connection : acl_connections_) { if (connection.second.address_with_type_.GetAddress() == address) { Loading Loading @@ -911,8 +945,6 @@ struct AclManager::impl { uint16_t conn_interval_max = 0x0C00; uint16_t conn_latency = 0x0C0; uint16_t supervision_timeout = 0x0C00; uint16_t minimum_ce_length = 0x0002; uint16_t maximum_ce_length = 0x0C00; ASSERT(le_client_callbacks_ != nullptr); connecting_le_.insert(address_with_type); Loading @@ -921,7 +953,7 @@ struct AclManager::impl { LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy, address_with_type.GetAddressType(), address_with_type.GetAddress(), own_address_type, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, minimum_ce_length, maximum_ce_length), supervision_timeout, kMinimumCeLength, kMaximumCeLength), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); Loading Loading @@ -1188,6 +1220,17 @@ struct AclManager::impl { common::BindOnce(&impl::on_read_clock_complete, common::Unretained(this)), handler_); } void handle_le_connection_update(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { auto packet = LeConnectionUpdateBuilder::Create(handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kMinimumCeLength, kMaximumCeLength); hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); }), handler_); } template <class T> void check_command_complete(CommandCompleteView view) { ASSERT(view.IsValid()); Loading Loading @@ -1574,6 +1617,31 @@ struct AclManager::impl { return true; } bool LeConnectionUpdate(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { auto& connection = check_and_get_connection(handle); if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); return false; } if (!connection.on_connection_update_complete_callback_.is_null()) { LOG_INFO("There is another pending connection update"); return false; } connection.on_connection_update_complete_callback_ = std::move(done_callback); connection.on_connection_update_complete_callback_handler_ = handler; if (conn_interval_min < 0x0006 || conn_interval_min > 0x0C80 || conn_interval_max < 0x0006 || conn_interval_max > 0x0C80 || conn_latency > 0x01F3 || supervision_timeout < 0x000A || supervision_timeout > 0x0C80) { LOG_ERROR("Invalid parameter"); return false; } handler_->Post(BindOnce(&impl::handle_le_connection_update, common::Unretained(this), handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout)); return true; } void Finish(uint16_t handle) { auto& connection = check_and_get_connection(handle); ASSERT_LOG(connection.is_disconnected_, "Finish must be invoked after disconnection (handle 0x%04hx)", handle); Loading @@ -1582,6 +1650,9 @@ struct AclManager::impl { const AclManager& acl_manager_; static constexpr uint16_t kMinimumCeLength = 0x0002; static constexpr uint16_t kMaximumCeLength = 0x0C00; Controller* controller_ = nullptr; uint16_t max_acl_packet_credits_ = 0; uint16_t acl_packet_credits_ = 0; Loading Loading @@ -1732,6 +1803,13 @@ bool AclConnection::ReadClock(WhichClock which_clock) { return manager_->pimpl_->ReadClock(handle_, which_clock); } bool AclConnection::LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { return manager_->pimpl_->LeConnectionUpdate(handle_, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, std::move(done_callback), handler); } void AclConnection::Finish() { return manager_->pimpl_->Finish(handle_); } Loading system/gd/hci/acl_manager.h +5 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,11 @@ class AclConnection { virtual bool ReadRssi(); virtual bool ReadClock(WhichClock which_clock); // LE ACL Method virtual bool LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler); // Ask AclManager to clean me up. Must invoke after on_disconnect is called virtual void Finish(); Loading system/gd/hci/acl_manager_test.cc +39 −0 Original line number Diff line number Diff line Loading @@ -537,6 +537,45 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) { 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_update_success) { AddressWithType remote_with_type(remote, AddressType::PUBLIC_DEVICE_ADDRESS); test_hci_layer_->SetCommandFuture(); acl_manager_->CreateLeConnection(remote_with_type); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); test_hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); auto first_connection = GetLeConnectionFuture(); test_hci_layer_->IncomingLeMetaEvent( LeConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); auto first_connection_status = first_connection.wait_for(kTimeout); ASSERT_EQ(first_connection_status, std::future_status::ready); std::shared_ptr<AclConnection> connection = GetLastLeConnection(); ASSERT_EQ(connection->GetAddress(), remote); std::promise<ErrorCode> promise; auto future = promise.get_future(); connection->LeConnectionUpdate( 0x0006, 0x0C80, 0x0000, 0x000A, common::BindOnce([](std::promise<ErrorCode> promise, ErrorCode code) { promise.set_value(code); }, std::move(promise)), client_handler_); test_hci_layer_->IncomingLeMetaEvent( LeConnectionUpdateCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, 0x0006, 0x0000, 0x000A)); EXPECT_EQ(future.wait_for(std::chrono::milliseconds(3)), std::future_status::ready); EXPECT_EQ(future.get(), ErrorCode::SUCCESS); } TEST_F(AclManagerTest, invoke_registered_callback_disconnection_complete) { uint16_t handle = 0x123; Loading system/gd/l2cap/le/internal/link.cc +14 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,13 @@ void Link::Disconnect() { acl_connection_->Disconnect(hci::DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION); } void Link::UpdateConnectionParameter(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { acl_connection_->LeConnectionUpdate( conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), signal_id), l2cap_handler_); } std::shared_ptr<FixedChannelImpl> Link::AllocateFixedChannel(Cid cid, SecurityPolicy security_policy) { auto channel = fixed_channel_allocator_.AllocateChannel(cid, security_policy); data_pipeline_manager_.AttachChannel(cid, channel, Loading Loading @@ -172,11 +179,17 @@ uint16_t Link::GetInitialCredit() const { return parameter_provider_->GetLeInitialCredit(); } void Link::SendLeCredit(Cid local_cid, uint16_t credit) { signalling_manager_.SendCredit(local_cid, credit); } void Link::on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code) { ConnectionParameterUpdateResponseResult result = (error_code == hci::ErrorCode::SUCCESS) ? ConnectionParameterUpdateResponseResult::ACCEPTED : ConnectionParameterUpdateResponseResult::REJECTED; signalling_manager_.SendConnectionParameterUpdateResponse(SignalId(), result); } } // namespace internal } // namespace le } // namespace l2cap Loading system/gd/l2cap/le/internal/link.h +6 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,10 @@ class Link : public l2cap::internal::ILink { virtual void Disconnect(); // Handles connection parameter update request from remote virtual void UpdateConnectionParameter(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout); // FixedChannel methods virtual std::shared_ptr<FixedChannelImpl> AllocateFixedChannel(Cid cid, SecurityPolicy security_policy); Loading Loading @@ -122,6 +126,8 @@ class Link : public l2cap::internal::ILink { std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_; os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); void on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code); }; } // namespace internal Loading Loading
system/gd/hci/acl_manager.cc +81 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ struct AclManager::acl_connection { os::Handler* disconnect_handler_ = nullptr; ConnectionManagementCallbacks* command_complete_callbacks_; common::OnceCallback<void(ErrorCode)> on_disconnect_callback_; // For LE Connection parameter update from L2CAP common::OnceCallback<void(ErrorCode)> on_connection_update_complete_callback_; os::Handler* on_connection_update_complete_callback_handler_ = nullptr; // Round-robin: Track if dequeue is registered for this connection bool is_registered_ = false; // Credits: Track the number of packets which have been sent to the controller Loading Loading @@ -84,6 +87,9 @@ struct AclManager::impl { hci_layer_->RegisterLeEventHandler(SubeventCode::ENHANCED_CONNECTION_COMPLETE, Bind(&impl::on_le_enhanced_connection_complete, common::Unretained(this)), handler_); hci_layer_->RegisterLeEventHandler(SubeventCode::CONNECTION_UPDATE_COMPLETE, Bind(&impl::on_le_connection_update_complete, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(EventCode::CONNECTION_PACKET_TYPE_CHANGED, Bind(&impl::on_connection_packet_type_changed, common::Unretained(this)), handler_); Loading Loading @@ -864,6 +870,34 @@ struct AclManager::impl { } } void on_le_connection_update_complete(LeMetaEventView view) { auto complete_view = LeConnectionUpdateCompleteView::Create(view); if (!complete_view.IsValid()) { LOG_ERROR("Received on_le_connection_update_complete with invalid packet"); return; } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { auto status = complete_view.GetStatus(); std::string error_code = ErrorCodeText(status); LOG_ERROR("Received on_le_connection_update_complete with error code %s", error_code.c_str()); return; } auto handle = complete_view.GetConnectionHandle(); if (acl_connections_.find(handle) == acl_connections_.end()) { LOG_WARN("Can't find connection"); return; } auto& connection = acl_connections_.find(handle)->second; if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); return; } if (!connection.on_connection_update_complete_callback_.is_null()) { connection.on_connection_update_complete_callback_handler_->Post( common::BindOnce(std::move(connection.on_connection_update_complete_callback_), complete_view.GetStatus())); connection.on_connection_update_complete_callback_handler_ = nullptr; } } bool is_classic_link_already_connected(Address address) { for (const auto& connection : acl_connections_) { if (connection.second.address_with_type_.GetAddress() == address) { Loading Loading @@ -911,8 +945,6 @@ struct AclManager::impl { uint16_t conn_interval_max = 0x0C00; uint16_t conn_latency = 0x0C0; uint16_t supervision_timeout = 0x0C00; uint16_t minimum_ce_length = 0x0002; uint16_t maximum_ce_length = 0x0C00; ASSERT(le_client_callbacks_ != nullptr); connecting_le_.insert(address_with_type); Loading @@ -921,7 +953,7 @@ struct AclManager::impl { LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy, address_with_type.GetAddressType(), address_with_type.GetAddress(), own_address_type, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, minimum_ce_length, maximum_ce_length), supervision_timeout, kMinimumCeLength, kMaximumCeLength), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); Loading Loading @@ -1188,6 +1220,17 @@ struct AclManager::impl { common::BindOnce(&impl::on_read_clock_complete, common::Unretained(this)), handler_); } void handle_le_connection_update(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { auto packet = LeConnectionUpdateBuilder::Create(handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kMinimumCeLength, kMaximumCeLength); hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); }), handler_); } template <class T> void check_command_complete(CommandCompleteView view) { ASSERT(view.IsValid()); Loading Loading @@ -1574,6 +1617,31 @@ struct AclManager::impl { return true; } bool LeConnectionUpdate(uint16_t handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { auto& connection = check_and_get_connection(handle); if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); return false; } if (!connection.on_connection_update_complete_callback_.is_null()) { LOG_INFO("There is another pending connection update"); return false; } connection.on_connection_update_complete_callback_ = std::move(done_callback); connection.on_connection_update_complete_callback_handler_ = handler; if (conn_interval_min < 0x0006 || conn_interval_min > 0x0C80 || conn_interval_max < 0x0006 || conn_interval_max > 0x0C80 || conn_latency > 0x01F3 || supervision_timeout < 0x000A || supervision_timeout > 0x0C80) { LOG_ERROR("Invalid parameter"); return false; } handler_->Post(BindOnce(&impl::handle_le_connection_update, common::Unretained(this), handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout)); return true; } void Finish(uint16_t handle) { auto& connection = check_and_get_connection(handle); ASSERT_LOG(connection.is_disconnected_, "Finish must be invoked after disconnection (handle 0x%04hx)", handle); Loading @@ -1582,6 +1650,9 @@ struct AclManager::impl { const AclManager& acl_manager_; static constexpr uint16_t kMinimumCeLength = 0x0002; static constexpr uint16_t kMaximumCeLength = 0x0C00; Controller* controller_ = nullptr; uint16_t max_acl_packet_credits_ = 0; uint16_t acl_packet_credits_ = 0; Loading Loading @@ -1732,6 +1803,13 @@ bool AclConnection::ReadClock(WhichClock which_clock) { return manager_->pimpl_->ReadClock(handle_, which_clock); } bool AclConnection::LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { return manager_->pimpl_->LeConnectionUpdate(handle_, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, std::move(done_callback), handler); } void AclConnection::Finish() { return manager_->pimpl_->Finish(handle_); } Loading
system/gd/hci/acl_manager.h +5 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,11 @@ class AclConnection { virtual bool ReadRssi(); virtual bool ReadClock(WhichClock which_clock); // LE ACL Method virtual bool LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler); // Ask AclManager to clean me up. Must invoke after on_disconnect is called virtual void Finish(); Loading
system/gd/hci/acl_manager_test.cc +39 −0 Original line number Diff line number Diff line Loading @@ -537,6 +537,45 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) { 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); } TEST_F(AclManagerTest, invoke_registered_callback_le_connection_update_success) { AddressWithType remote_with_type(remote, AddressType::PUBLIC_DEVICE_ADDRESS); test_hci_layer_->SetCommandFuture(); acl_manager_->CreateLeConnection(remote_with_type); auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(packet); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT(command_view.IsValid()); EXPECT_EQ(command_view.GetPeerAddress(), remote); EXPECT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); test_hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); auto first_connection = GetLeConnectionFuture(); test_hci_layer_->IncomingLeMetaEvent( LeConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, Role::SLAVE, AddressType::PUBLIC_DEVICE_ADDRESS, remote, 0x0100, 0x0010, 0x0011, MasterClockAccuracy::PPM_30)); auto first_connection_status = first_connection.wait_for(kTimeout); ASSERT_EQ(first_connection_status, std::future_status::ready); std::shared_ptr<AclConnection> connection = GetLastLeConnection(); ASSERT_EQ(connection->GetAddress(), remote); std::promise<ErrorCode> promise; auto future = promise.get_future(); connection->LeConnectionUpdate( 0x0006, 0x0C80, 0x0000, 0x000A, common::BindOnce([](std::promise<ErrorCode> promise, ErrorCode code) { promise.set_value(code); }, std::move(promise)), client_handler_); test_hci_layer_->IncomingLeMetaEvent( LeConnectionUpdateCompleteBuilder::Create(ErrorCode::SUCCESS, 0x123, 0x0006, 0x0000, 0x000A)); EXPECT_EQ(future.wait_for(std::chrono::milliseconds(3)), std::future_status::ready); EXPECT_EQ(future.get(), ErrorCode::SUCCESS); } TEST_F(AclManagerTest, invoke_registered_callback_disconnection_complete) { uint16_t handle = 0x123; Loading
system/gd/l2cap/le/internal/link.cc +14 −1 Original line number Diff line number Diff line Loading @@ -55,6 +55,13 @@ void Link::Disconnect() { acl_connection_->Disconnect(hci::DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION); } void Link::UpdateConnectionParameter(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { acl_connection_->LeConnectionUpdate( conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), signal_id), l2cap_handler_); } std::shared_ptr<FixedChannelImpl> Link::AllocateFixedChannel(Cid cid, SecurityPolicy security_policy) { auto channel = fixed_channel_allocator_.AllocateChannel(cid, security_policy); data_pipeline_manager_.AttachChannel(cid, channel, Loading Loading @@ -172,11 +179,17 @@ uint16_t Link::GetInitialCredit() const { return parameter_provider_->GetLeInitialCredit(); } void Link::SendLeCredit(Cid local_cid, uint16_t credit) { signalling_manager_.SendCredit(local_cid, credit); } void Link::on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code) { ConnectionParameterUpdateResponseResult result = (error_code == hci::ErrorCode::SUCCESS) ? ConnectionParameterUpdateResponseResult::ACCEPTED : ConnectionParameterUpdateResponseResult::REJECTED; signalling_manager_.SendConnectionParameterUpdateResponse(SignalId(), result); } } // namespace internal } // namespace le } // namespace l2cap Loading
system/gd/l2cap/le/internal/link.h +6 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,10 @@ class Link : public l2cap::internal::ILink { virtual void Disconnect(); // Handles connection parameter update request from remote virtual void UpdateConnectionParameter(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout); // FixedChannel methods virtual std::shared_ptr<FixedChannelImpl> AllocateFixedChannel(Cid cid, SecurityPolicy security_policy); Loading Loading @@ -122,6 +126,8 @@ class Link : public l2cap::internal::ILink { std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_; os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); void on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code); }; } // namespace internal Loading