oem-ibm: Support system reboot after inband code update

This commit adds a bmc effecter that causes a system reboot(
phyp, chassis and bmc)

After bmc sends an end update successful event, Host will
set this new effecter. Upon getting the setStateEffecterStates
call bmc-pldm does the following:
1. Set the power restore to reboot the host once the BMC
   is rebooted
2. power off Host and Chassis
3. reboot the bmc

Tested with pldmtool
Steps after patching changes:
1. Boot host to STANDBY
2. Fetch the effecter to note the effecterId
   Ex: ./pldmtool platform GetPDR -d 28
3. Trigger the system reboot by toggling the effecter
   ./pldmtool platform SetStateEffecterStates -i 10 -c 1
   -d 1 1

Signed-off-by: Sagar Srinivas <sagar.srinivas@ibm.com>
Change-Id: Id2d4201a7d61ae335adc64f2583571a37dc7879d
diff --git a/oem/ibm/libpldmresponder/inband_code_update.cpp b/oem/ibm/libpldmresponder/inband_code_update.cpp
index 723caad..27ce945 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.cpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.cpp
@@ -138,7 +138,6 @@
                   << "ERROR=" << e.what() << std::endl;
         rc = PLDM_ERROR;
     }
-    newImageId.clear();
     return rc;
 }
 
@@ -198,7 +197,7 @@
                 msg.read(iface, props);
                 processPriorityChangeNotification(props);
             }));
-    fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+    fwUpdateMatcher.push_back(std::make_unique<sdbusplus::bus::match::match>(
         pldm::utils::DBusHandler::getBus(),
         "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
         "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
@@ -206,6 +205,7 @@
             DBusInterfaceAdded interfaces;
             sdbusplus::message::object_path path;
             msg.read(path, interfaces);
+
             for (auto& interface : interfaces)
             {
                 if (interface.first ==
@@ -214,6 +214,7 @@
                     auto imageInterface =
                         "xyz.openbmc_project.Software.Activation";
                     auto imageObjPath = path.str.c_str();
+
                     try
                     {
                         auto propVal = dBusIntf->getDbusPropertyVariant(
@@ -224,20 +225,82 @@
                             isCodeUpdateInProgress())
                         {
                             newImageId = path.str;
+                            if (!imageActivationMatch)
+                            {
+                                imageActivationMatch = std::make_unique<
+                                    sdbusplus::bus::match::match>(
+                                    pldm::utils::DBusHandler::getBus(),
+                                    propertiesChanged(newImageId,
+                                                      "xyz.openbmc_project."
+                                                      "Software.Activation"),
+                                    [this](sdbusplus::message::message& msg) {
+                                        DbusChangedProps props;
+                                        std::string iface;
+                                        msg.read(iface, props);
+                                        const auto itr =
+                                            props.find("Activation");
+                                        if (itr != props.end())
+                                        {
+                                            PropertyValue value = itr->second;
+                                            auto propVal =
+                                                std::get<std::string>(value);
+                                            if (propVal ==
+                                                "xyz.openbmc_project.Software."
+                                                "Activation.Activations.Active")
+                                            {
+                                                CodeUpdateState state =
+                                                    CodeUpdateState::END;
+                                                setCodeUpdateProgress(false);
+                                                auto sensorId =
+                                                    getFirmwareUpdateSensor();
+                                                sendStateSensorEvent(
+                                                    sensorId,
+                                                    PLDM_STATE_SENSOR_STATE, 0,
+                                                    uint8_t(state),
+                                                    uint8_t(CodeUpdateState::
+                                                                START));
+                                                newImageId.clear();
+                                            }
+                                            else if (propVal ==
+                                                         "xyz.openbmc_project."
+                                                         "Software.Activation."
+                                                         "Activations.Failed" ||
+                                                     propVal ==
+                                                         "xyz.openbmc_"
+                                                         "project.Software."
+                                                         "Activation."
+                                                         "Activations."
+                                                         "Invalid")
+                                            {
+                                                CodeUpdateState state =
+                                                    CodeUpdateState::FAIL;
+                                                setCodeUpdateProgress(false);
+                                                auto sensorId =
+                                                    getFirmwareUpdateSensor();
+                                                sendStateSensorEvent(
+                                                    sensorId,
+                                                    PLDM_STATE_SENSOR_STATE, 0,
+                                                    uint8_t(state),
+                                                    uint8_t(CodeUpdateState::
+                                                                START));
+                                                newImageId.clear();
+                                            }
+                                        }
+                                    });
+                            }
                             auto rc = setRequestedActivation();
-                            CodeUpdateState state = CodeUpdateState::END;
                             if (rc != PLDM_SUCCESS)
                             {
-                                state = CodeUpdateState::FAIL;
+                                CodeUpdateState state = CodeUpdateState::FAIL;
+                                setCodeUpdateProgress(false);
+                                auto sensorId = getFirmwareUpdateSensor();
+                                sendStateSensorEvent(
+                                    sensorId, PLDM_STATE_SENSOR_STATE, 0,
+                                    uint8_t(state),
+                                    uint8_t(CodeUpdateState::START));
                                 std::cerr
                                     << "could not set RequestedActivation \n";
                             }
-                            setCodeUpdateProgress(false);
-                            auto sensorId = getFirmwareUpdateSensor();
-                            sendStateSensorEvent(
-                                sensorId, PLDM_STATE_SENSOR_STATE, 0,
-                                uint8_t(state),
-                                uint8_t(CodeUpdateState::START));
                             break;
                         }
                     }
@@ -247,7 +310,7 @@
                     }
                 }
             }
-        });
+        }));
 }
 
 void CodeUpdate::processPriorityChangeNotification(