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/log.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::bus& 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::message& 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 log<level::INFO>("Updated NTP setting", entry("ENABLED=%d", isNtp)); 88 } 89 catch (const sdbusplus::exception::SdBusError& ex) 90 { 91 log<level::ERR>("Failed to update NTP setting", 92 entry("ERR=%s", ex.what())); 93 } 94 } 95 96 bool Manager::setCurrentTimeMode(const std::string& mode) 97 { 98 auto newMode = utils::strToMode(mode); 99 if (newMode != timeMode) 100 { 101 log<level::INFO>("Time mode is changed", 102 entry("MODE=%s", mode.c_str())); 103 timeMode = newMode; 104 return true; 105 } 106 else 107 { 108 return false; 109 } 110 } 111 112 void Manager::onTimeModeChanged(const std::string& mode) 113 { 114 // When time_mode is updated, update the NTP setting 115 updateNtpSetting(mode); 116 } 117 118 std::string Manager::getSetting(const char* path, const char* interface, 119 const char* setting) const 120 { 121 std::string settingManager = utils::getService(bus, path, interface); 122 return utils::getProperty<std::string>(bus, settingManager.c_str(), path, 123 interface, setting); 124 } 125 126 } // namespace time 127 } // namespace phosphor 128