blob: 485f2f921feda17e32a3d431fa49240ab4eecc4d [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"
Cezary Zwolaka4e67612021-02-18 13:16:16 +010010#include "utils/transform.hpp"
11
12#include <phosphor-logging/log.hpp>
13
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010014Trigger::Trigger(
15 boost::asio::io_context& ioc,
16 const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
Szymon Dompkee28aa532021-10-27 12:33:12 +020017 const std::string& idIn, const std::string& nameIn,
Szymon Dompke94f71c52021-12-10 07:16:33 +010018 const std::vector<TriggerAction>& triggerActionsIn,
19 const std::shared_ptr<std::vector<std::string>> reportIdsIn,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010020 std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010021 interfaces::TriggerManager& triggerManager,
Szymon Dompke94f71c52021-12-10 07:16:33 +010022 interfaces::JsonStorage& triggerStorageIn,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010023 const interfaces::TriggerFactory& triggerFactory, Sensors sensorsIn) :
Szymon Dompkee28aa532021-10-27 12:33:12 +020024 id(idIn),
25 name(nameIn), triggerActions(std::move(triggerActionsIn)),
Szymon Dompke94f71c52021-12-10 07:16:33 +010026 path(triggerDir + id), reportIds(std::move(reportIdsIn)),
Cezary Zwolak4416fce2021-03-17 03:21:06 +010027 thresholds(std::move(thresholdsIn)),
Szymon Dompkee28aa532021-10-27 12:33:12 +020028 fileName(std::to_string(std::hash<std::string>{}(id))),
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +010029 triggerStorage(triggerStorageIn), sensors(std::move(sensorsIn)),
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010030 messanger(ioc)
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010031{
32 deleteIface = objServer->add_unique_interface(
33 path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
34 dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010035 if (persistent)
36 {
37 triggerStorage.remove(fileName);
38 }
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +010039 messanger.send(messages::TriggerPresenceChangedInd{
40 messages::Presence::Removed, id, {}});
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010041 boost::asio::post(ioc, [this, &triggerManager] {
42 triggerManager.removeTrigger(this);
43 });
44 });
45 });
46
47 triggerIface = objServer->add_unique_interface(
Szymon Dompke94f71c52021-12-10 07:16:33 +010048 path, triggerIfaceName, [this, &triggerFactory](auto& dbusIface) {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010049 persistent = storeConfiguration();
50 dbusIface.register_property_rw(
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010051 "Persistent", persistent,
52 sdbusplus::vtable::property_::emits_change,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010053 [this](bool newVal, const auto&) {
54 if (newVal == persistent)
55 {
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010056 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010057 }
58 if (newVal)
59 {
60 persistent = storeConfiguration();
61 }
62 else
63 {
64 triggerStorage.remove(fileName);
65 persistent = false;
66 }
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010067 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010068 },
69 [this](const auto&) { return persistent; });
70
Szymon Dompke94f71c52021-12-10 07:16:33 +010071 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010072 "Thresholds", TriggerThresholdParams{},
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010073 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010074 [this, &triggerFactory](auto newVal, auto& oldVal) {
75 auto newThresholdParams = std::visit(
76 utils::ToLabeledThresholdParamConversion(), newVal);
77 triggerFactory.updateThresholds(thresholds, triggerActions,
78 reportIds, sensors,
79 newThresholdParams);
80 oldVal = std::move(newVal);
81 return 1;
82 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +010083 [this](const auto&) {
Krzysztof Grobelny55824552022-02-18 16:15:31 +010084 return fromLabeledThresholdParam(getLabeledThresholds());
Cezary Zwolak4416fce2021-03-17 03:21:06 +010085 });
86
Szymon Dompke94f71c52021-12-10 07:16:33 +010087 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010088 "Sensors", SensorsInfo{},
89 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010090 [this, &triggerFactory](auto newVal, auto& oldVal) {
91 auto labeledSensorInfo =
92 triggerFactory.getLabeledSensorsInfo(newVal);
93 triggerFactory.updateSensors(sensors, labeledSensorInfo);
94 for (const auto& threshold : thresholds)
95 {
96 threshold->updateSensors(sensors);
97 }
98 oldVal = std::move(newVal);
99 return 1;
100 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100101 [this](const auto&) {
Szymon Dompke94f71c52021-12-10 07:16:33 +0100102 return utils::fromLabeledSensorsInfo(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100103 getLabeledSensorInfo());
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100104 });
105
Szymon Dompke94f71c52021-12-10 07:16:33 +0100106 dbusIface.register_property_rw(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100107 "ReportNames", *reportIds,
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100108 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100109 [this](auto newVal, auto& oldVal) {
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100110 TriggerManager::verifyReportIds(newVal);
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100111 *reportIds = newVal;
112 messanger.send(messages::TriggerPresenceChangedInd{
113 messages::Presence::Exist, id, *reportIds});
Szymon Dompke94f71c52021-12-10 07:16:33 +0100114 oldVal = std::move(newVal);
115 return 1;
116 },
117 [this](const auto&) { return *reportIds; });
Szymon Dompke20013012021-07-23 09:54:20 +0200118
119 dbusIface.register_property_r(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100120 "Discrete", isDiscreate(), sdbusplus::vtable::property_::const_,
121 [this](const auto& x) { return isDiscreate(); });
Szymon Dompke20013012021-07-23 09:54:20 +0200122
Szymon Dompkee28aa532021-10-27 12:33:12 +0200123 dbusIface.register_property_rw(
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100124 "Name", name, sdbusplus::vtable::property_::emits_change,
Szymon Dompkee28aa532021-10-27 12:33:12 +0200125 [this](auto newVal, auto& oldVal) {
126 name = oldVal = newVal;
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100127 return 1;
Szymon Dompkee28aa532021-10-27 12:33:12 +0200128 },
129 [this](const auto&) { return name; });
130
Szymon Dompke94f71c52021-12-10 07:16:33 +0100131 dbusIface.register_property_r(
132 "TriggerActions", std::vector<std::string>(),
133 sdbusplus::vtable::property_::const_, [this](const auto&) {
134 return utils::transform(triggerActions,
135 [](const auto& action) {
136 return actionToString(action);
137 });
138 });
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100139 });
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100140
141 for (const auto& threshold : thresholds)
142 {
143 threshold->initialize();
144 }
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100145
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100146 messanger.on_receive<messages::CollectTriggerIdReq>(
147 [this](const auto& msg) {
148 if (utils::contains(*reportIds, msg.reportId))
149 {
150 messanger.send(messages::CollectTriggerIdResp{id});
151 }
152 });
153
154 messanger.send(messages::TriggerPresenceChangedInd{
155 messages::Presence::Exist, id, *reportIds});
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100156}
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100157
158bool Trigger::storeConfiguration() const
159{
160 try
161 {
162 nlohmann::json data;
163
Szymon Dompke94f71c52021-12-10 07:16:33 +0100164 auto labeledThresholdParams =
165 std::visit(utils::ToLabeledThresholdParamConversion(),
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100166 fromLabeledThresholdParam(getLabeledThresholds()));
Szymon Dompke94f71c52021-12-10 07:16:33 +0100167
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100168 data["Version"] = triggerVersion;
Szymon Dompkee28aa532021-10-27 12:33:12 +0200169 data["Id"] = id;
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100170 data["Name"] = name;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100171 data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
Szymon Dompke94f71c52021-12-10 07:16:33 +0100172 data["TriggerActions"] =
173 utils::transform(triggerActions, [](const auto& action) {
174 return actionToString(action);
175 });
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100176 data["ThresholdParams"] =
177 utils::labeledThresholdParamsToJson(labeledThresholdParams);
Szymon Dompke94f71c52021-12-10 07:16:33 +0100178 data["ReportIds"] = *reportIds;
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100179 data["Sensors"] = getLabeledSensorInfo();
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100180
181 triggerStorage.store(fileName, data);
182 }
183 catch (const std::exception& e)
184 {
185 phosphor::logging::log<phosphor::logging::level::ERR>(
186 "Failed to store a trigger in storage",
187 phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
188 return false;
189 }
190 return true;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100191}
Krzysztof Grobelny55824552022-02-18 16:15:31 +0100192
193std::vector<LabeledSensorInfo> Trigger::getLabeledSensorInfo() const
194{
195 return utils::transform(sensors, [](const auto& sensor) {
196 return sensor->getLabeledSensorInfo();
197 });
198}
199
200std::vector<LabeledThresholdParam> Trigger::getLabeledThresholds() const
201{
202 return utils::transform(thresholds, [](const auto& threshold) {
203 return threshold->getThresholdParam();
204 });
205}
206
207bool Trigger::isDiscreate() const
208{
209 const auto labeledThresholds = getLabeledThresholds();
210
211 return utils::isFirstElementOfType<std::monostate>(labeledThresholds) ||
212 utils::isFirstElementOfType<discrete::LabeledThresholdParam>(
213 labeledThresholds);
214}