From e8a960f6a1c86d15de03a26c22b868771a49929c Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Thu, 8 Dec 2016 02:43:27 -0500
Subject: [PATCH] service: Add nfc services

3dbrew was used for the command information.
---
 src/core/CMakeLists.txt            |  6 +++
 src/core/hle/service/nfc/nfc.cpp   | 18 +++++++++
 src/core/hle/service/nfc/nfc.h     | 14 +++++++
 src/core/hle/service/nfc/nfc_m.cpp | 44 +++++++++++++++++++++
 src/core/hle/service/nfc/nfc_m.h   | 22 +++++++++++
 src/core/hle/service/nfc/nfc_u.cpp | 41 ++++++++++++++++++++
 src/core/hle/service/nfc/nfc_u.h   | 22 +++++++++++
 src/core/hle/service/service.cpp   | 62 +++++++++++++++---------------
 8 files changed, 199 insertions(+), 30 deletions(-)
 create mode 100644 src/core/hle/service/nfc/nfc.cpp
 create mode 100644 src/core/hle/service/nfc/nfc.h
 create mode 100644 src/core/hle/service/nfc/nfc_m.cpp
 create mode 100644 src/core/hle/service/nfc/nfc_m.h
 create mode 100644 src/core/hle/service/nfc/nfc_u.cpp
 create mode 100644 src/core/hle/service/nfc/nfc_u.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8ce141e6a..a5b699047 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -107,6 +107,9 @@ set(SRCS
             hle/service/mic_u.cpp
             hle/service/ndm/ndm.cpp
             hle/service/ndm/ndm_u.cpp
+            hle/service/nfc/nfc.cpp
+            hle/service/nfc/nfc_m.cpp
+            hle/service/nfc/nfc_u.cpp
             hle/service/news/news.cpp
             hle/service/news/news_s.cpp
             hle/service/news/news_u.cpp
@@ -258,6 +261,9 @@ set(HEADERS
             hle/service/mic_u.h
             hle/service/ndm/ndm.h
             hle/service/ndm/ndm_u.h
+            hle/service/nfc/nfc.h
+            hle/service/nfc/nfc_m.h
+            hle/service/nfc/nfc_u.h
             hle/service/news/news.h
             hle/service/news/news_s.h
             hle/service/news/news_u.h
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
new file mode 100644
index 000000000..d9738c6a1
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -0,0 +1,18 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/nfc/nfc.h"
+#include "core/hle/service/nfc/nfc_m.h"
+#include "core/hle/service/nfc/nfc_u.h"
+
+namespace Service {
+namespace NFC {
+
+void Init() {
+    AddService(new NFC_M());
+    AddService(new NFC_U());
+}
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h
new file mode 100644
index 000000000..cd65a5fdc
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc.h
@@ -0,0 +1,14 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service {
+namespace NFC {
+
+/// Initialize all NFC services.
+void Init();
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/nfc/nfc_m.cpp b/src/core/hle/service/nfc/nfc_m.cpp
new file mode 100644
index 000000000..717335c11
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc_m.cpp
@@ -0,0 +1,44 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/nfc/nfc_m.h"
+
+namespace Service {
+namespace NFC {
+
+const Interface::FunctionInfo FunctionTable[] = {
+    // clang-format off
+    // nfc:u shared commands
+    {0x00010040, nullptr, "Initialize"},
+    {0x00020040, nullptr, "Shutdown"},
+    {0x00030000, nullptr, "StartCommunication"},
+    {0x00040000, nullptr, "StopCommunication"},
+    {0x00050040, nullptr, "StartTagScanning"},
+    {0x00060000, nullptr, "StopTagScanning"},
+    {0x00070000, nullptr, "LoadAmiiboData"},
+    {0x00080000, nullptr, "ResetTagScanState"},
+    {0x00090002, nullptr, "UpdateStoredAmiiboData"},
+    {0x000D0000, nullptr, "GetTagState"},
+    {0x000F0000, nullptr, "CommunicationGetStatus"},
+    {0x00100000, nullptr, "GetTagInfo2"},
+    {0x00110000, nullptr, "GetTagInfo"},
+    {0x00120000, nullptr, "CommunicationGetResult"},
+    {0x00130040, nullptr, "OpenAppData"},
+    {0x00140384, nullptr, "InitializeWriteAppData"},
+    {0x00150040, nullptr, "ReadAppData"},
+    {0x00160242, nullptr, "WriteAppData"},
+    {0x00170000, nullptr, "GetAmiiboSettings"},
+    {0x00180000, nullptr, "GetAmiiboConfig"},
+    {0x00190000, nullptr, "GetAppDataInitStruct"},
+    // nfc:m
+    {0x04040A40, nullptr, "SetAmiiboSettings"}
+    // clang-format on
+};
+
+NFC_M::NFC_M() {
+    Register(FunctionTable);
+}
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/nfc/nfc_m.h b/src/core/hle/service/nfc/nfc_m.h
new file mode 100644
index 000000000..fae75535b
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc_m.h
@@ -0,0 +1,22 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace NFC {
+
+class NFC_M final : public Interface {
+public:
+    NFC_M();
+
+    std::string GetPortName() const override {
+        return "nfc:m";
+    }
+};
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/nfc/nfc_u.cpp b/src/core/hle/service/nfc/nfc_u.cpp
new file mode 100644
index 000000000..deffb0b4f
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc_u.cpp
@@ -0,0 +1,41 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/nfc/nfc_u.h"
+
+namespace Service {
+namespace NFC {
+
+const Interface::FunctionInfo FunctionTable[] = {
+    // clang-format off
+    {0x00010040, nullptr, "Initialize"},
+    {0x00020040, nullptr, "Shutdown"},
+    {0x00030000, nullptr, "StartCommunication"},
+    {0x00040000, nullptr, "StopCommunication"},
+    {0x00050040, nullptr, "StartTagScanning"},
+    {0x00060000, nullptr, "StopTagScanning"},
+    {0x00070000, nullptr, "LoadAmiiboData"},
+    {0x00080000, nullptr, "ResetTagScanState"},
+    {0x00090002, nullptr, "UpdateStoredAmiiboData"},
+    {0x000D0000, nullptr, "GetTagState"},
+    {0x000F0000, nullptr, "CommunicationGetStatus"},
+    {0x00100000, nullptr, "GetTagInfo2"},
+    {0x00110000, nullptr, "GetTagInfo"},
+    {0x00120000, nullptr, "CommunicationGetResult"},
+    {0x00130040, nullptr, "OpenAppData"},
+    {0x00140384, nullptr, "InitializeWriteAppData"},
+    {0x00150040, nullptr, "ReadAppData"},
+    {0x00160242, nullptr, "WriteAppData"},
+    {0x00170000, nullptr, "GetAmiiboSettings"},
+    {0x00180000, nullptr, "GetAmiiboConfig"},
+    {0x00190000, nullptr, "GetAppDataInitStruct"},
+    // clang-format on
+};
+
+NFC_U::NFC_U() {
+    Register(FunctionTable);
+}
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/nfc/nfc_u.h b/src/core/hle/service/nfc/nfc_u.h
new file mode 100644
index 000000000..eb7507314
--- /dev/null
+++ b/src/core/hle/service/nfc/nfc_u.h
@@ -0,0 +1,22 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace NFC {
+
+class NFC_U final : public Interface {
+public:
+    NFC_U();
+
+    std::string GetPortName() const override {
+        return "nfc:u";
+    }
+};
+
+} // namespace NFC
+} // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index ca7eeac8a..5f16c18fa 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -28,6 +28,7 @@
 #include "core/hle/service/mic_u.h"
 #include "core/hle/service/ndm/ndm.h"
 #include "core/hle/service/news/news.h"
+#include "core/hle/service/nfc/nfc.h"
 #include "core/hle/service/nim/nim.h"
 #include "core/hle/service/ns_s.h"
 #include "core/hle/service/nwm_uds.h"
@@ -109,21 +110,22 @@ void Init() {
     AddNamedPort(new SRV::Interface);
     AddNamedPort(new ERR_F::Interface);
 
-    Service::FS::ArchiveInit();
-    Service::AM::Init();
-    Service::APT::Init();
-    Service::BOSS::Init();
-    Service::CAM::Init();
-    Service::CECD::Init();
-    Service::CFG::Init();
-    Service::DLP::Init();
-    Service::FRD::Init();
-    Service::HID::Init();
-    Service::IR::Init();
-    Service::NEWS::Init();
-    Service::NDM::Init();
-    Service::NIM::Init();
-    Service::PTM::Init();
+    FS::ArchiveInit();
+    AM::Init();
+    APT::Init();
+    BOSS::Init();
+    CAM::Init();
+    CECD::Init();
+    CFG::Init();
+    DLP::Init();
+    FRD::Init();
+    HID::Init();
+    IR::Init();
+    NDM::Init();
+    NEWS::Init();
+    NFC::Init();
+    NIM::Init();
+    PTM::Init();
 
     AddService(new AC_U::Interface);
     AddService(new ACT_A::Interface);
@@ -148,21 +150,21 @@ void Init() {
 /// Shutdown ServiceManager
 void Shutdown() {
 
-    Service::PTM::Shutdown();
-    Service::NDM::Shutdown();
-    Service::NIM::Shutdown();
-    Service::NEWS::Shutdown();
-    Service::IR::Shutdown();
-    Service::HID::Shutdown();
-    Service::FRD::Shutdown();
-    Service::DLP::Shutdown();
-    Service::CFG::Shutdown();
-    Service::CECD::Shutdown();
-    Service::CAM::Shutdown();
-    Service::BOSS::Shutdown();
-    Service::APT::Shutdown();
-    Service::AM::Shutdown();
-    Service::FS::ArchiveShutdown();
+    PTM::Shutdown();
+    NIM::Shutdown();
+    NEWS::Shutdown();
+    NDM::Shutdown();
+    IR::Shutdown();
+    HID::Shutdown();
+    FRD::Shutdown();
+    DLP::Shutdown();
+    CFG::Shutdown();
+    CECD::Shutdown();
+    CAM::Shutdown();
+    BOSS::Shutdown();
+    APT::Shutdown();
+    AM::Shutdown();
+    FS::ArchiveShutdown();
 
     g_srv_services.clear();
     g_kernel_named_ports.clear();