Switch to using new settings API
Change-Id: I0b0a9a70fcd8f1eb0f366bb2daf3d1fe77f3d648
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/time-config.cpp b/time-config.cpp
index 7dbd5c4..416ffc9 100644
--- a/time-config.cpp
+++ b/time-config.cpp
@@ -4,22 +4,52 @@
#include <memory>
#include <mapper.h>
#include <cassert>
+#include <cctype>
+#include <algorithm>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
#include "time-manager.hpp"
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
std::map<std::string, TimeConfig::FUNCTOR> TimeConfig::iv_TimeParams = {
- { "time_mode", std::make_tuple(&TimeConfig::getSystemSettings,
- &TimeConfig::updateTimeMode)
- },
-
- { "time_owner", std::make_tuple(&TimeConfig::getSystemSettings,
- &TimeConfig::updateTimeOwner)
- },
-
+ // TODO via openbmc/openbmc#668 - openbmc/openbmc#1770 is still work in
+ // progress at the time of writing this, so the use_dhcp_ntp is still using
+ // the old org.openbmc settings interfaces. The whole of time manager is
+ // anyway being rewritten to use new xyz.openbmc_project interfaces; as part
+ // of that switching to new setting interfaces is also covered.
{ "use_dhcp_ntp", std::make_tuple(&TimeConfig::getSystemSettings,
&TimeConfig::updateNetworkSettings)
}
};
+namespace internal
+{
+namespace setting
+{
+
+/** @brief Convert d-bus enum string to native string. For eg, convert
+ * "xyz.openbmc_project.Time.Owner.Split" to "SPLIT".
+ *
+ * @param[in] value - setting enum string
+ *
+ * @return converted string
+ */
+inline auto dbusToNative(std::string&& value)
+{
+ auto setting = std::move(value);
+ auto index = setting.find_last_of('.') + 1;
+ setting = setting.substr(index, setting.length() - index);
+ std::transform(setting.begin(), setting.end(), setting.begin(),
+ [](unsigned char c){ return std::toupper(c); });
+ return setting;
+}
+
+} // namespace setting
+} // namespace internal
+
TimeConfig::TimeConfig() :
iv_dbus(nullptr),
iv_CurrTimeMode(timeModes::MANUAL),
@@ -288,6 +318,29 @@
// First call from TimeManager to config manager
iv_dbus = dbus;
+ auto timeOwnerFunctor = std::make_tuple(&TimeConfig::getTimeOwnerSetting,
+ &TimeConfig::updateTimeOwner);
+ iv_TimeParams.emplace(settings.timeOwner, std::move(timeOwnerFunctor));
+ auto timeSyncFunctor = std::make_tuple(
+ &TimeConfig::getTimeSyncMethodSetting,
+ &TimeConfig::updateTimeMode);
+ iv_TimeParams.emplace(settings.timeSyncMethod, std::move(timeSyncFunctor));
+
+ using namespace sdbusplus::bus::match::rules;
+ sdbusplus::bus::bus bus(iv_dbus);
+
+ settingsMatches.emplace_back(
+ bus,
+ propertiesChanged(settings.timeOwner, settings::timeOwnerIntf),
+ std::bind(std::mem_fn(&TimeConfig::settingsChanged),
+ this, std::placeholders::_1));
+
+ settingsMatches.emplace_back(
+ bus,
+ propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf),
+ std::bind(std::mem_fn(&TimeConfig::settingsChanged),
+ this, std::placeholders::_1));
+
// Read saved info like Who was the owner , what was the mode,
// what was the use_dhcp_ntp setting before etc..
auto r = readPersistentData();
@@ -595,3 +648,79 @@
}
return 0;
}
+
+std::string TimeConfig::getTimeOwnerSetting(const char* path)
+{
+ sdbusplus::bus::bus bus{iv_dbus};
+ auto method = bus.new_method_call(
+ settings.service(settings.timeOwner,
+ settings::timeOwnerIntf).c_str(),
+ path,
+ "org.freedesktop.DBus.Properties",
+ "Get");
+ method.append(settings::timeOwnerIntf, "TimeOwner");
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Error in TimeOwner Get");
+ elog<InternalFailure>();
+ }
+
+ sdbusplus::message::variant<std::string> result;
+ reply.read(result);
+ // TODO via openbmc/openbmc#668 - because the old org.openbmc settings
+ // interfaces defined the time settings as strings, the code in this file
+ // is based around that fact. We use enums in the new settings interfaces,
+ // so code in this file can be changed to work with enums instead. That's
+ // being covered by the time manager rework (#668). For now, converting the
+ // settings to the string format that this object expects it to be.
+ // For eg, convert "xyz.openbmc_project.Time.Owner.Split" to "SPLIT".
+ auto setting = result.get<std::string>();
+ return internal::setting::dbusToNative(std::move(setting));
+}
+
+std::string TimeConfig::getTimeSyncMethodSetting(const char* path)
+{
+ sdbusplus::bus::bus bus{iv_dbus};
+ auto method = bus.new_method_call(
+ settings.service(settings.timeSyncMethod,
+ settings::timeSyncIntf).c_str(),
+ path,
+ "org.freedesktop.DBus.Properties",
+ "Get");
+ method.append(settings::timeSyncIntf, "TimeSyncMethod");
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Error in TimeSyncMethod Get");
+ elog<InternalFailure>();
+ }
+
+ sdbusplus::message::variant<std::string> result;
+ reply.read(result);
+ auto setting = result.get<std::string>();
+ return internal::setting::dbusToNative(std::move(setting));
+}
+
+int TimeConfig::settingsChanged(sdbusplus::message::message& msg)
+{
+ using Interface = std::string;
+ using Property = std::string;
+ using Value = std::string;
+ using Properties = std::map<Property, sdbusplus::message::variant<Value>>;
+
+ Interface interface;
+ Properties properties;
+
+ msg.read(interface, properties);
+
+ auto path = msg.get_path();
+ for(const auto& p : properties)
+ {
+ auto setting = p.second.get<std::string>();
+ updatePropertyVal(path,
+ internal::setting::dbusToNative(std::move(setting)));
+ }
+
+ return 0;
+}
diff --git a/time-config.hpp b/time-config.hpp
index 2d55b4b..257ab30 100644
--- a/time-config.hpp
+++ b/time-config.hpp
@@ -1,5 +1,6 @@
#include <map>
#include <systemd/sd-bus.h>
+#include <sdbusplus/bus/match.hpp>
#include "settings.hpp"
/** @class TimeConfig
@@ -194,6 +195,14 @@
// Most of this is statically constructed and PGOOD is added later.
static std::map<std::string, FUNCTOR> iv_TimeParams;
+ /** @brief Callback to handle change in a setting
+ *
+ * @param[in] msg - sdbusplus dbusmessage
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+ int settingsChanged(sdbusplus::message::message& msg);
+
private:
// Bus initialised by manager on a call to process initial settings
sd_bus *iv_dbus;
@@ -228,6 +237,9 @@
/** @brief Settings objects of intereset */
settings::Objects settings;
+ /** @brief sbdbusplus match objects */
+ std::vector<sdbusplus::bus::match_t> settingsMatches;
+
static constexpr auto cv_TimeModeFile = "/var/lib/obmc/saved_timeMode";
static constexpr auto cv_TimeOwnerFile = "/var/lib/obmc/saved_timeOwner";
static constexpr auto cv_DhcpNtpFile = "/var/lib/obmc/saved_dhcpNtp";
@@ -273,6 +285,22 @@
*/
std::string getSystemSettings(const char* key);
+ /** @brief Returns the time owner setting
+ *
+ * @param[in] path - Time owner setting object path
+ *
+ * @return - Value as string
+ */
+ std::string getTimeOwnerSetting(const char* path);
+
+ /** @brief Returns the time sync method setting
+ *
+ * @param[in] path - Time sync method setting object path
+ *
+ * @return - Value as string
+ */
+ std::string getTimeSyncMethodSetting(const char* path);
+
/** @brief Reads the data hosted by /org/openbmc/control/power0
*
* @param[in] key - Name of the property
diff --git a/time-manager.cpp b/time-manager.cpp
index 0279e4a..d0e7113 100644
--- a/time-manager.cpp
+++ b/time-manager.cpp
@@ -594,46 +594,7 @@
goto finish;
}
- if (!strcmp(key, "time_mode"))
- {
- r = sd_bus_message_read(m, "v", "s", &value);
- if (r < 0)
- {
- std::cerr << "Error: " << strerror(-r)
- << "reading timeMode" << std::endl;
- goto finish;
- }
- r = tmgr->config.updatePropertyVal(key, value);
- if (r < 0)
- {
- std::cerr << "Error: " << strerror(-r)
- << "processing timeMode" << std::endl;
- goto finish;
- }
- }
- else if (!strcmp(key, "time_owner"))
- {
- r = sd_bus_message_read(m, "v", "s", &value);
- if (r < 0)
- {
- std::cerr << "Error: " << strerror(-r)
- << "reading timeOwner" << std::endl;
- goto finish;
- }
- r = tmgr->config.updatePropertyVal(key, value);
- if (r < 0)
- {
- std::cerr << "Error: " << strerror(-r)
- << "processing time_owner" << std::endl;
- goto finish;
- }
- else if (tmgr->config.isSplitModeChanged())
- {
- // Must have been a change away from mode SPLIT
- tmgr->resetHostOffset();
- }
- }
- else if (!strcmp(key, "use_dhcp_ntp"))
+ if (!strcmp(key, "use_dhcp_ntp"))
{
r = sd_bus_message_read(m, "v", "s", &value);
if (r < 0)