From 86a5082f6cf447258c169b483f03a2936ecf23d7 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Mon, 25 Mar 2019 13:11:36 -0700 Subject: rewrite Get Device ID using new provider API Modify to use the new provider API. One by one, change calls to remove any legacy API constructs. Tested-by: ipmitool raw 6 1 check for expected output Change-Id: I59688627eb32670559c1defad0b7af8abeb84c75 Signed-off-by: Vernon Mauery --- apphandler.cpp | 142 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 70 insertions(+), 72 deletions(-) diff --git a/apphandler.cpp b/apphandler.cpp index 0d124fe..e5144ce 100644 --- a/apphandler.cpp +++ b/apphandler.cpp @@ -61,19 +61,6 @@ using BMC = sdbusplus::xyz::openbmc_project::State::server::BMC; namespace fs = std::filesystem; namespace variant_ns = sdbusplus::message::variant_ns; -// Offset in get device id command. -typedef struct -{ - uint8_t id; - uint8_t revision; - uint8_t fw[2]; - uint8_t ipmi_ver; - uint8_t addn_dev_support; - uint8_t manuf_id[3]; - uint8_t prod_id[2]; - uint8_t aux[4]; -} __attribute__((packed)) ipmi_device_id_t; - /** * @brief Returns the Version info from primary s/w object * @@ -87,23 +74,30 @@ typedef struct */ std::string getActiveSoftwareVersionInfo() { - sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; + auto busp = getSdBus(); std::string revision{}; - auto objectTree = - ipmi::getAllDbusObjects(bus, softwareRoot, redundancyIntf, ""); - if (objectTree.empty()) + ipmi::ObjectTree objectTree; + try { - log("No Obj has implemented the s/w redundancy interface", - entry("INTERFACE=%s", redundancyIntf)); + objectTree = + ipmi::getAllDbusObjects(*busp, softwareRoot, redundancyIntf); + } + catch (sdbusplus::exception::SdBusError& e) + { + log("Failed to fetch redundancy object from dbus", + entry("INTERFACE=%s", redundancyIntf), + entry("ERRMSG=%s", e.what())); elog(); } auto objectFound = false; for (auto& softObject : objectTree) { - auto service = ipmi::getService(bus, redundancyIntf, softObject.first); - auto objValueTree = ipmi::getManagedObjects(bus, service, softwareRoot); + auto service = + ipmi::getService(*busp, redundancyIntf, softObject.first); + auto objValueTree = + ipmi::getManagedObjects(*busp, service, softwareRoot); auto minPriority = 0xFF; for (const auto& objIter : objValueTree) @@ -442,7 +436,7 @@ typedef struct char major; char minor; uint16_t d[2]; -} rev_t; +} Revision; /* Currently supports the vx.x-x-[-x] and v1.x.x-x-[-x] format. It will */ /* return -1 if not in those formats, this routine knows how to parse */ @@ -459,9 +453,8 @@ typedef struct /* Additional details : If the option group exists it will force Auxiliary */ /* Firmware Revision Information 4th byte to 1 indicating the build was */ /* derived with additional edits */ -int convert_version(const char* p, rev_t* rev) +int convertVersion(std::string s, Revision& rev) { - std::string s(p); std::string token; uint16_t commits; @@ -476,7 +469,7 @@ int convert_version(const char* p, rev_t* rev) location = s.find_first_of("."); if (location != std::string::npos) { - rev->major = + rev.major = static_cast(std::stoi(s.substr(0, location), 0, 16)); token = s.substr(location + 1); } @@ -486,7 +479,7 @@ int convert_version(const char* p, rev_t* rev) location = token.find_first_of(".-"); if (location != std::string::npos) { - rev->minor = static_cast( + rev.minor = static_cast( std::stoi(token.substr(0, location), 0, 16)); token = token.substr(location + 1); } @@ -498,7 +491,7 @@ int convert_version(const char* p, rev_t* rev) if (!token.empty()) { commits = std::stoi(token.substr(0, location), 0, 16); - rev->d[0] = (commits >> 8) | (commits << 8); + rev.d[0] = (commits >> 8) | (commits << 8); // commit number we skip location = token.find_first_of(".-"); @@ -509,7 +502,7 @@ int convert_version(const char* p, rev_t* rev) } else { - rev->d[0] = 0; + rev.d[0] = 0; } if (location != std::string::npos) @@ -527,36 +520,47 @@ int convert_version(const char* p, rev_t* rev) // We do this operation to get this displayed in least significant bytes // of ipmitool device id command. - rev->d[1] = (commits >> 8) | (commits << 8); + rev.d[1] = (commits >> 8) | (commits << 8); } return 0; } -ipmi_ret_t ipmi_app_get_device_id(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) +auto ipmiAppGetDeviceId() -> ipmi::RspType { - ipmi_ret_t rc = IPMI_CC_OK; int r = -1; - rev_t rev = {0}; - static ipmi_device_id_t dev_id{}; + Revision rev = {0}; + static struct + { + uint8_t id; + uint8_t revision; + uint8_t fw[2]; + uint8_t ipmiVer; + uint8_t addnDevSupport; + uint24_t manufId; + uint16_t prodId; + uint32_t aux; + } devId; static bool dev_id_initialized = false; const char* filename = "/usr/share/ipmi-providers/dev_id.json"; constexpr auto ipmiDevIdStateShift = 7; constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift); - // Data length - *data_len = sizeof(dev_id); - if (!dev_id_initialized) { try { auto version = getActiveSoftwareVersionInfo(); - r = convert_version(version.c_str(), &rev); + r = convertVersion(version, rev); } catch (const std::exception& e) { @@ -571,34 +575,28 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // or self-initialization in progress. // The availability may change in run time, so mask here // and initialize later. - dev_id.fw[0] = rev.major & ipmiDevIdFw1Mask; + devId.fw[0] = rev.major & ipmiDevIdFw1Mask; rev.minor = (rev.minor > 99 ? 99 : rev.minor); - dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; - std::memcpy(&dev_id.aux, rev.d, 4); + devId.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; + std::memcpy(&devId.aux, rev.d, 4); } // IPMI Spec version 2.0 - dev_id.ipmi_ver = 2; + devId.ipmiVer = 2; - std::ifstream dev_id_file(filename); - if (dev_id_file.is_open()) + std::ifstream devIdFile(filename); + if (devIdFile.is_open()) { - auto data = nlohmann::json::parse(dev_id_file, nullptr, false); + auto data = nlohmann::json::parse(devIdFile, nullptr, false); if (!data.is_discarded()) { - dev_id.id = data.value("id", 0); - dev_id.revision = data.value("revision", 0); - dev_id.addn_dev_support = data.value("addn_dev_support", 0); - dev_id.manuf_id[2] = data.value("manuf_id", 0) >> 16; - dev_id.manuf_id[1] = data.value("manuf_id", 0) >> 8; - dev_id.manuf_id[0] = data.value("manuf_id", 0); - dev_id.prod_id[1] = data.value("prod_id", 0) >> 8; - dev_id.prod_id[0] = data.value("prod_id", 0); - dev_id.aux[3] = data.value("aux", 0); - dev_id.aux[2] = data.value("aux", 0) >> 8; - dev_id.aux[1] = data.value("aux", 0) >> 16; - dev_id.aux[0] = data.value("aux", 0) >> 24; + devId.id = data.value("id", 0); + devId.revision = data.value("revision", 0); + devId.addnDevSupport = data.value("addn_dev_support", 0); + devId.manufId = data.value("manuf_id", 0); + devId.prodId = data.value("prod_id", 0); + devId.aux = data.value("aux", 0); // Don't read the file every time if successful dev_id_initialized = true; @@ -606,27 +604,26 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, else { log("Device ID JSON parser failure"); - rc = IPMI_CC_UNSPECIFIED_ERROR; + return ipmi::response(ipmi::ccUnspecifiedError); } } else { log("Device ID file not found"); - rc = IPMI_CC_UNSPECIFIED_ERROR; + return ipmi::response(ipmi::ccUnspecifiedError); } } // Set availability to the actual current BMC state - dev_id.fw[0] &= ipmiDevIdFw1Mask; + devId.fw[0] &= ipmiDevIdFw1Mask; if (!getCurrentBmcState()) { - dev_id.fw[0] |= (1 << ipmiDevIdStateShift); + devId.fw[0] |= (1 << ipmiDevIdStateShift); } - // Pack the actual response - std::memcpy(response, &dev_id, *data_len); - - return rc; + return ipmi::responseSuccess( + devId.id, devId.revision, devId.fw[0], devId.fw[1], devId.ipmiVer, + devId.addnDevSupport, devId.manufId, devId.prodId, devId.aux); } ipmi_ret_t ipmi_app_get_self_test_results(ipmi_netfn_t netfn, ipmi_cmd_t cmd, @@ -1069,6 +1066,11 @@ writeResponse: void register_netfn_app_functions() { + // + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, + ipmi::app::cmdGetDeviceId, ipmi::Privilege::User, + ipmiAppGetDeviceId); + // ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_get_bt_capabilities, PRIVILEGE_USER); @@ -1089,10 +1091,6 @@ void register_netfn_app_functions() ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_WD, NULL, ipmi_app_watchdog_get, PRIVILEGE_OPERATOR); - // - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL, - ipmi_app_get_device_id, PRIVILEGE_USER); - // ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SELF_TEST_RESULTS, NULL, ipmi_app_get_self_test_results, PRIVILEGE_USER); -- cgit v1.2.1