From 86773a7f081a8a6c71643ecdc6573b65dbf0ccd3 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 28 Apr 2019 18:57:37 -0400 Subject: [PATCH] bcat: Implement cmd RequestSyncDeliveryCache and variant Variant also supports only updating a single directory. These just both invoke backend commands. --- src/core/hle/service/bcat/module.cpp | 72 +++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 1459fab11..605aa6e00 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp @@ -145,8 +145,8 @@ public: IBcatService(Backend& backend) : ServiceFramework("IBcatService"), backend(backend) { // clang-format off static const FunctionInfo functions[] = { - {10100, nullptr, "RequestSyncDeliveryCache"}, - {10101, nullptr, "RequestSyncDeliveryCacheWithDirectoryName"}, + {10100, &IBcatService::RequestSyncDeliveryCache, "RequestSyncDeliveryCache"}, + {10101, &IBcatService::RequestSyncDeliveryCacheWithDirectoryName, "RequestSyncDeliveryCacheWithDirectoryName"}, {10200, nullptr, "CancelSyncDeliveryCacheRequest"}, {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"}, {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, @@ -162,7 +162,74 @@ public: }; // clang-format on RegisterHandlers(functions); + + auto& kernel{Core::System::GetInstance().Kernel()}; + progress.at(static_cast(SyncType::Normal)).event = + Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, + "BCAT::IDeliveryCacheProgressEvent"); + progress.at(static_cast(SyncType::Directory)).event = + Kernel::WritableEvent::CreateEventPair( + kernel, Kernel::ResetType::OneShot, + "BCAT::IDeliveryCacheProgressEvent::DirectoryName"); } + +private: + enum class SyncType { + Normal, + Directory, + Count, + }; + + std::function CreateCallback(SyncType type) { + return [this, type](bool success) { + auto& pair{progress.at(static_cast(type))}; + pair.impl.status = DeliveryCacheProgressImpl::Status::Complete; + pair.event.writable->Signal(); + }; + } + + std::shared_ptr CreateProgressService(SyncType type) { + const auto& pair{progress.at(static_cast(type))}; + return std::make_shared(pair.event.readable, pair.impl); + } + + void RequestSyncDeliveryCache(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_BCAT, "called"); + + backend.Synchronize({Core::CurrentProcess()->GetTitleID(), GetCurrentBuildID()}, + CreateCallback(SyncType::Normal)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(CreateProgressService(SyncType::Normal)); + } + + void RequestSyncDeliveryCacheWithDirectoryName(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto name_raw = rp.PopRaw(); + const auto name = + Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); + + LOG_DEBUG(Service_BCAT, "called, name={}", name); + + backend.SynchronizeDirectory({Core::CurrentProcess()->GetTitleID(), GetCurrentBuildID()}, + name, CreateCallback(SyncType::Directory)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(CreateProgressService(SyncType::Directory)); + } + + } + + Backend& backend; + + struct ProgressPair { + Kernel::EventPair event; + DeliveryCacheProgressImpl impl; + }; + + std::array(SyncType::Count)> progress{}; }; void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) { @@ -171,6 +238,7 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(*backend); +} class IDeliveryCacheFileService final : public ServiceFramework { public: