diff options
-rw-r--r-- | manager.cpp | 120 | ||||
-rw-r--r-- | manager.hpp | 18 | ||||
-rw-r--r-- | test/TestManager.cpp | 3 | ||||
-rw-r--r-- | utils.hpp | 44 |
4 files changed, 150 insertions, 35 deletions
diff --git a/manager.cpp b/manager.cpp index 9810e14..56e0d0b 100644 --- a/manager.cpp +++ b/manager.cpp @@ -10,8 +10,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"; -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 @@ const auto MATCH_PGOOD_CHANGE = 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 @@ Manager::Manager(sdbusplus::bus::bus& bus) // 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::restoreSettings() 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 @@ void Manager::onPropertyChanged(const std::string& key, { listener->onModeChanged(timeMode); } + // When time_mode is updated, update the NTP setting + updateNtpSetting(value); } else if (key == PROPERTY_TIME_OWNER) { @@ -150,13 +163,20 @@ int Manager::onPropertyChanged(sd_bus_message* msg, 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 @@ void Manager::setRequestedOwner(const std::string& owner) 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 @@ void Manager::onPgoodChanged(bool pgood) { listener->onModeChanged(timeMode); } + updateNtpSetting(requestedMode); setRequestedMode({}); // Clear requested mode } if (!requestedOwner.empty()) @@ -257,23 +318,12 @@ void Manager::setCurrentTimeOwner(const std::string& owner) 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) diff --git a/manager.hpp b/manager.hpp index 7edb30f..7c00122 100644 --- a/manager.hpp +++ b/manager.hpp @@ -70,6 +70,9 @@ class Manager /** @brief Check if host is on and update hostOn variable */ void checkHostOn(); + /** @brief Check if use_dhcp_ntp is used and update NTP setting */ + void checkDhcpNtp(); + /** @brief Get setting from settingsd service * * @param[in] setting - The string of the setting @@ -126,6 +129,18 @@ class Manager */ void setRequestedOwner(const std::string& owner); + /** @brief Update the NTP setting to systemd time service + * + * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL" + */ + void updateNtpSetting(const std::string& value); + + /** @brief Update dhcp_ntp setting to OpenBMC network service + * + * @param[in] value - The use_dhcp_ntp value, e.g. "yes" or "no" + */ + void updateDhcpNtpSetting(const std::string& useDhcpNtp); + /** @brief The static function called on settings property changed * * @param[in] msg - Data associated with subscribed signal @@ -176,6 +191,9 @@ class Manager /** @brief The string of time owner property */ static constexpr auto PROPERTY_TIME_OWNER = "time_owner"; + /** @brief The string of use dhcp ntp property */ + static constexpr auto PROPERTY_DHCP_NTP = "use_dhcp_ntp"; + using Updater = std::function<void(const std::string&)>; /** @brief Map the property string to functions that shall diff --git a/test/TestManager.cpp b/test/TestManager.cpp index 935590e..1e4096e 100644 --- a/test/TestManager.cpp +++ b/test/TestManager.cpp @@ -135,5 +135,8 @@ TEST_F(TestManager, propertyChange) ASSERT_DEATH(notifyPropertyChanged("invalid property", "whatever"), ""); } +// TODO: if gmock is ready, add case to test +// updateNtpSetting() and updateNetworkSetting() + } } @@ -1,5 +1,7 @@ #pragma once +#include <phosphor-logging/log.hpp> + #include <fstream> namespace phosphor @@ -9,6 +11,8 @@ namespace time namespace utils { +using namespace phosphor::logging; + /** @brief Read data with type T from file * * @param[in] fileName - The name of file to read from @@ -42,6 +46,46 @@ void writeData(const char* fileName, T&& data) } } +/** @brief The template function to get property from the requested dbus path + * + * @param[in] bus - The Dbus bus object + * @param[in] service - The Dbus service name + * @param[in] path - The Dbus object path + * @param[in] interface - The Dbus interface + * @param[in] propertyName - The property name to get + * + * @return The value of the property + */ +template <typename T> +T getProperty(sdbusplus::bus::bus& bus, + const char* service, + const char* path, + const char* interface, + const char* propertyName) +{ + sdbusplus::message::variant<T> value{}; + auto method = bus.new_method_call(service, + path, + "org.freedesktop.DBus.Properties", + "Get"); + method.append(interface, propertyName); + auto reply = bus.call(method); + if (reply) + { + reply.read(value); + } + else + { + // TODO: use elog to throw exception + log<level::ERR>("Failed to get property", + entry("SERVICE=%s", service), + entry("PATH=%s", path), + entry("INTERFACE=%s", interface), + entry("PROPERTY=%s", propertyName)); + } + return value.template get<T>(); +} + } } } |