prepo.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/hex_util.h"
  5. #include "common/logging/log.h"
  6. #include "core/core.h"
  7. #include "core/hle/ipc_helpers.h"
  8. #include "core/hle/kernel/k_process.h"
  9. #include "core/hle/service/acc/profile_manager.h"
  10. #include "core/hle/service/prepo/prepo.h"
  11. #include "core/hle/service/service.h"
  12. #include "core/reporter.h"
  13. namespace Service::PlayReport {
  14. class PlayReport final : public ServiceFramework<PlayReport> {
  15. public:
  16. explicit PlayReport(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
  17. // clang-format off
  18. static const FunctionInfo functions[] = {
  19. {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"},
  20. {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
  21. {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"},
  22. {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
  23. {10104, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
  24. {10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
  25. {10200, &PlayReport::RequestImmediateTransmission, "RequestImmediateTransmission"},
  26. {10300, &PlayReport::GetTransmissionStatus, "GetTransmissionStatus"},
  27. {10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
  28. {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
  29. {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
  30. {20200, nullptr, "SetOperationMode"},
  31. {30100, nullptr, "ClearStorage"},
  32. {30200, nullptr, "ClearStatistics"},
  33. {30300, nullptr, "GetStorageUsage"},
  34. {30400, nullptr, "GetStatistics"},
  35. {30401, nullptr, "GetThroughputHistory"},
  36. {30500, nullptr, "GetLastUploadError"},
  37. {30600, nullptr, "GetApplicationUploadSummary"},
  38. {40100, nullptr, "IsUserAgreementCheckEnabled"},
  39. {40101, nullptr, "SetUserAgreementCheckEnabled"},
  40. {50100, nullptr, "ReadAllApplicationReportFiles"},
  41. {90100, nullptr, "ReadAllReportFiles"},
  42. {90101, nullptr, "Unknown90101"},
  43. {90102, nullptr, "Unknown90102"},
  44. {90200, nullptr, "GetStatistics"},
  45. {90201, nullptr, "GetThroughputHistory"},
  46. {90300, nullptr, "GetLastUploadError"},
  47. };
  48. // clang-format on
  49. RegisterHandlers(functions);
  50. }
  51. private:
  52. template <Core::Reporter::PlayReportType Type>
  53. void SaveReport(Kernel::HLERequestContext& ctx) {
  54. IPC::RequestParser rp{ctx};
  55. const auto process_id = rp.PopRaw<u64>();
  56. const auto data1 = ctx.ReadBuffer(0);
  57. const auto data2 = [&ctx] {
  58. if (ctx.CanReadBuffer(1)) {
  59. return ctx.ReadBuffer(1);
  60. }
  61. return std::vector<u8>{};
  62. }();
  63. LOG_DEBUG(Service_PREPO,
  64. "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}",
  65. Type, process_id, data1.size(), data2.size());
  66. const auto& reporter{system.GetReporter()};
  67. reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
  68. process_id);
  69. IPC::ResponseBuilder rb{ctx, 2};
  70. rb.Push(ResultSuccess);
  71. }
  72. template <Core::Reporter::PlayReportType Type>
  73. void SaveReportWithUser(Kernel::HLERequestContext& ctx) {
  74. IPC::RequestParser rp{ctx};
  75. const auto user_id = rp.PopRaw<u128>();
  76. const auto process_id = rp.PopRaw<u64>();
  77. const auto data1 = ctx.ReadBuffer(0);
  78. const auto data2 = [&ctx] {
  79. if (ctx.CanReadBuffer(1)) {
  80. return ctx.ReadBuffer(1);
  81. }
  82. return std::vector<u8>{};
  83. }();
  84. LOG_DEBUG(Service_PREPO,
  85. "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, "
  86. "data1_size={:016X}, data2_size={:016X}",
  87. Type, user_id[1], user_id[0], process_id, data1.size(), data2.size());
  88. const auto& reporter{system.GetReporter()};
  89. reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
  90. process_id, user_id);
  91. IPC::ResponseBuilder rb{ctx, 2};
  92. rb.Push(ResultSuccess);
  93. }
  94. void RequestImmediateTransmission(Kernel::HLERequestContext& ctx) {
  95. LOG_WARNING(Service_PREPO, "(STUBBED) called");
  96. IPC::ResponseBuilder rb{ctx, 2};
  97. rb.Push(ResultSuccess);
  98. }
  99. void GetTransmissionStatus(Kernel::HLERequestContext& ctx) {
  100. LOG_WARNING(Service_PREPO, "(STUBBED) called");
  101. constexpr s32 status = 0;
  102. IPC::ResponseBuilder rb{ctx, 3};
  103. rb.Push(ResultSuccess);
  104. rb.Push(status);
  105. }
  106. void GetSystemSessionId(Kernel::HLERequestContext& ctx) {
  107. LOG_WARNING(Service_PREPO, "(STUBBED) called");
  108. constexpr u64 system_session_id = 0;
  109. IPC::ResponseBuilder rb{ctx, 4};
  110. rb.Push(ResultSuccess);
  111. rb.Push(system_session_id);
  112. }
  113. void SaveSystemReport(Kernel::HLERequestContext& ctx) {
  114. IPC::RequestParser rp{ctx};
  115. const auto title_id = rp.PopRaw<u64>();
  116. const auto data1 = ctx.ReadBuffer(0);
  117. const auto data2 = [&ctx] {
  118. if (ctx.CanReadBuffer(1)) {
  119. return ctx.ReadBuffer(1);
  120. }
  121. return std::vector<u8>{};
  122. }();
  123. LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
  124. title_id, data1.size(), data2.size());
  125. const auto& reporter{system.GetReporter()};
  126. reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2});
  127. IPC::ResponseBuilder rb{ctx, 2};
  128. rb.Push(ResultSuccess);
  129. }
  130. void SaveSystemReportWithUser(Kernel::HLERequestContext& ctx) {
  131. IPC::RequestParser rp{ctx};
  132. const auto user_id = rp.PopRaw<u128>();
  133. const auto title_id = rp.PopRaw<u64>();
  134. const auto data1 = ctx.ReadBuffer(0);
  135. const auto data2 = [&ctx] {
  136. if (ctx.CanReadBuffer(1)) {
  137. return ctx.ReadBuffer(1);
  138. }
  139. return std::vector<u8>{};
  140. }();
  141. LOG_DEBUG(Service_PREPO,
  142. "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, "
  143. "data2_size={:016X}",
  144. user_id[1], user_id[0], title_id, data1.size(), data2.size());
  145. const auto& reporter{system.GetReporter()};
  146. reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2},
  147. std::nullopt, user_id);
  148. IPC::ResponseBuilder rb{ctx, 2};
  149. rb.Push(ResultSuccess);
  150. }
  151. };
  152. void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
  153. std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager);
  154. std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager);
  155. std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager);
  156. std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager);
  157. std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager);
  158. }
  159. } // namespace Service::PlayReport