Use mapper to find service name

Use objectMapper to find the service name instead of using
hard-coded service name.

Change-Id: If436c65d9a9a4942eaf30ea20bc7b85e3e7694c1
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/epoch_base.cpp b/epoch_base.cpp
index 07b3113..09337de 100644
--- a/epoch_base.cpp
+++ b/epoch_base.cpp
@@ -5,6 +5,14 @@
 #include <iomanip>
 #include <sstream>
 
+namespace // anonymous
+{
+constexpr auto SYSTEMD_TIME_SERVICE = "org.freedesktop.timedate1";
+constexpr auto SYSTEMD_TIME_PATH = "/org/freedesktop/timedate1";
+constexpr auto SYSTEMD_TIME_INTERFACE = "org.freedesktop.timedate1";
+constexpr auto METHOD_SET_TIME = "SetTime";
+}
+
 namespace phosphor
 {
 namespace time
@@ -32,10 +40,10 @@
 using namespace std::chrono;
 void EpochBase::setTime(const microseconds& usec)
 {
-    auto method = bus.new_method_call("org.freedesktop.timedate1",
-                                      "/org/freedesktop/timedate1",
-                                      "org.freedesktop.timedate1",
-                                      "SetTime");
+    auto method = bus.new_method_call(SYSTEMD_TIME_SERVICE,
+                                      SYSTEMD_TIME_PATH,
+                                      SYSTEMD_TIME_INTERFACE,
+                                      METHOD_SET_TIME);
     method.append(static_cast<int64_t>(usec.count()),
                   false, // relative
                   false); // user_interaction
diff --git a/manager.cpp b/manager.cpp
index 36ff351..03992b1 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -7,7 +7,6 @@
 
 namespace // anonymous
 {
-constexpr auto SETTINGS_SERVICE = "org.openbmc.settings.Host";
 constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
 constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
 
@@ -24,19 +23,17 @@
     rules::path("/org/openbmc/control/power0") +
     rules::interface("org.freedesktop.DBus.Properties");
 
-constexpr auto POWER_SERVICE = "org.openbmc.control.Power";
 constexpr auto POWER_PATH = "/org/openbmc/control/power0";
-constexpr auto POWER_INTERFACE = POWER_SERVICE;
+constexpr auto POWER_INTERFACE = "org.openbmc.control.Power";
 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 SYSTEMD_TIME_INTERFACE = "org.freedesktop.timedate1";
 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 OBMC_NETWORK_INTERFACE = "org.openbmc.NetworkManager";
 constexpr auto METHOD_UPDATE_USE_NTP = "UpdateUseNtpField";
 }
 
@@ -92,8 +89,17 @@
 
 void Manager::checkHostOn()
 {
+    std::string powerService = utils::getService(bus,
+                                                 POWER_PATH,
+                                                 POWER_INTERFACE);
+    if (powerService.empty())
+    {
+        log<level::ERR>("Failed to get power service, assume host is off");
+        return;
+    }
+
     int pgood = utils::getProperty<int>(bus,
-                                        POWER_SERVICE,
+                                        powerService.c_str(),
                                         POWER_PATH,
                                         POWER_INTERFACE,
                                         PGOOD_STR);
@@ -102,12 +108,7 @@
 
 void Manager::checkDhcpNtp()
 {
-    std::string useDhcpNtp = utils::getProperty<std::string>(
-                                 bus,
-                                 SETTINGS_SERVICE,
-                                 SETTINGS_PATH,
-                                 SETTINGS_INTERFACE,
-                                 PROPERTY_DHCP_NTP);
+    std::string useDhcpNtp = getSettings(PROPERTY_DHCP_NTP);
     updateDhcpNtpSetting(useDhcpNtp);
 }
 
@@ -217,7 +218,16 @@
 
 void Manager::updateDhcpNtpSetting(const std::string& useDhcpNtp)
 {
-    auto method = bus.new_method_call(OBMC_NETWORK_SERVICE,
+    std::string networkService = utils::getService(bus,
+                                                   OBMC_NETWORK_PATH,
+                                                   OBMC_NETWORK_INTERFACE);
+    if (networkService.empty())
+    {
+        log<level::ERR>("Failed to get network service, ignore dhcp ntp");
+        return;
+    }
+
+    auto method = bus.new_method_call(networkService.c_str(),
                                       OBMC_NETWORK_PATH,
                                       OBMC_NETWORK_INTERFACE,
                                       METHOD_UPDATE_USE_NTP);
@@ -333,14 +343,23 @@
     }
 }
 
-std::string Manager::getSettings(const char* value) const
+std::string Manager::getSettings(const char* setting) const
 {
-    return utils::getProperty<std::string>(
-        bus,
-        SETTINGS_SERVICE,
-        SETTINGS_PATH,
-        SETTINGS_INTERFACE,
-        value);
+    std::string settingsService = utils::getService(bus,
+                                                    SETTINGS_PATH,
+                                                    SETTINGS_INTERFACE);
+    if (settingsService.empty())
+    {
+        log<level::ERR>("Failed to get settings service, unable to get setting",
+                        entry("SETTING=%s", setting));
+        return {};
+    }
+
+    return utils::getProperty<std::string>(bus,
+                                           settingsService.c_str(),
+                                           SETTINGS_PATH,
+                                           SETTINGS_INTERFACE,
+                                           setting);
 }
 
 }
diff --git a/utils.cpp b/utils.cpp
index 16cd1b4..6df6ed5 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -10,6 +10,10 @@
 
 namespace // anonymous
 {
+constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
+constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+
 /** @brief The map that maps the string to Mode */
 const std::map<std::string, Mode> modeMap =
 {
@@ -32,6 +36,41 @@
 
 using namespace phosphor::logging;
 
+std::string getService(sdbusplus::bus::bus& bus,
+                       const char* path,
+                       const char* interface)
+{
+    auto mapper = bus.new_method_call(MAPPER_BUSNAME,
+                                      MAPPER_PATH,
+                                      MAPPER_INTERFACE,
+                                      "GetObject");
+
+    mapper.append(path, std::vector<std::string>({interface}));
+    auto mapperResponseMsg = bus.call(mapper);
+
+    if (mapperResponseMsg.is_method_error())
+    {
+        // TODO: define repo specific errors and use elog report()
+        log<level::ERR>("Error in mapper call",
+                        entry("PATH=%s", path),
+                        entry("INTERFACE=%s", interface));
+        return {};
+    }
+
+    std::map<std::string, std::vector<std::string>> mapperResponse;
+    mapperResponseMsg.read(mapperResponse);
+    if (mapperResponse.empty())
+    {
+        // TODO: define repo specific errors and use elog report()
+        log<level::ERR>("Error reading mapper response",
+                        entry("PATH=%s", path),
+                        entry("INTERFACE=%s", interface));
+        return {};
+    }
+
+    return mapperResponse.begin()->first;
+}
+
 Mode strToMode(const std::string& mode)
 {
     auto it = modeMap.find(mode);
diff --git a/utils.hpp b/utils.hpp
index 54b7d7d..ea2e3e4 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -89,6 +89,18 @@
     return value.template get<T>();
 }
 
+/** @brief Get service name from object path and interface
+ *
+ * @param[in] bus          - The Dbus bus object
+ * @param[in] path         - The Dbus object path
+ * @param[in] interface    - The Dbus interface
+ *
+ * @return The name of the service
+ */
+std::string getService(sdbusplus::bus::bus& bus,
+                       const char* path,
+                       const char* interface);
+
 /** @brief Convert a string to enum Mode
  *
  * Convert the time mode string to enum.