Add BIOS DBus object

When HOST_BIOS_UPGRADE is enabled, create the "default" BIOS DBus object
so that it could be used for other services.
Typically, the BIOS version is sent from BIOS via OEM ipmi command, and
the oem handler could set the BIOS version accordingly.

When the BIOS is updated, this service could directly set the BIOS
version as well.

Tested: Verify the BIOS activation/version object is created on DBus.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I10d7b9a035d6a6f649fc5950f37e8fdb0db70176
diff --git a/item_updater.cpp b/item_updater.cpp
index e8196af..ac95219 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -748,6 +748,40 @@
     return valid;
 }
 
+#ifdef HOST_BIOS_UPGRADE
+void ItemUpdater::createBIOSObject()
+{
+    std::string path = BIOS_OBJPATH;
+    // Get version id from last item in the path
+    auto pos = path.rfind("/");
+    if (pos == std::string::npos)
+    {
+        log<level::ERR>("No version id found in object path",
+                        entry("BIOS_OBJPATH=%s", path.c_str()));
+        return;
+    }
+
+    createActiveAssociation(path);
+    createFunctionalAssociation(path);
+
+    auto versionId = path.substr(pos + 1);
+    auto version = "null";
+    AssociationList assocs = {};
+    biosActivation = std::make_unique<Activation>(
+        bus, path, *this, versionId, server::Activation::Activations::Active,
+        assocs);
+    auto dummyErase = [](std::string /*entryId*/) {
+        // Do nothing;
+    };
+    biosVersion = std::make_unique<VersionClass>(
+        bus, path, version, VersionPurpose::Host, "", "",
+        std::bind(dummyErase, std::placeholders::_1));
+    biosVersion->deleteObject =
+        std::make_unique<phosphor::software::manager::Delete>(bus, path,
+                                                              *biosVersion);
+}
+#endif
+
 } // namespace updater
 } // namespace software
 } // namespace phosphor
diff --git a/item_updater.hpp b/item_updater.hpp
index 721d371..b2185b9 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -62,6 +62,9 @@
         setBMCInventoryPath();
         processBMCImage();
         restoreFieldModeStatus();
+#ifdef HOST_BIOS_UPGRADE
+        createBIOSObject();
+#endif
         emit_object_added();
     };
 
@@ -253,6 +256,22 @@
      */
     bool checkImage(const std::string& filePath,
                     const std::vector<std::string>& imageList);
+
+#ifdef HOST_BIOS_UPGRADE
+    /** @brief Create the BIOS object without knowing the version.
+     *
+     *  The object is created only to provide the DBus access so that an
+     *  external service could set the correct BIOS version.
+     *  On BIOS code update, the version is updated accordingly.
+     */
+    void createBIOSObject();
+
+    /** @brief Persistent Activation D-Bus object for BIOS */
+    std::unique_ptr<Activation> biosActivation;
+
+    /** @brief Persistent Version D-Bus object for BIOS */
+    std::unique_ptr<VersionClass> biosVersion;
+#endif
 };
 
 } // namespace updater
diff --git a/meson.build b/meson.build
index 0e8a3c0..a6ebcc4 100644
--- a/meson.build
+++ b/meson.build
@@ -79,6 +79,9 @@
 conf.set_quoted('BMC_MSL', get_option('bmc-msl'))
 conf.set_quoted('REGEX_BMC_MSL', get_option('regex-bmc-msl'))
 
+if get_option('host-bios-upgrade').enabled()
+    conf.set_quoted('BIOS_OBJPATH', get_option('bios-object-path'))
+endif
 
 configure_file(output: 'config.h', configuration: conf)
 
diff --git a/meson_options.txt b/meson_options.txt
index 355773c..0877798 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -104,3 +104,9 @@
     value: '',
     description: 'The Regular expression to parse the MSL.',
 )
+
+option(
+    'bios-object-path', type: 'string',
+    value: '/xyz/openbmc_project/software/bios_active',
+    description: 'The BIOS DBus object path.',
+)