blob: 8b1f3dde79e87656d594fcfb18b38d19e26fa649 [file] [log] [blame] [edit]
From febe200fdf9115bd327a86ad621e963def1b5f09 Mon Sep 17 00:00:00 2001
From: Cody Smith <scody@google.com>
Date: Fri, 18 Feb 2022 13:20:45 +0000
Subject: [PATCH] Feature: Add association interfaces to a target EM
This change gives the `gpiopresence` daemon in `dbus-sensors`
the ability to, upon request via configuration EM, generate am
`xyz.openbmc_project.Association.Definitions` object, which is
used by the Object Mapper to generate associations between two
dbus interfaces.
As `gpiopresence` is unaware of what dbus interfaces may or may
not be probing for the interface it generates, it is left to
the user configuring `gpiopresence` to specify the association
via the `AssociationPath`, `AssociationForward`, and the
`AssociationReverse` fields in `GPIOStatus`.
Once set these will equate to the three string values in
`xyz.openbmc_project.Association.Definitions`.
Tested:
Add EM fields to an existing `GPIOStatus` object.
Check that an association is created by `gpiopresence`
as specified.
Patch Tracking Bug: b/232034841
Upstream info / review: https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/51360
Upstream-Status: Submitted
Justification: In review
Signed-off-by: Cody Smith <scody@google.com>
In-Review: https://gerrit.openbmc-project.xyz/c/openbmc/dbus-sensors/+/51360/12
Change-Id: I0572d124a8e9b9fedbdfb30d41fe399e005f5c03
---
include/GPIOPresenceSensor.hpp | 17 +++++-
src/GPIOPresenceSensor.cpp | 4 +-
src/GPIOPresenceSensorMain.cpp | 94 +++++++++++++++++++++++++++++-----
3 files changed, 101 insertions(+), 14 deletions(-)
diff --git a/include/GPIOPresenceSensor.hpp b/include/GPIOPresenceSensor.hpp
index a9f49a0..fa32a20 100644
--- a/include/GPIOPresenceSensor.hpp
+++ b/include/GPIOPresenceSensor.hpp
@@ -31,6 +31,11 @@ static constexpr inline const char* propertyGpioLine = "GpioLine";
static constexpr inline const char* propertyPolarity = "Polarity";
static constexpr inline const char* propertyPresent = "Present";
static constexpr inline const char* propertyPollRate = "PollRate";
+static constexpr inline const char* propertyAssociationPath = "AssociationPath";
+static constexpr inline const char* propertyAssociationForward =
+ "AssociationForward";
+static constexpr inline const char* propertyAssociationReverse =
+ "AssociationReverse";
} // namespace Properties
namespace interfaces
@@ -50,8 +55,15 @@ struct Config
bool activeLow;
// Presence signal.
bool present;
- // Update loop polling rate.
+ // (Optional) Update loop polling rate.
int pollRate;
+ // (Optional) Association
+ bool generateAssociation;
+ std::string associationPath;
+ std::string associationForward;
+ std::string associationReverse;
+ // (Internal) Parent path
+ std::string parentPath;
};
// Actively listen to the config information from EntityManager and calls the
@@ -65,9 +77,11 @@ class GPIOPresence
// Add a dbus object to the reference list.
// @params statusIfc: pointer to object status interface.
+ // @params associationIfc: Optional pointer to object association interface
// @params objPath: the dbus object path.
// @params config: EM config
void addObj(std::unique_ptr<sdbusplus::asio::dbus_interface> statusIfc,
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc,
std::string_view objPath, const Config& config);
// Remove a object from the object reference list.
@@ -89,6 +103,7 @@ class GPIOPresence
struct ObjIfaces
{
std::unique_ptr<sdbusplus::asio::dbus_interface> statusIfc;
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc;
Config config;
};
diff --git a/src/GPIOPresenceSensor.cpp b/src/GPIOPresenceSensor.cpp
index 870b4b4..2d48491 100644
--- a/src/GPIOPresenceSensor.cpp
+++ b/src/GPIOPresenceSensor.cpp
@@ -26,10 +26,12 @@ int GPIOPresence::readLine(std::string_view lineLabel)
void GPIOPresence::addObj(
std::unique_ptr<sdbusplus::asio::dbus_interface> statusIfc,
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc,
std::string_view objPath, const Config& config)
{
std::cerr << "New objPath added " << objPath << std::endl;
- objIfaces[std::string(objPath)] = {std::move(statusIfc), config};
+ objIfaces[std::string(objPath)] = {std::move(statusIfc),
+ std::move(associationIfc), config};
}
void GPIOPresence::removeObj(std::string_view objPath)
diff --git a/src/GPIOPresenceSensorMain.cpp b/src/GPIOPresenceSensorMain.cpp
index 8b22d25..f556900 100644
--- a/src/GPIOPresenceSensorMain.cpp
+++ b/src/GPIOPresenceSensorMain.cpp
@@ -1,8 +1,10 @@
#include "Utils.hpp"
#include <GPIOPresenceSensor.hpp>
+#include <sdbusplus/bus/match.hpp>
#include <iostream>
+#include <utility>
namespace gpiopresencesensing
{
@@ -15,7 +17,7 @@ using OnInterfaceRemovedCallback = std::function<void(std::string_view)>;
// Helper function to convert dbus property to struct
// @param[in] properties: dbus properties
-Config getConfig(const SensorBaseConfigMap& properties)
+Config getConfig(const SensorBaseConfigMap& properties, std::string parentPath)
{
auto name = loadVariant<std::string>(properties, Properties::propertyName);
auto gpioLine =
@@ -31,8 +33,48 @@ Config getConfig(const SensorBaseConfigMap& properties)
pollRate =
loadVariant<uint32_t>(properties, Properties::propertyPollRate);
}
- return {name, gpioLine, polarity == "active_low",
- /*present*/ false, pollRate};
+
+ // Optional Association
+ bool generateAssociation = false;
+ std::string associationForward = "";
+ std::string associationReverse = "";
+ std::string associationPath = "";
+
+ auto propertyAssociationPath =
+ properties.find(Properties::propertyAssociationPath);
+ if (propertyAssociationPath != properties.end())
+ {
+ associationPath = loadVariant<std::string>(
+ properties, Properties::propertyAssociationPath);
+
+ auto propertyAssociationForward =
+ properties.find(Properties::propertyAssociationForward);
+ if (propertyAssociationForward != properties.end())
+ {
+ associationForward = loadVariant<std::string>(
+ properties, Properties::propertyAssociationForward);
+
+ auto propertyAssociationReverse =
+ properties.find(Properties::propertyAssociationReverse);
+ if (propertyAssociationReverse != properties.end())
+ {
+ associationReverse = loadVariant<std::string>(
+ properties, Properties::propertyAssociationReverse);
+ generateAssociation = true;
+ }
+ }
+ }
+
+ return {name,
+ gpioLine,
+ polarity == "active_low",
+ /*present*/ false,
+ pollRate,
+ generateAssociation,
+ associationPath,
+ associationForward,
+ associationReverse,
+ std::move(parentPath)};
}
void setupInterfaceAdded(sdbusplus::asio::connection* conn,
@@ -49,7 +91,7 @@ void setupInterfaceAdded(sdbusplus::asio::connection* conn,
Config config;
try
{
- config = getConfig(found->second);
+ config = getConfig(found->second, objPath.parent_path());
callback(objPath.str, found->first, config);
}
catch (std::exception& e)
@@ -62,23 +104,24 @@ void setupInterfaceAdded(sdbusplus::asio::connection* conn,
// call the user callback for all the device that is already available
conn->async_method_call(
- [cb](const boost::system::error_code ec,
- ManagedObjectType managedObjs) {
+ [callback = cb](const boost::system::error_code ec,
+ ManagedObjectType managedObjs) {
if (ec)
{
return;
}
for (auto& obj : managedObjs)
{
- auto& item = obj.second;
+ SensorData& item = obj.second;
+
auto found = item.find(interfaces::emGPIOCableSensingIfc);
if (found != item.end())
{
Config config;
try
{
- config = getConfig(found->second);
- cb(obj.first.str, found->first, config);
+ config = getConfig(found->second, obj.first.parent_path());
+ callback(obj.first.str, found->first, config);
}
catch (std::exception& e)
{
@@ -103,7 +146,7 @@ void setupInterfaceRemoved(sdbusplus::asio::connection* conn,
OnInterfaceRemovedCallback&& cb)
{
// Listen to the interface removed event.
- std::function<void(sdbusplus::message::message & msg)> handler =
+ std::function<void(sdbusplus::message::message&)> handler =
[callback = std::move(cb)](sdbusplus::message::message msg) {
sdbusplus::message::object_path objPath;
msg.read(objPath);
@@ -162,14 +205,41 @@ int main()
{
controller->removeObj(objPath.str);
}
- // Status
+ // Add Status
auto statusIfc = objectServer.add_unique_interface(
objPath, gpiopresencesensing::interfaces::statusIfc);
+ std::cout << "Adding status interface: " << config.name
+ << " at path: " << objPath.str << std::endl;
statusIfc->register_property(
gpiopresencesensing::Properties::propertyPresent, false);
statusIfc->register_property("Name", config.name);
statusIfc->initialize();
- controller->addObj(std::move(statusIfc), objPath.str, config);
+ // Add Inventory Association
+ if (config.generateAssociation)
+ {
+ sdbusplus::message::object_path associationPath(
+ config.associationPath);
+
+ std::cout << "Adding association interface: "
+ << config.associationPath
+ << " at path: " << associationPath.str << std::endl;
+
+ auto assocIfc = objectServer.add_unique_interface(
+ associationPath, association::interface);
+ assocIfc->register_property(
+ "Associations",
+ std::vector<Association>{{config.associationForward,
+ config.associationReverse,
+ config.parentPath}});
+ assocIfc->initialize();
+ controller->addObj(std::move(statusIfc), std::move(assocIfc),
+ objPath.str, config);
+ }
+ else
+ {
+ controller->addObj(std::move(statusIfc), nullptr, objPath.str,
+ config);
+ }
controller->setMinPollRate(config.pollRate);
// It is possible there are more EM config in the pipeline.
// Therefore, delay the main loop by 10 seconds to wait for more
--
2.40.1.521.gf1e218fcd8-goog