Create BMC functional Association

Create a functional association for the "running" BMC image.

Change-Id: Id254df06b4361b418e765cc5222b1e1ee0d348a3
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 6b4ff5e..dda7a8d 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -143,6 +143,10 @@
 
 void ItemUpdater::processBMCImage()
 {
+    using VersionClass = phosphor::software::manager::Version;
+    // Read os-release from /etc/ to get the functional BMC version
+    auto functionalVersion = VersionClass::getBMCVersion(OS_RELEASE_FILE);
+
     // Read os-release from folders under /media/ to get
     // BMC Software Versions.
     for(const auto& iter : fs::directory_iterator(MEDIA_DIR))
@@ -161,9 +165,7 @@
                                 entry("FileName=%s", osRelease.string()));
                 activationState = server::Activation::Activations::Invalid;
             }
-            auto version =
-                    phosphor::software::manager::Version::
-                            getBMCVersion(osRelease);
+            auto version = VersionClass::getBMCVersion(osRelease);
             if (version.empty())
             {
                 log<level::ERR>("Failed to read version from osRelease",
@@ -176,6 +178,12 @@
             auto purpose = server::Version::VersionPurpose::BMC;
             auto path = fs::path(SOFTWARE_OBJPATH) / id;
 
+            // Create functional association if this is the functional version
+            if (version.compare(functionalVersion) == 0)
+            {
+                createFunctionalAssociation(path);
+            }
+
             AssociationList associations = {};
 
             if (activationState == server::Activation::Activations::Active)
@@ -465,11 +473,22 @@
     associations(assocs);
 }
 
+void ItemUpdater::createFunctionalAssociation(const std::string& path)
+{
+    assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION,
+                                        FUNCTIONAL_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)
+        // Since there could be multiple associations to the same path,
+        // only remove ones that have an active forward association.
+        if ((std::get<0>(*iter)).compare(ACTIVE_FWD_ASSOCIATION) == 0 &&
+            (std::get<2>(*iter)).compare(path) == 0)
         {
             iter = assocs.erase(iter);
             associations(assocs);