PEL: Set critical association to object paths

Create critical association to inventory d-bus objects.
This is being done for the items in callouts that need
their service indicators turned on in its code, and
that the other association endpoint is the chasis so
it can be used for health rollup.

The associations property on the
xyz.openbmc_project.Association.Definitions interface
will have following entry added to called out object path:
["health_rollup", "critical",
"/xyz/openbmc_project/inventory/system/chassis"]

Signed-off-by: Sumit Kumar <sumit_kumar@in.ibm.com>
Change-Id: I50dfe4807ac9c19f54c49dfa2b9ec7119aaffb96
diff --git a/extensions/openpower-pels/data_interface.cpp b/extensions/openpower-pels/data_interface.cpp
index 89b1f54..0365b8b 100644
--- a/extensions/openpower-pels/data_interface.cpp
+++ b/extensions/openpower-pels/data_interface.cpp
@@ -79,6 +79,7 @@
 constexpr auto operationalStatus =
     "xyz.openbmc_project.State.Decorator.OperationalStatus";
 constexpr auto logSetting = "xyz.openbmc_project.Logging.Settings";
+constexpr auto association = "xyz.openbmc_project.Association.Definitions";
 } // namespace interface
 
 using namespace sdbusplus::xyz::openbmc_project::State::Boot::server;
@@ -528,6 +529,39 @@
     _bus.call(method);
 }
 
+using AssociationTuple = std::tuple<std::string, std::string, std::string>;
+using AssociationsProperty = std::vector<AssociationTuple>;
+
+void DataInterface::setCriticalAssociation(const std::string& objectPath) const
+{
+    DBusValue getAssociationValue;
+
+    auto service = getService(objectPath, interface::association);
+
+    getProperty(service, objectPath, interface::association, "Associations",
+                getAssociationValue);
+
+    auto association = std::get<AssociationsProperty>(getAssociationValue);
+
+    AssociationTuple critAssociation{
+        "health_rollup", "critical",
+        "/xyz/openbmc_project/inventory/system/chassis"};
+
+    if (std::find(association.begin(), association.end(), critAssociation) ==
+        association.end())
+    {
+        association.push_back(critAssociation);
+        DBusValue setAssociationValue = association;
+
+        auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
+                                           interface::dbusProperty, "Set");
+
+        method.append(interface::association, "Associations",
+                      setAssociationValue);
+        _bus.call(method);
+    }
+}
+
 std::vector<std::string> DataInterface::getSystemNames() const
 {
     DBusSubTree subtree;