oem-ibm: Maintain bootside Mapping and Set bios attribute

This commit adds code to maintain a mapping between running,
non-running and Temp, Perm side which would help the bmc
and remote PLDM terminus determine at any point in time if the
code update was successful and that remote PLDM terminus knows
exactly which side it is running on.

In the event the code update failed, then for that case
the new added bios attribute "fw_boot_side", which will
be set in the event. If BMC tries to boot from the new
"Temp" side (other side), and if it fails, then BMC must
update fw_boot_side to "Perm".

Change-Id: I9f1edad1e36850742aba88d93f8cf0fc8b9d8c8d
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index 907f2cb..895c9f2 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -26,6 +26,24 @@
 using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
 namespace oem_ibm_platform
 {
+using AttributeName = std::string;
+using AttributeType = std::string;
+using ReadonlyStatus = bool;
+using DisplayName = std::string;
+using Description = std::string;
+using MenuPath = std::string;
+using CurrentValue = std::variant<int64_t, std::string>;
+using DefaultValue = std::variant<int64_t, std::string>;
+using OptionString = std::string;
+using OptionValue = std::variant<int64_t, std::string>;
+using Option = std::vector<std::tuple<OptionString, OptionValue>>;
+using BIOSTableObj =
+    std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
+               MenuPath, CurrentValue, DefaultValue, Option>;
+using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;
+using PendingObj = std::tuple<AttributeType, CurrentValue>;
+using PendingAttributes = std::map<AttributeName, PendingObj>;
+
 constexpr uint16_t ENTITY_INSTANCE_0 = 0;
 constexpr uint16_t ENTITY_INSTANCE_1 = 1;
 
@@ -147,6 +165,39 @@
                     }
                 }
             });
+        updateBIOSMatch = std::make_unique<sdbusplus::bus::match_t>(
+            pldm::utils::DBusHandler::getBus(),
+            propertiesChanged("/xyz/openbmc_project/bios_config/manager",
+                              "xyz.openbmc_project.BIOSConfig.Manager"),
+            [codeUpdate](sdbusplus::message_t& msg) {
+                constexpr auto propertyName = "PendingAttributes";
+                using Value =
+                    std::variant<std::string, PendingAttributes, BaseBIOSTable>;
+                using Properties = std::map<pldm::utils::DbusProp, Value>;
+                Properties props{};
+                std::string intf;
+                msg.read(intf, props);
+                auto valPropMap = props.find(propertyName);
+                if (valPropMap == props.end())
+                {
+                    return;
+                }
+
+                PendingAttributes pendingAttributes =
+                    std::get<PendingAttributes>(valPropMap->second);
+                for (auto it : pendingAttributes)
+                {
+                    if (it.first == "fw_boot_side")
+                    {
+                        auto& [attributeType, attributevalue] = it.second;
+                        std::string nextBootSideAttr =
+                            std::get<std::string>(attributevalue);
+                        std::string nextBootSide =
+                            (nextBootSideAttr == "Perm" ? Pside : Tside);
+                        codeUpdate->setNextBootSide(nextBootSide);
+                    }
+                }
+            });
     }
 
     int getOemStateSensorReadingsHandler(
@@ -360,6 +411,9 @@
     pldm::requester::Handler<pldm::requester::Request>* handler;
 
     /** @brief D-Bus property changed signal match */
+    std::unique_ptr<sdbusplus::bus::match_t> updateBIOSMatch;
+
+    /** @brief D-Bus property changed signal match */
     std::unique_ptr<sdbusplus::bus::match_t> hostOffMatch;
 
     /** @brief D-Bus property changed signal match */