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) :
49*f356fdc9SAlbert Zhang         ActivationBlocksTransitionInherit(bus, path.c_str(),
50*f356fdc9SAlbert Zhang                                           action::emit_interface_added),
51*f356fdc9SAlbert Zhang         bus(bus)
5281c67725SLei YU     {
538afeee56SLei YU         enableRebootGuard();
5481c67725SLei YU     }
5581c67725SLei YU 
5681c67725SLei YU     ~ActivationBlocksTransition()
5781c67725SLei YU     {
588afeee56SLei YU         disableRebootGuard();
5981c67725SLei YU     }
6081c67725SLei YU 
6181c67725SLei YU   private:
6281c67725SLei YU     sdbusplus::bus::bus& bus;
638afeee56SLei YU 
648afeee56SLei YU     /** @brief Enables a Guard that blocks any BMC reboot commands */
658afeee56SLei YU     void enableRebootGuard();
668afeee56SLei YU 
678afeee56SLei YU     /** @brief Disables any guard that was blocking the BMC reboot */
688afeee56SLei YU     void disableRebootGuard();
6981c67725SLei YU };
7081c67725SLei YU 
7190c8a8b9SLei YU using ActivationProgressInherit = sdbusplus::server::object::object<
7290c8a8b9SLei YU     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
7390c8a8b9SLei YU 
7490c8a8b9SLei YU class ActivationProgress : public ActivationProgressInherit
7590c8a8b9SLei YU {
7690c8a8b9SLei YU   public:
7790c8a8b9SLei YU     /** @brief Constructs ActivationProgress.
7890c8a8b9SLei YU      *
7990c8a8b9SLei YU      * @param[in] bus    - The Dbus bus object
8090c8a8b9SLei YU      * @param[in] path   - The Dbus object path
8190c8a8b9SLei YU      */
8290c8a8b9SLei YU     ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
83*f356fdc9SAlbert Zhang         ActivationProgressInherit(bus, path.c_str(),
84*f356fdc9SAlbert Zhang                                   action::emit_interface_added)
8590c8a8b9SLei YU     {
8690c8a8b9SLei YU         progress(0);
8790c8a8b9SLei YU     }
8890c8a8b9SLei YU };
8990c8a8b9SLei YU 
9001539e7eSLei YU using ActivationInherit = sdbusplus::server::object::object<
9101539e7eSLei YU     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
9291029448SLei YU     sdbusplus::xyz::openbmc_project::Software::server::Activation,
939930137bSLei YU     sdbusplus::xyz::openbmc_project::Association::server::Definitions,
949930137bSLei YU     sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
9501539e7eSLei YU 
9601539e7eSLei YU /** @class Activation
9701539e7eSLei YU  *  @brief OpenBMC activation software management implementation.
9801539e7eSLei YU  *  @details A concrete implementation for
9901539e7eSLei YU  *  xyz.openbmc_project.Software.Activation DBus API.
10001539e7eSLei YU  */
10101539e7eSLei YU class Activation : public ActivationInherit
10201539e7eSLei YU {
10301539e7eSLei YU   public:
104ff83c2a0SLei YU     friend class ::TestActivation;
10512c9f4c4SLei YU     using Status = Activations;
106ff83c2a0SLei YU 
10701539e7eSLei YU     /** @brief Constructs Activation Software Manager
10801539e7eSLei YU      *
10901539e7eSLei YU      * @param[in] bus    - The Dbus bus object
11001539e7eSLei YU      * @param[in] path   - The Dbus object path
11101539e7eSLei YU      * @param[in] versionId  - The software version id
11201539e7eSLei YU      * @param[in] extVersion - The extended version
11301539e7eSLei YU      * @param[in] activationStatus - The status of Activation
11491029448SLei YU      * @param[in] assocs - Association objects
1159930137bSLei YU      * @param[in] filePath - The image filesystem path
11601539e7eSLei YU      */
1179930137bSLei YU     Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
11801539e7eSLei YU                const std::string& versionId, const std::string& extVersion,
1197f2a2152SLei YU                Status activationStatus, const AssociationList& assocs,
120ffb36539SLei YU                const std::string& filePath,
1219930137bSLei YU                AssociationInterface* associationInterface,
122ffb36539SLei YU                ActivationListener* activationListener) :
1239930137bSLei YU         ActivationInherit(bus, objPath.c_str(), true),
1249930137bSLei YU         bus(bus), objPath(objPath), versionId(versionId),
12512c9f4c4SLei YU         systemdSignals(
12612c9f4c4SLei YU             bus,
12712c9f4c4SLei YU             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
12812c9f4c4SLei YU                 sdbusRule::path("/org/freedesktop/systemd1") +
12912c9f4c4SLei YU                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
13012c9f4c4SLei YU             std::bind(&Activation::unitStateChange, this,
1317f2a2152SLei YU                       std::placeholders::_1)),
132ffb36539SLei YU         associationInterface(associationInterface),
133ffb36539SLei YU         activationListener(activationListener)
13401539e7eSLei YU     {
13501539e7eSLei YU         // Set Properties.
13601539e7eSLei YU         extendedVersion(extVersion);
13701539e7eSLei YU         activation(activationStatus);
13891029448SLei YU         associations(assocs);
1399930137bSLei YU         path(filePath);
14001539e7eSLei YU 
1419edb7330SLei YU         auto info = Version::getExtVersionInfo(extVersion);
1429edb7330SLei YU         manufacturer = info["manufacturer"];
1439edb7330SLei YU         model = info["model"];
1449edb7330SLei YU 
14501539e7eSLei YU         // Emit deferred signal.
14601539e7eSLei YU         emit_object_added();
14701539e7eSLei YU     }
14801539e7eSLei YU 
14901539e7eSLei YU     /** @brief Overloaded Activation property setter function
15001539e7eSLei YU      *
15101539e7eSLei YU      * @param[in] value - One of Activation::Activations
15201539e7eSLei YU      *
15301539e7eSLei YU      * @return Success or exception thrown
15401539e7eSLei YU      */
155ff83c2a0SLei YU     Status activation(Status value) override;
15601539e7eSLei YU 
15701539e7eSLei YU     /** @brief Activation */
15801539e7eSLei YU     using ActivationInherit::activation;
15901539e7eSLei YU 
16001539e7eSLei YU     /** @brief Overloaded requestedActivation property setter function
16101539e7eSLei YU      *
16201539e7eSLei YU      * @param[in] value - One of Activation::RequestedActivations
16301539e7eSLei YU      *
16401539e7eSLei YU      * @return Success or exception thrown
16501539e7eSLei YU      */
16601539e7eSLei YU     RequestedActivations
16701539e7eSLei YU         requestedActivation(RequestedActivations value) override;
16801539e7eSLei YU 
16963f9e712SLei YU     /** @brief Get the object path */
17063f9e712SLei YU     const std::string& getObjectPath() const
17163f9e712SLei YU     {
17263f9e712SLei YU         return objPath;
17363f9e712SLei YU     }
17463f9e712SLei YU 
175a5c47bb3SLei YU     /** @brief Get the version ID */
176a5c47bb3SLei YU     const std::string& getVersionId() const
177a5c47bb3SLei YU     {
178a5c47bb3SLei YU         return versionId;
179a5c47bb3SLei YU     }
18012c9f4c4SLei YU 
18112c9f4c4SLei YU   private:
18212c9f4c4SLei YU     /** @brief Check if systemd state change is relevant to this object
18312c9f4c4SLei YU      *
18412c9f4c4SLei YU      * Instance specific interface to handle the detected systemd state
18512c9f4c4SLei YU      * change
18612c9f4c4SLei YU      *
18712c9f4c4SLei YU      * @param[in]  msg       - Data associated with subscribed signal
18812c9f4c4SLei YU      *
18912c9f4c4SLei YU      */
19012c9f4c4SLei YU     void unitStateChange(sdbusplus::message::message& msg);
19112c9f4c4SLei YU 
192d0bbfa9eSLei YU     /**
193d0bbfa9eSLei YU      * @brief Delete the version from Image Manager and the
194d0bbfa9eSLei YU      *        untar image from image upload dir.
195d0bbfa9eSLei YU      */
196d0bbfa9eSLei YU     void deleteImageManagerObject();
197d0bbfa9eSLei YU 
198ff83c2a0SLei YU     /** @brief Invoke the update service for the PSU
199ff83c2a0SLei YU      *
200ff83c2a0SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
201ff83c2a0SLei YU      *
202ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
203ff83c2a0SLei YU      */
204ff83c2a0SLei YU     bool doUpdate(const std::string& psuInventoryPath);
205ff83c2a0SLei YU 
206ff83c2a0SLei YU     /** @brief Do PSU update one-by-one
207ff83c2a0SLei YU      *
208ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
209ff83c2a0SLei YU      */
210ff83c2a0SLei YU     bool doUpdate();
211ff83c2a0SLei YU 
212ff83c2a0SLei YU     /** @brief Handle an update done event */
213ff83c2a0SLei YU     void onUpdateDone();
214ff83c2a0SLei YU 
215ff83c2a0SLei YU     /** @brief Handle an update failure event */
216ff83c2a0SLei YU     void onUpdateFailed();
217ff83c2a0SLei YU 
21812c9f4c4SLei YU     /** @brief Start PSU update */
219ff83c2a0SLei YU     Status startActivation();
22012c9f4c4SLei YU 
22112c9f4c4SLei YU     /** @brief Finish PSU update */
22212c9f4c4SLei YU     void finishActivation();
22312c9f4c4SLei YU 
2249edb7330SLei YU     /** @brief Check if the PSU is comaptible with this software*/
2259edb7330SLei YU     bool isCompatible(const std::string& psuInventoryPath);
2269edb7330SLei YU 
2272e0e2de5SLei YU     /** @brief Store the updated PSU image to persistent dir */
2282e0e2de5SLei YU     void storeImage();
2292e0e2de5SLei YU 
230e8945ea6SLei YU     /** @brief Construct the systemd service name
231e8945ea6SLei YU      *
232e8945ea6SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
233e8945ea6SLei YU      *
234e8945ea6SLei YU      * @return The escaped string of systemd unit to do the PSU update.
235e8945ea6SLei YU      */
236e8945ea6SLei YU     std::string getUpdateService(const std::string& psuInventoryPath);
237e8945ea6SLei YU 
23801539e7eSLei YU     /** @brief Persistent sdbusplus DBus bus connection */
23901539e7eSLei YU     sdbusplus::bus::bus& bus;
24001539e7eSLei YU 
24101539e7eSLei YU     /** @brief Persistent DBus object path */
2429930137bSLei YU     std::string objPath;
24301539e7eSLei YU 
244a5c47bb3SLei YU     /** @brief Version id */
245a5c47bb3SLei YU     std::string versionId;
246a5c47bb3SLei YU 
24712c9f4c4SLei YU     /** @brief Used to subscribe to dbus systemd signals */
24812c9f4c4SLei YU     sdbusplus::bus::match_t systemdSignals;
24912c9f4c4SLei YU 
250ff83c2a0SLei YU     /** @brief The queue of psu objects to be updated */
251ff83c2a0SLei YU     std::queue<std::string> psuQueue;
252ff83c2a0SLei YU 
253ff83c2a0SLei YU     /** @brief The progress step for each PSU update is done */
254ff83c2a0SLei YU     uint32_t progressStep;
255ff83c2a0SLei YU 
25612c9f4c4SLei YU     /** @brief The PSU update systemd unit */
25712c9f4c4SLei YU     std::string psuUpdateUnit;
25881c67725SLei YU 
2597f2a2152SLei YU     /** @brief The PSU Inventory path of the current updating PSU */
2607f2a2152SLei YU     std::string currentUpdatingPsu;
2617f2a2152SLei YU 
26281c67725SLei YU     /** @brief Persistent ActivationBlocksTransition dbus object */
26381c67725SLei YU     std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
26490c8a8b9SLei YU 
26590c8a8b9SLei YU     /** @brief Persistent ActivationProgress dbus object */
26690c8a8b9SLei YU     std::unique_ptr<ActivationProgress> activationProgress;
2677f2a2152SLei YU 
2687f2a2152SLei YU     /** @brief The AssociationInterface pointer */
2697f2a2152SLei YU     AssociationInterface* associationInterface;
2709edb7330SLei YU 
271ffb36539SLei YU     /** @brief The activationListener pointer */
272ffb36539SLei YU     ActivationListener* activationListener;
273ffb36539SLei YU 
2749edb7330SLei YU     /** @brief The PSU manufacturer of the software */
2759edb7330SLei YU     std::string manufacturer;
2769edb7330SLei YU 
2779edb7330SLei YU     /** @brief The PSU model of the software */
2789edb7330SLei YU     std::string model;
27901539e7eSLei YU };
28001539e7eSLei YU 
28101539e7eSLei YU } // namespace updater
28201539e7eSLei YU } // namespace software
28301539e7eSLei YU } // namespace phosphor
284