usb: Update the RequestedActivation property

Subscribe to the add software interface, when an update is detected,
call back the updateActivation method and verify whether it needs
to be updated. If necessary:
1. Set ApplyTime to OnReset to prevent the bmc from restarting
   immediately after the update.
2. Change the RequestedActivation attribute value and start to update
   the image bmc.

Tested: Manually start the phopshor-usb-manager daemon, and saw that
the bmc upgrade file(*.tar) has been copied to /tmp/images and
the update has been triggered, and bmc has not been restarted
immediately.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Ic650e34f8ec61d3c826332d28275db90f9ef348e
diff --git a/usb/usb_manager.hpp b/usb/usb_manager.hpp
index f3323a8..e67115c 100644
--- a/usb/usb_manager.hpp
+++ b/usb/usb_manager.hpp
@@ -1,6 +1,9 @@
 #pragma once
 
+#include "utils.hpp"
+
 #include <phosphor-logging/lg2.hpp>
+#include <sdeventplus/event.hpp>
 
 #include <filesystem>
 
@@ -9,6 +12,7 @@
 namespace usb
 {
 namespace fs = std::filesystem;
+namespace MatchRules = sdbusplus::bus::match::rules;
 
 class USBManager
 {
@@ -20,8 +24,25 @@
     USBManager& operator=(const USBManager&) = delete;
     USBManager& operator=(USBManager&&) = default;
 
-    explicit USBManager(const fs::path& path) : usbPath(path)
-    {}
+    explicit USBManager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
+                        const fs::path& path) :
+        bus(bus),
+        event(event), usbPath(path), isUSBCodeUpdate(false),
+        fwUpdateMatcher(bus,
+                        MatchRules::interfacesAdded() +
+                            MatchRules::path("/xyz/openbmc_project/software"),
+                        std::bind(std::mem_fn(&USBManager::updateActivation),
+                                  this, std::placeholders::_1))
+    {
+        if (!run())
+        {
+            lg2::error("Failed to FW Update via USB, usbPath:{USBPATH}",
+                       "USBPATH", usbPath);
+            event.exit(0);
+        }
+
+        isUSBCodeUpdate = true;
+    }
 
     /** @brief Find the first file with a .tar extension according to the USB
      *         file path.
@@ -30,9 +51,38 @@
      */
     bool run();
 
+    /** @brief Creates an Activation D-Bus object.
+     *
+     * @param[in]  msg   - Data associated with subscribed signal
+     */
+    void updateActivation(sdbusplus::message::message& msg);
+
+    /** @brief Set Apply Time to OnReset.
+     *
+     */
+    void setApplyTime();
+
+    /** @brief Method to set the RequestedActivation D-Bus property.
+     *
+     *  @param[in] path  - Update the object path of the firmware
+     */
+    void setRequestedActivation(const std::string& path);
+
   private:
+    /** @brief Persistent sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** sd event handler. */
+    sdeventplus::Event& event;
+
     /** The USB path detected. */
     const fs::path& usbPath;
+
+    /** Indicates whether USB codeupdate is going on. */
+    bool isUSBCodeUpdate;
+
+    /** sdbusplus signal match for new image. */
+    sdbusplus::bus::match_t fwUpdateMatcher;
 };
 
 } // namespace usb