xref: /openbmc/phosphor-time-manager/manager.cpp (revision c0e77cf805dbc85608b92ec593513f111619e5b8)
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