diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | selutility.cpp | 117 | ||||
-rw-r--r-- | selutility.hpp | 66 |
3 files changed, 185 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 7317cce..51e1519 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,7 +48,8 @@ libapphandler_la_SOURCES = \ sensor-gen.cpp \ utils.cpp \ inventory-sensor-gen.cpp \ - fru-read-gen.cpp + fru-read-gen.cpp \ + selutility.cpp libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -lstdc++fs -version-info 0:0:0 -shared libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) diff --git a/selutility.cpp b/selutility.cpp new file mode 100644 index 0000000..68226f1 --- /dev/null +++ b/selutility.cpp @@ -0,0 +1,117 @@ +#include <chrono> +#include <vector> +#include <phosphor-logging/elog-errors.hpp> +#include "host-ipmid/ipmid-api.h" +#include "xyz/openbmc_project/Common/error.hpp" +#include "selutility.hpp" +#include "types.hpp" +#include "utils.hpp" + +extern const ipmi::sensor::InvObjectIDMap invSensors; +using namespace phosphor::logging; +using InternalFailure = + sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; + +namespace ipmi +{ + +namespace sel +{ + +namespace internal +{ + +GetSELEntryResponse prepareSELEntry( + const std::string& objPath, + ipmi::sensor::InvObjectIDMap::const_iterator iter) +{ + ipmi::sel::GetSELEntryResponse record {}; + + sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; + auto service = ipmi::getService(bus, logEntryIntf, objPath); + + // Read all the log entry properties. + auto methodCall = bus.new_method_call(service.c_str(), + objPath.c_str(), + propIntf, + "GetAll"); + methodCall.append(logEntryIntf); + + auto reply = bus.call(methodCall); + if (reply.is_method_error()) + { + log<level::ERR>("Error in reading logging property entries"); + elog<InternalFailure>(); + } + + std::map<std::string, PropertyType> entryData; + reply.read(entryData); + + // Read Id from the log entry. + static constexpr auto propId = "Id"; + auto iterId = entryData.find(propId); + if (iterId == entryData.end()) + { + log<level::ERR>("Error in reading Id of logging entry"); + elog<InternalFailure>(); + } + + record.recordID = static_cast<uint16_t>( + sdbusplus::message::variant_ns::get<uint32_t>(iterId->second)); + + // Read Timestamp from the log entry. + static constexpr auto propTimeStamp = "Timestamp"; + auto iterTimeStamp = entryData.find(propTimeStamp); + if (iterTimeStamp == entryData.end()) + { + log<level::ERR>("Error in reading Timestamp of logging entry"); + elog<InternalFailure>(); + } + + std::chrono::milliseconds chronoTimeStamp( + sdbusplus::message::variant_ns::get<uint64_t> + (iterTimeStamp->second)); + record.timeStamp = static_cast<uint32_t>(std::chrono::duration_cast< + std::chrono::seconds>(chronoTimeStamp).count()); + + static constexpr auto systemEventRecord = 0x02; + static constexpr auto generatorID = 0x2000; + static constexpr auto eventMsgRevision = 0x04; + + record.recordType = systemEventRecord; + record.generatorID = generatorID; + record.eventMsgRevision = eventMsgRevision; + + record.sensorType = iter->second.sensorType; + record.sensorNum = iter->second.sensorID; + record.eventData1 = iter->second.eventOffset; + + // Read Resolved from the log entry. + static constexpr auto propResolved = "Resolved"; + auto iterResolved = entryData.find(propResolved); + if (iterResolved == entryData.end()) + { + log<level::ERR>("Error in reading Resolved field of logging entry"); + elog<InternalFailure>(); + } + + static constexpr auto deassertEvent = 0x80; + + // Evaluate if the event is assertion or deassertion event + if (sdbusplus::message::variant_ns::get<bool>(iterResolved->second)) + { + record.eventType = deassertEvent | iter->second.eventReadingType; + } + else + { + record.eventType = iter->second.eventReadingType; + } + + return record; +} + +} // namespace internal + +} // namespace sel + +} // namespace ipmi diff --git a/selutility.hpp b/selutility.hpp new file mode 100644 index 0000000..83ff0fd --- /dev/null +++ b/selutility.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include <cstdint> +#include <sdbusplus/server.hpp> +#include "types.hpp" + +namespace ipmi +{ + +namespace sel +{ + +static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper"; +static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper"; +static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; + +static constexpr auto logBasePath = "/xyz/openbmc_project/logging/entry"; +static constexpr auto logEntryIntf = "xyz.openbmc_project.Logging.Entry"; +static constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete"; + +static constexpr auto propIntf = "org.freedesktop.DBus.Properties"; + +using PropertyType = sdbusplus::message::variant<bool, uint32_t, uint64_t, + std::string, std::vector<std::string>>; + +/** @struct GetSELEntryResponse + * + * IPMI payload for Get SEL Entry command response. + */ +struct GetSELEntryResponse +{ + uint16_t nextRecordID; //!< Next RecordID. + uint16_t recordID; //!< Record ID. + uint8_t recordType; //!< Record Type. + uint32_t timeStamp; //!< Timestamp. + uint16_t generatorID; //!< Generator ID. + uint8_t eventMsgRevision; //!< Event Message Revision. + uint8_t sensorType; //!< Sensor Type. + uint8_t sensorNum; //!< Sensor Number. + uint8_t eventType; //!< Event Dir | Event Type. + uint8_t eventData1; //!< Event Data 1. + uint8_t eventData2; //!< Event Data 2. + uint8_t eventData3; //!< Event Data 3. +} __attribute__((packed)); + +namespace internal +{ + +/** @brief Convert logging entry to SEL event record + * + * @param[in] objPath - DBUS object path of the logging entry. + * @param[in] iter - Iterator to the sensor data corresponding to the logging + * entry + * + * @return On success return the SEL event record, throw an exception in case + * of failure. + */ +GetSELEntryResponse prepareSELEntry( + const std::string& objPath, + ipmi::sensor::InvObjectIDMap::const_iterator iter); + +} //internal + +} // namespace sel + +} // namespace ipmi |