101539e7eSLei YU #pragma once
201539e7eSLei YU 
301539e7eSLei YU #include "config.h"
401539e7eSLei YU 
5ffb36539SLei YU #include "activation_listener.hpp"
67f2a2152SLei YU #include "association_interface.hpp"
791029448SLei YU #include "types.hpp"
89edb7330SLei YU #include "version.hpp"
991029448SLei YU 
10ff83c2a0SLei YU #include <queue>
1101539e7eSLei YU #include <sdbusplus/server.hpp>
1291029448SLei YU #include <xyz/openbmc_project/Association/Definitions/server.hpp>
139930137bSLei YU #include <xyz/openbmc_project/Common/FilePath/server.hpp>
1401539e7eSLei YU #include <xyz/openbmc_project/Software/Activation/server.hpp>
1581c67725SLei YU #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
1690c8a8b9SLei YU #include <xyz/openbmc_project/Software/ActivationProgress/server.hpp>
1701539e7eSLei YU #include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
1801539e7eSLei YU 
19ff83c2a0SLei YU class TestActivation;
20ff83c2a0SLei YU 
2101539e7eSLei YU namespace phosphor
2201539e7eSLei YU {
2301539e7eSLei YU namespace software
2401539e7eSLei YU {
2501539e7eSLei YU namespace updater
2601539e7eSLei YU {
2701539e7eSLei YU 
2812c9f4c4SLei YU namespace sdbusRule = sdbusplus::bus::match::rules;
2912c9f4c4SLei YU 
3081c67725SLei YU using ActivationBlocksTransitionInherit = sdbusplus::server::object::object<
3181c67725SLei YU     sdbusplus::xyz::openbmc_project::Software::server::
3281c67725SLei YU         ActivationBlocksTransition>;
3381c67725SLei YU 
3481c67725SLei YU /** @class ActivationBlocksTransition
3581c67725SLei YU  *  @brief OpenBMC ActivationBlocksTransition implementation.
3681c67725SLei YU  *  @details A concrete implementation for
3781c67725SLei YU  *  xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
3881c67725SLei YU  */
3981c67725SLei YU class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
4081c67725SLei YU {
4181c67725SLei YU   public:
4281c67725SLei YU     /** @brief Constructs ActivationBlocksTransition.
4381c67725SLei YU      *
4481c67725SLei YU      * @param[in] bus    - The Dbus bus object
4581c67725SLei YU      * @param[in] path   - The Dbus object path
4681c67725SLei YU      */
4781c67725SLei YU     ActivationBlocksTransition(sdbusplus::bus::bus& bus,
4881c67725SLei YU                                const std::string& path) :
4981c67725SLei YU         ActivationBlocksTransitionInherit(bus, path.c_str(), true),
5081c67725SLei YU         bus(bus), path(path)
5181c67725SLei YU     {
5281c67725SLei YU         std::vector<std::string> interfaces({interface});
5381c67725SLei YU         bus.emit_interfaces_added(path.c_str(), interfaces);
54*8afeee56SLei YU         enableRebootGuard();
5581c67725SLei YU     }
5681c67725SLei YU 
5781c67725SLei YU     ~ActivationBlocksTransition()
5881c67725SLei YU     {
5981c67725SLei YU         std::vector<std::string> interfaces({interface});
6081c67725SLei YU         bus.emit_interfaces_removed(path.c_str(), interfaces);
61*8afeee56SLei YU         disableRebootGuard();
6281c67725SLei YU     }
6381c67725SLei YU 
6481c67725SLei YU   private:
6581c67725SLei YU     // TODO Remove once openbmc/openbmc#1975 is resolved
6681c67725SLei YU     static constexpr auto interface =
6781c67725SLei YU         "xyz.openbmc_project.Software.ActivationBlocksTransition";
6881c67725SLei YU     sdbusplus::bus::bus& bus;
6981c67725SLei YU     std::string path;
70*8afeee56SLei YU 
71*8afeee56SLei YU     /** @brief Enables a Guard that blocks any BMC reboot commands */
72*8afeee56SLei YU     void enableRebootGuard();
73*8afeee56SLei YU 
74*8afeee56SLei YU     /** @brief Disables any guard that was blocking the BMC reboot */
75*8afeee56SLei YU     void disableRebootGuard();
7681c67725SLei YU };
7781c67725SLei YU 
7890c8a8b9SLei YU using ActivationProgressInherit = sdbusplus::server::object::object<
7990c8a8b9SLei YU     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
8090c8a8b9SLei YU 
8190c8a8b9SLei YU class ActivationProgress : public ActivationProgressInherit
8290c8a8b9SLei YU {
8390c8a8b9SLei YU   public:
8490c8a8b9SLei YU     /** @brief Constructs ActivationProgress.
8590c8a8b9SLei YU      *
8690c8a8b9SLei YU      * @param[in] bus    - The Dbus bus object
8790c8a8b9SLei YU      * @param[in] path   - The Dbus object path
8890c8a8b9SLei YU      */
8990c8a8b9SLei YU     ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
9090c8a8b9SLei YU         ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
9190c8a8b9SLei YU     {
9290c8a8b9SLei YU         progress(0);
9390c8a8b9SLei YU         std::vector<std::string> interfaces({interface});
9490c8a8b9SLei YU         bus.emit_interfaces_added(path.c_str(), interfaces);
9590c8a8b9SLei YU     }
9690c8a8b9SLei YU 
9790c8a8b9SLei YU     ~ActivationProgress()
9890c8a8b9SLei YU     {
9990c8a8b9SLei YU         std::vector<std::string> interfaces({interface});
10090c8a8b9SLei YU         bus.emit_interfaces_removed(path.c_str(), interfaces);
10190c8a8b9SLei YU     }
10290c8a8b9SLei YU 
10390c8a8b9SLei YU   private:
10490c8a8b9SLei YU     // TODO Remove once openbmc/openbmc#1975 is resolved
10590c8a8b9SLei YU     static constexpr auto interface =
10690c8a8b9SLei YU         "xyz.openbmc_project.Software.ActivationProgress";
10790c8a8b9SLei YU     sdbusplus::bus::bus& bus;
10890c8a8b9SLei YU     std::string path;
10990c8a8b9SLei YU };
11090c8a8b9SLei YU 
11101539e7eSLei YU using ActivationInherit = sdbusplus::server::object::object<
11201539e7eSLei YU     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
11391029448SLei YU     sdbusplus::xyz::openbmc_project::Software::server::Activation,
1149930137bSLei YU     sdbusplus::xyz::openbmc_project::Association::server::Definitions,
1159930137bSLei YU     sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
11601539e7eSLei YU 
11701539e7eSLei YU /** @class Activation
11801539e7eSLei YU  *  @brief OpenBMC activation software management implementation.
11901539e7eSLei YU  *  @details A concrete implementation for
12001539e7eSLei YU  *  xyz.openbmc_project.Software.Activation DBus API.
12101539e7eSLei YU  */
12201539e7eSLei YU class Activation : public ActivationInherit
12301539e7eSLei YU {
12401539e7eSLei YU   public:
125ff83c2a0SLei YU     friend class ::TestActivation;
12612c9f4c4SLei YU     using Status = Activations;
127ff83c2a0SLei YU 
12801539e7eSLei YU     /** @brief Constructs Activation Software Manager
12901539e7eSLei YU      *
13001539e7eSLei YU      * @param[in] bus    - The Dbus bus object
13101539e7eSLei YU      * @param[in] path   - The Dbus object path
13201539e7eSLei YU      * @param[in] versionId  - The software version id
13301539e7eSLei YU      * @param[in] extVersion - The extended version
13401539e7eSLei YU      * @param[in] activationStatus - The status of Activation
13591029448SLei YU      * @param[in] assocs - Association objects
1369930137bSLei YU      * @param[in] filePath - The image filesystem path
13701539e7eSLei YU      */
1389930137bSLei YU     Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
13901539e7eSLei YU                const std::string& versionId, const std::string& extVersion,
1407f2a2152SLei YU                Status activationStatus, const AssociationList& assocs,
141ffb36539SLei YU                const std::string& filePath,
1429930137bSLei YU                AssociationInterface* associationInterface,
143ffb36539SLei YU                ActivationListener* activationListener) :
1449930137bSLei YU         ActivationInherit(bus, objPath.c_str(), true),
1459930137bSLei YU         bus(bus), objPath(objPath), versionId(versionId),
14612c9f4c4SLei YU         systemdSignals(
14712c9f4c4SLei YU             bus,
14812c9f4c4SLei YU             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
14912c9f4c4SLei YU                 sdbusRule::path("/org/freedesktop/systemd1") +
15012c9f4c4SLei YU                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
15112c9f4c4SLei YU             std::bind(&Activation::unitStateChange, this,
1527f2a2152SLei YU                       std::placeholders::_1)),
153ffb36539SLei YU         associationInterface(associationInterface),
154ffb36539SLei YU         activationListener(activationListener)
15501539e7eSLei YU     {
15601539e7eSLei YU         // Set Properties.
15701539e7eSLei YU         extendedVersion(extVersion);
15801539e7eSLei YU         activation(activationStatus);
15991029448SLei YU         associations(assocs);
1609930137bSLei YU         path(filePath);
16101539e7eSLei YU 
1629edb7330SLei YU         auto info = Version::getExtVersionInfo(extVersion);
1639edb7330SLei YU         manufacturer = info["manufacturer"];
1649edb7330SLei YU         model = info["model"];
1659edb7330SLei YU 
16601539e7eSLei YU         // Emit deferred signal.
16701539e7eSLei YU         emit_object_added();
16801539e7eSLei YU     }
16901539e7eSLei YU 
17001539e7eSLei YU     /** @brief Overloaded Activation property setter function
17101539e7eSLei YU      *
17201539e7eSLei YU      * @param[in] value - One of Activation::Activations
17301539e7eSLei YU      *
17401539e7eSLei YU      * @return Success or exception thrown
17501539e7eSLei YU      */
176ff83c2a0SLei YU     Status activation(Status value) override;
17701539e7eSLei YU 
17801539e7eSLei YU     /** @brief Activation */
17901539e7eSLei YU     using ActivationInherit::activation;
18001539e7eSLei YU 
18101539e7eSLei YU     /** @brief Overloaded requestedActivation property setter function
18201539e7eSLei YU      *
18301539e7eSLei YU      * @param[in] value - One of Activation::RequestedActivations
18401539e7eSLei YU      *
18501539e7eSLei YU      * @return Success or exception thrown
18601539e7eSLei YU      */
18701539e7eSLei YU     RequestedActivations
18801539e7eSLei YU         requestedActivation(RequestedActivations value) override;
18901539e7eSLei YU 
19063f9e712SLei YU     /** @brief Get the object path */
19163f9e712SLei YU     const std::string& getObjectPath() const
19263f9e712SLei YU     {
19363f9e712SLei YU         return objPath;
19463f9e712SLei YU     }
19563f9e712SLei YU 
196a5c47bb3SLei YU     /** @brief Get the version ID */
197a5c47bb3SLei YU     const std::string& getVersionId() const
198a5c47bb3SLei YU     {
199a5c47bb3SLei YU         return versionId;
200a5c47bb3SLei YU     }
20112c9f4c4SLei YU 
20212c9f4c4SLei YU   private:
20312c9f4c4SLei YU     /** @brief Check if systemd state change is relevant to this object
20412c9f4c4SLei YU      *
20512c9f4c4SLei YU      * Instance specific interface to handle the detected systemd state
20612c9f4c4SLei YU      * change
20712c9f4c4SLei YU      *
20812c9f4c4SLei YU      * @param[in]  msg       - Data associated with subscribed signal
20912c9f4c4SLei YU      *
21012c9f4c4SLei YU      */
21112c9f4c4SLei YU     void unitStateChange(sdbusplus::message::message& msg);
21212c9f4c4SLei YU 
213d0bbfa9eSLei YU     /**
214d0bbfa9eSLei YU      * @brief Delete the version from Image Manager and the
215d0bbfa9eSLei YU      *        untar image from image upload dir.
216d0bbfa9eSLei YU      */
217d0bbfa9eSLei YU     void deleteImageManagerObject();
218d0bbfa9eSLei YU 
219ff83c2a0SLei YU     /** @brief Invoke the update service for the PSU
220ff83c2a0SLei YU      *
221ff83c2a0SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
222ff83c2a0SLei YU      *
223ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
224ff83c2a0SLei YU      */
225ff83c2a0SLei YU     bool doUpdate(const std::string& psuInventoryPath);
226ff83c2a0SLei YU 
227ff83c2a0SLei YU     /** @brief Do PSU update one-by-one
228ff83c2a0SLei YU      *
229ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
230ff83c2a0SLei YU      */
231ff83c2a0SLei YU     bool doUpdate();
232ff83c2a0SLei YU 
233ff83c2a0SLei YU     /** @brief Handle an update done event */
234ff83c2a0SLei YU     void onUpdateDone();
235ff83c2a0SLei YU 
236ff83c2a0SLei YU     /** @brief Handle an update failure event */
237ff83c2a0SLei YU     void onUpdateFailed();
238ff83c2a0SLei YU 
23912c9f4c4SLei YU     /** @brief Start PSU update */
240ff83c2a0SLei YU     Status startActivation();
24112c9f4c4SLei YU 
24212c9f4c4SLei YU     /** @brief Finish PSU update */
24312c9f4c4SLei YU     void finishActivation();
24412c9f4c4SLei YU 
2459edb7330SLei YU     /** @brief Check if the PSU is comaptible with this software*/
2469edb7330SLei YU     bool isCompatible(const std::string& psuInventoryPath);
2479edb7330SLei YU 
2482e0e2de5SLei YU     /** @brief Store the updated PSU image to persistent dir */
2492e0e2de5SLei YU     void storeImage();
2502e0e2de5SLei YU 
251e8945ea6SLei YU     /** @brief Construct the systemd service name
252e8945ea6SLei YU      *
253e8945ea6SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
254e8945ea6SLei YU      *
255e8945ea6SLei YU      * @return The escaped string of systemd unit to do the PSU update.
256e8945ea6SLei YU      */
257e8945ea6SLei YU     std::string getUpdateService(const std::string& psuInventoryPath);
258e8945ea6SLei YU 
25901539e7eSLei YU     /** @brief Persistent sdbusplus DBus bus connection */
26001539e7eSLei YU     sdbusplus::bus::bus& bus;
26101539e7eSLei YU 
26201539e7eSLei YU     /** @brief Persistent DBus object path */
2639930137bSLei YU     std::string objPath;
26401539e7eSLei YU 
265a5c47bb3SLei YU     /** @brief Version id */
266a5c47bb3SLei YU     std::string versionId;
267a5c47bb3SLei YU 
26812c9f4c4SLei YU     /** @brief Used to subscribe to dbus systemd signals */
26912c9f4c4SLei YU     sdbusplus::bus::match_t systemdSignals;
27012c9f4c4SLei YU 
271ff83c2a0SLei YU     /** @brief The queue of psu objects to be updated */
272ff83c2a0SLei YU     std::queue<std::string> psuQueue;
273ff83c2a0SLei YU 
274ff83c2a0SLei YU     /** @brief The progress step for each PSU update is done */
275ff83c2a0SLei YU     uint32_t progressStep;
276ff83c2a0SLei YU 
27712c9f4c4SLei YU     /** @brief The PSU update systemd unit */
27812c9f4c4SLei YU     std::string psuUpdateUnit;
27981c67725SLei YU 
2807f2a2152SLei YU     /** @brief The PSU Inventory path of the current updating PSU */
2817f2a2152SLei YU     std::string currentUpdatingPsu;
2827f2a2152SLei YU 
28381c67725SLei YU     /** @brief Persistent ActivationBlocksTransition dbus object */
28481c67725SLei YU     std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
28590c8a8b9SLei YU 
28690c8a8b9SLei YU     /** @brief Persistent ActivationProgress dbus object */
28790c8a8b9SLei YU     std::unique_ptr<ActivationProgress> activationProgress;
2887f2a2152SLei YU 
2897f2a2152SLei YU     /** @brief The AssociationInterface pointer */
2907f2a2152SLei YU     AssociationInterface* associationInterface;
2919edb7330SLei YU 
292ffb36539SLei YU     /** @brief The activationListener pointer */
293ffb36539SLei YU     ActivationListener* activationListener;
294ffb36539SLei YU 
2959edb7330SLei YU     /** @brief The PSU manufacturer of the software */
2969edb7330SLei YU     std::string manufacturer;
2979edb7330SLei YU 
2989edb7330SLei YU     /** @brief The PSU model of the software */
2999edb7330SLei YU     std::string model;
30001539e7eSLei YU };
30101539e7eSLei YU 
30201539e7eSLei YU } // namespace updater
30301539e7eSLei YU } // namespace software
30401539e7eSLei YU } // namespace phosphor
305