htc: implement (fixing linker errors) through HtclowManagerImpl::OpenDriver

This commit is contained in:
Michael Scire 2021-02-08 01:25:10 -08:00 committed by SciresM
parent 1687bf2e07
commit c878123274
30 changed files with 582 additions and 22 deletions

View file

@ -21,6 +21,8 @@ namespace ams::htclow {
namespace impl {
enum class DriverType {
Unknown = 0,
Debug = 1,
Socket = 2,
Usb = 3,
HostBridge = 4,
@ -29,5 +31,6 @@ namespace ams::htclow {
}
constexpr inline s16 ProtocolVersion = 5;
}

View file

@ -20,6 +20,7 @@
#include <stratosphere/settings/settings_fwdbg_types.hpp>
#include <stratosphere/settings/settings_fwdbg_api.hpp>
#include <stratosphere/settings/factory/settings_serial_number.hpp>
#include <stratosphere/settings/factory/settings_configuration_id.hpp>
#include <stratosphere/settings/factory/settings_device_certificate.hpp>
#include <stratosphere/settings/system/settings_error_report.hpp>
#include <stratosphere/settings/system/settings_firmware_version.hpp>

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::settings::factory {
struct ConfigurationId1 {
char str[30];
};
static_assert(sizeof(ConfigurationId1) == 30);
static_assert(util::is_pod<ConfigurationId1>::value);
void GetConfigurationId1(ConfigurationId1 *out);
}

View file

@ -24,4 +24,6 @@ namespace ams::settings::factory {
static_assert(sizeof(SerialNumber) == 0x18);
static_assert(util::is_pod<SerialNumber>::value);
Result GetSerialNumber(SerialNumber *out);
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_ctrl_service.hpp"
#include "../mux/htclow_mux.hpp"
namespace ams::htclow::ctrl {
namespace {
constexpr const char BeaconPacketResponseTemplate[] =
"{\r\n"
" \"Spec\" : \"%s\",\r\n"
" \"Conn\" : \"%s\",\r\n"
" \"HW\" : \"%s\",\r\n"
" \"Name\" : \"%s\",\r\n"
" \"SN\" : \"%s\",\r\n"
" \"FW\" : \"%s\",\r\n"
" \"Prot\" : \"%d\"\r\n"
"}\r\n";
}
HtcctrlService::HtcctrlService(HtcctrlPacketFactory *pf, HtcctrlStateMachine *sm, mux::Mux *mux)
: m_settings_holder(), m_beacon_response(), m_1100(), m_packet_factory(pf), m_state_machine(sm), m_mux(mux), m_event(os::EventClearMode_ManualClear),
m_send_buffer(pf), m_mutex(), m_condvar(), m_2170(), m_version(ProtocolVersion)
{
/* Lock ourselves. */
std::scoped_lock lk(m_mutex);
/* Set the mux version. */
m_mux->SetVersion(m_version);
/* Update our beacon response. */
this->UpdateBeaconResponse(this->GetConnectionType(impl::DriverType::Unknown));
}
const char *HtcctrlService::GetConnectionType(impl::DriverType driver_type) const {
switch (driver_type) {
case impl::DriverType::Socket: return "TCP";
case impl::DriverType::Usb: return "USB-gen2";
case impl::DriverType::PlainChannel: return "HBPC-gen2";
default: return "Unknown";
}
}
void HtcctrlService::UpdateBeaconResponse(const char *connection) {
/* Load settings into the holder. */
m_settings_holder.LoadSettings();
/* Print our beacon response. */
util::SNPrintf(m_beacon_response, sizeof(m_beacon_response), BeaconPacketResponseTemplate,
m_settings_holder.GetSpec(),
connection,
m_settings_holder.GetHardwareType(),
m_settings_holder.GetTargetName(),
m_settings_holder.GetSerialNumber(),
m_settings_holder.GetFirmwareVersion(),
ProtocolVersion
);
}
}

View file

@ -40,17 +40,21 @@ namespace ams::htclow::ctrl {
class HtcctrlService {
private:
SettingsHolder m_settings_holder;
u8 m_beacon_response[0x1000];
char m_beacon_response[0x1000];
u8 m_1100[0x1000];
HtcctrlPacketFactory *m_packet_factory;
HtcctrlStateMachine *m_state_machine;
mux::Mux *m_mux;
os::EventType m_event;
os::Event m_event;
HtcctrlSendBuffer m_send_buffer;
os::SdkMutex m_mutex;
os::SdkConditionVariable m_condvar;
u8 m_2170[0x1000];
u16 m_version;
s16 m_version;
private:
const char *GetConnectionType(impl::DriverType driver_type) const;
void UpdateBeaconResponse(const char *connection);
public:
HtcctrlService(HtcctrlPacketFactory *pf, HtcctrlStateMachine *sm, mux::Mux *mux);
};

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_ctrl_settings_holder.hpp"
namespace ams::htclow::ctrl {
void SettingsHolder::LoadSettings() {
/* Load configuration id. */
{
settings::factory::ConfigurationId1 cfg_id;
settings::factory::GetConfigurationId1(std::addressof(cfg_id));
if (cfg_id.str[0]) {
util::Strlcpy(m_hardware_type, cfg_id.str, sizeof(m_hardware_type));
} else {
util::Strlcpy(m_hardware_type, "Unknown", sizeof(m_hardware_type));
}
}
/* Load device name. */
{
char device_name[0x40];
settings::fwdbg::GetSettingsItemValue(device_name, sizeof(device_name), "target_manager", "device_name");
util::Strlcpy(m_target_name, device_name, sizeof(m_target_name));
}
/* Load serial number. */
{
settings::factory::SerialNumber sn;
if (R_SUCCEEDED(settings::factory::GetSerialNumber(std::addressof(sn)))) {
util::Strlcpy(m_serial_number, sn.str, sizeof(m_serial_number));
} else {
m_serial_number[0] = '\x00';
}
}
/* Load firmware version. */
{
settings::system::FirmwareVersion fw_ver;
settings::system::GetFirmwareVersion(std::addressof(fw_ver));
util::Strlcpy(m_firmware_version, fw_ver.display_name, sizeof(m_firmware_version));
}
}
}

View file

@ -26,6 +26,14 @@ namespace ams::htclow::ctrl {
char m_firmware_version[0x40];
public:
SettingsHolder() { /* ... */ }
void LoadSettings();
const char *GetSpec() { return "NX"; }
const char *GetHardwareType() { return m_hardware_type; }
const char *GetTargetName() { return m_target_name; }
const char *GetSerialNumber() { return m_serial_number; }
const char *GetFirmwareVersion() { return m_firmware_version; }
};
}

View file

@ -20,6 +20,7 @@ namespace ams::htclow::ctrl {
namespace {
/* TODO: Real module id names */
constexpr const impl::ChannelInternalType ServiceChannels[] = {
{
.channel_id = 0,

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_listener.hpp"
namespace ams::htclow {
Listener::Listener(mem::StandardAllocator *allocator, mux::Mux *mux, ctrl::HtcctrlService *ctrl_srv, Worker *worker)
: m_thread_stack_size(4_KB), m_allocator(allocator), m_mux(mux), m_service(ctrl_srv), m_worker(worker), m_event(os::EventClearMode_ManualClear), m_driver(nullptr), m_thread_running(false), m_cancelled(false)
{
/* Allocate stack. */
m_listen_thread_stack = m_allocator->Allocate(m_thread_stack_size, os::ThreadStackAlignment);
}
}

View file

@ -26,7 +26,7 @@ namespace ams::htclow {
mux::Mux *m_mux;
ctrl::HtcctrlService *m_service;
Worker *m_worker;
os::EventType m_event;
os::Event m_event;
os::ThreadType m_listen_thread;
void *m_listen_thread_stack;
driver::IDriver *m_driver;

View file

@ -31,8 +31,10 @@ namespace ams::htclow {
/* ... */
}
//Result HtclowManagerImpl::OpenDriver(impl::DriverType driver_type);
//
Result HtclowManagerImpl::OpenDriver(impl::DriverType driver_type) {
AMS_ABORT("TODO");
}
//void HtclowManagerImpl::CloseDriver();
//
//void HtclowManagerImpl::Disconnect();

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_worker.hpp"
namespace ams::htclow {
Worker::Worker(mem::StandardAllocator *allocator, mux::Mux *mux, ctrl::HtcctrlService *ctrl_srv)
: m_thread_stack_size(4_KB), m_allocator(allocator), m_mux(mux), m_service(ctrl_srv), m_driver(nullptr), m_event(os::EventClearMode_ManualClear), m_7C400()
{
/* Allocate stacks. */
m_receive_thread_stack = m_allocator->Allocate(m_thread_stack_size, os::ThreadStackAlignment);
m_send_thread_stack = m_allocator->Allocate(m_thread_stack_size, os::ThreadStackAlignment);
}
}

View file

@ -31,7 +31,7 @@ namespace ams::htclow {
driver::IDriver *m_driver;
os::ThreadType m_receive_thread;
os::ThreadType m_send_thread;
os::EventType m_event;
os::Event m_event;
void *m_receive_thread_stack;
void *m_send_thread_stack;
u8 m_7C400;

View file

@ -21,9 +21,20 @@ namespace ams::htclow::mux {
Mux::Mux(PacketFactory *pf, ctrl::HtcctrlStateMachine *sm)
: m_packet_factory(pf), m_state_machine(sm), m_task_manager(), m_wake_event(os::EventClearMode_ManualClear),
m_channel_impl_map(pf, sm, std::addressof(m_task_manager), std::addressof(m_wake_event)), m_global_send_buffer(pf),
m_mutex(), m_is_sleeping(false), m_version(5)
m_mutex(), m_is_sleeping(false), m_version(ProtocolVersion)
{
/* ... */
}
void Mux::SetVersion(u16 version) {
/* Set our version. */
m_version = version;
/* Set all entries in our map. */
/* NOTE: Nintendo does this highly inefficiently... */
for (auto &pair : m_channel_impl_map.GetMap()) {
m_channel_impl_map[pair.first].SetVersion(m_version);
}
}
}

View file

@ -34,6 +34,8 @@ namespace ams::htclow::mux {
u16 m_version;
public:
Mux(PacketFactory *pf, ctrl::HtcctrlStateMachine *sm);
void SetVersion(u16 version);
};
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_mux_channel_impl.hpp"
namespace ams::htclow::mux {
void ChannelImpl::SetVersion(s16 version) {
/* Sanity check the version. */
AMS_ASSERT(version <= ProtocolVersion);
/* Set version. */
m_version = version;
m_send_buffer.SetVersion(version);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
#include "htclow_mux_task_manager.hpp"
#include "htclow_mux_send_buffer.hpp"
namespace ams::htclow {
class PacketFactory;
namespace ctrl {
class HtcctrlStateMachine;
}
}
namespace ams::htclow::mux {
class ChannelImpl {
private:
impl::ChannelInternalType m_channel;
PacketFactory *m_packet_factory;
ctrl::HtcctrlStateMachine *m_state_machine;
TaskManager *m_task_manager;
os::Event *m_event;
SendBuffer m_send_buffer;
RingBuffer m_receive_buffer;
s16 m_version;
/* TODO: Channel config */
/* TODO: tracking variables. */
std::optional<u64> m_108;
os::Event m_send_packet_event;
/* TODO: Channel state. */
public:
ChannelImpl(impl::ChannelInternalType channel, PacketFactory *pf, ctrl::HtcctrlStateMachine *sm, TaskManager *tm, os::Event *ev);
void SetVersion(s16 version);
};
}

View file

@ -30,4 +30,17 @@ namespace ams::htclow::mux {
}
}
ChannelImpl &ChannelImplMap::GetChannelImpl(int index) {
return GetReference(m_channel_storage[index]);
}
ChannelImpl &ChannelImplMap::GetChannelImpl(impl::ChannelInternalType channel) {
/* Find the channel. */
auto it = m_map.find(channel);
AMS_ASSERT(it != m_map.end());
/* Return the implementation object. */
return this->GetChannelImpl(it->second);
}
}

View file

@ -15,19 +15,7 @@
*/
#pragma once
#include <stratosphere.hpp>
#include "htclow_mux_task_manager.hpp"
namespace ams::htclow {
class PacketFactory;
namespace ctrl {
class HtcctrlStateMachine;
}
}
#include "htclow_mux_channel_impl.hpp"
namespace ams::htclow::mux {
@ -47,10 +35,22 @@ namespace ams::htclow::mux {
os::Event *m_event;
u8 m_map_buffer[MapRequiredMemorySize];
MapType m_map;
u8 m_storage[0x5200]; /* TODO */
TYPED_STORAGE(ChannelImpl) m_channel_storage[MaxChannelCount];
bool m_storage_valid[MaxChannelCount];
public:
ChannelImplMap(PacketFactory *pf, ctrl::HtcctrlStateMachine *sm, TaskManager *tm, os::Event *ev);
ChannelImpl &GetChannelImpl(impl::ChannelInternalType channel);
private:
ChannelImpl &GetChannelImpl(int index);
public:
MapType &GetMap() {
return m_map;
}
ChannelImpl &operator[](impl::ChannelInternalType channel) {
return this->GetChannelImpl(channel);
}
};
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
namespace ams::htclow::mux {
class RingBuffer {
private:
void *m_buffer;
void *m_read_only_buffer;
bool m_is_read_only;
size_t m_buffer_size;
size_t m_data_size;
size_t m_offset;
bool m_has_copied;
public:
RingBuffer() : m_buffer(), m_read_only_buffer(), m_is_read_only(true), m_buffer_size(), m_data_size(), m_offset(), m_has_copied(false) { /* ... */ }
};
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "htclow_mux_channel_impl.hpp"
namespace ams::htclow::mux {
void SendBuffer::SetVersion(s16 version) {
/* Set version. */
m_version = version;
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
#include "../htclow_packet.hpp"
#include "htclow_mux_ring_buffer.hpp"
namespace ams::htclow {
class PacketFactory;
}
namespace ams::htclow::mux {
class SendBuffer {
private:
using PacketList = util::IntrusiveListBaseTraits<Packet>::ListType;
private:
impl::ChannelInternalType m_channel;
PacketFactory *m_packet_factory;
RingBuffer m_ring_buffer;
PacketList m_packet_list;
s16 m_version;
bool m_flow_control_enabled;
size_t m_max_packet_size;
public:
SendBuffer(impl::ChannelInternalType channel, PacketFactory *pf);
void SetVersion(s16 version);
};
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "settings_serial_number_impl.hpp"
namespace ams::settings::impl {
Result GetConfigurationId1(settings::factory::ConfigurationId1 *out) {
static_assert(sizeof(*out) == sizeof(::SetCalConfigurationId1));
return ::setcalGetConfigurationId1(reinterpret_cast<::SetCalConfigurationId1 *>(out));
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
namespace ams::settings::impl {
Result GetConfigurationId1(settings::factory::ConfigurationId1 *out);
}

View file

@ -18,6 +18,11 @@
namespace ams::settings::impl {
Result GetSerialNumber(settings::factory::SerialNumber *out) {
static_assert(sizeof(*out) == sizeof(::SetCalSerialNumber));
return ::setcalGetSerialNumber(reinterpret_cast<::SetCalSerialNumber *>(out));
}
Result GetSerialNumber(settings::system::SerialNumber *out) {
static_assert(sizeof(*out) == sizeof(::SetSysSerialNumber));
return ::setsysGetSerialNumber(reinterpret_cast<::SetSysSerialNumber *>(out));

View file

@ -18,6 +18,7 @@
namespace ams::settings::impl {
Result GetSerialNumber(settings::factory::SerialNumber *out);
Result GetSerialNumber(settings::system::SerialNumber *out);
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "impl/settings_configuration_id_impl.hpp"
namespace ams::settings::factory {
void GetConfigurationId1(ConfigurationId1 *out) {
R_ABORT_UNLESS(settings::impl::GetConfigurationId1(out));
}
}

View file

@ -16,6 +16,20 @@
#include <stratosphere.hpp>
#include "impl/settings_serial_number_impl.hpp"
namespace ams::settings::factory {
Result GetSerialNumber(SerialNumber *out) {
const Result result = settings::impl::GetSerialNumber(out);
if (!settings::ResultCalibrationDataFileSystemCorrupted::Includes(result) && !settings::ResultCalibrationDataCrcError::Includes(result)) {
R_ABORT_UNLESS(result);
}
return result;
}
}
namespace ams::settings::system {
void GetSerialNumber(SerialNumber *out) {

View file

@ -44,4 +44,9 @@ namespace ams::settings {
R_DEFINE_ERROR_RESULT(SettingsItemKeyInvalidFormat, 262);
R_DEFINE_ERROR_RESULT(SettingsItemValueInvalidFormat, 263);
R_DEFINE_ERROR_RANGE(CalibrationDataError, 580, 599);
R_DEFINE_ERROR_RESULT(CalibrationDataFileSystemCorrupted, 581);
R_DEFINE_ERROR_RESULT(CalibrationDataCrcError, 582);
R_DEFINE_ERROR_RESULT(CalibrationDataShaError, 583);
}