diff options
| author | Maufeat <sahyno1996@gmail.com> | 2026-08-19 19:56:06 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-08-19 19:56:06 +0200 |
| commit | 5c54abf353e64faf2b4d6ce433f062021801a548 (patch) | |
| tree | 10c46389806db1ab6e8dd106c8f2d091030fde9f /src | |
| parent | 0465292a81ed71b1f806b7107ca64edcef083e31 (diff) | |
[nim] unstub IShopServiceAsync (#4272)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
unstub IShopServiceAsync (but still stub Request, with empty JSON response)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4272
Reviewed-by: Samuel <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nim/nim.cpp | 131 |
1 files changed, 118 insertions, 13 deletions
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 661da88b0c..e5f2d85dde 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -5,33 +5,136 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <chrono> -#include <ctime> +#include <mutex> +#include <string> +#include <vector> + #include "core/core.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/nim/nim.h" +#include "core/hle/service/os/event.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" namespace Service::NIM { - class IShopServiceAsync final : public ServiceFramework<IShopServiceAsync> { public: explicit IShopServiceAsync(Core::System& system_) - : ServiceFramework{system_, "IShopServiceAsync"} { + : ServiceFramework{system_, "IShopServiceAsync"}, + service_context{system_, "IShopServiceAsync"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "Cancel"}, - {1, nullptr, "GetSize"}, - {2, nullptr, "Read"}, - {3, nullptr, "GetErrorCode"}, - {4, nullptr, "Request"}, - {5, nullptr, "Prepare"}, + {0, D<&IShopServiceAsync::Cancel>, "Cancel"}, + {1, D<&IShopServiceAsync::GetSize>, "GetSize"}, + {2, D<&IShopServiceAsync::Read>, "Read"}, + {3, D<&IShopServiceAsync::GetErrorCode>, "GetErrorCode"}, + {4, D<&IShopServiceAsync::Request>, "Request"}, + {5, D<&IShopServiceAsync::Prepare>, "Prepare"}, }; // clang-format on RegisterHandlers(functions); + + completion_event = service_context.CreateEvent("IShopServiceAsync:Completion"); + } + + ~IShopServiceAsync() override { + CancelImpl(); + service_context.CloseEvent(completion_event); + } + + Kernel::KReadableEvent* GetEvent() const { + return &completion_event->GetReadableEvent(); + } + +private: + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* completion_event; + + std::jthread worker; + std::atomic<u32> error_code{0}; + + std::mutex data_mutex; + std::vector<u8> download_data; + + void CancelImpl() { + worker.request_stop(); + if (worker.joinable()) { + worker.join(); + } + } + + Result Cancel() { + LOG_DEBUG(Service_NIM, "called"); + CancelImpl(); + R_SUCCEED(); + } + + Result GetSize(Out<u64> out_size) { + LOG_DEBUG(Service_NIM, "called"); + std::scoped_lock lock{data_mutex}; + *out_size = download_data.size(); + R_SUCCEED(); + } + + Result Read(Out<u64> out_size, u64 offset, OutBuffer<BufferAttr_HipcAutoSelect> out_buffer) { + std::scoped_lock lock{data_mutex}; + + u64 actual_read = 0; + if (offset < download_data.size()) { + actual_read = std::min<u64>(out_buffer.size(), download_data.size() - offset); + std::memcpy(out_buffer.data(), download_data.data() + offset, actual_read); + } + + *out_size = actual_read; + R_SUCCEED(); + } + + Result GetErrorCode(Out<u32> out_error_code) { + LOG_DEBUG(Service_NIM, "called"); + *out_error_code = error_code.load(); + R_SUCCEED(); + } + + Result Request() { + LOG_DEBUG(Service_NIM, "(STUBBED) called"); + CancelImpl(); + + error_code.store(0); + completion_event->Clear(system.Kernel()); + + { + std::scoped_lock lock{data_mutex}; + download_data.clear(); + } + + worker = std::jthread([this](const std::stop_token& stop_token) { + if (stop_token.stop_requested()) { + error_code.store(1); + } else { + std::scoped_lock lock{data_mutex}; + // Dummy JSON response, else it fails... + const std::string dummy_response = "{}"; + download_data.assign(dummy_response.begin(), dummy_response.end()); + error_code.store(0); + } + completion_event->Signal(system.Kernel()); + }); + + R_SUCCEED(); + } + + Result Prepare(InArray<char, BufferAttr_HipcMapAlias> in_path, InArray<char, BufferAttr_HipcMapAlias> in_post) { + LOG_DEBUG(Service_NIM, "called"); + if (!in_path.empty()) { + std::string url(in_path.data(), in_path.size()); + LOG_INFO(Service_NIM, "Preparing request for URL: {}", url); + } + R_SUCCEED(); } }; @@ -49,11 +152,13 @@ public: } private: - void CreateAsyncInterface(HLERequestContext& ctx) { - LOG_WARNING(Service_NIM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + void CreateAsyncInterface(HLERequestContext& ctx) {LOG_DEBUG(Service_NIM, "called"); + auto async_interface = std::make_shared<IShopServiceAsync>(system); + + IPC::ResponseBuilder rb{ctx, 2, 1, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<IShopServiceAsync>(ctx, system); + rb.PushCopyObjects(ctx, async_interface->GetEvent()); + rb.PushIpcInterface<IShopServiceAsync>(ctx, std::move(async_interface)); } }; |
