blob: 894c0aacef917a1837f4e11fe1365ff19e9b7e2a [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
21constexpr auto eventStateSensorJson = "event_state_sensor.json";
22
23const std::set<std::string_view> supportedDbusPropertyTypes = {
24 "bool", "uint8_t", "int16_t", "uint16_t", "int32_t",
25 "uint32_t", "int64_t", "uint64_t", "double", "string"};
26
27StateSensorHandler::StateSensorHandler(const std::string& dirPath)
28{
29 fs::path dir(dirPath);
30 if (!fs::exists(dir) || fs::is_empty(dir))
31 {
32 std::cerr << "Event config directory does not exist or empty, DIR="
33 << dirPath << "\n";
34 return;
35 }
36
37 fs::path filePath = dir / eventStateSensorJson;
38 if (!fs::exists(filePath))
39 {
40 std::cerr << "Event state sensor JSON does not exist, PATH=" << filePath
41 << "\n";
42 throw InternalFailure();
43 }
44
45 std::ifstream jsonFile(filePath);
46
47 auto data = Json::parse(jsonFile, nullptr, false);
48 if (data.is_discarded())
49 {
50 std::cerr << "Parsing Event state sensor JSON file failed, FILE="
51 << filePath;
52 throw InternalFailure();
53 }
54
55 auto entries = data.value("entries", emptyJsonList);
56 for (const auto& entry : entries)
57 {
58 StateSensorEntry stateSensorEntry{};
59 stateSensorEntry.containerId =
60 static_cast<uint16_t>(entry.value("containerID", 0));
61 stateSensorEntry.entityType =
62 static_cast<uint16_t>(entry.value("entityType", 0));
63 stateSensorEntry.entityInstance =
64 static_cast<uint16_t>(entry.value("entityInstance", 0));
65 stateSensorEntry.sensorOffset =
66 static_cast<uint8_t>(entry.value("sensorOffset", 0));
67
68 pldm::utils::DBusMapping dbusInfo{};
69
70 auto dbus = entry.value("dbus", emptyJson);
71 dbusInfo.objectPath = dbus.value("object_path", "");
72 dbusInfo.interface = dbus.value("interface", "");
73 dbusInfo.propertyName = dbus.value("property_name", "");
74 dbusInfo.propertyType = dbus.value("property_type", "");
75 if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() ||
76 dbusInfo.propertyName.empty() ||
77 (supportedDbusPropertyTypes.find(dbusInfo.propertyType) ==
78 supportedDbusPropertyTypes.end()))
79 {
80 std::cerr << "Invalid dbus config,"
81 << " OBJPATH=" << dbusInfo.objectPath << " INTERFACE="
82 << dbusInfo.interface << " PROPERTY_NAME="
83 << dbusInfo.propertyName
84 << " PROPERTY_TYPE=" << dbusInfo.propertyType << "\n";
85 continue;
86 }
87
88 auto eventStates = entry.value("event_states", emptyJsonList);
89 auto propertyValues = dbus.value("property_values", emptyJsonList);
90 if ((eventStates.size() == 0) || (propertyValues.size() == 0) ||
91 (eventStates.size() != propertyValues.size()))
92 {
93 std::cerr << "Invalid event state JSON config,"
94 << " EVENT_STATE_SIZE=" << eventStates.size()
95 << " PROPERTY_VALUE_SIZE=" << propertyValues.size()
96 << "\n";
97 continue;
98 }
99
100 auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues,
101 dbusInfo.propertyType);
102 eventMap.emplace(
103 stateSensorEntry,
104 std::make_tuple(std::move(dbusInfo), std::move(eventStateMap)));
105 }
106}
107
108StateToDBusValue StateSensorHandler::mapStateToDBusVal(
109 const Json& eventStates, const Json& propertyValues, std::string_view type)
110{
111 StateToDBusValue eventStateMap{};
112 auto stateIt = eventStates.begin();
113 auto propIt = propertyValues.begin();
114
115 for (; stateIt != eventStates.end(); ++stateIt, ++propIt)
116 {
117 auto propValue = utils::jsonEntryToDbusVal(type, propIt.value());
118 eventStateMap.emplace((*stateIt).get<uint8_t>(), std::move(propValue));
119 }
120
121 return eventStateMap;
122}
123
124int StateSensorHandler::eventAction(const StateSensorEntry& entry,
125 pdr::EventState state)
126{
127 try
128 {
129 const auto& [dbusMapping, eventStateMap] = eventMap.at(entry);
130 utils::PropertyValue propValue{};
131 try
132 {
133 propValue = eventStateMap.at(state);
134 }
135 catch (const std::out_of_range& e)
136 {
137 std::cerr << "Invalid event state" << static_cast<unsigned>(state)
138 << '\n';
139 return PLDM_ERROR_INVALID_DATA;
140 }
141
142 try
143 {
144 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue);
145 }
146 catch (const std::exception& e)
147 {
148 std::cerr << "Error setting property, ERROR=" << e.what()
149 << " PROPERTY=" << dbusMapping.propertyName
150 << " INTERFACE=" << dbusMapping.interface << " PATH="
151 << dbusMapping.objectPath << "\n";
152 return PLDM_ERROR;
153 }
154 }
155 catch (const std::out_of_range& e)
156 {
157 // There is no BMC action for this PLDM event
158 return PLDM_SUCCESS;
159 }
160 return PLDM_SUCCESS;
161}
162
163} // namespace pldm::responder::events