diff options
Diffstat (limited to 'src/core/hle/service')
20 files changed, 289 insertions, 74 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 6c29cb613..2632cd3ef 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -496,8 +496,9 @@ public: void LoadIdTokenCache(HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); + rb.Push(0); } protected: diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index a2375508a..4f400d341 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -506,8 +506,8 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) { void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; idle_time_detection_extension = rp.Pop<u32>(); - LOG_WARNING(Service_AM, "(STUBBED) called idle_time_detection_extension={}", - idle_time_detection_extension); + LOG_DEBUG(Service_AM, "(STUBBED) called idle_time_detection_extension={}", + idle_time_detection_extension); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/glue/ectx.cpp b/src/core/hle/service/glue/ectx.cpp index 1bd9314ae..6f71b62f3 100644 --- a/src/core/hle/service/glue/ectx.cpp +++ b/src/core/hle/service/glue/ectx.cpp @@ -2,13 +2,48 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/glue/ectx.h" +#include "core/hle/service/ipc_helpers.h" namespace Service::Glue { +// This is nn::err::context::IContextRegistrar +class IContextRegistrar : public ServiceFramework<IContextRegistrar> { +public: + IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IContextRegistrar::Complete, "Complete"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + ~IContextRegistrar() override = default; + +private: + void Complete(HLERequestContext& ctx) { + struct InputParameters { + u32 unk; + }; + struct OutputParameters { + u32 unk; + }; + + IPC::RequestParser rp{ctx}; + [[maybe_unused]] auto input = rp.PopRaw<InputParameters>(); + [[maybe_unused]] auto value = ctx.ReadBuffer(); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } +}; + ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "CreateContextRegistrar"}, + {0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"}, {1, nullptr, "CommitContext"}, }; // clang-format on @@ -18,4 +53,10 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { ECTX_AW::~ECTX_AW() = default; +void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system)); +} + } // namespace Service::Glue diff --git a/src/core/hle/service/glue/ectx.h b/src/core/hle/service/glue/ectx.h index a608de053..ffa74d8d3 100644 --- a/src/core/hle/service/glue/ectx.h +++ b/src/core/hle/service/glue/ectx.h @@ -15,6 +15,9 @@ class ECTX_AW final : public ServiceFramework<ECTX_AW> { public: explicit ECTX_AW(Core::System& system_); ~ECTX_AW() override; + +private: + void CreateContextRegistrar(HLERequestContext& ctx); }; } // namespace Service::Glue diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index c42489ff9..055c0a2db 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -318,15 +318,15 @@ public: return false; } - if (!page_table.IsInsideAddressSpace(out_addr, size)) { + if (!page_table.Contains(out_addr, size)) { return false; } - if (page_table.IsInsideHeapRegion(out_addr, size)) { + if (page_table.IsInHeapRegion(out_addr, size)) { return false; } - if (page_table.IsInsideAliasRegion(out_addr, size)) { + if (page_table.IsInAliasRegion(out_addr, size)) { return false; } @@ -358,7 +358,7 @@ public: } ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) { - auto& page_table{process->PageTable()}; + auto& page_table{process->GetPageTable()}; VAddr addr{}; for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { @@ -382,7 +382,7 @@ public: ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, VAddr bss_addr, std::size_t bss_size, std::size_t size) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { - auto& page_table{process->PageTable()}; + auto& page_table{process->GetPageTable()}; VAddr addr{}; CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size)); @@ -437,12 +437,12 @@ public: CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, nro_header.segment_headers[DATA_INDEX].memory_size); - CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( + CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute)); - CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( + CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read)); - return process->PageTable().SetProcessMemoryPermission( + return process->GetPageTable().SetProcessMemoryPermission( data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite); } @@ -571,7 +571,7 @@ public: Result UnmapNro(const NROInfo& info) { // Each region must be unmapped separately to validate memory state - auto& page_table{system.ApplicationProcess()->PageTable()}; + auto& page_table{system.ApplicationProcess()->GetPageTable()}; if (info.bss_size != 0) { CASCADE_CODE(page_table.UnmapCodeMemory( @@ -643,7 +643,7 @@ public: initialized = true; current_map_addr = - GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart()); + GetInteger(system.ApplicationProcess()->GetPageTable().GetAliasCodeRegionStart()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp index bc232c334..9556e9193 100644 --- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp +++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp @@ -180,7 +180,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed } void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, - const std::vector<u8>& seed) { + std::span<const u8> seed) { // Initialize context ctx.used = false; ctx.counter = 0; diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.h b/src/core/hle/service/nfc/common/amiibo_crypto.h index 6a3e0841e..2cc0e4d51 100644 --- a/src/core/hle/service/nfc/common/amiibo_crypto.h +++ b/src/core/hle/service/nfc/common/amiibo_crypto.h @@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed // Initializes mbedtls context void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, - const std::vector<u8>& seed); + std::span<const u8> seed); // Feeds data to mbedtls context to generate the derived key void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output); diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 2d633b03f..49446bc42 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -34,8 +34,6 @@ #include "core/hle/service/nfc/mifare_result.h" #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/time/time_manager.h" -#include "core/hle/service/time/time_zone_content_manager.h" -#include "core/hle/service/time/time_zone_types.h" namespace Service::NFC { NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, @@ -1486,6 +1484,7 @@ DeviceState NfcDevice::GetCurrentState() const { } Result NfcDevice::GetNpadId(Core::HID::NpadIdType& out_npad_id) const { + // TODO: This should get the npad id from nn::hid::system::GetXcdHandleForNpadWithNfc out_npad_id = npad_id; return ResultSuccess; } diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index 562f3a28e..a71d26157 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include <algorithm> + #include "common/logging/log.h" #include "core/core.h" #include "core/hid/hid_types.h" @@ -10,6 +12,7 @@ #include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/time/clock_types.h" +#include "core/hle/service/time/time_manager.h" namespace Service::NFC { @@ -51,22 +54,53 @@ Result DeviceManager::Finalize() { return ResultSuccess; } -Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, - std::size_t max_allowed_devices) const { +Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices, + bool skip_fatal_errors) const { + std::scoped_lock lock{mutex}; + if (max_allowed_devices < 1) { + return ResultInvalidArgument; + } + + Result result = IsNfcParameterSet(); + if (result.IsError()) { + return result; + } + + result = IsNfcEnabled(); + if (result.IsError()) { + return result; + } + + result = IsNfcInitialized(); + if (result.IsError()) { + return result; + } + for (auto& device : devices) { if (nfp_devices.size() >= max_allowed_devices) { continue; } - if (device->GetCurrentState() != DeviceState::Unavailable) { - nfp_devices.push_back(device->GetHandle()); + if (skip_fatal_errors) { + constexpr u64 MinimumRecoveryTime = 60; + auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + const u64 elapsed_time = standard_steady_clock.GetCurrentTimePoint(system).time_point - + time_since_last_error; + + if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { + continue; + } } + if (device->GetCurrentState() == DeviceState::Unavailable) { + continue; + } + nfp_devices.push_back(device->GetHandle()); } if (nfp_devices.empty()) { return ResultDeviceNotFound; } - return ResultSuccess; + return result; } DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { @@ -79,10 +113,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { return device->GetCurrentState(); } - return DeviceState::Unavailable; + return DeviceState::Finalized; } -Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const { +Result DeviceManager::GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -128,7 +162,7 @@ Result DeviceManager::StopDetection(u64 device_handle) { return result; } -Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { +Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -142,24 +176,46 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { return result; } -Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const { - std::scoped_lock lock{mutex}; - +Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event, + u64 device_handle) const { + std::vector<u64> nfp_devices; std::shared_ptr<NfcDevice> device = nullptr; - GetDeviceFromHandle(device_handle, device, false); + Result result = ListDevices(nfp_devices, 9, false); - // TODO: Return proper error code on failure - return device->GetActivateEvent(); -} + if (result.IsSuccess()) { + result = CheckHandleOnList(device_handle, nfp_devices); + } -Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const { - std::scoped_lock lock{mutex}; + if (result.IsSuccess()) { + result = GetDeviceFromHandle(device_handle, device, false); + } + + if (result.IsSuccess()) { + *out_event = &device->GetActivateEvent(); + } + + return result; +} +Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event, + u64 device_handle) const { + std::vector<u64> nfp_devices; std::shared_ptr<NfcDevice> device = nullptr; - GetDeviceFromHandle(device_handle, device, false); + Result result = ListDevices(nfp_devices, 9, false); - // TODO: Return proper error code on failure - return device->GetDeactivateEvent(); + if (result.IsSuccess()) { + result = CheckHandleOnList(device_handle, nfp_devices); + } + + if (result.IsSuccess()) { + result = GetDeviceFromHandle(device_handle, device, false); + } + + if (result.IsSuccess()) { + *out_event = &device->GetDeactivateEvent(); + } + + return result; } Result DeviceManager::ReadMifare(u64 device_handle, @@ -253,7 +309,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) { return result; } -Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) const { +Result DeviceManager::GetApplicationArea(u64 device_handle, std::span<u8> data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -324,7 +380,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id, return result; } -Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const { +Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -338,7 +394,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi return result; } -Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const { +Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -352,7 +408,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i return result; } -Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const { +Result DeviceManager::GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -399,7 +455,7 @@ Result DeviceManager::Format(u64 device_handle) { return result; } -Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const { +Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -414,7 +470,7 @@ Result DeviceManager::GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info } Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle, - NFP::RegisterInfoPrivate& register_info) const { + NFP::RegisterInfoPrivate& register_info) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -471,7 +527,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) { return result; } -Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) const { +Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_application_area) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -485,7 +541,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica return result; } -Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) const { +Result DeviceManager::GetAll(u64 device_handle, NFP::NfpData& nfp_data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -541,7 +597,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) { return result; } -Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) const { +Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) { std::scoped_lock lock{mutex}; std::shared_ptr<NfcDevice> device = nullptr; @@ -593,6 +649,19 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons return result; } +Result DeviceManager::CheckHandleOnList(u64 device_handle, + const std::span<const u64> device_list) const { + if (device_list.size() < 1) { + return ResultDeviceNotFound; + } + + if (std::find(device_list.begin(), device_list.end(), device_handle) != device_list.end()) { + return ResultSuccess; + } + + return ResultDeviceNotFound; +} + Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device, bool check_state) const { if (check_state) { @@ -647,7 +716,7 @@ Result DeviceManager::GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& de } Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, - Result operation_result) const { + Result operation_result) { if (operation_result.IsSuccess()) { return operation_result; } @@ -669,6 +738,12 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device, return device_state; } + if (operation_result == ResultUnknown112 || operation_result == ResultUnknown114 || + operation_result == ResultUnknown115) { + auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + time_since_last_error = standard_steady_clock.GetCurrentTimePoint(system).time_point; + } + return operation_result; } diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index c61ba0cf3..c9f038e32 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h @@ -27,15 +27,16 @@ public: // Nfc device manager Result Initialize(); Result Finalize(); - Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices) const; + Result ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices, + bool skip_fatal_errors) const; DeviceState GetDeviceState(u64 device_handle) const; - Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id) const; + Result GetNpadId(u64 device_handle, Core::HID::NpadIdType& npad_id); Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); Result StopDetection(u64 device_handle); - Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const; - Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; - Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; + Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info); + Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const; + Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const; Result ReadMifare(u64 device_handle, const std::span<const MifareReadBlockParameter> read_parameters, std::span<MifareReadBlockData> read_data); @@ -48,28 +49,28 @@ public: Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target); Result Unmount(u64 device_handle); Result OpenApplicationArea(u64 device_handle, u32 access_id); - Result GetApplicationArea(u64 device_handle, std::span<u8> data) const; + Result GetApplicationArea(u64 device_handle, std::span<u8> data); Result SetApplicationArea(u64 device_handle, std::span<const u8> data); Result Flush(u64 device_handle); Result Restore(u64 device_handle); Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); - Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const; - Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const; - Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const; + Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info); + Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info); + Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info); u32 GetApplicationAreaSize() const; Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); Result Format(u64 device_handle); - Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const; - Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const; + Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info); + Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info); Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info); Result DeleteRegisterInfo(u64 device_handle); Result DeleteApplicationArea(u64 device_handle); - Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const; - Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const; + Result ExistsApplicationArea(u64 device_handle, bool& has_application_area); + Result GetAll(u64 device_handle, NFP::NfpData& nfp_data); Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data); Result FlushDebug(u64 device_handle); Result BreakTag(u64 device_handle, NFP::BreakType break_type); - Result ReadBackupData(u64 device_handle, std::span<u8> data) const; + Result ReadBackupData(u64 device_handle, std::span<u8> data); Result WriteBackupData(u64 device_handle, std::span<const u8> data); Result WriteNtf(u64 device_handle, NFP::WriteType, std::span<const u8> data); @@ -78,17 +79,20 @@ private: Result IsNfcParameterSet() const; Result IsNfcInitialized() const; + Result CheckHandleOnList(u64 device_handle, std::span<const u64> device_list) const; + Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device, bool check_state) const; Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) const; - Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result) const; + Result VerifyDeviceResult(std::shared_ptr<NfcDevice> device, Result operation_result); Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const; std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const; bool is_initialized = false; + u64 time_since_last_error = 0; mutable std::mutex mutex; std::array<std::shared_ptr<NfcDevice>, 10> devices{}; diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index e7ca7582e..179c7ba2c 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp @@ -79,7 +79,7 @@ void NfcInterface::ListDevices(HLERequestContext& ctx) { const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>(); LOG_DEBUG(Service_NFC, "called"); - auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices); + auto result = GetManager()->ListDevices(nfp_devices, max_allowed_devices, true); result = TranslateResultToServiceError(result); if (result.IsError()) { @@ -190,9 +190,13 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) { const auto device_handle{rp.Pop<u64>()}; LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); + Kernel::KReadableEvent* out_event = nullptr; + auto result = GetManager()->AttachActivateEvent(&out_event, device_handle); + result = TranslateResultToServiceError(result); + IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle)); + rb.Push(result); + rb.PushCopyObjects(out_event); } void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { @@ -200,9 +204,13 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { const auto device_handle{rp.Pop<u64>()}; LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); + Kernel::KReadableEvent* out_event = nullptr; + auto result = GetManager()->AttachDeactivateEvent(&out_event, device_handle); + result = TranslateResultToServiceError(result); + IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle)); + rb.Push(result); + rb.PushCopyObjects(out_event); } void NfcInterface::ReadMifare(HLERequestContext& ctx) { diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h index 715c0e80c..464b5fd69 100644 --- a/src/core/hle/service/nfc/nfc_result.h +++ b/src/core/hle/service/nfc/nfc_result.h @@ -17,7 +17,10 @@ constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77); constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); +constexpr Result ResultUnknown112(ErrorModule::NFC, 112); constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); +constexpr Result ResultUnknown114(ErrorModule::NFC, 114); +constexpr Result ResultUnknown115(ErrorModule::NFC, 115); constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120); constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index e7f7e273b..968eaa175 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -128,7 +128,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) { } bool is_out_io{}; ASSERT(system.ApplicationProcess() - ->PageTable() + ->GetPageTable() .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, handle_description->size, Kernel::KMemoryPermission::None, true, false) @@ -255,7 +255,7 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { if (auto freeInfo{file.FreeHandle(params.handle, false)}) { if (freeInfo->can_unlock) { ASSERT(system.ApplicationProcess() - ->PageTable() + ->GetPageTable() .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) .IsSuccess()); } diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index e63b0a357..11f8efbac 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -559,7 +559,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; if (!descriptor) { - LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); + LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd); pollfd.revents = PollEvents::Nval; return {0, Errno::SUCCESS}; } diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp index 0dfb0f166..5dfcaabb1 100644 --- a/src/core/hle/service/sockets/nsd.cpp +++ b/src/core/hle/service/sockets/nsd.cpp @@ -10,12 +10,21 @@ namespace Service::Sockets { constexpr Result ResultOverflow{ErrorModule::NSD, 6}; +// This is nn::oe::ServerEnvironmentType +enum class ServerEnvironmentType : u8 { + Dd, + Lp, + Sd, + Sp, + Dp, +}; + NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { {5, nullptr, "GetSettingUrl"}, {10, nullptr, "GetSettingName"}, - {11, nullptr, "GetEnvironmentIdentifier"}, + {11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"}, {12, nullptr, "GetDeviceId"}, {13, nullptr, "DeleteSettings"}, {14, nullptr, "ImportSettings"}, @@ -36,7 +45,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na {62, nullptr, "DeleteSaveDataOfFsForTest"}, {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"}, {64, nullptr, "SetWithoutDomainExchangeFqdns"}, - {100, nullptr, "GetApplicationServerEnvironmentType"}, + {100, &NSD::GetApplicationServerEnvironmentType, "GetApplicationServerEnvironmentType"}, {101, nullptr, "SetApplicationServerEnvironmentType"}, {102, nullptr, "DeleteApplicationServerEnvironmentType"}, }; @@ -94,6 +103,20 @@ void NSD::ResolveEx(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) { + const std::string environment_identifier = "lp1"; + ctx.WriteBuffer(environment_identifier); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(ServerEnvironmentType::Lp)); +} + NSD::~NSD() = default; } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/nsd.h b/src/core/hle/service/sockets/nsd.h index a7379a8a9..b0cfec507 100644 --- a/src/core/hle/service/sockets/nsd.h +++ b/src/core/hle/service/sockets/nsd.h @@ -19,6 +19,8 @@ public: private: void Resolve(HLERequestContext& ctx); void ResolveEx(HLERequestContext& ctx); + void GetEnvironmentIdentifier(HLERequestContext& ctx); + void GetApplicationServerEnvironmentType(HLERequestContext& ctx); }; } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 84cc79de8..22e4a6f49 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -24,7 +24,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres" {2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"}, {3, nullptr, "GetHostByAddrRequest"}, {4, nullptr, "GetHostStringErrorRequest"}, - {5, nullptr, "GetGaiStringErrorRequest"}, + {5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"}, {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, {7, nullptr, "GetNameInfoRequest"}, {8, nullptr, "RequestCancelHandleRequest"}, @@ -300,6 +300,20 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) { }); } +void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) { + struct InputParameters { + GetAddrInfoError gai_errno; + }; + IPC::RequestParser rp{ctx}; + auto input = rp.PopRaw<InputParameters>(); + + const std::string result = Translate(input.gai_errno); + ctx.WriteBuffer(result); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { // Additional options are ignored auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx); diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h index d99a9d560..282ef9071 100644 --- a/src/core/hle/service/sockets/sfdnsres.h +++ b/src/core/hle/service/sockets/sfdnsres.h @@ -18,6 +18,7 @@ public: private: void GetHostByNameRequest(HLERequestContext& ctx); + void GetGaiStringErrorRequest(HLERequestContext& ctx); void GetHostByNameRequestWithOptions(HLERequestContext& ctx); void GetAddrInfoRequest(HLERequestContext& ctx); void GetAddrInfoRequestWithOptions(HLERequestContext& ctx); diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index 2f9a0e39c..c1187209f 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -81,6 +81,44 @@ GetAddrInfoError Translate(Network::GetAddrInfoError error) { } } +const char* Translate(GetAddrInfoError error) { + // https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254 + switch (error) { + case GetAddrInfoError::SUCCESS: + return "Success"; + case GetAddrInfoError::ADDRFAMILY: + return "Address family for hostname not supported"; + case GetAddrInfoError::AGAIN: + return "Temporary failure in name resolution"; + case GetAddrInfoError::BADFLAGS: + return "Invalid value for ai_flags"; + case GetAddrInfoError::FAIL: + return "Non-recoverable failure in name resolution"; + case GetAddrInfoError::FAMILY: + return "ai_family not supported"; + case GetAddrInfoError::MEMORY: + return "Memory allocation failure"; + case GetAddrInfoError::NODATA: + return "No address associated with hostname"; + case GetAddrInfoError::NONAME: + return "hostname nor servname provided, or not known"; + case GetAddrInfoError::SERVICE: + return "servname not supported for ai_socktype"; + case GetAddrInfoError::SOCKTYPE: + return "ai_socktype not supported"; + case GetAddrInfoError::SYSTEM: + return "System error returned in errno"; + case GetAddrInfoError::BADHINTS: + return "Invalid value for hints"; + case GetAddrInfoError::PROTOCOL: + return "Resolved protocol is unknown"; + case GetAddrInfoError::OVERFLOW_: + return "Argument buffer overflow"; + default: + return "Unknown error"; + } +} + Network::Domain Translate(Domain domain) { switch (domain) { case Domain::Unspecified: diff --git a/src/core/hle/service/sockets/sockets_translate.h b/src/core/hle/service/sockets/sockets_translate.h index 694868b37..bd6721fd3 100644 --- a/src/core/hle/service/sockets/sockets_translate.h +++ b/src/core/hle/service/sockets/sockets_translate.h @@ -20,6 +20,9 @@ std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value); /// Translate abstract getaddrinfo error to guest getaddrinfo error GetAddrInfoError Translate(Network::GetAddrInfoError value); +/// Translate guest error to string +const char* Translate(GetAddrInfoError value); + /// Translate guest domain to abstract domain Network::Domain Translate(Domain domain); |