1 #pragma once
2 
3 #include "config.h"
4 
5 #include "property_change_listener.hpp"
6 #include "settings.hpp"
7 #include "types.hpp"
8 
9 #include <sdbusplus/bus.hpp>
10 #include <sdbusplus/bus/match.hpp>
11 #include <set>
12 #include <string>
13 
14 namespace phosphor
15 {
16 namespace time
17 {
18 
19 /** @class Manager
20  *  @brief The manager to handle OpenBMC time.
21  *  @details It registers various time related settings and properties signals
22  *  on DBus and handle the changes.
23  *  For certain properties it also notifies the changed events to listeners.
24  */
25 class Manager
26 {
27   public:
28     friend class TestManager;
29 
30     explicit Manager(sdbusplus::bus::bus& bus);
31     Manager(const Manager&) = delete;
32     Manager& operator=(const Manager&) = delete;
33     Manager(Manager&&) = delete;
34     Manager& operator=(Manager&&) = delete;
35     ~Manager() = default;
36 
37     /** @brief Add a listener that will be called
38      * when property is changed
39      **/
40     void addListener(PropertyChangeListner* listener);
41 
42   private:
43     /** @brief Persistent sdbusplus DBus connection */
44     sdbusplus::bus::bus& bus;
45 
46     /** @brief The match of settings property change */
47     std::vector<sdbusplus::bus::match::match> settingsMatches;
48 
49     /** @brief The match of host state change */
50     std::unique_ptr<sdbusplus::bus::match::match> hostStateChangeMatch;
51 
52     /** @brief The container to hold all the listeners */
53     std::set<PropertyChangeListner*> listeners;
54 
55     /** @brief Settings objects of intereset */
56     settings::Objects settings;
57 
58     /** @brief The value to indicate if host is on */
59     bool hostOn = false;
60 
61     /** @brief The requested time mode when host is on*/
62     std::string requestedMode;
63 
64     /** @brief The requested time owner when host is on*/
65     std::string requestedOwner;
66 
67     /** @brief The current time mode */
68     Mode timeMode = DEFAULT_TIME_MODE;
69 
70     /** @brief The current time owner */
71     Owner timeOwner = DEFAULT_TIME_OWNER;
72 
73     /** @brief Restore saved settings */
74     void restoreSettings();
75 
76     /** @brief Check if host is on and update hostOn variable */
77     void checkHostOn();
78 
79     /** @brief Get setting from settingsd service
80      *
81      * @param[in] path - The dbus object path
82      * @param[in] interface - The dbus interface
83      * @param[in] setting - The string of the setting
84      *
85      * @return The setting value in string
86      */
87     std::string getSetting(const char* path, 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, const std::string& value);
136 
137     /** @brief Notified on host state has changed
138      *
139      * @param[in] msg - sdbusplus dbusmessage
140      */
141     void onHostStateChanged(sdbusplus::message::message& msg);
142 
143     /** @brief Notified on host state has changed
144      *
145      * @param[in] on - Indicate if the host is on or off
146      */
147     void onHostState(bool on);
148 
149     /** @brief Set the property as requested time mode/owner
150      *
151      * @param[in] key - The property name
152      * @param[in] value - The property value
153      */
154     void setPropertyAsRequested(const std::string& key,
155                                 const std::string& value);
156 
157     /** @brief Set the current mode to user requested one
158      *  if conditions allow it
159      *
160      * @param[in] mode - The string of time mode
161      */
162     void setRequestedMode(const std::string& mode);
163 
164     /** @brief Set the current owner to user requested one
165      *  if conditions allow it
166      *
167      * @param[in] owner - The string of time owner
168      */
169     void setRequestedOwner(const std::string& owner);
170 
171     /** @brief Update the NTP setting to systemd time service
172      *
173      * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL"
174      */
175     void updateNtpSetting(const std::string& value);
176 
177     /** @brief The static function called on settings property changed
178      *
179      * @param[in] msg - Data associated with subscribed signal
180      * @param[in] userData - Pointer to this object instance
181      * @param[out] retError  - Not used but required with signal API
182      */
183     static int onPropertyChanged(sd_bus_message* msg, void* userData,
184                                  sd_bus_error* retError);
185 
186     /** @brief The string of time mode property */
187     static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod";
188 
189     /** @brief The string of time owner property */
190     static constexpr auto PROPERTY_TIME_OWNER = "TimeOwner";
191 
192     using Updater = std::function<void(const std::string&)>;
193 
194     /** @brief Map the property string to functions that shall
195      *  be called when the property is changed
196      */
197     const std::map<std::string, Updater> propertyUpdaters = {
198         {PROPERTY_TIME_MODE,
199          std::bind(&Manager::setCurrentTimeMode, this, std::placeholders::_1)},
200         {PROPERTY_TIME_OWNER, std::bind(&Manager::setCurrentTimeOwner, this,
201                                         std::placeholders::_1)}};
202 
203     /** @brief The properties that manager shall notify the
204      *  listeners when changed
205      */
206     static const std::set<std::string> managedProperties;
207 
208     /** @brief The map that maps the string to Owners */
209     static const std::map<std::string, Owner> ownerMap;
210 
211     /** @brief The file name of saved time mode */
212     static constexpr auto modeFile = "/var/lib/obmc/saved_time_mode";
213 
214     /** @brief The file name of saved time owner */
215     static constexpr auto ownerFile = "/var/lib/obmc/saved_time_owner";
216 };
217 
218 } // namespace time
219 } // namespace phosphor
220