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         std::vector<sdbusplus::bus::match::match> settingsMatches;
47 
48         /** @brief The match of host state change */
49         std::unique_ptr<sdbusplus::bus::match::match> hostStateChangeMatch;
50 
51         /** @brief The container to hold all the listeners */
52         std::set<PropertyChangeListner*> listeners;
53 
54         /** @brief Settings objects of intereset */
55         settings::Objects settings;
56 
57         /** @brief The value to indicate if host is on */
58         bool hostOn = false;
59 
60         /** @brief The requested time mode when host is on*/
61         std::string requestedMode;
62 
63         /** @brief The requested time owner when host is on*/
64         std::string requestedOwner;
65 
66         /** @brief The current time mode */
67         Mode timeMode;
68 
69         /** @brief The current time owner */
70         Owner timeOwner;
71 
72         /** @brief Restore saved settings */
73         void restoreSettings();
74 
75         /** @brief Check if host is on and update hostOn variable */
76         void checkHostOn();
77 
78         /** @brief Get setting from settingsd service
79          *
80          * @param[in] path - The dbus object path
81          * @param[in] interface - The dbus interface
82          * @param[in] setting - The string of the setting
83          *
84          * @return The setting value in string
85          */
86         std::string getSetting(const char* path,
87                                const char* interface,
88                                const char* setting) const;
89 
90         /** @brief Set current time mode from the time mode string
91          *
92          * @param[in] mode - The string of time mode
93          *
94          * @return - true if the mode is updated
95          *           false if it's the same as before
96          */
97         bool setCurrentTimeMode(const std::string& mode);
98 
99         /** @brief Set current time owner from the time owner string
100          *
101          * @param[in] owner - The string of time owner
102          *
103          * @return - true if the owner is updated
104          *           false if it's the same as before
105          */
106         bool setCurrentTimeOwner(const std::string& owner);
107 
108         /** @brief Called on time mode is changed
109          *
110          * Notify listeners that time mode is changed and update ntp setting
111          *
112          * @param[in] mode - The string of time mode
113          */
114         void onTimeModeChanged(const std::string& mode);
115 
116         /** @brief Called on time owner is changed
117          *
118          * Notify listeners that time owner is changed
119          */
120         void onTimeOwnerChanged();
121 
122         /** @brief Callback to handle change in a setting
123          *
124          *  @param[in] msg - sdbusplus dbusmessage
125          *
126          *  @return 0 on success, < 0 on failure.
127          */
128         int onSettingsChanged(sdbusplus::message::message& msg);
129 
130         /** @brief Notified on settings property changed
131          *
132          * @param[in] key - The name of property that is changed
133          * @param[in] value - The value of the property
134          */
135         void onPropertyChanged(const std::string& key,
136                                const std::string& value);
137 
138         /** @brief Notified on host state has changed
139          *
140          * @param[in] msg - sdbusplus dbusmessage
141          */
142         void onHostStateChanged(sdbusplus::message::message& msg);
143 
144         /** @brief Notified on host state has changed
145          *
146          * @param[in] on - Indicate if the host is on or off
147          */
148         void onHostState(bool on);
149 
150         /** @brief Set the property as requested time mode/owner
151          *
152          * @param[in] key - The property name
153          * @param[in] value - The property value
154          */
155         void setPropertyAsRequested(const std::string& key,
156                                     const std::string& value);
157 
158         /** @brief Set the current mode to user requested one
159          *  if conditions allow it
160          *
161          * @param[in] mode - The string of time mode
162          */
163         void setRequestedMode(const std::string& mode);
164 
165         /** @brief Set the current owner to user requested one
166          *  if conditions allow it
167          *
168          * @param[in] owner - The string of time owner
169          */
170         void setRequestedOwner(const std::string& owner);
171 
172         /** @brief Update the NTP setting to systemd time service
173          *
174          * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL"
175          */
176         void updateNtpSetting(const std::string& value);
177 
178         /** @brief The static function called on settings property changed
179          *
180          * @param[in] msg - Data associated with subscribed signal
181          * @param[in] userData - Pointer to this object instance
182          * @param[out] retError  - Not used but required with signal API
183          */
184         static int onPropertyChanged(sd_bus_message* msg,
185                                      void* userData,
186                                      sd_bus_error* retError);
187 
188         /** @brief The string of time mode property */
189         static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod";
190 
191         /** @brief The string of time owner property */
192         static constexpr auto PROPERTY_TIME_OWNER = "TimeOwner";
193 
194         using Updater = std::function<void(const std::string&)>;
195 
196         /** @brief Map the property string to functions that shall
197          *  be called when the property is changed
198          */
199         const std::map<std::string, Updater> propertyUpdaters =
200         {
201             {PROPERTY_TIME_MODE, std::bind(&Manager::setCurrentTimeMode,
202                                            this, std::placeholders::_1)},
203             {PROPERTY_TIME_OWNER, std::bind(&Manager::setCurrentTimeOwner,
204                                             this, std::placeholders::_1)}
205         };
206 
207         /** @brief The properties that manager shall notify the
208          *  listeners when changed
209          */
210         static const std::set<std::string> managedProperties;
211 
212         /** @brief The map that maps the string to Owners */
213         static const std::map<std::string, Owner> ownerMap;
214 
215         /** @brief The file name of saved time mode */
216         static constexpr auto modeFile = "/var/lib/obmc/saved_time_mode";
217 
218         /** @brief The file name of saved time owner */
219         static constexpr auto ownerFile = "/var/lib/obmc/saved_time_owner";
220 };
221 
222 }
223 }
224