#include "event_parser.hpp" #include #include #include #include #include PHOSPHOR_LOG2_USING; namespace pldm::responder::events { namespace fs = std::filesystem; using InternalFailure = sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; const Json emptyJson{}; const std::vector emptyJsonList{}; const std::set supportedDbusPropertyTypes = { "bool", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t", "double", "string"}; StateSensorHandler::StateSensorHandler(const std::string& dirPath) { fs::path dir(dirPath); if (!fs::exists(dir) || fs::is_empty(dir)) { error("Event config directory does not exist or empty, DIR={DIR_PATH}", "DIR_PATH", dirPath.c_str()); return; } for (auto& file : fs::directory_iterator(dirPath)) { std::ifstream jsonFile(file.path()); auto data = Json::parse(jsonFile, nullptr, false); if (data.is_discarded()) { error( "Parsing Event state sensor JSON file failed, FILE={FILE_PATH}", "FILE_PATH", file.path().c_str()); continue; } auto entries = data.value("entries", emptyJsonList); for (const auto& entry : entries) { StateSensorEntry stateSensorEntry{}; stateSensorEntry.containerId = static_cast(entry.value("containerID", 0)); stateSensorEntry.entityType = static_cast(entry.value("entityType", 0)); stateSensorEntry.entityInstance = static_cast(entry.value("entityInstance", 0)); stateSensorEntry.sensorOffset = static_cast(entry.value("sensorOffset", 0)); stateSensorEntry.stateSetid = static_cast(entry.value("stateSetId", 0)); pldm::utils::DBusMapping dbusInfo{}; auto dbus = entry.value("dbus", emptyJson); dbusInfo.objectPath = dbus.value("object_path", ""); dbusInfo.interface = dbus.value("interface", ""); dbusInfo.propertyName = dbus.value("property_name", ""); dbusInfo.propertyType = dbus.value("property_type", ""); if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() || dbusInfo.propertyName.empty() || !supportedDbusPropertyTypes.contains(dbusInfo.propertyType)) { error( "Invalid dbus config, OBJPATH= {DBUS_OBJ_PATH} INTERFACE={DBUS_INTF} PROPERTY_NAME={DBUS_PROP} PROPERTY_TYPE={DBUS_PROP_TYPE}", "DBUS_OBJ_PATH", dbusInfo.objectPath.c_str(), "DBUS_INTF", dbusInfo.interface, "DBUS_PROP", dbusInfo.propertyName, "DBUS_PROP_TYPE", dbusInfo.propertyType); continue; } auto eventStates = entry.value("event_states", emptyJsonList); auto propertyValues = dbus.value("property_values", emptyJsonList); if ((eventStates.size() == 0) || (propertyValues.size() == 0) || (eventStates.size() != propertyValues.size())) { error( "Invalid event state JSON config, EVENT_STATE_SIZE={EVENT_STATE_SIZE} PROPERTY_VALUE_SIZE={PROP_VAL_SIZE}", "EVENT_STATE_SIZE", eventStates.size(), "PROP_VAL_SIZE", propertyValues.size()); continue; } auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues, dbusInfo.propertyType); eventMap.emplace( stateSensorEntry, std::make_tuple(std::move(dbusInfo), std::move(eventStateMap))); } } } StateToDBusValue StateSensorHandler::mapStateToDBusVal( const Json& eventStates, const Json& propertyValues, std::string_view type) { StateToDBusValue eventStateMap{}; auto stateIt = eventStates.begin(); auto propIt = propertyValues.begin(); for (; stateIt != eventStates.end(); ++stateIt, ++propIt) { auto propValue = utils::jsonEntryToDbusVal(type, propIt.value()); eventStateMap.emplace((*stateIt).get(), std::move(propValue)); } return eventStateMap; } int StateSensorHandler::eventAction(const StateSensorEntry& entry, pdr::EventState state) { try { const auto& [dbusMapping, eventStateMap] = eventMap.at(entry); utils::PropertyValue propValue{}; try { propValue = eventStateMap.at(state); } catch (const std::out_of_range& e) { error("Invalid event state '{EVENT_STATE}': {ERROR}", "EVENT_STATE", state, "ERROR", e); return PLDM_ERROR_INVALID_DATA; } try { pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue); } catch (const std::exception& e) { error( "Error setting property value '{PROPERTY}' on interface '{INTERFACE}' at '{PATH}': {ERROR}", "PROPERTY", dbusMapping.propertyName, "INTERFACE", dbusMapping.interface, "PATH", dbusMapping.objectPath, "ERROR", e); return PLDM_ERROR; } } catch (const std::out_of_range&) { // There is no BMC action for this PLDM event return PLDM_SUCCESS; } return PLDM_SUCCESS; } } // namespace pldm::responder::events