ITimeServiceManager.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using Ryujinx.Common;
  2. using Ryujinx.Cpu;
  3. using Ryujinx.HLE.Exceptions;
  4. using Ryujinx.HLE.HOS.Ipc;
  5. using Ryujinx.HLE.HOS.Kernel.Common;
  6. using Ryujinx.HLE.HOS.Services.Time.Clock;
  7. using Ryujinx.HLE.Utilities;
  8. using System;
  9. using System.IO;
  10. namespace Ryujinx.HLE.HOS.Services.Time
  11. {
  12. [Service("time:m")] // 9.0.0+
  13. class ITimeServiceManager : IpcService
  14. {
  15. private TimeManager _timeManager;
  16. private int _automaticCorrectionEvent;
  17. public ITimeServiceManager(ServiceCtx context)
  18. {
  19. _timeManager = TimeManager.Instance;
  20. _automaticCorrectionEvent = 0;
  21. }
  22. [CommandHipc(0)]
  23. // GetUserStaticService() -> object<nn::timesrv::detail::service::IStaticService>
  24. public ResultCode GetUserStaticService(ServiceCtx context)
  25. {
  26. MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.User));
  27. return ResultCode.Success;
  28. }
  29. [CommandHipc(5)]
  30. // GetAdminStaticService() -> object<nn::timesrv::detail::service::IStaticService>
  31. public ResultCode GetAdminStaticService(ServiceCtx context)
  32. {
  33. MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Admin));
  34. return ResultCode.Success;
  35. }
  36. [CommandHipc(6)]
  37. // GetRepairStaticService() -> object<nn::timesrv::detail::service::IStaticService>
  38. public ResultCode GetRepairStaticService(ServiceCtx context)
  39. {
  40. MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Repair));
  41. return ResultCode.Success;
  42. }
  43. [CommandHipc(9)]
  44. // GetManufactureStaticService() -> object<nn::timesrv::detail::service::IStaticService>
  45. public ResultCode GetManufactureStaticService(ServiceCtx context)
  46. {
  47. MakeObject(context, new IStaticServiceForPsc(_timeManager, TimePermissions.Manufacture));
  48. return ResultCode.Success;
  49. }
  50. [CommandHipc(10)]
  51. // SetupStandardSteadyClock(nn::util::Uuid clock_source_id, nn::TimeSpanType setup_value, nn::TimeSpanType internal_offset, nn::TimeSpanType test_offset, bool is_rtc_reset_detected)
  52. public ResultCode SetupStandardSteadyClock(ServiceCtx context)
  53. {
  54. UInt128 clockSourceId = context.RequestData.ReadStruct<UInt128>();
  55. TimeSpanType setupValue = context.RequestData.ReadStruct<TimeSpanType>();
  56. TimeSpanType internalOffset = context.RequestData.ReadStruct<TimeSpanType>();
  57. TimeSpanType testOffset = context.RequestData.ReadStruct<TimeSpanType>();
  58. bool isRtcResetDetected = context.RequestData.ReadBoolean();
  59. ITickSource tickSource = context.Device.System.TickSource;
  60. _timeManager.SetupStandardSteadyClock(tickSource, clockSourceId, setupValue, internalOffset, testOffset, isRtcResetDetected);
  61. return ResultCode.Success;
  62. }
  63. [CommandHipc(11)]
  64. // SetupStandardLocalSystemClock(nn::time::SystemClockContext context, nn::time::PosixTime posix_time)
  65. public ResultCode SetupStandardLocalSystemClock(ServiceCtx context)
  66. {
  67. SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
  68. long posixTime = context.RequestData.ReadInt64();
  69. ITickSource tickSource = context.Device.System.TickSource;
  70. _timeManager.SetupStandardLocalSystemClock(tickSource, clockContext, posixTime);
  71. return ResultCode.Success;
  72. }
  73. [CommandHipc(12)]
  74. // SetupStandardNetworkSystemClock(nn::time::SystemClockContext context, nn::TimeSpanType sufficient_accuracy)
  75. public ResultCode SetupStandardNetworkSystemClock(ServiceCtx context)
  76. {
  77. SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
  78. TimeSpanType sufficientAccuracy = context.RequestData.ReadStruct<TimeSpanType>();
  79. _timeManager.SetupStandardNetworkSystemClock(clockContext, sufficientAccuracy);
  80. return ResultCode.Success;
  81. }
  82. [CommandHipc(13)]
  83. // SetupStandardUserSystemClock(bool automatic_correction_enabled, nn::time::SteadyClockTimePoint steady_clock_timepoint)
  84. public ResultCode SetupStandardUserSystemClock(ServiceCtx context)
  85. {
  86. bool isAutomaticCorrectionEnabled = context.RequestData.ReadBoolean();
  87. context.RequestData.BaseStream.Position += 7;
  88. SteadyClockTimePoint steadyClockTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
  89. ITickSource tickSource = context.Device.System.TickSource;
  90. _timeManager.SetupStandardUserSystemClock(tickSource, isAutomaticCorrectionEnabled, steadyClockTimePoint);
  91. return ResultCode.Success;
  92. }
  93. [CommandHipc(14)]
  94. // 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)
  95. public ResultCode SetupTimeZoneManager(ServiceCtx context)
  96. {
  97. string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24);
  98. SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
  99. uint totalLocationNameCount = context.RequestData.ReadUInt32();
  100. UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
  101. (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21();
  102. byte[] temp = new byte[bufferSize];
  103. context.Memory.Read(bufferPosition, temp);
  104. using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp))
  105. {
  106. _timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
  107. }
  108. return ResultCode.Success;
  109. }
  110. [CommandHipc(15)]
  111. // SetupEphemeralNetworkSystemClock()
  112. public ResultCode SetupEphemeralNetworkSystemClock(ServiceCtx context)
  113. {
  114. _timeManager.SetupEphemeralNetworkSystemClock();
  115. return ResultCode.Success;
  116. }
  117. [CommandHipc(50)]
  118. // Unknown50() -> handle<copy>
  119. public ResultCode Unknown50(ServiceCtx context)
  120. {
  121. // TODO: figure out the usage of this event
  122. throw new ServiceNotImplementedException(this, context);
  123. }
  124. [CommandHipc(51)]
  125. // Unknown51() -> handle<copy>
  126. public ResultCode Unknown51(ServiceCtx context)
  127. {
  128. // TODO: figure out the usage of this event
  129. throw new ServiceNotImplementedException(this, context);
  130. }
  131. [CommandHipc(52)]
  132. // Unknown52() -> handle<copy>
  133. public ResultCode Unknown52(ServiceCtx context)
  134. {
  135. // TODO: figure out the usage of this event
  136. throw new ServiceNotImplementedException(this, context);
  137. }
  138. [CommandHipc(60)]
  139. // GetStandardUserSystemClockAutomaticCorrectionEvent() -> handle<copy>
  140. public ResultCode GetStandardUserSystemClockAutomaticCorrectionEvent(ServiceCtx context)
  141. {
  142. if (_automaticCorrectionEvent == 0)
  143. {
  144. if (context.Process.HandleTable.GenerateHandle(_timeManager.StandardUserSystemClock.GetAutomaticCorrectionReadableEvent(), out _automaticCorrectionEvent) != KernelResult.Success)
  145. {
  146. throw new InvalidOperationException("Out of handles!");
  147. }
  148. }
  149. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_automaticCorrectionEvent);
  150. return ResultCode.Success;
  151. }
  152. [CommandHipc(100)]
  153. // SetStandardSteadyClockRtcOffset(nn::TimeSpanType rtc_offset)
  154. public ResultCode SetStandardSteadyClockRtcOffset(ServiceCtx context)
  155. {
  156. TimeSpanType rtcOffset = context.RequestData.ReadStruct<TimeSpanType>();
  157. ITickSource tickSource = context.Device.System.TickSource;
  158. _timeManager.SetStandardSteadyClockRtcOffset(tickSource, rtcOffset);
  159. return ResultCode.Success;
  160. }
  161. [CommandHipc(200)]
  162. // GetAlarmRegistrationEvent() -> handle<copy>
  163. public ResultCode GetAlarmRegistrationEvent(ServiceCtx context)
  164. {
  165. // TODO
  166. throw new ServiceNotImplementedException(this, context);
  167. }
  168. [CommandHipc(201)]
  169. // UpdateSteadyAlarms()
  170. public ResultCode UpdateSteadyAlarms(ServiceCtx context)
  171. {
  172. // TODO
  173. throw new ServiceNotImplementedException(this, context);
  174. }
  175. [CommandHipc(202)]
  176. // TryGetNextSteadyClockAlarmSnapshot() -> (bool, nn::time::SteadyClockAlarmSnapshot)
  177. public ResultCode TryGetNextSteadyClockAlarmSnapshot(ServiceCtx context)
  178. {
  179. // TODO
  180. throw new ServiceNotImplementedException(this, context);
  181. }
  182. }
  183. }