fw-update: Add StartUpdate D-Bus API support for firmware updates

This commit adds support for the StartUpdate D-Bus API to enable FW
updates through the xyz.openbmc_project.Software.Update interface. The
user would need to enable `fw-update-pkg-inotify` meson option to
switch to inotify mechanism.

The existing inotify mechanism has critical limitations:
- Race condition between a BMC code updater and PLDM updater when
  accessing images from /tmp/images directory
- Lack of a standard D-Bus interface for firmware operations
- No proper error handling or status reporting

This implementation follows the upstream design for device & component
level inventory & update, based on the proposed code-update design
document [1]. The FW Update is triggered at the top-level i.e. all valid
targets will be updated with a single StartUpdate call.

Key changes:
- Add Update class implementing the Software.Update D-Bus interface
- Add startUpdate method that accepts file descriptors and processes
  firmware packages via streams
- Refactor UpdateManager to support both file path and stream-based
  package processing

Tests:
- Successful FW Update with both inotify and startUpdate flows on
  gb200nvl-obmc platform with multiple components (GPU + SMA)
- FW Update failure case by modifying the package size. The Redfish task
  immediately fails with Exception after creation.

[1]: https://gerrit.openbmc.org/c/openbmc/docs/+/76645

Change-Id: Ic2ca74431316161de844f6a3966f612760f5c298
Signed-off-by: P Arun Kumar Reddy <arunpapannagari23@gmail.com>
diff --git a/fw-update/update.hpp b/fw-update/update.hpp
new file mode 100644
index 0000000..307b702
--- /dev/null
+++ b/fw-update/update.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <xyz/openbmc_project/Software/ApplyTime/server.hpp>
+#include <xyz/openbmc_project/Software/Update/server.hpp>
+
+namespace pldm
+{
+
+namespace fw_update
+{
+
+class UpdateManager;
+
+using UpdateIntf = sdbusplus::server::object_t<
+    sdbusplus::xyz::openbmc_project::Software::server::Update>;
+using ApplyTimeIntf =
+    sdbusplus::xyz::openbmc_project::Software::server::ApplyTime;
+
+/** @class Update
+ *
+ *  Concrete implementation of xyz.openbmc_project.Software.Update D-Bus
+ *  interface
+ */
+class Update : public UpdateIntf
+{
+  public:
+    /** @brief Constructor
+     *
+     *  @param[in] bus - Bus to attach to
+     *  @param[in] objPath - D-Bus object path
+     *  @param[in] updateManager - Reference to FW update manager
+     */
+    Update(sdbusplus::bus::bus& bus, const std::string& path,
+           UpdateManager* updateManager) :
+        UpdateIntf(bus, path.c_str()), updateManager(updateManager),
+        objPath(path)
+    {}
+
+    virtual sdbusplus::message::object_path startUpdate(
+        sdbusplus::message::unix_fd image,
+        ApplyTimeIntf::RequestedApplyTimes applyTime) override;
+
+    ~Update() noexcept override = default;
+
+  private:
+    UpdateManager* updateManager;
+    const std::string objPath;
+    std::stringstream imageStream;
+};
+
+} // namespace fw_update
+
+} // namespace pldm