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