diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/time/interface.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.cpp | 89 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.h | 18 |
3 files changed, 88 insertions, 21 deletions
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index 18a5d71d5..e3cbd7004 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp | |||
| @@ -21,7 +21,7 @@ Time::Time(std::shared_ptr<Module> time, const char* name) | |||
| 21 | {102, nullptr, "GetStandardUserSystemClockInitialYear"}, | 21 | {102, nullptr, "GetStandardUserSystemClockInitialYear"}, |
| 22 | {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, | 22 | {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, |
| 23 | {300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"}, | 23 | {300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"}, |
| 24 | {400, nullptr, "GetClockSnapshot"}, | 24 | {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, |
| 25 | {401, nullptr, "GetClockSnapshotFromSystemClockContext"}, | 25 | {401, nullptr, "GetClockSnapshotFromSystemClockContext"}, |
| 26 | {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, | 26 | {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, |
| 27 | {501, nullptr, "CalculateSpanBetween"}, | 27 | {501, nullptr, "CalculateSpanBetween"}, |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 28fd8debc..dc504eaac 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -15,6 +15,26 @@ | |||
| 15 | 15 | ||
| 16 | namespace Service::Time { | 16 | namespace Service::Time { |
| 17 | 17 | ||
| 18 | void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, | ||
| 19 | CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) { | ||
| 20 | std::time_t time(posix_time); | ||
| 21 | std::tm* tm = std::localtime(&time); | ||
| 22 | if (tm == nullptr) { | ||
| 23 | return; | ||
| 24 | } | ||
| 25 | calendar_time.year = tm->tm_year + 1900; | ||
| 26 | calendar_time.month = tm->tm_mon + 1; | ||
| 27 | calendar_time.day = tm->tm_mday; | ||
| 28 | calendar_time.hour = tm->tm_hour; | ||
| 29 | calendar_time.minute = tm->tm_min; | ||
| 30 | calendar_time.second = tm->tm_sec; | ||
| 31 | |||
| 32 | additional_info.day_of_week = tm->tm_wday; | ||
| 33 | additional_info.day_of_year = tm->tm_yday; | ||
| 34 | std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC")); | ||
| 35 | additional_info.utc_offset = 0; | ||
| 36 | } | ||
| 37 | |||
| 18 | class ISystemClock final : public ServiceFramework<ISystemClock> { | 38 | class ISystemClock final : public ServiceFramework<ISystemClock> { |
| 19 | public: | 39 | public: |
| 20 | ISystemClock() : ServiceFramework("ISystemClock") { | 40 | ISystemClock() : ServiceFramework("ISystemClock") { |
| @@ -150,26 +170,6 @@ private: | |||
| 150 | rb.PushRaw(calendar_time); | 170 | rb.PushRaw(calendar_time); |
| 151 | rb.PushRaw(additional_info); | 171 | rb.PushRaw(additional_info); |
| 152 | } | 172 | } |
| 153 | |||
| 154 | void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, | ||
| 155 | CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) { | ||
| 156 | std::time_t t(posix_time); | ||
| 157 | std::tm* tm = std::localtime(&t); | ||
| 158 | if (!tm) { | ||
| 159 | return; | ||
| 160 | } | ||
| 161 | calendar_time.year = tm->tm_year + 1900; | ||
| 162 | calendar_time.month = tm->tm_mon + 1; | ||
| 163 | calendar_time.day = tm->tm_mday; | ||
| 164 | calendar_time.hour = tm->tm_hour; | ||
| 165 | calendar_time.minute = tm->tm_min; | ||
| 166 | calendar_time.second = tm->tm_sec; | ||
| 167 | |||
| 168 | additional_info.day_of_week = tm->tm_wday; | ||
| 169 | additional_info.day_of_year = tm->tm_yday; | ||
| 170 | std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC")); | ||
| 171 | additional_info.utc_offset = 0; | ||
| 172 | } | ||
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { | 175 | void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { |
| @@ -207,6 +207,55 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c | |||
| 207 | LOG_DEBUG(Service_Time, "called"); | 207 | LOG_DEBUG(Service_Time, "called"); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | ||
| 211 | LOG_DEBUG(Service_Time, "called"); | ||
| 212 | |||
| 213 | IPC::RequestParser rp{ctx}; | ||
| 214 | auto unknown_u8 = rp.PopRaw<u8>(); | ||
| 215 | |||
| 216 | ClockSnapshot clock_snapshot{}; | ||
| 217 | |||
| 218 | const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( | ||
| 219 | std::chrono::system_clock::now().time_since_epoch()) | ||
| 220 | .count()}; | ||
| 221 | CalendarTime calendar_time{}; | ||
| 222 | std::time_t time(time_since_epoch); | ||
| 223 | std::tm* tm = std::localtime(&time); | ||
| 224 | if (tm == nullptr) { | ||
| 225 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 226 | rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code | ||
| 227 | return; | ||
| 228 | } | ||
| 229 | SteadyClockTimePoint steady_clock_time_point{CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / | ||
| 230 | 1000}; | ||
| 231 | |||
| 232 | LocationName location_name{"UTC"}; | ||
| 233 | calendar_time.year = tm->tm_year + 1900; | ||
| 234 | calendar_time.month = tm->tm_mon + 1; | ||
| 235 | calendar_time.day = tm->tm_mday; | ||
| 236 | calendar_time.hour = tm->tm_hour; | ||
| 237 | calendar_time.minute = tm->tm_min; | ||
| 238 | calendar_time.second = tm->tm_sec; | ||
| 239 | clock_snapshot.system_posix_time = time_since_epoch; | ||
| 240 | clock_snapshot.network_posix_time = time_since_epoch; | ||
| 241 | clock_snapshot.system_calendar_time = calendar_time; | ||
| 242 | clock_snapshot.network_calendar_time = calendar_time; | ||
| 243 | |||
| 244 | CalendarAdditionalInfo additional_info{}; | ||
| 245 | PosixToCalendar(time_since_epoch, calendar_time, additional_info, {}); | ||
| 246 | |||
| 247 | clock_snapshot.system_calendar_info = additional_info; | ||
| 248 | clock_snapshot.network_calendar_info = additional_info; | ||
| 249 | |||
| 250 | clock_snapshot.steady_clock_timepoint = steady_clock_time_point; | ||
| 251 | clock_snapshot.location_name = location_name; | ||
| 252 | clock_snapshot.clock_auto_adjustment_enabled = 1; | ||
| 253 | clock_snapshot.ipc_u8 = unknown_u8; | ||
| 254 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 255 | rb.Push(RESULT_SUCCESS); | ||
| 256 | ctx.WriteBuffer(&clock_snapshot, sizeof(ClockSnapshot)); | ||
| 257 | } | ||
| 258 | |||
| 210 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) | 259 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) |
| 211 | : ServiceFramework(name), time(std::move(time)) {} | 260 | : ServiceFramework(name), time(std::move(time)) {} |
| 212 | 261 | ||
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 5659ecad3..ca30ec60f 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -53,6 +53,23 @@ struct SystemClockContext { | |||
| 53 | static_assert(sizeof(SystemClockContext) == 0x20, | 53 | static_assert(sizeof(SystemClockContext) == 0x20, |
| 54 | "SystemClockContext structure has incorrect size"); | 54 | "SystemClockContext structure has incorrect size"); |
| 55 | 55 | ||
| 56 | struct ClockSnapshot { | ||
| 57 | SystemClockContext user_clock_context; | ||
| 58 | SystemClockContext network_clock_context; | ||
| 59 | s64_le system_posix_time; | ||
| 60 | s64_le network_posix_time; | ||
| 61 | CalendarTime system_calendar_time; | ||
| 62 | CalendarTime network_calendar_time; | ||
| 63 | CalendarAdditionalInfo system_calendar_info; | ||
| 64 | CalendarAdditionalInfo network_calendar_info; | ||
| 65 | SteadyClockTimePoint steady_clock_timepoint; | ||
| 66 | LocationName location_name; | ||
| 67 | u8 clock_auto_adjustment_enabled; | ||
| 68 | u8 ipc_u8; | ||
| 69 | INSERT_PADDING_BYTES(2); | ||
| 70 | }; | ||
| 71 | static_assert(sizeof(ClockSnapshot) == 0xd0, "ClockSnapshot is an invalid size"); | ||
| 72 | |||
| 56 | class Module final { | 73 | class Module final { |
| 57 | public: | 74 | public: |
| 58 | class Interface : public ServiceFramework<Interface> { | 75 | class Interface : public ServiceFramework<Interface> { |
| @@ -65,6 +82,7 @@ public: | |||
| 65 | void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); | 82 | void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); |
| 66 | void GetTimeZoneService(Kernel::HLERequestContext& ctx); | 83 | void GetTimeZoneService(Kernel::HLERequestContext& ctx); |
| 67 | void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); | 84 | void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); |
| 85 | void GetClockSnapshot(Kernel::HLERequestContext& ctx); | ||
| 68 | 86 | ||
| 69 | protected: | 87 | protected: |
| 70 | std::shared_ptr<Module> time; | 88 | std::shared_ptr<Module> time; |