diff --git a/app/src/main/cpp/skyline/services/glue/IStaticService.h b/app/src/main/cpp/skyline/services/glue/IStaticService.h index f6ecae7c..db523ca5 100644 --- a/app/src/main/cpp/skyline/services/glue/IStaticService.h +++ b/app/src/main/cpp/skyline/services/glue/IStaticService.h @@ -8,8 +8,8 @@ namespace skyline::service::glue { /** - * @brief IStaticService (covers time:a, time:r, time:u) is glue's version of pcv::IStaticService, it adds some more functions and provides the user variant - * @url https://switchbrew.org/wiki/PSC_services#time:su.2C_time:s + * @brief IStaticService (covers time:a, time:r, time:u) is glue's extension of pcv::IStaticService, it adds some more functions and provides the user variant that most applications use + * @url https://switchbrew.org/wiki/Glue_services#time:a.2C_time:r.2C_time:u */ class IStaticService : public BaseService { private: diff --git a/app/src/main/cpp/skyline/services/glue/ITimeZoneService.h b/app/src/main/cpp/skyline/services/glue/ITimeZoneService.h index 3d2b0a71..373bd9f3 100644 --- a/app/src/main/cpp/skyline/services/glue/ITimeZoneService.h +++ b/app/src/main/cpp/skyline/services/glue/ITimeZoneService.h @@ -13,9 +13,13 @@ namespace skyline::service::timesrv { struct TimeServiceObject; } } + namespace skyline::service::glue { - + /** + * @brief ITimeZoneService is glue's extension of psc::ITimeZoneService, it adds support for reading TimeZone location data and simplifies rule handling. This is the variant normally used by applications. + * @url https://switchbrew.org/wiki/Glue_services#ITimeZoneService + */ class ITimeZoneService : public BaseService { private: std::shared_ptr core; @@ -32,6 +36,10 @@ namespace skyline::service::glue { Result GetTotalLocationNameCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** + * @brief Returns a list of available timezone location names beginning from the given index + * @url https://switchbrew.org/wiki/Glue_services#LoadLocationNameList + */ Result LoadLocationNameList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); Result LoadTimeZoneRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); diff --git a/app/src/main/cpp/skyline/services/serviceman.cpp b/app/src/main/cpp/skyline/services/serviceman.cpp index beae4696..3f316e4e 100644 --- a/app/src/main/cpp/skyline/services/serviceman.cpp +++ b/app/src/main/cpp/skyline/services/serviceman.cpp @@ -64,9 +64,9 @@ namespace skyline::service { SERVICE_CASE(hid::IHidServer, "hid") SERVICE_CASE(timesrv::IStaticService, "time:s", globalServiceState->timesrv, timesrv::constant::StaticServiceSystemPermissions) // Both of these would be registered after TimeServiceManager::Setup normally but we call that in the GlobalServiceState constructor so can just list them here directly SERVICE_CASE(timesrv::IStaticService, "time:su", globalServiceState->timesrv, timesrv::constant::StaticServiceSystemUpdatePermissions) - SERVICE_CASE(glue::IStaticService, "time:a", globalServiceState->timesrv.managerServer.GetAdminStaticService(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceAdminPermissions) - SERVICE_CASE(glue::IStaticService, "time:r", globalServiceState->timesrv.managerServer.GetRepairStaticService(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceRepairPermissions) - SERVICE_CASE(glue::IStaticService, "time:u", globalServiceState->timesrv.managerServer.GetUserStaticService(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceUserPermissions) + SERVICE_CASE(glue::IStaticService, "time:a", globalServiceState->timesrv.managerServer.GetStaticServiceAsAdmin(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceAdminPermissions) + SERVICE_CASE(glue::IStaticService, "time:r", globalServiceState->timesrv.managerServer.GetStaticServiceAsRepair(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceRepairPermissions) + SERVICE_CASE(glue::IStaticService, "time:u", globalServiceState->timesrv.managerServer.GetStaticServiceAsUser(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceUserPermissions) SERVICE_CASE(fssrv::IFileSystemProxy, "fsp-srv") SERVICE_CASE(nvdrv::INvDrvServices, "nvdrv") SERVICE_CASE(nvdrv::INvDrvServices, "nvdrv:a") diff --git a/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp b/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp index 3363cefa..2ab8fb24 100644 --- a/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp @@ -127,14 +127,25 @@ namespace skyline::service::timesrv { out.steadyClockTimePoint = *timePoint; out.automaticCorrectionEnabled = core.userSystemClock.IsAutomaticCorrectionEnabled(); - // TODO GetDeviceLocationName + + auto locationName{core.timeZoneManager.GetLocationName()}; + if (!locationName) + return locationName; + + out.locationName = *locationName; + auto userPosixTime{ClockSnapshot::GetCurrentTime(out.steadyClockTimePoint, out.userContext)}; if (!userPosixTime) return userPosixTime; out.userPosixTime = *userPosixTime; - // TODO CalendarTimeWithMyRule + auto userCalendarTime{core.timeZoneManager.ToCalendarTimeWithMyRule(*userPosixTime)}; + if (!userCalendarTime) + return userCalendarTime; + + out.userCalendarTime = userCalendarTime->calendarTime; + out.userCalendarAdditionalInfo = userCalendarTime->additionalInfo; // Not necessarily a fatal error if this fails auto networkPosixTime{ClockSnapshot::GetCurrentTime(out.steadyClockTimePoint, out.networkContext)}; @@ -143,7 +154,12 @@ namespace skyline::service::timesrv { else out.networkPosixTime = 0; - // TODO CalendarTimeWithMyRule + auto networkCalendarTime{core.timeZoneManager.ToCalendarTimeWithMyRule(out.networkPosixTime)}; + if (!networkCalendarTime) + return networkCalendarTime; + + out.networkCalendarTime = networkCalendarTime->calendarTime; + out.networkCalendarAdditionalInfo = networkCalendarTime->additionalInfo; out._unk_ = unk; out.version = 0; diff --git a/app/src/main/cpp/skyline/services/timesrv/ISteadyClock.h b/app/src/main/cpp/skyline/services/timesrv/ISteadyClock.h index 015af36b..af80b906 100644 --- a/app/src/main/cpp/skyline/services/timesrv/ISteadyClock.h +++ b/app/src/main/cpp/skyline/services/timesrv/ISteadyClock.h @@ -47,4 +47,4 @@ namespace skyline::service::timesrv { SFUNC(0xC8, ISteadyClock, GetInternalOffset), ) }; -} +} \ No newline at end of file diff --git a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp index 9460fba9..59c1fd6c 100644 --- a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp @@ -57,7 +57,7 @@ namespace skyline::service::timesrv { return updateTime; response.Push(*locationName); - response.Push(0); + response.Push(0); // Padding response.Push(*updateTime); return {}; @@ -77,11 +77,11 @@ namespace skyline::service::timesrv { } Result ITimeZoneService::ParseTimeZoneBinaryIpc(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - return core.timeZoneManager.ParseTimeZoneBinary(request.inputBuf.at(0), request.outputBuf.at(0)); + return core::TimeZoneManager::ParseTimeZoneBinary(request.inputBuf.at(0), request.outputBuf.at(0)); } Result ITimeZoneService::ParseTimeZoneBinary(span binary, span rule) { - return core.timeZoneManager.ParseTimeZoneBinary(binary, rule); + return core::TimeZoneManager::ParseTimeZoneBinary(binary, rule); } Result ITimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { @@ -90,7 +90,7 @@ namespace skyline::service::timesrv { Result ITimeZoneService::ToCalendarTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { auto posixTime{request.Pop()}; - auto calendarTime{core.timeZoneManager.ToCalendarTime(reinterpret_cast(request.inputBuf.at(0).data()), posixTime)}; + auto calendarTime{core::TimeZoneManager::ToCalendarTime(reinterpret_cast(request.inputBuf.at(0).data()), posixTime)}; if (calendarTime) response.Push(*calendarTime); @@ -110,7 +110,7 @@ namespace skyline::service::timesrv { Result ITimeZoneService::ToPosixTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { auto calendarTime{request.Pop()}; - auto posixTime{core.timeZoneManager.ToPosixTime(reinterpret_cast(request.inputBuf.at(0).data()), calendarTime)}; + auto posixTime{core::TimeZoneManager::ToPosixTime(reinterpret_cast(request.inputBuf.at(0).data()), calendarTime)}; if (!posixTime) return posixTime; diff --git a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h index 8ab560cb..09576630 100644 --- a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h +++ b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h @@ -11,7 +11,7 @@ namespace skyline::service::timesrv { } /** - * @brief ITimeZoneService is used to retrieve and set timezone info and convert between times and dates + * @brief ITimeZoneService is used to retrieve and set timezone info and convert between times and dates by the system * @url https://switchbrew.org/wiki/PSC_services#ITimeZoneService */ class ITimeZoneService : public BaseService { diff --git a/app/src/main/cpp/skyline/services/timesrv/common.h b/app/src/main/cpp/skyline/services/timesrv/common.h index 32f6d0e4..50d79094 100644 --- a/app/src/main/cpp/skyline/services/timesrv/common.h +++ b/app/src/main/cpp/skyline/services/timesrv/common.h @@ -5,7 +5,7 @@ namespace skyline::service::timesrv { using PosixTime = i64; //!< Unit for time in seconds since the epoch - using LocationName = std::array; + using LocationName = std::array; /** * @brief Stores a quantity of time with nanosecond accuracy and provides helper functions to convert it to other units @@ -58,6 +58,7 @@ namespace skyline::service::timesrv { /** * @brief Holds details about a point in time sourced from a steady clock (e.g. RTC) + * @url https://switchbrew.org/w/index.php?title=PSC_services#SteadyClockTimePoint */ struct __attribute__((packed)) SteadyClockTimePoint { i64 timePoint; //!< Time in seconds @@ -69,6 +70,7 @@ namespace skyline::service::timesrv { /** * @brief Describes a system clocks offset from its associated steady clock + * @url https://switchbrew.org/w/index.php?title=PSC_services#SystemClockContext */ struct __attribute__((packed)) SystemClockContext { i64 offset; // Offset between the steady timepoint and the epoch @@ -80,6 +82,7 @@ namespace skyline::service::timesrv { /** * @brief A particular time point in Nintendo's calendar format + * @url https://switchbrew.org/w/index.php?title=PSC_services#CalendarTime */ struct CalendarTime { u16 year; //!< The current year minus 1900 @@ -94,6 +97,7 @@ namespace skyline::service::timesrv { /** * @brief Additional metadata about the time alongside CalendarTime + * @url https://switchbrew.org/w/index.php?title=PSC_services#CalendarAdditionalInfo */ struct CalendarAdditionalInfo { u32 dayOfWeek; //!< 0-6 @@ -126,7 +130,7 @@ namespace skyline::service::timesrv { CalendarAdditionalInfo userCalendarAdditionalInfo; CalendarAdditionalInfo networkCalendarAdditionalInfo; SteadyClockTimePoint steadyClockTimePoint; - std::array locationName; + LocationName locationName; u8 automaticCorrectionEnabled; u8 _unk_; u16 version; diff --git a/app/src/main/cpp/skyline/services/timesrv/core.cpp b/app/src/main/cpp/skyline/services/timesrv/core.cpp index d688f4cc..de4b368e 100644 --- a/app/src/main/cpp/skyline/services/timesrv/core.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/core.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include "core.h" #include "time_manager_server.h" diff --git a/app/src/main/cpp/skyline/services/timesrv/time_manager_server.cpp b/app/src/main/cpp/skyline/services/timesrv/time_manager_server.cpp index 209bda6f..b22477b2 100644 --- a/app/src/main/cpp/skyline/services/timesrv/time_manager_server.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/time_manager_server.cpp @@ -2,26 +2,26 @@ // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) #include -#include #include "core.h" +#include "IStaticService.h" #include "time_manager_server.h" namespace skyline::service::timesrv { TimeManagerServer::TimeManagerServer(core::TimeServiceObject &core) : core(core) {} - std::shared_ptr TimeManagerServer::GetUserStaticService(const DeviceState &state, ServiceManager &manager) { + std::shared_ptr TimeManagerServer::GetStaticServiceAsUser(const DeviceState &state, ServiceManager &manager) { return std::make_shared(state, manager, core, constant::StaticServiceUserPermissions); } - std::shared_ptr TimeManagerServer::GetAdminStaticService(const DeviceState &state, ServiceManager &manager) { + std::shared_ptr TimeManagerServer::GetStaticServiceAsAdmin(const DeviceState &state, ServiceManager &manager) { return std::make_shared(state, manager, core, constant::StaticServiceAdminPermissions); } - std::shared_ptr TimeManagerServer::GetRepairStaticService(const DeviceState &state, ServiceManager &manager) { + std::shared_ptr TimeManagerServer::GetStaticServiceAsRepair(const DeviceState &state, ServiceManager &manager) { return std::make_shared(state, manager, core, constant::StaticServiceRepairPermissions); } - std::shared_ptr TimeManagerServer::GetManagerStaticService(const DeviceState &state, ServiceManager &manager) { + std::shared_ptr TimeManagerServer::GetStaticServiceAsServiceManager(const DeviceState &state, ServiceManager &manager) { return std::make_shared(state, manager, core, constant::StaticServiceManagerPermissions); } diff --git a/app/src/main/cpp/skyline/services/timesrv/time_manager_server.h b/app/src/main/cpp/skyline/services/timesrv/time_manager_server.h index 6facfc3b..89e832ee 100644 --- a/app/src/main/cpp/skyline/services/timesrv/time_manager_server.h +++ b/app/src/main/cpp/skyline/services/timesrv/time_manager_server.h @@ -6,14 +6,20 @@ #include #include #include +#include #include "common.h" -#include "IStaticService.h" namespace skyline::service::timesrv { namespace core { struct TimeServiceObject; } + class IStaticService; + + /** + * @brief time:m (we don't expose this as IPC as games don't use it) is used to manage the state of timesrv + * @url https://switchbrew.org/w/index.php?title=PSC_services#time:m + */ class TimeManagerServer { private: core::TimeServiceObject &core; @@ -21,29 +27,61 @@ namespace skyline::service::timesrv { public: TimeManagerServer(core::TimeServiceObject &core); - std::shared_ptr GetUserStaticService(const DeviceState &state, ServiceManager &manager); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#GetStaticServiceAsUser + */ + std::shared_ptr GetStaticServiceAsUser(const DeviceState &state, ServiceManager &manager); - std::shared_ptr GetAdminStaticService(const DeviceState &state, ServiceManager &manager); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#GetStaticServiceAsAdmin + */ + std::shared_ptr GetStaticServiceAsAdmin(const DeviceState &state, ServiceManager &manager); - std::shared_ptr GetRepairStaticService(const DeviceState &state, ServiceManager &manager); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#GetStaticServiceAsRepair + */ + std::shared_ptr GetStaticServiceAsRepair(const DeviceState &state, ServiceManager &manager); - std::shared_ptr GetManagerStaticService(const DeviceState &state, ServiceManager &manager); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#GetStaticServiceAsServiceManager + */ + std::shared_ptr GetStaticServiceAsServiceManager(const DeviceState &state, ServiceManager &manager); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupStandardSteadyClockCore + */ Result SetupStandardSteadyClock(UUID rtcId, TimeSpanType rtcOffset, TimeSpanType internalOffset, TimeSpanType testOffset, bool rtcResetDetected); - - Result SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, size_t locationCount, std::array binaryVersion, span binary); - + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupStandardLocalSystemClockCore + */ Result SetupStandardLocalSystemClock(const SystemClockContext &context, PosixTime posixTime); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupStandardNetworkSystemClockCore + */ Result SetupStandardNetworkSystemClock(const SystemClockContext &context, TimeSpanType sufficientAccuracy); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupStandardUserSystemClockCore + */ Result SetupStandardUserSystemClock(bool enableAutomaticCorrection, const SteadyClockTimePoint &automaticCorrectionUpdateTime); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupTimeZoneServiceCore + */ + Result SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, size_t locationCount, std::array binaryVersion, span binary); + + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetupEphemeralNetworkSystemClockCore + */ Result SetupEphemeralSystemClock(); std::shared_ptr GetStandardUserSystemClockAutomaticCorrectionEvent(); + /** + * @url https://switchbrew.org/w/index.php?title=PSC_services#SetStandardSteadyClockBaseTime + */ Result SetStandardSteadyClockRtcOffset(TimeSpanType rtcOffset); }; } diff --git a/app/src/main/cpp/skyline/services/timesrv/time_shared_memory.cpp b/app/src/main/cpp/skyline/services/timesrv/time_shared_memory.cpp index 59e71338..3afcc59d 100644 --- a/app/src/main/cpp/skyline/services/timesrv/time_shared_memory.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/time_shared_memory.cpp @@ -53,11 +53,9 @@ namespace skyline::service::timesrv::core { return out; } - namespace constant { - constexpr size_t TimeSharedMemorySize{0x1000}; //!< The size of the time shared memory region - } + constexpr size_t TimeSharedMemorySize{0x1000}; //!< The size of the time shared memory region - TimeSharedMemory::TimeSharedMemory(const DeviceState &state) : kTimeSharedMemory(std::make_shared(state, constant::TimeSharedMemorySize)), timeSharedMemory(reinterpret_cast(kTimeSharedMemory->kernel.ptr)) {} + TimeSharedMemory::TimeSharedMemory(const DeviceState &state) : kTimeSharedMemory(std::make_shared(state, TimeSharedMemorySize)), timeSharedMemory(reinterpret_cast(kTimeSharedMemory->kernel.ptr)) {} void TimeSharedMemory::SetupStandardSteadyClock(UUID rtcId, TimeSpanType baseTimePoint) { SteadyClockTimePoint context{ diff --git a/app/src/main/cpp/skyline/services/timesrv/timezone_manager.cpp b/app/src/main/cpp/skyline/services/timesrv/timezone_manager.cpp index 12be9eac..5f68366b 100644 --- a/app/src/main/cpp/skyline/services/timesrv/timezone_manager.cpp +++ b/app/src/main/cpp/skyline/services/timesrv/timezone_manager.cpp @@ -18,7 +18,7 @@ namespace skyline::service::timesrv::core { ResultValue TimeZoneManager::GetLocationName() { std::lock_guard lock(mutex); - if (!initialized) + if (!IsInitialized()) return result::ClockUninitialized; return locationName; @@ -39,7 +39,7 @@ namespace skyline::service::timesrv::core { ResultValue TimeZoneManager::GetUpdateTime() { std::lock_guard lock(mutex); - if (!initialized) + if (!IsInitialized()) return result::ClockUninitialized; return updateTime; @@ -53,7 +53,7 @@ namespace skyline::service::timesrv::core { ResultValue TimeZoneManager::GetLocationCount() { std::lock_guard lock(mutex); - if (!initialized) + if (!IsInitialized()) return result::ClockUninitialized; return locationCount; @@ -67,7 +67,7 @@ namespace skyline::service::timesrv::core { ResultValue> TimeZoneManager::GetBinaryVersion() { std::lock_guard lock(mutex); - if (!initialized) + if (!IsInitialized()) return result::ClockUninitialized; return binaryVersion; @@ -124,7 +124,7 @@ namespace skyline::service::timesrv::core { .tm_sec = calendarTime.second, }; - // Nintendo optionally two times here, presumably to deal with DST correction but we are probably fine without it + // Nintendo optionally returns two times here, presumably to deal with DST correction but we are probably fine without it return static_cast(tz_mktime_z(pRule, &posixCalendarTime)); } } \ No newline at end of file diff --git a/app/src/main/cpp/skyline/services/timesrv/timezone_manager.h b/app/src/main/cpp/skyline/services/timesrv/timezone_manager.h index c86c797e..ac5861ad 100644 --- a/app/src/main/cpp/skyline/services/timesrv/timezone_manager.h +++ b/app/src/main/cpp/skyline/services/timesrv/timezone_manager.h @@ -26,6 +26,10 @@ namespace skyline::service::timesrv::core { } public: + bool IsInitialized() { + return initialized; + } + /** * @brief Initialises the manager, setting the initial timezone so it is ready for use by applications */ @@ -53,12 +57,12 @@ namespace skyline::service::timesrv::core { /** * @brief Parses a raw TZIF2 file into a timezone rule that can be passed to other functions */ - Result ParseTimeZoneBinary(span binary, span ruleOut); + static Result ParseTimeZoneBinary(span binary, span ruleOut); /** * @brief Converts a POSIX time to a calendar time using the given rule */ - ResultValue ToCalendarTime(tz_timezone_t pRule, PosixTime posixTime); + static ResultValue ToCalendarTime(tz_timezone_t pRule, PosixTime posixTime); /** * @brief Converts a POSIX to a calendar time using the current location's rule @@ -70,7 +74,7 @@ namespace skyline::service::timesrv::core { /** * @brief Converts a calendar time to a POSIX time using the given rule */ - ResultValue ToPosixTime(tz_timezone_t pRule, CalendarTime calendarTime); + static ResultValue ToPosixTime(tz_timezone_t pRule, CalendarTime calendarTime); /** * @brief Converts a calendar time to a POSIX time using the current location's rule @@ -79,4 +83,4 @@ namespace skyline::service::timesrv::core { return ToPosixTime(rule, calendarTime); } }; -} +} \ No newline at end of file