1 #pragma once
2 
3 #include "types.hpp"
4 #include "property_change_listener.hpp"
5 #include "settings.hpp"
6 
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/bus/match.hpp>
9 
10 #include <set>
11 #include <string>
12 
13 namespace phosphor
14 {
15 namespace time
16 {
17 
18 /** @class Manager
19  *  @brief The manager to handle OpenBMC time.
20  *  @details It registers various time related settings and properties signals
21  *  on DBus and handle the changes.
22  *  For certain properties it also notifies the changed events to listeners.
23  */
24 class Manager
25 {
26     public:
27         friend class TestManager;
28 
29         explicit Manager(sdbusplus::bus::bus& bus);
30         Manager(const Manager&) = delete;
31         Manager& operator=(const Manager&) = delete;
32         Manager(Manager&&) = delete;
33         Manager& operator=(Manager&&) = delete;
34         ~Manager() = default;
35 
36         /** @brief Add a listener that will be called
37           * when property is changed
38          **/
39         void addListener(PropertyChangeListner* listener);
40 
41     private:
42         /** @brief Persistent sdbusplus DBus connection */
43         sdbusplus::bus::bus& bus;
44 
45         /** @brief The match of settings property change */
46         // TODO: This is to be removed when all properties are handled in
47         // new settings daemon
48         sdbusplus::bus::match::match propertyChangeMatch;
49 
50         /** @brief The match of settings property change */
51         std::vector<sdbusplus::bus::match::match> settingsMatches;
52 
53         /** @brief The match of pgood change */
54         sdbusplus::bus::match::match pgoodChangeMatch;
55 
56         /** @brief The container to hold all the listeners */
57         std::set<PropertyChangeListner*> listeners;
58 
59         /** @brief Settings objects of intereset */
60         settings::Objects settings;
61 
62         /** @brief The value to indicate if host is on */
63         bool hostOn = false;
64 
65         /** @brief The requested time mode when host is on*/
66         std::string requestedMode;
67 
68         /** @brief The requested time owner when host is on*/
69         std::string requestedOwner;
70 
71         /** @brief The current time mode */
72         Mode timeMode;
73 
74         /** @brief The current time owner */
75         Owner timeOwner;
76 
77         /** @brief Restore saved settings */
78         void restoreSettings();
79 
80         /** @brief Check if host is on and update hostOn variable */
81         void checkHostOn();
82 
83         /** @brief Check if use_dhcp_ntp is used and update NTP setting */
84         void checkDhcpNtp();
85 
86         /** @brief Get setting from settingsd service
87          *
88          * @param[in] setting - The string of the setting
89          *
90          * @return The setting value in string
91          */
92         std::string getSettings(const char* setting) const;
93 
94         /** @brief Get setting from settingsd service
95          *
96          * @param[in] path - The dbus object path
97          * @param[in] interface - The dbus interface
98          * @param[in] setting - The string of the setting
99          *
100          * @return The setting value in string
101          */
102         std::string getSetting(const char* path,
103                                const char* interface,
104                                const char* setting) const;
105 
106         /** @brief Set current time mode from the time mode string
107          *
108          * @param[in] mode - The string of time mode
109          *
110          * @return - true if the mode is updated
111          *           false if it's the same as before
112          */
113         bool setCurrentTimeMode(const std::string& mode);
114 
115         /** @brief Set current time owner from the time owner string
116          *
117          * @param[in] owner - The string of time owner
118          *
119          * @return - true if the owner is updated
120          *           false if it's the same as before
121          */
122         bool setCurrentTimeOwner(const std::string& owner);
123 
124         /** @brief Called on time mode is changed
125          *
126          * Notify listeners that time mode is changed and update ntp setting
127          *
128          * @param[in] mode - The string of time mode
129          */
130         void onTimeModeChanged(const std::string& mode);
131 
132         /** @brief Called on time owner is changed
133          *
134          * Notify listeners that time owner is changed
135          */
136         void onTimeOwnerChanged();
137 
138         /** @brief Callback to handle change in a setting
139          *
140          *  @param[in] msg - sdbusplus dbusmessage
141          *
142          *  @return 0 on success, < 0 on failure.
143          */
144         int onSettingsChanged(sdbusplus::message::message& msg);
145 
146         /** @brief Notified on settings property changed
147          *
148          * @param[in] key - The name of property that is changed
149          * @param[in] value - The value of the property
150          */
151         void onPropertyChanged(const std::string& key,
152                                const std::string& value);
153 
154         /** @brief Notified on pgood has changed
155          *
156          * @param[in] pgood - The changed pgood value
157          */
158         void onPgoodChanged(bool pgood);
159 
160         /** @brief Set the property as requested time mode/owner
161          *
162          * @param[in] key - The property name
163          * @param[in] value - The property value
164          */
165         void setPropertyAsRequested(const std::string& key,
166                                     const std::string& value);
167 
168         /** @brief Set the current mode to user requested one
169          *  if conditions allow it
170          *
171          * @param[in] mode - The string of time mode
172          */
173         void setRequestedMode(const std::string& mode);
174 
175         /** @brief Set the current owner to user requested one
176          *  if conditions allow it
177          *
178          * @param[in] owner - The string of time owner
179          */
180         void setRequestedOwner(const std::string& owner);
181 
182         /** @brief Update the NTP setting to systemd time service
183          *
184          * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL"
185          */
186         void updateNtpSetting(const std::string& value);
187 
188         /** @brief Update dhcp_ntp setting to OpenBMC network service
189          *
190          * @param[in] value - The use_dhcp_ntp value, e.g. "yes" or "no"
191          */
192         void updateDhcpNtpSetting(const std::string& useDhcpNtp);
193 
194         /** @brief The static function called on settings property changed
195          *
196          * @param[in] msg - Data associated with subscribed signal
197          * @param[in] userData - Pointer to this object instance
198          * @param[out] retError  - Not used but required with signal API
199          */
200         static int onPropertyChanged(sd_bus_message* msg,
201                                      void* userData,
202                                      sd_bus_error* retError);
203 
204         /** @brief Notified on pgood has changed
205          *
206          * @param[in] msg - Data associated with subscribed signal
207          * @param[in] userData - Pointer to this object instance
208          * @param[out] retError  - Not used but required with signal API
209          */
210         static int onPgoodChanged(sd_bus_message* msg,
211                                   void* userData,
212                                   sd_bus_error* retError);
213 
214         /** @brief The string of time mode property */
215         static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod";
216 
217         /** @brief The string of time owner property */
218         static constexpr auto PROPERTY_TIME_OWNER = "TimeOwner";
219 
220         /** @brief The string of use dhcp ntp property */
221         static constexpr auto PROPERTY_DHCP_NTP = "use_dhcp_ntp";
222 
223         using Updater = std::function<void(const std::string&)>;
224 
225         /** @brief Map the property string to functions that shall
226          *  be called when the property is changed
227          */
228         const std::map<std::string, Updater> propertyUpdaters =
229         {
230             {PROPERTY_TIME_MODE, std::bind(&Manager::setCurrentTimeMode,
231                                            this, std::placeholders::_1)},
232             {PROPERTY_TIME_OWNER, std::bind(&Manager::setCurrentTimeOwner,
233                                             this, std::placeholders::_1)}
234         };
235 
236         /** @brief The properties that manager shall notify the
237          *  listeners when changed
238          */
239         static const std::set<std::string> managedProperties;
240 
241         /** @brief The map that maps the string to Owners */
242         static const std::map<std::string, Owner> ownerMap;
243 
244         /** @brief The file name of saved time mode */
245         static constexpr auto modeFile = "/var/lib/obmc/saved_time_mode";
246 
247         /** @brief The file name of saved time owner */
248         static constexpr auto ownerFile = "/var/lib/obmc/saved_time_owner";
249 };
250 
251 }
252 }
253