Remove use of legacy inventory interface
Made below given changes:
1.With legacy code we used to read software version info from the system
file: /etc/os-release, now with new updates we will read it from the
s/w object which is implementing the interface
"xyz.openbmc_project.Software.RedundancyPriority" interface.
2.Removed legacy code related to inventory(FRU) for sensors
Tested:
1.Verified f/w version info using below given command
>ipmitool mc info -I dbus
2.Verified get sensor type info using below given command
>ipmitool raw 0x04 0x2f 0x02 -I dbus
Resolves openbmc/openbmc#2870
Change-Id: I384bf4aaacd56f4a871833b533b2a8a68c489959
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
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_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 @@
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_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 @@
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;
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ }
- 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);
- }
+ 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 @@
// Pack the actual response
memcpy(response, &dev_id, *data_len);
-finish:
- free(busname);
- free(ver);
+
return rc;
}
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 7d9d394..f6ccc13 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -71,57 +71,6 @@
uint8_t indication[2];
} __attribute__ ((packed)) ;
-// Use a lookup table to find the interface name of a specific sensor
-// This will be used until an alternative is found. this is the first
-// step for mapping IPMI
-int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) {
-
- char *str1;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- sd_bus_message *reply = NULL, *m=NULL;
-
-
- int r;
-
- r = sd_bus_message_new_method_call(bus,&m,interface->bus,interface->path,"org.freedesktop.DBus.Properties","Get");
- if (r < 0) {
- fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
- fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
- interface->bus, interface->path, interface->interface);
- goto final;
- }
-
- r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name);
- if (r < 0) {
- fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
- fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
- interface->bus, interface->path, interface->interface);
- goto final;
- }
-
- r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0) {
- fprintf(stderr, "Failed to call the method: %s", strerror(-r));
- goto final;
- }
-
- r = sd_bus_message_read(reply, "v", "s", &str1) ;
- if (r < 0) {
- fprintf(stderr, "Failed to get a response: %s", strerror(-r));
- goto final;
- }
-
- strcpy(property_value, str1);
-
-final:
-
- sd_bus_error_free(&error);
- m = sd_bus_message_unref(m);
- reply = sd_bus_message_unref(reply);
-
- return r;
-}
-
int get_bus_for_path(const char *path, char **busname) {
return mapper_get_service(bus, path, busname);
}
@@ -332,19 +281,6 @@
}
-uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) {
- char fru_type_name[64];
- int r= 0;
-
- r = find_interface_property_fru_type(a, "fru_type", fru_type_name);
- if (r<0) {
- fprintf(stderr, "Failed to get a fru type: %s", strerror(-r));
- return -1;
- } else {
- return dbus_to_sensor_type(fru_type_name);
- }
-}
-
uint8_t get_type_from_interface(dbus_interface_t dbus_if) {
char *p;
@@ -359,12 +295,6 @@
if (dbus_if.sensortype != 0)
{
type = dbus_if.sensortype;
- }
- // Legacy codebase does not populate type during initial handling:
- else if (strstr(dbus_if.interface, "InventoryItem")) {
- // InventoryItems are real frus. So need to get the
- // fru_type property
- type = dbus_to_sensor_type_from_dbus(&dbus_if);
} else {
// Non InventoryItems
p = strrchr (dbus_if.path, '/');