From 6c045c9beb9c202fdea49274edd845fb2af491c3 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 10:52:48 -0600 Subject: service: nfc: fix tagprotocol and implement GetApplicationAreaId --- src/core/hle/service/nfp/nfp_device.cpp | 33 +++++++++++++++++++++++++++++++-- src/core/hle/service/nfp/nfp_device.h | 6 ++++-- src/core/hle/service/nfp/nfp_types.h | 10 +++++++--- src/core/hle/service/nfp/nfp_user.cpp | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index b19672560..2f9dfa9c2 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -77,6 +77,9 @@ void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { LoadAmiibo(nfc_status.data); break; case Common::Input::NfcState::AmiiboRemoved: + if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) { + break; + } if (device_state != DeviceState::SearchingForTag) { CloseAmiibo(); } @@ -97,6 +100,8 @@ bool NfpDevice::LoadAmiibo(std::span data) { return false; } + // TODO: Filter by allowed_protocols here + memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); device_state = DeviceState::TagFound; @@ -143,7 +148,7 @@ void NfpDevice::Finalize() { device_state = DeviceState::Unavailable; } -Result NfpDevice::StartDetection(s32 protocol_) { +Result NfpDevice::StartDetection([[maybe_unused]] TagProtocol allowed_protocol) { if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); return WrongDeviceState; @@ -155,7 +160,7 @@ Result NfpDevice::StartDetection(s32 protocol_) { } device_state = DeviceState::SearchingForTag; - protocol = protocol_; + allowed_protocols = allowed_protocol; return ResultSuccess; } @@ -469,6 +474,30 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { return ResultSuccess; } +Result NfpDevice::GetApplicationAreaId(u32& application_area_id) const { + if (device_state != DeviceState::TagMounted) { + LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); + if (device_state == DeviceState::TagRemoved) { + return TagRemoved; + } + return WrongDeviceState; + } + + if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { + LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); + return WrongDeviceState; + } + + if (tag_data.settings.settings.appdata_initialized.Value() == 0) { + LOG_WARNING(Service_NFP, "Application area is not initialized"); + return ApplicationAreaIsNotInitialized; + } + + application_area_id = tag_data.application_area_id; + + return ResultSuccess; +} + Result NfpDevice::GetApplicationArea(std::vector& data) const { if (device_state != DeviceState::TagMounted) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 76d0e9ae4..3d1cb4609 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "common/common_funcs.h" @@ -37,7 +38,7 @@ public: void Initialize(); void Finalize(); - Result StartDetection(s32 protocol_); + Result StartDetection(TagProtocol allowed_protocol); Result StopDetection(); Result Mount(MountTarget mount_target); Result Unmount(); @@ -53,6 +54,7 @@ public: Result DeleteAllData(); Result OpenApplicationArea(u32 access_id); + Result GetApplicationAreaId(u32& application_area_id) const; Result GetApplicationArea(std::vector& data) const; Result SetApplicationArea(std::span data); Result CreateApplicationArea(u32 access_id, std::span data); @@ -88,7 +90,7 @@ private: bool is_data_moddified{}; bool is_app_area_open{}; - s32 protocol{}; + TagProtocol allowed_protocols{}; s64 current_posix_time{}; MountTarget mount_target{MountTarget::None}; DeviceState device_state{DeviceState::Unavailable}; diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index 63d5917cb..866aefe20 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -88,11 +88,15 @@ enum class PackedTagType : u8 { Type5, // ISO15693 RW/RO 540 bytes 106kbit/s }; +// Verify this enum. It might be completely wrong default protocol is 0x48 enum class TagProtocol : u32 { None, - TypeA, // ISO14443A - TypeB, // ISO14443B - TypeF, // Sony Felica + TypeA = 1U << 0, // ISO14443A + TypeB = 1U << 1, // ISO14443B + TypeF = 1U << 2, // Sony Felica + Unknown1 = 1U << 3, + Unknown2 = 1U << 5, + All = 0xFFFFFFFFU, }; using UniqueSerialNumber = std::array; diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index 33e2ef518..ac492cc27 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp @@ -130,7 +130,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) { void IUser::StartDetection(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; - const auto nfp_protocol{rp.Pop()}; + const auto nfp_protocol{rp.PopEnum()}; LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol); if (state == State::NonInitialized) { -- cgit v1.2.3 From fb57cd26a1219a5c91d2cb4dec402528f8ba308e Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 11:07:48 -0600 Subject: service: am: Implement cabinet applet backend --- src/core/CMakeLists.txt | 4 + src/core/frontend/applets/cabinet.cpp | 20 +++ src/core/frontend/applets/cabinet.h | 36 +++++ src/core/hle/service/am/applets/applet_cabinet.cpp | 169 +++++++++++++++++++++ src/core/hle/service/am/applets/applet_cabinet.h | 99 ++++++++++++ src/core/hle/service/am/applets/applets.cpp | 20 ++- src/core/hle/service/am/applets/applets.h | 12 +- src/core/hle/service/nfp/nfp_types.h | 7 + 8 files changed, 360 insertions(+), 7 deletions(-) create mode 100644 src/core/frontend/applets/cabinet.cpp create mode 100644 src/core/frontend/applets/cabinet.h create mode 100644 src/core/hle/service/am/applets/applet_cabinet.cpp create mode 100644 src/core/hle/service/am/applets/applet_cabinet.h (limited to 'src/core') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f67f1ce92..740c5b0fd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -120,6 +120,8 @@ add_library(core STATIC file_sys/vfs_vector.h file_sys/xts_archive.cpp file_sys/xts_archive.h + frontend/applets/cabinet.cpp + frontend/applets/cabinet.h frontend/applets/controller.cpp frontend/applets/controller.h frontend/applets/error.cpp @@ -312,6 +314,8 @@ add_library(core STATIC hle/service/am/applet_ae.h hle/service/am/applet_oe.cpp hle/service/am/applet_oe.h + hle/service/am/applets/applet_cabinet.cpp + hle/service/am/applets/applet_cabinet.h hle/service/am/applets/applet_controller.cpp hle/service/am/applets/applet_controller.h hle/service/am/applets/applet_error.cpp diff --git a/src/core/frontend/applets/cabinet.cpp b/src/core/frontend/applets/cabinet.cpp new file mode 100644 index 000000000..5ade75de0 --- /dev/null +++ b/src/core/frontend/applets/cabinet.cpp @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/frontend/applets/cabinet.h" + +#include + +namespace Core::Frontend { + +CabinetApplet::~CabinetApplet() = default; + +void DefaultCabinetApplet::ShowCabinetApplet( + std::function callback, const CabinetParameters& parameters, + std::shared_ptr nfp_device) const { + LOG_WARNING(Service_AM, "(STUBBED) called"); + callback(false, {}); +} + +} // namespace Core::Frontend diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h new file mode 100644 index 000000000..1c68bf57d --- /dev/null +++ b/src/core/frontend/applets/cabinet.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "core/hle/service/nfp/nfp_types.h" + +namespace Service::NFP { +class NfpDevice; +} // namespace Service::NFP + +namespace Core::Frontend { + +struct CabinetParameters { + Service::NFP::TagInfo tag_info; + Service::NFP::RegisterInfo register_info; + Service::NFP::CabinetMode mode; +}; + +class CabinetApplet { +public: + virtual ~CabinetApplet(); + virtual void ShowCabinetApplet(std::function callback, + const CabinetParameters& parameters, + std::shared_ptr nfp_device) const = 0; +}; + +class DefaultCabinetApplet final : public CabinetApplet { +public: + void ShowCabinetApplet(std::function callback, + const CabinetParameters& parameters, + std::shared_ptr nfp_device) const override; +}; + +} // namespace Core::Frontend diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp new file mode 100644 index 000000000..1eb5a9f22 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -0,0 +1,169 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/core.h" +#include "core/frontend/applets/cabinet.h" +#include "core/hid/hid_core.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/service/am/am.h" +#include "core/hle/service/am/applets/applet_cabinet.h" +#include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/nfp/nfp_device.h" + +namespace Service::AM::Applets { + +Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::CabinetApplet& frontend_) + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_}, service_context{ + system_, + "CabinetApplet"} { + + availability_change_event = + service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); +} + +Cabinet::~Cabinet() = default; + +void Cabinet::Initialize() { + Applet::Initialize(); + + LOG_INFO(Service_HID, "Initializing Cabinet Applet."); + + LOG_ERROR(Service_HID, + "Initializing Applet with common_args: arg_version={}, lib_version={}, " + "play_startup_sound={}, size={}, system_tick={}, theme_color={}", + common_args.arguments_version, common_args.library_version, + common_args.play_startup_sound, common_args.size, common_args.system_tick, + common_args.theme_color); + + const auto storage = broker.PopNormalDataToApplet(); + ASSERT(storage != nullptr); + + const auto applet_input_data = storage->GetData(); + ASSERT(applet_input_data.size() >= sizeof(StartParamForAmiiboSettings)); + + std::memcpy(&applet_input_common, applet_input_data.data(), + sizeof(StartParamForAmiiboSettings)); +} + +bool Cabinet::TransactionComplete() const { + return is_complete; +} + +Result Cabinet::GetStatus() const { + return ResultSuccess; +} + +void Cabinet::ExecuteInteractive() { + ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); +} + +void Cabinet::Execute() { + if (is_complete) { + return; + } + + const auto callback = [this](bool apply_changes, const std::string& amiibo_name) { + DisplayCompleted(apply_changes, amiibo_name); + }; + + // TODO: listen on all controllers + if (nfp_device == nullptr) { + nfp_device = std::make_shared( + system.HIDCore().GetFirstNpadId(), system, service_context, availability_change_event); + nfp_device->Initialize(); + nfp_device->StartDetection(Service::NFP::TagProtocol::All); + } + + const Core::Frontend::CabinetParameters parameters{ + .tag_info = applet_input_common.tag_info, + .register_info = applet_input_common.register_info, + .mode = applet_input_common.applet_mode, + }; + + switch (applet_input_common.applet_mode) { + case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: + case Service::NFP::CabinetMode::StartGameDataEraser: + case Service::NFP::CabinetMode::StartRestorer: + case Service::NFP::CabinetMode::StartFormatter: + frontend.ShowCabinetApplet(callback, parameters, nfp_device); + break; + default: + UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); + DisplayCompleted(false, {}); + break; + } +} + +void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_name) { + Service::Mii::MiiManager manager; + ReturnValueForAmiiboSettings applet_output{}; + + if (!apply_changes) { + Cancel(); + } + + if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound && + nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) { + Cancel(); + } + + if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound) { + nfp_device->Mount(Service::NFP::MountTarget::All); + } + + switch (applet_input_common.applet_mode) { + case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { + Service::NFP::AmiiboName name{}; + memccpy(name.data(), amiibo_name.data(), 0, name.size()); + nfp_device->SetNicknameAndOwner(name); + break; + } + case Service::NFP::CabinetMode::StartGameDataEraser: + nfp_device->DeleteApplicationArea(); + break; + case Service::NFP::CabinetMode::StartRestorer: + nfp_device->RestoreAmiibo(); + break; + case Service::NFP::CabinetMode::StartFormatter: + nfp_device->DeleteAllData(); + break; + default: + UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); + break; + } + + applet_output.device_handle = applet_input_common.device_handle; + applet_output.result = CabinetResult::Success; + nfp_device->GetRegisterInfo(applet_output.register_info); + nfp_device->GetTagInfo(applet_output.tag_info); + nfp_device->Finalize(); + + std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); + std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared(system, std::move(out_data))); + broker.SignalStateChanged(); +} + +void Cabinet::Cancel() { + ReturnValueForAmiiboSettings applet_output{}; + applet_output.device_handle = applet_input_common.device_handle; + applet_output.result = CabinetResult::Cancel; + nfp_device->Finalize(); + + std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); + std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared(system, std::move(out_data))); + broker.SignalStateChanged(); +} + +} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h new file mode 100644 index 000000000..2d3f22434 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -0,0 +1,99 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "core/hle/result.h" +#include "core/hle/service/am/applets/applets.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/nfp/nfp_types.h" + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Core { +class System; +} // namespace Core + +namespace Service::NFP { +class NfpDevice; +} + +namespace Service::AM::Applets { + +enum class CabinetAppletVersion : s32 { + Version1 = 0x1, +}; + +enum class CabinetResult : u8 { + Cancel, + Success, +}; + +// This is nn::nfp::AmiiboSettingsStartParam +struct AmiiboSettingsStartParam { + u64 device_handle; + std::array param_1; + std::array param_2; +}; +static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, + "AmiiboSettingsStartParam is an invalid size"); + +// This is nn::nfp::StartParamForAmiiboSettings +struct StartParamForAmiiboSettings { + u8 param_1; + Service::NFP::CabinetMode applet_mode; + u8 flags; + u8 amiibo_settings_1; + u64 device_handle; + Service::NFP::TagInfo tag_info; + Service::NFP::RegisterInfo register_info; + std::array amiibo_settings_3; + INSERT_PADDING_BYTES(0x20); +}; +static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8, + "StartParamForAmiiboSettings is an invalid size"); + +// This is nn::nfp::ReturnValueForAmiiboSettings +struct ReturnValueForAmiiboSettings { + CabinetResult result; + INSERT_PADDING_BYTES(0x3); + u64 device_handle; + Service::NFP::TagInfo tag_info; + Service::NFP::RegisterInfo register_info; + INSERT_PADDING_BYTES(0x24); +}; +static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x190, + "ReturnValueForAmiiboSettings is an invalid size"); + +class Cabinet final : public Applet { +public: + explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::CabinetApplet& frontend_); + ~Cabinet() override; + + void Initialize() override; + + bool TransactionComplete() const override; + Result GetStatus() const override; + void ExecuteInteractive() override; + void Execute() override; + void DisplayCompleted(bool apply_changes, const std::string& amiibo_name); + void Cancel(); + +private: + const Core::Frontend::CabinetApplet& frontend; + Core::System& system; + + bool is_complete{false}; + std::shared_ptr nfp_device; + Kernel::KEvent* availability_change_event; + KernelHelpers::ServiceContext service_context; + StartParamForAmiiboSettings applet_input_common{}; +}; + +} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 7062df21c..10afbc2da 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "core/core.h" +#include "core/frontend/applets/cabinet.h" #include "core/frontend/applets/controller.h" #include "core/frontend/applets/error.h" #include "core/frontend/applets/general_frontend.h" @@ -16,6 +17,7 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" +#include "core/hle/service/am/applets/applet_cabinet.h" #include "core/hle/service/am/applets/applet_controller.h" #include "core/hle/service/am/applets/applet_error.h" #include "core/hle/service/am/applets/applet_general_backend.h" @@ -171,13 +173,15 @@ void Applet::Initialize() { AppletFrontendSet::AppletFrontendSet() = default; -AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, +AppletFrontendSet::AppletFrontendSet(CabinetApplet cabinet_applet, + ControllerApplet controller_applet, ErrorApplet error_applet, MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) - : controller{std::move(controller_applet)}, error{std::move(error_applet)}, - mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, + : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)}, + error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)}, + parental_controls{std::move(parental_controls_applet)}, photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} @@ -196,6 +200,10 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const { } void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { + if (set.cabinet != nullptr) { + frontend.cabinet = std::move(set.cabinet); + } + if (set.controller != nullptr) { frontend.controller = std::move(set.controller); } @@ -235,6 +243,10 @@ void AppletManager::SetDefaultAppletFrontendSet() { } void AppletManager::SetDefaultAppletsIfMissing() { + if (frontend.cabinet == nullptr) { + frontend.cabinet = std::make_unique(); + } + if (frontend.controller == nullptr) { frontend.controller = std::make_unique(system.HIDCore()); @@ -279,6 +291,8 @@ std::shared_ptr AppletManager::GetApplet(AppletId id, LibraryAppletMode switch (id) { case AppletId::Auth: return std::make_shared(system, mode, *frontend.parental_controls); + case AppletId::Cabinet: + return std::make_shared(system, mode, *frontend.cabinet); case AppletId::Controller: return std::make_shared(system, mode, *frontend.controller); case AppletId::Error: diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 12c6a5b1a..a22eb62a8 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -16,6 +16,7 @@ class System; } namespace Core::Frontend { +class CabinetApplet; class ControllerApplet; class ECommerceApplet; class ErrorApplet; @@ -176,6 +177,7 @@ protected: }; struct AppletFrontendSet { + using CabinetApplet = std::unique_ptr; using ControllerApplet = std::unique_ptr; using ErrorApplet = std::unique_ptr; using MiiEdit = std::unique_ptr; @@ -186,10 +188,11 @@ struct AppletFrontendSet { using WebBrowser = std::unique_ptr; AppletFrontendSet(); - AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, - MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, - PhotoViewer photo_viewer_, ProfileSelect profile_select_, - SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); + AppletFrontendSet(CabinetApplet cabinet_applet, ControllerApplet controller_applet, + ErrorApplet error_applet, MiiEdit mii_edit_, + ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, + ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, + WebBrowser web_browser_); ~AppletFrontendSet(); AppletFrontendSet(const AppletFrontendSet&) = delete; @@ -198,6 +201,7 @@ struct AppletFrontendSet { AppletFrontendSet(AppletFrontendSet&&) noexcept; AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; + CabinetApplet cabinet; ControllerApplet controller; ErrorApplet error; MiiEdit mii_edit; diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index 866aefe20..69858096a 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -99,6 +99,13 @@ enum class TagProtocol : u32 { All = 0xFFFFFFFFU, }; +enum class CabinetMode : u8 { + StartNicknameAndOwnerSettings, + StartGameDataEraser, + StartRestorer, + StartFormatter, +}; + using UniqueSerialNumber = std::array; using LockBytes = std::array; using HashData = std::array; -- cgit v1.2.3 From a253d1557d7d1fb1add6ae923ccb452d423d4547 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 13:59:00 -0600 Subject: service: am: Fix cabinet applet result --- src/core/hle/service/am/applets/applet_cabinet.cpp | 20 ++++++++++++++------ src/core/hle/service/am/applets/applet_cabinet.h | 12 ++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 1eb5a9f22..01f577ab9 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -32,7 +32,7 @@ void Cabinet::Initialize() { LOG_INFO(Service_HID, "Initializing Cabinet Applet."); - LOG_ERROR(Service_HID, + LOG_DEBUG(Service_HID, "Initializing Applet with common_args: arg_version={}, lib_version={}, " "play_startup_sound={}, size={}, system_tick={}, theme_color={}", common_args.arguments_version, common_args.library_version, @@ -111,14 +111,14 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam Cancel(); } - if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound) { + if (nfp_device->GetCurrentState() == Service::NFP::DeviceState::TagFound) { nfp_device->Mount(Service::NFP::MountTarget::All); } switch (applet_input_common.applet_mode) { case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { Service::NFP::AmiiboName name{}; - memccpy(name.data(), amiibo_name.data(), 0, name.size()); + memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); nfp_device->SetNicknameAndOwner(name); break; } @@ -137,11 +137,19 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam } applet_output.device_handle = applet_input_common.device_handle; - applet_output.result = CabinetResult::Success; - nfp_device->GetRegisterInfo(applet_output.register_info); - nfp_device->GetTagInfo(applet_output.tag_info); + applet_output.result = CabinetResult::Cancel; + const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); + const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); nfp_device->Finalize(); + if (reg_result.IsSuccess() && tag_result.IsSuccess()) { + applet_output.result = CabinetResult::All; + } else if (reg_result.IsSuccess()) { + applet_output.result = CabinetResult::RegisterInfo; + } else if (tag_result.IsSuccess()) { + applet_output.result = CabinetResult::TagInfo; + } + std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 2d3f22434..8466d5997 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -31,18 +31,21 @@ enum class CabinetAppletVersion : s32 { enum class CabinetResult : u8 { Cancel, - Success, + TagInfo = 1 << 1, + RegisterInfo = 1 << 2, + All = TagInfo | RegisterInfo, }; // This is nn::nfp::AmiiboSettingsStartParam struct AmiiboSettingsStartParam { u64 device_handle; std::array param_1; - std::array param_2; + u8 param_2; }; static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, "AmiiboSettingsStartParam is an invalid size"); +#pragma pack(1) // This is nn::nfp::StartParamForAmiiboSettings struct StartParamForAmiiboSettings { u8 param_1; @@ -53,7 +56,7 @@ struct StartParamForAmiiboSettings { Service::NFP::TagInfo tag_info; Service::NFP::RegisterInfo register_info; std::array amiibo_settings_3; - INSERT_PADDING_BYTES(0x20); + INSERT_PADDING_BYTES(0x24); }; static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8, "StartParamForAmiiboSettings is an invalid size"); @@ -67,8 +70,9 @@ struct ReturnValueForAmiiboSettings { Service::NFP::RegisterInfo register_info; INSERT_PADDING_BYTES(0x24); }; -static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x190, +static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, "ReturnValueForAmiiboSettings is an invalid size"); +#pragma pack() class Cabinet final : public Applet { public: -- cgit v1.2.3 From 75e6ec85e107d6e5422d882b97faaa813970d42e Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 15:14:08 -0600 Subject: general: Address review comments --- src/core/frontend/applets/cabinet.cpp | 2 +- src/core/frontend/applets/cabinet.h | 7 ++++--- src/core/hle/service/am/applets/applet_cabinet.cpp | 16 ++++++++-------- src/core/hle/service/am/applets/applet_cabinet.h | 11 ++++++----- src/core/hle/service/nfp/nfp_device.cpp | 4 +++- 5 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/core') diff --git a/src/core/frontend/applets/cabinet.cpp b/src/core/frontend/applets/cabinet.cpp index 5ade75de0..26c7fefe3 100644 --- a/src/core/frontend/applets/cabinet.cpp +++ b/src/core/frontend/applets/cabinet.cpp @@ -11,7 +11,7 @@ namespace Core::Frontend { CabinetApplet::~CabinetApplet() = default; void DefaultCabinetApplet::ShowCabinetApplet( - std::function callback, const CabinetParameters& parameters, + const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const { LOG_WARNING(Service_AM, "(STUBBED) called"); callback(false, {}); diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h index 1c68bf57d..c28a235c1 100644 --- a/src/core/frontend/applets/cabinet.h +++ b/src/core/frontend/applets/cabinet.h @@ -18,18 +18,19 @@ struct CabinetParameters { Service::NFP::CabinetMode mode; }; +using CabinetCallback = std::function; + class CabinetApplet { public: virtual ~CabinetApplet(); - virtual void ShowCabinetApplet(std::function callback, + virtual void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const = 0; }; class DefaultCabinetApplet final : public CabinetApplet { public: - void ShowCabinetApplet(std::function callback, - const CabinetParameters& parameters, + void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const override; }; diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 01f577ab9..d0969b0f1 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -98,7 +98,7 @@ void Cabinet::Execute() { } } -void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_name) { +void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) { Service::Mii::MiiManager manager; ReturnValueForAmiiboSettings applet_output{}; @@ -118,7 +118,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam switch (applet_input_common.applet_mode) { case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { Service::NFP::AmiiboName name{}; - memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); + std::memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); nfp_device->SetNicknameAndOwner(name); break; } @@ -142,12 +142,12 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); nfp_device->Finalize(); - if (reg_result.IsSuccess() && tag_result.IsSuccess()) { - applet_output.result = CabinetResult::All; - } else if (reg_result.IsSuccess()) { - applet_output.result = CabinetResult::RegisterInfo; - } else if (tag_result.IsSuccess()) { - applet_output.result = CabinetResult::TagInfo; + if (reg_result.IsSuccess()) { + applet_output.result |= CabinetResult::RegisterInfo; + } + + if (tag_result.IsSuccess()) { + applet_output.result |= CabinetResult::TagInfo; } std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 8466d5997..84197a807 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -25,16 +25,17 @@ class NfpDevice; namespace Service::AM::Applets { -enum class CabinetAppletVersion : s32 { +enum class CabinetAppletVersion : u32 { Version1 = 0x1, }; enum class CabinetResult : u8 { - Cancel, + Cancel = 0, TagInfo = 1 << 1, RegisterInfo = 1 << 2, All = TagInfo | RegisterInfo, }; +DECLARE_ENUM_FLAG_OPERATORS(CabinetResult) // This is nn::nfp::AmiiboSettingsStartParam struct AmiiboSettingsStartParam { @@ -45,7 +46,7 @@ struct AmiiboSettingsStartParam { static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, "AmiiboSettingsStartParam is an invalid size"); -#pragma pack(1) +#pragma pack(push, 1) // This is nn::nfp::StartParamForAmiiboSettings struct StartParamForAmiiboSettings { u8 param_1; @@ -72,7 +73,7 @@ struct ReturnValueForAmiiboSettings { }; static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, "ReturnValueForAmiiboSettings is an invalid size"); -#pragma pack() +#pragma pack(pop) class Cabinet final : public Applet { public: @@ -86,7 +87,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; - void DisplayCompleted(bool apply_changes, const std::string& amiibo_name); + void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); void Cancel(); private: diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 2f9dfa9c2..e1bf90d7c 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -148,7 +148,7 @@ void NfpDevice::Finalize() { device_state = DeviceState::Unavailable; } -Result NfpDevice::StartDetection([[maybe_unused]] TagProtocol allowed_protocol) { +Result NfpDevice::StartDetection(TagProtocol allowed_protocol) { if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); return WrongDeviceState; @@ -475,6 +475,8 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { } Result NfpDevice::GetApplicationAreaId(u32& application_area_id) const { + application_area_id = {}; + if (device_state != DeviceState::TagMounted) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); if (device_state == DeviceState::TagRemoved) { -- cgit v1.2.3