summaryrefslogtreecommitdiffstats
path: root/manager.hpp
blob: e84652c0a64b1be46d6f69e9aa23cc498d89a0f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#pragma once

#include "types.hpp"
#include "property_change_listener.hpp"
#include "settings.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>

#include <set>
#include <string>

namespace phosphor
{
namespace time
{

/** @class Manager
 *  @brief The manager to handle OpenBMC time.
 *  @details It registers various time related settings and properties signals
 *  on DBus and handle the changes.
 *  For certain properties it also notifies the changed events to listeners.
 */
class Manager
{
    public:
        friend class TestManager;

        explicit Manager(sdbusplus::bus::bus& bus);
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = delete;
        Manager& operator=(Manager&&) = delete;
        ~Manager() = default;

        /** @brief Add a listener that will be called
          * when property is changed
         **/
        void addListener(PropertyChangeListner* listener);

    private:
        /** @brief Persistent sdbusplus DBus connection */
        sdbusplus::bus::bus& bus;

        /** @brief The match of settings property change */
        std::vector<sdbusplus::bus::match::match> settingsMatches;

        /** @brief The match of host state change */
        std::unique_ptr<sdbusplus::bus::match::match> hostStateChangeMatch;

        /** @brief The container to hold all the listeners */
        std::set<PropertyChangeListner*> listeners;

        /** @brief Settings objects of intereset */
        settings::Objects settings;

        /** @brief The value to indicate if host is on */
        bool hostOn = false;

        /** @brief The requested time mode when host is on*/
        std::string requestedMode;

        /** @brief The requested time owner when host is on*/
        std::string requestedOwner;

        /** @brief The current time mode */
        Mode timeMode;

        /** @brief The current time owner */
        Owner timeOwner;

        /** @brief Restore saved settings */
        void restoreSettings();

        /** @brief Check if host is on and update hostOn variable */
        void checkHostOn();

        /** @brief Get setting from settingsd service
         *
         * @param[in] path - The dbus object path
         * @param[in] interface - The dbus interface
         * @param[in] setting - The string of the setting
         *
         * @return The setting value in string
         */
        std::string getSetting(const char* path,
                               const char* interface,
                               const char* setting) const;

        /** @brief Set current time mode from the time mode string
         *
         * @param[in] mode - The string of time mode
         *
         * @return - true if the mode is updated
         *           false if it's the same as before
         */
        bool setCurrentTimeMode(const std::string& mode);

        /** @brief Set current time owner from the time owner string
         *
         * @param[in] owner - The string of time owner
         *
         * @return - true if the owner is updated
         *           false if it's the same as before
         */
        bool setCurrentTimeOwner(const std::string& owner);

        /** @brief Called on time mode is changed
         *
         * Notify listeners that time mode is changed and update ntp setting
         *
         * @param[in] mode - The string of time mode
         */
        void onTimeModeChanged(const std::string& mode);

        /** @brief Called on time owner is changed
         *
         * Notify listeners that time owner is changed
         */
        void onTimeOwnerChanged();

        /** @brief Callback to handle change in a setting
         *
         *  @param[in] msg - sdbusplus dbusmessage
         *
         *  @return 0 on success, < 0 on failure.
         */
        int onSettingsChanged(sdbusplus::message::message& msg);

        /** @brief Notified on settings property changed
         *
         * @param[in] key - The name of property that is changed
         * @param[in] value - The value of the property
         */
        void onPropertyChanged(const std::string& key,
                               const std::string& value);

        /** @brief Notified on host state has changed
         *
         * @param[in] msg - sdbusplus dbusmessage
         */
        void onHostStateChanged(sdbusplus::message::message& msg);

        /** @brief Notified on host state has changed
         *
         * @param[in] on - Indicate if the host is on or off
         */
        void onHostState(bool on);

        /** @brief Set the property as requested time mode/owner
         *
         * @param[in] key - The property name
         * @param[in] value - The property value
         */
        void setPropertyAsRequested(const std::string& key,
                                    const std::string& value);

        /** @brief Set the current mode to user requested one
         *  if conditions allow it
         *
         * @param[in] mode - The string of time mode
         */
        void setRequestedMode(const std::string& mode);

        /** @brief Set the current owner to user requested one
         *  if conditions allow it
         *
         * @param[in] owner - The string of time owner
         */
        void setRequestedOwner(const std::string& owner);

        /** @brief Update the NTP setting to systemd time service
         *
         * @param[in] value - The time mode value, e.g. "NTP" or "MANUAL"
         */
        void updateNtpSetting(const std::string& value);

        /** @brief The static function called on settings property changed
         *
         * @param[in] msg - Data associated with subscribed signal
         * @param[in] userData - Pointer to this object instance
         * @param[out] retError  - Not used but required with signal API
         */
        static int onPropertyChanged(sd_bus_message* msg,
                                     void* userData,
                                     sd_bus_error* retError);

        /** @brief The string of time mode property */
        static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod";

        /** @brief The string of time owner property */
        static constexpr auto PROPERTY_TIME_OWNER = "TimeOwner";

        using Updater = std::function<void(const std::string&)>;

        /** @brief Map the property string to functions that shall
         *  be called when the property is changed
         */
        const std::map<std::string, Updater> propertyUpdaters =
        {
            {PROPERTY_TIME_MODE, std::bind(&Manager::setCurrentTimeMode,
                                           this, std::placeholders::_1)},
            {PROPERTY_TIME_OWNER, std::bind(&Manager::setCurrentTimeOwner,
                                            this, std::placeholders::_1)}
        };

        /** @brief The properties that manager shall notify the
         *  listeners when changed
         */
        static const std::set<std::string> managedProperties;

        /** @brief The map that maps the string to Owners */
        static const std::map<std::string, Owner> ownerMap;

        /** @brief The file name of saved time mode */
        static constexpr auto modeFile = "/var/lib/obmc/saved_time_mode";

        /** @brief The file name of saved time owner */
        static constexpr auto ownerFile = "/var/lib/obmc/saved_time_owner";
};

}
}
OpenPOWER on IntegriCloud