From 015d666a4d1b38a0f4b9f66e55613881c0908f37 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Fri, 23 Feb 2024 12:38:43 -0600
Subject: [PATCH] service: nfc: Implement SetNfcEnabled

---
 .../hle/service/nfc/common/device_manager.cpp |  8 +++++--
 .../hle/service/nfc/common/device_manager.h   |  5 ++++
 src/core/hle/service/nfc/nfc.cpp              |  4 ++--
 src/core/hle/service/nfc/nfc_interface.cpp    | 24 +++++++++++++++----
 src/core/hle/service/nfc/nfc_interface.h      |  6 +++++
 5 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index 94a8243b55..2dd3e9f892 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -13,6 +13,7 @@
 #include "core/hle/service/nfc/nfc_result.h"
 #include "core/hle/service/psc/time/steady_clock.h"
 #include "core/hle/service/service.h"
+#include "core/hle/service/set/system_settings_server.h"
 #include "core/hle/service/sm/sm.h"
 #include "hid_core/hid_types.h"
 #include "hid_core/hid_util.h"
@@ -32,6 +33,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex
     }
 
     is_initialized = false;
+
+    m_set_sys =
+        system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
 }
 
 DeviceManager ::~DeviceManager() {
@@ -774,8 +778,8 @@ Result DeviceManager::CheckDeviceState(std::shared_ptr<NfcDevice> device) const
 }
 
 Result DeviceManager::IsNfcEnabled() const {
-    // TODO: This calls nn::settings::detail::GetNfcEnableFlag
-    const bool is_enabled = true;
+    bool is_enabled{};
+    R_TRY(m_set_sys->GetNfcEnableFlag(&is_enabled));
     if (!is_enabled) {
         return ResultNfcDisabled;
     }
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h
index c56a2fbdaa..6c0e6b255e 100644
--- a/src/core/hle/service/nfc/common/device_manager.h
+++ b/src/core/hle/service/nfc/common/device_manager.h
@@ -15,6 +15,10 @@
 #include "core/hle/service/service.h"
 #include "hid_core/hid_types.h"
 
+namespace Service::Set {
+class ISystemSettingsServer;
+}
+
 namespace Service::NFC {
 class NfcDevice;
 
@@ -98,6 +102,7 @@ private:
     Core::System& system;
     KernelHelpers::ServiceContext service_context;
     Kernel::KEvent* availability_change_event;
+    std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
 };
 
 } // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 30ae989b9b..9d4808dbec 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -57,7 +57,7 @@ public:
             {1, &NfcInterface::Finalize, "FinalizeOld"},
             {2, &NfcInterface::GetState, "GetStateOld"},
             {3, &NfcInterface::IsNfcEnabled, "IsNfcEnabledOld"},
-            {100, nullptr, "SetNfcEnabledOld"},
+            {100, &NfcInterface::SetNfcEnabled, "SetNfcEnabledOld"},
             {400, &NfcInterface::Initialize, "Initialize"},
             {401, &NfcInterface::Finalize, "Finalize"},
             {402, &NfcInterface::GetState, "GetState"},
@@ -71,7 +71,7 @@ public:
             {410, &NfcInterface::GetTagInfo, "GetTagInfo"},
             {411, &NfcInterface::AttachActivateEvent, "AttachActivateEvent"},
             {412, &NfcInterface::AttachDeactivateEvent, "AttachDeactivateEvent"},
-            {500, nullptr, "SetNfcEnabled"},
+            {500, &NfcInterface::SetNfcEnabled, "SetNfcEnabled"},
             {510, nullptr, "OutputTestWave"},
             {1000, &NfcInterface::ReadMifare, "ReadMifare"},
             {1001, &NfcInterface::WriteMifare, "WriteMifare"},
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index 3e2c7deabe..c28e55431e 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -13,13 +13,18 @@
 #include "core/hle/service/nfc/nfc_result.h"
 #include "core/hle/service/nfc/nfc_types.h"
 #include "core/hle/service/nfp/nfp_result.h"
+#include "core/hle/service/set/system_settings_server.h"
+#include "core/hle/service/sm/sm.h"
 #include "hid_core/hid_types.h"
 
 namespace Service::NFC {
 
 NfcInterface::NfcInterface(Core::System& system_, const char* name, BackendType service_backend)
     : ServiceFramework{system_, name}, service_context{system_, service_name},
-      backend_type{service_backend} {}
+      backend_type{service_backend} {
+    m_set_sys =
+        system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
+}
 
 NfcInterface ::~NfcInterface() = default;
 
@@ -65,11 +70,11 @@ void NfcInterface::GetState(HLERequestContext& ctx) {
 void NfcInterface::IsNfcEnabled(HLERequestContext& ctx) {
     LOG_DEBUG(Service_NFC, "called");
 
-    // TODO: This calls nn::settings::detail::GetNfcEnableFlag
-    const bool is_enabled = true;
+    bool is_enabled{};
+    const auto result = m_set_sys->GetNfcEnableFlag(&is_enabled);
 
     IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
+    rb.Push(result);
     rb.Push(is_enabled);
 }
 
@@ -212,6 +217,17 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) {
     rb.PushCopyObjects(out_event);
 }
 
+void NfcInterface::SetNfcEnabled(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto is_enabled{rp.Pop<bool>()};
+    LOG_DEBUG(Service_NFC, "called, is_enabled={}", is_enabled);
+
+    const auto result = m_set_sys->SetNfcEnableFlag(is_enabled);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(result);
+}
+
 void NfcInterface::ReadMifare(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
     const auto device_handle{rp.Pop<u64>()};
diff --git a/src/core/hle/service/nfc/nfc_interface.h b/src/core/hle/service/nfc/nfc_interface.h
index 08be174d83..5cc0d8ec04 100644
--- a/src/core/hle/service/nfc/nfc_interface.h
+++ b/src/core/hle/service/nfc/nfc_interface.h
@@ -7,6 +7,10 @@
 #include "core/hle/service/nfc/nfc_types.h"
 #include "core/hle/service/service.h"
 
+namespace Service::Set {
+class ISystemSettingsServer;
+}
+
 namespace Service::NFC {
 class DeviceManager;
 
@@ -29,6 +33,7 @@ public:
     void AttachActivateEvent(HLERequestContext& ctx);
     void AttachDeactivateEvent(HLERequestContext& ctx);
     void ReadMifare(HLERequestContext& ctx);
+    void SetNfcEnabled(HLERequestContext& ctx);
     void WriteMifare(HLERequestContext& ctx);
     void SendCommandByPassThrough(HLERequestContext& ctx);
 
@@ -44,6 +49,7 @@ protected:
     BackendType backend_type;
     State state{State::NonInitialized};
     std::shared_ptr<DeviceManager> device_manager = nullptr;
+    std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
 };
 
 } // namespace Service::NFC