aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs')
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs219
1 files changed, 215 insertions, 4 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs b/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs
index 514e901e..a897b3f7 100644
--- a/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/ITimeServiceManager.cs
@@ -1,8 +1,219 @@
-namespace Ryujinx.HLE.HOS.Services.Time
+using Ryujinx.Common;
+using Ryujinx.HLE.Exceptions;
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Services.Time.Clock;
+using Ryujinx.HLE.Utilities;
+using System;
+using System.IO;
+using System.Text;
+
+namespace Ryujinx.HLE.HOS.Services.Time
{
- [Service("time:su")] // 9.0.0+
+ [Service("time:m")] // 9.0.0+
class ITimeServiceManager : IpcService
{
- public ITimeServiceManager(ServiceCtx context) { }
+ private TimeManager _timeManager;
+ private int _automaticCorrectionEvent;
+
+ public ITimeServiceManager(ServiceCtx context)
+ {
+ _timeManager = TimeManager.Instance;
+ _automaticCorrectionEvent = 0;
+ }
+
+ [Command(0)]
+ // GetUserStaticService() -> object<nn::timesrv::detail::service::IStaticService>
+ public ResultCode GetUserStaticService(ServiceCtx context)
+ {
+ MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.User));
+
+ return ResultCode.Success;
+ }
+
+ [Command(5)]
+ // GetAdminStaticService() -> object<nn::timesrv::detail::service::IStaticService>
+ public ResultCode GetAdminStaticService(ServiceCtx context)
+ {
+ MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Admin));
+
+ return ResultCode.Success;
+ }
+
+ [Command(6)]
+ // GetRepairStaticService() -> object<nn::timesrv::detail::service::IStaticService>
+ public ResultCode GetRepairStaticService(ServiceCtx context)
+ {
+ MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Repair));
+
+ return ResultCode.Success;
+ }
+
+ [Command(9)]
+ // GetManufactureStaticService() -> object<nn::timesrv::detail::service::IStaticService>
+ public ResultCode GetManufactureStaticService(ServiceCtx context)
+ {
+ MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Manufacture));
+
+ return ResultCode.Success;
+ }
+
+ [Command(10)]
+ // SetupStandardSteadyClock(nn::util::Uuid clock_source_id, nn::TimeSpanType setup_value, nn::TimeSpanType internal_offset, nn::TimeSpanType test_offset, bool is_rtc_reset_detected)
+ public ResultCode SetupStandardSteadyClock(ServiceCtx context)
+ {
+ UInt128 clockSourceId = context.RequestData.ReadStruct<UInt128>();
+ TimeSpanType setupValue = context.RequestData.ReadStruct<TimeSpanType>();
+ TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>();
+ TimeSpanType testOffset = context.RequestData.ReadStruct<TimeSpanType>();
+ bool isRtcResetDetected = context.RequestData.ReadBoolean();
+
+ _timeManager.SetupStandardSteadyClock(context.Thread, clockSourceId, setupValue, internalOffset, testOffset, isRtcResetDetected);
+
+ return ResultCode.Success;
+ }
+
+ [Command(11)]
+ // SetupStandardLocalSystemClock(nn::time::SystemClockContext context, nn::time::PosixTime posix_time)
+ public ResultCode SetupStandardLocalSystemClock(ServiceCtx context)
+ {
+ SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
+ long posixTime = context.RequestData.ReadInt64();
+
+ _timeManager.SetupStandardLocalSystemClock(context.Thread, clockContext, posixTime);
+
+ return ResultCode.Success;
+ }
+
+ [Command(12)]
+ // SetupStandardNetworkSystemClock(nn::time::SystemClockContext context, nn::TimeSpanType sufficient_accuracy)
+ public ResultCode SetupStandardNetworkSystemClock(ServiceCtx context)
+ {
+ SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
+ TimeSpanType sufficientAccuracy = context.RequestData.ReadStruct<TimeSpanType>();
+
+ _timeManager.SetupStandardNetworkSystemClock(clockContext, sufficientAccuracy);
+
+ return ResultCode.Success;
+ }
+
+ [Command(13)]
+ // SetupStandardUserSystemClock(bool automatic_correction_enabled, nn::time::SteadyClockTimePoint steady_clock_timepoint)
+ public ResultCode SetupStandardUserSystemClock(ServiceCtx context)
+ {
+ bool isAutomaticCorrectionEnabled = context.RequestData.ReadBoolean();
+
+ context.RequestData.BaseStream.Position += 7;
+
+ SteadyClockTimePoint steadyClockTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
+
+ _timeManager.SetupStandardUserSystemClock(context.Thread, isAutomaticCorrectionEnabled, steadyClockTimePoint);
+
+ return ResultCode.Success;
+ }
+
+ [Command(14)]
+ // SetupTimeZoneManager(nn::time::LocationName location_name, nn::time::SteadyClockTimePoint timezone_update_timepoint, u32 total_location_name_count, nn::time::TimeZoneRuleVersion timezone_rule_version, buffer<nn::time::TimeZoneBinary, 0x21> timezone_binary)
+ public ResultCode SetupTimeZoneManager(ServiceCtx context)
+ {
+ string locationName = Encoding.ASCII.GetString(context.RequestData.ReadBytes(0x24)).TrimEnd('\0');
+ SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
+ uint totalLocationNameCount = context.RequestData.ReadUInt32();
+ UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
+
+ (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21();
+
+ using (MemoryStream timeZoneBinaryStream = new MemoryStream(context.Memory.ReadBytes(bufferPosition, bufferSize)))
+ {
+ _timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
+ }
+
+ return ResultCode.Success;
+ }
+
+ [Command(15)]
+ // SetupEphemeralNetworkSystemClock()
+ public ResultCode SetupEphemeralNetworkSystemClock(ServiceCtx context)
+ {
+ _timeManager.SetupEphemeralNetworkSystemClock();
+
+ return ResultCode.Success;
+ }
+
+ [Command(50)]
+ // Unknown50() -> handle<copy>
+ public ResultCode Unknown50(ServiceCtx context)
+ {
+ // TODO: figure out the usage of this event
+ throw new ServiceNotImplementedException(context);
+ }
+
+ [Command(51)]
+ // Unknown51() -> handle<copy>
+ public ResultCode Unknown51(ServiceCtx context)
+ {
+ // TODO: figure out the usage of this event
+ throw new ServiceNotImplementedException(context);
+ }
+
+ [Command(52)]
+ // Unknown52() -> handle<copy>
+ public ResultCode Unknown52(ServiceCtx context)
+ {
+ // TODO: figure out the usage of this event
+ throw new ServiceNotImplementedException(context);
+ }
+
+ [Command(60)]
+ // GetStandardUserSystemClockAutomaticCorrectionEvent() -> handle<copy>
+ public ResultCode GetStandardUserSystemClockAutomaticCorrectionEvent(ServiceCtx context)
+ {
+ if (_automaticCorrectionEvent == 0)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_timeManager.StandardUserSystemClock.GetAutomaticCorrectionReadableEvent(), out _automaticCorrectionEvent) != KernelResult.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_automaticCorrectionEvent);
+
+ return ResultCode.Success;
+ }
+
+ [Command(100)]
+ // SetStandardSteadyClockRtcOffset(nn::TimeSpanType rtc_offset)
+ public ResultCode SetStandardSteadyClockRtcOffset(ServiceCtx context)
+ {
+ TimeSpanType rtcOffset = context.RequestData.ReadStruct<TimeSpanType>();
+
+ _timeManager.SetStandardSteadyClockRtcOffset(context.Thread, rtcOffset);
+
+ return ResultCode.Success;
+ }
+
+ [Command(200)]
+ // GetAlarmRegistrationEvent() -> handle<copy>
+ public ResultCode GetAlarmRegistrationEvent(ServiceCtx context)
+ {
+ // TODO
+ throw new ServiceNotImplementedException(context);
+ }
+
+ [Command(201)]
+ // UpdateSteadyAlarms()
+ public ResultCode UpdateSteadyAlarms(ServiceCtx context)
+ {
+ // TODO
+ throw new ServiceNotImplementedException(context);
+ }
+
+ [Command(202)]
+ // TryGetNextSteadyClockAlarmSnapshot() -> (bool, nn::time::SteadyClockAlarmSnapshot)
+ public ResultCode TryGetNextSteadyClockAlarmSnapshot(ServiceCtx context)
+ {
+ // TODO
+ throw new ServiceNotImplementedException(context);
+ }
}
-} \ No newline at end of file
+}