From 6ab82e8eeb3972745de76432c57dcaf29f3a45d3 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Thu, 30 Jan 2025 22:10:08 +1000 Subject: [PATCH] service: Implement rebootless system update stubs and types Adds initial support for rebootless system update related functionality: - Add system archive title IDs for ApplicationBlackList, RebootlessSystemUpdateVersion, and ContentActionTable - Add NS service result codes for system update operations - Implement stubs for ISystemUpdateControl::SetupToReceiveSystemUpdate and RequestCheckLatestUpdateIncludesRebootlessUpdate - Add RebootlessSystemUpdateVersion settings type and implement GetRebootlessSystemUpdateVersion in SET service - Fix GetSettingsItemValueImpl template implementation This provides basic infrastructure for handling system updates, particularly the rebootless update feature, though actual update functionality remains stubbed. --- .../file_sys/system_archive/system_archive.cpp | 12 +++++++++--- src/core/hle/result.h | 17 +++++++++++++++++ .../hle/service/ns/system_update_control.cpp | 18 ++++++++++++++++-- .../hle/service/ns/system_update_control.h | 5 +++++ src/core/hle/service/set/settings_types.h | 8 ++++++++ .../hle/service/set/system_settings_server.cpp | 16 ++++++++++++++-- .../hle/service/set/system_settings_server.h | 9 ++++----- 7 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/core/file_sys/system_archive/system_archive.cpp b/src/core/file_sys/system_archive/system_archive.cpp index b53eef877..4a189923d 100644 --- a/src/core/file_sys/system_archive/system_archive.cpp +++ b/src/core/file_sys/system_archive/system_archive.cpp @@ -12,6 +12,12 @@ namespace FileSys::SystemArchive { +namespace { + constexpr u64 ApplicationBlackListTID = 0x0100000000000825; + constexpr u64 RebootlessSystemUpdateVersionTID = 0x0100000000000826; + constexpr u64 ContentActionTableTID = 0x0100000000000827; +} // namespace + constexpr u64 SYSTEM_ARCHIVE_BASE_TITLE_ID = 0x0100000000000800; constexpr std::size_t SYSTEM_ARCHIVE_COUNT = 0x28; @@ -61,9 +67,9 @@ constexpr std::array SYSTEM_ARCHI {0x0100000000000822, "ControllerFirmware", nullptr}, {0x0100000000000823, "NgWord2", &NgWord2}, {0x0100000000000824, "PlatformConfigIcosaMariko", nullptr}, - {0x0100000000000825, "ApplicationBlackList", nullptr}, - {0x0100000000000826, "RebootlessSystemUpdateVersion", nullptr}, - {0x0100000000000827, "ContentActionTable", nullptr}, + {ApplicationBlackListTID, "ApplicationBlackList", nullptr}, + {RebootlessSystemUpdateVersionTID, "RebootlessSystemUpdateVersion", nullptr}, + {ContentActionTableTID, "ContentActionTable", nullptr}, }}; VirtualFile SynthesizeSystemArchive(const u64 title_id) { diff --git a/src/core/hle/result.h b/src/core/hle/result.h index b0a32d74b..ae1942645 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -292,6 +292,23 @@ private: u32 description_end; }; +namespace ResultNs { + + constexpr ResultRange InvalidSystemUpdateData{ErrorModule::NS, 101, 200}; + constexpr ResultRange RebootlessSystemUpdateNotSupported{ErrorModule::NS, 201, 300}; + constexpr ResultRange SystemUpdateNotFound{ErrorModule::NS, 301, 400}; + constexpr ResultRange RebootlessSystemUpdateVersionMismatch{ErrorModule::NS, 401, 500}; + + constexpr ResultRange SystemUpdateInProgress{ErrorModule::NS, 501, 600}; + constexpr ResultRange SystemUpdateInterrupted{ErrorModule::NS, 601, 700}; + constexpr ResultRange InvalidRebootlessVersion{ErrorModule::NS, 701, 800}; + constexpr ResultRange ContentVerificationFailed{ErrorModule::NS, 801, 900}; + constexpr ResultRange UpdateApplicationBlackListed{ErrorModule::NS, 901, 1000}; + constexpr ResultRange ContentActionTableError{ErrorModule::NS, 1001, 1100}; + constexpr ResultRange SetupReceiveUpdateFailed{ErrorModule::NS, 1101, 1200}; + +} // namespace ResultNs + #define R_SUCCEEDED(res) (static_cast(res).IsSuccess()) #define R_FAILED(res) (static_cast(res).IsFailure()) diff --git a/src/core/hle/service/ns/system_update_control.cpp b/src/core/hle/service/ns/system_update_control.cpp index f5f5cfd90..42e7cb219 100644 --- a/src/core/hle/service/ns/system_update_control.cpp +++ b/src/core/hle/service/ns/system_update_control.cpp @@ -3,6 +3,7 @@ #include "core/hle/service/cmif_serialization.h" #include "core/hle/service/ns/system_update_control.h" +#include "system_update_control.h" namespace Service::NS { @@ -31,8 +32,9 @@ ISystemUpdateControl::ISystemUpdateControl(Core::System& system_) {18, nullptr, "ApplyReceivedUpdate"}, {19, nullptr, "GetReceivedEulaDataSize"}, {20, nullptr, "GetReceivedEulaData"}, - {21, nullptr, "SetupToReceiveSystemUpdate"}, - {22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"}, + {21, &ISystemUpdateControl::SetupToReceiveSystemUpdate, "SetupToReceiveSystemUpdate"}, + {22, &ISystemUpdateControl::RequestCheckLatestUpdateIncludesRebootlessUpdate, + "RequestCheckLatestUpdateIncludesRebootlessUpdate"}, }; // clang-format on @@ -41,4 +43,16 @@ ISystemUpdateControl::ISystemUpdateControl(Core::System& system_) ISystemUpdateControl::~ISystemUpdateControl() = default; +void ISystemUpdateControl::SetupToReceiveSystemUpdate(HLERequestContext& ctx) { + LOG_WARNING(Service_NS, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultNs::SetupReceiveUpdateFailed); +} + +void ISystemUpdateControl::RequestCheckLatestUpdateIncludesRebootlessUpdate(HLERequestContext& ctx) { + LOG_WARNING(Service_NS, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultNs::RebootlessSystemUpdateNotSupported); +} + } // namespace Service::NS diff --git a/src/core/hle/service/ns/system_update_control.h b/src/core/hle/service/ns/system_update_control.h index a30a09000..5e92354ee 100644 --- a/src/core/hle/service/ns/system_update_control.h +++ b/src/core/hle/service/ns/system_update_control.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" namespace Service::NS { @@ -11,6 +12,10 @@ class ISystemUpdateControl final : public ServiceFramework public: explicit ISystemUpdateControl(Core::System& system_); ~ISystemUpdateControl() override; + +private: + void SetupToReceiveSystemUpdate(HLERequestContext& ctx); + void RequestCheckLatestUpdateIncludesRebootlessUpdate(HLERequestContext& ctx); }; } // namespace Service::NS diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 92c2948b0..d767b5f34 100644 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h @@ -501,4 +501,12 @@ struct TvSettings { }; static_assert(sizeof(TvSettings) == 0x20, "TvSettings is an invalid size"); +/// This is nn::settings::system::RebootlessSystemUpdateVersion +struct RebootlessSystemUpdateVersion { + u32 version; + char display_version[0x3C]; // Size to make total struct 0x40 bytes +}; +static_assert(sizeof(RebootlessSystemUpdateVersion) == 0x40, + "RebootlessSystemUpdateVersion is an invalid size"); + } // namespace Service::Set diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 5c2a36f00..3118d6621 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -238,7 +238,7 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {146, nullptr, "SetConsoleSixAxisSensorAngularVelocityTimeBias"}, {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, - {149, nullptr, "GetRebootlessSystemUpdateVersion"}, + {149, C<&ISystemSettingsServer::GetRebootlessSystemUpdateVersion>, "GetRebootlessSystemUpdateVersion"}, {150, C<&ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime>, "GetDeviceTimeZoneLocationUpdatedTime"}, {151, C<&ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime>, "SetDeviceTimeZoneLocationUpdatedTime"}, {152, C<&ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime>, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, @@ -906,7 +906,7 @@ Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled( Result ISystemSettingsServer::GetDebugModeFlag(Out is_debug_mode_enabled) { const auto result = GetSettingsItemValueImpl(*is_debug_mode_enabled, "settings_debug", - "is_debug_mode_enabled"); + "is_debug_mode_enabled"); LOG_DEBUG(Service_SET, "called, is_debug_mode_enabled={}", *is_debug_mode_enabled); R_RETURN(result); @@ -1306,6 +1306,18 @@ Result ISystemSettingsServer::SetPanelCrcMode(s32 panel_crc_mode) { R_SUCCEED(); } +Result ISystemSettingsServer::GetRebootlessSystemUpdateVersion( + Out out_rebootless_system_update) { + LOG_INFO(Service_SET, "called"); + + out_rebootless_system_update->version = 0; + std::memset(out_rebootless_system_update->display_version, 0, + sizeof(out_rebootless_system_update->display_version)); + std::strcpy(out_rebootless_system_update->display_version, "0.0.0"); + + R_SUCCEED(); +} + void ISystemSettingsServer::SetupSettings() { auto system_dir = Common::FS::GetCitronPath(Common::FS::CitronPath::NANDDir) / "system/save/8000000000000050"; diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 993e5de7d..0e1e470a8 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -40,11 +40,9 @@ public: template Result GetSettingsItemValueImpl(T& out_value, const std::string& category, const std::string& name) { - u64 data_size{}; - std::vector data(sizeof(T)); - R_TRY(GetSettingsItemValueImpl(data, data_size, category, name)); - std::memcpy(&out_value, data.data(), data_size); - R_SUCCEED(); + u64 size{}; + R_RETURN(GetSettingsItemValueImpl(std::span{reinterpret_cast(&out_value), sizeof(T)}, + size, category, name)); } public: @@ -155,6 +153,7 @@ public: Result GetFieldTestingFlag(Out out_field_testing_flag); Result GetPanelCrcMode(Out out_panel_crc_mode); Result SetPanelCrcMode(s32 panel_crc_mode); + Result GetRebootlessSystemUpdateVersion(Out out_rebootless_system_update); private: bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func);