176833cb5SWludzik, Jozef #include "trigger.hpp"
276833cb5SWludzik, Jozef
3e6d48874SKrzysztof Grobelny #include "messages/collect_trigger_id.hpp"
4e6d48874SKrzysztof Grobelny #include "messages/trigger_presence_changed_ind.hpp"
5e28aa53dSSzymon Dompke #include "trigger_manager.hpp"
6dcc4e193SKrzysztof Grobelny #include "types/report_types.hpp"
7dcc4e193SKrzysztof Grobelny #include "types/trigger_types.hpp"
8e6d48874SKrzysztof Grobelny #include "utils/contains.hpp"
94416fce6SCezary Zwolak #include "utils/conversion_trigger.hpp"
101cdd7e4fSSzymon Dompke #include "utils/dbus_path_utils.hpp"
11a4e67616SCezary Zwolak #include "utils/transform.hpp"
12a4e67616SCezary Zwolak
13a4e67616SCezary Zwolak #include <phosphor-logging/log.hpp>
14a4e67616SCezary Zwolak
Trigger(boost::asio::io_context & ioc,const std::shared_ptr<sdbusplus::asio::object_server> & objServer,TriggerId && idIn,const std::string & nameIn,const std::vector<TriggerAction> & triggerActionsIn,const std::shared_ptr<std::vector<std::string>> reportIdsIn,std::vector<std::shared_ptr<interfaces::Threshold>> && thresholdsIn,interfaces::TriggerManager & triggerManager,interfaces::JsonStorage & triggerStorageIn,const interfaces::TriggerFactory & triggerFactory,Sensors sensorsIn)1576833cb5SWludzik, Jozef Trigger::Trigger(
1676833cb5SWludzik, Jozef boost::asio::io_context& ioc,
1776833cb5SWludzik, Jozef const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
18b7b7e1b6SSzymon Dompke TriggerId&& idIn, const std::string& nameIn,
1994f71c51SSzymon Dompke const std::vector<TriggerAction>& triggerActionsIn,
2094f71c51SSzymon Dompke const std::shared_ptr<std::vector<std::string>> reportIdsIn,
211477fe6aSWludzik, Jozef std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
22a4e67616SCezary Zwolak interfaces::TriggerManager& triggerManager,
2394f71c51SSzymon Dompke interfaces::JsonStorage& triggerStorageIn,
24e6d48874SKrzysztof Grobelny const interfaces::TriggerFactory& triggerFactory, Sensors sensorsIn) :
25b7b7e1b6SSzymon Dompke id(std::move(idIn)),
261cdd7e4fSSzymon Dompke path(utils::pathAppend(utils::constants::triggerDirPath, *id)),
27e28aa53dSSzymon Dompke name(nameIn), triggerActions(std::move(triggerActionsIn)),
281cdd7e4fSSzymon Dompke reportIds(std::move(reportIdsIn)), thresholds(std::move(thresholdsIn)),
29b7b7e1b6SSzymon Dompke fileName(std::to_string(std::hash<std::string>{}(*id))),
30b4ef22e4SSzymon Dompke triggerStorage(triggerStorageIn), sensors(std::move(sensorsIn)),
31e6d48874SKrzysztof Grobelny messanger(ioc)
3276833cb5SWludzik, Jozef {
3376833cb5SWludzik, Jozef deleteIface = objServer->add_unique_interface(
__anon5e4599b80102(auto& dbusIface) 3476833cb5SWludzik, Jozef path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
3576833cb5SWludzik, Jozef dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
36a4e67616SCezary Zwolak if (persistent)
37a4e67616SCezary Zwolak {
38a4e67616SCezary Zwolak triggerStorage.remove(fileName);
39a4e67616SCezary Zwolak }
40e6d48874SKrzysztof Grobelny messanger.send(messages::TriggerPresenceChangedInd{
41b7b7e1b6SSzymon Dompke messages::Presence::Removed, *id, {}});
4276833cb5SWludzik, Jozef boost::asio::post(ioc, [this, &triggerManager] {
4376833cb5SWludzik, Jozef triggerManager.removeTrigger(this);
4476833cb5SWludzik, Jozef });
4576833cb5SWludzik, Jozef });
4676833cb5SWludzik, Jozef });
4776833cb5SWludzik, Jozef
4876833cb5SWludzik, Jozef triggerIface = objServer->add_unique_interface(
__anon5e4599b80402(auto& dbusIface) 4994f71c51SSzymon Dompke path, triggerIfaceName, [this, &triggerFactory](auto& dbusIface) {
50a4e67616SCezary Zwolak persistent = storeConfiguration();
51a4e67616SCezary Zwolak dbusIface.register_property_rw(
5276833cb5SWludzik, Jozef "Persistent", persistent,
5376833cb5SWludzik, Jozef sdbusplus::vtable::property_::emits_change,
54a4e67616SCezary Zwolak [this](bool newVal, const auto&) {
55a4e67616SCezary Zwolak if (newVal == persistent)
56a4e67616SCezary Zwolak {
573e2cc9d4SSzymon Dompke return 1;
58a4e67616SCezary Zwolak }
59a4e67616SCezary Zwolak if (newVal)
60a4e67616SCezary Zwolak {
61a4e67616SCezary Zwolak persistent = storeConfiguration();
62a4e67616SCezary Zwolak }
63a4e67616SCezary Zwolak else
64a4e67616SCezary Zwolak {
65a4e67616SCezary Zwolak triggerStorage.remove(fileName);
66a4e67616SCezary Zwolak persistent = false;
67a4e67616SCezary Zwolak }
683e2cc9d4SSzymon Dompke return 1;
69*583ba441SPatrick Williams },
70*583ba441SPatrick Williams [this](const auto&) { return persistent; });
71a4e67616SCezary Zwolak
7294f71c51SSzymon Dompke dbusIface.register_property_rw(
734416fce6SCezary Zwolak "Thresholds", TriggerThresholdParams{},
7476833cb5SWludzik, Jozef sdbusplus::vtable::property_::emits_change,
7594f71c51SSzymon Dompke [this, &triggerFactory](auto newVal, auto& oldVal) {
76*583ba441SPatrick Williams auto newThresholdParams = std::visit(
77*583ba441SPatrick Williams utils::ToLabeledThresholdParamConversion(), newVal);
7832305f14SSzymon Dompke TriggerManager::verifyThresholdParams(newThresholdParams);
79*583ba441SPatrick Williams triggerFactory.updateThresholds(
80*583ba441SPatrick Williams thresholds, *id, triggerActions, reportIds, sensors,
8194f71c51SSzymon Dompke newThresholdParams);
8294f71c51SSzymon Dompke oldVal = std::move(newVal);
8394f71c51SSzymon Dompke return 1;
84*583ba441SPatrick Williams },
85*583ba441SPatrick Williams [this](const auto&) {
8655824558SKrzysztof Grobelny return fromLabeledThresholdParam(getLabeledThresholds());
874416fce6SCezary Zwolak });
884416fce6SCezary Zwolak
8994f71c51SSzymon Dompke dbusIface.register_property_rw(
902efa95d8SEd Tanous "DiscreteThresholds", std::vector<discrete::ThresholdParam>{},
912efa95d8SEd Tanous sdbusplus::vtable::property_::emits_change,
922efa95d8SEd Tanous [this, &triggerFactory](
932efa95d8SEd Tanous const std::vector<discrete::ThresholdParam>& newVal,
942efa95d8SEd Tanous std::vector<discrete::ThresholdParam>& oldVal) {
952efa95d8SEd Tanous LabeledTriggerThresholdParams newThresholdParams =
962efa95d8SEd Tanous utils::ToLabeledThresholdParamConversion()(newVal);
972efa95d8SEd Tanous TriggerManager::verifyThresholdParams(newThresholdParams);
98*583ba441SPatrick Williams triggerFactory.updateThresholds(
99*583ba441SPatrick Williams thresholds, *id, triggerActions, reportIds, sensors,
1002efa95d8SEd Tanous newThresholdParams);
1012efa95d8SEd Tanous oldVal = std::move(newVal);
1022efa95d8SEd Tanous return 1;
1032efa95d8SEd Tanous },
1042efa95d8SEd Tanous [this](const auto&) {
1052efa95d8SEd Tanous TriggerThresholdParams unlabeled =
1062efa95d8SEd Tanous fromLabeledThresholdParam(getLabeledThresholds());
1072efa95d8SEd Tanous auto* ptr =
108*583ba441SPatrick Williams std::get_if<std::vector<discrete::ThresholdParam>>(
109*583ba441SPatrick Williams &unlabeled);
1102efa95d8SEd Tanous if (ptr == nullptr)
1112efa95d8SEd Tanous {
1122efa95d8SEd Tanous // If internal type doesn't match, return empty set
1132efa95d8SEd Tanous return std::vector<discrete::ThresholdParam>{};
1142efa95d8SEd Tanous }
1152efa95d8SEd Tanous return *ptr;
1162efa95d8SEd Tanous });
1172efa95d8SEd Tanous
1182efa95d8SEd Tanous dbusIface.register_property_rw(
1192efa95d8SEd Tanous "NumericThresholds", std::vector<numeric::ThresholdParam>{},
1202efa95d8SEd Tanous sdbusplus::vtable::property_::emits_change,
1212efa95d8SEd Tanous [this, &triggerFactory](
1222efa95d8SEd Tanous const std::vector<numeric::ThresholdParam>& newVal,
1232efa95d8SEd Tanous std::vector<numeric::ThresholdParam>& oldVal) {
1242efa95d8SEd Tanous LabeledTriggerThresholdParams newThresholdParams =
1252efa95d8SEd Tanous utils::ToLabeledThresholdParamConversion()(newVal);
1262efa95d8SEd Tanous TriggerManager::verifyThresholdParams(newThresholdParams);
127*583ba441SPatrick Williams triggerFactory.updateThresholds(
128*583ba441SPatrick Williams thresholds, *id, triggerActions, reportIds, sensors,
1292efa95d8SEd Tanous newThresholdParams);
1302efa95d8SEd Tanous oldVal = std::move(newVal);
1312efa95d8SEd Tanous return 1;
1322efa95d8SEd Tanous },
1332efa95d8SEd Tanous [this](const auto&) {
1342efa95d8SEd Tanous TriggerThresholdParams unlabeled =
1352efa95d8SEd Tanous fromLabeledThresholdParam(getLabeledThresholds());
1362efa95d8SEd Tanous auto* ptr =
137*583ba441SPatrick Williams std::get_if<std::vector<numeric::ThresholdParam>>(
138*583ba441SPatrick Williams &unlabeled);
1392efa95d8SEd Tanous if (ptr == nullptr)
1402efa95d8SEd Tanous {
1412efa95d8SEd Tanous // If internal type doesn't match, return empty set
1422efa95d8SEd Tanous return std::vector<numeric::ThresholdParam>{};
1432efa95d8SEd Tanous }
1442efa95d8SEd Tanous return *ptr;
1452efa95d8SEd Tanous });
1462efa95d8SEd Tanous dbusIface.register_property_rw(
1474416fce6SCezary Zwolak "Sensors", SensorsInfo{},
1484416fce6SCezary Zwolak sdbusplus::vtable::property_::emits_change,
14994f71c51SSzymon Dompke [this, &triggerFactory](auto newVal, auto& oldVal) {
15094f71c51SSzymon Dompke auto labeledSensorInfo =
15194f71c51SSzymon Dompke triggerFactory.getLabeledSensorsInfo(newVal);
15294f71c51SSzymon Dompke triggerFactory.updateSensors(sensors, labeledSensorInfo);
15394f71c51SSzymon Dompke for (const auto& threshold : thresholds)
15494f71c51SSzymon Dompke {
15594f71c51SSzymon Dompke threshold->updateSensors(sensors);
15694f71c51SSzymon Dompke }
15794f71c51SSzymon Dompke oldVal = std::move(newVal);
15894f71c51SSzymon Dompke return 1;
159*583ba441SPatrick Williams },
160*583ba441SPatrick Williams [this](const auto&) {
161*583ba441SPatrick Williams return utils::fromLabeledSensorsInfo(
162*583ba441SPatrick Williams getLabeledSensorInfo());
1634416fce6SCezary Zwolak });
1644416fce6SCezary Zwolak
16594f71c51SSzymon Dompke dbusIface.register_property_rw(
1661cdd7e4fSSzymon Dompke "Reports", std::vector<sdbusplus::message::object_path>(),
16776833cb5SWludzik, Jozef sdbusplus::vtable::property_::emits_change,
16894f71c51SSzymon Dompke [this](auto newVal, auto& oldVal) {
1691cdd7e4fSSzymon Dompke auto newReportIds = utils::transform<std::vector>(
170*583ba441SPatrick Williams newVal, [](const auto& path) {
171*583ba441SPatrick Williams return utils::reportPathToId(path);
172*583ba441SPatrick Williams });
1731cdd7e4fSSzymon Dompke TriggerManager::verifyReportIds(newReportIds);
1741cdd7e4fSSzymon Dompke *reportIds = newReportIds;
175e6d48874SKrzysztof Grobelny messanger.send(messages::TriggerPresenceChangedInd{
176b7b7e1b6SSzymon Dompke messages::Presence::Exist, *id, *reportIds});
17794f71c51SSzymon Dompke oldVal = std::move(newVal);
17894f71c51SSzymon Dompke return 1;
179*583ba441SPatrick Williams },
180*583ba441SPatrick Williams [this](const auto&) {
181*583ba441SPatrick Williams return utils::transform<std::vector>(
182*583ba441SPatrick Williams *reportIds, [](const auto& id) {
183*583ba441SPatrick Williams return utils::pathAppend(
184*583ba441SPatrick Williams utils::constants::reportDirPath, id);
1851cdd7e4fSSzymon Dompke });
1861cdd7e4fSSzymon Dompke });
1872001301aSSzymon Dompke
1882001301aSSzymon Dompke dbusIface.register_property_r(
18955824558SKrzysztof Grobelny "Discrete", isDiscreate(), sdbusplus::vtable::property_::const_,
19055824558SKrzysztof Grobelny [this](const auto& x) { return isDiscreate(); });
1912001301aSSzymon Dompke
192e28aa53dSSzymon Dompke dbusIface.register_property_rw(
19355824558SKrzysztof Grobelny "Name", name, sdbusplus::vtable::property_::emits_change,
194e28aa53dSSzymon Dompke [this](auto newVal, auto& oldVal) {
19532305f14SSzymon Dompke if (newVal.length() > utils::constants::maxIdNameLength)
19632305f14SSzymon Dompke {
197*583ba441SPatrick Williams throw errors::InvalidArgument("Name",
198*583ba441SPatrick Williams "Name is too long.");
19932305f14SSzymon Dompke }
200e28aa53dSSzymon Dompke name = oldVal = newVal;
2013e2cc9d4SSzymon Dompke return 1;
202*583ba441SPatrick Williams },
203*583ba441SPatrick Williams [this](const auto&) { return name; });
204e28aa53dSSzymon Dompke
205c7935fa1SPatrick Williams dbusIface.register_property_r(
206c7935fa1SPatrick Williams "TriggerActions", std::vector<std::string>(),
207c7935fa1SPatrick Williams sdbusplus::vtable::property_::const_, [this](const auto&) {
208*583ba441SPatrick Williams return utils::transform(triggerActions,
209*583ba441SPatrick Williams [](const auto& action) {
21094f71c51SSzymon Dompke return actionToString(action);
21194f71c51SSzymon Dompke });
21294f71c51SSzymon Dompke });
21376833cb5SWludzik, Jozef });
2141477fe6aSWludzik, Jozef
2151477fe6aSWludzik, Jozef for (const auto& threshold : thresholds)
2161477fe6aSWludzik, Jozef {
2171477fe6aSWludzik, Jozef threshold->initialize();
2181477fe6aSWludzik, Jozef }
219b4ef22e4SSzymon Dompke
220e6d48874SKrzysztof Grobelny messanger.on_receive<messages::CollectTriggerIdReq>(
__anon5e4599b81802(const auto& msg) 221e6d48874SKrzysztof Grobelny [this](const auto& msg) {
222e6d48874SKrzysztof Grobelny if (utils::contains(*reportIds, msg.reportId))
223b4ef22e4SSzymon Dompke {
224b7b7e1b6SSzymon Dompke messanger.send(messages::CollectTriggerIdResp{*id});
225b4ef22e4SSzymon Dompke }
226e6d48874SKrzysztof Grobelny });
227e6d48874SKrzysztof Grobelny
228e6d48874SKrzysztof Grobelny messanger.send(messages::TriggerPresenceChangedInd{
229b7b7e1b6SSzymon Dompke messages::Presence::Exist, *id, *reportIds});
23076833cb5SWludzik, Jozef }
231a4e67616SCezary Zwolak
storeConfiguration() const232a4e67616SCezary Zwolak bool Trigger::storeConfiguration() const
233a4e67616SCezary Zwolak {
234a4e67616SCezary Zwolak try
235a4e67616SCezary Zwolak {
236a4e67616SCezary Zwolak nlohmann::json data;
237a4e67616SCezary Zwolak
23894f71c51SSzymon Dompke auto labeledThresholdParams =
23994f71c51SSzymon Dompke std::visit(utils::ToLabeledThresholdParamConversion(),
24055824558SKrzysztof Grobelny fromLabeledThresholdParam(getLabeledThresholds()));
24194f71c51SSzymon Dompke
242a4e67616SCezary Zwolak data["Version"] = triggerVersion;
243b7b7e1b6SSzymon Dompke data["Id"] = *id;
244a4e67616SCezary Zwolak data["Name"] = name;
2454416fce6SCezary Zwolak data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
246*583ba441SPatrick Williams data["TriggerActions"] =
247*583ba441SPatrick Williams utils::transform(triggerActions, [](const auto& action) {
248*583ba441SPatrick Williams return actionToString(action);
249*583ba441SPatrick Williams });
250a4e67616SCezary Zwolak data["ThresholdParams"] =
2514416fce6SCezary Zwolak utils::labeledThresholdParamsToJson(labeledThresholdParams);
25294f71c51SSzymon Dompke data["ReportIds"] = *reportIds;
25355824558SKrzysztof Grobelny data["Sensors"] = getLabeledSensorInfo();
254a4e67616SCezary Zwolak
255a4e67616SCezary Zwolak triggerStorage.store(fileName, data);
256a4e67616SCezary Zwolak }
257a4e67616SCezary Zwolak catch (const std::exception& e)
258a4e67616SCezary Zwolak {
259a4e67616SCezary Zwolak phosphor::logging::log<phosphor::logging::level::ERR>(
260a4e67616SCezary Zwolak "Failed to store a trigger in storage",
261a4e67616SCezary Zwolak phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
262a4e67616SCezary Zwolak return false;
263a4e67616SCezary Zwolak }
264a4e67616SCezary Zwolak return true;
265a4e67616SCezary Zwolak }
26655824558SKrzysztof Grobelny
getLabeledSensorInfo() const26755824558SKrzysztof Grobelny std::vector<LabeledSensorInfo> Trigger::getLabeledSensorInfo() const
26855824558SKrzysztof Grobelny {
26955824558SKrzysztof Grobelny return utils::transform(sensors, [](const auto& sensor) {
27055824558SKrzysztof Grobelny return sensor->getLabeledSensorInfo();
27155824558SKrzysztof Grobelny });
27255824558SKrzysztof Grobelny }
27355824558SKrzysztof Grobelny
getLabeledThresholds() const27455824558SKrzysztof Grobelny std::vector<LabeledThresholdParam> Trigger::getLabeledThresholds() const
27555824558SKrzysztof Grobelny {
27655824558SKrzysztof Grobelny return utils::transform(thresholds, [](const auto& threshold) {
27755824558SKrzysztof Grobelny return threshold->getThresholdParam();
27855824558SKrzysztof Grobelny });
27955824558SKrzysztof Grobelny }
28055824558SKrzysztof Grobelny
isDiscreate() const28155824558SKrzysztof Grobelny bool Trigger::isDiscreate() const
28255824558SKrzysztof Grobelny {
28355824558SKrzysztof Grobelny const auto labeledThresholds = getLabeledThresholds();
28455824558SKrzysztof Grobelny
28555824558SKrzysztof Grobelny return utils::isFirstElementOfType<std::monostate>(labeledThresholds) ||
28655824558SKrzysztof Grobelny utils::isFirstElementOfType<discrete::LabeledThresholdParam>(
28755824558SKrzysztof Grobelny labeledThresholds);
28855824558SKrzysztof Grobelny }
289