blob: 990ff7c1a6cb0b352d7ee8db09be02aef1668983 [file] [log] [blame]
Patrick Williams70a47ba2021-09-02 09:53:31 -05001#include "event_parser.hpp"
2
3#include <xyz/openbmc_project/Common/error.hpp>
4
5#include <filesystem>
6#include <fstream>
7#include <iostream>
8#include <set>
9
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
21const 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
35 for (auto& file : fs::directory_iterator(dirPath))
36 {
37 std::ifstream jsonFile(file.path());
38
39 auto data = Json::parse(jsonFile, nullptr, false);
40 if (data.is_discarded())
41 {
42 std::cerr << "Parsing Event state sensor JSON file failed, FILE="
43 << file.path();
44 continue;
45 }
46
47 auto entries = data.value("entries", emptyJsonList);
48 for (const auto& entry : entries)
49 {
50 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));
59
60 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 }
98 }
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
TOM JOSEPHd4d97a52020-03-23 14:36:34 +0530156} // namespace pldm::responder::events