diff options
| author | mailwl <mailwl@gmail.com> | 2018-05-31 15:33:30 +0300 | 
|---|---|---|
| committer | mailwl <mailwl@gmail.com> | 2018-06-01 09:40:28 +0300 | 
| commit | 11568c2ea36b712498fd0cedd03748331946030a (patch) | |
| tree | 0a3767de73ca5cdc9fab6cf53711c58dd5e77de0 /src/core | |
| parent | bdd68fc210d2b7138f8fcd22ec41c8b238500c28 (diff) | |
Service/time: implement posix time to calendar conversion
Diffstat (limited to 'src/core')
| -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 @@  // Refer to the license.txt file included.  #include <chrono> +#include <ctime>  #include "common/logging/log.h"  #include "core/core_timing.h"  #include "core/hle/ipc_helpers.h" @@ -77,7 +78,7 @@ public:              {3, nullptr, "LoadLocationNameList"},              {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},              {5, nullptr, "GetTimeZoneRuleVersion"}, -            {100, nullptr, "ToCalendarTime"}, +            {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},              {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},              {200, nullptr, "ToPosixTime"},              {201, nullptr, "ToPosixTimeWithMyRule"}, @@ -86,9 +87,11 @@ public:      }  private: +    LocationName location_name{"UTC"}; +    TimeZoneRule my_time_zone_rule{}; +      void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { -        NGLOG_WARNING(Service_Time, "(STUBBED) called"); -        LocationName location_name{}; +        NGLOG_DEBUG(Service_Time, "called");          IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};          rb.Push(RESULT_SUCCESS);          rb.PushRaw(location_name); @@ -103,23 +106,70 @@ private:      void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) {          NGLOG_WARNING(Service_Time, "(STUBBED) called"); + +        ctx.WriteBuffer(&my_time_zone_rule, sizeof(TimeZoneRule)); +          IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      } +    void ToCalendarTime(Kernel::HLERequestContext& ctx) { +        IPC::RequestParser rp{ctx}; +        const u64 posix_time = rp.Pop<u64>(); + +        NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); + +        TimeZoneRule time_zone_rule{}; +        auto buffer = ctx.ReadBuffer(); +        std::memcpy(&time_zone_rule, buffer.data(), buffer.size()); + +        CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; +        CalendarAdditionalInfo additional_info{}; + +        PosixToCalendar(posix_time, calendar_time, additional_info, time_zone_rule); + +        IPC::ResponseBuilder rb{ctx, 10}; +        rb.Push(RESULT_SUCCESS); +        rb.PushRaw(calendar_time); +        rb.PushRaw(additional_info); +    } +      void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) {          IPC::RequestParser rp{ctx}; -        u64 posix_time = rp.Pop<u64>(); +        const u64 posix_time = rp.Pop<u64>();          NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time);          CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};          CalendarAdditionalInfo additional_info{}; + +        PosixToCalendar(posix_time, calendar_time, additional_info, my_time_zone_rule); +          IPC::ResponseBuilder rb{ctx, 10};          rb.Push(RESULT_SUCCESS);          rb.PushRaw(calendar_time);          rb.PushRaw(additional_info);      } + +    void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time, +                         CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) { +        std::time_t t(posix_time); +        std::tm* tm = std::localtime(&t); +        if (!tm) { +            return; +        } +        calendar_time.year = tm->tm_year + 1900; +        calendar_time.month = tm->tm_mon + 1; +        calendar_time.day = tm->tm_mday; +        calendar_time.hour = tm->tm_hour; +        calendar_time.minute = tm->tm_min; +        calendar_time.second = tm->tm_sec; + +        additional_info.day_of_week = tm->tm_wday; +        additional_info.day_of_year = tm->tm_yday; +        std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC")); +        additional_info.utc_offset = 0; +    }  };  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 @@  #pragma once +#include <array>  #include "core/hle/service/service.h"  namespace Service::Time { -// TODO(Rozelette) RE this structure  struct LocationName { -    INSERT_PADDING_BYTES(0x24); +    std::array<u8, 0x24> name;  };  static_assert(sizeof(LocationName) == 0x24, "LocationName is incorrect size"); @@ -25,26 +25,34 @@ struct CalendarTime {  };  static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size"); -// TODO(Rozelette) RE this structure  struct CalendarAdditionalInfo { -    INSERT_PADDING_BYTES(0x18); +    u32_le day_of_week; +    u32_le day_of_year; +    std::array<u8, 8> name; +    INSERT_PADDING_BYTES(1); +    s32_le utc_offset;  };  static_assert(sizeof(CalendarAdditionalInfo) == 0x18,                "CalendarAdditionalInfo structure has incorrect size"); -// TODO(bunnei) RE this structure -struct SystemClockContext { -    INSERT_PADDING_BYTES(0x20); +// TODO(mailwl) RE this structure +struct TimeZoneRule { +    INSERT_PADDING_BYTES(0x4000);  }; -static_assert(sizeof(SystemClockContext) == 0x20, -              "SystemClockContext structure has incorrect size");  struct SteadyClockTimePoint { -    u64 value; +    u64_le value;      INSERT_PADDING_WORDS(4);  };  static_assert(sizeof(SteadyClockTimePoint) == 0x18, "SteadyClockTimePoint is incorrect size"); +struct SystemClockContext { +    u64_le offset; +    SteadyClockTimePoint time_point; +}; +static_assert(sizeof(SystemClockContext) == 0x20, +              "SystemClockContext structure has incorrect size"); +  class Module final {  public:      class Interface : public ServiceFramework<Interface> { | 
