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