Loading system/gd/hci/acl_manager.cc +10 −7 Original line number Diff line number Diff line Loading @@ -1427,9 +1427,10 @@ struct AclManager::impl { } 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) { uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) { auto packet = LeConnectionUpdateBuilder::Create(handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kMinimumCeLength, kMaximumCeLength); supervision_timeout, min_ce_length, max_ce_length); hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); Loading Loading @@ -1869,8 +1870,9 @@ struct AclManager::impl { } 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) { uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { auto& connection = check_and_get_connection(handle); if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); Loading @@ -1889,7 +1891,7 @@ struct AclManager::impl { return false; } handler_->Post(BindOnce(&impl::handle_le_connection_update, common::Unretained(this), handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout)); conn_interval_max, conn_latency, supervision_timeout, min_ce_length, max_ce_length)); return true; } Loading Loading @@ -2074,10 +2076,11 @@ bool AclConnection::ReadClock(WhichClock which_clock) { } bool AclConnection::LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, 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); supervision_timeout, min_ce_length, max_ce_length, std::move(done_callback), handler); } void AclConnection::Finish() { Loading system/gd/hci/acl_manager.h +2 −2 Original line number Diff line number Diff line Loading @@ -149,8 +149,8 @@ class AclConnection { // 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); uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, 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 +1 −1 Original line number Diff line number Diff line Loading @@ -588,7 +588,7 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_update_success) std::promise<ErrorCode> promise; auto future = promise.get_future(); connection->LeConnectionUpdate( 0x0006, 0x0C80, 0x0000, 0x000A, 0x0006, 0x0C80, 0x0000, 0x000A, 0, 0, common::BindOnce([](std::promise<ErrorCode> promise, ErrorCode code) { promise.set_value(code); }, std::move(promise)), client_handler_); Loading system/gd/l2cap/le/internal/link.cc +25 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ namespace l2cap { namespace le { namespace internal { static constexpr uint16_t kDefaultMinimumCeLength = 0x0002; static constexpr uint16_t kDefaultMaximumCeLength = 0x0C00; Link::Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection, l2cap::internal::ParameterProvider* parameter_provider, DynamicChannelServiceManagerImpl* dynamic_service_manager, Loading @@ -55,14 +58,29 @@ 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) { // TODO: If we are slave and both only support legacy update connection parameter, use L2CAP void Link::UpdateConnectionParameterFromRemote(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, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kDefaultMinimumCeLength, kDefaultMaximumCeLength, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), signal_id), l2cap_handler_); } void Link::SendConnectionParameterUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) { if (acl_connection_->GetRole() == hci::Role::SLAVE) { // TODO: If both LL master and slave support 4.1, use HCI command directly signalling_manager_.SendConnectionParameterUpdateRequest(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout); return; } acl_connection_->LeConnectionUpdate( conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, min_ce_length, max_ce_length, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), kInvalidSignalId), 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, l2cap::internal::DataPipelineManager::ChannelMode::BASIC); Loading Loading @@ -135,12 +153,6 @@ std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateReservedDynam return channel; } DynamicChannelConfigurationOption Link::GetConfigurationForInitialConfiguration(Cid cid) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); return local_cid_to_pending_dynamic_channel_connection_map_[cid].configuration_; } void Link::FreeDynamicChannel(Cid cid) { if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) { return; Loading Loading @@ -195,6 +207,9 @@ void Link::SendLeCredit(Cid local_cid, uint16_t credit) { } void Link::on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code) { if (!signal_id.IsValid()) { return; } ConnectionParameterUpdateResponseResult result = (error_code == hci::ErrorCode::SUCCESS) ? ConnectionParameterUpdateResponseResult::ACCEPTED : ConnectionParameterUpdateResponseResult::REJECTED; Loading system/gd/l2cap/le/internal/link.h +10 −4 Original line number Diff line number Diff line Loading @@ -72,8 +72,13 @@ 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); virtual void UpdateConnectionParameterFromRemote(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout); virtual void SendConnectionParameterUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); // FixedChannel methods Loading @@ -98,8 +103,6 @@ class Link : public l2cap::internal::ILink { virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateReservedDynamicChannel( Cid reserved_cid, Psm psm, Cid remote_cid, SecurityPolicy security_policy); virtual 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 Loading Loading @@ -131,6 +134,9 @@ class Link : public l2cap::internal::ILink { os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); // Received connection update complete from ACL manager. SignalId is bound to a valid number when we need to send a // response to remote. If SignalId is bound to an invalid number, we don't send a response to remote, because the // connection update request is not from remote LL slave. void on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code); }; Loading Loading
system/gd/hci/acl_manager.cc +10 −7 Original line number Diff line number Diff line Loading @@ -1427,9 +1427,10 @@ struct AclManager::impl { } 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) { uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) { auto packet = LeConnectionUpdateBuilder::Create(handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kMinimumCeLength, kMaximumCeLength); supervision_timeout, min_ce_length, max_ce_length); hci_layer_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandStatusView status) { ASSERT(status.IsValid()); ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); Loading Loading @@ -1869,8 +1870,9 @@ struct AclManager::impl { } 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) { uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, common::OnceCallback<void(ErrorCode)> done_callback, os::Handler* handler) { auto& connection = check_and_get_connection(handle); if (connection.is_disconnected_) { LOG_INFO("Already disconnected"); Loading @@ -1889,7 +1891,7 @@ struct AclManager::impl { return false; } handler_->Post(BindOnce(&impl::handle_le_connection_update, common::Unretained(this), handle, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout)); conn_interval_max, conn_latency, supervision_timeout, min_ce_length, max_ce_length)); return true; } Loading Loading @@ -2074,10 +2076,11 @@ bool AclConnection::ReadClock(WhichClock which_clock) { } bool AclConnection::LeConnectionUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, 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); supervision_timeout, min_ce_length, max_ce_length, std::move(done_callback), handler); } void AclConnection::Finish() { Loading
system/gd/hci/acl_manager.h +2 −2 Original line number Diff line number Diff line Loading @@ -149,8 +149,8 @@ class AclConnection { // 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); uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length, 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 +1 −1 Original line number Diff line number Diff line Loading @@ -588,7 +588,7 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_update_success) std::promise<ErrorCode> promise; auto future = promise.get_future(); connection->LeConnectionUpdate( 0x0006, 0x0C80, 0x0000, 0x000A, 0x0006, 0x0C80, 0x0000, 0x000A, 0, 0, common::BindOnce([](std::promise<ErrorCode> promise, ErrorCode code) { promise.set_value(code); }, std::move(promise)), client_handler_); Loading
system/gd/l2cap/le/internal/link.cc +25 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ namespace l2cap { namespace le { namespace internal { static constexpr uint16_t kDefaultMinimumCeLength = 0x0002; static constexpr uint16_t kDefaultMaximumCeLength = 0x0C00; Link::Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection, l2cap::internal::ParameterProvider* parameter_provider, DynamicChannelServiceManagerImpl* dynamic_service_manager, Loading @@ -55,14 +58,29 @@ 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) { // TODO: If we are slave and both only support legacy update connection parameter, use L2CAP void Link::UpdateConnectionParameterFromRemote(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, conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, kDefaultMinimumCeLength, kDefaultMaximumCeLength, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), signal_id), l2cap_handler_); } void Link::SendConnectionParameterUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) { if (acl_connection_->GetRole() == hci::Role::SLAVE) { // TODO: If both LL master and slave support 4.1, use HCI command directly signalling_manager_.SendConnectionParameterUpdateRequest(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout); return; } acl_connection_->LeConnectionUpdate( conn_interval_min, conn_interval_max, conn_latency, supervision_timeout, min_ce_length, max_ce_length, common::BindOnce(&Link::on_connection_update_complete, common::Unretained(this), kInvalidSignalId), 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, l2cap::internal::DataPipelineManager::ChannelMode::BASIC); Loading Loading @@ -135,12 +153,6 @@ std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateReservedDynam return channel; } DynamicChannelConfigurationOption Link::GetConfigurationForInitialConfiguration(Cid cid) { ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()); return local_cid_to_pending_dynamic_channel_connection_map_[cid].configuration_; } void Link::FreeDynamicChannel(Cid cid) { if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) { return; Loading Loading @@ -195,6 +207,9 @@ void Link::SendLeCredit(Cid local_cid, uint16_t credit) { } void Link::on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code) { if (!signal_id.IsValid()) { return; } ConnectionParameterUpdateResponseResult result = (error_code == hci::ErrorCode::SUCCESS) ? ConnectionParameterUpdateResponseResult::ACCEPTED : ConnectionParameterUpdateResponseResult::REJECTED; Loading
system/gd/l2cap/le/internal/link.h +10 −4 Original line number Diff line number Diff line Loading @@ -72,8 +72,13 @@ 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); virtual void UpdateConnectionParameterFromRemote(SignalId signal_id, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout); virtual void SendConnectionParameterUpdate(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); // FixedChannel methods Loading @@ -98,8 +103,6 @@ class Link : public l2cap::internal::ILink { virtual std::shared_ptr<l2cap::internal::DynamicChannelImpl> AllocateReservedDynamicChannel( Cid reserved_cid, Psm psm, Cid remote_cid, SecurityPolicy security_policy); virtual 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 Loading Loading @@ -131,6 +134,9 @@ class Link : public l2cap::internal::ILink { os::Alarm link_idle_disconnect_alarm_{l2cap_handler_}; DISALLOW_COPY_AND_ASSIGN(Link); // Received connection update complete from ACL manager. SignalId is bound to a valid number when we need to send a // response to remote. If SignalId is bound to an invalid number, we don't send a response to remote, because the // connection update request is not from remote LL slave. void on_connection_update_complete(SignalId signal_id, hci::ErrorCode error_code); }; Loading