summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar german772022-05-07 15:28:51 -0500
committerGravatar Narr the Reg2022-05-09 10:28:04 -0500
commitcc6a4bedfc01ef251cf9caf362997a1821fd1ffa (patch)
tree10fa1408c999dcc9bd5da6ed64a15712440438bc /src
parentMerge pull request #8300 from Morph1984/resultval-range (diff)
downloadyuzu-cc6a4bedfc01ef251cf9caf362997a1821fd1ffa.tar.gz
yuzu-cc6a4bedfc01ef251cf9caf362997a1821fd1ffa.tar.xz
yuzu-cc6a4bedfc01ef251cf9caf362997a1821fd1ffa.zip
service: notifa: Implement most part of this service
Implements partially RegisterAlarmSetting, UpdateAlarmSetting, LoadApplicationParameter, DeleteAlarmSetting. Needed for Fitness `Boxing 2: Rhythm & Exercise` and `Ring Fit Adventure`.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/glue/notif.cpp132
-rw-r--r--src/core/hle/service/glue/notif.h48
2 files changed, 172 insertions, 8 deletions
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp
index b971846e7..3ace2dabd 100644
--- a/src/core/hle/service/glue/notif.cpp
+++ b/src/core/hle/service/glue/notif.cpp
@@ -1,6 +1,11 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
5#include <cstring>
6
7#include "common/assert.h"
8#include "common/logging/log.h"
4#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
5#include "core/hle/service/glue/notif.h" 10#include "core/hle/service/glue/notif.h"
6 11
@@ -9,11 +14,11 @@ namespace Service::Glue {
9NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { 14NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} {
10 // clang-format off 15 // clang-format off
11 static const FunctionInfo functions[] = { 16 static const FunctionInfo functions[] = {
12 {500, nullptr, "RegisterAlarmSetting"}, 17 {500, &NOTIF_A::RegisterAlarmSetting, "RegisterAlarmSetting"},
13 {510, nullptr, "UpdateAlarmSetting"}, 18 {510, &NOTIF_A::UpdateAlarmSetting, "UpdateAlarmSetting"},
14 {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, 19 {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"},
15 {530, nullptr, "LoadApplicationParameter"}, 20 {530, &NOTIF_A::LoadApplicationParameter, "LoadApplicationParameter"},
16 {540, nullptr, "DeleteAlarmSetting"}, 21 {540, &NOTIF_A::DeleteAlarmSetting, "DeleteAlarmSetting"},
17 {1000, &NOTIF_A::Initialize, "Initialize"}, 22 {1000, &NOTIF_A::Initialize, "Initialize"},
18 }; 23 };
19 // clang-format on 24 // clang-format on
@@ -23,21 +28,132 @@ NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} {
23 28
24NOTIF_A::~NOTIF_A() = default; 29NOTIF_A::~NOTIF_A() = default;
25 30
31void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) {
32 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0);
33 const auto application_parameter_size = ctx.GetReadBufferSize(1);
34
35 ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting),
36 "alarm_setting_buffer_size is not 0x40 bytes");
37 ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter),
38 "application_parameter_size is bigger than 0x400 bytes");
39
40 AlarmSetting new_alarm{};
41 memcpy(&new_alarm, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting));
42
43 // TODO: Count alarms per game id
44 if (alarms.size() >= max_alarms) {
45 LOG_ERROR(Service_NOTIF, "Alarm limit reached");
46 IPC::ResponseBuilder rb{ctx, 2};
47 rb.Push(ResultUnknown);
48 return;
49 }
50
51 new_alarm.alarm_setting_id = last_alarm_setting_id++;
52 alarms.push_back(new_alarm);
53
54 // TODO: Save application parameter data
55
56 LOG_WARNING(Service_NOTIF,
57 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}",
58 application_parameter_size, new_alarm.alarm_setting_id, new_alarm.kind,
59 new_alarm.muted);
60
61 IPC::ResponseBuilder rb{ctx, 2};
62 rb.Push(ResultSuccess);
63 rb.Push(new_alarm.alarm_setting_id);
64}
65
66void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) {
67 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0);
68 const auto application_parameter_size = ctx.GetReadBufferSize(1);
69
70 ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting),
71 "alarm_setting_buffer_size is not 0x40 bytes");
72 ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter),
73 "application_parameter_size is bigger than 0x400 bytes");
74
75 AlarmSetting alarm_setting{};
76 memcpy(&alarm_setting, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting));
77
78 const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id);
79 if (alarm_it != alarms.end()) {
80 LOG_DEBUG(Service_NOTIF, "Alarm updated");
81 *alarm_it = alarm_setting;
82 // TODO: Save application parameter data
83 }
84
85 LOG_WARNING(Service_NOTIF,
86 "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}",
87 application_parameter_size, alarm_setting.alarm_setting_id, alarm_setting.kind,
88 alarm_setting.muted);
89
90 IPC::ResponseBuilder rb{ctx, 2};
91 rb.Push(ResultSuccess);
92}
93
26void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { 94void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) {
27 // Returns an array of AlarmSetting 95 LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size());
28 constexpr s32 alarm_count = 0;
29 96
30 LOG_WARNING(Service_NOTIF, "(STUBBED) called"); 97 // TODO: Only return alarms of this game id
98 ctx.WriteBuffer(alarms);
31 99
32 IPC::ResponseBuilder rb{ctx, 3}; 100 IPC::ResponseBuilder rb{ctx, 3};
33 rb.Push(ResultSuccess); 101 rb.Push(ResultSuccess);
34 rb.Push(alarm_count); 102 rb.Push(static_cast<u32>(alarms.size()));
103}
104
105void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) {
106 IPC::RequestParser rp{ctx};
107 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()};
108
109 const auto alarm_it = GetAlarmFromId(alarm_setting_id);
110 if (alarm_it == alarms.end()) {
111 LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id);
112 IPC::ResponseBuilder rb{ctx, 2};
113 rb.Push(ResultUnknown);
114 return;
115 }
116
117 // TODO: Read application parameter related to this setting id
118 ApplicationParameter application_parameter{};
119
120 LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id);
121
122 ctx.WriteBuffer(application_parameter);
123
124 IPC::ResponseBuilder rb{ctx, 2};
125 rb.Push(ResultSuccess);
126 rb.Push(static_cast<u32>(application_parameter.size()));
127}
128
129void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) {
130 IPC::RequestParser rp{ctx};
131 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()};
132
133 std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) {
134 return alarm.alarm_setting_id == alarm_setting_id;
135 });
136
137 LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id);
138
139 IPC::ResponseBuilder rb{ctx, 2};
140 rb.Push(ResultSuccess);
35} 141}
36 142
37void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { 143void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) {
144 // TODO: Load previous alarms from config
145
38 LOG_WARNING(Service_NOTIF, "(STUBBED) called"); 146 LOG_WARNING(Service_NOTIF, "(STUBBED) called");
39 IPC::ResponseBuilder rb{ctx, 2}; 147 IPC::ResponseBuilder rb{ctx, 2};
40 rb.Push(ResultSuccess); 148 rb.Push(ResultSuccess);
41} 149}
42 150
151std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId(
152 AlarmSettingId alarm_setting_id) {
153 return std::find_if(alarms.begin(), alarms.end(),
154 [alarm_setting_id](const AlarmSetting& alarm) {
155 return alarm.alarm_setting_id == alarm_setting_id;
156 });
157}
158
43} // namespace Service::Glue 159} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h
index 7310d7f72..4467e1f35 100644
--- a/src/core/hle/service/glue/notif.h
+++ b/src/core/hle/service/glue/notif.h
@@ -3,6 +3,10 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <array>
7#include <vector>
8
9#include "common/uuid.h"
6#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
7 11
8namespace Core { 12namespace Core {
@@ -17,8 +21,52 @@ public:
17 ~NOTIF_A() override; 21 ~NOTIF_A() override;
18 22
19private: 23private:
24 static constexpr std::size_t max_alarms = 8;
25
26 // This is nn::notification::AlarmSettingId
27 using AlarmSettingId = u16;
28 static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size");
29
30 using ApplicationParameter = std::array<u8, 0x400>;
31 static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size");
32
33 struct DailyAlarmSetting {
34 s8 hour;
35 s8 minute;
36 };
37 static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size");
38
39 struct WeeklyScheduleAlarmSetting {
40 INSERT_PADDING_BYTES(0xA);
41 std::array<DailyAlarmSetting, 0x7> day_of_week;
42 };
43 static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18,
44 "WeeklyScheduleAlarmSetting is an invalid size");
45
46 // This is nn::notification::AlarmSetting
47 struct AlarmSetting {
48 AlarmSettingId alarm_setting_id;
49 u8 kind;
50 u8 muted;
51 INSERT_PADDING_BYTES(0x4);
52 Common::UUID account_id;
53 u64 application_id;
54 INSERT_PADDING_BYTES(0x8);
55 WeeklyScheduleAlarmSetting schedule;
56 };
57 static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size");
58
59 void RegisterAlarmSetting(Kernel::HLERequestContext& ctx);
60 void UpdateAlarmSetting(Kernel::HLERequestContext& ctx);
20 void ListAlarmSettings(Kernel::HLERequestContext& ctx); 61 void ListAlarmSettings(Kernel::HLERequestContext& ctx);
62 void LoadApplicationParameter(Kernel::HLERequestContext& ctx);
63 void DeleteAlarmSetting(Kernel::HLERequestContext& ctx);
21 void Initialize(Kernel::HLERequestContext& ctx); 64 void Initialize(Kernel::HLERequestContext& ctx);
65
66 std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id);
67
68 std::vector<AlarmSetting> alarms{};
69 AlarmSettingId last_alarm_setting_id{};
22}; 70};
23 71
24} // namespace Service::Glue 72} // namespace Service::Glue