blob: d07075872c7c0125a947d6e4eba5555f8c2cdcc3 [file] [log] [blame]
Patrick Williams70a47ba2021-09-02 09:53:31 -05001#include "event_parser.hpp"
2
Riya Dixit49cfb132023-03-02 04:26:53 -06003#include <phosphor-logging/lg2.hpp>
Patrick Williams70a47ba2021-09-02 09:53:31 -05004#include <xyz/openbmc_project/Common/error.hpp>
5
6#include <filesystem>
7#include <fstream>
8#include <iostream>
9#include <set>
10
Riya Dixit49cfb132023-03-02 04:26:53 -060011PHOSPHOR_LOG2_USING;
12
Patrick Williams70a47ba2021-09-02 09:53:31 -050013namespace pldm::responder::events
14{
Patrick Williams70a47ba2021-09-02 09:53:31 -050015namespace fs = std::filesystem;
16using InternalFailure =
17 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
18
19const Json emptyJson{};
20const std::vector<Json> emptyJsonList{};
Patrick Williams70a47ba2021-09-02 09:53:31 -050021
22const std::set<std::string_view> supportedDbusPropertyTypes = {
23 "bool", "uint8_t", "int16_t", "uint16_t", "int32_t",
24 "uint32_t", "int64_t", "uint64_t", "double", "string"};
25
26StateSensorHandler::StateSensorHandler(const std::string& dirPath)
27{
28 fs::path dir(dirPath);
29 if (!fs::exists(dir) || fs::is_empty(dir))
30 {
Riya Dixit49cfb132023-03-02 04:26:53 -060031 error("Event config directory does not exist or empty, DIR={DIR_PATH}",
32 "DIR_PATH", dirPath.c_str());
Patrick Williams70a47ba2021-09-02 09:53:31 -050033 return;
34 }
35
36 for (auto& file : fs::directory_iterator(dirPath))
37 {
38 std::ifstream jsonFile(file.path());
39
40 auto data = Json::parse(jsonFile, nullptr, false);
41 if (data.is_discarded())
42 {
Riya Dixit49cfb132023-03-02 04:26:53 -060043 error(
44 "Parsing Event state sensor JSON file failed, FILE={FILE_PATH}",
45 "FILE_PATH", file.path().c_str());
Patrick Williams70a47ba2021-09-02 09:53:31 -050046 continue;
47 }
48
49 auto entries = data.value("entries", emptyJsonList);
50 for (const auto& entry : entries)
51 {
52 StateSensorEntry stateSensorEntry{};
53 stateSensorEntry.containerId =
54 static_cast<uint16_t>(entry.value("containerID", 0));
55 stateSensorEntry.entityType =
56 static_cast<uint16_t>(entry.value("entityType", 0));
57 stateSensorEntry.entityInstance =
58 static_cast<uint16_t>(entry.value("entityInstance", 0));
59 stateSensorEntry.sensorOffset =
60 static_cast<uint8_t>(entry.value("sensorOffset", 0));
61
62 pldm::utils::DBusMapping dbusInfo{};
63
64 auto dbus = entry.value("dbus", emptyJson);
65 dbusInfo.objectPath = dbus.value("object_path", "");
66 dbusInfo.interface = dbus.value("interface", "");
67 dbusInfo.propertyName = dbus.value("property_name", "");
68 dbusInfo.propertyType = dbus.value("property_type", "");
69 if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() ||
70 dbusInfo.propertyName.empty() ||
71 (supportedDbusPropertyTypes.find(dbusInfo.propertyType) ==
72 supportedDbusPropertyTypes.end()))
73 {
Riya Dixit49cfb132023-03-02 04:26:53 -060074 error(
75 "Invalid dbus config, OBJPATH= {DBUS_OBJ_PATH} INTERFACE={DBUS_INTF} PROPERTY_NAME={DBUS_PROP} PROPERTY_TYPE={DBUS_PROP_TYPE}",
76 "DBUS_OBJ_PATH", dbusInfo.objectPath.c_str(), "DBUS_INTF",
77 dbusInfo.interface, "DBUS_PROP", dbusInfo.propertyName,
78 "DBUS_PROP_TYPE", dbusInfo.propertyType);
Patrick Williams70a47ba2021-09-02 09:53:31 -050079 continue;
80 }
81
82 auto eventStates = entry.value("event_states", emptyJsonList);
83 auto propertyValues = dbus.value("property_values", emptyJsonList);
84 if ((eventStates.size() == 0) || (propertyValues.size() == 0) ||
85 (eventStates.size() != propertyValues.size()))
86 {
Riya Dixit49cfb132023-03-02 04:26:53 -060087 error(
88 "Invalid event state JSON config, EVENT_STATE_SIZE={EVENT_STATE_SIZE} PROPERTY_VALUE_SIZE={PROP_VAL_SIZE}",
89 "EVENT_STATE_SIZE", eventStates.size(), "PROP_VAL_SIZE",
90 propertyValues.size());
Patrick Williams70a47ba2021-09-02 09:53:31 -050091 continue;
92 }
93
94 auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues,
95 dbusInfo.propertyType);
96 eventMap.emplace(
97 stateSensorEntry,
98 std::make_tuple(std::move(dbusInfo), std::move(eventStateMap)));
99 }
100 }
101}
102
103StateToDBusValue StateSensorHandler::mapStateToDBusVal(
104 const Json& eventStates, const Json& propertyValues, std::string_view type)
105{
106 StateToDBusValue eventStateMap{};
107 auto stateIt = eventStates.begin();
108 auto propIt = propertyValues.begin();
109
110 for (; stateIt != eventStates.end(); ++stateIt, ++propIt)
111 {
112 auto propValue = utils::jsonEntryToDbusVal(type, propIt.value());
113 eventStateMap.emplace((*stateIt).get<uint8_t>(), std::move(propValue));
114 }
115
116 return eventStateMap;
117}
118
119int StateSensorHandler::eventAction(const StateSensorEntry& entry,
120 pdr::EventState state)
121{
122 try
123 {
124 const auto& [dbusMapping, eventStateMap] = eventMap.at(entry);
125 utils::PropertyValue propValue{};
126 try
127 {
128 propValue = eventStateMap.at(state);
129 }
130 catch (const std::out_of_range& e)
131 {
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500132 error("Invalid event state '{EVENT_STATE}': {ERROR}", "EVENT_STATE",
133 state, "ERROR", e);
Patrick Williams70a47ba2021-09-02 09:53:31 -0500134 return PLDM_ERROR_INVALID_DATA;
135 }
136
137 try
138 {
139 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue);
140 }
141 catch (const std::exception& e)
142 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600143 error(
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500144 "Error setting property value '{PROPERTY}' on interface '{INTERFACE}' at '{PATH}': {ERROR}",
145 "PROPERTY", dbusMapping.propertyName, "INTERFACE",
146 dbusMapping.interface, "PATH", dbusMapping.objectPath, "ERROR",
147 e);
Patrick Williams70a47ba2021-09-02 09:53:31 -0500148 return PLDM_ERROR;
149 }
150 }
Kamalkumar Patel58cbcaf2023-10-06 03:48:25 -0500151 catch (const std::out_of_range&)
Patrick Williams70a47ba2021-09-02 09:53:31 -0500152 {
153 // There is no BMC action for this PLDM event
154 return PLDM_SUCCESS;
155 }
156 return PLDM_SUCCESS;
157}
158
Riya Dixit49cfb132023-03-02 04:26:53 -0600159} // namespace pldm::responder::events