예제 #1
0
        [CommandHipc(300)] // 4.0.0+
        // CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> s64
        public ResultCode CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context)
        {
            SteadyClockCore steadyClock = _timeManager.StandardSteadyClock;

            if (!steadyClock.IsInitialized())
            {
                return(ResultCode.UninitializedClock);
            }

            ITickSource tickSource = context.Device.System.TickSource;

            SystemClockContext   otherContext     = context.RequestData.ReadStruct <SystemClockContext>();
            SteadyClockTimePoint currentTimePoint = steadyClock.GetCurrentTimePoint(tickSource);

            ResultCode result = ResultCode.TimeMismatch;

            if (currentTimePoint.ClockSourceId == otherContext.SteadyTimePoint.ClockSourceId)
            {
                TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
                long         baseTimePoint = otherContext.Offset + currentTimePoint.TimePoint - ticksTimeSpan.ToSeconds();

                context.ResponseData.Write(baseTimePoint);

                result = ResultCode.Success;
            }

            return(result);
        }
예제 #2
0
        // SetCurrentTime(nn::time::PosixTime)
        public ResultCode SetCurrentTime(ServiceCtx context)
        {
            if (!_writePermission)
            {
                return(ResultCode.PermissionDenied);
            }

            long                 posixTime        = context.RequestData.ReadInt64();
            SteadyClockCore      steadyClockCore  = _clockCore.GetSteadyClockCore();
            SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(context.Thread);

            SystemClockContext clockContext = new SystemClockContext()
            {
                Offset          = posixTime - currentTimePoint.TimePoint,
                SteadyTimePoint = currentTimePoint
            };

            ResultCode result = _clockCore.SetSystemClockContext(clockContext);

            if (result == ResultCode.Success)
            {
                result = _clockCore.Flush(clockContext);
            }

            return(result);
        }
예제 #3
0
        // 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);
        }
예제 #4
0
        // 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);
        }
예제 #5
0
        public void SetupStandardNetworkSystemClock(SystemClockContext clockContext, TimeSpanType sufficientAccuracy)
        {
            StandardNetworkSystemClock.SetUpdateCallbackInstance(NetworkClockContextWriter);

            if (StandardNetworkSystemClock.SetSystemClockContext(clockContext) != ResultCode.Success)
            {
                throw new InternalServiceException("Cannot set network SystemClockContext");
            }

            StandardNetworkSystemClock.SetStandardNetworkClockSufficientAccuracy(sufficientAccuracy);
            StandardNetworkSystemClock.MarkInitialized();

            // TODO: propagate IPC late binding of "time:s" and "time:p"
        }
예제 #6
0
        [Command(401)] // 4.0.0+
        // GetClockSnapshotFromSystemClockContext(u8, nn::time::SystemClockContext, nn::time::SystemClockContext) -> buffer<nn::time::sf::ClockSnapshot, 0x1a>
        public ResultCode GetClockSnapshotFromSystemClockContext(ServiceCtx context)
        {
            byte type = context.RequestData.ReadByte();

            context.RequestData.BaseStream.Position += 7;

            SystemClockContext userContext    = context.RequestData.ReadStruct <SystemClockContext>();
            SystemClockContext networkContext = context.RequestData.ReadStruct <SystemClockContext>();

            ResultCode result = GetClockSnapshotFromSystemClockContextInternal(context.Thread, userContext, networkContext, type, out ClockSnapshot clockSnapshot);

            if (result == ResultCode.Success)
            {
                WriteClockSnapshotFromBuffer(context, context.Request.RecvListBuff[0], clockSnapshot);
            }

            return(result);
        }
예제 #7
0
        // SetClockContext(nn::time::SystemClockContext)
        public ResultCode SetSystemClockContext(ServiceCtx context)
        {
            if (!_writePermission)
            {
                return(ResultCode.PermissionDenied);
            }

            if (!_bypassUninitializedClock && !_clockCore.IsInitialized())
            {
                return(ResultCode.UninitializedClock);
            }

            SystemClockContext clockContext = context.RequestData.ReadStruct <SystemClockContext>();

            ResultCode result = _clockCore.SetSystemClockContext(clockContext);

            return(result);
        }
예제 #8
0
        // SetSystemClockContext(nn::time::SystemClockContext)
        public ResultCode SetSystemClockContext(ServiceCtx context)
        {
            if (!_writePermission)
            {
                return(ResultCode.PermissionDenied);
            }

            SystemClockContext clockContext = context.RequestData.ReadStruct <SystemClockContext>();

            ResultCode result = _clockCore.SetSystemClockContext(clockContext);

            if (result == ResultCode.Success)
            {
                result = _clockCore.Flush(clockContext);
            }

            return(result);
        }
예제 #9
0
        [Command(300)] // 4.0.0+
        // CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> s64
        public ResultCode CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context)
        {
            SystemClockContext   otherContext     = context.RequestData.ReadStruct <SystemClockContext>();
            SteadyClockTimePoint currentTimePoint = StandardSteadyClockCore.Instance.GetCurrentTimePoint(context.Thread);

            ResultCode result = ResultCode.TimeMismatch;

            if (currentTimePoint.ClockSourceId == otherContext.SteadyTimePoint.ClockSourceId)
            {
                TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(context.Thread.Context.CntpctEl0, context.Thread.Context.CntfrqEl0);
                long         baseTimePoint = otherContext.Offset + currentTimePoint.TimePoint - ticksTimeSpan.ToSeconds();

                context.ResponseData.Write(baseTimePoint);

                result = 0;
            }

            return(result);
        }
예제 #10
0
        public void SetupStandardLocalSystemClock(KThread thread, SystemClockContext clockContext, long posixTime)
        {
            StandardLocalSystemClock.SetUpdateCallbackInstance(LocalClockContextWriter);

            SteadyClockTimePoint currentTimePoint = StandardLocalSystemClock.GetSteadyClockCore().GetCurrentTimePoint(thread);

            if (currentTimePoint.ClockSourceId == clockContext.SteadyTimePoint.ClockSourceId)
            {
                StandardLocalSystemClock.SetSystemClockContext(clockContext);
            }
            else
            {
                if (StandardLocalSystemClock.SetCurrentTime(thread, posixTime) != ResultCode.Success)
                {
                    throw new InternalServiceException("Cannot set current local time");
                }
            }

            StandardLocalSystemClock.MarkInitialized();

            // TODO: propagate IPC late binding of "time:s" and "time:p"
        }
예제 #11
0
        [CommandHipc(401)] // 4.0.0+
        // GetClockSnapshotFromSystemClockContext(u8, nn::time::SystemClockContext, nn::time::SystemClockContext) -> buffer<nn::time::sf::ClockSnapshot, 0x1a>
        public ResultCode GetClockSnapshotFromSystemClockContext(ServiceCtx context)
        {
            byte type = context.RequestData.ReadByte();

            context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf <ClockSnapshot>());

            context.RequestData.BaseStream.Position += 7;

            SystemClockContext userContext    = context.RequestData.ReadStruct <SystemClockContext>();
            SystemClockContext networkContext = context.RequestData.ReadStruct <SystemClockContext>();

            ITickSource tickSource = context.Device.System.TickSource;

            ResultCode result = GetClockSnapshotFromSystemClockContextInternal(tickSource, userContext, networkContext, type, out ClockSnapshot clockSnapshot);

            if (result == ResultCode.Success)
            {
                WriteClockSnapshotFromBuffer(context, context.Request.RecvListBuff[0], clockSnapshot);
            }

            return(result);
        }
예제 #12
0
        private ResultCode GetClockSnapshotFromSystemClockContextInternal(ITickSource tickSource, SystemClockContext userContext, SystemClockContext networkContext, byte type, out ClockSnapshot clockSnapshot)
        {
            clockSnapshot = new ClockSnapshot();

            SteadyClockCore      steadyClockCore  = _timeManager.StandardSteadyClock;
            SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(tickSource);

            clockSnapshot.IsAutomaticCorrectionEnabled = _timeManager.StandardUserSystemClock.IsAutomaticCorrectionEnabled();
            clockSnapshot.UserContext          = userContext;
            clockSnapshot.NetworkContext       = networkContext;
            clockSnapshot.SteadyClockTimePoint = currentTimePoint;

            ResultCode result = _timeManager.TimeZone.Manager.GetDeviceLocationName(out string deviceLocationName);

            if (result != ResultCode.Success)
            {
                return(result);
            }

            char[] tzName       = deviceLocationName.ToCharArray();
            char[] locationName = new char[0x24];

            Array.Copy(tzName, locationName, tzName.Length);

            clockSnapshot.LocationName = locationName;

            result = ClockSnapshot.GetCurrentTime(out clockSnapshot.UserTime, currentTimePoint, clockSnapshot.UserContext);

            if (result == ResultCode.Success)
            {
                result = _timeManager.TimeZone.Manager.ToCalendarTimeWithMyRules(clockSnapshot.UserTime, out CalendarInfo userCalendarInfo);

                if (result == ResultCode.Success)
                {
                    clockSnapshot.UserCalendarTime           = userCalendarInfo.Time;
                    clockSnapshot.UserCalendarAdditionalTime = userCalendarInfo.AdditionalInfo;

                    if (ClockSnapshot.GetCurrentTime(out clockSnapshot.NetworkTime, currentTimePoint, clockSnapshot.NetworkContext) != ResultCode.Success)
                    {
                        clockSnapshot.NetworkTime = 0;
                    }

                    result = _timeManager.TimeZone.Manager.ToCalendarTimeWithMyRules(clockSnapshot.NetworkTime, out CalendarInfo networkCalendarInfo);

                    if (result == ResultCode.Success)
                    {
                        clockSnapshot.NetworkCalendarTime           = networkCalendarInfo.Time;
                        clockSnapshot.NetworkCalendarAdditionalTime = networkCalendarInfo.AdditionalInfo;
                        clockSnapshot.Type = type;

                        // Probably a version field?
                        clockSnapshot.Unknown = 0;
                    }
                }
            }

            return(result);
        }
예제 #13
0
 public void UpdateNetworkSystemClockContext(SystemClockContext context)
 {
     WriteObjectToSharedMemory(NetworkSystemClockContextOffset, 4, context);
 }
예제 #14
0
 public void UpdateLocalSystemClockContext(SystemClockContext context)
 {
     WriteObjectToSharedMemory(LocalSystemClockContextOffset, 4, context);
 }
예제 #15
0
        public override ResultCode Flush(SystemClockContext context)
        {
            // TODO: set:sys SetUserSystemClockContext

            return(ResultCode.Success);
        }
예제 #16
0
 public override ResultCode Flush(SystemClockContext context)
 {
     return(ResultCode.Success);
 }