summaryrefslogtreecommitdiffstats
path: root/apphandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apphandler.cpp')
-rw-r--r--apphandler.cpp146
1 files changed, 111 insertions, 35 deletions
diff --git a/apphandler.cpp b/apphandler.cpp
index e370f0c..6564181 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -24,6 +24,8 @@
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include "xyz/openbmc_project/Common/error.hpp"
+#include "xyz/openbmc_project/Software/Version/server.hpp"
+#include "xyz/openbmc_project/Software/Activation/server.hpp"
extern sd_bus *bus;
@@ -32,10 +34,21 @@ constexpr auto bmc_guid_interface = "xyz.openbmc_project.Common.UUID";
constexpr auto bmc_guid_property = "UUID";
constexpr auto bmc_guid_len = 16;
+static constexpr auto redundancyIntf =
+ "xyz.openbmc_project.Software.RedundancyPriority";
+static constexpr auto versionIntf =
+ "xyz.openbmc_project.Software.Version";
+static constexpr auto activationIntf =
+ "xyz.openbmc_project.Software.Activation";
+static constexpr auto softwareRoot = "/xyz/openbmc_project/software";
+
void register_netfn_app_functions() __attribute__((constructor));
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using Version = sdbusplus::xyz::openbmc_project::Software::server::Version;
+using Activation =
+ sdbusplus::xyz::openbmc_project::Software::server::Activation;
namespace fs = std::experimental::filesystem;
// Offset in get device id command.
@@ -51,6 +64,82 @@ typedef struct
uint8_t aux[4];
}__attribute__((packed)) ipmi_device_id_t;
+/**
+ * @brief Returns the Version info from primary s/w object
+ *
+ * Get the Version info from the active s/w object which is having high
+ * "Priority" value(a smaller number is a higher priority) and "Purpose"
+ * is "BMC" from the list of all s/w objects those are implementing
+ * RedundancyPriority interface from the given softwareRoot path.
+ *
+ * @return On success returns the Version info from primary s/w object.
+ *
+ */
+std::string getActiveSoftwareVersionInfo()
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ std::string revision{};
+ auto objectTree = ipmi::getAllDbusObjects(bus, softwareRoot, redundancyIntf,
+ "");
+ if (objectTree.empty())
+ {
+ log<level::ERR>("No Obj has implemented the s/w redundancy interface",
+ entry("INTERFACE=%s", redundancyIntf));
+ elog<InternalFailure>();
+ }
+
+ auto objectFound = false;
+ for (auto& softObject : objectTree)
+ {
+ auto service = ipmi::getService(bus, redundancyIntf, softObject.first);
+ auto objValueTree = ipmi::getManagedObjects(bus, service, softwareRoot);
+
+ auto minPriority = 0xFF;
+ for (const auto& objIter : objValueTree)
+ {
+ try
+ {
+ auto& intfMap = objIter.second;
+ auto& redundancyPriorityProps = intfMap.at(redundancyIntf);
+ auto& versionProps = intfMap.at(versionIntf);
+ auto& activationProps = intfMap.at(activationIntf);
+ auto priority =
+ redundancyPriorityProps.at("Priority").get<uint8_t>();
+ auto purpose = versionProps.at("Purpose").get<std::string>();
+ auto activation =
+ activationProps.at("Activation").get<std::string>();
+ auto version = versionProps.at("Version").get<std::string>();
+ if ((Version::convertVersionPurposeFromString(purpose) ==
+ Version::VersionPurpose::BMC) &&
+ (Activation::convertActivationsFromString(activation) ==
+ Activation::Activations::Active))
+ {
+ if (priority < minPriority)
+ {
+ minPriority = priority;
+ objectFound = true;
+ revision = std::move(version);
+ }
+ }
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ }
+ }
+ }
+
+ if (!objectFound)
+ {
+ log<level::ERR>("Could not found an BMC software Object");
+ elog<InternalFailure>();
+ }
+
+ return revision;
+}
+
+
ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -162,12 +251,7 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_data_len_t data_len, ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
- const char *objname =
- "/org/openbmc/inventory/system/chassis/motherboard/bmc";
- const char *iface = "org.openbmc.InventoryItem";
- char *ver = NULL;
- char *busname = NULL;
- int r;
+ int r = -1;
rev_t rev = {0};
static ipmi_device_id_t dev_id{};
static bool dev_id_initialized = false;
@@ -178,33 +262,27 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
if (!dev_id_initialized)
{
- // Firmware revision is already implemented,
- // so get it from appropriate position.
- r = mapper_get_service(bus, objname, &busname);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- objname, strerror(-r));
- goto finish;
+ try
+ {
+ auto version = getActiveSoftwareVersionInfo();
+ r = convert_version(version.c_str(), &rev);
}
- r = sd_bus_get_property_string(bus,busname,objname,iface,"version",
- NULL, &ver);
- if ( r < 0 ) {
- fprintf(stderr, "Failed to obtain version property: %s\n",
- strerror(-r));
- } else {
- r = convert_version(ver, &rev);
- if( r >= 0 ) {
- // bit7 identifies if the device is available
- // 0=normal operation
- // 1=device firmware, SDR update,
- // or self-initialization in progress.
- // our SDR is normal working condition, so mask:
- dev_id.fw[0] = 0x7F & rev.major;
-
- rev.minor = (rev.minor > 99 ? 99 : rev.minor);
- dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
- memcpy(&dev_id.aux, rev.d, 4);
- }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ }
+
+ if( r >= 0 ) {
+ // bit7 identifies if the device is available
+ // 0=normal operation
+ // 1=device firmware, SDR update,
+ // or self-initialization in progress.
+ // our SDR is normal working condition, so mask:
+ dev_id.fw[0] = 0x7F & rev.major;
+
+ rev.minor = (rev.minor > 99 ? 99 : rev.minor);
+ dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
+ memcpy(&dev_id.aux, rev.d, 4);
}
// IPMI Spec version 2.0
@@ -247,9 +325,7 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
// Pack the actual response
memcpy(response, &dev_id, *data_len);
-finish:
- free(busname);
- free(ver);
+
return rc;
}
OpenPOWER on IntegriCloud