diff options
Diffstat (limited to 'dcmihandler.cpp')
-rw-r--r-- | dcmihandler.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp index 8b47845..3c77ed5 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -3,6 +3,7 @@ #include <phosphor-logging/elog-errors.hpp> #include <phosphor-logging/log.hpp> #include <sdbusplus/bus.hpp> +#include <nlohmann/json.hpp> #include "utils.hpp" #include <stdio.h> #include <string.h> @@ -11,6 +12,7 @@ #include <bitset> #include <cmath> #include "xyz/openbmc_project/Common/error.hpp" +#include "config.h" using namespace phosphor::logging; using InternalFailure = @@ -29,6 +31,10 @@ constexpr auto DCMI_SPEC_MAJOR_VERSION = 1; constexpr auto DCMI_SPEC_MINOR_VERSION = 5; constexpr auto DCMI_CAP_JSON_FILE = "/usr/share/ipmi-providers/dcmi_cap.json"; +constexpr auto SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value"; +constexpr auto SENSOR_VALUE_PROP = "Value"; +constexpr auto SENSOR_SCALE_PROP = "Scale"; + using namespace phosphor::logging; namespace dcmi @@ -1004,6 +1010,68 @@ ipmi_ret_t getTempReadings(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return IPMI_CC_OK; } +int64_t getPowerReading(sdbusplus::bus::bus& bus) +{ + std::ifstream sensorFile(POWER_READING_SENSOR); + std::string objectPath; + if (!sensorFile.is_open()) + { + log<level::ERR>("Power reading configuration file not found", + entry("POWER_SENSOR_FILE=%s", POWER_READING_SENSOR)); + elog<InternalFailure>(); + } + + auto data = nlohmann::json::parse(sensorFile, nullptr, false); + if (data.is_discarded()) + { + log<level::ERR>("Error in parsing configuration file", + entry("POWER_SENSOR_FILE=%s", POWER_READING_SENSOR)); + elog<InternalFailure>(); + } + + objectPath = data.value("path", ""); + if (objectPath.empty()) + { + log<level::ERR>("Power sensor D-Bus object path is empty", + entry("POWER_SENSOR_FILE=%s", POWER_READING_SENSOR)); + elog<InternalFailure>(); + } + + auto service = ipmi::getService(bus, SENSOR_VALUE_INTF, objectPath); + + //Read the sensor value and scale properties + auto properties = ipmi::getAllDbusProperties( + bus, service, objectPath, SENSOR_VALUE_INTF); + auto power = properties[SENSOR_VALUE_PROP].get<int64_t>(); + auto scale = properties[SENSOR_SCALE_PROP].get<int64_t>(); + + // Power reading needs to be scaled with the Scale value using the formula + // Value * 10^Scale. + power *= std::pow(10, scale); + + return power; +} + +ipmi_ret_t getPowerReading(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, ipmi_response_t response, + ipmi_data_len_t data_len, ipmi_context_t context) +{ + ipmi_ret_t rc = IPMI_CC_OK; + sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; + try + { + getPowerReading(bus); + } + catch (InternalFailure& e) + { + log<level::ERR>("Error in reading power sensor value", + entry("INTERFACE=%s", SENSOR_VALUE_INTF), + entry("PROPERTY=%s", SENSOR_VALUE_PROP)); + return IPMI_CC_UNSPECIFIED_ERROR; + } + return rc; +} + void register_netfn_dcmi_functions() { // <Get Power Limit> @@ -1062,6 +1130,9 @@ void register_netfn_dcmi_functions() ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_TEMP_READINGS, NULL, getTempReadings, PRIVILEGE_USER); + // <Get Power Reading> + ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_POWER_READING, + NULL, getPowerReading, PRIVILEGE_USER); return; } // 956379 |