1415b964fSLei YU #include "manager.hpp"
2ab4cc6a5SGunnar Mills
37f4fca55SLei YU #include "utils.hpp"
4415b964fSLei YU
5947b5346SGeorge Liu #include <phosphor-logging/lg2.hpp>
6415b964fSLei YU
7f93c405fSPavithra Barithaya #include <cassert>
8f93c405fSPavithra Barithaya
9415b964fSLei YU namespace rules = sdbusplus::bus::match::rules;
10415b964fSLei YU
11415b964fSLei YU namespace // anonymous
12415b964fSLei YU {
13a741713cSLei YU
14864e173eSPavithra Barithaya constexpr auto systemdTimeService = "org.freedesktop.timedate1";
15864e173eSPavithra Barithaya constexpr auto systemdTimePath = "/org/freedesktop/timedate1";
16864e173eSPavithra Barithaya constexpr auto systemdTimeInterface = "org.freedesktop.timedate1";
17864e173eSPavithra Barithaya constexpr auto methodSetNtp = "SetNTP";
18e101030bSJason Zhu constexpr auto propertyNtp = "NTP";
19ab4cc6a5SGunnar Mills } // namespace
20415b964fSLei YU
21415b964fSLei YU namespace phosphor
22415b964fSLei YU {
23415b964fSLei YU namespace time
24415b964fSLei YU {
25415b964fSLei YU
26dd42c7faSPavithra Barithaya PHOSPHOR_LOG2_USING;
27dd42c7faSPavithra Barithaya
Manager(sdbusplus::bus_t & bus)2838679266SPatrick Williams Manager::Manager(sdbusplus::bus_t& bus) : bus(bus), settings(bus)
29415b964fSLei YU {
30710d49beSLei YU using namespace sdbusplus::bus::match::rules;
31e101030bSJason Zhu timedateMatches.emplace_back(
32e101030bSJason Zhu bus, propertiesChanged(systemdTimePath, systemdTimeInterface),
33e101030bSJason Zhu [&](sdbusplus::message_t& m) { onTimedateChanged(m); });
34710d49beSLei YU settingsMatches.emplace_back(
35ab4cc6a5SGunnar Mills bus, propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf),
3656608000SWilliam A. Kennington III [&](sdbusplus::message_t& m) { onSettingsChanged(m); });
37710d49beSLei YU
387f4fca55SLei YU // Check the settings daemon to process the new settings
39710d49beSLei YU auto mode = getSetting(settings.timeSyncMethod.c_str(),
40864e173eSPavithra Barithaya settings::timeSyncIntf, propertyTimeMode);
41710d49beSLei YU
42e101030bSJason Zhu onPropertyChanged(propertyTimeMode, mode, true);
43415b964fSLei YU }
44415b964fSLei YU
onPropertyChanged(const std::string & key,const std::string & value,bool forceSet)45415b964fSLei YU void Manager::onPropertyChanged(const std::string& key,
46e101030bSJason Zhu const std::string& value, bool forceSet)
47415b964fSLei YU {
48864e173eSPavithra Barithaya assert(key == propertyTimeMode);
490a70452aSGeorge Liu
50e101030bSJason Zhu bool newNtpMode = (settings::ntpSync == value);
51e101030bSJason Zhu bool oldNtpMode = (Mode::NTP == getTimeMode());
52e101030bSJason Zhu if (forceSet || (newNtpMode != oldNtpMode))
53e101030bSJason Zhu {
540a70452aSGeorge Liu // Notify listeners
55a5003cebSLei YU onTimeModeChanged(value);
56e101030bSJason Zhu setCurrentTimeMode(value);
57e101030bSJason Zhu debug("NTP property changed in phosphor-settings, update to systemd"
58e101030bSJason Zhu " time service.");
59e101030bSJason Zhu }
60e101030bSJason Zhu else
61e101030bSJason Zhu {
62e101030bSJason Zhu debug("NTP mode is already the same, skip setting to systemd time"
63e101030bSJason Zhu " service again.");
64e101030bSJason Zhu }
65415b964fSLei YU }
66415b964fSLei YU
onSettingsChanged(sdbusplus::message_t & msg)6738679266SPatrick Williams int Manager::onSettingsChanged(sdbusplus::message_t& msg)
68710d49beSLei YU {
69710d49beSLei YU using Interface = std::string;
70710d49beSLei YU using Property = std::string;
71710d49beSLei YU using Value = std::string;
72c09ac3faSPatrick Williams using Properties = std::map<Property, std::variant<Value>>;
73710d49beSLei YU
74710d49beSLei YU Interface interface;
75710d49beSLei YU Properties properties;
76710d49beSLei YU
77710d49beSLei YU msg.read(interface, properties);
78710d49beSLei YU
79710d49beSLei YU for (const auto& p : properties)
80710d49beSLei YU {
815b746c79SPatrick Williams onPropertyChanged(p.first, std::get<std::string>(p.second));
82710d49beSLei YU }
83710d49beSLei YU
84710d49beSLei YU return 0;
85710d49beSLei YU }
86710d49beSLei YU
onTimedateChanged(sdbusplus::message_t & msg)87e101030bSJason Zhu int Manager::onTimedateChanged(sdbusplus::message_t& msg)
88e101030bSJason Zhu {
89e101030bSJason Zhu using Properties = std::map<std::string, std::variant<std::string, bool>>;
90e101030bSJason Zhu
91e101030bSJason Zhu std::string interface;
92e101030bSJason Zhu Properties properties;
93e101030bSJason Zhu
94e101030bSJason Zhu msg.read(interface, properties);
95e101030bSJason Zhu
96e101030bSJason Zhu auto iter = properties.find(propertyNtp);
97e101030bSJason Zhu if (iter == properties.end())
98e101030bSJason Zhu {
99e101030bSJason Zhu return -1;
100e101030bSJason Zhu }
101e101030bSJason Zhu
102e101030bSJason Zhu try
103e101030bSJason Zhu {
104e101030bSJason Zhu bool newNtpMode = std::get<bool>(iter->second);
105e101030bSJason Zhu bool oldNtpMode = (Mode::NTP == getTimeMode());
106e101030bSJason Zhu if (newNtpMode != oldNtpMode)
107e101030bSJason Zhu {
108*c0e77cf8SPatrick Williams const auto& timeMode =
109*c0e77cf8SPatrick Williams newNtpMode ? settings::ntpSync : settings::manualSync;
110e101030bSJason Zhu std::string settingManager = utils::getService(
111e101030bSJason Zhu bus, settings.timeSyncMethod.c_str(), settings::timeSyncIntf);
112e101030bSJason Zhu utils::setProperty(bus, settingManager, settings.timeSyncMethod,
113e101030bSJason Zhu settings::timeSyncIntf, propertyTimeMode,
114e101030bSJason Zhu timeMode);
115e101030bSJason Zhu setCurrentTimeMode(timeMode);
116e101030bSJason Zhu debug("NTP property changed in systemd time service, update to"
117e101030bSJason Zhu " phosphor-settings.");
118e101030bSJason Zhu }
119e101030bSJason Zhu else
120e101030bSJason Zhu {
121e101030bSJason Zhu debug("NTP mode is already the same, skip setting to"
122e101030bSJason Zhu " phosphor-settings again.");
123e101030bSJason Zhu }
124e101030bSJason Zhu }
125e101030bSJason Zhu catch (const std::exception& ex)
126e101030bSJason Zhu {
127e101030bSJason Zhu error("Failed to sync NTP: {ERROR}", "ERROR", ex);
128e101030bSJason Zhu }
129e101030bSJason Zhu
130e101030bSJason Zhu return 0;
131e101030bSJason Zhu }
132e101030bSJason Zhu
updateNtpSetting(const std::string & value)133a741713cSLei YU void Manager::updateNtpSetting(const std::string& value)
134a741713cSLei YU {
1357e5f9f79SGeorge Liu try
1367e5f9f79SGeorge Liu {
137710d49beSLei YU bool isNtp =
138710d49beSLei YU (value == "xyz.openbmc_project.Time.Synchronization.Method.NTP");
139864e173eSPavithra Barithaya auto method = bus.new_method_call(systemdTimeService, systemdTimePath,
140864e173eSPavithra Barithaya systemdTimeInterface, methodSetNtp);
141a741713cSLei YU method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable
142a741713cSLei YU // 'false' meaning no policy-kit
143a741713cSLei YU
14489efe6edSLei YU bus.call_noreply(method);
145dd42c7faSPavithra Barithaya info("Updated NTP setting: {ENABLED}", "ENABLED", isNtp);
146a741713cSLei YU }
14738679266SPatrick Williams catch (const sdbusplus::exception_t& ex)
148a741713cSLei YU {
149dd42c7faSPavithra Barithaya error("Failed to update NTP setting: {ERROR}", "ERROR", ex);
150a741713cSLei YU }
151a741713cSLei YU }
152a741713cSLei YU
setCurrentTimeMode(const std::string & mode)153a5003cebSLei YU bool Manager::setCurrentTimeMode(const std::string& mode)
154a5003cebSLei YU {
1557e5f9f79SGeorge Liu try
1567e5f9f79SGeorge Liu {
157ddd54428SLei YU auto newMode = utils::strToMode(mode);
158a5003cebSLei YU if (newMode != timeMode)
159415b964fSLei YU {
160dd42c7faSPavithra Barithaya info("Time mode has been changed to {MODE}", "MODE", newMode);
161a5003cebSLei YU timeMode = newMode;
162a5003cebSLei YU return true;
163a5003cebSLei YU }
164a5003cebSLei YU }
1657e5f9f79SGeorge Liu catch (const sdbusplus::exception_t& ex)
1667e5f9f79SGeorge Liu {
167dd42c7faSPavithra Barithaya error("Failed to convert mode from string: {ERROR}", "ERROR", ex);
1687e5f9f79SGeorge Liu }
1697e5f9f79SGeorge Liu
1707e5f9f79SGeorge Liu return false;
171415b964fSLei YU }
172415b964fSLei YU
onTimeModeChanged(const std::string & mode)173a5003cebSLei YU void Manager::onTimeModeChanged(const std::string& mode)
174a5003cebSLei YU {
175a5003cebSLei YU // When time_mode is updated, update the NTP setting
176a5003cebSLei YU updateNtpSetting(mode);
177a5003cebSLei YU }
178a5003cebSLei YU
getSetting(const char * path,const char * interface,const char * setting) const179ab4cc6a5SGunnar Mills std::string Manager::getSetting(const char* path, const char* interface,
180710d49beSLei YU const char* setting) const
181710d49beSLei YU {
1827e5f9f79SGeorge Liu try
1837e5f9f79SGeorge Liu {
184710d49beSLei YU std::string settingManager = utils::getService(bus, path, interface);
1857e5f9f79SGeorge Liu return utils::getProperty<std::string>(bus, settingManager.c_str(),
1867e5f9f79SGeorge Liu path, interface, setting);
1877e5f9f79SGeorge Liu }
1887e5f9f79SGeorge Liu catch (const std::exception& ex)
1897e5f9f79SGeorge Liu {
190dd42c7faSPavithra Barithaya error(
1917e5f9f79SGeorge Liu "Failed to get property: {ERROR}, path: {PATH}, interface: {INTERFACE}, name: {NAME}",
1927e5f9f79SGeorge Liu "ERROR", ex, "PATH", path, "INTERFACE", interface, "NAME", setting);
1937e5f9f79SGeorge Liu return {};
1947e5f9f79SGeorge Liu }
195710d49beSLei YU }
196710d49beSLei YU
197ab4cc6a5SGunnar Mills } // namespace time
198ab4cc6a5SGunnar Mills } // namespace phosphor
199