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