diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/time/time.cpp | 58 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.h | 28 |
2 files changed, 72 insertions, 14 deletions
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 2eb37fb42..654012189 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <chrono> | 5 | #include <chrono> |
| 6 | #include <ctime> | ||
| 6 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 7 | #include "core/core_timing.h" | 8 | #include "core/core_timing.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| @@ -77,7 +78,7 @@ public: | |||
| 77 | {3, nullptr, "LoadLocationNameList"}, | 78 | {3, nullptr, "LoadLocationNameList"}, |
| 78 | {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"}, | 79 | {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"}, |
| 79 | {5, nullptr, "GetTimeZoneRuleVersion"}, | 80 | {5, nullptr, "GetTimeZoneRuleVersion"}, |
| 80 | {100, nullptr, "ToCalendarTime"}, | 81 | {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, |
| 81 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, | 82 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, |
| 82 | {200, nullptr, "ToPosixTime"}, | 83 | {200, nullptr, "ToPosixTime"}, |
| 83 | {201, nullptr, "ToPosixTimeWithMyRule"}, | 84 | {201, nullptr, "ToPosixTimeWithMyRule"}, |
| @@ -86,9 +87,11 @@ public: | |||
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | private: | 89 | private: |
| 90 | LocationName location_name{"UTC"}; | ||
| 91 | TimeZoneRule my_time_zone_rule{}; | ||
| 92 | |||
| 89 | void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { | 93 | void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { |
| 90 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); | 94 | NGLOG_DEBUG(Service_Time, "called"); |
| 91 | LocationName location_name{}; | ||
| 92 | IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; | 95 | IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; |
| 93 | rb.Push(RESULT_SUCCESS); | 96 | rb.Push(RESULT_SUCCESS); |
| 94 | rb.PushRaw(location_name); | 97 | rb.PushRaw(location_name); |
| @@ -103,23 +106,70 @@ private: | |||
| 103 | 106 | ||
| 104 | void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { | 107 | void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { |
| 105 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); | 108 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); |
| 109 | |||
| 110 | ctx.WriteBuffer(&my_time_zone_rule, sizeof(TimeZoneRule)); | ||
| 111 | |||
| 106 | IPC::ResponseBuilder rb{ctx, 2}; | 112 | IPC::ResponseBuilder rb{ctx, 2}; |
| 107 | rb.Push(RESULT_SUCCESS); | 113 | rb.Push(RESULT_SUCCESS); |
| 108 | } | 114 | } |
| 109 | 115 | ||
| 116 | void ToCalendarTime(Kernel::HLERequestContext& ctx) { | ||
| 117 | IPC::RequestParser rp{ctx}; | ||
| 118 | const u64 posix_time = rp.Pop<u64>(); | ||
| 119 | |||
| 120 | NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); | ||
| 121 | |||
| 122 | TimeZoneRule time_zone_rule{}; | ||
| 123 | auto buffer = ctx.ReadBuffer(); | ||
| 124 | std::memcpy(&time_zone_rule, buffer.data(), buffer.size()); | ||
| 125 | |||
| 126 | CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; | ||
| 127 | CalendarAdditionalInfo additional_info{}; | ||
| 128 | |||
| 129 | PosixToCalendar(posix_time, calendar_time, additional_info, time_zone_rule); | ||
| 130 | |||
| 131 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 132 | rb.Push(RESULT_SUCCESS); | ||
| 133 | rb.PushRaw(calendar_time); | ||
| 134 | rb.PushRaw(additional_info); | ||
| 135 | } | ||
| 136 | |||
| 110 | void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) { | 137 | void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) { |
| 111 | IPC::RequestParser rp{ctx}; | 138 | IPC::RequestParser rp{ctx}; |
| 112 | u64 posix_time = rp.Pop<u64>(); | 139 | const u64 posix_time = rp.Pop<u64>(); |
| 113 | 140 | ||
| 114 | NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); | 141 | NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); |
| 115 | 142 | ||
| 116 | CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; | 143 | CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; |
| 117 | CalendarAdditionalInfo additional_info{}; | 144 | CalendarAdditionalInfo additional_info{}; |
| 145 | |||
| 146 | PosixToCalendar(posix_time, calendar_time, additional_info, my_time_zone_rule); | ||
| 147 | |||
| 118 | IPC::ResponseBuilder rb{ctx, 10}; | 148 | IPC::ResponseBuilder rb{ctx, 10}; |
| 119 | rb.Push(RESULT_SUCCESS); | 149 | rb.Push(RESULT_SUCCESS); |
| 120 | rb.PushRaw(calendar_time); | 150 | rb.PushRaw(calendar_time); |
| 121 | rb.PushRaw(additional_info); | 151 | rb.PushRaw(additional_info); |
| 122 | } | 152 | } |
| 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 | } | ||
| 123 | }; | 173 | }; |
| 124 | 174 | ||
| 125 | void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { | 175 | void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 12fe1995a..49af38589 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | 9 | ||
| 9 | namespace Service::Time { | 10 | namespace Service::Time { |
| 10 | 11 | ||
| 11 | // TODO(Rozelette) RE this structure | ||
| 12 | struct LocationName { | 12 | struct LocationName { |
| 13 | INSERT_PADDING_BYTES(0x24); | 13 | std::array<u8, 0x24> name; |
| 14 | }; | 14 | }; |
| 15 | static_assert(sizeof(LocationName) == 0x24, "LocationName is incorrect size"); | 15 | static_assert(sizeof(LocationName) == 0x24, "LocationName is incorrect size"); |
| 16 | 16 | ||
| @@ -25,26 +25,34 @@ struct CalendarTime { | |||
| 25 | }; | 25 | }; |
| 26 | static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size"); | 26 | static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size"); |
| 27 | 27 | ||
| 28 | // TODO(Rozelette) RE this structure | ||
| 29 | struct CalendarAdditionalInfo { | 28 | struct CalendarAdditionalInfo { |
| 30 | INSERT_PADDING_BYTES(0x18); | 29 | u32_le day_of_week; |
| 30 | u32_le day_of_year; | ||
| 31 | std::array<u8, 8> name; | ||
| 32 | INSERT_PADDING_BYTES(1); | ||
| 33 | s32_le utc_offset; | ||
| 31 | }; | 34 | }; |
| 32 | static_assert(sizeof(CalendarAdditionalInfo) == 0x18, | 35 | static_assert(sizeof(CalendarAdditionalInfo) == 0x18, |
| 33 | "CalendarAdditionalInfo structure has incorrect size"); | 36 | "CalendarAdditionalInfo structure has incorrect size"); |
| 34 | 37 | ||
| 35 | // TODO(bunnei) RE this structure | 38 | // TODO(mailwl) RE this structure |
| 36 | struct SystemClockContext { | 39 | struct TimeZoneRule { |
| 37 | INSERT_PADDING_BYTES(0x20); | 40 | INSERT_PADDING_BYTES(0x4000); |
| 38 | }; | 41 | }; |
| 39 | static_assert(sizeof(SystemClockContext) == 0x20, | ||
| 40 | "SystemClockContext structure has incorrect size"); | ||
| 41 | 42 | ||
| 42 | struct SteadyClockTimePoint { | 43 | struct SteadyClockTimePoint { |
| 43 | u64 value; | 44 | u64_le value; |
| 44 | INSERT_PADDING_WORDS(4); | 45 | INSERT_PADDING_WORDS(4); |
| 45 | }; | 46 | }; |
| 46 | static_assert(sizeof(SteadyClockTimePoint) == 0x18, "SteadyClockTimePoint is incorrect size"); | 47 | static_assert(sizeof(SteadyClockTimePoint) == 0x18, "SteadyClockTimePoint is incorrect size"); |
| 47 | 48 | ||
| 49 | struct SystemClockContext { | ||
| 50 | u64_le offset; | ||
| 51 | SteadyClockTimePoint time_point; | ||
| 52 | }; | ||
| 53 | static_assert(sizeof(SystemClockContext) == 0x20, | ||
| 54 | "SystemClockContext structure has incorrect size"); | ||
| 55 | |||
| 48 | class Module final { | 56 | class Module final { |
| 49 | public: | 57 | public: |
| 50 | class Interface : public ServiceFramework<Interface> { | 58 | class Interface : public ServiceFramework<Interface> { |