aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2022-03-15 04:07:07 +0100
committerGitHub <noreply@github.com>2022-03-15 04:07:07 +0100
commite2ffa5a125fcbe8a25c73d8e04c08c08ef378860 (patch)
tree3a43fe53fbd015f3c60caf0e27fc9364ea2d8e41
parent73feac5819903bbc16ebb3b4a47b5734d5699492 (diff)
ntc: Implement IEnsureNetworkClockAvailabilityService (#3192)1.1.76
* ntc: Implement IEnsureNetworkClockAvailabilityService This PR implement a basic `IEnsureNetworkClockAvailabilityService` checked by RE. It's needed by Splatoon 2 with Guest Internet Access enabled. Game is now playable with this setting. * Update Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com>
-rw-r--r--Ryujinx.Common/Logging/LogClass.cs1
-rw-r--r--Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs18
-rw-r--r--Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs77
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/ResultCode.cs24
4 files changed, 108 insertions, 12 deletions
diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs
index a7d36765..20c8da3f 100644
--- a/Ryujinx.Common/Logging/LogClass.cs
+++ b/Ryujinx.Common/Logging/LogClass.cs
@@ -47,6 +47,7 @@ namespace Ryujinx.Common.Logging
ServiceNim,
ServiceNs,
ServiceNsd,
+ ServiceNtc,
ServiceNv,
ServiceOlsc,
ServicePctl,
diff --git a/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs b/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs
index f5a3bc7b..1a4100ee 100644
--- a/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs
+++ b/Ryujinx.HLE/HOS/Services/Nim/Ntc/IStaticService.cs
@@ -1,8 +1,24 @@
-namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService;
+
+namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
{
[Service("ntc")]
class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }
+
+ [CommandHipc(0)]
+ // OpenEnsureNetworkClockAvailabilityService(u64) -> object<nn::ntc::detail::service::IEnsureNetworkClockAvailabilityService>
+ public ResultCode CreateAsyncInterface(ServiceCtx context)
+ {
+ ulong unknown = context.RequestData.ReadUInt64();
+
+ MakeObject(context, new IEnsureNetworkClockAvailabilityService(context));
+
+ Logger.Stub?.PrintStub(LogClass.ServiceNtc, new { unknown });
+
+ return ResultCode.Success;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs b/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs
new file mode 100644
index 00000000..fb31bd1f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nim/Ntc/StaticService/IEnsureNetworkClockAvailabilityService.cs
@@ -0,0 +1,77 @@
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService
+{
+ class IEnsureNetworkClockAvailabilityService : IpcService
+ {
+ private KEvent _finishNotificationEvent;
+ private ResultCode _taskResultCode;
+
+ public IEnsureNetworkClockAvailabilityService(ServiceCtx context)
+ {
+ _finishNotificationEvent = new KEvent(context.Device.System.KernelContext);
+ _taskResultCode = ResultCode.Success;
+
+ // NOTE: The service starts a thread that polls Nintendo NTP server and syncs the time with it.
+ // Additionnally it gets and uses some settings too:
+ // autonomic_correction_interval_seconds, autonomic_correction_failed_retry_interval_seconds,
+ // autonomic_correction_immediate_try_count_max, autonomic_correction_immediate_try_interval_milliseconds
+ }
+
+ [CommandHipc(0)]
+ // StartTask()
+ public ResultCode StartTask(ServiceCtx context)
+ {
+ if (!context.Device.Configuration.EnableInternetAccess)
+ {
+ return (ResultCode)Time.ResultCode.NetworkTimeNotAvailable;
+ }
+
+ // NOTE: Since we don't support the Nintendo NTP server, we can signal the event now to confirm the update task is done.
+ _finishNotificationEvent.ReadableEvent.Signal();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceNtc);
+
+ return ResultCode.Success;
+ }
+
+ [CommandHipc(1)]
+ // GetFinishNotificationEvent() -> handle<copy>
+ public ResultCode GetFinishNotificationEvent(ServiceCtx context)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_finishNotificationEvent.ReadableEvent, out int finishNotificationEventHandle) != KernelResult.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(finishNotificationEventHandle);
+
+ return ResultCode.Success;
+ }
+
+ [CommandHipc(2)]
+ // GetResult()
+ public ResultCode GetResult(ServiceCtx context)
+ {
+ return _taskResultCode;
+ }
+
+ [CommandHipc(3)]
+ // Cancel()
+ public ResultCode Cancel(ServiceCtx context)
+ {
+ // NOTE: The update task should be canceled here.
+ _finishNotificationEvent.ReadableEvent.Signal();
+
+ _taskResultCode = (ResultCode)Time.ResultCode.NetworkTimeTaskCanceled;
+
+ Logger.Stub?.PrintStub(LogClass.ServiceNtc);
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs
index 57bf4206..3b042ec0 100644
--- a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs
@@ -7,16 +7,18 @@
Success = 0,
- TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
- PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
- TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
- UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
- TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
- Overflow = (201 << ErrorCodeShift) | ModuleId,
- LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
- OutOfRange = (902 << ErrorCodeShift) | ModuleId,
- TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
- TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
- NotImplemented = (990 << ErrorCodeShift) | ModuleId,
+ TimeServiceNotInitialized = (0 << ErrorCodeShift) | ModuleId,
+ PermissionDenied = (1 << ErrorCodeShift) | ModuleId,
+ TimeMismatch = (102 << ErrorCodeShift) | ModuleId,
+ UninitializedClock = (103 << ErrorCodeShift) | ModuleId,
+ TimeNotFound = (200 << ErrorCodeShift) | ModuleId,
+ Overflow = (201 << ErrorCodeShift) | ModuleId,
+ LocationNameTooLong = (801 << ErrorCodeShift) | ModuleId,
+ OutOfRange = (902 << ErrorCodeShift) | ModuleId,
+ TimeZoneConversionFailed = (903 << ErrorCodeShift) | ModuleId,
+ TimeZoneNotFound = (989 << ErrorCodeShift) | ModuleId,
+ NotImplemented = (990 << ErrorCodeShift) | ModuleId,
+ NetworkTimeNotAvailable = (1000 << ErrorCodeShift) | ModuleId,
+ NetworkTimeTaskCanceled = (1003 << ErrorCodeShift) | ModuleId,
}
}