oem-ibm: Support for concurrent out-of-band FW update

Redfish triggers the out-of-band code update to BMC. This code update is
called concurrent FW update when the remote PLDM terminus is up during
code update.

The system has two boot sides: Temporary and Permanent, with the default
image running from the temporary side. During an out-of-band (OOB) code
update triggered by the Redfish client, the boot side is swapped, the
correct image is assigned to the permanent side, and a new image is
written to the temporary side. Boot side rename event is used to notify
the remote PLDM terminus about the rename operation during the update.

Change-Id: I21f2b871c5cdd35660e2fc84019749f0365f1d76
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/oem/ibm/libpldmresponder/inband_code_update.cpp b/oem/ibm/libpldmresponder/inband_code_update.cpp
index d3ea1a8..8acfe56 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.cpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.cpp
@@ -228,10 +228,7 @@
                     {
                         auto propVal = dBusIntf->getDbusPropertyVariant(
                             imageObjPath, "Activation", imageInterface);
-                        const auto& imageProp = std::get<std::string>(propVal);
-                        if (imageProp == "xyz.openbmc_project.Software."
-                                         "Activation.Activations.Ready" &&
-                            isCodeUpdateInProgress())
+                        if (isCodeUpdateInProgress())
                         {
                             newImageId = path.str;
                             if (!imageActivationMatch)
@@ -311,6 +308,11 @@
                             }
                             break;
                         }
+                        else
+                        {
+                            // Out of band update
+                            processRenameEvent();
+                        }
                     }
                     catch (const sdbusplus::exception_t& e)
                     {
@@ -324,6 +326,15 @@
         }));
 }
 
+void CodeUpdate::processRenameEvent()
+{
+    currBootSide = Pside;
+    auto sensorId = getBootSideRenameStateSensor();
+    sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
+                         PLDM_OEM_IBM_BOOT_SIDE_RENAME_STATE_RENAMED,
+                         PLDM_OEM_IBM_BOOT_SIDE_RENAME_STATE_NOT_RENAMED);
+}
+
 void CodeUpdate::processPriorityChangeNotification(
     const DbusChangedProps& chProperties)
 {
diff --git a/oem/ibm/libpldmresponder/inband_code_update.hpp b/oem/ibm/libpldmresponder/inband_code_update.hpp
index c16ac44..9f67553 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.hpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.hpp
@@ -151,6 +151,23 @@
         return firmwareUpdateSensorId;
     }
 
+    /* @brief Method to set the sensor id for boot side rename state
+     * @param[in] sensorId - sensor id for boot side rename update
+     *                       state
+     */
+    void setBootSideRenameStateSensor(uint16_t sensorId)
+    {
+        bootSideRenameStateSensorId = sensorId;
+    }
+
+    /* @brief Method to fetch the sensor id for boot side rename state
+     * @return - sensor id
+     */
+    uint16_t getBootSideRenameStateSensor()
+    {
+        return bootSideRenameStateSensorId;
+    }
+
     /* @brief Method to send a state sensor event to Host from CodeUpdate class
      * @param[in] sensorId - sensor id for the event
      * @param[in] sensorEventClass - sensor event class wrt DSP0248
@@ -174,6 +191,10 @@
      */
     int assembleCodeUpdateImage();
 
+    /* @brief Method to process the bootside rename event, sends a boot side
+     * rename event notification to host when code update is initiated*/
+    void processRenameEvent();
+
     virtual ~CodeUpdate() {}
 
   private:
@@ -195,7 +216,7 @@
         oemPlatformHandler; //!< oem platform handler
     uint16_t markerLidSensorId;
     uint16_t firmwareUpdateSensorId;
-
+    uint16_t bootSideRenameStateSensorId;
     /** @brief D-Bus property changed signal match for image activation */
     std::unique_ptr<sdbusplus::bus::match_t> imageActivationMatch;
 
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index decb953..cb2862d 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -333,7 +333,8 @@
     auto state =
         reinterpret_cast<state_sensor_possible_states*>(possibleStates);
     if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
-        (stateSetID == PLDM_OEM_IBM_VERIFICATION_STATE))
+        (stateSetID == PLDM_OEM_IBM_VERIFICATION_STATE) ||
+        (stateSetID == PLDM_OEM_IBM_BOOT_SIDE_RENAME))
         state->states[0].byte = 6;
     else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
         state->states[0].byte = 126;
@@ -438,6 +439,9 @@
     buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
                                 ENTITY_INSTANCE_0,
                                 PLDM_OEM_IBM_VERIFICATION_STATE, repo);
+    buildAllCodeUpdateSensorPDR(this, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
+                                ENTITY_INSTANCE_0,
+                                PLDM_OEM_IBM_BOOT_SIDE_RENAME, repo);
     auto sensorId = findStateSensorId(
         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_VERIFICATION_STATE);
@@ -446,6 +450,10 @@
         repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
         ENTITY_INSTANCE_0, 1, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
     codeUpdate->setFirmwareUpdateSensor(sensorId);
+    sensorId =
+        findStateSensorId(repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
+                          ENTITY_INSTANCE_0, 0, PLDM_OEM_IBM_BOOT_SIDE_RENAME);
+    codeUpdate->setBootSideRenameStateSensor(sensorId);
 }
 
 void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(