blob: e38102ccad15bb6e54c076748a09abe6c4266811 [file] [log] [blame]
TOM JOSEPHd4d97a52020-03-23 14:36:34 +05301#include "event_parser.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include <xyz/openbmc_project/Common/error.hpp>
4
TOM JOSEPHd4d97a52020-03-23 14:36:34 +05305#include <filesystem>
6#include <fstream>
7#include <iostream>
8#include <set>
TOM JOSEPHd4d97a52020-03-23 14:36:34 +05309
10namespace pldm::responder::events
11{
12
13namespace fs = std::filesystem;
14using InternalFailure =
15 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
16
17const Json emptyJson{};
18const std::vector<Json> emptyJsonList{};
19const std::vector<std::string> emptyStringVec{};
20
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053021const std::set<std::string_view> supportedDbusPropertyTypes = {
22 "bool", "uint8_t", "int16_t", "uint16_t", "int32_t",
23 "uint32_t", "int64_t", "uint64_t", "double", "string"};
24
25StateSensorHandler::StateSensorHandler(const std::string& dirPath)
26{
27 fs::path dir(dirPath);
28 if (!fs::exists(dir) || fs::is_empty(dir))
29 {
30 std::cerr << "Event config directory does not exist or empty, DIR="
31 << dirPath << "\n";
32 return;
33 }
34
Tom Josepha792b212020-08-12 10:48:26 +053035 for (auto& file : fs::directory_iterator(dirPath))
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053036 {
Tom Josepha792b212020-08-12 10:48:26 +053037 std::ifstream jsonFile(file.path());
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053038
Tom Josepha792b212020-08-12 10:48:26 +053039 auto data = Json::parse(jsonFile, nullptr, false);
40 if (data.is_discarded())
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053041 {
Tom Josepha792b212020-08-12 10:48:26 +053042 std::cerr << "Parsing Event state sensor JSON file failed, FILE="
43 << file.path();
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053044 continue;
45 }
46
Tom Josepha792b212020-08-12 10:48:26 +053047 auto entries = data.value("entries", emptyJsonList);
48 for (const auto& entry : entries)
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053049 {
Tom Josepha792b212020-08-12 10:48:26 +053050 StateSensorEntry stateSensorEntry{};
51 stateSensorEntry.containerId =
52 static_cast<uint16_t>(entry.value("containerID", 0));
53 stateSensorEntry.entityType =
54 static_cast<uint16_t>(entry.value("entityType", 0));
55 stateSensorEntry.entityInstance =
56 static_cast<uint16_t>(entry.value("entityInstance", 0));
57 stateSensorEntry.sensorOffset =
58 static_cast<uint8_t>(entry.value("sensorOffset", 0));
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053059
Tom Josepha792b212020-08-12 10:48:26 +053060 pldm::utils::DBusMapping dbusInfo{};
61
62 auto dbus = entry.value("dbus", emptyJson);
63 dbusInfo.objectPath = dbus.value("object_path", "");
64 dbusInfo.interface = dbus.value("interface", "");
65 dbusInfo.propertyName = dbus.value("property_name", "");
66 dbusInfo.propertyType = dbus.value("property_type", "");
67 if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() ||
68 dbusInfo.propertyName.empty() ||
69 (supportedDbusPropertyTypes.find(dbusInfo.propertyType) ==
70 supportedDbusPropertyTypes.end()))
71 {
72 std::cerr << "Invalid dbus config,"
73 << " OBJPATH=" << dbusInfo.objectPath << " INTERFACE="
74 << dbusInfo.interface << " PROPERTY_NAME="
75 << dbusInfo.propertyName
76 << " PROPERTY_TYPE=" << dbusInfo.propertyType << "\n";
77 continue;
78 }
79
80 auto eventStates = entry.value("event_states", emptyJsonList);
81 auto propertyValues = dbus.value("property_values", emptyJsonList);
82 if ((eventStates.size() == 0) || (propertyValues.size() == 0) ||
83 (eventStates.size() != propertyValues.size()))
84 {
85 std::cerr << "Invalid event state JSON config,"
86 << " EVENT_STATE_SIZE=" << eventStates.size()
87 << " PROPERTY_VALUE_SIZE=" << propertyValues.size()
88 << "\n";
89 continue;
90 }
91
92 auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues,
93 dbusInfo.propertyType);
94 eventMap.emplace(
95 stateSensorEntry,
96 std::make_tuple(std::move(dbusInfo), std::move(eventStateMap)));
97 }
TOM JOSEPHd4d97a52020-03-23 14:36:34 +053098 }
99}
100
101StateToDBusValue StateSensorHandler::mapStateToDBusVal(
102 const Json& eventStates, const Json& propertyValues, std::string_view type)
103{
104 StateToDBusValue eventStateMap{};
105 auto stateIt = eventStates.begin();
106 auto propIt = propertyValues.begin();
107
108 for (; stateIt != eventStates.end(); ++stateIt, ++propIt)
109 {
110 auto propValue = utils::jsonEntryToDbusVal(type, propIt.value());
111 eventStateMap.emplace((*stateIt).get<uint8_t>(), std::move(propValue));
112 }
113
114 return eventStateMap;
115}
116
117int StateSensorHandler::eventAction(const StateSensorEntry& entry,
118 pdr::EventState state)
119{
120 try
121 {
122 const auto& [dbusMapping, eventStateMap] = eventMap.at(entry);
123 utils::PropertyValue propValue{};
124 try
125 {
126 propValue = eventStateMap.at(state);
127 }
128 catch (const std::out_of_range& e)
129 {
130 std::cerr << "Invalid event state" << static_cast<unsigned>(state)
131 << '\n';
132 return PLDM_ERROR_INVALID_DATA;
133 }
134
135 try
136 {
137 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue);
138 }
139 catch (const std::exception& e)
140 {
141 std::cerr << "Error setting property, ERROR=" << e.what()
142 << " PROPERTY=" << dbusMapping.propertyName
143 << " INTERFACE=" << dbusMapping.interface << " PATH="
144 << dbusMapping.objectPath << "\n";
145 return PLDM_ERROR;
146 }
147 }
148 catch (const std::out_of_range& e)
149 {
150 // There is no BMC action for this PLDM event
151 return PLDM_SUCCESS;
152 }
153 return PLDM_SUCCESS;
154}
155
156} // namespace pldm::responder::events