Invoke SetNTP and UpdateUseNtpField in time manager

1. When time mode is changed, invoke systemd timedate1's SetNTP
method to update NTP settings;
2. When settings use_dhcp_ntp property is changed, invoke
NetworkManager's UpdateUseNtpField method to update its setting;
3. Move the common code of getProperty() into utils.hpp

Change-Id: I981e0e9de9c0430282b3364c38c282312bb2be89
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/manager.cpp b/manager.cpp
index 9810e14..56e0d0b 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -10,8 +10,6 @@
 constexpr auto SETTINGS_SERVICE = "org.openbmc.settings.Host";
 constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
 constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
-constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
-constexpr auto METHOD_GET = "Get";
 
 // TODO: Use new settings in xyz.openbmc_project
 const auto MATCH_PROPERTY_CHANGE =
@@ -26,11 +24,20 @@
     rules::path("/org/openbmc/control/power0") +
     rules::interface("org.freedesktop.DBus.Properties");
 
-// TODO: consider put the get properties related functions into a common place
 constexpr auto POWER_SERVICE = "org.openbmc.control.Power";
 constexpr auto POWER_PATH = "/org/openbmc/control/power0";
 constexpr auto POWER_INTERFACE = POWER_SERVICE;
 constexpr auto PGOOD_STR = "pgood";
+
+constexpr auto SYSTEMD_TIME_SERVICE = "org.freedesktop.timedate1";
+constexpr auto SYSTEMD_TIME_PATH = "/org/freedesktop/timedate1";
+constexpr auto SYSTEMD_TIME_INTERFACE = SYSTEMD_TIME_SERVICE;
+constexpr auto METHOD_SET_NTP = "SetNTP";
+
+constexpr auto OBMC_NETWORK_SERVICE = "org.openbmc.NetworkManager";
+constexpr auto OBMC_NETWORK_PATH = "/org/openbmc/NetworkManager/Interface";
+constexpr auto OBMC_NETWORK_INTERFACE = OBMC_NETWORK_SERVICE;
+constexpr auto METHOD_UPDATE_USE_NTP = "UpdateUseNtpField";
 }
 
 namespace phosphor
@@ -64,6 +71,8 @@
     // Check the settings daemon to process the new settings
     onPropertyChanged(PROPERTY_TIME_MODE, getSettings(PROPERTY_TIME_MODE));
     onPropertyChanged(PROPERTY_TIME_OWNER, getSettings(PROPERTY_TIME_OWNER));
+
+    checkDhcpNtp();
 }
 
 void Manager::addListener(PropertyChangeListner* listener)
@@ -91,26 +100,28 @@
 
 void Manager::checkHostOn()
 {
-    sdbusplus::message::variant<int> pgood = 0;
-    auto method = bus.new_method_call(POWER_SERVICE,
-                                      POWER_PATH,
-                                      PROPERTY_INTERFACE,
-                                      METHOD_GET);
-    method.append(PROPERTY_INTERFACE, PGOOD_STR);
-    auto reply = bus.call(method);
-    if (reply)
-    {
-        reply.read(pgood);
-    }
+    int pgood = utils::getProperty<int>(bus,
+                                        POWER_SERVICE,
+                                        POWER_PATH,
+                                        POWER_INTERFACE,
+                                        PGOOD_STR);
+    hostOn = static_cast<bool>(pgood);
+}
 
-    hostOn = static_cast<bool>(pgood.get<int>());
+void Manager::checkDhcpNtp()
+{
+    std::string useDhcpNtp = utils::getProperty<std::string>(
+                                 bus,
+                                 SETTINGS_SERVICE,
+                                 SETTINGS_PATH,
+                                 SETTINGS_INTERFACE,
+                                 PROPERTY_DHCP_NTP);
+    updateDhcpNtpSetting(useDhcpNtp);
 }
 
 void Manager::onPropertyChanged(const std::string& key,
                                 const std::string& value)
 {
-    // TODO: Check dhcp_ntp
-
     if (hostOn)
     {
         // If host is on, set the values as requested time mode/owner.
@@ -127,6 +138,8 @@
             {
                 listener->onModeChanged(timeMode);
             }
+            // When time_mode is updated, update the NTP setting
+            updateNtpSetting(value);
         }
         else if (key == PROPERTY_TIME_OWNER)
         {
@@ -150,13 +163,20 @@
     std::string ignore;
     properties props;
     m.read(ignore, props);
+    auto manager = static_cast<Manager*>(userData);
     for (const auto& item : props)
     {
         if (managedProperties.find(item.first) != managedProperties.end())
         {
-            static_cast<Manager*>(userData)->onPropertyChanged(
+            // For managed properties, notify listeners
+            manager->onPropertyChanged(
                 item.first, item.second.get<std::string>());
         }
+        else if (item.first == PROPERTY_DHCP_NTP)
+        {
+            // For other manager interested properties, handle specifically
+            manager->updateDhcpNtpSetting(item.second.get<std::string>());
+        }
     }
     return 0;
 }
@@ -190,6 +210,46 @@
     requestedOwner = owner;
 }
 
+void Manager::updateNtpSetting(const std::string& value)
+{
+    bool isNtp = (value == "NTP");
+    auto method = bus.new_method_call(SYSTEMD_TIME_SERVICE,
+                                      SYSTEMD_TIME_PATH,
+                                      SYSTEMD_TIME_INTERFACE,
+                                      METHOD_SET_NTP);
+    method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable
+                                 // 'false' meaning no policy-kit
+
+    if (bus.call(method))
+    {
+        log<level::INFO>("Updated NTP setting",
+                         entry("ENABLED:%d", isNtp));
+    }
+    else
+    {
+        log<level::ERR>("Failed to update NTP setting");
+    }
+}
+
+void Manager::updateDhcpNtpSetting(const std::string& useDhcpNtp)
+{
+    auto method = bus.new_method_call(OBMC_NETWORK_SERVICE,
+                                      OBMC_NETWORK_PATH,
+                                      OBMC_NETWORK_INTERFACE,
+                                      METHOD_UPDATE_USE_NTP);
+    method.append(useDhcpNtp);
+
+    if (bus.call(method))
+    {
+        log<level::INFO>("Updated use ntp field",
+                         entry("USENTPFIELD:%s", useDhcpNtp.c_str()));
+    }
+    else
+    {
+        log<level::ERR>("Failed to update UseNtpField");
+    }
+}
+
 void Manager::onPgoodChanged(bool pgood)
 {
     hostOn = pgood;
@@ -204,6 +264,7 @@
         {
             listener->onModeChanged(timeMode);
         }
+        updateNtpSetting(requestedMode);
         setRequestedMode({}); // Clear requested mode
     }
     if (!requestedOwner.empty())
@@ -257,23 +318,12 @@
 
 std::string Manager::getSettings(const char* value) const
 {
-    sdbusplus::message::variant<std::string> mode;
-    auto method = bus.new_method_call(SETTINGS_SERVICE,
-                                      SETTINGS_PATH,
-                                      PROPERTY_INTERFACE,
-                                      METHOD_GET);
-    method.append(SETTINGS_INTERFACE, value);
-    auto reply = bus.call(method);
-    if (reply)
-    {
-        reply.read(mode);
-    }
-    else
-    {
-        log<level::ERR>("Failed to get settings");
-    }
-
-    return mode.get<std::string>();
+    return utils::getProperty<std::string>(
+        bus,
+        SETTINGS_SERVICE,
+        SETTINGS_PATH,
+        SETTINGS_INTERFACE,
+        value);
 }
 
 Mode Manager::convertToMode(const std::string& mode)