From d97de43996aeee03b4b4cfef404d6153d95cc535 Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 5 Aug 2023 14:07:06 -0600 Subject: [PATCH] service: bcat: Implement news service for Qlaunch --- src/core/hle/service/bcat/bcat_module.cpp | 193 +++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp index a6281913a..f1c116b40 100644 --- a/src/core/hle/service/bcat/bcat_module.cpp +++ b/src/core/hle/service/bcat/bcat_module.cpp @@ -147,7 +147,7 @@ public: {30202, nullptr, "BlockDeliveryTask"}, {30203, nullptr, "UnblockDeliveryTask"}, {30210, nullptr, "SetDeliveryTaskTimer"}, - {30300, nullptr, "RegisterSystemApplicationDeliveryTasks"}, + {30300, &IBcatService::RegisterSystemApplicationDeliveryTasks, "RegisterSystemApplicationDeliveryTasks"}, {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, {90101, nullptr, "Unknown90101"}, {90200, nullptr, "GetDeliveryList"}, @@ -234,6 +234,13 @@ private: rb.Push(ResultSuccess); } + void RegisterSystemApplicationDeliveryTasks(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + void ClearDeliveryCacheStorage(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto title_id = rp.PopRaw(); @@ -584,6 +591,187 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr modu Module::Interface::~Interface() = default; +class INewsService final : public ServiceFramework { +public: + explicit INewsService(Core::System& system_) : ServiceFramework{system_, "INewsService"} { + // clang-format off + static const FunctionInfo functions[] = { + {10100, nullptr, "PostLocalNews"}, + {20100, nullptr, "SetPassphrase"}, + {30100, &INewsService::GetSubscriptionStatus, "GetSubscriptionStatus"}, + {30101, nullptr, "GetTopicList"}, + {30110, nullptr, "Unknown30110"}, + {30200, nullptr, "IsSystemUpdateRequired"}, + {30201, nullptr, "Unknown30201"}, + {30210, nullptr, "Unknown30210"}, + {30300, nullptr, "RequestImmediateReception"}, + {30400, nullptr, "DecodeArchiveFile"}, + {30500, nullptr, "Unknown30500"}, + {30900, nullptr, "Unknown30900"}, + {30901, nullptr, "Unknown30901"}, + {30902, nullptr, "Unknown30902"}, + {40100, nullptr, "SetSubscriptionStatus"}, + {40101, nullptr, "RequestAutoSubscription"}, + {40200, nullptr, "ClearStorage"}, + {40201, nullptr, "ClearSubscriptionStatusAll"}, + {90100, nullptr, "GetNewsDatabaseDump"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetSubscriptionStatus(HLERequestContext& ctx) { + const auto buffer_data = ctx.ReadBuffer(); + + LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size()); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } +}; + +class INewsDatabaseService final : public ServiceFramework { +public: + explicit INewsDatabaseService(Core::System& system_) + : ServiceFramework{system_, "INewsDatabaseService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetListV1"}, + {1, &INewsDatabaseService::Count, "Count"}, + {2, nullptr, "CountWithKey"}, + {3, nullptr, "UpdateIntegerValue"}, + {4, nullptr, "UpdateIntegerValueWithAddition"}, + {5, nullptr, "UpdateStringValue"}, + {1000, nullptr, "GetList"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Count(HLERequestContext& ctx) { + const auto buffer_data = ctx.ReadBuffer(); + + LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size()); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } +}; + +class INewlyArrivedEventHolder final : public ServiceFramework { +public: + explicit INewlyArrivedEventHolder(Core::System& system_) + : ServiceFramework{system_, "INewlyArrivedEventHolder"}, service_context{ + system_, + "INewlyArrivedEventHolder"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &INewlyArrivedEventHolder::Get, "Get"}, + }; + // clang-format on + + RegisterHandlers(functions); + arrived_event = service_context.CreateEvent("INewlyArrivedEventHolder::ArrivedEvent"); + } + +private: + void Get(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(arrived_event->GetReadableEvent()); + } + + Kernel::KEvent* arrived_event; + KernelHelpers::ServiceContext service_context; +}; + +class IOverwriteEventHolder final : public ServiceFramework { +public: + explicit IOverwriteEventHolder(Core::System& system_) + : ServiceFramework{system_, "IOverwriteEventHolder"}, service_context{ + system_, + "IOverwriteEventHolder"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IOverwriteEventHolder::Get, "Get"}, + }; + // clang-format on + + RegisterHandlers(functions); + overwrite_event = service_context.CreateEvent("IOverwriteEventHolder::OverwriteEvent"); + } + +private: + void Get(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(overwrite_event->GetReadableEvent()); + } + + Kernel::KEvent* overwrite_event; + KernelHelpers::ServiceContext service_context; +}; + +class News final : public ServiceFramework { +public: + explicit News(Core::System& system_) : ServiceFramework{system_, "news:p"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &News::CreateNewsService, "CreateNewsService"}, + {1, &News::CreateNewlyArrivedEventHolder, "CreateNewlyArrivedEventHolder"}, + {2, nullptr, "CreateNewsDataService"}, + {3, &News::CreateNewsDatabaseService, "CreateNewsDatabaseService"}, + {4, &News::CreateOverwriteEventHolder, "CreateOverwriteEventHolder"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void CreateNewsService(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + + void CreateNewlyArrivedEventHolder(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + + void CreateNewsDatabaseService(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + + void CreateOverwriteEventHolder(HLERequestContext& ctx) { + LOG_INFO(Service_BCAT, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } +}; + void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); auto module = std::make_shared(); @@ -600,6 +788,9 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService( "bcat:s", std::make_shared(system, module, system.GetFileSystemController(), "bcat:s")); + + server_manager->RegisterNamedService("news:p", std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); }