From 508bba2932178e4ba294c458937e10234c5913c0 Mon Sep 17 00:00:00 2001
From: wwylele <wwylele@gmail.com>
Date: Thu, 1 Mar 2018 21:12:20 +0200
Subject: [PATCH] Service/NIM: convert to ServiceFramework

---
 src/core/hle/ipc_helpers.h           |  8 -----
 src/core/hle/service/nim/nim.cpp     | 41 +++----------------------
 src/core/hle/service/nim/nim.h       | 32 ++-----------------
 src/core/hle/service/nim/nim_aoc.cpp | 27 ++++++++--------
 src/core/hle/service/nim/nim_aoc.h   |  9 ++----
 src/core/hle/service/nim/nim_s.cpp   | 21 +++++++------
 src/core/hle/service/nim/nim_s.h     |  9 ++----
 src/core/hle/service/nim/nim_u.cpp   | 46 ++++++++++++++++++++--------
 src/core/hle/service/nim/nim_u.h     | 31 ++++++++++++++++---
 src/core/hle/service/service.cpp     |  3 +-
 10 files changed, 99 insertions(+), 128 deletions(-)

diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index b2f8f97179..aaa5d429bb 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -116,9 +116,6 @@ public:
     void PushRaw(const T& value);
 
     // TODO : ensure that translate params are added after all regular params
-    template <typename... H>
-    [[deprecated]] void PushCopyHandles(H... handles);
-
     template <typename... O>
     void PushCopyObjects(Kernel::SharedPtr<O>... pointers);
 
@@ -185,11 +182,6 @@ void RequestBuilder::Push(const First& first_value, const Other&... other_values
     Push(other_values...);
 }
 
-template <typename... H>
-inline void RequestBuilder::PushCopyHandles(H... handles) {
-    PushCopyHLEHandles(handles...);
-}
-
 template <typename... H>
 inline void RequestBuilder::PushCopyHLEHandles(H... handles) {
     Push(CopyHandleDesc(sizeof...(H)));
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index b10d5852ba..f8d745fb4c 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -2,51 +2,18 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "core/hle/ipc.h"
-#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/service/nim/nim.h"
 #include "core/hle/service/nim/nim_aoc.h"
 #include "core/hle/service/nim/nim_s.h"
 #include "core/hle/service/nim/nim_u.h"
-#include "core/hle/service/service.h"
 
 namespace Service {
 namespace NIM {
 
-static Kernel::SharedPtr<Kernel::Event> nim_system_update_event;
-
-void CheckForSysUpdateEvent(Service::Interface* self) {
-    IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x5, 0, 0); // 0x50000
-    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
-    rb.Push(RESULT_SUCCESS);
-    rb.PushCopyHandles(Kernel::g_handle_table.Create(nim_system_update_event).Unwrap());
-    LOG_TRACE(Service_NIM, "called");
-}
-
-void CheckSysUpdateAvailable(Service::Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
-
-    cmd_buff[1] = RESULT_SUCCESS.raw;
-    cmd_buff[2] = 0; // No update available
-
-    LOG_WARNING(Service_NIM, "(STUBBED) called");
-}
-
-void Init() {
-    using namespace Kernel;
-
-    AddService(new NIM_AOC_Interface);
-    AddService(new NIM_S_Interface);
-    AddService(new NIM_U_Interface);
-
-    nim_system_update_event = Kernel::Event::Create(ResetType::OneShot, "NIM System Update Event");
-}
-
-void Shutdown() {
-    nim_system_update_event = nullptr;
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+    std::make_shared<NIM_AOC>()->InstallAsService(service_manager);
+    std::make_shared<NIM_S>()->InstallAsService(service_manager);
+    std::make_shared<NIM_U>()->InstallAsService(service_manager);
 }
 
 } // namespace NIM
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
index dbf605e5a6..4182d03615 100644
--- a/src/core/hle/service/nim/nim.h
+++ b/src/core/hle/service/nim/nim.h
@@ -4,38 +4,12 @@
 
 #pragma once
 
+#include "core/hle/service/service.h"
+
 namespace Service {
-
-class Interface;
-
 namespace NIM {
 
-/**
- * NIM::CheckForSysUpdateEvent service function
- *  Inputs:
- *      1 : None
- *  Outputs:
- *      1 : Result of function, 0 on success, otherwise error code
- *      2 : Copy handle descriptor
- *      3 : System Update event handle
- */
-void CheckForSysUpdateEvent(Service::Interface* self);
-
-/**
- * NIM::CheckSysUpdateAvailable service function
- *  Inputs:
- *      1 : None
- *  Outputs:
- *      1 : Result of function, 0 on success, otherwise error code
- *      2 : flag, 0 = no system update available, 1 = system update available.
- */
-void CheckSysUpdateAvailable(Service::Interface* self);
-
-/// Initialize NIM service(s)
-void Init();
-
-/// Shutdown NIM service(s)
-void Shutdown();
+void InstallInterfaces(SM::ServiceManager& service_manager);
 
 } // namespace NIM
 } // namespace Service
diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp
index 2d0fb6fc41..ffee9c5e18 100644
--- a/src/core/hle/service/nim/nim_aoc.cpp
+++ b/src/core/hle/service/nim/nim_aoc.cpp
@@ -7,20 +7,21 @@
 namespace Service {
 namespace NIM {
 
-const Interface::FunctionInfo FunctionTable[] = {
-    {0x00030042, nullptr, "SetApplicationId"},
-    {0x00040042, nullptr, "SetTin"},
-    {0x000902D0, nullptr, "ListContentSetsEx"},
-    {0x00180000, nullptr, "GetBalance"},
-    {0x001D0000, nullptr, "GetCustomerSupportCode"},
-    {0x00210000, nullptr, "Initialize"},
-    {0x00240282, nullptr, "CalculateContentsRequiredSize"},
-    {0x00250000, nullptr, "RefreshServerTime"},
-};
-
-NIM_AOC_Interface::NIM_AOC_Interface() {
-    Register(FunctionTable);
+NIM_AOC::NIM_AOC() : ServiceFramework("nim:aoc", 2) {
+    const FunctionInfo functions[] = {
+        {0x00030042, nullptr, "SetApplicationId"},
+        {0x00040042, nullptr, "SetTin"},
+        {0x000902D0, nullptr, "ListContentSetsEx"},
+        {0x00180000, nullptr, "GetBalance"},
+        {0x001D0000, nullptr, "GetCustomerSupportCode"},
+        {0x00210000, nullptr, "Initialize"},
+        {0x00240282, nullptr, "CalculateContentsRequiredSize"},
+        {0x00250000, nullptr, "RefreshServerTime"},
+    };
+    RegisterHandlers(functions);
 }
 
+NIM_AOC::~NIM_AOC() = default;
+
 } // namespace NIM
 } // namespace Service
diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h
index aace45b5aa..dc6fcec1c1 100644
--- a/src/core/hle/service/nim/nim_aoc.h
+++ b/src/core/hle/service/nim/nim_aoc.h
@@ -9,13 +9,10 @@
 namespace Service {
 namespace NIM {
 
-class NIM_AOC_Interface : public Service::Interface {
+class NIM_AOC final : public ServiceFramework<NIM_AOC> {
 public:
-    NIM_AOC_Interface();
-
-    std::string GetPortName() const override {
-        return "nim:aoc";
-    }
+    NIM_AOC();
+    ~NIM_AOC();
 };
 
 } // namespace NIM
diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp
index 28b87e6f7e..b0acc1937b 100644
--- a/src/core/hle/service/nim/nim_s.cpp
+++ b/src/core/hle/service/nim/nim_s.cpp
@@ -7,17 +7,18 @@
 namespace Service {
 namespace NIM {
 
-const Interface::FunctionInfo FunctionTable[] = {
-    {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"},
-    {0x0016020A, nullptr, "ListTitles"},
-    {0x00290000, nullptr, "AccountCheckBalanceSOAP"},
-    {0x002D0042, nullptr, "DownloadTickets"},
-    {0x00420240, nullptr, "StartDownload"},
-};
-
-NIM_S_Interface::NIM_S_Interface() {
-    Register(FunctionTable);
+NIM_S::NIM_S() : ServiceFramework("nim:s", 1) {
+    const FunctionInfo functions[] = {
+        {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"},
+        {0x0016020A, nullptr, "ListTitles"},
+        {0x00290000, nullptr, "AccountCheckBalanceSOAP"},
+        {0x002D0042, nullptr, "DownloadTickets"},
+        {0x00420240, nullptr, "StartDownload"},
+    };
+    RegisterHandlers(functions);
 }
 
+NIM_S::~NIM_S() = default;
+
 } // namespace NIM
 } // namespace Service
diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h
index f4bf73d263..bbcd40b5c0 100644
--- a/src/core/hle/service/nim/nim_s.h
+++ b/src/core/hle/service/nim/nim_s.h
@@ -9,13 +9,10 @@
 namespace Service {
 namespace NIM {
 
-class NIM_S_Interface : public Service::Interface {
+class NIM_S final : public ServiceFramework<NIM_S> {
 public:
-    NIM_S_Interface();
-
-    std::string GetPortName() const override {
-        return "nim:s";
-    }
+    NIM_S();
+    ~NIM_S();
 };
 
 } // namespace NIM
diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp
index 5696602780..5a7a2bafb4 100644
--- a/src/core/hle/service/nim/nim_u.cpp
+++ b/src/core/hle/service/nim/nim_u.cpp
@@ -2,24 +2,46 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "core/hle/service/nim/nim.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/event.h"
 #include "core/hle/service/nim/nim_u.h"
 
 namespace Service {
 namespace NIM {
 
-const Interface::FunctionInfo FunctionTable[] = {
-    {0x00010000, nullptr, "StartSysUpdate"},
-    {0x00020000, nullptr, "GetUpdateDownloadProgress"},
-    {0x00040000, nullptr, "FinishTitlesInstall"},
-    {0x00050000, CheckForSysUpdateEvent, "CheckForSysUpdateEvent"},
-    {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
-    {0x000A0000, nullptr, "GetState"},
-    {0x000B0000, nullptr, "GetSystemTitleHash"},
-};
+NIM_U::NIM_U() : ServiceFramework("nim:u", 2) {
+    const FunctionInfo functions[] = {
+        {0x00010000, nullptr, "StartSysUpdate"},
+        {0x00020000, nullptr, "GetUpdateDownloadProgress"},
+        {0x00040000, nullptr, "FinishTitlesInstall"},
+        {0x00050000, &NIM_U::CheckForSysUpdateEvent, "CheckForSysUpdateEvent"},
+        {0x00090000, &NIM_U::CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
+        {0x000A0000, nullptr, "GetState"},
+        {0x000B0000, nullptr, "GetSystemTitleHash"},
+    };
+    RegisterHandlers(functions);
+    nim_system_update_event =
+        Kernel::Event::Create(Kernel::ResetType::OneShot, "NIM System Update Event");
+}
 
-NIM_U_Interface::NIM_U_Interface() {
-    Register(FunctionTable);
+NIM_U::~NIM_U() = default;
+
+void NIM_U::CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x5, 0, 0); // 0x50000
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
+    rb.Push(RESULT_SUCCESS);
+    rb.PushCopyObjects(nim_system_update_event);
+    LOG_TRACE(Service_NIM, "called");
+}
+
+void NIM_U::CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x9, 0, 0); // 0x90000
+
+    IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(false); // No update available
+
+    LOG_WARNING(Service_NIM, "(STUBBED) called");
 }
 
 } // namespace NIM
diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h
index c4b74985ac..7dd8ea087f 100644
--- a/src/core/hle/service/nim/nim_u.h
+++ b/src/core/hle/service/nim/nim_u.h
@@ -9,13 +9,34 @@
 namespace Service {
 namespace NIM {
 
-class NIM_U_Interface : public Service::Interface {
+class NIM_U final : public ServiceFramework<NIM_U> {
 public:
-    NIM_U_Interface();
+    NIM_U();
+    ~NIM_U();
 
-    std::string GetPortName() const override {
-        return "nim:u";
-    }
+private:
+    /**
+     * NIM::CheckForSysUpdateEvent service function
+     *  Inputs:
+     *      1 : None
+     *  Outputs:
+     *      1 : Result of function, 0 on success, otherwise error code
+     *      2 : Copy handle descriptor
+     *      3 : System Update event handle
+     */
+    void CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx);
+
+    /**
+     * NIM::CheckSysUpdateAvailable service function
+     *  Inputs:
+     *      1 : None
+     *  Outputs:
+     *      1 : Result of function, 0 on success, otherwise error code
+     *      2 : u8 flag, 0 = no system update available, 1 = system update available.
+     */
+    void CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx);
+
+    Kernel::SharedPtr<Kernel::Event> nim_system_update_event;
 };
 
 } // namespace NIM
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index b6f59adf2e..75ae946619 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -252,7 +252,7 @@ void Init() {
     NDM::Init();
     NEWS::Init();
     NFC::Init();
-    NIM::Init();
+    NIM::InstallInterfaces(*SM::g_service_manager);
     NWM::Init();
     PTM::InstallInterfaces(*SM::g_service_manager);
     QTM::Init();
@@ -272,7 +272,6 @@ void Init() {
 /// Shutdown ServiceManager
 void Shutdown() {
     NFC::Shutdown();
-    NIM::Shutdown();
     NEWS::Shutdown();
     NDM::Shutdown();
     FRD::Shutdown();