Add support for dbus parameter
Added support for parameter type dbus sensor and utility functions
to read dbus sensor value.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Change-Id: I04db0016f312edea095442a693500c3b4e571d6c
diff --git a/dbusSensor.hpp b/dbusSensor.hpp
new file mode 100644
index 0000000..8ab17a2
--- /dev/null
+++ b/dbusSensor.hpp
@@ -0,0 +1,38 @@
+#include "dbusUtils.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+const char* sensorIntf = "xyz.openbmc_project.Sensor.Value";
+
+class DbusSensor
+{
+ public:
+ DbusSensor() = delete;
+ virtual ~DbusSensor() = default;
+
+ /** @brief Constructs DbusSensor
+ *
+ * @param[in] bus - Handle to system dbus
+ * @param[in] path - The Dbus path of sensor
+ */
+ DbusSensor(sdbusplus::bus::bus& bus, const std::string& path) :
+ bus(bus), path(path)
+ {
+ servName = getService(bus, path, sensorIntf);
+ }
+
+ /** @brief Get sensor value property from D-bus interface */
+ double getSensorValue()
+ {
+ return getDbusProperty<double>(bus, servName, path, sensorIntf,
+ "Value");
+ }
+
+ private:
+ /** @brief sdbusplus bus client connection. */
+ sdbusplus::bus::bus& bus;
+ /** @brief complete path for sensor */
+ std::string path;
+ /** @brief service name for the sensor daemon */
+ std::string servName;
+};
diff --git a/dbusUtils.hpp b/dbusUtils.hpp
new file mode 100644
index 0000000..a12a21d
--- /dev/null
+++ b/dbusUtils.hpp
@@ -0,0 +1,84 @@
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+const char* propIntf = "org.freedesktop.DBus.Properties";
+const char* mapperBusName = "xyz.openbmc_project.ObjectMapper";
+const char* mapperPath = "/xyz/openbmc_project/object_mapper";
+const char* mapperIntf = "xyz.openbmc_project.ObjectMapper";
+
+const char* methodGetObject = "GetObject";
+const char* methodGet = "Get";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+using Value = std::variant<int64_t, double, std::string, bool>;
+
+std::string getService(sdbusplus::bus::bus& bus, const std::string& path,
+ const char* intf)
+{
+ /* Get mapper object for sensor path */
+ auto mapper = bus.new_method_call(mapperBusName, mapperPath, mapperIntf,
+ methodGetObject);
+
+ mapper.append(path.c_str());
+ mapper.append(std::vector<std::string>({intf}));
+
+ std::unordered_map<std::string, std::vector<std::string>> resp;
+
+ try
+ {
+ auto msg = bus.call(mapper);
+
+ msg.read(resp);
+ if (msg.is_method_error())
+ {
+ log<level::ERR>("Error in mapper call");
+ elog<InternalFailure>();
+ }
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ log<level::ERR>("ObjectMapper call failure",
+ entry("WHAT=%s", ex.what()));
+ throw;
+ }
+
+ if (resp.begin() == resp.end())
+ {
+ throw std::runtime_error("Unable to find Object: " + path);
+ }
+
+ return resp.begin()->first;
+}
+
+template <typename T>
+
+T getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
+ const std::string& path, const std::string& intf,
+ const std::string& property)
+{
+
+ Value value;
+
+ auto method =
+ bus.new_method_call(service.c_str(), path.c_str(), propIntf, methodGet);
+
+ method.append(intf, property);
+
+ auto msg = bus.call(method);
+
+ if (msg.is_method_error())
+ {
+ log<level::ERR>("Failed to get property",
+ entry("PROPERTY=%s", property.c_str()),
+ entry("PATH=%s", path.c_str()),
+ entry("INTERFACE=%s", intf.c_str()));
+ elog<InternalFailure>();
+ }
+
+ msg.read(value);
+
+ return std::get<T>(value);
+}
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index ef8543f..501d9cd 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -39,6 +39,9 @@
case constParam:
return value;
break;
+ case dbusParam:
+ return dbusSensor->getSensorValue();
+ break;
default:
throw std::invalid_argument("param type not supported");
}
@@ -92,7 +95,30 @@
}
}
- /* TODO: Check for dbus parameter */
+ /* Check for dbus parameter */
+ auto dbusParams = params.value("DbusParam", empty);
+ if (!dbusParams.empty())
+ {
+ for (auto& j : dbusParams)
+ {
+ /* Get parameter dbus sensor descriptor */
+ auto desc = j.value("Desc", empty);
+ if ((!desc.empty()) && (j.find("ParamName") != j.end()))
+ {
+ std::string sensorType = desc.value("SensorType", "");
+ std::string name = desc.value("Name", "");
+
+ if (!sensorType.empty() && !name.empty())
+ {
+ std::string objPath(sensorDbusPath);
+ objPath += sensorType + "/" + name;
+
+ auto paramPtr = std::make_unique<SensorParam>(bus, objPath);
+ paramMap.emplace(j["ParamName"], std::move(paramPtr));
+ }
+ }
+ }
+ }
/* Print all parameters for debug purpose only */
if (DEBUG)
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index a49c94f..6b11eb4 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -1,3 +1,5 @@
+#include "dbusSensor.hpp"
+
#include <nlohmann/json.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
@@ -44,11 +46,22 @@
explicit SensorParam(double value) : value(value), paramType(constParam)
{}
+ /** @brief Constructs SensorParam (type = dbusParam)
+ *
+ * @param[in] bus - Handle to system dbus
+ * @param[in] path - The Dbus path of sensor
+ */
+ SensorParam(sdbusplus::bus::bus& bus, std::string path) :
+ dbusSensor(std::make_unique<DbusSensor>(bus, path)),
+ paramType(dbusParam)
+ {}
+
/** @brief Get sensor value property from D-bus interface */
double getParamValue();
private:
- double value;
+ std::unique_ptr<DbusSensor> dbusSensor = nullptr;
+ double value = 0;
ParamType paramType;
};