1 #include "manager.hpp" 2 3 #include "utils.hpp" 4 5 #include <assert.h> 6 7 #include <phosphor-logging/elog-errors.hpp> 8 #include <phosphor-logging/elog.hpp> 9 #include <phosphor-logging/lg2.hpp> 10 #include <xyz/openbmc_project/Common/error.hpp> 11 12 namespace rules = sdbusplus::bus::match::rules; 13 14 namespace // anonymous 15 { 16 17 constexpr auto SYSTEMD_TIME_SERVICE = "org.freedesktop.timedate1"; 18 constexpr auto SYSTEMD_TIME_PATH = "/org/freedesktop/timedate1"; 19 constexpr auto SYSTEMD_TIME_INTERFACE = "org.freedesktop.timedate1"; 20 constexpr auto METHOD_SET_NTP = "SetNTP"; 21 } // namespace 22 23 namespace phosphor 24 { 25 namespace time 26 { 27 28 using namespace phosphor::logging; 29 30 Manager::Manager(sdbusplus::bus_t& bus) : bus(bus), settings(bus) 31 { 32 using namespace sdbusplus::bus::match::rules; 33 settingsMatches.emplace_back( 34 bus, propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf), 35 std::bind(std::mem_fn(&Manager::onSettingsChanged), this, 36 std::placeholders::_1)); 37 38 // Check the settings daemon to process the new settings 39 auto mode = getSetting(settings.timeSyncMethod.c_str(), 40 settings::timeSyncIntf, PROPERTY_TIME_MODE); 41 42 onPropertyChanged(PROPERTY_TIME_MODE, mode); 43 } 44 45 void Manager::onPropertyChanged(const std::string& key, 46 const std::string& value) 47 { 48 assert(key == PROPERTY_TIME_MODE); 49 50 // Notify listeners 51 setCurrentTimeMode(value); 52 onTimeModeChanged(value); 53 } 54 55 int Manager::onSettingsChanged(sdbusplus::message_t& msg) 56 { 57 using Interface = std::string; 58 using Property = std::string; 59 using Value = std::string; 60 using Properties = std::map<Property, std::variant<Value>>; 61 62 Interface interface; 63 Properties properties; 64 65 msg.read(interface, properties); 66 67 for (const auto& p : properties) 68 { 69 onPropertyChanged(p.first, std::get<std::string>(p.second)); 70 } 71 72 return 0; 73 } 74 75 void Manager::updateNtpSetting(const std::string& value) 76 { 77 bool isNtp = 78 (value == "xyz.openbmc_project.Time.Synchronization.Method.NTP"); 79 auto method = bus.new_method_call(SYSTEMD_TIME_SERVICE, SYSTEMD_TIME_PATH, 80 SYSTEMD_TIME_INTERFACE, METHOD_SET_NTP); 81 method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable 82 // 'false' meaning no policy-kit 83 84 try 85 { 86 bus.call_noreply(method); 87 lg2::info("Updated NTP setting: {ENABLED}", "ENABLED", isNtp); 88 } 89 catch (const sdbusplus::exception_t& ex) 90 { 91 lg2::error("Failed to update NTP setting: {ERROR}", "ERROR", ex); 92 } 93 } 94 95 bool Manager::setCurrentTimeMode(const std::string& mode) 96 { 97 auto newMode = utils::strToMode(mode); 98 if (newMode != timeMode) 99 { 100 lg2::info("Time mode has been changed to {MODE}", "MODE", newMode); 101 timeMode = newMode; 102 return true; 103 } 104 else 105 { 106 return false; 107 } 108 } 109 110 void Manager::onTimeModeChanged(const std::string& mode) 111 { 112 // When time_mode is updated, update the NTP setting 113 updateNtpSetting(mode); 114 } 115 116 std::string Manager::getSetting(const char* path, const char* interface, 117 const char* setting) const 118 { 119 std::string settingManager = utils::getService(bus, path, interface); 120 return utils::getProperty<std::string>(bus, settingManager.c_str(), path, 121 interface, setting); 122 } 123 124 } // namespace time 125 } // namespace phosphor 126