diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index f2ef3ec5387db1ec9560c743aa7e11e02330f051..3d5b0ff1ea92ab37cf9335c4c76ddb72c329ba58 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h @@ -4,6 +4,8 @@ #pragma once +#include <boost/safe_numerics/safe_integer.hpp> + #include "common/common_funcs.h" #include "common/common_types.h" #include "common/uuid.h" @@ -17,6 +19,24 @@ struct SteadyClockTimePoint { s64 time_point; Common::UUID clock_source_id; + ResultCode GetSpanBetween(SteadyClockTimePoint other, s64& span) const { + span = 0; + + if (clock_source_id != other.clock_source_id) { + return ERROR_TIME_MISMATCH; + } + + const boost::safe_numerics::safe<s64> this_time_point{time_point}; + const boost::safe_numerics::safe<s64> other_time_point{other.time_point}; + try { + span = other_time_point - this_time_point; + } catch (const std::exception&) { + return ERROR_OVERFLOW; + } + + return RESULT_SUCCESS; + } + static SteadyClockTimePoint GetRandom() { return {0, Common::UUID::Generate()}; } diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index b1307a434d1de00ebd4fb8cbe12f5fb6eb1a3427..0bc90b1838de3c98e264046d96ff24604da414b0 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp @@ -24,7 +24,7 @@ Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* nam {100, nullptr, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, {101, nullptr, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, {102, nullptr, "GetStandardUserSystemClockInitialYear"}, - {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, + {200, &Time::IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"}, {201, nullptr, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, diff --git a/src/core/hle/service/time/standard_network_system_clock_core.h b/src/core/hle/service/time/standard_network_system_clock_core.h index 46728516082efd5e10bfefe446da4e8dbfcaf5bf..3f505c37c0dd824e6dde3ab725b3e0c0b079b642 100644 --- a/src/core/hle/service/time/standard_network_system_clock_core.h +++ b/src/core/hle/service/time/standard_network_system_clock_core.h @@ -8,6 +8,10 @@ #include "core/hle/service/time/steady_clock_core.h" #include "core/hle/service/time/system_clock_core.h" +namespace Core { +class System; +} + namespace Service::Time::Clock { class StandardNetworkSystemClockCore final : public SystemClockCore { @@ -19,6 +23,22 @@ public: standard_network_clock_sufficient_accuracy = value; } + bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) { + SystemClockContext context{}; + if (GetClockContext(system, context) != RESULT_SUCCESS) { + return {}; + } + + s64 span{}; + if (context.steady_time_point.GetSpanBetween( + GetSteadyClockCore().GetCurrentTimePoint(system), span) != RESULT_SUCCESS) { + return {}; + } + + return TimeSpanType{span}.nanoseconds < + standard_network_clock_sufficient_accuracy.nanoseconds; + } + private: TimeSpanType standard_network_clock_sufficient_accuracy{}; }; diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 970aed0bbbd9dfda90ddf99f8de1c821bc7f8f74..2053fa0789580f2a8ccb51461f0a867745af439d 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -199,6 +199,15 @@ void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager()); } +void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( + Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()}; + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); +} + void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 7b77ac7ea9dabdf931f8be1d80536311db86951f..0b3cda6aa38ae3a77cc7b851ff5dc4c815656691 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -27,6 +27,7 @@ public: void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx); void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); void GetTimeZoneService(Kernel::HLERequestContext& ctx); + void IsStandardNetworkSystemClockAccuracySufficient(Kernel::HLERequestContext& ctx); void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); void GetClockSnapshot(Kernel::HLERequestContext& ctx); void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);