1d4d97a53STOM JOSEPH #include "event_parser.hpp"
2d4d97a53STOM JOSEPH 
349cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp>
46492f524SGeorge Liu #include <xyz/openbmc_project/Common/error.hpp>
56492f524SGeorge Liu 
6d4d97a53STOM JOSEPH #include <filesystem>
7d4d97a53STOM JOSEPH #include <fstream>
8d4d97a53STOM JOSEPH #include <set>
9d4d97a53STOM JOSEPH 
1049cfb138SRiya Dixit PHOSPHOR_LOG2_USING;
1149cfb138SRiya Dixit 
12d4d97a53STOM JOSEPH namespace pldm::responder::events
13d4d97a53STOM JOSEPH {
14d4d97a53STOM JOSEPH namespace fs = std::filesystem;
15d4d97a53STOM JOSEPH using InternalFailure =
16d4d97a53STOM JOSEPH     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
17d4d97a53STOM JOSEPH 
18d4d97a53STOM JOSEPH const Json emptyJson{};
19d4d97a53STOM JOSEPH const std::vector<Json> emptyJsonList{};
20d4d97a53STOM JOSEPH 
21d4d97a53STOM JOSEPH const std::set<std::string_view> supportedDbusPropertyTypes = {
22d4d97a53STOM JOSEPH     "bool",     "uint8_t", "int16_t",  "uint16_t", "int32_t",
23d4d97a53STOM JOSEPH     "uint32_t", "int64_t", "uint64_t", "double",   "string"};
24d4d97a53STOM JOSEPH 
25d4d97a53STOM JOSEPH StateSensorHandler::StateSensorHandler(const std::string& dirPath)
26d4d97a53STOM JOSEPH {
27d4d97a53STOM JOSEPH     fs::path dir(dirPath);
28d4d97a53STOM JOSEPH     if (!fs::exists(dir) || fs::is_empty(dir))
29d4d97a53STOM JOSEPH     {
3049cfb138SRiya Dixit         error("Event config directory does not exist or empty, DIR={DIR_PATH}",
3149cfb138SRiya Dixit               "DIR_PATH", dirPath.c_str());
32d4d97a53STOM JOSEPH         return;
33d4d97a53STOM JOSEPH     }
34d4d97a53STOM JOSEPH 
35a792b216STom Joseph     for (auto& file : fs::directory_iterator(dirPath))
36d4d97a53STOM JOSEPH     {
37a792b216STom Joseph         std::ifstream jsonFile(file.path());
38d4d97a53STOM JOSEPH 
39d4d97a53STOM JOSEPH         auto data = Json::parse(jsonFile, nullptr, false);
40d4d97a53STOM JOSEPH         if (data.is_discarded())
41d4d97a53STOM JOSEPH         {
4249cfb138SRiya Dixit             error(
4349cfb138SRiya Dixit                 "Parsing Event state sensor JSON file failed, FILE={FILE_PATH}",
4449cfb138SRiya Dixit                 "FILE_PATH", file.path().c_str());
45a792b216STom Joseph             continue;
46d4d97a53STOM JOSEPH         }
47d4d97a53STOM JOSEPH 
48d4d97a53STOM JOSEPH         auto entries = data.value("entries", emptyJsonList);
49d4d97a53STOM JOSEPH         for (const auto& entry : entries)
50d4d97a53STOM JOSEPH         {
51d4d97a53STOM JOSEPH             StateSensorEntry stateSensorEntry{};
52d4d97a53STOM JOSEPH             stateSensorEntry.containerId =
53d4d97a53STOM JOSEPH                 static_cast<uint16_t>(entry.value("containerID", 0));
54d4d97a53STOM JOSEPH             stateSensorEntry.entityType =
55d4d97a53STOM JOSEPH                 static_cast<uint16_t>(entry.value("entityType", 0));
56d4d97a53STOM JOSEPH             stateSensorEntry.entityInstance =
57d4d97a53STOM JOSEPH                 static_cast<uint16_t>(entry.value("entityInstance", 0));
58d4d97a53STOM JOSEPH             stateSensorEntry.sensorOffset =
59d4d97a53STOM JOSEPH                 static_cast<uint8_t>(entry.value("sensorOffset", 0));
60e3607a3cSSagar Srinivas             stateSensorEntry.stateSetid =
61e3607a3cSSagar Srinivas                 static_cast<uint16_t>(entry.value("stateSetId", 0));
62d4d97a53STOM JOSEPH 
63d4d97a53STOM JOSEPH             pldm::utils::DBusMapping dbusInfo{};
64d4d97a53STOM JOSEPH 
65d4d97a53STOM JOSEPH             auto dbus = entry.value("dbus", emptyJson);
66d4d97a53STOM JOSEPH             dbusInfo.objectPath = dbus.value("object_path", "");
67d4d97a53STOM JOSEPH             dbusInfo.interface = dbus.value("interface", "");
68d4d97a53STOM JOSEPH             dbusInfo.propertyName = dbus.value("property_name", "");
69d4d97a53STOM JOSEPH             dbusInfo.propertyType = dbus.value("property_type", "");
70d4d97a53STOM JOSEPH             if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() ||
71d4d97a53STOM JOSEPH                 dbusInfo.propertyName.empty() ||
72*06f9b29eSSagar Srinivas                 !supportedDbusPropertyTypes.contains(dbusInfo.propertyType))
73d4d97a53STOM JOSEPH             {
7449cfb138SRiya Dixit                 error(
7549cfb138SRiya Dixit                     "Invalid dbus config, OBJPATH= {DBUS_OBJ_PATH} INTERFACE={DBUS_INTF} PROPERTY_NAME={DBUS_PROP} PROPERTY_TYPE={DBUS_PROP_TYPE}",
7649cfb138SRiya Dixit                     "DBUS_OBJ_PATH", dbusInfo.objectPath.c_str(), "DBUS_INTF",
7749cfb138SRiya Dixit                     dbusInfo.interface, "DBUS_PROP", dbusInfo.propertyName,
7849cfb138SRiya Dixit                     "DBUS_PROP_TYPE", dbusInfo.propertyType);
79d4d97a53STOM JOSEPH                 continue;
80d4d97a53STOM JOSEPH             }
81d4d97a53STOM JOSEPH 
82d4d97a53STOM JOSEPH             auto eventStates = entry.value("event_states", emptyJsonList);
83d4d97a53STOM JOSEPH             auto propertyValues = dbus.value("property_values", emptyJsonList);
84d4d97a53STOM JOSEPH             if ((eventStates.size() == 0) || (propertyValues.size() == 0) ||
85d4d97a53STOM JOSEPH                 (eventStates.size() != propertyValues.size()))
86d4d97a53STOM JOSEPH             {
8749cfb138SRiya Dixit                 error(
8849cfb138SRiya Dixit                     "Invalid event state JSON config, EVENT_STATE_SIZE={EVENT_STATE_SIZE} PROPERTY_VALUE_SIZE={PROP_VAL_SIZE}",
8949cfb138SRiya Dixit                     "EVENT_STATE_SIZE", eventStates.size(), "PROP_VAL_SIZE",
9049cfb138SRiya Dixit                     propertyValues.size());
91d4d97a53STOM JOSEPH                 continue;
92d4d97a53STOM JOSEPH             }
93d4d97a53STOM JOSEPH 
94d4d97a53STOM JOSEPH             auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues,
95d4d97a53STOM JOSEPH                                                    dbusInfo.propertyType);
96d4d97a53STOM JOSEPH             eventMap.emplace(
97d4d97a53STOM JOSEPH                 stateSensorEntry,
98d4d97a53STOM JOSEPH                 std::make_tuple(std::move(dbusInfo), std::move(eventStateMap)));
99d4d97a53STOM JOSEPH         }
100d4d97a53STOM JOSEPH     }
101a792b216STom Joseph }
102d4d97a53STOM JOSEPH 
103d4d97a53STOM JOSEPH StateToDBusValue StateSensorHandler::mapStateToDBusVal(
104d4d97a53STOM JOSEPH     const Json& eventStates, const Json& propertyValues, std::string_view type)
105d4d97a53STOM JOSEPH {
106d4d97a53STOM JOSEPH     StateToDBusValue eventStateMap{};
107d4d97a53STOM JOSEPH     auto stateIt = eventStates.begin();
108d4d97a53STOM JOSEPH     auto propIt = propertyValues.begin();
109d4d97a53STOM JOSEPH 
110d4d97a53STOM JOSEPH     for (; stateIt != eventStates.end(); ++stateIt, ++propIt)
111d4d97a53STOM JOSEPH     {
112d4d97a53STOM JOSEPH         auto propValue = utils::jsonEntryToDbusVal(type, propIt.value());
113d4d97a53STOM JOSEPH         eventStateMap.emplace((*stateIt).get<uint8_t>(), std::move(propValue));
114d4d97a53STOM JOSEPH     }
115d4d97a53STOM JOSEPH 
116d4d97a53STOM JOSEPH     return eventStateMap;
117d4d97a53STOM JOSEPH }
118d4d97a53STOM JOSEPH 
119d4d97a53STOM JOSEPH int StateSensorHandler::eventAction(const StateSensorEntry& entry,
120d4d97a53STOM JOSEPH                                     pdr::EventState state)
121d4d97a53STOM JOSEPH {
122d4d97a53STOM JOSEPH     try
123d4d97a53STOM JOSEPH     {
124d4d97a53STOM JOSEPH         const auto& [dbusMapping, eventStateMap] = eventMap.at(entry);
125d4d97a53STOM JOSEPH         utils::PropertyValue propValue{};
126d4d97a53STOM JOSEPH         try
127d4d97a53STOM JOSEPH         {
128d4d97a53STOM JOSEPH             propValue = eventStateMap.at(state);
129d4d97a53STOM JOSEPH         }
130d4d97a53STOM JOSEPH         catch (const std::out_of_range& e)
131d4d97a53STOM JOSEPH         {
13258cbcaf2SKamalkumar Patel             error("Invalid event state '{EVENT_STATE}': {ERROR}", "EVENT_STATE",
13358cbcaf2SKamalkumar Patel                   state, "ERROR", e);
134d4d97a53STOM JOSEPH             return PLDM_ERROR_INVALID_DATA;
135d4d97a53STOM JOSEPH         }
136d4d97a53STOM JOSEPH 
137d4d97a53STOM JOSEPH         try
138d4d97a53STOM JOSEPH         {
139d4d97a53STOM JOSEPH             pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue);
140d4d97a53STOM JOSEPH         }
141d4d97a53STOM JOSEPH         catch (const std::exception& e)
142d4d97a53STOM JOSEPH         {
14349cfb138SRiya Dixit             error(
14458cbcaf2SKamalkumar Patel                 "Error setting property value '{PROPERTY}' on interface '{INTERFACE}' at '{PATH}': {ERROR}",
14558cbcaf2SKamalkumar Patel                 "PROPERTY", dbusMapping.propertyName, "INTERFACE",
14658cbcaf2SKamalkumar Patel                 dbusMapping.interface, "PATH", dbusMapping.objectPath, "ERROR",
14758cbcaf2SKamalkumar Patel                 e);
148d4d97a53STOM JOSEPH             return PLDM_ERROR;
149d4d97a53STOM JOSEPH         }
150d4d97a53STOM JOSEPH     }
15158cbcaf2SKamalkumar Patel     catch (const std::out_of_range&)
152d4d97a53STOM JOSEPH     {
153d4d97a53STOM JOSEPH         // There is no BMC action for this PLDM event
154d4d97a53STOM JOSEPH         return PLDM_SUCCESS;
155d4d97a53STOM JOSEPH     }
156d4d97a53STOM JOSEPH     return PLDM_SUCCESS;
157d4d97a53STOM JOSEPH }
158d4d97a53STOM JOSEPH 
159d4d97a53STOM JOSEPH } // namespace pldm::responder::events
160