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.
This commit is contained in:
Zephyron 2025-01-30 22:10:08 +10:00 committed by Mike Lothian
parent e61f612d8d
commit c69ef17cdd
7 changed files with 73 additions and 25 deletions

View File

@ -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<SystemArchiveDescriptor, SYSTEM_ARCHIVE_COUNT> 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) {

View File

@ -317,6 +317,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<Result>(res).IsSuccess())
#define R_FAILED(res) (static_cast<Result>(res).IsFailure())

View File

@ -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

View File

@ -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<ISystemUpdateControl>
public:
explicit ISystemUpdateControl(Core::System& system_);
~ISystemUpdateControl() override;
private:
void SetupToReceiveSystemUpdate(HLERequestContext& ctx);
void RequestCheckLatestUpdateIncludesRebootlessUpdate(HLERequestContext& ctx);
};
} // namespace Service::NS

View File

@ -512,9 +512,9 @@ static_assert(sizeof(TvSettings) == 0x20, "TvSettings is an invalid size");
/// This is nn::settings::system::RebootlessSystemUpdateVersion
struct RebootlessSystemUpdateVersion {
u32 version;
u8 reserved[0x1c];
char display_version[0x20];
char display_version[0x3C]; // Size to make total struct 0x40 bytes
};
static_assert(sizeof(RebootlessSystemUpdateVersion) == 0x40, "RebootlessSystemUpdateVersion is an invalid size");
static_assert(sizeof(RebootlessSystemUpdateVersion) == 0x40,
"RebootlessSystemUpdateVersion is an invalid size");
} // namespace Service::Set

View File

@ -906,7 +906,7 @@ Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(
Result ISystemSettingsServer::GetDebugModeFlag(Out<bool> is_debug_mode_enabled) {
const auto result = GetSettingsItemValueImpl<bool>(*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);
@ -1194,15 +1194,6 @@ Result ISystemSettingsServer::SetKeyboardLayout(KeyboardLayout keyboard_layout)
R_SUCCEED();
}
Result ISystemSettingsServer::GetRebootlessSystemUpdateVersion(Out<RebootlessSystemUpdateVersion> out_rebootless_system_update) {
LOG_INFO(Service_SET, "(STUBBED) called");
out_rebootless_system_update->version = 0;
strcpy(out_rebootless_system_update->display_version, "0.0.0");
R_SUCCEED();
}
Result ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(
Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point) {
LOG_INFO(Service_SET, "called");
@ -1315,6 +1306,18 @@ Result ISystemSettingsServer::SetPanelCrcMode(s32 panel_crc_mode) {
R_SUCCEED();
}
Result ISystemSettingsServer::GetRebootlessSystemUpdateVersion(
Out<RebootlessSystemUpdateVersion> 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::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050";

View File

@ -38,12 +38,15 @@ public:
const std::string& category, const std::string& name);
template <typename T>
Result GetSettingsItemValueImpl(T& out_value, const std::string& category,
const std::string& name) {
u64 data_size{};
std::vector<u8> data(sizeof(T));
R_TRY(GetSettingsItemValueImpl(data, data_size, category, name));
std::memcpy(&out_value, data.data(), data_size);
Result GetSettingsItemValueImpl(T& output_value, const std::string& category,
const std::string& name) {
const size_t value_size = sizeof(T);
std::vector<u8> raw_data(value_size);
u64 actual_size{};
R_TRY(GetSettingsItemValueImpl(raw_data, actual_size, category, name));
std::memcpy(&output_value, raw_data.data(), actual_size);
R_SUCCEED();
}
@ -136,7 +139,6 @@ public:
Result SetAppletLaunchFlags(u32 applet_launch_flag);
Result GetKeyboardLayout(Out<KeyboardLayout> out_keyboard_layout);
Result SetKeyboardLayout(KeyboardLayout keyboard_layout);
Result GetRebootlessSystemUpdateVersion(Out<RebootlessSystemUpdateVersion> out_rebootless_system_update);
Result GetDeviceTimeZoneLocationUpdatedTime(
Out<Service::PSC::Time::SteadyClockTimePoint> out_time_point);
Result SetDeviceTimeZoneLocationUpdatedTime(
@ -156,6 +158,7 @@ public:
Result GetFieldTestingFlag(Out<bool> out_field_testing_flag);
Result GetPanelCrcMode(Out<s32> out_panel_crc_mode);
Result SetPanelCrcMode(s32 panel_crc_mode);
Result GetRebootlessSystemUpdateVersion(Out<RebootlessSystemUpdateVersion> out_rebootless_system_update);
private:
bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func);