Compare commits

..

11 Commits

Author SHA1 Message Date
bb6e35c85e Android #16 2023-07-22 00:58:04 +00:00
efda6cc9ec Merge pull request #11123 from Morph1984/remove-mem-hungry-opts
ci: Remove GA, Gr optimizations from MSVC
2023-07-21 15:06:07 -04:00
8927f016e1 Merge pull request #11069 from lat9nq/mingw-no-tzdb
common: Use arithmetic instead of string ops to get time zone
2023-07-21 15:05:59 -04:00
c0202da9ac Merge pull request #11096 from german77/amiibooo
service: nfc: Update Implementation to match with latest RE
2023-07-21 09:21:48 -04:00
7fc5ef68d2 ci: Remove GA, Gr optimizations from MSVC
Internal testing has shown these result in higher committed memory usage in some systems.
Also Ob2 is already implied by O2, so that can be removed as well.
2023-07-21 01:30:43 -04:00
54f150b70a service: nfc: Update Implementation to match with latest RE 2023-07-17 11:24:23 -06:00
63a0a1f826 time_zone: Clean up includes 2023-07-12 03:03:03 -04:00
9e0d6f7d54 time_zone: Swap subtraction order 2023-07-12 03:02:45 -04:00
13755c0903 time_zone: Account for leap years
Protects against invalid hour offsets during transitions to years
following leap years.
2023-07-12 02:34:02 -04:00
833306bf5e settings: Disable C++20 tzdb path on MinGW
This path always results in Etc/UTC on MinGW, which often is not
close to the local time zone.
2023-07-10 17:52:35 -04:00
90d76333da time_zone: Remove string ops for determing zone
MinGW's strftime implementation does not work and cannot be used to
determine the time zone. Besides that, the string operations are
actually unnecessary since we can get the offset from
std::localtime.

Compare localtime to gmtime to find the zone offset on all platforms.
2023-07-10 17:51:34 -04:00
10 changed files with 165 additions and 84 deletions

View File

@ -12,7 +12,7 @@ steps:
inputs: inputs:
targetType: 'filePath' targetType: 'filePath'
filePath: './.ci/scripts/windows/install-vulkan-sdk.ps1' filePath: './.ci/scripts/windows/install-vulkan-sdk.ps1'
- script: refreshenv && glslangValidator --version && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_ENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd .. - script: refreshenv && glslangValidator --version && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_ENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake' displayName: 'Configure CMake'
- task: MSBuild@1 - task: MSBuild@1
displayName: 'Build' displayName: 'Build'

View File

@ -26,7 +26,8 @@ std::string GetTimeZoneString() {
std::string location_name; std::string location_name;
if (time_zone_index == 0) { // Auto if (time_zone_index == 0) { // Auto
#if __cpp_lib_chrono >= 201907L #if __cpp_lib_chrono >= 201907L && !defined(MINGW)
// Disabled for MinGW -- tzdb always returns Etc/UTC
try { try {
const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb(); const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb();
const std::chrono::time_zone* current_zone = time_zone_data.current_zone(); const std::chrono::time_zone* current_zone = time_zone_data.current_zone();

View File

@ -4,13 +4,13 @@
#include <chrono> #include <chrono>
#include <exception> #include <exception>
#include <iomanip> #include <iomanip>
#include <map>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <fmt/chrono.h> #include <fmt/chrono.h>
#include <fmt/core.h> #include <fmt/core.h>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h"
#include "common/time_zone.h" #include "common/time_zone.h"
namespace Common::TimeZone { namespace Common::TimeZone {
@ -33,32 +33,29 @@ std::string GetDefaultTimeZone() {
return "GMT"; return "GMT";
} }
static std::string GetOsTimeZoneOffset() { // Results are not comparable to seconds since Epoch
const std::time_t t{std::time(nullptr)}; static std::time_t TmSpecToSeconds(const struct std::tm& spec) {
const std::tm tm{*std::localtime(&t)}; const int year = spec.tm_year - 1; // Years up to now
const int leap_years = year / 4 - year / 100;
return fmt::format("{:%z}", tm); std::time_t cumulative = spec.tm_year;
} cumulative = cumulative * 365 + leap_years + spec.tm_yday; // Years to days
cumulative = cumulative * 24 + spec.tm_hour; // Days to hours
static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) { cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes
try { cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds
return std::stoi(timezone); return cumulative;
} catch (const std::invalid_argument&) {
LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
return 0;
} catch (const std::out_of_range&) {
LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
return 0;
}
} }
std::chrono::seconds GetCurrentOffsetSeconds() { std::chrono::seconds GetCurrentOffsetSeconds() {
const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())}; const std::time_t t{std::time(nullptr)};
const std::tm local{*std::localtime(&t)};
const std::tm gmt{*std::gmtime(&t)};
int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds // gmt_seconds is a different offset than time(nullptr)
seconds += (offset % 100) * 60; // Convert minute component to seconds const auto gmt_seconds = TmSpecToSeconds(gmt);
const auto local_seconds = TmSpecToSeconds(local);
const auto seconds_offset = local_seconds - gmt_seconds;
return std::chrono::seconds{seconds}; return std::chrono::seconds{seconds_offset};
} }
// Key is [Hours * 100 + Minutes], multiplied by 100 if DST // Key is [Hours * 100 + Minutes], multiplied by 100 if DST
@ -71,11 +68,6 @@ const static std::map<s64, const char*> off_timezones = {
}; };
std::string FindSystemTimeZone() { std::string FindSystemTimeZone() {
#if defined(MINGW)
// MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/
// e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400"
return timezones[0];
#else
const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count());
const s64 minutes = seconds / 60; const s64 minutes = seconds / 60;
@ -97,7 +89,6 @@ std::string FindSystemTimeZone() {
} }
} }
return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
#endif
} }
} // namespace Common::TimeZone } // namespace Common::TimeZone

View File

@ -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, 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 // Initialize context
ctx.used = false; ctx.used = false;
ctx.counter = 0; ctx.counter = 0;

View File

@ -75,7 +75,7 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
// Initializes mbedtls context // Initializes mbedtls context
void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, 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 // Feeds data to mbedtls context to generate the derived key
void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output); void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output);

View File

@ -34,8 +34,6 @@
#include "core/hle/service/nfc/mifare_result.h" #include "core/hle/service/nfc/mifare_result.h"
#include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/time_manager.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 { namespace Service::NFC {
NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, 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 { 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; out_npad_id = npad_id;
return ResultSuccess; return ResultSuccess;
} }

View File

@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hid/hid_types.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/common/device_manager.h"
#include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h"
namespace Service::NFC { namespace Service::NFC {
@ -51,22 +54,53 @@ Result DeviceManager::Finalize() {
return ResultSuccess; return ResultSuccess;
} }
Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, Result DeviceManager::ListDevices(std::vector<u64>& nfp_devices, std::size_t max_allowed_devices,
std::size_t max_allowed_devices) const { 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) { for (auto& device : devices) {
if (nfp_devices.size() >= max_allowed_devices) { if (nfp_devices.size() >= max_allowed_devices) {
continue; continue;
} }
if (device->GetCurrentState() != DeviceState::Unavailable) { if (skip_fatal_errors) {
nfp_devices.push_back(device->GetHandle()); 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()) { if (nfp_devices.empty()) {
return ResultDeviceNotFound; return ResultDeviceNotFound;
} }
return ResultSuccess; return result;
} }
DeviceState DeviceManager::GetDeviceState(u64 device_handle) const { DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
@ -79,10 +113,10 @@ DeviceState DeviceManager::GetDeviceState(u64 device_handle) const {
return device->GetCurrentState(); 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -128,7 +162,7 @@ Result DeviceManager::StopDetection(u64 device_handle) {
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -142,24 +176,46 @@ Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const {
return result; return result;
} }
Kernel::KReadableEvent& DeviceManager::AttachActivateEvent(u64 device_handle) const { Result DeviceManager::AttachActivateEvent(Kernel::KReadableEvent** out_event,
std::scoped_lock lock{mutex}; u64 device_handle) const {
std::vector<u64> nfp_devices;
std::shared_ptr<NfcDevice> device = nullptr; 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 if (result.IsSuccess()) {
return device->GetActivateEvent(); result = CheckHandleOnList(device_handle, nfp_devices);
}
if (result.IsSuccess()) {
result = GetDeviceFromHandle(device_handle, device, false);
}
if (result.IsSuccess()) {
*out_event = &device->GetActivateEvent();
}
return result;
} }
Kernel::KReadableEvent& DeviceManager::AttachDeactivateEvent(u64 device_handle) const { Result DeviceManager::AttachDeactivateEvent(Kernel::KReadableEvent** out_event,
std::scoped_lock lock{mutex}; u64 device_handle) const {
std::vector<u64> nfp_devices;
std::shared_ptr<NfcDevice> device = nullptr; 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 if (result.IsSuccess()) {
return device->GetDeactivateEvent(); 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, Result DeviceManager::ReadMifare(u64 device_handle,
@ -253,7 +309,7 @@ Result DeviceManager::OpenApplicationArea(u64 device_handle, u32 access_id) {
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -324,7 +380,7 @@ Result DeviceManager::CreateApplicationArea(u64 device_handle, u32 access_id,
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -338,7 +394,7 @@ Result DeviceManager::GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& regi
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -352,7 +408,7 @@ Result DeviceManager::GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_i
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -399,7 +455,7 @@ Result DeviceManager::Format(u64 device_handle) {
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; 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, Result DeviceManager::GetRegisterInfoPrivate(u64 device_handle,
NFP::RegisterInfoPrivate& register_info) const { NFP::RegisterInfoPrivate& register_info) {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -471,7 +527,7 @@ Result DeviceManager::DeleteApplicationArea(u64 device_handle) {
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -485,7 +541,7 @@ Result DeviceManager::ExistsApplicationArea(u64 device_handle, bool& has_applica
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -541,7 +597,7 @@ Result DeviceManager::BreakTag(u64 device_handle, NFP::BreakType break_type) {
return result; 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::scoped_lock lock{mutex};
std::shared_ptr<NfcDevice> device = nullptr; std::shared_ptr<NfcDevice> device = nullptr;
@ -593,6 +649,19 @@ Result DeviceManager::WriteNtf(u64 device_handle, NFP::WriteType, std::span<cons
return result; 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, Result DeviceManager::GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& nfc_device,
bool check_state) const { bool check_state) const {
if (check_state) { 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 DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
Result operation_result) const { Result operation_result) {
if (operation_result.IsSuccess()) { if (operation_result.IsSuccess()) {
return operation_result; return operation_result;
} }
@ -669,6 +738,12 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr<NfcDevice> device,
return device_state; 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; return operation_result;
} }

View File

@ -27,15 +27,16 @@ public:
// Nfc device manager // Nfc device manager
Result Initialize(); Result Initialize();
Result Finalize(); 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; 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; Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const;
Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); Result StartDetection(u64 device_handle, NfcProtocol tag_protocol);
Result StopDetection(u64 device_handle); Result StopDetection(u64 device_handle);
Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const; Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info);
Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; Result AttachActivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; Result AttachDeactivateEvent(Kernel::KReadableEvent** event, u64 device_handle) const;
Result ReadMifare(u64 device_handle, Result ReadMifare(u64 device_handle,
const std::span<const MifareReadBlockParameter> read_parameters, const std::span<const MifareReadBlockParameter> read_parameters,
std::span<MifareReadBlockData> read_data); std::span<MifareReadBlockData> read_data);
@ -48,28 +49,28 @@ public:
Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target); Result Mount(u64 device_handle, NFP::ModelType model_type, NFP::MountTarget mount_target);
Result Unmount(u64 device_handle); Result Unmount(u64 device_handle);
Result OpenApplicationArea(u64 device_handle, u32 access_id); 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 SetApplicationArea(u64 device_handle, std::span<const u8> data);
Result Flush(u64 device_handle); Result Flush(u64 device_handle);
Result Restore(u64 device_handle); Result Restore(u64 device_handle);
Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); Result CreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info) const; Result GetRegisterInfo(u64 device_handle, NFP::RegisterInfo& register_info);
Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info) const; Result GetCommonInfo(u64 device_handle, NFP::CommonInfo& common_info);
Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info) const; Result GetModelInfo(u64 device_handle, NFP::ModelInfo& model_info);
u32 GetApplicationAreaSize() const; u32 GetApplicationAreaSize() const;
Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data); Result RecreateApplicationArea(u64 device_handle, u32 access_id, std::span<const u8> data);
Result Format(u64 device_handle); Result Format(u64 device_handle);
Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info) const; Result GetAdminInfo(u64 device_handle, NFP::AdminInfo& admin_info);
Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info) const; Result GetRegisterInfoPrivate(u64 device_handle, NFP::RegisterInfoPrivate& register_info);
Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info); Result SetRegisterInfoPrivate(u64 device_handle, const NFP::RegisterInfoPrivate& register_info);
Result DeleteRegisterInfo(u64 device_handle); Result DeleteRegisterInfo(u64 device_handle);
Result DeleteApplicationArea(u64 device_handle); Result DeleteApplicationArea(u64 device_handle);
Result ExistsApplicationArea(u64 device_handle, bool& has_application_area) const; Result ExistsApplicationArea(u64 device_handle, bool& has_application_area);
Result GetAll(u64 device_handle, NFP::NfpData& nfp_data) const; Result GetAll(u64 device_handle, NFP::NfpData& nfp_data);
Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data); Result SetAll(u64 device_handle, const NFP::NfpData& nfp_data);
Result FlushDebug(u64 device_handle); Result FlushDebug(u64 device_handle);
Result BreakTag(u64 device_handle, NFP::BreakType break_type); 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 WriteBackupData(u64 device_handle, std::span<const u8> data);
Result WriteNtf(u64 device_handle, NFP::WriteType, 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 IsNfcParameterSet() const;
Result IsNfcInitialized() 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, Result GetDeviceFromHandle(u64 handle, std::shared_ptr<NfcDevice>& device,
bool check_state) const; bool check_state) const;
Result GetDeviceHandle(u64 handle, std::shared_ptr<NfcDevice>& device) 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; Result CheckDeviceState(std::shared_ptr<NfcDevice> device) const;
std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const; const std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle) const;
bool is_initialized = false; bool is_initialized = false;
u64 time_since_last_error = 0;
mutable std::mutex mutex; mutable std::mutex mutex;
std::array<std::shared_ptr<NfcDevice>, 10> devices{}; std::array<std::shared_ptr<NfcDevice>, 10> devices{};

View File

@ -79,7 +79,7 @@ void NfcInterface::ListDevices(HLERequestContext& ctx) {
const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>(); const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
LOG_DEBUG(Service_NFC, "called"); 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); result = TranslateResultToServiceError(result);
if (result.IsError()) { if (result.IsError()) {
@ -190,9 +190,13 @@ void NfcInterface::AttachActivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()}; const auto device_handle{rp.Pop<u64>()};
LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 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}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess); rb.Push(result);
rb.PushCopyObjects(GetManager()->AttachActivateEvent(device_handle)); rb.PushCopyObjects(out_event);
} }
void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
@ -200,9 +204,13 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
const auto device_handle{rp.Pop<u64>()}; const auto device_handle{rp.Pop<u64>()};
LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 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}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess); rb.Push(result);
rb.PushCopyObjects(GetManager()->AttachDeactivateEvent(device_handle)); rb.PushCopyObjects(out_event);
} }
void NfcInterface::ReadMifare(HLERequestContext& ctx) { void NfcInterface::ReadMifare(HLERequestContext& ctx) {

View File

@ -17,7 +17,10 @@ constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88);
constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); constexpr Result ResultTagRemoved(ErrorModule::NFC, 97);
constexpr Result ResultUnknown112(ErrorModule::NFC, 112);
constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); 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 ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);