1 #pragma once
2 
3 #include <sdbusplus/server.hpp>
4 #include <xyz/openbmc_project/Software/Activation/server.hpp>
5 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
6 #include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp"
7 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp"
8 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp"
9 #include "xyz/openbmc_project/Object/Delete/server.hpp"
10 #include "org/openbmc/Associations/server.hpp"
11 
12 namespace openpower
13 {
14 namespace software
15 {
16 namespace updater
17 {
18 
19 using AssociationList =
20         std::vector<std::tuple<std::string, std::string, std::string>>;
21 using ActivationInherit = sdbusplus::server::object::object<
22     sdbusplus::xyz::openbmc_project::Object::server::Delete,
23     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
24     sdbusplus::xyz::openbmc_project::Software::server::Activation,
25     sdbusplus::org::openbmc::server::Associations>;
26 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
27  sdbusplus::xyz::openbmc_project::Software::server::ActivationBlocksTransition>;
28 using RedundancyPriorityInherit = sdbusplus::server::object::object<
29     sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>;
30 using ActivationProgressInherit = sdbusplus::server::object::object<
31     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
32 
33 namespace sdbusRule = sdbusplus::bus::match::rules;
34 
35 class ItemUpdater;
36 class Activation;
37 class RedundancyPriority;
38 
39 /** @class RedundancyPriority
40  *  @brief OpenBMC RedundancyPriority implementation
41  *  @details A concrete implementation for
42  *  xyz.openbmc_project.Software.RedundancyPriority DBus API.
43  */
44 class RedundancyPriority : public RedundancyPriorityInherit
45 {
46     public:
47         /** @brief Constructs RedundancyPriority.
48          *
49          *  @param[in] bus    - The Dbus bus object
50          *  @param[in] path   - The Dbus object path
51          *  @param[in] parent - Parent object.
52          *  @param[in] value  - The redundancyPriority value
53          */
54         RedundancyPriority(sdbusplus::bus::bus& bus,
55                                    const std::string& path,
56                                    Activation& parent,
57                                    uint8_t value) :
58                                    RedundancyPriorityInherit(bus,
59                                    path.c_str(), true),
60                                    parent(parent),
61                                    bus(bus),
62                                    path(path)
63         {
64             // Set Property
65             priority(value);
66             std::vector<std::string> interfaces({interface});
67             bus.emit_interfaces_added(path.c_str(), interfaces);
68         }
69 
70         ~RedundancyPriority()
71         {
72             std::vector<std::string> interfaces({interface});
73             bus.emit_interfaces_removed(path.c_str(), interfaces);
74         }
75 
76         /** @brief Overloaded Priority property set function
77          *
78          *  @param[in] value - uint8_t
79          *
80          *  @return Success or exception thrown
81          */
82         uint8_t priority(uint8_t value) override;
83 
84         /** @brief Priority property get function
85          *
86          * @returns uint8_t - The Priority value
87          */
88         using RedundancyPriorityInherit::priority;
89 
90         /** @brief Parent Object. */
91         Activation& parent;
92 
93     private:
94         // TODO Remove once openbmc/openbmc#1975 is resolved
95         static constexpr auto interface =
96                 "xyz.openbmc_project.Software.RedundancyPriority";
97         sdbusplus::bus::bus& bus;
98         std::string path;
99 };
100 
101 /** @class ActivationBlocksTransition
102  *  @brief OpenBMC ActivationBlocksTransition implementation.
103  *  @details A concrete implementation for
104  *  xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
105  */
106 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
107 {
108     public:
109         /** @brief Constructs ActivationBlocksTransition.
110          *
111          * @param[in] bus    - The Dbus bus object
112          * @param[in] path   - The Dbus object path
113          */
114         ActivationBlocksTransition(sdbusplus::bus::bus& bus,
115                                    const std::string& path) :
116                    ActivationBlocksTransitionInherit(bus, path.c_str(), true),
117                    bus(bus),
118                    path(path)
119         {
120             std::vector<std::string> interfaces({interface});
121             bus.emit_interfaces_added(path.c_str(), interfaces);
122         }
123 
124         ~ActivationBlocksTransition()
125         {
126             std::vector<std::string> interfaces({interface});
127             bus.emit_interfaces_removed(path.c_str(), interfaces);
128         }
129 
130     private:
131         // TODO Remove once openbmc/openbmc#1975 is resolved
132         static constexpr auto interface =
133                 "xyz.openbmc_project.Software.ActivationBlocksTransition";
134         sdbusplus::bus::bus& bus;
135         std::string path;
136 };
137 
138 class ActivationProgress : public ActivationProgressInherit
139 {
140     public:
141         /** @brief Constructs ActivationProgress.
142          *
143          * @param[in] bus    - The Dbus bus object
144          * @param[in] path   - The Dbus object path
145          */
146         ActivationProgress(sdbusplus::bus::bus& bus,
147                            const std::string& path) :
148                    ActivationProgressInherit(bus, path.c_str(), true),
149                    bus(bus),
150                    path(path)
151        {
152            progress(0);
153            std::vector<std::string> interfaces({interface});
154            bus.emit_interfaces_added(path.c_str(), interfaces);
155        }
156 
157         ~ActivationProgress()
158         {
159             std::vector<std::string> interfaces({interface});
160             bus.emit_interfaces_removed(path.c_str(), interfaces);
161         }
162 
163     private:
164         // TODO Remove once openbmc/openbmc#1975 is resolved
165         static constexpr auto interface =
166                 "xyz.openbmc_project.Software.ActivationProgress";
167         sdbusplus::bus::bus& bus;
168         std::string path;
169 };
170 
171 /** @class Activation
172  *  @brief OpenBMC activation software management implementation.
173  *  @details A concrete implementation for
174  *  xyz.openbmc_project.Software.Activation DBus API.
175  */
176 class Activation : public ActivationInherit
177 {
178     public:
179         /** @brief Constructs Activation Software Manager
180          *
181          * @param[in] bus    - The Dbus bus object
182          * @param[in] path   - The Dbus object path
183          * @param[in] parent - Parent object.
184          * @param[in] versionId  - The software version id
185          * @param[in] extVersion - The extended version
186          * @param[in] activationStatus - The status of Activation
187          * @param[in] assocs - Association objects
188          */
189         Activation(sdbusplus::bus::bus& bus, const std::string& path,
190                    ItemUpdater& parent,
191                    std::string& versionId,
192                    std::string& extVersion,
193                    sdbusplus::xyz::openbmc_project::Software::
194                    server::Activation::Activations activationStatus,
195                    AssociationList& assocs) :
196                    ActivationInherit(bus, path.c_str(), true),
197                    bus(bus),
198                    path(path),
199                    parent(parent),
200                    versionId(versionId),
201                    systemdSignals(
202                            bus,
203                            sdbusRule::type::signal() +
204                            sdbusRule::member("JobRemoved") +
205                            sdbusRule::path("/org/freedesktop/systemd1") +
206                            sdbusRule::interface(
207                                    "org.freedesktop.systemd1.Manager"),
208                            std::bind(std::mem_fn(&Activation::unitStateChange),
209                                   this, std::placeholders::_1))
210         {
211             // Enable systemd signals
212             subscribeToSystemdSignals();
213             // Set Properties.
214             extendedVersion(extVersion);
215             activation(activationStatus);
216             associations(assocs);
217 
218             // Emit deferred signal.
219             emit_object_added();
220         }
221 
222         /** @brief Activation property get function
223          *
224          *  @returns One of Activation::Activations
225          */
226         using ActivationInherit::activation;
227 
228         /** @brief Overloaded Activation property setter function
229          *
230          *  @param[in] value - One of Activation::Activations
231          *
232          *  @return Success or exception thrown
233          */
234         Activations activation(Activations value) override;
235 
236         /** @brief Overloaded requestedActivation property setter function
237          *
238          *  @param[in] value - One of Activation::RequestedActivations
239          *
240          *  @return Success or exception thrown
241          */
242         RequestedActivations requestedActivation(RequestedActivations value)
243                 override;
244 
245         /** @brief Check if systemd state change is relevant to this object
246          *
247          * Instance specific interface to handle the detected systemd state
248          * change
249          *
250          * @param[in]  msg       - Data associated with subscribed signal
251          *
252          */
253         void unitStateChange(sdbusplus::message::message& msg);
254 
255         /**
256          * @brief subscribe to the systemd signals
257          *
258          * This object needs to capture when it's systemd targets complete
259          * so it can keep it's state updated
260          *
261          **/
262         void subscribeToSystemdSignals();
263 
264         /**
265          * @brief unsubscribe from the systemd signals
266          *
267          * Once the activation process has completed successfully, we can
268          * safely unsubscribe from systemd signals.
269          *
270          **/
271         void unsubscribeFromSystemdSignals();
272 
273         /** @brief Persistent sdbusplus DBus bus connection */
274         sdbusplus::bus::bus& bus;
275 
276         /** @brief Persistent DBus object path */
277         std::string path;
278 
279         /** @brief Parent Object. */
280         ItemUpdater& parent;
281 
282         /** @brief Version id */
283         std::string versionId;
284 
285         /** @brief Persistent ActivationBlocksTransition dbus object */
286         std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
287 
288         /** @brief Persistent ActivationProgress dbus object */
289         std::unique_ptr<ActivationProgress> activationProgress;
290 
291         /** @brief Persistent RedundancyPriority dbus object */
292         std::unique_ptr<RedundancyPriority> redundancyPriority;
293 
294         /** @brief Used to subscribe to dbus systemd signals **/
295         sdbusplus::bus::match_t systemdSignals;
296 
297         /** @brief Tracks whether the read-only & read-write volumes have been
298          *created as part of the activation process. **/
299         bool ubiVolumesCreated = false;
300 
301         /** @brief activation status property get function
302          *
303          * @returns Activations - The activation value
304          */
305         using ActivationInherit::activation;
306 
307         /** @brief Deletes the d-bus object.
308          *
309          *
310          * */
311         void delete_() override;
312 
313     private:
314         /** @brief Member function for clarity & brevity at activation start */
315         void startActivation();
316 
317         /** @brief Member function for clarity & brevity at activation end */
318         void finishActivation();
319 };
320 
321 } // namespace updater
322 } // namespace software
323 } // namespace openpower
324