// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" #include "core/core.h" #include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_interface.h" #include "core/hle/service/nfp/nfp_result.h" #include "core/hle/service/nfp/nfp_types.h" namespace Service::NFP { Interface::Interface(Core::System& system_, const char* name) : NfcInterface{system_, name, NFC::BackendType::Nfp} {} Interface::~Interface() = default; void Interface::InitializeSystem(HLERequestContext& ctx) { Initialize(ctx); } void Interface::InitializeDebug(HLERequestContext& ctx) { Initialize(ctx); } void Interface::FinalizeSystem(HLERequestContext& ctx) { Finalize(ctx); } void Interface::FinalizeDebug(HLERequestContext& ctx) { Finalize(ctx); } void Interface::Mount(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto model_type{rp.PopEnum()}; const auto mount_target{rp.PopEnum()}; LOG_INFO(Service_NFP, "called, device_handle={}, model_type={}, mount_target={}", device_handle, model_type, mount_target); auto result = GetManager()->Mount(device_handle, model_type, mount_target); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::Unmount(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->Unmount(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::OpenApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto access_id{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}, access_id={}", device_handle, access_id); auto result = GetManager()->OpenApplicationArea(device_handle, access_id); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto data_size = ctx.GetWriteBufferSize(); LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); std::vector data(data_size); auto result = GetManager()->GetApplicationArea(device_handle, data); result = TranslateResultToServiceError(result); if (result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; } ctx.WriteBuffer(data); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(result); rb.Push(static_cast(data_size)); } void Interface::SetApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto data{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}", device_handle, data.size()); auto result = GetManager()->SetApplicationArea(device_handle, data); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::Flush(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->Flush(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::Restore(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->Restore(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::CreateApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto access_id{rp.Pop()}; const auto data{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}, access_id={}", device_handle, access_id, data.size()); auto result = GetManager()->CreateApplicationArea(device_handle, access_id, data); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetRegisterInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); RegisterInfo register_info{}; auto result = GetManager()->GetRegisterInfo(device_handle, register_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(register_info); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetCommonInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); CommonInfo common_info{}; auto result = GetManager()->GetCommonInfo(device_handle, common_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(common_info); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetModelInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); ModelInfo model_info{}; auto result = GetManager()->GetModelInfo(device_handle, model_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(model_info); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetApplicationAreaSize(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(GetManager()->GetApplicationAreaSize()); } void Interface::RecreateApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto access_id{rp.Pop()}; const auto data{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}, access_id={}", device_handle, access_id, data.size()); auto result = GetManager()->RecreateApplicationArea(device_handle, access_id, data); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::Format(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->Format(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetAdminInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); AdminInfo admin_info{}; auto result = GetManager()->GetAdminInfo(device_handle, admin_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(admin_info); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::GetRegisterInfoPrivate(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); RegisterInfoPrivate register_info{}; auto result = GetManager()->GetRegisterInfoPrivate(device_handle, register_info); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(register_info); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::SetRegisterInfoPrivate(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto register_info_buffer{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}, buffer_size={}", device_handle, register_info_buffer.size()); RegisterInfoPrivate register_info{}; memcpy(®ister_info, register_info_buffer.data(), sizeof(RegisterInfoPrivate)); auto result = GetManager()->SetRegisterInfoPrivate(device_handle, register_info); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::DeleteRegisterInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->DeleteRegisterInfo(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::DeleteApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->DeleteApplicationArea(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::ExistsApplicationArea(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); bool has_application_area = false; auto result = GetManager()->ExistsApplicationArea(device_handle, has_application_area); result = TranslateResultToServiceError(result); if (result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; } IPC::ResponseBuilder rb{ctx, 3}; rb.Push(result); rb.Push(has_application_area); } void Interface::GetAll(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); NfpData nfp_data{}; auto result = GetManager()->GetAll(device_handle, nfp_data); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(nfp_data); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::SetAll(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto nfp_data_buffer{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); NfpData nfp_data{}; memcpy(&nfp_data, nfp_data_buffer.data(), sizeof(NfpData)); auto result = GetManager()->SetAll(device_handle, nfp_data); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::FlushDebug(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->FlushDebug(device_handle); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::BreakTag(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto break_type{rp.PopEnum()}; LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}, break_type={}", device_handle, break_type); auto result = GetManager()->BreakTag(device_handle, break_type); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::ReadBackupData(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); std::vector backup_data{}; auto result = GetManager()->ReadBackupData(device_handle, backup_data); result = TranslateResultToServiceError(result); if (result.IsSuccess()) { ctx.WriteBuffer(backup_data); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::WriteBackupData(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto backup_data_buffer{ctx.ReadBuffer()}; LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); auto result = GetManager()->WriteBackupData(device_handle, backup_data_buffer); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } void Interface::WriteNtf(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; const auto write_type{rp.PopEnum()}; const auto ntf_data_buffer{ctx.ReadBuffer()}; LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); auto result = GetManager()->WriteNtf(device_handle, write_type, ntf_data_buffer); result = TranslateResultToServiceError(result); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } } // namespace Service::NFP