platform-mc: sensor: Support none-telemetry base unit
As [1], The sensor D-Bus object path `/xyz/openbmc_project/sensors/` and
`xyz.openbmc_project.Sensor.Value` interface are only used for the
telemetry sensor types which are listed. The non-telemetry PLDM sensor
with the `baseUnit` type `count`, `corrected_errors`,
`uncorrected_errors` and `oemunit` are none-telemetry types and are not
belong to that list.
Those unit types are metric types which are count of somethings so the
metric D-Bus object path `/xyz/openbmc_project/metric/` and D-Bus
`xyz.openbmc_project.Metric.Value` should be used as [2]. Support
creating D-Bus object path and polling sensor values for the numeric
sensor/compact numeric sensor PDRs with the BaseUnit type is
none-telemetry.
[1] https://github.com/openbmc/phosphor-dbus-interfaces/blob/90cfce16584253a5f524c718ce5a6ae7c33f7b8c/yaml/xyz/openbmc_project/Sensor/Value.interface.yaml#L1
[2] https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Sensor/Value.interface.yaml
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: Iaf8d842e6ec0cb082b139d15da1a1bd10a701acf
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index 6b387dd..2f56bbf 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -28,6 +28,8 @@
sensorId = pdr->sensor_id;
std::string path;
SensorUnit sensorUnit = SensorUnit::DegreesC;
+ MetricUnit metricUnit = MetricUnit::Count;
+ useMetricInterface = false;
switch (pdr->base_unit)
{
@@ -59,6 +61,16 @@
sensorNameSpace = "/xyz/openbmc_project/sensors/utilization/";
sensorUnit = SensorUnit::Percent;
break;
+ case PLDM_SENSOR_UNIT_COUNTS:
+ case PLDM_SENSOR_UNIT_CORRECTED_ERRORS:
+ case PLDM_SENSOR_UNIT_UNCORRECTABLE_ERRORS:
+ sensorNameSpace = "/xyz/openbmc_project/metric/count/";
+ useMetricInterface = true;
+ break;
+ case PLDM_SENSOR_UNIT_OEMUNIT:
+ sensorNameSpace = "/xyz/openbmc_project/metric/oem/";
+ useMetricInterface = true;
+ break;
default:
lg2::error("Sensor {NAME} has Invalid baseUnit {UNIT}.", "NAME",
sensorName, "UNIT", pdr->base_unit);
@@ -70,9 +82,16 @@
path = sensorNameSpace + sensorName;
try
{
- auto service = pldm::utils::DBusHandler().getService(
- path.c_str(), "xyz.openbmc_project.Sensor.Value");
- if (!service.empty())
+ std::string tmp{};
+ std::string interface = SENSOR_VALUE_INTF;
+ if (useMetricInterface)
+ {
+ interface = METRIC_VALUE_INTF;
+ }
+ tmp = pldm::utils::DBusHandler().getService(path.c_str(),
+ interface.c_str());
+
+ if (!tmp.empty())
{
throw sdbusplus::xyz::openbmc_project::Common::Error::
TooManyResources();
@@ -275,21 +294,44 @@
updateTime = pdr->update_interval * 1000000;
}
- try
+ if (!useMetricInterface)
{
- valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
+ try
+ {
+ valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create Value interface for numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
+ valueIntf->minValue(unitModifier(conversionFormula(minValue)));
+ valueIntf->unit(sensorUnit);
}
- catch (const sdbusplus::exception_t& e)
+ else
{
- lg2::error(
- "Failed to create Value interface for numeric sensor {PATH} error - {ERROR}",
- "PATH", path, "ERROR", e);
- throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+ try
+ {
+ metricIntf = std::make_unique<MetricIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create Metric interface for numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ metricIntf->maxValue(unitModifier(conversionFormula(maxValue)));
+ metricIntf->minValue(unitModifier(conversionFormula(minValue)));
+ metricIntf->unit(metricUnit);
}
- valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
- valueIntf->minValue(unitModifier(conversionFormula(minValue)));
+
hysteresis = unitModifier(conversionFormula(hysteresis));
- valueIntf->unit(sensorUnit);
try
{
@@ -319,7 +361,7 @@
}
operationalStatusIntf->functional(!sensorDisabled);
- if (hasWarningThresholds)
+ if (hasWarningThresholds && !useMetricInterface)
{
try
{
@@ -338,7 +380,7 @@
thresholdWarningIntf->warningLow(unitModifier(warningLow));
}
- if (hasCriticalThresholds)
+ if (hasCriticalThresholds && !useMetricInterface)
{
try
{
@@ -372,6 +414,8 @@
sensorId = pdr->sensor_id;
std::string path;
SensorUnit sensorUnit = SensorUnit::DegreesC;
+ MetricUnit metricUnit = MetricUnit::Count;
+ useMetricInterface = false;
switch (pdr->base_unit)
{
@@ -403,6 +447,16 @@
sensorNameSpace = "/xyz/openbmc_project/sensors/utilization/";
sensorUnit = SensorUnit::Percent;
break;
+ case PLDM_SENSOR_UNIT_COUNTS:
+ case PLDM_SENSOR_UNIT_CORRECTED_ERRORS:
+ case PLDM_SENSOR_UNIT_UNCORRECTABLE_ERRORS:
+ sensorNameSpace = "/xyz/openbmc_project/metric/count/";
+ useMetricInterface = true;
+ break;
+ case PLDM_SENSOR_UNIT_OEMUNIT:
+ sensorNameSpace = "/xyz/openbmc_project/metric/oem/";
+ useMetricInterface = true;
+ break;
default:
lg2::error("Sensor {NAME} has Invalid baseUnit {UNIT}.", "NAME",
sensorName, "UNIT", pdr->base_unit);
@@ -414,9 +468,16 @@
path = sensorNameSpace + sensorName;
try
{
- auto service = pldm::utils::DBusHandler().getService(
- path.c_str(), "xyz.openbmc_project.Sensor.Value");
- if (!service.empty())
+ std::string tmp{};
+ std::string interface = SENSOR_VALUE_INTF;
+ if (useMetricInterface)
+ {
+ interface = METRIC_VALUE_INTF;
+ }
+ tmp = pldm::utils::DBusHandler().getService(path.c_str(),
+ interface.c_str());
+
+ if (!tmp.empty())
{
throw sdbusplus::xyz::openbmc_project::Common::Error::
TooManyResources();
@@ -485,21 +546,45 @@
* updateTime is in microseconds
*/
updateTime = static_cast<uint64_t>(DEFAULT_SENSOR_UPDATER_INTERVAL * 1000);
- try
+
+ if (!useMetricInterface)
{
- valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
+ try
+ {
+ valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create Value interface for compact numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
+ valueIntf->minValue(unitModifier(conversionFormula(minValue)));
+ valueIntf->unit(sensorUnit);
}
- catch (const sdbusplus::exception_t& e)
+ else
{
- lg2::error(
- "Failed to create Value interface for compact numeric sensor {PATH} error - {ERROR}",
- "PATH", path, "ERROR", e);
- throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
+ try
+ {
+ metricIntf = std::make_unique<MetricIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create Metric interface for compact numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ metricIntf->maxValue(unitModifier(conversionFormula(maxValue)));
+ metricIntf->minValue(unitModifier(conversionFormula(minValue)));
+ metricIntf->unit(metricUnit);
}
- valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
- valueIntf->minValue(unitModifier(conversionFormula(minValue)));
+
hysteresis = unitModifier(conversionFormula(hysteresis));
- valueIntf->unit(sensorUnit);
try
{
@@ -529,7 +614,7 @@
}
operationalStatusIntf->functional(!sensorDisabled);
- if (hasWarningThresholds)
+ if (hasWarningThresholds && !useMetricInterface)
{
try
{
@@ -548,7 +633,7 @@
thresholdWarningIntf->warningLow(unitModifier(warningLow));
}
- if (hasCriticalThresholds)
+ if (hasCriticalThresholds && !useMetricInterface)
{
try
{
@@ -583,7 +668,9 @@
void NumericSensor::updateReading(bool available, bool functional, double value)
{
- if (!availabilityIntf || !operationalStatusIntf || !valueIntf)
+ if (!availabilityIntf || !operationalStatusIntf ||
+ (!useMetricInterface && !valueIntf) ||
+ (useMetricInterface && !metricIntf))
{
lg2::error(
"Failed to update sensor {NAME} D-Bus interface don't exist.",
@@ -592,7 +679,16 @@
}
availabilityIntf->available(available);
operationalStatusIntf->functional(functional);
- double curValue = valueIntf->value();
+ double curValue = 0;
+ if (!useMetricInterface)
+ {
+ curValue = valueIntf->value();
+ }
+ else
+ {
+ curValue = metricIntf->value();
+ }
+
double newValue = std::numeric_limits<double>::quiet_NaN();
if (functional && available)
{
@@ -600,8 +696,15 @@
if (newValue != curValue &&
(!std::isnan(newValue) || !std::isnan(curValue)))
{
- valueIntf->value(newValue);
- updateThresholds();
+ if (!useMetricInterface)
+ {
+ valueIntf->value(newValue);
+ updateThresholds();
+ }
+ else
+ {
+ metricIntf->value(newValue);
+ }
}
}
else
@@ -609,14 +712,22 @@
if (newValue != curValue &&
(!std::isnan(newValue) || !std::isnan(curValue)))
{
- valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+ if (!useMetricInterface)
+ {
+ valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+ }
+ else
+ {
+ metricIntf->value(std::numeric_limits<double>::quiet_NaN());
+ }
}
}
}
void NumericSensor::handleErrGetSensorReading()
{
- if (!operationalStatusIntf || !valueIntf)
+ if (!operationalStatusIntf || (!useMetricInterface && !valueIntf) ||
+ (useMetricInterface && !metricIntf))
{
lg2::error(
"Failed to update sensor {NAME} D-Bus interfaces don't exist.",
@@ -624,7 +735,14 @@
return;
}
operationalStatusIntf->functional(false);
- valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+ if (!useMetricInterface)
+ {
+ valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+ }
+ else
+ {
+ metricIntf->value(std::numeric_limits<double>::quiet_NaN());
+ }
}
bool NumericSensor::checkThreshold(bool alarm, bool direction, double value,
@@ -657,16 +775,24 @@
void NumericSensor::updateThresholds()
{
- if (!valueIntf)
+ double value = std::numeric_limits<double>::quiet_NaN();
+
+ if ((!useMetricInterface && !valueIntf) ||
+ (useMetricInterface && !metricIntf))
{
lg2::error(
"Failed to update thresholds sensor {NAME} D-Bus interfaces don't exist.",
"NAME", sensorName);
return;
}
-
- auto value = valueIntf->value();
-
+ if (!useMetricInterface)
+ {
+ value = valueIntf->value();
+ }
+ else
+ {
+ value = metricIntf->value();
+ }
if (thresholdWarningIntf &&
!std::isnan(thresholdWarningIntf->warningHigh()))
{
diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp
index 92c709f..307f5e0 100644
--- a/platform-mc/numeric_sensor.hpp
+++ b/platform-mc/numeric_sensor.hpp
@@ -8,6 +8,7 @@
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/Metric/Value/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
#include <xyz/openbmc_project/Sensor/Value/server.hpp>
@@ -21,9 +22,15 @@
namespace platform_mc
{
+constexpr const char* SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
+constexpr const char* METRIC_VALUE_INTF = "xyz.openbmc_project.Metric.Value";
+
using SensorUnit = sdbusplus::xyz::openbmc_project::Sensor::server::Value::Unit;
using ValueIntf = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Sensor::server::Value>;
+using MetricUnit = sdbusplus::xyz::openbmc_project::Metric::server::Value::Unit;
+using MetricIntf = sdbusplus::server::object_t<
+ sdbusplus::xyz::openbmc_project::Metric::server::Value>;
using ThresholdWarningIntf = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning>;
using ThresholdCriticalIntf = sdbusplus::server::object_t<
@@ -206,6 +213,7 @@
*/
void updateThresholds();
+ std::unique_ptr<MetricIntf> metricIntf = nullptr;
std::unique_ptr<ValueIntf> valueIntf = nullptr;
std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr;
std::unique_ptr<ThresholdCriticalIntf> thresholdCriticalIntf = nullptr;
@@ -226,6 +234,7 @@
/** @brief A power-of-10 multiplier for baseUnit */
int8_t baseUnitModifier;
+ bool useMetricInterface = false;
};
} // namespace platform_mc
} // namespace pldm