Overriding ipmiAppGetSystemGuid method
Due to the below upstream change systemGUID read changed from
/xyz/openbmc_project/control/host0/systemGUID interface to
/xyz/openbmc_project/inventory/system/chassis/motherboard/bios
https://gerrit.openbmc.org/c/openbmc/phosphor-host-ipmid/+/74471
Since hosting SystemGUID at a different place than inventory,
overriding ipmiAppGetSystemGuid API. So that it can match OEM
mechanism of setting it.
Change-Id: I7b0ba6bc06db869ce95bae3e7eb81e4b8ad804a7
Signed-off-by: poram srinivasa rao <poramx.srinivasa.rao@intel.com>
Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
diff --git a/src/appcommands.cpp b/src/appcommands.cpp
index b3b3ed2..c1089c4 100644
--- a/src/appcommands.cpp
+++ b/src/appcommands.cpp
@@ -13,18 +13,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
*/
+#include "xyz/openbmc_project/Common/error.hpp"
+
#include <byteswap.h>
#include <appcommands.hpp>
#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <nlohmann/json.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/log.hpp>
#include <types.hpp>
#include <fstream>
#include <regex>
+using namespace phosphor::logging;
+using namespace sdbusplus::error::xyz::openbmc_project::common;
+
namespace ipmi
{
@@ -260,6 +267,107 @@
return std::nullopt;
}
+static constexpr size_t uuidLength = 16;
+static std::array<uint8_t, uuidLength>
+ rfc4122ToIpmiConvesrion(std::string rfc4122)
+{
+ using Argument = xyz::openbmc_project::common::InvalidArgument;
+ // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+ // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
+ // order
+ // Ex: 0x2332fc2c40e66298e511f2782395a361
+ constexpr size_t uuidHexLength = (2 * uuidLength);
+ constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
+ std::array<uint8_t, uuidLength> uuid;
+ if (rfc4122.size() == uuidRfc4122Length)
+ {
+ rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
+ rfc4122.end());
+ }
+ if (rfc4122.size() != uuidHexLength)
+ {
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+ }
+ for (size_t ind = 0; ind < uuidHexLength; ind += 2)
+ {
+ char v[3];
+ v[0] = rfc4122[ind];
+ v[1] = rfc4122[ind + 1];
+ v[2] = 0;
+ size_t err;
+ long b;
+ try
+ {
+ b = std::stoul(v, &err, 16);
+ }
+ catch (const std::exception& e)
+ {
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+ }
+ // check that exactly two ascii bytes were converted
+ if (err != 2)
+ {
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+ }
+ uuid[uuidLength - (ind / 2) - 1] = static_cast<uint8_t>(b);
+ }
+ return uuid;
+}
+
+ipmi::RspType<std::array<uint8_t, 16>>
+ ipmiAppGetSystemGuid(ipmi::Context::ptr& ctx)
+{
+ static constexpr auto uuidInterface = "xyz.openbmc_project.Common.UUID";
+ static constexpr auto uuidProperty = "UUID";
+ // Get the Inventory object implementing BMC interface
+ ipmi::DbusObjectInfo objectInfo{};
+ boost::system::error_code ec =
+ ipmi::getDbusObject(ctx, uuidInterface, objectInfo);
+
+ if (ec.value())
+ {
+ lg2::error("Failed to locate System UUID object, "
+ "interface: {INTERFACE}, error: {ERROR}",
+ "INTERFACE", uuidInterface, "ERROR", ec.message());
+ return ipmi::responseUnspecifiedError();
+ }
+
+ // Read UUID property value from bmcObject
+ // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+ std::string rfc4122Uuid{};
+ ec = ipmi::getDbusProperty(ctx, objectInfo.second, objectInfo.first,
+ uuidInterface, uuidProperty, rfc4122Uuid);
+
+ if (ec.value())
+ {
+ lg2::error("Failed to read System UUID property, "
+ "interface: {INTERFACE}, property: {PROPERTY}, "
+ "error: {ERROR}",
+ "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
+ "ERROR", ec.message());
+ return ipmi::responseUnspecifiedError();
+ }
+ std::array<uint8_t, 16> uuid;
+ try
+ {
+ // convert to IPMI format
+ uuid = rfc4122ToIpmiConvesrion(rfc4122Uuid);
+ }
+ catch (const InvalidArgument& e)
+ {
+ lg2::error("Failed in parsing BMC UUID property, "
+ "interface: {INTERFACE}, property: {PROPERTY}, "
+ "value: {VALUE}, error: {ERROR}",
+ "INTERFACE", uuidInterface, "PROPERTY", uuidProperty,
+ "VALUE", rfc4122Uuid, "ERROR", e);
+ return ipmi::responseUnspecifiedError();
+ }
+ return ipmi::responseSuccess(uuid);
+}
+
RspType<uint8_t, // Device ID
uint8_t, // Device Revision
uint7_t, // Firmware Revision Major
@@ -392,6 +500,9 @@
// <Get Device ID>
registerHandler(prioOemBase, netFnApp, app::cmdGetDeviceId, Privilege::User,
ipmiAppGetDeviceId);
+ // <Get System GUID>
+ registerHandler(prioOemBase, netFnApp, app::cmdGetSystemGuid,
+ Privilege::User, ipmiAppGetSystemGuid);
}
} // namespace ipmi