ITimeServiceManager.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. [Command(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. [Command(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. [Command(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. [Command(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. [Command(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. [Command(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. [Command(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. [Command(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. [Command(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 = Encoding.ASCII.GetString(context.RequestData.ReadBytes(0x24)).TrimEnd('\0');
  95. SteadyClockTimePoint timeZoneUpdateTimePoint = context.RequestData.ReadStruct<SteadyClockTimePoint>();
  96. uint totalLocationNameCount = context.RequestData.ReadUInt32();
  97. UInt128 timeZoneRuleVersion = context.RequestData.ReadStruct<UInt128>();
  98. (long bufferPosition, long bufferSize) = context.Request.GetBufferType0x21();
  99. using (MemoryStream timeZoneBinaryStream = new MemoryStream(context.Memory.ReadBytes(bufferPosition, bufferSize)))
  100. {
  101. _timeManager.SetupTimeZoneManager(locationName, timeZoneUpdateTimePoint, totalLocationNameCount, timeZoneRuleVersion, timeZoneBinaryStream);
  102. }
  103. return ResultCode.Success;
  104. }
  105. [Command(15)]
  106. // SetupEphemeralNetworkSystemClock()
  107. public ResultCode SetupEphemeralNetworkSystemClock(ServiceCtx context)
  108. {
  109. _timeManager.SetupEphemeralNetworkSystemClock();
  110. return ResultCode.Success;
  111. }
  112. [Command(50)]
  113. // Unknown50() -> handle<copy>
  114. public ResultCode Unknown50(ServiceCtx context)
  115. {
  116. // TODO: figure out the usage of this event
  117. throw new ServiceNotImplementedException(context);
  118. }
  119. [Command(51)]
  120. // Unknown51() -> handle<copy>
  121. public ResultCode Unknown51(ServiceCtx context)
  122. {
  123. // TODO: figure out the usage of this event
  124. throw new ServiceNotImplementedException(context);
  125. }
  126. [Command(52)]
  127. // Unknown52() -> handle<copy>
  128. public ResultCode Unknown52(ServiceCtx context)
  129. {
  130. // TODO: figure out the usage of this event
  131. throw new ServiceNotImplementedException(context);
  132. }
  133. [Command(60)]
  134. // GetStandardUserSystemClockAutomaticCorrectionEvent() -> handle<copy>
  135. public ResultCode GetStandardUserSystemClockAutomaticCorrectionEvent(ServiceCtx context)
  136. {
  137. if (_automaticCorrectionEvent == 0)
  138. {
  139. if (context.Process.HandleTable.GenerateHandle(_timeManager.StandardUserSystemClock.GetAutomaticCorrectionReadableEvent(), out _automaticCorrectionEvent) != KernelResult.Success)
  140. {
  141. throw new InvalidOperationException("Out of handles!");
  142. }
  143. }
  144. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_automaticCorrectionEvent);
  145. return ResultCode.Success;
  146. }
  147. [Command(100)]
  148. // SetStandardSteadyClockRtcOffset(nn::TimeSpanType rtc_offset)
  149. public ResultCode SetStandardSteadyClockRtcOffset(ServiceCtx context)
  150. {
  151. TimeSpanType rtcOffset = context.RequestData.ReadStruct<TimeSpanType>();
  152. _timeManager.SetStandardSteadyClockRtcOffset(context.Thread, rtcOffset);
  153. return ResultCode.Success;
  154. }
  155. [Command(200)]
  156. // GetAlarmRegistrationEvent() -> handle<copy>
  157. public ResultCode GetAlarmRegistrationEvent(ServiceCtx context)
  158. {
  159. // TODO
  160. throw new ServiceNotImplementedException(context);
  161. }
  162. [Command(201)]
  163. // UpdateSteadyAlarms()
  164. public ResultCode UpdateSteadyAlarms(ServiceCtx context)
  165. {
  166. // TODO
  167. throw new ServiceNotImplementedException(context);
  168. }
  169. [Command(202)]
  170. // TryGetNextSteadyClockAlarmSnapshot() -> (bool, nn::time::SteadyClockAlarmSnapshot)
  171. public ResultCode TryGetNextSteadyClockAlarmSnapshot(ServiceCtx context)
  172. {
  173. // TODO
  174. throw new ServiceNotImplementedException(context);
  175. }
  176. }
  177. }