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