summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/hle/service/frd/frd.cpp91
-rw-r--r--src/core/hle/service/frd/frd.h88
-rw-r--r--src/core/hle/service/frd/frd_u.cpp107
-rw-r--r--src/core/hle/service/service.cpp3
6 files changed, 236 insertions, 55 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 4c86151ab..757e0cf47 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -34,6 +34,7 @@ namespace Log {
SUB(Kernel, SVC) \
CLS(Service) \
SUB(Service, SRV) \
+ SUB(Service, FRD) \
SUB(Service, FS) \
SUB(Service, ERR) \
SUB(Service, APT) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index e4c39c308..4da4831c3 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -49,6 +49,7 @@ enum class Class : ClassType {
Service, ///< HLE implementation of system services. Each major service
/// should have its own subclass.
Service_SRV, ///< The SRV (Service Directory) implementation
+ Service_FRD, ///< The FRD (Friends) service
Service_FS, ///< The FS (Filesystem) service implementation
Service_ERR, ///< The ERR (Error) port implementation
Service_APT, ///< The APT (Applets) service
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
index c13ffd9d2..15d604bb6 100644
--- a/src/core/hle/service/frd/frd.cpp
+++ b/src/core/hle/service/frd/frd.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/string_util.h"
+
#include "core/hle/service/service.h"
#include "core/hle/service/frd/frd.h"
#include "core/hle/service/frd/frd_a.h"
@@ -10,6 +12,95 @@
namespace Service {
namespace FRD {
+static FriendKey my_friend_key = {0, 0, 0ull};
+static MyPresence my_presence = {};
+
+void GetMyPresence(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 shifted_out_size = cmd_buff[64];
+ u32 my_presence_addr = cmd_buff[65];
+
+ ASSERT(shifted_out_size == ((sizeof(MyPresence) << 14) | 2));
+
+ Memory::WriteBlock(my_presence_addr, reinterpret_cast<const u8*>(&my_presence), sizeof(MyPresence));
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_FRD, "(STUBBED) called");
+}
+
+void GetFriendKeyList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unknown = cmd_buff[1];
+ u32 frd_count = cmd_buff[2];
+ u32 frd_key_addr = cmd_buff[65];
+
+ FriendKey zero_key = {};
+ for (u32 i = 0; i < frd_count; ++i) {
+ Memory::WriteBlock(frd_key_addr + i * sizeof(FriendKey),
+ reinterpret_cast<const u8*>(&zero_key), sizeof(FriendKey));
+ }
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = 0; // 0 friends
+ LOG_WARNING(Service_FRD, "(STUBBED) called, unknown=%d, frd_count=%d, frd_key_addr=0x%08X",
+ unknown, frd_count, frd_key_addr);
+}
+
+void GetFriendProfile(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 count = cmd_buff[1];
+ u32 frd_key_addr = cmd_buff[3];
+ u32 profiles_addr = cmd_buff[65];
+
+ Profile zero_profile = {};
+ for (u32 i = 0; i < count; ++i) {
+ Memory::WriteBlock(profiles_addr + i * sizeof(Profile),
+ reinterpret_cast<const u8*>(&zero_profile), sizeof(Profile));
+ }
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, profiles_addr=0x%08X",
+ count, frd_key_addr, profiles_addr);
+}
+
+void GetFriendAttributeFlags(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 count = cmd_buff[1];
+ u32 frd_key_addr = cmd_buff[3];
+ u32 attr_flags_addr = cmd_buff[65];
+
+ for (u32 i = 0; i < count; ++i) {
+ //TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte
+ Memory::Write8(attr_flags_addr + i, 0);
+ }
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, attr_flags_addr=0x%08X",
+ count, frd_key_addr, attr_flags_addr);
+}
+
+void GetMyFriendKey(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ Memory::WriteBlock(cmd_buff[2], reinterpret_cast<const u8*>(&my_friend_key), sizeof(FriendKey));
+ LOG_WARNING(Service_FRD, "(STUBBED) called");
+}
+
+void GetMyScreenName(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ // TODO: (mailwl) get the name from config
+ Common::UTF8ToUTF16("Citra").copy(reinterpret_cast<char16_t*>(&cmd_buff[2]), 11);
+ LOG_WARNING(Service_FRD, "(STUBBED) called");
+}
+
void Init() {
using namespace Kernel;
diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h
index f9f88b444..c8283a7f3 100644
--- a/src/core/hle/service/frd/frd.h
+++ b/src/core/hle/service/frd/frd.h
@@ -4,9 +4,97 @@
#pragma once
+#include "common/common_types.h"
+
namespace Service {
+
+class Interface;
+
namespace FRD {
+struct FriendKey {
+ u32 friend_id;
+ u32 unknown;
+ u64 friend_code;
+};
+
+struct MyPresence {
+ u8 unknown[0x12C];
+};
+
+struct Profile {
+ u8 region;
+ u8 country;
+ u8 area;
+ u8 language;
+ u32 unknown;
+};
+
+/**
+ * FRD::GetMyPresence service function
+ * Inputs:
+ * 64 : sizeof (MyPresence) << 14 | 2
+ * 65 : Address of MyPresence structure
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void GetMyPresence(Service::Interface* self);
+
+/**
+ * FRD::GetFriendKeyList service function
+ * Inputs:
+ * 1 : Unknown
+ * 2 : Max friends count
+ * 65 : Address of FriendKey List
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : FriendKey count filled
+ */
+void GetFriendKeyList(Service::Interface* self);
+
+/**
+ * FRD::GetFriendProfile service function
+ * Inputs:
+ * 1 : Friends count
+ * 2 : Friends count << 18 | 2
+ * 3 : Address of FriendKey List
+ * 64 : (count * sizeof (Profile)) << 10 | 2
+ * 65 : Address of Profiles List
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void GetFriendProfile(Service::Interface* self);
+
+/**
+ * FRD::GetFriendAttributeFlags service function
+ * Inputs:
+ * 1 : Friends count
+ * 2 : Friends count << 18 | 2
+ * 3 : Address of FriendKey List
+ * 65 : Address of AttributeFlags
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void GetFriendAttributeFlags(Service::Interface* self);
+
+/**
+ * FRD::GetMyFriendKey service function
+ * Inputs:
+ * none
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2-5 : FriendKey
+ */
+void GetMyFriendKey(Service::Interface* self);
+
+/**
+ * FRD::GetMyScreenName service function
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : UTF16 encoded name (max 11 symbols)
+ */
+void GetMyScreenName(Service::Interface* self);
+
/// Initialize FRD service(s)
void Init();
diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp
index 2c6885377..db8666416 100644
--- a/src/core/hle/service/frd/frd_u.cpp
+++ b/src/core/hle/service/frd/frd_u.cpp
@@ -2,65 +2,66 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/hle/service/frd/frd.h"
#include "core/hle/service/frd/frd_u.h"
namespace Service {
namespace FRD {
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010000, nullptr, "HasLoggedIn"},
- {0x00020000, nullptr, "IsOnline"},
- {0x00030000, nullptr, "Login"},
- {0x00040000, nullptr, "Logout"},
- {0x00050000, nullptr, "GetMyFriendKey"},
- {0x00060000, nullptr, "GetMyPreference"},
- {0x00070000, nullptr, "GetMyProfile"},
- {0x00080000, nullptr, "GetMyPresence"},
- {0x00090000, nullptr, "GetMyScreenName"},
- {0x000A0000, nullptr, "GetMyMii"},
- {0x000B0000, nullptr, "GetMyLocalAccountId"},
- {0x000C0000, nullptr, "GetMyPlayingGame"},
- {0x000D0000, nullptr, "GetMyFavoriteGame"},
- {0x000E0000, nullptr, "GetMyNcPrincipalId"},
- {0x000F0000, nullptr, "GetMyComment"},
- {0x00100040, nullptr, "GetMyPassword"},
- {0x00110080, nullptr, "GetFriendKeyList"},
- {0x00120042, nullptr, "GetFriendPresence"},
- {0x00130142, nullptr, "GetFriendScreenName"},
- {0x00140044, nullptr, "GetFriendMii"},
- {0x00150042, nullptr, "GetFriendProfile"},
- {0x00160042, nullptr, "GetFriendRelationship"},
- {0x00170042, nullptr, "GetFriendAttributeFlags"},
- {0x00180044, nullptr, "GetFriendPlayingGame"},
- {0x00190042, nullptr, "GetFriendFavoriteGame"},
- {0x001A00C4, nullptr, "GetFriendInfo"},
- {0x001B0080, nullptr, "IsIncludedInFriendList"},
- {0x001C0042, nullptr, "UnscrambleLocalFriendCode"},
- {0x001D0002, nullptr, "UpdateGameModeDescription"},
- {0x001E02C2, nullptr, "UpdateGameMode"},
- {0x001F0042, nullptr, "SendInvitation"},
- {0x00200002, nullptr, "AttachToEventNotification"},
- {0x00210040, nullptr, "SetNotificationMask"},
- {0x00220040, nullptr, "GetEventNotification"},
- {0x00230000, nullptr, "GetLastResponseResult"},
- {0x00240040, nullptr, "PrincipalIdToFriendCode"},
- {0x00250080, nullptr, "FriendCodeToPrincipalId"},
- {0x00260080, nullptr, "IsValidFriendCode"},
- {0x00270040, nullptr, "ResultToErrorCode"},
- {0x00280244, nullptr, "RequestGameAuthentication"},
- {0x00290000, nullptr, "GetGameAuthenticationData"},
- {0x002A0204, nullptr, "RequestServiceLocator"},
- {0x002B0000, nullptr, "GetServiceLocatorData"},
- {0x002C0002, nullptr, "DetectNatProperties"},
- {0x002D0000, nullptr, "GetNatProperties"},
- {0x002E0000, nullptr, "GetServerTimeInterval"},
- {0x002F0040, nullptr, "AllowHalfAwake"},
- {0x00300000, nullptr, "GetServerTypes"},
- {0x00310082, nullptr, "GetFriendComment"},
- {0x00320042, nullptr, "SetClientSdkVersion"},
- {0x00330000, nullptr, "GetMyApproachContext"},
- {0x00340046, nullptr, "AddFriendWithApproach"},
- {0x00350082, nullptr, "DecryptApproachContext"},
+ {0x00010000, nullptr, "HasLoggedIn"},
+ {0x00020000, nullptr, "IsOnline"},
+ {0x00030000, nullptr, "Login"},
+ {0x00040000, nullptr, "Logout"},
+ {0x00050000, GetMyFriendKey, "GetMyFriendKey"},
+ {0x00060000, nullptr, "GetMyPreference"},
+ {0x00070000, nullptr, "GetMyProfile"},
+ {0x00080000, GetMyPresence, "GetMyPresence"},
+ {0x00090000, GetMyScreenName, "GetMyScreenName"},
+ {0x000A0000, nullptr, "GetMyMii"},
+ {0x000B0000, nullptr, "GetMyLocalAccountId"},
+ {0x000C0000, nullptr, "GetMyPlayingGame"},
+ {0x000D0000, nullptr, "GetMyFavoriteGame"},
+ {0x000E0000, nullptr, "GetMyNcPrincipalId"},
+ {0x000F0000, nullptr, "GetMyComment"},
+ {0x00100040, nullptr, "GetMyPassword"},
+ {0x00110080, GetFriendKeyList, "GetFriendKeyList"},
+ {0x00120042, nullptr, "GetFriendPresence"},
+ {0x00130142, nullptr, "GetFriendScreenName"},
+ {0x00140044, nullptr, "GetFriendMii"},
+ {0x00150042, GetFriendProfile, "GetFriendProfile"},
+ {0x00160042, nullptr, "GetFriendRelationship"},
+ {0x00170042, GetFriendAttributeFlags, "GetFriendAttributeFlags"},
+ {0x00180044, nullptr, "GetFriendPlayingGame"},
+ {0x00190042, nullptr, "GetFriendFavoriteGame"},
+ {0x001A00C4, nullptr, "GetFriendInfo"},
+ {0x001B0080, nullptr, "IsIncludedInFriendList"},
+ {0x001C0042, nullptr, "UnscrambleLocalFriendCode"},
+ {0x001D0002, nullptr, "UpdateGameModeDescription"},
+ {0x001E02C2, nullptr, "UpdateGameMode"},
+ {0x001F0042, nullptr, "SendInvitation"},
+ {0x00200002, nullptr, "AttachToEventNotification"},
+ {0x00210040, nullptr, "SetNotificationMask"},
+ {0x00220040, nullptr, "GetEventNotification"},
+ {0x00230000, nullptr, "GetLastResponseResult"},
+ {0x00240040, nullptr, "PrincipalIdToFriendCode"},
+ {0x00250080, nullptr, "FriendCodeToPrincipalId"},
+ {0x00260080, nullptr, "IsValidFriendCode"},
+ {0x00270040, nullptr, "ResultToErrorCode"},
+ {0x00280244, nullptr, "RequestGameAuthentication"},
+ {0x00290000, nullptr, "GetGameAuthenticationData"},
+ {0x002A0204, nullptr, "RequestServiceLocator"},
+ {0x002B0000, nullptr, "GetServiceLocatorData"},
+ {0x002C0002, nullptr, "DetectNatProperties"},
+ {0x002D0000, nullptr, "GetNatProperties"},
+ {0x002E0000, nullptr, "GetServerTimeInterval"},
+ {0x002F0040, nullptr, "AllowHalfAwake"},
+ {0x00300000, nullptr, "GetServerTypes"},
+ {0x00310082, nullptr, "GetFriendComment"},
+ {0x00320042, nullptr, "SetClientSdkVersion"},
+ {0x00330000, nullptr, "GetMyApproachContext"},
+ {0x00340046, nullptr, "AddFriendWithApproach"},
+ {0x00350082, nullptr, "DecryptApproachContext"},
};
FRD_U_Interface::FRD_U_Interface() {
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 35b648409..833a68f05 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -70,9 +70,8 @@ ResultVal<bool> Interface::SyncRequest() {
// TODO(bunnei): Hack - ignore error
cmd_buff[1] = 0;
return MakeResult<bool>(false);
- } else {
- LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
}
+ LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
itr->second.func(this);