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 systemdTimeService = "org.freedesktop.timedate1";
15 constexpr auto systemdTimePath = "/org/freedesktop/timedate1";
16 constexpr auto systemdTimeInterface = "org.freedesktop.timedate1";
17 constexpr auto methodSetNtp = "SetNTP";
18 } // namespace
19 
20 namespace phosphor
21 {
22 namespace time
23 {
24 
25 PHOSPHOR_LOG2_USING;
26 
27 Manager::Manager(sdbusplus::bus_t& bus) : bus(bus), settings(bus)
28 {
29     using namespace sdbusplus::bus::match::rules;
30     settingsMatches.emplace_back(
31         bus, propertiesChanged(settings.timeSyncMethod, settings::timeSyncIntf),
32         [&](sdbusplus::message_t& m) { onSettingsChanged(m); });
33 
34     // Check the settings daemon to process the new settings
35     auto mode = getSetting(settings.timeSyncMethod.c_str(),
36                            settings::timeSyncIntf, propertyTimeMode);
37 
38     onPropertyChanged(propertyTimeMode, mode);
39 }
40 
41 void Manager::onPropertyChanged(const std::string& key,
42                                 const std::string& value)
43 {
44     assert(key == propertyTimeMode);
45 
46     // Notify listeners
47     setCurrentTimeMode(value);
48     onTimeModeChanged(value);
49 }
50 
51 int Manager::onSettingsChanged(sdbusplus::message_t& msg)
52 {
53     using Interface = std::string;
54     using Property = std::string;
55     using Value = std::string;
56     using Properties = std::map<Property, std::variant<Value>>;
57 
58     Interface interface;
59     Properties properties;
60 
61     msg.read(interface, properties);
62 
63     for (const auto& p : properties)
64     {
65         onPropertyChanged(p.first, std::get<std::string>(p.second));
66     }
67 
68     return 0;
69 }
70 
71 void Manager::updateNtpSetting(const std::string& value)
72 {
73     try
74     {
75         bool isNtp =
76             (value == "xyz.openbmc_project.Time.Synchronization.Method.NTP");
77         auto method = bus.new_method_call(systemdTimeService, systemdTimePath,
78                                           systemdTimeInterface, methodSetNtp);
79         method.append(isNtp, false); // isNtp: 'true/false' means Enable/Disable
80                                      // 'false' meaning no policy-kit
81 
82         bus.call_noreply(method);
83         info("Updated NTP setting: {ENABLED}", "ENABLED", isNtp);
84     }
85     catch (const sdbusplus::exception_t& ex)
86     {
87         error("Failed to update NTP setting: {ERROR}", "ERROR", ex);
88     }
89 }
90 
91 bool Manager::setCurrentTimeMode(const std::string& mode)
92 {
93     try
94     {
95         auto newMode = utils::strToMode(mode);
96         if (newMode != timeMode)
97         {
98             info("Time mode has been changed to {MODE}", "MODE", newMode);
99             timeMode = newMode;
100             return true;
101         }
102     }
103     catch (const sdbusplus::exception_t& ex)
104     {
105         error("Failed to convert mode from string: {ERROR}", "ERROR", ex);
106     }
107 
108     return false;
109 }
110 
111 void Manager::onTimeModeChanged(const std::string& mode)
112 {
113     // When time_mode is updated, update the NTP setting
114     updateNtpSetting(mode);
115 }
116 
117 std::string Manager::getSetting(const char* path, const char* interface,
118                                 const char* setting) const
119 {
120     try
121     {
122         std::string settingManager = utils::getService(bus, path, interface);
123         return utils::getProperty<std::string>(bus, settingManager.c_str(),
124                                                path, interface, setting);
125     }
126     catch (const std::exception& ex)
127     {
128         error(
129             "Failed to get property: {ERROR}, path: {PATH}, interface: {INTERFACE}, name: {NAME}",
130             "ERROR", ex, "PATH", path, "INTERFACE", interface, "NAME", setting);
131         return {};
132     }
133 }
134 
135 } // namespace time
136 } // namespace phosphor
137