From 363d6fdb892afe97d75d24566532fe32042fba2b Mon Sep 17 00:00:00 2001
From: NarcolepticK <NarcolepticKrias@gmail.com>
Date: Sat, 30 Jun 2018 23:27:57 -0400
Subject: [PATCH] service/cecd: Migrate to ServiceFramework

---
 src/core/hle/service/cecd/cecd.cpp     | 58 +++++++++---------
 src/core/hle/service/cecd/cecd.h       | 85 +++++++++++++++-----------
 src/core/hle/service/cecd/cecd_ndm.cpp | 20 +++---
 src/core/hle/service/cecd/cecd_ndm.h   | 10 +--
 src/core/hle/service/cecd/cecd_s.cpp   | 46 +++++++-------
 src/core/hle/service/cecd/cecd_s.h     | 10 +--
 src/core/hle/service/cecd/cecd_u.cpp   | 46 +++++++-------
 src/core/hle/service/cecd/cecd_u.h     | 10 +--
 src/core/hle/service/service.cpp       |  3 +-
 9 files changed, 148 insertions(+), 140 deletions(-)

diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp
index 421006a9e..7fdeb3466 100644
--- a/src/core/hle/service/cecd/cecd.cpp
+++ b/src/core/hle/service/cecd/cecd.cpp
@@ -3,64 +3,62 @@
 // Refer to the license.txt file included.
 
 #include "common/logging/log.h"
-#include "core/hle/ipc.h"
-#include "core/hle/kernel/event.h"
-#include "core/hle/kernel/handle_table.h"
+#include "core/hle/ipc_helpers.h"
 #include "core/hle/result.h"
 #include "core/hle/service/cecd/cecd.h"
 #include "core/hle/service/cecd/cecd_ndm.h"
 #include "core/hle/service/cecd/cecd_s.h"
 #include "core/hle/service/cecd/cecd_u.h"
-#include "core/hle/service/service.h"
+
 
 namespace Service {
 namespace CECD {
 
-static Kernel::SharedPtr<Kernel::Event> cecinfo_event;
-static Kernel::SharedPtr<Kernel::Event> change_state_event;
+void Module::Interface::GetCecStateAbbreviated(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x0E, 0, 0);
 
-void GetCecStateAbbreviated(Service::Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
-
-    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
-    cmd_buff[2] = static_cast<u32>(CecStateAbbreviated::CEC_STATE_ABBREV_IDLE);
+    IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
+    rb.Push(RESULT_SUCCESS);
+    rb.Push<u32>(static_cast<u32>(CecStateAbbreviated::CEC_STATE_ABBREV_IDLE));
 
     LOG_WARNING(Service_CECD, "(STUBBED) called");
 }
 
-void GetCecInfoEventHandle(Service::Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
+void Module::Interface::GetCecInfoEventHandle(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x0F, 0, 0);
 
-    cmd_buff[1] = RESULT_SUCCESS.raw;                                    // No error
-    cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).Unwrap(); // Event handle
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
+    rb.Push(RESULT_SUCCESS);
+    rb.PushCopyObjects(cecd->cecinfo_event);
 
     LOG_WARNING(Service_CECD, "(STUBBED) called");
 }
 
-void GetChangeStateEventHandle(Service::Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
+void Module::Interface::GetChangeStateEventHandle(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x10, 0, 0);
 
-    cmd_buff[1] = RESULT_SUCCESS.raw;                                         // No error
-    cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).Unwrap(); // Event handle
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
+    rb.Push(RESULT_SUCCESS);
+    rb.PushCopyObjects(cecd->change_state_event);
 
     LOG_WARNING(Service_CECD, "(STUBBED) called");
 }
 
-void Init() {
-    AddService(new CECD_NDM);
-    AddService(new CECD_S);
-    AddService(new CECD_U);
+Module::Interface::Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session)
+    : ServiceFramework(name, max_session), cecd(std::move(cecd)) {}
 
-    cecinfo_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
-    change_state_event =
-        Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD::change_state_event");
+Module::Module() {
+    using namespace Kernel;
+    cecinfo_event = Event::Create(Kernel::ResetType::OneShot, "CECD::cecinfo_event");
+    change_state_event = Event::Create(Kernel::ResetType::OneShot, "CECD::change_state_event");
 }
 
-void Shutdown() {
-    cecinfo_event = nullptr;
-    change_state_event = nullptr;
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+    auto cecd = std::make_shared<Module>();
+    std::make_shared<CECD_NDM>(cecd)->InstallAsService(service_manager);
+    std::make_shared<CECD_S>(cecd)->InstallAsService(service_manager);
+    std::make_shared<CECD_U>(cecd)->InstallAsService(service_manager);
 }
 
 } // namespace CECD
-
 } // namespace Service
diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h
index ea97f9266..e2557a3db 100644
--- a/src/core/hle/service/cecd/cecd.h
+++ b/src/core/hle/service/cecd/cecd.h
@@ -4,10 +4,10 @@
 
 #pragma once
 
+#include "core/hle/kernel/event.h"
+#include "core/hle/service/service.h"
+
 namespace Service {
-
-class Interface;
-
 namespace CECD {
 
 enum class CecStateAbbreviated {
@@ -20,41 +20,58 @@ enum class CecStateAbbreviated {
                                 /// OVER_BOSS and those listed here
 };
 
-/**
- * GetCecStateAbbreviated service function
- *  Inputs:
- *      0: 0x000E0000
- *  Outputs:
- *      1: ResultCode
- *      2: CecStateAbbreviated
- */
-void GetCecStateAbbreviated(Service::Interface* self);
+class Module final {
+public:
+    Module();
+    ~Module() = default;
 
-/**
- * GetCecInfoEventHandle service function
- *  Inputs:
- *      0: 0x000F0000
- *  Outputs:
- *      1: ResultCode
- *      3: Event Handle
- */
-void GetCecInfoEventHandle(Service::Interface* self);
+    class Interface : public ServiceFramework<Interface> {
+    public:
+        Interface(std::shared_ptr<Module> cecd, const char* name, u32 max_session);
+        ~Interface() = default;
 
-/**
- * GetChangeStateEventHandle service function
- *  Inputs:
- *      0: 0x00100000
- *  Outputs:
- *      1: ResultCode
- *      3: Event Handle
- */
-void GetChangeStateEventHandle(Service::Interface* self);
+    protected:
+        /**
+         * GetCecStateAbbreviated service function
+         *  Inputs:
+         *      0: 0x000E0000
+         *  Outputs:
+         *      1: ResultCode
+         *      2: CecStateAbbreviated
+         */
+        void GetCecStateAbbreviated(Kernel::HLERequestContext& ctx);
+
+        /**
+         * GetCecInfoEventHandle service function
+         *  Inputs:
+         *      0: 0x000F0000
+         *  Outputs:
+         *      1: ResultCode
+         *      3: Event Handle
+         */
+        void GetCecInfoEventHandle(Kernel::HLERequestContext& ctx);
+
+        /**
+         * GetChangeStateEventHandle service function
+         *  Inputs:
+         *      0: 0x00100000
+         *  Outputs:
+         *      1: ResultCode
+         *      3: Event Handle
+         */
+        void GetChangeStateEventHandle(Kernel::HLERequestContext& ctx);
+
+    private:
+        std::shared_ptr<Module> cecd;
+    };
+
+private:
+    Kernel::SharedPtr<Kernel::Event> cecinfo_event;
+    Kernel::SharedPtr<Kernel::Event> change_state_event;
+};
 
 /// Initialize CECD service(s)
-void Init();
-
-/// Shutdown CECD service(s)
-void Shutdown();
+void InstallInterfaces(SM::ServiceManager& service_manager);
 
 } // namespace CECD
 } // namespace Service
diff --git a/src/core/hle/service/cecd/cecd_ndm.cpp b/src/core/hle/service/cecd/cecd_ndm.cpp
index 7baf93750..f615c13bf 100644
--- a/src/core/hle/service/cecd/cecd_ndm.cpp
+++ b/src/core/hle/service/cecd/cecd_ndm.cpp
@@ -2,21 +2,23 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "core/hle/service/cecd/cecd.h"
 #include "core/hle/service/cecd/cecd_ndm.h"
 
 namespace Service {
 namespace CECD {
 
-static const Interface::FunctionInfo FunctionTable[] = {
-    {0x00010000, nullptr, "Initialize"},
-    {0x00020000, nullptr, "Deinitialize"},
-    {0x00030000, nullptr, "ResumeDaemon"},
-    {0x00040040, nullptr, "SuspendDaemon"},
-};
+CECD_NDM::CECD_NDM(std::shared_ptr<Module> cecd)
+    : Module::Interface(std::move(cecd), "cecd:ndm", DefaultMaxSessions) {
+    static const FunctionInfo functions[] = {
+        // clang-format off
+        {0x00010000, nullptr, "Initialize"},
+        {0x00020000, nullptr, "Deinitialize"},
+        {0x00030000, nullptr, "ResumeDaemon"},
+        {0x00040040, nullptr, "SuspendDaemon"},
+        // clang-format on
+    };
 
-CECD_NDM::CECD_NDM() {
-    Register(FunctionTable);
+    RegisterHandlers(functions);
 }
 
 } // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_ndm.h b/src/core/hle/service/cecd/cecd_ndm.h
index 2e2e50ada..01e9e19fd 100644
--- a/src/core/hle/service/cecd/cecd_ndm.h
+++ b/src/core/hle/service/cecd/cecd_ndm.h
@@ -4,18 +4,14 @@
 
 #pragma once
 
-#include "core/hle/service/service.h"
+#include "core/hle/service/cecd/cecd.h"
 
 namespace Service {
 namespace CECD {
 
-class CECD_NDM : public Interface {
+class CECD_NDM final : public Module::Interface {
 public:
-    CECD_NDM();
-
-    std::string GetPortName() const override {
-        return "cecd:ndm";
-    }
+    explicit CECD_NDM(std::shared_ptr<Module> cecd);
 };
 
 } // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp
index eacda7d41..f9cab854e 100644
--- a/src/core/hle/service/cecd/cecd_s.cpp
+++ b/src/core/hle/service/cecd/cecd_s.cpp
@@ -2,34 +2,36 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "core/hle/service/cecd/cecd.h"
 #include "core/hle/service/cecd/cecd_s.h"
 
 namespace Service {
 namespace CECD {
 
-static const Interface::FunctionInfo FunctionTable[] = {
-    // cecd:u shared commands
-    {0x000100C2, nullptr, "OpenRawFile"},
-    {0x00020042, nullptr, "ReadRawFile"},
-    {0x00030104, nullptr, "ReadMessage"},
-    {0x00040106, nullptr, "ReadMessageWithHMAC"},
-    {0x00050042, nullptr, "WriteRawFile"},
-    {0x00060104, nullptr, "WriteMessage"},
-    {0x00070106, nullptr, "WriteMessageWithHMAC"},
-    {0x00080102, nullptr, "Delete"},
-    {0x000A00C4, nullptr, "GetSystemInfo"},
-    {0x000B0040, nullptr, "RunCommand"},
-    {0x000C0040, nullptr, "RunCommandAlt"},
-    {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"},
-    {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"},
-    {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"},
-    {0x00110104, nullptr, "OpenAndWrite"},
-    {0x00120104, nullptr, "OpenAndRead"},
-};
+CECD_S::CECD_S(std::shared_ptr<Module> cecd)
+    : Module::Interface(std::move(cecd), "cecd:s", DefaultMaxSessions) {
+    static const FunctionInfo functions[] = {
+        // cecd:u shared commands
+        // clang-format off
+        {0x000100C2, nullptr, "OpenRawFile"},
+        {0x00020042, nullptr, "ReadRawFile"},
+        {0x00030104, nullptr, "ReadMessage"},
+        {0x00040106, nullptr, "ReadMessageWithHMAC"},
+        {0x00050042, nullptr, "WriteRawFile"},
+        {0x00060104, nullptr, "WriteMessage"},
+        {0x00070106, nullptr, "WriteMessageWithHMAC"},
+        {0x00080102, nullptr, "Delete"},
+        {0x000A00C4, nullptr, "GetSystemInfo"},
+        {0x000B0040, nullptr, "RunCommand"},
+        {0x000C0040, nullptr, "RunCommandAlt"},
+        {0x000E0000, &CECD_S::GetCecStateAbbreviated, "GetCecStateAbbreviated"},
+        {0x000F0000, &CECD_S::GetCecInfoEventHandle, "GetCecInfoEventHandle"},
+        {0x00100000, &CECD_S::GetChangeStateEventHandle, "GetChangeStateEventHandle"},
+        {0x00110104, nullptr, "OpenAndWrite"},
+        {0x00120104, nullptr, "OpenAndRead"},
+        // clang-format on
+    };
 
-CECD_S::CECD_S() {
-    Register(FunctionTable);
+    RegisterHandlers(functions);
 }
 
 } // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_s.h b/src/core/hle/service/cecd/cecd_s.h
index ab6c6789a..96ac68756 100644
--- a/src/core/hle/service/cecd/cecd_s.h
+++ b/src/core/hle/service/cecd/cecd_s.h
@@ -4,18 +4,14 @@
 
 #pragma once
 
-#include "core/hle/service/service.h"
+#include "core/hle/service/cecd/cecd.h"
 
 namespace Service {
 namespace CECD {
 
-class CECD_S : public Interface {
+class CECD_S final : public Module::Interface {
 public:
-    CECD_S();
-
-    std::string GetPortName() const override {
-        return "cecd:s";
-    }
+    explicit CECD_S(std::shared_ptr<Module> cecd);
 };
 
 } // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp
index 3ed864f0b..d13c3ca09 100644
--- a/src/core/hle/service/cecd/cecd_u.cpp
+++ b/src/core/hle/service/cecd/cecd_u.cpp
@@ -2,34 +2,36 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include "core/hle/service/cecd/cecd.h"
 #include "core/hle/service/cecd/cecd_u.h"
 
 namespace Service {
 namespace CECD {
 
-static const Interface::FunctionInfo FunctionTable[] = {
-    // cecd:u shared commands
-    {0x000100C2, nullptr, "OpenRawFile"},
-    {0x00020042, nullptr, "ReadRawFile"},
-    {0x00030104, nullptr, "ReadMessage"},
-    {0x00040106, nullptr, "ReadMessageWithHMAC"},
-    {0x00050042, nullptr, "WriteRawFile"},
-    {0x00060104, nullptr, "WriteMessage"},
-    {0x00070106, nullptr, "WriteMessageWithHMAC"},
-    {0x00080102, nullptr, "Delete"},
-    {0x000A00C4, nullptr, "GetSystemInfo"},
-    {0x000B0040, nullptr, "RunCommand"},
-    {0x000C0040, nullptr, "RunCommandAlt"},
-    {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"},
-    {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"},
-    {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"},
-    {0x00110104, nullptr, "OpenAndWrite"},
-    {0x00120104, nullptr, "OpenAndRead"},
-};
+CECD_U::CECD_U(std::shared_ptr<Module> cecd)
+    : Module::Interface(std::move(cecd), "cecd:u", DefaultMaxSessions) {
+    static const FunctionInfo functions[] = {
+        // cecd:u shared commands
+        // clang-format off
+        {0x000100C2, nullptr, "OpenRawFile"},
+        {0x00020042, nullptr, "ReadRawFile"},
+        {0x00030104, nullptr, "ReadMessage"},
+        {0x00040106, nullptr, "ReadMessageWithHMAC"},
+        {0x00050042, nullptr, "WriteRawFile"},
+        {0x00060104, nullptr, "WriteMessage"},
+        {0x00070106, nullptr, "WriteMessageWithHMAC"},
+        {0x00080102, nullptr, "Delete"},
+        {0x000A00C4, nullptr, "GetSystemInfo"},
+        {0x000B0040, nullptr, "RunCommand"},
+        {0x000C0040, nullptr, "RunCommandAlt"},
+        {0x000E0000, &CECD_U::GetCecStateAbbreviated, "GetCecStateAbbreviated"},
+        {0x000F0000, &CECD_U::GetCecInfoEventHandle, "GetCecInfoEventHandle"},
+        {0x00100000, &CECD_U::GetChangeStateEventHandle, "GetChangeStateEventHandle"},
+        {0x00110104, nullptr, "OpenAndWrite"},
+        {0x00120104, nullptr, "OpenAndRead"},
+        // clang-format on
+    };
 
-CECD_U::CECD_U() {
-    Register(FunctionTable);
+    RegisterHandlers(functions);
 }
 
 } // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_u.h b/src/core/hle/service/cecd/cecd_u.h
index 16e874ff5..39712e71a 100644
--- a/src/core/hle/service/cecd/cecd_u.h
+++ b/src/core/hle/service/cecd/cecd_u.h
@@ -4,18 +4,14 @@
 
 #pragma once
 
-#include "core/hle/service/service.h"
+#include "core/hle/service/cecd/cecd.h"
 
 namespace Service {
 namespace CECD {
 
-class CECD_U : public Interface {
+class CECD_U final : public Module::Interface {
 public:
-    CECD_U();
-
-    std::string GetPortName() const override {
-        return "cecd:u";
-    }
+    explicit CECD_U(std::shared_ptr<Module> cecd);
 };
 
 } // namespace CECD
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 881a51a7d..d5979c4dd 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -239,7 +239,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
     APT::InstallInterfaces(*sm);
     BOSS::Init();
     CAM::InstallInterfaces(*sm);
-    CECD::Init();
+    CECD::InstallInterfaces(*sm);
     CFG::InstallInterfaces(*sm);
     DLP::InstallInterfaces(*sm);
     FRD::InstallInterfaces(*sm);
@@ -268,7 +268,6 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
 
 /// Shutdown ServiceManager
 void Shutdown() {
-    CECD::Shutdown();
     BOSS::Shutdown();
     FS::ArchiveShutdown();