TIME: consolidate time:* interfaces, stub functions and structs
This commit is contained in:
		| @@ -58,7 +58,6 @@ set(SRCS | ||||
|             hle/service/sm/controller.cpp | ||||
|             hle/service/sm/sm.cpp | ||||
|             hle/service/time/time.cpp | ||||
|             hle/service/time/time_s.cpp | ||||
|             hle/service/vi/vi.cpp | ||||
|             hle/service/vi/vi_m.cpp | ||||
|             hle/shared_page.cpp | ||||
| @@ -148,7 +147,6 @@ set(HEADERS | ||||
|             hle/service/sm/controller.h | ||||
|             hle/service/sm/sm.h | ||||
|             hle/service/time/time.h | ||||
|             hle/service/time/time_s.h | ||||
|             hle/service/vi/vi.h | ||||
|             hle/service/vi/vi_m.h | ||||
|             hle/shared_page.h | ||||
|   | ||||
| @@ -2,14 +2,140 @@ | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <chrono> | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/client_session.h" | ||||
| #include "core/hle/service/time/time.h" | ||||
| #include "core/hle/service/time/time_s.h" | ||||
|  | ||||
| namespace Service { | ||||
| namespace Time { | ||||
|  | ||||
| class ISystemClock final : public ServiceFramework<ISystemClock> { | ||||
| public: | ||||
|     ISystemClock() : ServiceFramework("ISystemClock") { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void GetCurrentTime(Kernel::HLERequestContext& ctx) { | ||||
|         const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>( | ||||
|                                        std::chrono::system_clock::now().time_since_epoch()) | ||||
|                                        .count()}; | ||||
|         IPC::RequestBuilder rb{ctx, 4}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.Push<u64>(time_since_epoch); | ||||
|         LOG_DEBUG(Service, "called"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class ISteadyClock final : public ServiceFramework<ISteadyClock> { | ||||
| public: | ||||
|     ISteadyClock() : ServiceFramework("ISteadyClock") {} | ||||
| }; | ||||
|  | ||||
| class ITimeZoneService final : public ServiceFramework<ITimeZoneService> { | ||||
| public: | ||||
|     ITimeZoneService() : ServiceFramework("ITimeZoneService") { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"}, | ||||
|             {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service, "(STUBBED) called"); | ||||
|         LocationName name{}; | ||||
|         IPC::RequestBuilder rb{ctx, 11}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushRaw(name); | ||||
|     } | ||||
|  | ||||
|     void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         u64 posixTime = rp.Pop<u64>(); | ||||
|  | ||||
|         LOG_WARNING(Service, "(STUBBED) called, posixTime=0x%016llX", posixTime); | ||||
|  | ||||
|         CalendarTime calendarTime{2018, 1, 1, 0, 0, 0}; | ||||
|         CalendarAdditionalInfo additionalInfo{}; | ||||
|         IPC::RequestBuilder rb{ctx, 10}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushRaw(calendarTime); | ||||
|         rb.PushRaw(additionalInfo); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void TIME::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { | ||||
|     auto client_port = std::make_shared<ISystemClock>()->CreatePort(); | ||||
|     auto session = client_port->Connect(); | ||||
|     if (session.Succeeded()) { | ||||
|         LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", | ||||
|                   (*session)->GetObjectId()); | ||||
|         IPC::RequestBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushMoveObjects(std::move(session).Unwrap()); | ||||
|     } else { | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void TIME::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { | ||||
|     auto client_port = std::make_shared<ISystemClock>()->CreatePort(); | ||||
|     auto session = client_port->Connect(); | ||||
|     if (session.Succeeded()) { | ||||
|         LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", | ||||
|                   (*session)->GetObjectId()); | ||||
|         IPC::RequestBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushMoveObjects(std::move(session).Unwrap()); | ||||
|     } else { | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void TIME::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { | ||||
|     auto client_port = std::make_shared<ISteadyClock>()->CreatePort(); | ||||
|     auto session = client_port->Connect(); | ||||
|     if (session.Succeeded()) { | ||||
|         LOG_DEBUG(Service, "called, initialized ISteadyClock -> session=%u", | ||||
|                   (*session)->GetObjectId()); | ||||
|         IPC::RequestBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushMoveObjects(std::move(session).Unwrap()); | ||||
|     } else { | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void TIME::GetTimeZoneService(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.PushIpcInterface<ITimeZoneService>(); | ||||
|     LOG_DEBUG(Service, "called"); | ||||
| } | ||||
|  | ||||
| TIME::TIME(const char* name) : ServiceFramework(name) { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0x00000000, &TIME::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, | ||||
|         {0x00000001, &TIME::GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, | ||||
|         {0x00000002, &TIME::GetStandardSteadyClock, "GetStandardSteadyClock"}, | ||||
|         {0x00000003, &TIME::GetTimeZoneService, "GetTimeZoneService"}, | ||||
|     }; | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
|  | ||||
| void InstallInterfaces(SM::ServiceManager& service_manager) { | ||||
|     std::make_shared<TimeS>()->InstallAsService(service_manager); | ||||
|     std::make_shared<TIME>("time:a")->InstallAsService(service_manager); | ||||
|     std::make_shared<TIME>("time:r")->InstallAsService(service_manager); | ||||
|     std::make_shared<TIME>("time:s")->InstallAsService(service_manager); | ||||
|     std::make_shared<TIME>("time:u")->InstallAsService(service_manager); | ||||
| } | ||||
|  | ||||
| } // namespace Time | ||||
|   | ||||
| @@ -9,6 +9,42 @@ | ||||
| namespace Service { | ||||
| namespace Time { | ||||
|  | ||||
| // TODO(Rozelette) RE this structure | ||||
| struct LocationName { | ||||
|     INSERT_PADDING_BYTES(0x24); | ||||
| }; | ||||
| static_assert(sizeof(LocationName) == 0x24, "LocationName structure has incorrect size"); | ||||
|  | ||||
| struct CalendarTime { | ||||
|     u16_le year; | ||||
|     u8 month; // Starts at 1 | ||||
|     u8 day;   // Starts at 1 | ||||
|     u8 hour; | ||||
|     u8 minute; | ||||
|     u8 second; | ||||
|     INSERT_PADDING_BYTES(1); | ||||
| }; | ||||
| static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size"); | ||||
|  | ||||
| // TODO(Rozelette) RE this structure | ||||
| struct CalendarAdditionalInfo { | ||||
|     INSERT_PADDING_BYTES(0x18); | ||||
| }; | ||||
| static_assert(sizeof(CalendarAdditionalInfo) == 0x18, | ||||
|               "CalendarAdditionalInfo structure has incorrect size"); | ||||
|  | ||||
| class TIME final : public ServiceFramework<TIME> { | ||||
| public: | ||||
|     explicit TIME(const char* name); | ||||
|     ~TIME() = default; | ||||
|  | ||||
| private: | ||||
|     void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); | ||||
|     void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx); | ||||
|     void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); | ||||
|     void GetTimeZoneService(Kernel::HLERequestContext& ctx); | ||||
| }; | ||||
|  | ||||
| /// Registers all Time services with the specified service manager. | ||||
| void InstallInterfaces(SM::ServiceManager& service_manager); | ||||
|  | ||||
|   | ||||
| @@ -1,58 +0,0 @@ | ||||
| // Copyright 2018 yuzu emulator team | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <chrono> | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/client_session.h" | ||||
| #include "core/hle/service/time/time_s.h" | ||||
|  | ||||
| namespace Service { | ||||
| namespace Time { | ||||
|  | ||||
| class ISystemClock final : public ServiceFramework<ISystemClock> { | ||||
| public: | ||||
|     ISystemClock() : ServiceFramework("ISystemClock") { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void GetCurrentTime(Kernel::HLERequestContext& ctx) { | ||||
|         const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>( | ||||
|                                        std::chrono::system_clock::now().time_since_epoch()) | ||||
|                                        .count()}; | ||||
|         IPC::RequestBuilder rb{ctx, 4}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.Push<u64>(time_since_epoch); | ||||
|         LOG_DEBUG(Service, "called"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void TimeS::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { | ||||
|     auto client_port = std::make_shared<ISystemClock>()->CreatePort(); | ||||
|     auto session = client_port->Connect(); | ||||
|     if (session.Succeeded()) { | ||||
|         LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", | ||||
|                   (*session)->GetObjectId()); | ||||
|         IPC::RequestBuilder rb{ctx, 2, 0, 1}; | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|         rb.PushMoveObjects(std::move(session).Unwrap()); | ||||
|     } else { | ||||
|         UNIMPLEMENTED(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| TimeS::TimeS() : ServiceFramework("time:s") { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0x00000000, &TimeS::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, | ||||
|     }; | ||||
|     RegisterHandlers(functions); | ||||
| } | ||||
|  | ||||
| } // namespace Time | ||||
| } // namespace Service | ||||
| @@ -1,23 +0,0 @@ | ||||
| // Copyright 2018 yuzu emulator team | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Service { | ||||
| namespace Time { | ||||
|  | ||||
| class TimeS final : public ServiceFramework<TimeS> { | ||||
| public: | ||||
|     TimeS(); | ||||
|     ~TimeS() = default; | ||||
|  | ||||
| private: | ||||
|     void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); | ||||
| }; | ||||
|  | ||||
| } // namespace Time | ||||
| } // namespace Service | ||||
		Reference in New Issue
	
	Block a user