ITimeServiceManager.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using Ryujinx.Common;
  2. using Ryujinx.HLE.Exceptions;
  3. using Ryujinx.HLE.HOS.Ipc;
  4. using Ryujinx.HLE.HOS.Kernel.Common;
  5. using Ryujinx.HLE.HOS.Services.Time.Clock;
  6. using Ryujinx.HLE.Utilities;
  7. using System;
  8. using System.IO;
  9. using System.Text;
  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. _timeManager.SetupStandardSteadyClock(context.Thread, clockSourceId, setupValue, internalOffset, testOffset, isRtcResetDetected);
  60. return ResultCode.Success;
  61. }
  62. [CommandHipc(11)]
  63. // SetupStandardLocalSystemClock(nn::time::SystemClockContext context, nn::time::PosixTime posix_time)
  64. public ResultCode SetupStandardLocalSystemClock(ServiceCtx context)
  65. {
  66. SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
  67. long posixTime = context.RequestData.ReadInt64();
  68. _timeManager.SetupStandardLocalSystemClock(context.Thread, clockContext, posixTime);
  69. return ResultCode.Success;
  70. }
  71. [CommandHipc(12)]
  72. // SetupStandardNetworkSystemClock(nn::time::SystemClockContext context, nn::TimeSpanType sufficient_accuracy)
  73. public ResultCode SetupStandardNetworkSystemClock(ServiceCtx context)
  74. {
  75. SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>();
  76. TimeSpanType sufficientAccuracy = context.RequestData.ReadStruct<TimeSpanType>();
  77. _timeManager.SetupStandardNetworkSystemClock(clockContext, sufficientAccuracy);
  78. return ResultCode.Success;
  79. }
  80. [CommandHipc(13)]
  81. // SetupStandardUserSystemClock(bool automatic_correction_enabled, nn::time::SteadyClockTimePoint steady_clock_timepoint)
  82. public ResultCode SetupStandardUserSystemClock(ServiceCtx context)
  83. {
  84. bool isAutomaticCorrectionEnabled = context.RequestData.ReadBoolean();
  85. context.RequestData.BaseStream.Position += 7;
  86. SteadyClockTimePoint steadyClockTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
  87. _timeManager.SetupStandardUserSystemClock(context.Thread, isAutomaticCorrectionEnabled, steadyClockTimePoint);
  88. return ResultCode.Success;
  89. }
  90. [CommandHipc(14)]
  91. // 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)
  92. public ResultCode SetupTimeZoneManager(ServiceCtx context)
  93. {
  94. string locationName = StringUtils.ReadInlinedAsciiString(context.RequestData, 0x24);
  95. SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
  96. uint totalLocationNameCount = context.RequestData.ReadUInt32();
  97. UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
  98. (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21();
  99. byte[] temp = new byte[bufferSize];
  100. context.Memory.Read(bufferPosition, temp);
  101. using (MemoryStream timeZoneBinaryStream = new MemoryStream(temp))
  102. {
  103. _timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
  104. }
  105. return ResultCode.Success;
  106. }
  107. [CommandHipc(15)]
  108. // SetupEphemeralNetworkSystemClock()
  109. public ResultCode SetupEphemeralNetworkSystemClock(ServiceCtx context)
  110. {
  111. _timeManager.SetupEphemeralNetworkSystemClock();
  112. return ResultCode.Success;
  113. }
  114. [CommandHipc(50)]
  115. // Unknown50() -> handle<copy>
  116. public ResultCode Unknown50(ServiceCtx context)
  117. {
  118. // TODO: figure out the usage of this event
  119. throw new ServiceNotImplementedException(this, context);
  120. }
  121. [CommandHipc(51)]
  122. // Unknown51() -> handle<copy>
  123. public ResultCode Unknown51(ServiceCtx context)
  124. {
  125. // TODO: figure out the usage of this event
  126. throw new ServiceNotImplementedException(this, context);
  127. }
  128. [CommandHipc(52)]
  129. // Unknown52() -> handle<copy>
  130. public ResultCode Unknown52(ServiceCtx context)
  131. {
  132. // TODO: figure out the usage of this event
  133. throw new ServiceNotImplementedException(this, context);
  134. }
  135. [CommandHipc(60)]
  136. // GetStandardUserSystemClockAutomaticCorrectionEvent() -> handle<copy>
  137. public ResultCode GetStandardUserSystemClockAutomaticCorrectionEvent(ServiceCtx context)
  138. {
  139. if (_automaticCorrectionEvent == 0)
  140. {
  141. if (context.Process.HandleTable.GenerateHandle(_timeManager.StandardUserSystemClock.GetAutomaticCorrectionReadableEvent(), out _automaticCorrectionEvent) != KernelResult.Success)
  142. {
  143. throw new InvalidOperationException("Out of handles!");
  144. }
  145. }
  146. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_automaticCorrectionEvent);
  147. return ResultCode.Success;
  148. }
  149. [CommandHipc(100)]
  150. // SetStandardSteadyClockRtcOffset(nn::TimeSpanType rtc_offset)
  151. public ResultCode SetStandardSteadyClockRtcOffset(ServiceCtx context)
  152. {
  153. TimeSpanType rtcOffset = context.RequestData.ReadStruct<TimeSpanType>();
  154. _timeManager.SetStandardSteadyClockRtcOffset(context.Thread, rtcOffset);
  155. return ResultCode.Success;
  156. }
  157. [CommandHipc(200)]
  158. // GetAlarmRegistrationEvent() -> handle<copy>
  159. public ResultCode GetAlarmRegistrationEvent(ServiceCtx context)
  160. {
  161. // TODO
  162. throw new ServiceNotImplementedException(this, context);
  163. }
  164. [CommandHipc(201)]
  165. // UpdateSteadyAlarms()
  166. public ResultCode UpdateSteadyAlarms(ServiceCtx context)
  167. {
  168. // TODO
  169. throw new ServiceNotImplementedException(this, context);
  170. }
  171. [CommandHipc(202)]
  172. // TryGetNextSteadyClockAlarmSnapshot() -> (bool, nn::time::SteadyClockAlarmSnapshot)
  173. public ResultCode TryGetNextSteadyClockAlarmSnapshot(ServiceCtx context)
  174. {
  175. // TODO
  176. throw new ServiceNotImplementedException(this, context);
  177. }
  178. }
  179. }