blob: ff08638800252fd59b58b5d546021354a2b76dd2 [file] [log] [blame]
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01001#include "trigger.hpp"
2
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01003#include "messages/collect_trigger_id.hpp"
4#include "messages/trigger_presence_changed_ind.hpp"
Szymon Dompkee28aa532021-10-27 12:33:12 +02005#include "trigger_manager.hpp"
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00006#include "types/report_types.hpp"
7#include "types/trigger_types.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01008#include "utils/contains.hpp"
Cezary Zwolak4416fce2021-03-17 03:21:06 +01009#include "utils/conversion_trigger.hpp"
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020010#include "utils/dbus_path_utils.hpp"
Cezary Zwolaka4e67612021-02-18 13:16:16 +010011#include "utils/transform.hpp"
12
13#include <phosphor-logging/log.hpp>
14
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010015Trigger::Trigger(
16 boost::asio::io_context& ioc,
17 const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020018 TriggerId&& idIn, const std::string& nameIn,
Szymon Dompke94f71c52021-12-10 07:16:33 +010019 const std::vector<TriggerAction>& triggerActionsIn,
20 const std::shared_ptr<std::vector<std::string>> reportIdsIn,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010021 std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010022 interfaces::TriggerManager& triggerManager,
Szymon Dompke94f71c52021-12-10 07:16:33 +010023 interfaces::JsonStorage& triggerStorageIn,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010024 const interfaces::TriggerFactory& triggerFactory, Sensors sensorsIn) :
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020025 id(std::move(idIn)),
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020026 path(utils::pathAppend(utils::constants::triggerDirPath, *id)),
Szymon Dompkee28aa532021-10-27 12:33:12 +020027 name(nameIn), triggerActions(std::move(triggerActionsIn)),
Szymon Dompke1cdd7e42022-06-08 14:43:13 +020028 reportIds(std::move(reportIdsIn)), thresholds(std::move(thresholdsIn)),
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020029 fileName(std::to_string(std::hash<std::string>{}(*id))),
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +010030 triggerStorage(triggerStorageIn), sensors(std::move(sensorsIn)),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010031 messanger(ioc)
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010032{
33 deleteIface = objServer->add_unique_interface(
34 path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
35 dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010036 if (persistent)
37 {
38 triggerStorage.remove(fileName);
39 }
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010040 messanger.send(messages::TriggerPresenceChangedInd{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020041 messages::Presence::Removed, *id, {}});
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010042 boost::asio::post(ioc, [this, &triggerManager] {
43 triggerManager.removeTrigger(this);
44 });
45 });
46 });
47
48 triggerIface = objServer->add_unique_interface(
Szymon Dompke94f71c52021-12-10 07:16:33 +010049 path, triggerIfaceName, [this, &triggerFactory](auto& dbusIface) {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010050 persistent = storeConfiguration();
51 dbusIface.register_property_rw(
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010052 "Persistent", persistent,
53 sdbusplus::vtable::property_::emits_change,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010054 [this](bool newVal, const auto&) {
55 if (newVal == persistent)
56 {
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010057 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010058 }
59 if (newVal)
60 {
61 persistent = storeConfiguration();
62 }
63 else
64 {
65 triggerStorage.remove(fileName);
66 persistent = false;
67 }
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010068 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010069 },
70 [this](const auto&) { return persistent; });
71
Szymon Dompke94f71c52021-12-10 07:16:33 +010072 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010073 "Thresholds", TriggerThresholdParams{},
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010074 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010075 [this, &triggerFactory](auto newVal, auto& oldVal) {
76 auto newThresholdParams = std::visit(
77 utils::ToLabeledThresholdParamConversion(), newVal);
Szymon Dompke32305f12022-07-05 15:37:21 +020078 TriggerManager::verifyThresholdParams(newThresholdParams);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020079 triggerFactory.updateThresholds(
80 thresholds, *id, triggerActions, reportIds, sensors,
81 newThresholdParams);
Szymon Dompke94f71c52021-12-10 07:16:33 +010082 oldVal = std::move(newVal);
83 return 1;
84 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +010085 [this](const auto&) {
Krzysztof Grobelny55824552022-02-18 16:15:31 +010086 return fromLabeledThresholdParam(getLabeledThresholds());
Cezary Zwolak4416fce2021-03-17 03:21:06 +010087 });
88
Szymon Dompke94f71c52021-12-10 07:16:33 +010089 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010090 "Sensors", SensorsInfo{},
91 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010092 [this, &triggerFactory](auto newVal, auto& oldVal) {
93 auto labeledSensorInfo =
94 triggerFactory.getLabeledSensorsInfo(newVal);
95 triggerFactory.updateSensors(sensors, labeledSensorInfo);
96 for (const auto& threshold : thresholds)
97 {
98 threshold->updateSensors(sensors);
99 }
100 oldVal = std::move(newVal);
101 return 1;
102 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100103 [this](const auto&) {
Szymon Dompke94f71c52021-12-10 07:16:33 +0100104 return utils::fromLabeledSensorsInfo(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100105 getLabeledSensorInfo());
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100106 });
107
Szymon Dompke94f71c52021-12-10 07:16:33 +0100108 dbusIface.register_property_rw(
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200109 "Reports", std::vector<sdbusplus::message::object_path>(),
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100110 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100111 [this](auto newVal, auto& oldVal) {
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200112 auto newReportIds = utils::transform<std::vector>(
113 newVal, [](const auto& path) {
114 return utils::reportPathToId(path);
115 });
116 TriggerManager::verifyReportIds(newReportIds);
117 *reportIds = newReportIds;
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100118 messanger.send(messages::TriggerPresenceChangedInd{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200119 messages::Presence::Exist, *id, *reportIds});
Szymon Dompke94f71c52021-12-10 07:16:33 +0100120 oldVal = std::move(newVal);
121 return 1;
122 },
Szymon Dompke1cdd7e42022-06-08 14:43:13 +0200123 [this](const auto&) {
124 return utils::transform<std::vector>(
125 *reportIds, [](const auto& id) {
126 return utils::pathAppend(
127 utils::constants::reportDirPath, id);
128 });
129 });
Szymon Dompke20013012021-07-23 09:54:20 +0200130
131 dbusIface.register_property_r(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100132 "Discrete", isDiscreate(), sdbusplus::vtable::property_::const_,
133 [this](const auto& x) { return isDiscreate(); });
Szymon Dompke20013012021-07-23 09:54:20 +0200134
Szymon Dompkee28aa532021-10-27 12:33:12 +0200135 dbusIface.register_property_rw(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100136 "Name", name, sdbusplus::vtable::property_::emits_change,
Szymon Dompkee28aa532021-10-27 12:33:12 +0200137 [this](auto newVal, auto& oldVal) {
Szymon Dompke32305f12022-07-05 15:37:21 +0200138 if (newVal.length() > utils::constants::maxIdNameLength)
139 {
Krzysztof Grobelny62c08e92022-09-16 10:28:53 +0200140 throw errors::InvalidArgument("Name",
141 "Name is too long.");
Szymon Dompke32305f12022-07-05 15:37:21 +0200142 }
Szymon Dompkee28aa532021-10-27 12:33:12 +0200143 name = oldVal = newVal;
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100144 return 1;
Szymon Dompkee28aa532021-10-27 12:33:12 +0200145 },
146 [this](const auto&) { return name; });
147
Szymon Dompke94f71c52021-12-10 07:16:33 +0100148 dbusIface.register_property_r(
149 "TriggerActions", std::vector<std::string>(),
150 sdbusplus::vtable::property_::const_, [this](const auto&) {
151 return utils::transform(triggerActions,
152 [](const auto& action) {
153 return actionToString(action);
154 });
155 });
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100156 });
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100157
158 for (const auto& threshold : thresholds)
159 {
160 threshold->initialize();
161 }
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100162
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100163 messanger.on_receive<messages::CollectTriggerIdReq>(
164 [this](const auto& msg) {
165 if (utils::contains(*reportIds, msg.reportId))
166 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200167 messanger.send(messages::CollectTriggerIdResp{*id});
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100168 }
169 });
170
171 messanger.send(messages::TriggerPresenceChangedInd{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200172 messages::Presence::Exist, *id, *reportIds});
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100173}
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100174
175bool Trigger::storeConfiguration() const
176{
177 try
178 {
179 nlohmann::json data;
180
Szymon Dompke94f71c52021-12-10 07:16:33 +0100181 auto labeledThresholdParams =
182 std::visit(utils::ToLabeledThresholdParamConversion(),
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100183 fromLabeledThresholdParam(getLabeledThresholds()));
Szymon Dompke94f71c52021-12-10 07:16:33 +0100184
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100185 data["Version"] = triggerVersion;
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200186 data["Id"] = *id;
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100187 data["Name"] = name;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100188 data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
Szymon Dompke94f71c52021-12-10 07:16:33 +0100189 data["TriggerActions"] =
190 utils::transform(triggerActions, [](const auto& action) {
191 return actionToString(action);
192 });
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100193 data["ThresholdParams"] =
194 utils::labeledThresholdParamsToJson(labeledThresholdParams);
Szymon Dompke94f71c52021-12-10 07:16:33 +0100195 data["ReportIds"] = *reportIds;
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100196 data["Sensors"] = getLabeledSensorInfo();
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100197
198 triggerStorage.store(fileName, data);
199 }
200 catch (const std::exception& e)
201 {
202 phosphor::logging::log<phosphor::logging::level::ERR>(
203 "Failed to store a trigger in storage",
204 phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
205 return false;
206 }
207 return true;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100208}
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100209
210std::vector<LabeledSensorInfo> Trigger::getLabeledSensorInfo() const
211{
212 return utils::transform(sensors, [](const auto& sensor) {
213 return sensor->getLabeledSensorInfo();
214 });
215}
216
217std::vector<LabeledThresholdParam> Trigger::getLabeledThresholds() const
218{
219 return utils::transform(thresholds, [](const auto& threshold) {
220 return threshold->getThresholdParam();
221 });
222}
223
224bool Trigger::isDiscreate() const
225{
226 const auto labeledThresholds = getLabeledThresholds();
227
228 return utils::isFirstElementOfType<std::monostate>(labeledThresholds) ||
229 utils::isFirstElementOfType<discrete::LabeledThresholdParam>(
230 labeledThresholds);
231}