blob: 631a2da88900ad97aa16e3ee7bbbd6c128e21b8f [file] [log] [blame]
Lei YU415b9642017-02-09 11:37:26 +08001#include "manager.hpp"
Gunnar Millsab4cc6a2018-09-14 14:42:39 -05002
Lei YU7f4fca52017-02-23 15:15:51 +08003#include "utils.hpp"
Lei YU415b9642017-02-09 11:37:26 +08004
George Liu947b5342022-07-01 16:12:18 +08005#include <phosphor-logging/lg2.hpp>
Lei YU415b9642017-02-09 11:37:26 +08006
Pavithra Barithayaf93c4052023-04-26 23:28:13 -05007#include <cassert>
8
Lei YU415b9642017-02-09 11:37:26 +08009namespace rules = sdbusplus::bus::match::rules;
10
11namespace // anonymous
12{
Lei YUa7417132017-02-23 15:24:05 +080013
Pavithra Barithaya864e1732023-04-11 04:30:23 -050014constexpr auto systemdTimeService = "org.freedesktop.timedate1";
15constexpr auto systemdTimePath = "/org/freedesktop/timedate1";
16constexpr auto systemdTimeInterface = "org.freedesktop.timedate1";
17constexpr auto methodSetNtp = "SetNTP";
Jason Zhue1010302024-04-02 04:20:43 +000018constexpr auto propertyNtp = "NTP";
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050019} // namespace
Lei YU415b9642017-02-09 11:37:26 +080020
21namespace phosphor
22{
23namespace time
24{
25
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -050026PHOSPHOR_LOG2_USING;
27
Patrick Williams38679262022-07-22 19:26:55 -050028Manager::Manager(sdbusplus::bus_t& bus) : bus(bus), settings(bus)
Lei YU415b9642017-02-09 11:37:26 +080029{
Lei YU710d49b2017-08-01 17:10:17 +080030 using namespace sdbusplus::bus::match::rules;
Jason Zhue1010302024-04-02 04:20:43 +000031 timedateMatches.emplace_back(
32 bus, propertiesChanged(systemdTimePath, systemdTimeInterface),
33 [&](sdbusplus::message_t& m) { onTimedateChanged(m); });
Lei YU710d49b2017-08-01 17:10:17 +080034 settingsMatches.emplace_back(
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050035 bus, propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf),
William A. Kennington III56608002022-11-22 15:22:39 -080036 [&](sdbusplus::message_t& m) { onSettingsChanged(m); });
Lei YU710d49b2017-08-01 17:10:17 +080037
Lei YU7f4fca52017-02-23 15:15:51 +080038 // Check the settings daemon to process the new settings
Lei YU710d49b2017-08-01 17:10:17 +080039 auto mode = getSetting(settings.timeSyncMethod.c_str(),
Pavithra Barithaya864e1732023-04-11 04:30:23 -050040 settings::timeSyncIntf, propertyTimeMode);
Lei YU710d49b2017-08-01 17:10:17 +080041
Jason Zhue1010302024-04-02 04:20:43 +000042 onPropertyChanged(propertyTimeMode, mode, true);
Lei YU415b9642017-02-09 11:37:26 +080043}
44
Lei YU415b9642017-02-09 11:37:26 +080045void Manager::onPropertyChanged(const std::string& key,
Jason Zhue1010302024-04-02 04:20:43 +000046 const std::string& value, bool forceSet)
Lei YU415b9642017-02-09 11:37:26 +080047{
Pavithra Barithaya864e1732023-04-11 04:30:23 -050048 assert(key == propertyTimeMode);
George Liu0a704522020-04-13 14:51:40 +080049
Jason Zhue1010302024-04-02 04:20:43 +000050 bool newNtpMode = (settings::ntpSync == value);
51 bool oldNtpMode = (Mode::NTP == getTimeMode());
52 if (forceSet || (newNtpMode != oldNtpMode))
53 {
54 // Notify listeners
55 onTimeModeChanged(value);
56 setCurrentTimeMode(value);
57 debug("NTP property changed in phosphor-settings, update to systemd"
58 " time service.");
59 }
60 else
61 {
62 debug("NTP mode is already the same, skip setting to systemd time"
63 " service again.");
64 }
Lei YU415b9642017-02-09 11:37:26 +080065}
66
Patrick Williams38679262022-07-22 19:26:55 -050067int Manager::onSettingsChanged(sdbusplus::message_t& msg)
Lei YU710d49b2017-08-01 17:10:17 +080068{
69 using Interface = std::string;
70 using Property = std::string;
71 using Value = std::string;
Patrick Williamsc09ac3f2020-05-13 18:01:29 -050072 using Properties = std::map<Property, std::variant<Value>>;
Lei YU710d49b2017-08-01 17:10:17 +080073
74 Interface interface;
75 Properties properties;
76
77 msg.read(interface, properties);
78
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050079 for (const auto& p : properties)
Lei YU710d49b2017-08-01 17:10:17 +080080 {
Patrick Williams5b746c72020-05-13 11:49:35 -050081 onPropertyChanged(p.first, std::get<std::string>(p.second));
Lei YU710d49b2017-08-01 17:10:17 +080082 }
83
84 return 0;
85}
86
Jason Zhue1010302024-04-02 04:20:43 +000087int Manager::onTimedateChanged(sdbusplus::message_t& msg)
88{
89 using Properties = std::map<std::string, std::variant<std::string, bool>>;
90
91 std::string interface;
92 Properties properties;
93
94 msg.read(interface, properties);
95
96 auto iter = properties.find(propertyNtp);
97 if (iter == properties.end())
98 {
99 return -1;
100 }
101
102 try
103 {
104 bool newNtpMode = std::get<bool>(iter->second);
105 bool oldNtpMode = (Mode::NTP == getTimeMode());
106 if (newNtpMode != oldNtpMode)
107 {
Patrick Williamsc0e77cf2024-08-16 15:20:46 -0400108 const auto& timeMode =
109 newNtpMode ? settings::ntpSync : settings::manualSync;
Jason Zhue1010302024-04-02 04:20:43 +0000110 std::string settingManager = utils::getService(
111 bus, settings.timeSyncMethod.c_str(), settings::timeSyncIntf);
112 utils::setProperty(bus, settingManager, settings.timeSyncMethod,
113 settings::timeSyncIntf, propertyTimeMode,
114 timeMode);
115 setCurrentTimeMode(timeMode);
116 debug("NTP property changed in systemd time service, update to"
117 " phosphor-settings.");
118 }
119 else
120 {
121 debug("NTP mode is already the same, skip setting to"
122 " phosphor-settings again.");
123 }
124 }
125 catch (const std::exception& ex)
126 {
127 error("Failed to sync NTP: {ERROR}", "ERROR", ex);
128 }
129
130 return 0;
131}
132
Lei YUa7417132017-02-23 15:24:05 +0800133void Manager::updateNtpSetting(const std::string& value)
134{
Lei YU89efe6e2018-07-24 10:38:01 +0800135 try
Lei YUa7417132017-02-23 15:24:05 +0800136 {
George Liu7e5f9f72022-08-17 12:32:24 +0800137 bool isNtp =
138 (value == "xyz.openbmc_project.Time.Synchronization.Method.NTP");
Pavithra Barithaya864e1732023-04-11 04:30:23 -0500139 auto method = bus.new_method_call(systemdTimeService, systemdTimePath,
140 systemdTimeInterface, methodSetNtp);
George Liu7e5f9f72022-08-17 12:32:24 +0800141 method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable
142 // 'false' meaning no policy-kit
143
Lei YU89efe6e2018-07-24 10:38:01 +0800144 bus.call_noreply(method);
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -0500145 info("Updated NTP setting: {ENABLED}", "ENABLED", isNtp);
Lei YUa7417132017-02-23 15:24:05 +0800146 }
Patrick Williams38679262022-07-22 19:26:55 -0500147 catch (const sdbusplus::exception_t& ex)
Lei YUa7417132017-02-23 15:24:05 +0800148 {
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -0500149 error("Failed to update NTP setting: {ERROR}", "ERROR", ex);
Lei YUa7417132017-02-23 15:24:05 +0800150 }
151}
152
Lei YUa5003ce2017-02-24 15:35:25 +0800153bool Manager::setCurrentTimeMode(const std::string& mode)
Lei YU415b9642017-02-09 11:37:26 +0800154{
George Liu7e5f9f72022-08-17 12:32:24 +0800155 try
Lei YUa5003ce2017-02-24 15:35:25 +0800156 {
George Liu7e5f9f72022-08-17 12:32:24 +0800157 auto newMode = utils::strToMode(mode);
158 if (newMode != timeMode)
159 {
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -0500160 info("Time mode has been changed to {MODE}", "MODE", newMode);
George Liu7e5f9f72022-08-17 12:32:24 +0800161 timeMode = newMode;
162 return true;
163 }
Lei YUa5003ce2017-02-24 15:35:25 +0800164 }
George Liu7e5f9f72022-08-17 12:32:24 +0800165 catch (const sdbusplus::exception_t& ex)
Lei YUa5003ce2017-02-24 15:35:25 +0800166 {
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -0500167 error("Failed to convert mode from string: {ERROR}", "ERROR", ex);
Lei YUa5003ce2017-02-24 15:35:25 +0800168 }
George Liu7e5f9f72022-08-17 12:32:24 +0800169
170 return false;
Lei YU415b9642017-02-09 11:37:26 +0800171}
172
Lei YUa5003ce2017-02-24 15:35:25 +0800173void Manager::onTimeModeChanged(const std::string& mode)
174{
Lei YUa5003ce2017-02-24 15:35:25 +0800175 // When time_mode is updated, update the NTP setting
176 updateNtpSetting(mode);
177}
178
Gunnar Millsab4cc6a2018-09-14 14:42:39 -0500179std::string Manager::getSetting(const char* path, const char* interface,
Lei YU710d49b2017-08-01 17:10:17 +0800180 const char* setting) const
181{
George Liu7e5f9f72022-08-17 12:32:24 +0800182 try
183 {
184 std::string settingManager = utils::getService(bus, path, interface);
185 return utils::getProperty<std::string>(bus, settingManager.c_str(),
186 path, interface, setting);
187 }
188 catch (const std::exception& ex)
189 {
Pavithra Barithayadd42c7f2022-08-11 05:09:02 -0500190 error(
George Liu7e5f9f72022-08-17 12:32:24 +0800191 "Failed to get property: {ERROR}, path: {PATH}, interface: {INTERFACE}, name: {NAME}",
192 "ERROR", ex, "PATH", path, "INTERFACE", interface, "NAME", setting);
193 return {};
194 }
Lei YU710d49b2017-08-01 17:10:17 +0800195}
196
Gunnar Millsab4cc6a2018-09-14 14:42:39 -0500197} // namespace time
198} // namespace phosphor