Implement BMC position for RBMC prototype system
BMC’s role in RBMC prototype system is determined based on its
position.
This commit adds the code to implement BMC position for RBMC
prototype system based on whether BMC has access to motherboard EEPROM
or not.
Test:
```
Tested the changes by keeping lab system IM value in constants file, observed that position interface is created for the system.
root@rainvpdteam:~# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system xyz.openbmc_project.Inventory.Decorator.Position
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Position property u 0 emits-change writable
```
Change-Id: Ia66065950ac75b7b7e95b4b6cce938663ebb9756
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp
index 9708beb..f5068c9 100644
--- a/vpd-manager/include/constants.hpp
+++ b/vpd-manager/include/constants.hpp
@@ -2,6 +2,7 @@
#include <cstdint>
#include <iostream>
+#include <vector>
namespace vpd
{
namespace constants
@@ -239,5 +240,10 @@
"/usr/share/vpd/50001_power_vs.json";
static constexpr auto correlatedPropJsonFile =
"/usr/share/vpd/correlated_properties.json";
+
+static constexpr auto rbmcPositionInterface =
+ "xyz.openbmc_project.Inventory.Decorator.Position";
+static std::vector<uint8_t> rbmcPrototypeSystemImValue{
+ 55, 54, 48, 48, 50, 48, 48, 48};
} // namespace constants
} // namespace vpd
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index 766f54c..7d0c4d7 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -442,17 +442,29 @@
// Update BMC postion for RBMC prototype system
// Ignore BMC position update in case of any error
uint16_t l_errCode = 0;
- if (isRbmcProtoTypeSystem(l_errCode) && l_errCode == 0)
+ if (isRbmcPrototypeSystem(l_errCode))
{
- size_t l_rbmcPosition = constants::VALUE_1;
- if (isMotherboardEepromAccessible())
- {
- l_rbmcPosition = constants::VALUE_0;
- }
+ size_t l_bmcPosition = std::numeric_limits<size_t>::max();
+ checkAndUpdateBmcPosition(l_bmcPosition);
- (void)l_rbmcPosition;
- // ToDo: Create Object interface map for position property and
- // publish it on DBus.
+ if (dbusUtility::callPIM(types::ObjectMap{
+ {sdbusplus::message::object_path(constants::systemInvPath),
+ {{constants::rbmcPositionInterface,
+ {{"Position", l_bmcPosition}}}}}}))
+ {
+ m_logger->logMessage(
+ "Updating BMC position failed for path [" +
+ std::string(constants::systemInvPath) +
+ "], bmc position: " + std::to_string(l_bmcPosition));
+
+ // ToDo: Check is PEL required
+ }
+ }
+ else if (l_errCode != 0)
+ {
+ m_logger->logMessage(
+ "Unable to determine whether system is RBMC system or not, reason: " +
+ commonUtility::getErrCodeMsg(l_errCode));
}
// Enable all mux which are used for connecting to the i2c on the
@@ -489,23 +501,62 @@
SetTimerToDetectVpdCollectionStatus();
}
-bool IbmHandler::isRbmcProtoTypeSystem(
- [[maybe_unused]] uint16_t& o_errCode) const noexcept
+bool IbmHandler::isRbmcPrototypeSystem(uint16_t& o_errCode) const noexcept
{
- // TODO:
- // Parse the system VPD from EEPROM.
- // Check the IM keyword value. If the IM value indicates an RBMC prototype
- // system, return true otherwise false.
- // In case of any error or IM value not found in the map, set error code and
- // return false.
+ types::BinaryVector l_imValue = dbusUtility::getImFromDbus();
+ if (l_imValue.empty())
+ {
+ o_errCode = error_code::DBUS_FAILURE;
+ return false;
+ }
+
+ if (constants::rbmcPrototypeSystemImValue == l_imValue)
+ {
+ return true;
+ }
return false;
}
-bool IbmHandler::isMotherboardEepromAccessible() const noexcept
+void IbmHandler::checkAndUpdateBmcPosition(size_t& o_bmcPosition) const noexcept
{
- // TODO: Check whether the motherboard EEPROM is accessible.
+ if (m_worker.get() == nullptr)
+ {
+ m_logger->logMessage("Worker object not found");
+ return;
+ }
- return false;
+ const nlohmann::json& l_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
+ if (l_sysCfgJsonObj.empty())
+ {
+ m_logger->logMessage(
+ "System config JSON is empty, unable to find BMC position");
+ return;
+ }
+
+ uint16_t l_errCode = 0;
+ std::string l_motherboardEepromPath = jsonUtility::getFruPathFromJson(
+ l_sysCfgJsonObj, constants::systemVpdInvPath, l_errCode);
+
+ if (!l_motherboardEepromPath.empty())
+ {
+ o_bmcPosition = constants::VALUE_1;
+ std::error_code l_ec;
+ if (std::filesystem::exists(l_motherboardEepromPath, l_ec))
+ {
+ o_bmcPosition = constants::VALUE_0;
+ }
+ }
+ else if (l_errCode)
+ {
+ m_logger->logMessage("Unable to determine BMC position, reason: " +
+ commonUtility::getErrCodeMsg(l_errCode));
+ }
+ else
+ {
+ m_logger->logMessage("Unable to determine BMC position, as FRU path[" +
+ std::string(constants::systemVpdInvPath) +
+ "], not found in the system config JSON.");
+ }
}
} // namespace vpd
diff --git a/vpd-manager/oem-handler/ibm_handler.hpp b/vpd-manager/oem-handler/ibm_handler.hpp
index 6a79133..2eafc49 100644
--- a/vpd-manager/oem-handler/ibm_handler.hpp
+++ b/vpd-manager/oem-handler/ibm_handler.hpp
@@ -127,18 +127,17 @@
*
* @return true for RBMC prototype system, false otherwise.
*/
- bool isRbmcProtoTypeSystem(
- [[maybe_unused]] uint16_t& o_errCode) const noexcept;
+ bool isRbmcPrototypeSystem(uint16_t& o_errCode) const noexcept;
/**
- * @brief Checks whether the motherboard EEPROM is accessible.
+ * @brief Checks and updates BMC position.
*
- * This function is used to update the BMC position for the RBMC prototype
- * system based on whether the motherboard EEPROM can be accessed.
+ * This API updates BMC position for the RBMC prototype
+ * system based on whether the motherboard EEPROM is accessible.
*
- * @return true if able to access motherboard EEPROM, false otherwise.
+ * @param[out] o_bmcPosition - BMC position.
*/
- bool isMotherboardEepromAccessible() const noexcept;
+ void checkAndUpdateBmcPosition(size_t& o_bmcPosition) const noexcept;
// Parsed system config json object.
nlohmann::json m_sysCfgJsonObj{};