mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 22:00:05 +00:00 
			
		
		
		
	Merge pull request #3469 from wwylele/frd-new-framework
Service/FRD: convert to ServiceFramework
This commit is contained in:
		
						commit
						5dc8ac80dd
					
				
					 8 changed files with 313 additions and 305 deletions
				
			
		|  | @ -45,18 +45,6 @@ public: | ||||||
|             memset(cmdbuf + index, 0, size_in_words * sizeof(u32)); |             memset(cmdbuf + index, 0, size_in_words * sizeof(u32)); | ||||||
|         index += size_in_words; |         index += size_in_words; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     /**
 |  | ||||||
|      * @brief Retrieves the address of a static buffer, used when a buffer is needed for output |  | ||||||
|      * @param buffer_id The index of the static buffer |  | ||||||
|      * @param data_size If non-null, will store the size of the buffer |  | ||||||
|      */ |  | ||||||
|     VAddr PeekStaticBuffer(u8 buffer_id, size_t* data_size = nullptr) const { |  | ||||||
|         u32* static_buffer = cmdbuf + Kernel::kStaticBuffersOffset / sizeof(u32) + buffer_id * 2; |  | ||||||
|         if (data_size) |  | ||||||
|             *data_size = StaticBufferDescInfo{static_buffer[0]}.size; |  | ||||||
|         return static_buffer[1]; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class RequestBuilder : public RequestHelperBase { | class RequestBuilder : public RequestHelperBase { | ||||||
|  | @ -122,7 +110,6 @@ public: | ||||||
|     template <typename... O> |     template <typename... O> | ||||||
|     void PushMoveObjects(Kernel::SharedPtr<O>... pointers); |     void PushMoveObjects(Kernel::SharedPtr<O>... pointers); | ||||||
| 
 | 
 | ||||||
|     [[deprecated]] void PushStaticBuffer(VAddr buffer_vaddr, size_t size, u8 buffer_id); |  | ||||||
|     void PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id); |     void PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id); | ||||||
| 
 | 
 | ||||||
|     /// Pushes an HLE MappedBuffer interface back to unmapped the buffer.
 |     /// Pushes an HLE MappedBuffer interface back to unmapped the buffer.
 | ||||||
|  | @ -204,11 +191,6 @@ inline void RequestBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) { | ||||||
|     PushMoveHLEHandles(context->AddOutgoingHandle(std::move(pointers))...); |     PushMoveHLEHandles(context->AddOutgoingHandle(std::move(pointers))...); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void RequestBuilder::PushStaticBuffer(VAddr buffer_vaddr, size_t size, u8 buffer_id) { |  | ||||||
|     Push(StaticBufferDesc(size, buffer_id)); |  | ||||||
|     Push(buffer_vaddr); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| inline void RequestBuilder::PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id) { | inline void RequestBuilder::PushStaticBuffer(const std::vector<u8>& buffer, u8 buffer_id) { | ||||||
|     ASSERT_MSG(buffer_id < MAX_STATIC_BUFFERS, "Invalid static buffer id"); |     ASSERT_MSG(buffer_id < MAX_STATIC_BUFFERS, "Invalid static buffer id"); | ||||||
| 
 | 
 | ||||||
|  | @ -309,18 +291,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     u32 PopPID(); |     u32 PopPID(); | ||||||
| 
 | 
 | ||||||
|     /**
 |  | ||||||
|      * @brief Pops the static buffer vaddr |  | ||||||
|      * @return                  The virtual address of the buffer |  | ||||||
|      * @param[out] data_size    If non-null, the pointed value will be set to the size of the data |  | ||||||
|      * |  | ||||||
|      * In real services, static buffers must be set up before any IPC request using those is sent. |  | ||||||
|      * It is the duty of the process (usually services) to allocate and set up the receiving static |  | ||||||
|      * buffer information. Our HLE services do not need to set up the buffers beforehand. |  | ||||||
|      * Please note that the setup uses virtual addresses. |  | ||||||
|      */ |  | ||||||
|     [[deprecated]] VAddr PopStaticBuffer(size_t* data_size); |  | ||||||
| 
 |  | ||||||
|     /**
 |     /**
 | ||||||
|      * @brief Pops a static buffer from the IPC request buffer. |      * @brief Pops a static buffer from the IPC request buffer. | ||||||
|      * @return The buffer that was copied from the IPC request originator. |      * @return The buffer that was copied from the IPC request originator. | ||||||
|  | @ -467,14 +437,6 @@ inline u32 RequestParser::PopPID() { | ||||||
|     return Pop<u32>(); |     return Pop<u32>(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline VAddr RequestParser::PopStaticBuffer(size_t* data_size) { |  | ||||||
|     const u32 sbuffer_descriptor = Pop<u32>(); |  | ||||||
|     StaticBufferDescInfo bufferInfo{sbuffer_descriptor}; |  | ||||||
|     if (data_size != nullptr) |  | ||||||
|         *data_size = bufferInfo.size; |  | ||||||
|     return Pop<VAddr>(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| inline const std::vector<u8>& RequestParser::PopStaticBuffer() { | inline const std::vector<u8>& RequestParser::PopStaticBuffer() { | ||||||
|     const u32 sbuffer_descriptor = Pop<u32>(); |     const u32 sbuffer_descriptor = Pop<u32>(); | ||||||
|     // Pop the address from the incoming request buffer
 |     // Pop the address from the incoming request buffer
 | ||||||
|  |  | ||||||
|  | @ -2,127 +2,120 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
|  | #include <array> | ||||||
|  | #include <vector> | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| #include "core/hle/ipc.h" |  | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/frd/frd.h" | #include "core/hle/service/frd/frd.h" | ||||||
| #include "core/hle/service/frd/frd_a.h" | #include "core/hle/service/frd/frd_a.h" | ||||||
| #include "core/hle/service/frd/frd_u.h" | #include "core/hle/service/frd/frd_u.h" | ||||||
| #include "core/hle/service/service.h" |  | ||||||
| #include "core/memory.h" |  | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace FRD { | namespace FRD { | ||||||
| 
 | 
 | ||||||
| static FriendKey my_friend_key = {0, 0, 0ull}; | Module::Interface::Interface(std::shared_ptr<Module> frd, const char* name, u32 max_session) | ||||||
| static MyPresence my_presence = {}; |     : ServiceFramework(name, max_session), frd(std::move(frd)) {} | ||||||
| 
 | 
 | ||||||
| void GetMyPresence(Service::Interface* self) { | Module::Interface::~Interface() = default; | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |  | ||||||
| 
 | 
 | ||||||
|     u32 shifted_out_size = cmd_buff[64]; | void Module::Interface::GetMyPresence(Kernel::HLERequestContext& ctx) { | ||||||
|     u32 my_presence_addr = cmd_buff[65]; |     IPC::RequestParser rp(ctx, 0x08, 0, 0); | ||||||
| 
 | 
 | ||||||
|     ASSERT(shifted_out_size == ((sizeof(MyPresence) << 14) | 2)); |     std::vector<u8> buffer(sizeof(MyPresence)); | ||||||
|  |     std::memcpy(buffer.data(), &frd->my_presence, buffer.size()); | ||||||
| 
 | 
 | ||||||
|     Memory::WriteBlock(my_presence_addr, &my_presence, sizeof(MyPresence)); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
| 
 |     rb.Push(RESULT_SUCCESS); | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |     rb.PushStaticBuffer(buffer, 0); | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_FRD, "(STUBBED) called"); |     LOG_WARNING(Service_FRD, "(STUBBED) called"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetFriendKeyList(Service::Interface* self) { | void Module::Interface::GetFriendKeyList(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x11, 2, 0); | ||||||
|  |     u32 unknown = rp.Pop<u32>(); | ||||||
|  |     u32 frd_count = rp.Pop<u32>(); | ||||||
| 
 | 
 | ||||||
|     u32 unknown = cmd_buff[1]; |     std::vector<u8> buffer(sizeof(FriendKey) * frd_count, 0); | ||||||
|     u32 frd_count = cmd_buff[2]; |  | ||||||
|     u32 frd_key_addr = cmd_buff[65]; |  | ||||||
| 
 | 
 | ||||||
|     FriendKey zero_key = {}; |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     for (u32 i = 0; i < frd_count; ++i) { |     rb.Push(RESULT_SUCCESS); | ||||||
|         Memory::WriteBlock(frd_key_addr + i * sizeof(FriendKey), &zero_key, sizeof(FriendKey)); |     rb.Push<u32>(0); // 0 friends
 | ||||||
|     } |     rb.PushStaticBuffer(buffer, 0); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |     LOG_WARNING(Service_FRD, "(STUBBED) called, unknown=%u, frd_count=%u", unknown, frd_count); | ||||||
|     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) { | void Module::Interface::GetFriendProfile(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x15, 1, 2); | ||||||
|  |     u32 count = rp.Pop<u32>(); | ||||||
|  |     std::vector<u8> frd_keys = rp.PopStaticBuffer(); | ||||||
|  |     ASSERT(frd_keys.size() == count * sizeof(FriendKey)); | ||||||
| 
 | 
 | ||||||
|     u32 count = cmd_buff[1]; |     std::vector<u8> buffer(sizeof(Profile) * count, 0); | ||||||
|     u32 frd_key_addr = cmd_buff[3]; |  | ||||||
|     u32 profiles_addr = cmd_buff[65]; |  | ||||||
| 
 | 
 | ||||||
|     Profile zero_profile = {}; |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|     for (u32 i = 0; i < count; ++i) { |     rb.Push(RESULT_SUCCESS); | ||||||
|         Memory::WriteBlock(profiles_addr + i * sizeof(Profile), &zero_profile, sizeof(Profile)); |     rb.PushStaticBuffer(buffer, 0); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |     LOG_WARNING(Service_FRD, "(STUBBED) called, count=%u", count); | ||||||
|     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) { | void Module::Interface::GetFriendAttributeFlags(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x17, 1, 2); | ||||||
|  |     u32 count = rp.Pop<u32>(); | ||||||
|  |     std::vector<u8> frd_keys = rp.PopStaticBuffer(); | ||||||
|  |     ASSERT(frd_keys.size() == count * sizeof(FriendKey)); | ||||||
| 
 | 
 | ||||||
|     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
 |     // TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte
 | ||||||
|         Memory::Write8(attr_flags_addr + i, 0); |     std::vector<u8> buffer(1 * count, 0); | ||||||
|     } |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.PushStaticBuffer(buffer, 0); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |     LOG_WARNING(Service_FRD, "(STUBBED) called, count=%u", count); | ||||||
|     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) { | void Module::Interface::GetMyFriendKey(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x5, 0, 0); | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.PushRaw(frd->my_friend_key); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |  | ||||||
|     std::memcpy(&cmd_buff[2], &my_friend_key, sizeof(FriendKey)); |  | ||||||
|     LOG_WARNING(Service_FRD, "(STUBBED) called"); |     LOG_WARNING(Service_FRD, "(STUBBED) called"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetMyScreenName(Service::Interface* self) { | void Module::Interface::GetMyScreenName(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x9, 0, 0); | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(7, 0); | ||||||
|  | 
 | ||||||
|  |     struct ScreenName { | ||||||
|  |         std::array<char16_t, 12> name; | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |  | ||||||
|     // TODO: (mailwl) get the name from config
 |     // TODO: (mailwl) get the name from config
 | ||||||
|     Common::UTF8ToUTF16("Citra").copy(reinterpret_cast<char16_t*>(&cmd_buff[2]), 11); |     ScreenName screen_name{u"Citra"}; | ||||||
|  | 
 | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.PushRaw(screen_name); | ||||||
|  | 
 | ||||||
|     LOG_WARNING(Service_FRD, "(STUBBED) called"); |     LOG_WARNING(Service_FRD, "(STUBBED) called"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UnscrambleLocalFriendCode(Service::Interface* self) { | void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx) { | ||||||
|     const size_t scrambled_friend_code_size = 12; |     const size_t scrambled_friend_code_size = 12; | ||||||
|     const size_t friend_code_size = 8; |     const size_t friend_code_size = 8; | ||||||
| 
 | 
 | ||||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1C, 1, 2); |     IPC::RequestParser rp(ctx, 0x1C, 1, 2); | ||||||
|     const u32 friend_code_count = rp.Pop<u32>(); |     const u32 friend_code_count = rp.Pop<u32>(); | ||||||
|     size_t in_buffer_size; |     std::vector<u8> scrambled_friend_codes = rp.PopStaticBuffer(); | ||||||
|     const VAddr scrambled_friend_codes = rp.PopStaticBuffer(&in_buffer_size); |     ASSERT_MSG(scrambled_friend_codes.size() == (friend_code_count * scrambled_friend_code_size), | ||||||
|     ASSERT_MSG(in_buffer_size == (friend_code_count * scrambled_friend_code_size), |  | ||||||
|                "Wrong input buffer size"); |                "Wrong input buffer size"); | ||||||
| 
 | 
 | ||||||
|     size_t out_buffer_size; |     std::vector<u8> unscrambled_friend_codes(friend_code_count * friend_code_size, 0); | ||||||
|     VAddr unscrambled_friend_codes = rp.PeekStaticBuffer(0, &out_buffer_size); |  | ||||||
|     ASSERT_MSG(out_buffer_size == (friend_code_count * friend_code_size), |  | ||||||
|                "Wrong output buffer size"); |  | ||||||
| 
 |  | ||||||
|     for (u32 current = 0; current < friend_code_count; ++current) { |  | ||||||
|     // TODO(B3N30): Unscramble the codes and compare them against the friend list
 |     // TODO(B3N30): Unscramble the codes and compare them against the friend list
 | ||||||
|     //              Only write 0 if the code isn't in friend list, otherwise write the
 |     //              Only write 0 if the code isn't in friend list, otherwise write the
 | ||||||
|     //              unscrambled one
 |     //              unscrambled one
 | ||||||
|  | @ -137,38 +130,32 @@ void UnscrambleLocalFriendCode(Service::Interface* self) { | ||||||
|     // scambled_friend_code[5]; unscrambled_friend_code[3] = scambled_friend_code[3] ^
 |     // scambled_friend_code[5]; unscrambled_friend_code[3] = scambled_friend_code[3] ^
 | ||||||
|     // scambled_friend_code[5];
 |     // scambled_friend_code[5];
 | ||||||
| 
 | 
 | ||||||
|         u64 result = 0ull; |  | ||||||
|         Memory::WriteBlock(unscrambled_friend_codes + (current * sizeof(result)), &result, |  | ||||||
|                            sizeof(result)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     LOG_WARNING(Service_FRD, "(STUBBED) called"); |     LOG_WARNING(Service_FRD, "(STUBBED) called"); | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.PushStaticBuffer(unscrambled_friend_codes, out_buffer_size, 0); |     rb.PushStaticBuffer(unscrambled_friend_codes, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetClientSdkVersion(Service::Interface* self) { | void Module::Interface::SetClientSdkVersion(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x32, 1, 2); | ||||||
|  |     u32 version = rp.Pop<u32>(); | ||||||
|  |     rp.PopPID(); | ||||||
| 
 | 
 | ||||||
|     const u32 version = cmd_buff[1]; |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
| 
 |     rb.Push(RESULT_SUCCESS); | ||||||
|     self->SetVersion(version); |  | ||||||
| 
 | 
 | ||||||
|     LOG_WARNING(Service_FRD, "(STUBBED) called, version: 0x%08X", version); |     LOG_WARNING(Service_FRD, "(STUBBED) called, version: 0x%08X", version); | ||||||
| 
 |  | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Init() { | Module::Module() = default; | ||||||
|     using namespace Kernel; | Module::~Module() = default; | ||||||
| 
 | 
 | ||||||
|     AddService(new FRD_A_Interface); | void InstallInterfaces(SM::ServiceManager& service_manager) { | ||||||
|     AddService(new FRD_U_Interface); |     auto frd = std::make_shared<Module>(); | ||||||
|  |     std::make_shared<FRD_U>(frd)->InstallAsService(service_manager); | ||||||
|  |     std::make_shared<FRD_A>(frd)->InstallAsService(service_manager); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Shutdown() {} |  | ||||||
| 
 |  | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
| 
 | 
 | ||||||
| } // namespace Service
 | } // namespace Service
 | ||||||
|  |  | ||||||
|  | @ -4,7 +4,9 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <memory> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +32,18 @@ struct Profile { | ||||||
|     u32 unknown; |     u32 unknown; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | class Module final { | ||||||
|  | public: | ||||||
|  |     Module(); | ||||||
|  |     ~Module(); | ||||||
|  | 
 | ||||||
|  |     class Interface : public ServiceFramework<Interface> { | ||||||
|  |     public: | ||||||
|  |         Interface(std::shared_ptr<Module> frd, const char* name, u32 max_session); | ||||||
|  |         ~Interface(); | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  |         /**
 | ||||||
|          * FRD::GetMyPresence service function |          * FRD::GetMyPresence service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      64 : sizeof (MyPresence) << 14 | 2 |          *      64 : sizeof (MyPresence) << 14 | 2 | ||||||
|  | @ -38,9 +51,9 @@ struct Profile { | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void GetMyPresence(Service::Interface* self); |         void GetMyPresence(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::GetFriendKeyList service function |          * FRD::GetFriendKeyList service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Unknown |          *      1 : Unknown | ||||||
|  | @ -50,9 +63,9 @@ void GetMyPresence(Service::Interface* self); | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : FriendKey count filled |          *      2 : FriendKey count filled | ||||||
|          */ |          */ | ||||||
| void GetFriendKeyList(Service::Interface* self); |         void GetFriendKeyList(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::GetFriendProfile service function |          * FRD::GetFriendProfile service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Friends count |          *      1 : Friends count | ||||||
|  | @ -63,9 +76,9 @@ void GetFriendKeyList(Service::Interface* self); | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void GetFriendProfile(Service::Interface* self); |         void GetFriendProfile(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::GetFriendAttributeFlags service function |          * FRD::GetFriendAttributeFlags service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Friends count |          *      1 : Friends count | ||||||
|  | @ -75,9 +88,9 @@ void GetFriendProfile(Service::Interface* self); | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void GetFriendAttributeFlags(Service::Interface* self); |         void GetFriendAttributeFlags(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::GetMyFriendKey service function |          * FRD::GetMyFriendKey service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      none |          *      none | ||||||
|  | @ -85,17 +98,17 @@ void GetFriendAttributeFlags(Service::Interface* self); | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2-5 : FriendKey |          *      2-5 : FriendKey | ||||||
|          */ |          */ | ||||||
| void GetMyFriendKey(Service::Interface* self); |         void GetMyFriendKey(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::GetMyScreenName service function |          * FRD::GetMyScreenName service function | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : UTF16 encoded name (max 11 symbols) |          *      2 : UTF16 encoded name (max 11 symbols) | ||||||
|          */ |          */ | ||||||
| void GetMyScreenName(Service::Interface* self); |         void GetMyScreenName(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::UnscrambleLocalFriendCode service function |          * FRD::UnscrambleLocalFriendCode service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Friend code count |          *      1 : Friend code count | ||||||
|  | @ -106,22 +119,27 @@ void GetMyScreenName(Service::Interface* self); | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void UnscrambleLocalFriendCode(Service::Interface* self); |         void UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * FRD::SetClientSdkVersion service function |          * FRD::SetClientSdkVersion service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Used SDK Version |          *      1 : Used SDK Version | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void SetClientSdkVersion(Service::Interface* self); |         void SetClientSdkVersion(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /// Initialize FRD service(s)
 |     private: | ||||||
| void Init(); |         std::shared_ptr<Module> frd; | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
| /// Shutdown FRD service(s)
 | private: | ||||||
| void Shutdown(); |     FriendKey my_friend_key = {0, 0, 0ull}; | ||||||
|  |     MyPresence my_presence = {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void InstallInterfaces(SM::ServiceManager& service_manager); | ||||||
| 
 | 
 | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
| } // namespace Service
 | } // namespace Service
 | ||||||
|  |  | ||||||
|  | @ -7,11 +7,63 @@ | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace FRD { | namespace FRD { | ||||||
| 
 | 
 | ||||||
| // Empty arrays are illegal -- commented out until an entry is added.
 | FRD_A::FRD_A(std::shared_ptr<Module> frd) : Module::Interface(std::move(frd), "frd:a", 8) { | ||||||
| // const Interface::FunctionInfo FunctionTable[] = { };
 |     static const FunctionInfo functions[] = { | ||||||
| 
 |         {0x00010000, nullptr, "HasLoggedIn"}, | ||||||
| FRD_A_Interface::FRD_A_Interface() { |         {0x00020000, nullptr, "IsOnline"}, | ||||||
|     // Register(FunctionTable);
 |         {0x00030000, nullptr, "Login"}, | ||||||
|  |         {0x00040000, nullptr, "Logout"}, | ||||||
|  |         {0x00050000, &FRD_A::GetMyFriendKey, "GetMyFriendKey"}, | ||||||
|  |         {0x00060000, nullptr, "GetMyPreference"}, | ||||||
|  |         {0x00070000, nullptr, "GetMyProfile"}, | ||||||
|  |         {0x00080000, &FRD_A::GetMyPresence, "GetMyPresence"}, | ||||||
|  |         {0x00090000, &FRD_A::GetMyScreenName, "GetMyScreenName"}, | ||||||
|  |         {0x000A0000, nullptr, "GetMyMii"}, | ||||||
|  |         {0x000B0000, nullptr, "GetMyLocalAccountId"}, | ||||||
|  |         {0x000C0000, nullptr, "GetMyPlayingGame"}, | ||||||
|  |         {0x000D0000, nullptr, "GetMyFavoriteGame"}, | ||||||
|  |         {0x000E0000, nullptr, "GetMyNcPrincipalId"}, | ||||||
|  |         {0x000F0000, nullptr, "GetMyComment"}, | ||||||
|  |         {0x00100040, nullptr, "GetMyPassword"}, | ||||||
|  |         {0x00110080, &FRD_A::GetFriendKeyList, "GetFriendKeyList"}, | ||||||
|  |         {0x00120042, nullptr, "GetFriendPresence"}, | ||||||
|  |         {0x00130142, nullptr, "GetFriendScreenName"}, | ||||||
|  |         {0x00140044, nullptr, "GetFriendMii"}, | ||||||
|  |         {0x00150042, &FRD_A::GetFriendProfile, "GetFriendProfile"}, | ||||||
|  |         {0x00160042, nullptr, "GetFriendRelationship"}, | ||||||
|  |         {0x00170042, &FRD_A::GetFriendAttributeFlags, "GetFriendAttributeFlags"}, | ||||||
|  |         {0x00180044, nullptr, "GetFriendPlayingGame"}, | ||||||
|  |         {0x00190042, nullptr, "GetFriendFavoriteGame"}, | ||||||
|  |         {0x001A00C4, nullptr, "GetFriendInfo"}, | ||||||
|  |         {0x001B0080, nullptr, "IsIncludedInFriendList"}, | ||||||
|  |         {0x001C0042, &FRD_A::UnscrambleLocalFriendCode, "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, &FRD_A::SetClientSdkVersion, "SetClientSdkVersion"}, | ||||||
|  |         {0x00330000, nullptr, "GetMyApproachContext"}, | ||||||
|  |         {0x00340046, nullptr, "AddFriendWithApproach"}, | ||||||
|  |         {0x00350082, nullptr, "DecryptApproachContext"}, | ||||||
|  |     }; | ||||||
|  |     RegisterHandlers(functions); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
|  |  | ||||||
|  | @ -4,18 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/frd/frd.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace FRD { | namespace FRD { | ||||||
| 
 | 
 | ||||||
| class FRD_A_Interface : public Service::Interface { | class FRD_A final : public Module::Interface { | ||||||
| public: | public: | ||||||
|     FRD_A_Interface(); |     explicit FRD_A(std::shared_ptr<Module> frd); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "frd:a"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
|  |  | ||||||
|  | @ -2,22 +2,22 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/frd/frd.h" |  | ||||||
| #include "core/hle/service/frd/frd_u.h" | #include "core/hle/service/frd/frd_u.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace FRD { | namespace FRD { | ||||||
| 
 | 
 | ||||||
| const Interface::FunctionInfo FunctionTable[] = { | FRD_U::FRD_U(std::shared_ptr<Module> frd) : Module::Interface(std::move(frd), "frd:u", 8) { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|         {0x00010000, nullptr, "HasLoggedIn"}, |         {0x00010000, nullptr, "HasLoggedIn"}, | ||||||
|         {0x00020000, nullptr, "IsOnline"}, |         {0x00020000, nullptr, "IsOnline"}, | ||||||
|         {0x00030000, nullptr, "Login"}, |         {0x00030000, nullptr, "Login"}, | ||||||
|         {0x00040000, nullptr, "Logout"}, |         {0x00040000, nullptr, "Logout"}, | ||||||
|     {0x00050000, GetMyFriendKey, "GetMyFriendKey"}, |         {0x00050000, &FRD_U::GetMyFriendKey, "GetMyFriendKey"}, | ||||||
|         {0x00060000, nullptr, "GetMyPreference"}, |         {0x00060000, nullptr, "GetMyPreference"}, | ||||||
|         {0x00070000, nullptr, "GetMyProfile"}, |         {0x00070000, nullptr, "GetMyProfile"}, | ||||||
|     {0x00080000, GetMyPresence, "GetMyPresence"}, |         {0x00080000, &FRD_U::GetMyPresence, "GetMyPresence"}, | ||||||
|     {0x00090000, GetMyScreenName, "GetMyScreenName"}, |         {0x00090000, &FRD_U::GetMyScreenName, "GetMyScreenName"}, | ||||||
|         {0x000A0000, nullptr, "GetMyMii"}, |         {0x000A0000, nullptr, "GetMyMii"}, | ||||||
|         {0x000B0000, nullptr, "GetMyLocalAccountId"}, |         {0x000B0000, nullptr, "GetMyLocalAccountId"}, | ||||||
|         {0x000C0000, nullptr, "GetMyPlayingGame"}, |         {0x000C0000, nullptr, "GetMyPlayingGame"}, | ||||||
|  | @ -25,18 +25,18 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
|         {0x000E0000, nullptr, "GetMyNcPrincipalId"}, |         {0x000E0000, nullptr, "GetMyNcPrincipalId"}, | ||||||
|         {0x000F0000, nullptr, "GetMyComment"}, |         {0x000F0000, nullptr, "GetMyComment"}, | ||||||
|         {0x00100040, nullptr, "GetMyPassword"}, |         {0x00100040, nullptr, "GetMyPassword"}, | ||||||
|     {0x00110080, GetFriendKeyList, "GetFriendKeyList"}, |         {0x00110080, &FRD_U::GetFriendKeyList, "GetFriendKeyList"}, | ||||||
|         {0x00120042, nullptr, "GetFriendPresence"}, |         {0x00120042, nullptr, "GetFriendPresence"}, | ||||||
|         {0x00130142, nullptr, "GetFriendScreenName"}, |         {0x00130142, nullptr, "GetFriendScreenName"}, | ||||||
|         {0x00140044, nullptr, "GetFriendMii"}, |         {0x00140044, nullptr, "GetFriendMii"}, | ||||||
|     {0x00150042, GetFriendProfile, "GetFriendProfile"}, |         {0x00150042, &FRD_U::GetFriendProfile, "GetFriendProfile"}, | ||||||
|         {0x00160042, nullptr, "GetFriendRelationship"}, |         {0x00160042, nullptr, "GetFriendRelationship"}, | ||||||
|     {0x00170042, GetFriendAttributeFlags, "GetFriendAttributeFlags"}, |         {0x00170042, &FRD_U::GetFriendAttributeFlags, "GetFriendAttributeFlags"}, | ||||||
|         {0x00180044, nullptr, "GetFriendPlayingGame"}, |         {0x00180044, nullptr, "GetFriendPlayingGame"}, | ||||||
|         {0x00190042, nullptr, "GetFriendFavoriteGame"}, |         {0x00190042, nullptr, "GetFriendFavoriteGame"}, | ||||||
|         {0x001A00C4, nullptr, "GetFriendInfo"}, |         {0x001A00C4, nullptr, "GetFriendInfo"}, | ||||||
|         {0x001B0080, nullptr, "IsIncludedInFriendList"}, |         {0x001B0080, nullptr, "IsIncludedInFriendList"}, | ||||||
|     {0x001C0042, UnscrambleLocalFriendCode, "UnscrambleLocalFriendCode"}, |         {0x001C0042, &FRD_U::UnscrambleLocalFriendCode, "UnscrambleLocalFriendCode"}, | ||||||
|         {0x001D0002, nullptr, "UpdateGameModeDescription"}, |         {0x001D0002, nullptr, "UpdateGameModeDescription"}, | ||||||
|         {0x001E02C2, nullptr, "UpdateGameMode"}, |         {0x001E02C2, nullptr, "UpdateGameMode"}, | ||||||
|         {0x001F0042, nullptr, "SendInvitation"}, |         {0x001F0042, nullptr, "SendInvitation"}, | ||||||
|  | @ -58,14 +58,12 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
|         {0x002F0040, nullptr, "AllowHalfAwake"}, |         {0x002F0040, nullptr, "AllowHalfAwake"}, | ||||||
|         {0x00300000, nullptr, "GetServerTypes"}, |         {0x00300000, nullptr, "GetServerTypes"}, | ||||||
|         {0x00310082, nullptr, "GetFriendComment"}, |         {0x00310082, nullptr, "GetFriendComment"}, | ||||||
|     {0x00320042, SetClientSdkVersion, "SetClientSdkVersion"}, |         {0x00320042, &FRD_U::SetClientSdkVersion, "SetClientSdkVersion"}, | ||||||
|         {0x00330000, nullptr, "GetMyApproachContext"}, |         {0x00330000, nullptr, "GetMyApproachContext"}, | ||||||
|         {0x00340046, nullptr, "AddFriendWithApproach"}, |         {0x00340046, nullptr, "AddFriendWithApproach"}, | ||||||
|         {0x00350082, nullptr, "DecryptApproachContext"}, |         {0x00350082, nullptr, "DecryptApproachContext"}, | ||||||
| }; |     }; | ||||||
| 
 |     RegisterHandlers(functions); | ||||||
| FRD_U_Interface::FRD_U_Interface() { |  | ||||||
|     Register(FunctionTable); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
|  |  | ||||||
|  | @ -4,18 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/frd/frd.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace FRD { | namespace FRD { | ||||||
| 
 | 
 | ||||||
| class FRD_U_Interface : public Service::Interface { | class FRD_U final : public Module::Interface { | ||||||
| public: | public: | ||||||
|     FRD_U_Interface(); |     explicit FRD_U(std::shared_ptr<Module> frd); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "frd:u"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace FRD
 | } // namespace FRD
 | ||||||
|  |  | ||||||
|  | @ -244,7 +244,7 @@ void Init() { | ||||||
|     CECD::Init(); |     CECD::Init(); | ||||||
|     CFG::Init(); |     CFG::Init(); | ||||||
|     DLP::Init(); |     DLP::Init(); | ||||||
|     FRD::Init(); |     FRD::InstallInterfaces(*SM::g_service_manager); | ||||||
|     GSP::InstallInterfaces(*SM::g_service_manager); |     GSP::InstallInterfaces(*SM::g_service_manager); | ||||||
|     HID::InstallInterfaces(*SM::g_service_manager); |     HID::InstallInterfaces(*SM::g_service_manager); | ||||||
|     IR::InstallInterfaces(*SM::g_service_manager); |     IR::InstallInterfaces(*SM::g_service_manager); | ||||||
|  | @ -274,7 +274,6 @@ void Shutdown() { | ||||||
|     NFC::Shutdown(); |     NFC::Shutdown(); | ||||||
|     NEWS::Shutdown(); |     NEWS::Shutdown(); | ||||||
|     NDM::Shutdown(); |     NDM::Shutdown(); | ||||||
|     FRD::Shutdown(); |  | ||||||
|     DLP::Shutdown(); |     DLP::Shutdown(); | ||||||
|     CFG::Shutdown(); |     CFG::Shutdown(); | ||||||
|     CECD::Shutdown(); |     CECD::Shutdown(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue