diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 544eb243..f918dbb3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -62,7 +62,9 @@ add_library(skyline SHARED ${source_DIR}/skyline/services/am/applet.cpp ${source_DIR}/skyline/services/am/appletController.cpp ${source_DIR}/skyline/services/hid/hid.cpp - ${source_DIR}/skyline/services/time/time.cpp + ${source_DIR}/skyline/services/timesrv/IStaticService.cpp + ${source_DIR}/skyline/services/timesrv/ISystemClock.cpp + ${source_DIR}/skyline/services/timesrv/ITimeZoneService.cpp ${source_DIR}/skyline/services/fs/fs.cpp ${source_DIR}/skyline/services/nvdrv/nvdrv.cpp ${source_DIR}/skyline/services/nvnflinger/dispdrv.cpp diff --git a/app/src/main/cpp/skyline/services/base_service.h b/app/src/main/cpp/skyline/services/base_service.h index d82f3e34..796478c7 100644 --- a/app/src/main/cpp/skyline/services/base_service.h +++ b/app/src/main/cpp/skyline/services/base_service.h @@ -44,9 +44,9 @@ namespace skyline::service { IAudioRenderer, hid, hid_IAppletResource, - time, - time_ISystemClock, - time_ITimeZoneService, + timesrv_IStaticService, + timesrv_ISystemClock, + timesrv_ITimeZoneService, fs_fsp, fs_IFileSystem, nvdrv, @@ -69,8 +69,9 @@ namespace skyline::service { {"audout:u", Service::audout_u}, {"audren:u", Service::IAudioRendererManager}, {"hid", Service::hid}, - {"time:s", Service::time}, - {"time:a", Service::time}, + {"time:s", Service::timesrv_IStaticService}, + {"time:a", Service::timesrv_IStaticService}, + {"time:u", Service::timesrv_IStaticService}, {"fsp-srv", Service::fs_fsp}, {"nvdrv", Service::nvdrv}, {"nvdrv:a", Service::nvdrv}, diff --git a/app/src/main/cpp/skyline/services/serviceman.cpp b/app/src/main/cpp/skyline/services/serviceman.cpp index 2665bd4e..4349b134 100644 --- a/app/src/main/cpp/skyline/services/serviceman.cpp +++ b/app/src/main/cpp/skyline/services/serviceman.cpp @@ -8,7 +8,7 @@ #include "audout/audout.h" #include "fatal/fatal.h" #include "hid/hid.h" -#include "time/timesrv.h" +#include "timesrv/IStaticService.h" #include "fs/fs.h" #include "nvdrv/nvdrv.h" #include "vi/vi_m.h" @@ -50,8 +50,8 @@ namespace skyline::service { case Service::hid: serviceObj = std::make_shared(state, *this); break; - case Service::time: - serviceObj = std::make_shared(state, *this); + case Service::timesrv_IStaticService: + serviceObj = std::make_shared(state, *this); break; case Service::fs_fsp: serviceObj = std::make_shared(state, *this); diff --git a/app/src/main/cpp/skyline/services/time/time.cpp b/app/src/main/cpp/skyline/services/time/time.cpp deleted file mode 100644 index a484c076..00000000 --- a/app/src/main/cpp/skyline/services/time/time.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "timesrv.h" - -namespace skyline::service::time { - time::time(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::time, "time", { - {0x0, SFUNC(time::GetStandardUserSystemClock)}, - {0x1, SFUNC(time::GetStandardNetworkSystemClock)}, - {0x3, SFUNC(time::GetTimeZoneService)}, - {0x4, SFUNC(time::GetStandardLocalSystemClock)} - }) {} - - void time::GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - manager.RegisterService(std::make_shared(SystemClockType::User, state, manager), session, response); - } - - void time::GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - manager.RegisterService(std::make_shared(SystemClockType::Network, state, manager), session, response); - } - - void time::GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - manager.RegisterService(std::make_shared(state, manager), session, response); - } - - void time::GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - manager.RegisterService(std::make_shared(SystemClockType::Local, state, manager), session, response); - } - - ISystemClock::ISystemClock(SystemClockType clockType, const DeviceState &state, ServiceManager &manager) : type(clockType), BaseService(state, manager, Service::time_ISystemClock, "time:ISystemClock", { - {0x0, SFUNC(ISystemClock::GetCurrentTime)} - }) {} - - void ISystemClock::GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - response.Push(static_cast(std::time(nullptr))); - } - - ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::time_ITimeZoneService, "time:ITimeZoneService", { - {0x65, SFUNC(ITimeZoneService::ToCalendarTimeWithMyRule)} - }) {} - - void ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - time_t curTime = std::time(nullptr); - tm calender = *std::gmtime(&curTime); - CalendarTime calendarTime{ - .year = static_cast(calender.tm_year), - .month = static_cast(calender.tm_mon), - .day = static_cast(calender.tm_hour), - .minute = static_cast(calender.tm_min), - .second = static_cast(calender.tm_sec) - }; - response.Push(calendarTime); - CalendarAdditionalInfo calendarInfo{ - .day_week = static_cast(calender.tm_wday), - .day_month = static_cast(calender.tm_mday), - .name = *reinterpret_cast(calender.tm_zone), - .dst = static_cast(calender.tm_isdst), - .utc_rel = static_cast(calender.tm_gmtoff) - }; - response.Push(calendarInfo); - } -} diff --git a/app/src/main/cpp/skyline/services/time/timesrv.h b/app/src/main/cpp/skyline/services/time/timesrv.h deleted file mode 100644 index a52d2eef..00000000 --- a/app/src/main/cpp/skyline/services/time/timesrv.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include -#include - -namespace skyline::service::time { - /** - * @brief The type of a #SystemClockType - */ - enum class SystemClockType { - User, //!< Use time provided by user - Network, //!< Use network time - Local, //!< Use local time - }; - - /** - * @brief time (This covers both time:a and time:s) is responsible for providing handles to various clock services (https://switchbrew.org/wiki/PSC_services#time:su.2C_time:s) - */ - class time : public BaseService { - public: - time(const DeviceState &state, ServiceManager &manager); - - /** - * @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardUserSystemClock) - */ - void GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - - /** - * @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock) - */ - void GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - - /** - * @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock) - */ - void GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - - /** - * @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock) - */ - void GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - }; - - /** - * @brief ISystemClock is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ISystemClock) - */ - class ISystemClock : public BaseService { - public: - SystemClockType type; //!< The type of the system clock - - ISystemClock(SystemClockType clockType, const DeviceState &state, ServiceManager &manager); - - /** - * @brief This returns the amount of seconds since epoch - */ - void GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - }; - - /** - * @brief ITimeZoneService is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ITimeZoneService) - */ - class ITimeZoneService : public BaseService { - public: - /** - * @brief This holds a particular time point in calendar format - */ - struct CalendarTime { - u16 year; - u8 month; - u8 day; - u8 hour; - u8 minute; - u8 second; - u8 : 8; - }; - static_assert(sizeof(CalendarTime) == 8); - - /** - * @brief This is passed in addition to CalendarTime - */ - struct CalendarAdditionalInfo { - u32 day_week; - u32 day_month; - u64 name; - i32 dst; - u32 utc_rel; - }; - static_assert(sizeof(CalendarAdditionalInfo) == 24); - - ITimeZoneService(const DeviceState &state, ServiceManager &manager); - - /** - * @brief This receives a u64 #PosixTime (https://switchbrew.org/wiki/PSC_services#PosixTime), and returns a #CalendarTime (https://switchbrew.org/wiki/PSC_services#CalendarTime), #CalendarAdditionalInfo (https://switchbrew.org/wiki/PSC_services#CalendarAdditionalInfo) - */ - void ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); - }; -} diff --git a/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp b/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp new file mode 100644 index 00000000..d76d89d7 --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/IStaticService.cpp @@ -0,0 +1,28 @@ +#include "IStaticService.h" +#include "ISystemClock.h" +#include "ITimeZoneService.h" + +namespace skyline::service::timesrv { + IStaticService::IStaticService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::timesrv_IStaticService, "timesrv:IStaticService", { + {0x0, SFUNC(IStaticService::GetStandardUserSystemClock)}, + {0x1, SFUNC(IStaticService::GetStandardNetworkSystemClock)}, + {0x3, SFUNC(IStaticService::GetTimeZoneService)}, + {0x4, SFUNC(IStaticService::GetStandardLocalSystemClock)} + }) {} + + void IStaticService::GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + manager.RegisterService(std::make_shared(SystemClockType::User, state, manager), session, response); + } + + void IStaticService::GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + manager.RegisterService(std::make_shared(SystemClockType::Network, state, manager), session, response); + } + + void IStaticService::GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + manager.RegisterService(std::make_shared(state, manager), session, response); + } + + void IStaticService::GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + manager.RegisterService(std::make_shared(SystemClockType::Local, state, manager), session, response); + } +} diff --git a/app/src/main/cpp/skyline/services/timesrv/IStaticService.h b/app/src/main/cpp/skyline/services/timesrv/IStaticService.h new file mode 100644 index 00000000..f41d9866 --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/IStaticService.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace skyline::service::timesrv { + /** + * @brief IStaticService (This covers time:u, time:a and time:s) is responsible for providing handles to various clock services (https://switchbrew.org/wiki/PSC_services#time:su.2C_time:s) + */ + class IStaticService : public BaseService { + public: + IStaticService(const DeviceState &state, ServiceManager &manager); + + /** + * @brief This returns a handle to a ISystemClock for user time + */ + void GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief This returns a handle to a ISystemClock for network time + */ + void GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief This returns a handle to a ITimeZoneService for reading time zone information + */ + void GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief This returns a handle to a ISystemClock for local time + */ + void GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + }; +} diff --git a/app/src/main/cpp/skyline/services/timesrv/ISystemClock.cpp b/app/src/main/cpp/skyline/services/timesrv/ISystemClock.cpp new file mode 100644 index 00000000..b0eadcb9 --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/ISystemClock.cpp @@ -0,0 +1,11 @@ +#include "ISystemClock.h" + +namespace skyline::service::timesrv { + ISystemClock::ISystemClock(const SystemClockType clockType, const DeviceState &state, ServiceManager &manager) : type(clockType), BaseService(state, manager, Service::timesrv_ISystemClock, "timesrv:ISystemClock", { + {0x0, SFUNC(ISystemClock::GetCurrentTime)} + }) {} + + void ISystemClock::GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + response.Push(static_cast(std::time(nullptr))); + } +} diff --git a/app/src/main/cpp/skyline/services/timesrv/ISystemClock.h b/app/src/main/cpp/skyline/services/timesrv/ISystemClock.h new file mode 100644 index 00000000..abca1733 --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/ISystemClock.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +namespace skyline::service::timesrv { + /** + * @brief The type of a #SystemClockType + */ + enum class SystemClockType { + User, //!< Use time provided by user + Network, //!< Use network time + Local, //!< Use local time + }; + + /** + * @brief ISystemClock is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ISystemClock) + */ + class ISystemClock : public BaseService { + public: + const SystemClockType type; //!< The type of the system clock + + ISystemClock(const SystemClockType clockType, const DeviceState &state, ServiceManager &manager); + + /** + * @brief This returns the amount of seconds since epoch + */ + void GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + }; +} diff --git a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp new file mode 100644 index 00000000..990248f7 --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.cpp @@ -0,0 +1,28 @@ +#include "ITimeZoneService.h" + +namespace skyline::service::timesrv { + ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::timesrv_ITimeZoneService, "timesrv:ITimeZoneService", { + {0x65, SFUNC(ITimeZoneService::ToCalendarTimeWithMyRule)} + }) {} + + void ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + time_t curTime = std::time(nullptr); + tm calender = *std::gmtime(&curTime); + CalendarTime calendarTime{ + .year = static_cast(calender.tm_year), + .month = static_cast(calender.tm_mon), + .day = static_cast(calender.tm_hour), + .minute = static_cast(calender.tm_min), + .second = static_cast(calender.tm_sec) + }; + response.Push(calendarTime); + CalendarAdditionalInfo calendarInfo{ + .day_week = static_cast(calender.tm_wday), + .day_month = static_cast(calender.tm_mday), + .name = *reinterpret_cast(calender.tm_zone), + .dst = static_cast(calender.tm_isdst), + .utc_rel = static_cast(calender.tm_gmtoff) + }; + response.Push(calendarInfo); + } +} diff --git a/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h new file mode 100644 index 00000000..d777163b --- /dev/null +++ b/app/src/main/cpp/skyline/services/timesrv/ITimeZoneService.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +namespace skyline::service::timesrv { + /** + * @brief ITimeZoneService is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ITimeZoneService) + */ + class ITimeZoneService : public BaseService { + private: + /** + * @brief This holds a particular time point in calendar format + */ + struct CalendarTime { + u16 year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; + u8 _pad_; + }; + static_assert(sizeof(CalendarTime) == 0x8); + + /** + * @brief This is passed in addition to CalendarTime + */ + struct CalendarAdditionalInfo { + u32 day_week; + u32 day_month; + u64 name; + i32 dst; + u32 utc_rel; + }; + static_assert(sizeof(CalendarAdditionalInfo) == 0x18); + + public: + ITimeZoneService(const DeviceState &state, ServiceManager &manager); + + /** + * @brief This receives a u64 #PosixTime (https://switchbrew.org/wiki/PSC_services#PosixTime), and returns a #CalendarTime (https://switchbrew.org/wiki/PSC_services#CalendarTime), #CalendarAdditionalInfo (https://switchbrew.org/wiki/PSC_services#CalendarAdditionalInfo) + */ + void ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + }; +}