101539e7eSLei YU #pragma once
201539e7eSLei YU 
301539e7eSLei YU #include "config.h"
401539e7eSLei YU 
5*ffb36539SLei 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);
5481c67725SLei YU     }
5581c67725SLei YU 
5681c67725SLei YU     ~ActivationBlocksTransition()
5781c67725SLei YU     {
5881c67725SLei YU         std::vector<std::string> interfaces({interface});
5981c67725SLei YU         bus.emit_interfaces_removed(path.c_str(), interfaces);
6081c67725SLei YU     }
6181c67725SLei YU 
6281c67725SLei YU   private:
6381c67725SLei YU     // TODO Remove once openbmc/openbmc#1975 is resolved
6481c67725SLei YU     static constexpr auto interface =
6581c67725SLei YU         "xyz.openbmc_project.Software.ActivationBlocksTransition";
6681c67725SLei YU     sdbusplus::bus::bus& bus;
6781c67725SLei YU     std::string path;
6881c67725SLei YU };
6981c67725SLei YU 
7090c8a8b9SLei YU using ActivationProgressInherit = sdbusplus::server::object::object<
7190c8a8b9SLei YU     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
7290c8a8b9SLei YU 
7390c8a8b9SLei YU class ActivationProgress : public ActivationProgressInherit
7490c8a8b9SLei YU {
7590c8a8b9SLei YU   public:
7690c8a8b9SLei YU     /** @brief Constructs ActivationProgress.
7790c8a8b9SLei YU      *
7890c8a8b9SLei YU      * @param[in] bus    - The Dbus bus object
7990c8a8b9SLei YU      * @param[in] path   - The Dbus object path
8090c8a8b9SLei YU      */
8190c8a8b9SLei YU     ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) :
8290c8a8b9SLei YU         ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path)
8390c8a8b9SLei YU     {
8490c8a8b9SLei YU         progress(0);
8590c8a8b9SLei YU         std::vector<std::string> interfaces({interface});
8690c8a8b9SLei YU         bus.emit_interfaces_added(path.c_str(), interfaces);
8790c8a8b9SLei YU     }
8890c8a8b9SLei YU 
8990c8a8b9SLei YU     ~ActivationProgress()
9090c8a8b9SLei YU     {
9190c8a8b9SLei YU         std::vector<std::string> interfaces({interface});
9290c8a8b9SLei YU         bus.emit_interfaces_removed(path.c_str(), interfaces);
9390c8a8b9SLei YU     }
9490c8a8b9SLei YU 
9590c8a8b9SLei YU   private:
9690c8a8b9SLei YU     // TODO Remove once openbmc/openbmc#1975 is resolved
9790c8a8b9SLei YU     static constexpr auto interface =
9890c8a8b9SLei YU         "xyz.openbmc_project.Software.ActivationProgress";
9990c8a8b9SLei YU     sdbusplus::bus::bus& bus;
10090c8a8b9SLei YU     std::string path;
10190c8a8b9SLei YU };
10290c8a8b9SLei YU 
10301539e7eSLei YU using ActivationInherit = sdbusplus::server::object::object<
10401539e7eSLei YU     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
10591029448SLei YU     sdbusplus::xyz::openbmc_project::Software::server::Activation,
1069930137bSLei YU     sdbusplus::xyz::openbmc_project::Association::server::Definitions,
1079930137bSLei YU     sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
10801539e7eSLei YU 
10901539e7eSLei YU /** @class Activation
11001539e7eSLei YU  *  @brief OpenBMC activation software management implementation.
11101539e7eSLei YU  *  @details A concrete implementation for
11201539e7eSLei YU  *  xyz.openbmc_project.Software.Activation DBus API.
11301539e7eSLei YU  */
11401539e7eSLei YU class Activation : public ActivationInherit
11501539e7eSLei YU {
11601539e7eSLei YU   public:
117ff83c2a0SLei YU     friend class ::TestActivation;
11812c9f4c4SLei YU     using Status = Activations;
119ff83c2a0SLei YU 
12001539e7eSLei YU     /** @brief Constructs Activation Software Manager
12101539e7eSLei YU      *
12201539e7eSLei YU      * @param[in] bus    - The Dbus bus object
12301539e7eSLei YU      * @param[in] path   - The Dbus object path
12401539e7eSLei YU      * @param[in] versionId  - The software version id
12501539e7eSLei YU      * @param[in] extVersion - The extended version
12601539e7eSLei YU      * @param[in] activationStatus - The status of Activation
12791029448SLei YU      * @param[in] assocs - Association objects
1289930137bSLei YU      * @param[in] filePath - The image filesystem path
12901539e7eSLei YU      */
1309930137bSLei YU     Activation(sdbusplus::bus::bus& bus, const std::string& objPath,
13101539e7eSLei YU                const std::string& versionId, const std::string& extVersion,
1327f2a2152SLei YU                Status activationStatus, const AssociationList& assocs,
133*ffb36539SLei YU                const std::string& filePath,
1349930137bSLei YU                AssociationInterface* associationInterface,
135*ffb36539SLei YU                ActivationListener* activationListener) :
1369930137bSLei YU         ActivationInherit(bus, objPath.c_str(), true),
1379930137bSLei YU         bus(bus), objPath(objPath), versionId(versionId),
13812c9f4c4SLei YU         systemdSignals(
13912c9f4c4SLei YU             bus,
14012c9f4c4SLei YU             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
14112c9f4c4SLei YU                 sdbusRule::path("/org/freedesktop/systemd1") +
14212c9f4c4SLei YU                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
14312c9f4c4SLei YU             std::bind(&Activation::unitStateChange, this,
1447f2a2152SLei YU                       std::placeholders::_1)),
145*ffb36539SLei YU         associationInterface(associationInterface),
146*ffb36539SLei YU         activationListener(activationListener)
14701539e7eSLei YU     {
14801539e7eSLei YU         // Set Properties.
14901539e7eSLei YU         extendedVersion(extVersion);
15001539e7eSLei YU         activation(activationStatus);
15191029448SLei YU         associations(assocs);
1529930137bSLei YU         path(filePath);
15301539e7eSLei YU 
1549edb7330SLei YU         auto info = Version::getExtVersionInfo(extVersion);
1559edb7330SLei YU         manufacturer = info["manufacturer"];
1569edb7330SLei YU         model = info["model"];
1579edb7330SLei YU 
15801539e7eSLei YU         // Emit deferred signal.
15901539e7eSLei YU         emit_object_added();
16001539e7eSLei YU     }
16101539e7eSLei YU 
16201539e7eSLei YU     /** @brief Overloaded Activation property setter function
16301539e7eSLei YU      *
16401539e7eSLei YU      * @param[in] value - One of Activation::Activations
16501539e7eSLei YU      *
16601539e7eSLei YU      * @return Success or exception thrown
16701539e7eSLei YU      */
168ff83c2a0SLei YU     Status activation(Status value) override;
16901539e7eSLei YU 
17001539e7eSLei YU     /** @brief Activation */
17101539e7eSLei YU     using ActivationInherit::activation;
17201539e7eSLei YU 
17301539e7eSLei YU     /** @brief Overloaded requestedActivation property setter function
17401539e7eSLei YU      *
17501539e7eSLei YU      * @param[in] value - One of Activation::RequestedActivations
17601539e7eSLei YU      *
17701539e7eSLei YU      * @return Success or exception thrown
17801539e7eSLei YU      */
17901539e7eSLei YU     RequestedActivations
18001539e7eSLei YU         requestedActivation(RequestedActivations value) override;
18101539e7eSLei YU 
18263f9e712SLei YU     /** @brief Get the object path */
18363f9e712SLei YU     const std::string& getObjectPath() const
18463f9e712SLei YU     {
18563f9e712SLei YU         return objPath;
18663f9e712SLei YU     }
18763f9e712SLei YU 
188a5c47bb3SLei YU     /** @brief Get the version ID */
189a5c47bb3SLei YU     const std::string& getVersionId() const
190a5c47bb3SLei YU     {
191a5c47bb3SLei YU         return versionId;
192a5c47bb3SLei YU     }
19312c9f4c4SLei YU 
19412c9f4c4SLei YU   private:
19512c9f4c4SLei YU     /** @brief Check if systemd state change is relevant to this object
19612c9f4c4SLei YU      *
19712c9f4c4SLei YU      * Instance specific interface to handle the detected systemd state
19812c9f4c4SLei YU      * change
19912c9f4c4SLei YU      *
20012c9f4c4SLei YU      * @param[in]  msg       - Data associated with subscribed signal
20112c9f4c4SLei YU      *
20212c9f4c4SLei YU      */
20312c9f4c4SLei YU     void unitStateChange(sdbusplus::message::message& msg);
20412c9f4c4SLei YU 
205d0bbfa9eSLei YU     /**
206d0bbfa9eSLei YU      * @brief Delete the version from Image Manager and the
207d0bbfa9eSLei YU      *        untar image from image upload dir.
208d0bbfa9eSLei YU      */
209d0bbfa9eSLei YU     void deleteImageManagerObject();
210d0bbfa9eSLei YU 
211ff83c2a0SLei YU     /** @brief Invoke the update service for the PSU
212ff83c2a0SLei YU      *
213ff83c2a0SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
214ff83c2a0SLei YU      *
215ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
216ff83c2a0SLei YU      */
217ff83c2a0SLei YU     bool doUpdate(const std::string& psuInventoryPath);
218ff83c2a0SLei YU 
219ff83c2a0SLei YU     /** @brief Do PSU update one-by-one
220ff83c2a0SLei YU      *
221ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
222ff83c2a0SLei YU      */
223ff83c2a0SLei YU     bool doUpdate();
224ff83c2a0SLei YU 
225ff83c2a0SLei YU     /** @brief Handle an update done event */
226ff83c2a0SLei YU     void onUpdateDone();
227ff83c2a0SLei YU 
228ff83c2a0SLei YU     /** @brief Handle an update failure event */
229ff83c2a0SLei YU     void onUpdateFailed();
230ff83c2a0SLei YU 
23112c9f4c4SLei YU     /** @brief Start PSU update */
232ff83c2a0SLei YU     Status startActivation();
23312c9f4c4SLei YU 
23412c9f4c4SLei YU     /** @brief Finish PSU update */
23512c9f4c4SLei YU     void finishActivation();
23612c9f4c4SLei YU 
2379edb7330SLei YU     /** @brief Check if the PSU is comaptible with this software*/
2389edb7330SLei YU     bool isCompatible(const std::string& psuInventoryPath);
2399edb7330SLei YU 
2402e0e2de5SLei YU     /** @brief Store the updated PSU image to persistent dir */
2412e0e2de5SLei YU     void storeImage();
2422e0e2de5SLei YU 
243e8945ea6SLei YU     /** @brief Construct the systemd service name
244e8945ea6SLei YU      *
245e8945ea6SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
246e8945ea6SLei YU      *
247e8945ea6SLei YU      * @return The escaped string of systemd unit to do the PSU update.
248e8945ea6SLei YU      */
249e8945ea6SLei YU     std::string getUpdateService(const std::string& psuInventoryPath);
250e8945ea6SLei YU 
25101539e7eSLei YU     /** @brief Persistent sdbusplus DBus bus connection */
25201539e7eSLei YU     sdbusplus::bus::bus& bus;
25301539e7eSLei YU 
25401539e7eSLei YU     /** @brief Persistent DBus object path */
2559930137bSLei YU     std::string objPath;
25601539e7eSLei YU 
257a5c47bb3SLei YU     /** @brief Version id */
258a5c47bb3SLei YU     std::string versionId;
259a5c47bb3SLei YU 
26012c9f4c4SLei YU     /** @brief Used to subscribe to dbus systemd signals */
26112c9f4c4SLei YU     sdbusplus::bus::match_t systemdSignals;
26212c9f4c4SLei YU 
263ff83c2a0SLei YU     /** @brief The queue of psu objects to be updated */
264ff83c2a0SLei YU     std::queue<std::string> psuQueue;
265ff83c2a0SLei YU 
266ff83c2a0SLei YU     /** @brief The progress step for each PSU update is done */
267ff83c2a0SLei YU     uint32_t progressStep;
268ff83c2a0SLei YU 
26912c9f4c4SLei YU     /** @brief The PSU update systemd unit */
27012c9f4c4SLei YU     std::string psuUpdateUnit;
27181c67725SLei YU 
2727f2a2152SLei YU     /** @brief The PSU Inventory path of the current updating PSU */
2737f2a2152SLei YU     std::string currentUpdatingPsu;
2747f2a2152SLei YU 
27581c67725SLei YU     /** @brief Persistent ActivationBlocksTransition dbus object */
27681c67725SLei YU     std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
27790c8a8b9SLei YU 
27890c8a8b9SLei YU     /** @brief Persistent ActivationProgress dbus object */
27990c8a8b9SLei YU     std::unique_ptr<ActivationProgress> activationProgress;
2807f2a2152SLei YU 
2817f2a2152SLei YU     /** @brief The AssociationInterface pointer */
2827f2a2152SLei YU     AssociationInterface* associationInterface;
2839edb7330SLei YU 
284*ffb36539SLei YU     /** @brief The activationListener pointer */
285*ffb36539SLei YU     ActivationListener* activationListener;
286*ffb36539SLei YU 
2879edb7330SLei YU     /** @brief The PSU manufacturer of the software */
2889edb7330SLei YU     std::string manufacturer;
2899edb7330SLei YU 
2909edb7330SLei YU     /** @brief The PSU model of the software */
2919edb7330SLei YU     std::string model;
29201539e7eSLei YU };
29301539e7eSLei YU 
29401539e7eSLei YU } // namespace updater
29501539e7eSLei YU } // namespace software
29601539e7eSLei YU } // namespace phosphor
297