Implement system configuration Dbus interface

Change-Id: I713175e946af47990afcead00558ee4b90cbce8e
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 370709f..02ba4c2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,7 +16,9 @@
 		network_manager.hpp \
 		ipaddress.hpp \
 		types.hpp \
-		util.hpp
+		util.hpp \
+		routing_table.hpp \
+		system_configuration.hpp
 
 phosphor_network_manager_SOURCES = \
 		ethernet_interface.cpp \
@@ -24,6 +26,7 @@
 		network_config.cpp \
 		network_manager.cpp \
 		network_manager_main.cpp \
+		system_configuration.cpp \
 		xyz/openbmc_project/Network/VLAN/Create/server.cpp \
 		xyz/openbmc_project/Network/IP/Create/server.cpp \
 		util.cpp \
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index c824919..1f36815 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -89,11 +89,6 @@
                         gateway)));
     }
 
-    // TODO:- will move the default gateway to conf object
-    // once we implement that.
-
-    // TODO: openbmc/openbmc#1295
-    manager.defaultGateway = routingTable.getDefaultGateway();
 }
 
 void EthernetInterface::iP(IP::Protocol protType,
@@ -104,6 +99,8 @@
 
     if (dHCPEnabled())
     {
+        log<level::INFO>("DHCP enabled on the interface"),
+                        entry("INTERFACE=%s",interfaceName());
         return;
     }
 
@@ -277,7 +274,6 @@
     objectPath /= type;
     objectPath /= generateId(ipaddress, prefixLength, gateway);
     return objectPath.string();
-
 }
 
 }//namespace network
diff --git a/ethernet_interface.hpp b/ethernet_interface.hpp
index 856f874..313a0b9 100644
--- a/ethernet_interface.hpp
+++ b/ethernet_interface.hpp
@@ -25,7 +25,6 @@
 using IP = sdbusplus::xyz::openbmc_project::Network::server::IP;
 class Manager; // forward declaration of network manager.
 
-class Manager; // forward declaration of network manager.
 class TestEthernetInterface;
 
 using LinkSpeed = uint16_t;
diff --git a/system_configuration.cpp b/system_configuration.cpp
new file mode 100644
index 0000000..7913b96
--- /dev/null
+++ b/system_configuration.cpp
@@ -0,0 +1,108 @@
+#include "config.h"
+#include "system_configuration.hpp"
+#include "network_manager.hpp"
+#include "routing_table.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+// systemd service to kick start a target.
+constexpr auto HOSTNAMED_SERVICE    = "org.freedesktop.hostname1";
+constexpr auto HOSTNAMED_SERVICE_PATH  = "/org/freedesktop/hostname1";
+constexpr auto HOSTNAMED_INTERFACE  = "org.freedesktop.hostname1";
+constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
+constexpr auto METHOD_GET = "Get";
+constexpr auto METHOD_SET = "SetStaticHostname";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+using SystemConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+SystemConfiguration::SystemConfiguration(sdbusplus::bus::bus& bus,
+                                         const std::string& objPath,
+                                         Manager& parent) :
+        Iface(bus, objPath.c_str(), true),
+        bus(bus),
+        manager(parent)
+{
+    auto name = getHostNameFromSystem();
+    route::Table routingTable;
+
+    SystemConfigIntf::hostName(name);
+    SystemConfigIntf::defaultGateway(routingTable.getDefaultGateway());
+
+    this->emit_object_added();
+}
+
+std::string SystemConfiguration::hostName(std::string name)
+{
+    if (SystemConfigIntf::hostName() == name)
+    {
+        return name;
+    }
+    auto method = bus.new_method_call(
+                      HOSTNAMED_SERVICE,
+                      HOSTNAMED_SERVICE_PATH,
+                      HOSTNAMED_INTERFACE,
+                      METHOD_SET);
+
+    method.append(name, true);
+
+    if (!bus.call(method))
+    {
+        log<level::ERR>("Failed to set the hostname");
+        report<InternalFailure>();
+        return SystemConfigIntf::hostName();
+    }
+
+    return SystemConfigIntf::hostName(name);
+}
+
+std::string SystemConfiguration::getHostNameFromSystem() const
+{
+    sdbusplus::message::variant<std::string> name;
+    auto method = bus.new_method_call(
+                      HOSTNAMED_SERVICE,
+                      HOSTNAMED_SERVICE_PATH,
+                      PROPERTY_INTERFACE,
+                      METHOD_GET);
+
+    method.append(HOSTNAMED_INTERFACE, "Hostname");
+
+    auto reply = bus.call(method);
+
+    if (reply)
+    {
+        reply.read(name);
+    }
+    else
+    {
+        log<level::ERR>("Failed to get hostname");
+        report<InternalFailure>();
+        return "";
+    }
+    return name.get<std::string>();
+}
+
+
+std::string SystemConfiguration::defaultGateway(std::string gateway)
+{
+    if (SystemConfigIntf::defaultGateway() == gateway)
+    {
+        return gateway;
+    }
+    auto gw = SystemConfigIntf::defaultGateway(gateway);
+    manager.writeToConfigurationFile();
+    return gw;
+}
+
+}// namespace network
+}// namespace phosphor
diff --git a/system_configuration.hpp b/system_configuration.hpp
new file mode 100644
index 0000000..3ebe647
--- /dev/null
+++ b/system_configuration.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "xyz/openbmc_project/Network/SystemConfiguration/server.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+
+#include <string>
+
+namespace phosphor
+{
+namespace network
+{
+
+using SystemConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+using Iface =
+    sdbusplus::server::object::object<SystemConfigIntf>;
+
+class Manager; // forward declaration of network manager.
+
+/** @class SystemConfiguration
+ *  @brief Network system configuration.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.SystemConfiguration DBus API.
+ */
+class SystemConfiguration : public Iface
+{
+    public:
+        SystemConfiguration() = default;
+        SystemConfiguration(const SystemConfiguration&) = delete;
+        SystemConfiguration& operator=(const SystemConfiguration&) = delete;
+        SystemConfiguration(SystemConfiguration&&) = delete;
+        SystemConfiguration& operator=(SystemConfiguration&&) = delete;
+        virtual ~SystemConfiguration() = 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.
+         */
+        SystemConfiguration(sdbusplus::bus::bus& bus,
+                            const std::string& objPath,
+                            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 set the default gateway of the system.
+         *  @param[in] gateway - default gateway of the system.
+         */
+        std::string defaultGateway(std::string gateway) override;
+
+        using SystemConfigIntf::defaultGateway;
+
+    private:
+
+        /** @brief get the hostname from the system by doing
+         *         dbus call to hostnamed service.
+         */
+        std::string getHostNameFromSystem() const;
+
+        /** @brief Persistent sdbusplus DBus bus connection. */
+        sdbusplus::bus::bus& bus;
+
+        /** @brief Network Manager object. */
+        Manager& manager;
+
+};
+
+} // namespace network
+} // namespace phosphor