fw-update: Implement firmware UpdateManager
The UpdateManager parses the PLDM package and co-ordinates with
the DeviceUpdater to update all the PLDM enabled firmware devices.
Tested: Completed firmware update using PLDM for an FD
Signed-off-by: Tom Joseph <rushtotom@gmail.com>
Change-Id: Ia87675e0a88cb1f72ad82934e539739db193b9f6
diff --git a/fw-update/update_manager.hpp b/fw-update/update_manager.hpp
new file mode 100644
index 0000000..c942e38
--- /dev/null
+++ b/fw-update/update_manager.hpp
@@ -0,0 +1,136 @@
+#pragma once
+
+#include "libpldm/base.h"
+#include "libpldm/requester/pldm.h"
+
+#include "common/types.hpp"
+#include "device_updater.hpp"
+#include "package_parser.hpp"
+#include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
+#include "watch.hpp"
+
+#include <chrono>
+#include <filesystem>
+#include <fstream>
+#include <tuple>
+#include <unordered_map>
+
+namespace pldm
+{
+
+namespace fw_update
+{
+
+using namespace sdeventplus;
+using namespace sdeventplus::source;
+using namespace pldm::dbus_api;
+using namespace pldm;
+
+using DeviceIDRecordOffset = size_t;
+using DeviceUpdaterInfo = std::pair<mctp_eid_t, DeviceIDRecordOffset>;
+using DeviceUpdaterInfos = std::vector<DeviceUpdaterInfo>;
+using TotalComponentUpdates = size_t;
+
+class Activation;
+class ActivationProgress;
+
+class UpdateManager
+{
+ public:
+ UpdateManager() = delete;
+ UpdateManager(const UpdateManager&) = delete;
+ UpdateManager(UpdateManager&&) = delete;
+ UpdateManager& operator=(const UpdateManager&) = delete;
+ UpdateManager& operator=(UpdateManager&&) = delete;
+ ~UpdateManager() = default;
+
+ explicit UpdateManager(
+ Event& event,
+ pldm::requester::Handler<pldm::requester::Request>& handler,
+ Requester& requester, const DescriptorMap& descriptorMap,
+ const ComponentInfoMap& componentInfoMap) :
+ event(event),
+ handler(handler), requester(requester), descriptorMap(descriptorMap),
+ componentInfoMap(componentInfoMap),
+ watch(event.get(),
+ std::bind_front(&UpdateManager::processPackage, this))
+ {}
+
+ /** @brief Handle PLDM request for the commands in the FW update
+ * specification
+ *
+ * @param[in] eid - Remote MCTP Endpoint ID
+ * @param[in] command - PLDM command code
+ * @param[in] request - PLDM request message
+ * @param[in] requestLen - PLDM request message length
+ *
+ * @return PLDM response message
+ */
+ Response handleRequest(mctp_eid_t eid, uint8_t command,
+ const pldm_msg* request, size_t reqMsgLen);
+
+ int processPackage(const std::filesystem::path& packageFilePath);
+
+ void updateDeviceCompletion(mctp_eid_t eid, bool status);
+
+ void updateActivationProgress();
+
+ /** @brief Callback function that will be invoked when the
+ * RequestedActivation will be set to active in the Activation
+ * interface
+ */
+ void activatePackage();
+
+ void clearActivationInfo();
+
+ /** @brief
+ *
+ */
+ DeviceUpdaterInfos
+ associatePkgToDevices(const FirmwareDeviceIDRecords& fwDeviceIDRecords,
+ const DescriptorMap& descriptorMap,
+ TotalComponentUpdates& totalNumComponentUpdates);
+
+ const std::string swRootPath{"/xyz/openbmc_project/software/"};
+
+ private:
+ Event& event; //!< reference to PLDM daemon's main event loop
+ /** @brief PLDM request handler */
+ pldm::requester::Handler<pldm::requester::Request>& handler;
+ Requester& requester; //!< reference to Requester object
+ /** @brief Device identifiers of the managed FDs */
+ const DescriptorMap& descriptorMap;
+ /** @brief Component information needed for the update of the managed FDs */
+ const ComponentInfoMap& componentInfoMap;
+ Watch watch;
+
+ std::unique_ptr<Activation> activation;
+ std::unique_ptr<ActivationProgress> activationProgress;
+ std::string objPath;
+
+ std::filesystem::path fwPackageFilePath;
+ std::unique_ptr<PackageParser> parser;
+ std::ifstream package;
+
+ std::unordered_map<mctp_eid_t, std::unique_ptr<DeviceUpdater>>
+ deviceUpdaterMap;
+ std::unordered_map<mctp_eid_t, bool> deviceUpdateCompletionMap;
+
+ /** @brief Total number of component updates to calculate the progress of
+ * the Firmware activation
+ */
+ size_t totalNumComponentUpdates;
+
+ /** @brief FW update package can contain updates for multiple firmware
+ * devices and each device can have multiple components. Once
+ * each component is updated (Transfer completed, Verified and
+ * Applied) ActivationProgress is updated.
+ */
+ size_t compUpdateCompletedCount;
+ decltype(std::chrono::steady_clock::now()) startTime;
+};
+
+} // namespace fw_update
+
+} // namespace pldm
\ No newline at end of file