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 
1001539e7eSLei YU #include <sdbusplus/server.hpp>
1191029448SLei YU #include <xyz/openbmc_project/Association/Definitions/server.hpp>
129930137bSLei YU #include <xyz/openbmc_project/Common/FilePath/server.hpp>
1301539e7eSLei YU #include <xyz/openbmc_project/Software/Activation/server.hpp>
1481c67725SLei YU #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
1590c8a8b9SLei YU #include <xyz/openbmc_project/Software/ActivationProgress/server.hpp>
1601539e7eSLei YU #include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
1701539e7eSLei YU 
185670b188SPatrick Williams #include <queue>
195670b188SPatrick Williams 
20ff83c2a0SLei YU class TestActivation;
21ff83c2a0SLei YU 
2201539e7eSLei YU namespace phosphor
2301539e7eSLei YU {
2401539e7eSLei YU namespace software
2501539e7eSLei YU {
2601539e7eSLei YU namespace updater
2701539e7eSLei YU {
2801539e7eSLei YU 
2912c9f4c4SLei YU namespace sdbusRule = sdbusplus::bus::match::rules;
3012c9f4c4SLei YU 
31374fae56SPatrick Williams using ActivationBlocksTransitionInherit =
32374fae56SPatrick Williams     sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Software::
33374fae56SPatrick Williams                                     server::ActivationBlocksTransition>;
3481c67725SLei YU 
3581c67725SLei YU /** @class ActivationBlocksTransition
3681c67725SLei YU  *  @brief OpenBMC ActivationBlocksTransition implementation.
3781c67725SLei YU  *  @details A concrete implementation for
3881c67725SLei YU  *  xyz.openbmc_project.Software.ActivationBlocksTransition DBus API.
3981c67725SLei YU  */
4081c67725SLei YU class ActivationBlocksTransition : public ActivationBlocksTransitionInherit
4181c67725SLei YU {
4281c67725SLei YU   public:
43*66a54ad4SGeorge Liu     ActivationBlocksTransition() = delete;
44*66a54ad4SGeorge Liu     ActivationBlocksTransition(const ActivationBlocksTransition&) = delete;
45*66a54ad4SGeorge Liu     ActivationBlocksTransition&
46*66a54ad4SGeorge Liu         operator=(const ActivationBlocksTransition&) = delete;
47*66a54ad4SGeorge Liu     ActivationBlocksTransition(ActivationBlocksTransition&&) = delete;
48*66a54ad4SGeorge Liu     ActivationBlocksTransition&
49*66a54ad4SGeorge Liu         operator=(ActivationBlocksTransition&&) = delete;
50*66a54ad4SGeorge Liu 
5181c67725SLei YU     /** @brief Constructs ActivationBlocksTransition.
5281c67725SLei YU      *
5381c67725SLei YU      * @param[in] bus    - The Dbus bus object
5481c67725SLei YU      * @param[in] path   - The Dbus object path
5581c67725SLei YU      */
ActivationBlocksTransition(sdbusplus::bus_t & bus,const std::string & path)56374fae56SPatrick Williams     ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) :
57f356fdc9SAlbert Zhang         ActivationBlocksTransitionInherit(bus, path.c_str(),
58f356fdc9SAlbert Zhang                                           action::emit_interface_added),
59f356fdc9SAlbert Zhang         bus(bus)
6081c67725SLei YU     {
618afeee56SLei YU         enableRebootGuard();
6281c67725SLei YU     }
6381c67725SLei YU 
~ActivationBlocksTransition()64047d9944SGeorge Liu     ~ActivationBlocksTransition() override
6581c67725SLei YU     {
668afeee56SLei YU         disableRebootGuard();
6781c67725SLei YU     }
6881c67725SLei YU 
6981c67725SLei YU   private:
70374fae56SPatrick Williams     sdbusplus::bus_t& bus;
718afeee56SLei YU 
728afeee56SLei YU     /** @brief Enables a Guard that blocks any BMC reboot commands */
738afeee56SLei YU     void enableRebootGuard();
748afeee56SLei YU 
758afeee56SLei YU     /** @brief Disables any guard that was blocking the BMC reboot */
768afeee56SLei YU     void disableRebootGuard();
7781c67725SLei YU };
7881c67725SLei YU 
79374fae56SPatrick Williams using ActivationProgressInherit = sdbusplus::server::object_t<
8090c8a8b9SLei YU     sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
8190c8a8b9SLei YU 
8290c8a8b9SLei YU class ActivationProgress : public ActivationProgressInherit
8390c8a8b9SLei YU {
8490c8a8b9SLei YU   public:
8590c8a8b9SLei YU     /** @brief Constructs ActivationProgress.
8690c8a8b9SLei YU      *
8790c8a8b9SLei YU      * @param[in] bus    - The Dbus bus object
8890c8a8b9SLei YU      * @param[in] path   - The Dbus object path
8990c8a8b9SLei YU      */
ActivationProgress(sdbusplus::bus_t & bus,const std::string & path)90374fae56SPatrick Williams     ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) :
91f356fdc9SAlbert Zhang         ActivationProgressInherit(bus, path.c_str(),
92f356fdc9SAlbert Zhang                                   action::emit_interface_added)
9390c8a8b9SLei YU     {
9490c8a8b9SLei YU         progress(0);
9590c8a8b9SLei YU     }
9690c8a8b9SLei YU };
9790c8a8b9SLei YU 
98374fae56SPatrick Williams using ActivationInherit = sdbusplus::server::object_t<
9901539e7eSLei YU     sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
10091029448SLei YU     sdbusplus::xyz::openbmc_project::Software::server::Activation,
1019930137bSLei YU     sdbusplus::xyz::openbmc_project::Association::server::Definitions,
1029930137bSLei YU     sdbusplus::xyz::openbmc_project::Common::server::FilePath>;
10301539e7eSLei YU 
10401539e7eSLei YU /** @class Activation
10501539e7eSLei YU  *  @brief OpenBMC activation software management implementation.
10601539e7eSLei YU  *  @details A concrete implementation for
10701539e7eSLei YU  *  xyz.openbmc_project.Software.Activation DBus API.
10801539e7eSLei YU  */
10901539e7eSLei YU class Activation : public ActivationInherit
11001539e7eSLei YU {
11101539e7eSLei YU   public:
112ff83c2a0SLei YU     friend class ::TestActivation;
11312c9f4c4SLei YU     using Status = Activations;
114ff83c2a0SLei YU 
11501539e7eSLei YU     /** @brief Constructs Activation Software Manager
11601539e7eSLei YU      *
11701539e7eSLei YU      * @param[in] bus    - The Dbus bus object
11801539e7eSLei YU      * @param[in] path   - The Dbus object path
11901539e7eSLei YU      * @param[in] versionId  - The software version id
12001539e7eSLei YU      * @param[in] extVersion - The extended version
12101539e7eSLei YU      * @param[in] activationStatus - The status of Activation
12291029448SLei YU      * @param[in] assocs - Association objects
1239930137bSLei YU      * @param[in] filePath - The image filesystem path
12401539e7eSLei YU      */
Activation(sdbusplus::bus_t & bus,const std::string & objPath,const std::string & versionId,const std::string & extVersion,Status activationStatus,const AssociationList & assocs,const std::string & filePath,AssociationInterface * associationInterface,ActivationListener * activationListener)125374fae56SPatrick Williams     Activation(sdbusplus::bus_t& bus, const std::string& objPath,
12601539e7eSLei YU                const std::string& versionId, const std::string& extVersion,
1277f2a2152SLei YU                Status activationStatus, const AssociationList& assocs,
128ffb36539SLei YU                const std::string& filePath,
1299930137bSLei YU                AssociationInterface* associationInterface,
130ffb36539SLei YU                ActivationListener* activationListener) :
131434ae483STang Yiwei         ActivationInherit(bus, objPath.c_str(),
132434ae483STang Yiwei                           ActivationInherit::action::defer_emit),
1339930137bSLei YU         bus(bus), objPath(objPath), versionId(versionId),
13412c9f4c4SLei YU         systemdSignals(
13512c9f4c4SLei YU             bus,
13612c9f4c4SLei YU             sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
13712c9f4c4SLei YU                 sdbusRule::path("/org/freedesktop/systemd1") +
13812c9f4c4SLei YU                 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
13912c9f4c4SLei YU             std::bind(&Activation::unitStateChange, this,
1407f2a2152SLei YU                       std::placeholders::_1)),
141ffb36539SLei YU         associationInterface(associationInterface),
142ffb36539SLei YU         activationListener(activationListener)
14301539e7eSLei YU     {
14401539e7eSLei YU         // Set Properties.
14501539e7eSLei YU         extendedVersion(extVersion);
14601539e7eSLei YU         activation(activationStatus);
14791029448SLei YU         associations(assocs);
1489930137bSLei YU         path(filePath);
14901539e7eSLei YU 
1509edb7330SLei YU         auto info = Version::getExtVersionInfo(extVersion);
1519edb7330SLei YU         manufacturer = info["manufacturer"];
1529edb7330SLei YU         model = info["model"];
1539edb7330SLei YU 
15401539e7eSLei YU         // Emit deferred signal.
15501539e7eSLei YU         emit_object_added();
15601539e7eSLei YU     }
15701539e7eSLei YU 
15801539e7eSLei YU     /** @brief Overloaded Activation property setter function
15901539e7eSLei YU      *
16001539e7eSLei YU      * @param[in] value - One of Activation::Activations
16101539e7eSLei YU      *
16201539e7eSLei YU      * @return Success or exception thrown
16301539e7eSLei YU      */
164ff83c2a0SLei YU     Status activation(Status value) override;
16501539e7eSLei YU 
16601539e7eSLei YU     /** @brief Activation */
16701539e7eSLei YU     using ActivationInherit::activation;
16801539e7eSLei YU 
16901539e7eSLei YU     /** @brief Overloaded requestedActivation property setter function
17001539e7eSLei YU      *
17101539e7eSLei YU      * @param[in] value - One of Activation::RequestedActivations
17201539e7eSLei YU      *
17301539e7eSLei YU      * @return Success or exception thrown
17401539e7eSLei YU      */
17501539e7eSLei YU     RequestedActivations
17601539e7eSLei YU         requestedActivation(RequestedActivations value) override;
17701539e7eSLei YU 
17863f9e712SLei YU     /** @brief Get the object path */
getObjectPath() const17963f9e712SLei YU     const std::string& getObjectPath() const
18063f9e712SLei YU     {
18163f9e712SLei YU         return objPath;
18263f9e712SLei YU     }
18363f9e712SLei YU 
184a5c47bb3SLei YU     /** @brief Get the version ID */
getVersionId() const185a5c47bb3SLei YU     const std::string& getVersionId() const
186a5c47bb3SLei YU     {
187a5c47bb3SLei YU         return versionId;
188a5c47bb3SLei YU     }
18912c9f4c4SLei YU 
19012c9f4c4SLei YU   private:
19112c9f4c4SLei YU     /** @brief Check if systemd state change is relevant to this object
19212c9f4c4SLei YU      *
19312c9f4c4SLei YU      * Instance specific interface to handle the detected systemd state
19412c9f4c4SLei YU      * change
19512c9f4c4SLei YU      *
19612c9f4c4SLei YU      * @param[in]  msg       - Data associated with subscribed signal
19712c9f4c4SLei YU      *
19812c9f4c4SLei YU      */
199374fae56SPatrick Williams     void unitStateChange(sdbusplus::message_t& msg);
20012c9f4c4SLei YU 
201d0bbfa9eSLei YU     /**
202d0bbfa9eSLei YU      * @brief Delete the version from Image Manager and the
203d0bbfa9eSLei YU      *        untar image from image upload dir.
204d0bbfa9eSLei YU      */
205d0bbfa9eSLei YU     void deleteImageManagerObject();
206d0bbfa9eSLei YU 
207ff83c2a0SLei YU     /** @brief Invoke the update service for the PSU
208ff83c2a0SLei YU      *
209ff83c2a0SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
210ff83c2a0SLei YU      *
211ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
212ff83c2a0SLei YU      */
213ff83c2a0SLei YU     bool doUpdate(const std::string& psuInventoryPath);
214ff83c2a0SLei YU 
215ff83c2a0SLei YU     /** @brief Do PSU update one-by-one
216ff83c2a0SLei YU      *
217ff83c2a0SLei YU      * @return true if the update starts, and false if it fails.
218ff83c2a0SLei YU      */
219ff83c2a0SLei YU     bool doUpdate();
220ff83c2a0SLei YU 
221ff83c2a0SLei YU     /** @brief Handle an update done event */
222ff83c2a0SLei YU     void onUpdateDone();
223ff83c2a0SLei YU 
224ff83c2a0SLei YU     /** @brief Handle an update failure event */
225ff83c2a0SLei YU     void onUpdateFailed();
226ff83c2a0SLei YU 
22712c9f4c4SLei YU     /** @brief Start PSU update */
228ff83c2a0SLei YU     Status startActivation();
22912c9f4c4SLei YU 
23012c9f4c4SLei YU     /** @brief Finish PSU update */
23112c9f4c4SLei YU     void finishActivation();
23212c9f4c4SLei YU 
23333cf9f08SManojkiran Eda     /** @brief Check if the PSU is compatible with this software*/
2349edb7330SLei YU     bool isCompatible(const std::string& psuInventoryPath);
2359edb7330SLei YU 
2362e0e2de5SLei YU     /** @brief Store the updated PSU image to persistent dir */
2372e0e2de5SLei YU     void storeImage();
2382e0e2de5SLei YU 
239e8945ea6SLei YU     /** @brief Construct the systemd service name
240e8945ea6SLei YU      *
241e8945ea6SLei YU      * @param[in] psuInventoryPath - The PSU inventory to be updated.
242e8945ea6SLei YU      *
243e8945ea6SLei YU      * @return The escaped string of systemd unit to do the PSU update.
244e8945ea6SLei YU      */
245e8945ea6SLei YU     std::string getUpdateService(const std::string& psuInventoryPath);
246e8945ea6SLei YU 
24701539e7eSLei YU     /** @brief Persistent sdbusplus DBus bus connection */
248374fae56SPatrick Williams     sdbusplus::bus_t& bus;
24901539e7eSLei YU 
25001539e7eSLei YU     /** @brief Persistent DBus object path */
2519930137bSLei YU     std::string objPath;
25201539e7eSLei YU 
253a5c47bb3SLei YU     /** @brief Version id */
254a5c47bb3SLei YU     std::string versionId;
255a5c47bb3SLei YU 
25612c9f4c4SLei YU     /** @brief Used to subscribe to dbus systemd signals */
25712c9f4c4SLei YU     sdbusplus::bus::match_t systemdSignals;
25812c9f4c4SLei YU 
259ff83c2a0SLei YU     /** @brief The queue of psu objects to be updated */
260ff83c2a0SLei YU     std::queue<std::string> psuQueue;
261ff83c2a0SLei YU 
262ff83c2a0SLei YU     /** @brief The progress step for each PSU update is done */
263ff83c2a0SLei YU     uint32_t progressStep;
264ff83c2a0SLei YU 
26512c9f4c4SLei YU     /** @brief The PSU update systemd unit */
26612c9f4c4SLei YU     std::string psuUpdateUnit;
26781c67725SLei YU 
2687f2a2152SLei YU     /** @brief The PSU Inventory path of the current updating PSU */
2697f2a2152SLei YU     std::string currentUpdatingPsu;
2707f2a2152SLei YU 
27181c67725SLei YU     /** @brief Persistent ActivationBlocksTransition dbus object */
27281c67725SLei YU     std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition;
27390c8a8b9SLei YU 
27490c8a8b9SLei YU     /** @brief Persistent ActivationProgress dbus object */
27590c8a8b9SLei YU     std::unique_ptr<ActivationProgress> activationProgress;
2767f2a2152SLei YU 
2777f2a2152SLei YU     /** @brief The AssociationInterface pointer */
2787f2a2152SLei YU     AssociationInterface* associationInterface;
2799edb7330SLei YU 
280ffb36539SLei YU     /** @brief The activationListener pointer */
281ffb36539SLei YU     ActivationListener* activationListener;
282ffb36539SLei YU 
2839edb7330SLei YU     /** @brief The PSU manufacturer of the software */
2849edb7330SLei YU     std::string manufacturer;
2859edb7330SLei YU 
2869edb7330SLei YU     /** @brief The PSU model of the software */
2879edb7330SLei YU     std::string model;
28801539e7eSLei YU };
28901539e7eSLei YU 
29001539e7eSLei YU } // namespace updater
29101539e7eSLei YU } // namespace software
29201539e7eSLei YU } // namespace phosphor
293