Create active association

Create an association between an active image
and the active image's version object.

Resolves openbmc/openbmc#2007

Change-Id: I4fd27235db97a3cee87d2da335245e00ec602fba
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/activation.cpp b/activation.cpp
index 8dc4d38..af8f1e9 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -104,6 +104,9 @@
             roVolumeCreated = false;
             Activation::unsubscribeFromSystemdSignals();
 
+            // Create active association
+            parent.createActiveAssociation(path);
+
             return softwareServer::Activation::activation(
                     softwareServer::Activation::Activations::Active);
         }
diff --git a/activation.hpp b/activation.hpp
index 0a98b85..d22ed91 100644
--- a/activation.hpp
+++ b/activation.hpp
@@ -164,6 +164,8 @@
         std::string path;
 };
 
+// TODO: openbmc/openbmc#2086 - Add removeActiveAssociation() after
+//       Delete() is implemented
 /** @class Activation
  *  @brief OpenBMC activation software management implementation.
  *  @details A concrete implementation for
diff --git a/configure.ac b/configure.ac
index c7730a3..5e0d37b 100755
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,9 @@
 AC_DEFINE(ACTIVATION_REV_ASSOCIATION, "inventory", [The name of the activation's reverse association.])
 AC_DEFINE(CHASSIS_INVENTORY_PATH, "/xyz/openbmc_project/inventory/system/chassis/", [The chassis inventory path root.])
 
+AC_DEFINE(ACTIVE_FWD_ASSOCIATION, "active", [The name of the active's forward association.])
+AC_DEFINE(ACTIVE_REV_ASSOCIATION, "software_version", [The name of the active's reverse association.])
+
 AC_ARG_VAR(VERSION_BUSNAME, [The Dbus busname to own])
 AS_IF([test "x$VERSION_BUSNAME" == "x"], [VERSION_BUSNAME="xyz.openbmc_project.Software.Version"])
 AC_DEFINE_UNQUOTED([VERSION_BUSNAME], ["$VERSION_BUSNAME"], [The DBus busname to own])
diff --git a/item_updater.cpp b/item_updater.cpp
index 7d7df3f..4b8d534 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -441,6 +441,30 @@
     }
 }
 
+void ItemUpdater::createActiveAssociation(std::string path)
+{
+    assocs.emplace_back(std::make_tuple(ACTIVE_FWD_ASSOCIATION,
+                                        ACTIVE_REV_ASSOCIATION,
+                                        path));
+    associations(assocs);
+}
+
+void ItemUpdater::removeActiveAssociation(std::string path)
+{
+    for (auto iter = assocs.begin(); iter != assocs.end();)
+    {
+        if ((std::get<2>(*iter)).compare(path) == 0)
+        {
+            iter = assocs.erase(iter);
+            associations(assocs);
+        }
+        else
+        {
+            ++iter;
+        }
+    }
+}
+
 } // namespace updater
 } // namespace software
 } // namespace phosphor
diff --git a/item_updater.hpp b/item_updater.hpp
index 4015760..3489a47 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -5,6 +5,7 @@
 #include "version.hpp"
 #include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
 #include <xyz/openbmc_project/Control/FieldMode/server.hpp>
+#include "org/openbmc/Associations/server.hpp"
 
 namespace phosphor
 {
@@ -15,10 +16,14 @@
 
 using ItemUpdaterInherit = sdbusplus::server::object::object<
     sdbusplus::xyz::openbmc_project::Common::server::FactoryReset,
-    sdbusplus::xyz::openbmc_project::Control::server::FieldMode>;
+    sdbusplus::xyz::openbmc_project::Control::server::FieldMode,
+    sdbusplus::org::openbmc::server::Associations>;
 
 namespace MatchRules = sdbusplus::bus::match::rules;
 
+using AssociationList =
+        std::vector<std::tuple<std::string, std::string, std::string>>;
+
 /** @class ItemUpdater
  *  @brief Manages the activation of the BMC version items.
  */
@@ -79,6 +84,20 @@
      */
     void erase(std::string entryId);
 
+
+    /** @brief Creates an active association to the
+     *  newly active software image
+     *
+     * @param[in]  path - The path to create the association to.
+     */
+    void createActiveAssociation(std::string path);
+
+    /** @brief Removes an active association to the software image
+     *
+     * @param[in]  path - The path to remove the association from.
+     */
+    void removeActiveAssociation(std::string path);
+
     private:
         /** @brief Callback function for Software.Version match.
          *  @details Creates an Activation dbus object.
@@ -137,6 +156,9 @@
         /** @brief sdbusplus signal match for Software.Version */
         sdbusplus::bus::match_t versionMatch;
 
+        /** @brief This entry's associations */
+        AssociationList assocs = {};
+
         /** @brief Clears read only partition for
           * given Activation dbus object.
           *