Adding system configuration object & UT

This commit adds the system config object that implements
the SystemConfiguration interface.

The hostname property under this interface will initially
be set from the bios table when the service starts.

Whenever user sets the property, the same will be updated
in the bios table.

busctl tree xyz.openbmc_project.Network.Hypervisor
└─/xyz
  └─/xyz/openbmc_project
    └─/xyz/openbmc_project/network
      └─/xyz/openbmc_project/network/hypervisor
        └─/xyz/openbmc_project/network/hypervisor/config

Tested By:

busctl set-property xyz.openbmc_project.Network.Hypervisor
/xyz/openbmc_project/network/hypervisor/config
xyz.openbmc_project.Network.SystemConfiguration HostName s "vmi HN"

busctl introspect xyz.openbmc_project.Network.Hypervisor /xyz/openbmc_project/network/hypervisor/config
NAME                                            TYPE      SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable             interface -         -            -
.Introspect                                     method    -         s            -
org.freedesktop.DBus.Peer                       interface -         -            -
.GetMachineId                                   method    -         s            -
.Ping                                           method    -         -            -
org.freedesktop.DBus.Properties                 interface -         -            -
.Get                                            method    ss        v            -
.GetAll                                         method    s         a{sv}        -
.Set                                            method    ssv       -            -
.PropertiesChanged                              signal    sa{sv}as  -            -
xyz.openbmc_project.Network.SystemConfiguration interface -         -            -
.DefaultGateway                                 property  s         ""           emits-change writable
.DefaultGateway6                                property  s         ""           emits-change writable
.HostName                                       property  s         "vmi HN"     emits-change writable

busctl call  xyz.openbmc_project.BIOSConfigManager /xyz/openbmc_project/bios_config/manager xyz.openbmc_project.BIOSConfig.Manager GetAttribute s vmi_hostname
svv "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String" s "vmi HN" s ""

Signed-off-by: Asmitha Karunanithi <asmitk01@in.ibm.com>
Change-Id: Ib3afaef2da039d18cc672a1759b721698f9c14e2
diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp
index 4923cac..1540e0f 100644
--- a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp
+++ b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp
@@ -241,5 +241,12 @@
     log<level::INFO>("Create eth0 and eth1 objects");
 }
 
+void HypNetworkMgr::createSysConfObj()
+{
+    systemConf.reset(nullptr);
+    this->systemConf = std::make_unique<phosphor::network::HypSysConfig>(
+        bus, objectPath + "/config", *this);
+}
+
 } // namespace network
 } // namespace phosphor
diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp
index a1b4d9a..5616c66 100644
--- a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp
+++ b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "hyp_sys_config.hpp"
 #include "types.hpp"
 #include "util.hpp"
 
@@ -13,6 +14,7 @@
 {
 
 class HypEthInterface;
+class HypSysConfig;
 
 using biosAttrName = std::string;
 using biosAttrType = std::string;
@@ -45,6 +47,8 @@
     biosBaseOptions
 };
 
+using SystemConfPtr = std::unique_ptr<HypSysConfig>;
+
 /** @class Manager
  *  @brief Implementation for the
  *         xyz.openbmc_project.Network.Hypervisor DBus API.
@@ -104,6 +108,18 @@
      */
     void createIfObjects();
 
+    /** @brief Creates system config object
+     */
+    void createSysConfObj();
+
+    /** @brief gets the system conf object.
+     *
+     */
+    const SystemConfPtr& getSystemConf()
+    {
+        return systemConf;
+    }
+
   protected:
     /**
      * @brief get Dbus Prop
@@ -133,6 +149,9 @@
     /** @brief object path */
     std::string objectPath;
 
+    /** @brief pointer to system conf object. */
+    SystemConfPtr systemConf = nullptr;
+
     /** @brief Persistent map of EthernetInterface dbus
      *         objects and their names
      */
diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager_main.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager_main.cpp
index d0d7b7d..eed841a 100644
--- a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager_main.cpp
+++ b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager_main.cpp
@@ -27,6 +27,12 @@
     // Create the hypervisor eth interface objects
     manager.createIfObjects();
 
+    // Create the hypervisor system config object
+    manager.createSysConfObj();
+    const phosphor::network::SystemConfPtr& systemConfigObj =
+        manager.getSystemConf();
+    systemConfigObj->setHostName();
+
     bus.request_name(HYP_DEFAULT_NETWORK_BUSNAME);
 
     event.loop();
diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.cpp
new file mode 100644
index 0000000..29c2660
--- /dev/null
+++ b/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.cpp
@@ -0,0 +1,88 @@
+#include "hyp_sys_config.hpp"
+
+#include "hyp_network_manager.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+constexpr auto BIOS_SERVICE = "xyz.openbmc_project.BIOSConfigManager";
+constexpr auto BIOS_OBJPATH = "/xyz/openbmc_project/bios_config/manager";
+constexpr auto BIOS_MGR_INTF = "xyz.openbmc_project.BIOSConfig.Manager";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using InvalidArgumentMetadata = xyz::openbmc_project::Common::InvalidArgument;
+
+using SysConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+void HypSysConfig::setHostName()
+{
+    auto name = getHostNameFromBios();
+
+    SysConfigIntf::hostName(std::move(name));
+}
+
+std::string HypSysConfig::hostName(std::string name)
+{
+    if (SysConfigIntf::hostName() == name)
+    {
+        return name;
+    }
+
+    name = SysConfigIntf::hostName(name);
+    setHostNameInBios(name);
+    return name;
+}
+
+std::string HypSysConfig::getHostNameFromBios() const
+{
+    try
+    {
+        using getAttrRetType =
+            std::tuple<std::string, std::variant<std::string, int64_t>,
+                       std::variant<std::string, int64_t>>;
+        getAttrRetType name;
+        auto method = bus.new_method_call(BIOS_SERVICE, BIOS_OBJPATH,
+                                          BIOS_MGR_INTF, "GetAttribute");
+
+        method.append("vmi_hostname");
+
+        auto reply = bus.call(method);
+
+        std::string type;
+        std::variant<std::string, int64_t> currValue;
+        std::variant<std::string, int64_t> defValue;
+        reply.read(type, currValue, defValue);
+        return std::get<std::string>(currValue);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to get the hostname from bios table",
+                        entry("ERR=%s", ex.what()));
+    }
+    return std::string();
+}
+
+void HypSysConfig::setHostNameInBios(const std::string& name)
+{
+    auto properties = bus.new_method_call(BIOS_SERVICE, BIOS_OBJPATH,
+                                          BIOS_MGR_INTF, "SetAttribute");
+    properties.append("vmi_hostname");
+    properties.append(std::variant<std::string>(name));
+    auto result = bus.call(properties);
+
+    if (result.is_method_error())
+    {
+        throw std::runtime_error("Set attribute api failed");
+    }
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.hpp b/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.hpp
new file mode 100644
index 0000000..7d89d82
--- /dev/null
+++ b/src/ibm/hypervisor-network-mgr-src/hyp_sys_config.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "hyp_network_manager.hpp"
+#include "system_configuration.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Network/SystemConfiguration/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using SysConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+using Iface = sdbusplus::server::object::object<SysConfigIntf>;
+
+class HypNetworkMgr; // forward declaration of network manager.
+
+/** @class HypSysConfig
+ *  @brief Network system configuration.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.HypSysConfig DBus API.
+ */
+class HypSysConfig : public Iface
+{
+  public:
+    HypSysConfig() = default;
+    HypSysConfig(const HypSysConfig&) = delete;
+    HypSysConfig& operator=(const HypSysConfig&) = delete;
+    HypSysConfig(HypSysConfig&&) = delete;
+    HypSysConfig& operator=(HypSysConfig&&) = delete;
+    virtual ~HypSysConfig() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] parent - Parent object.
+     */
+    HypSysConfig(sdbusplus::bus::bus& bus, const std::string& objPath,
+                 HypNetworkMgr& parent) :
+        Iface(bus, objPath.c_str(), Iface::action::defer_emit),
+        bus(bus), manager(parent){};
+
+    /** @brief set the hostname of the system.
+     *  @param[in] name - host name of the system.
+     */
+    std::string hostName(std::string name) override;
+
+    /** @brief get hostname from bios and set the data member
+     */
+    void setHostName();
+
+  protected:
+    /** @brief get the hostname from the system by doing
+     *         dbus call to hostnamed service.
+     */
+    std::string getHostNameFromBios() const;
+
+    /** @brief set the hostname set in dbus obj in the basebiostable
+     *  @param[in] name - hostname that is set in dbus obj
+     */
+    void setHostNameInBios(const std::string& name);
+
+    /** @brief Persistent sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Hyp Network Manager object. */
+    HypNetworkMgr& manager;
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/ibm/hypervisor-network-mgr-src/meson.build b/src/ibm/hypervisor-network-mgr-src/meson.build
index 672c10d..becc10c 100644
--- a/src/ibm/hypervisor-network-mgr-src/meson.build
+++ b/src/ibm/hypervisor-network-mgr-src/meson.build
@@ -15,6 +15,7 @@
   'hyp-network-manager',
   'hyp_network_manager_main.cpp',
   'hyp_network_manager.cpp',
+  'hyp_sys_config.cpp',
   implicit_include_directories: false,
   dependencies: networkd_dep,
   install: true,