diff options
| author | Andrew Geissler <geissonator@yahoo.com> | 2019-02-19 13:05:38 -0600 |
|---|---|---|
| committer | Andrew Geissler <geissonator@yahoo.com> | 2019-04-05 20:54:21 +0000 |
| commit | cb7e1e7b053b375a32e0e701b4d72f4c6bd8df4b (patch) | |
| tree | f0c61e3b2cf5cb5c214e339875c7ab43f6d4f4cf /redfish-core/include | |
| parent | c6c91d49187bf4cc186a52f8765a356fd8d164ec (diff) | |
| download | bmcweb-cb7e1e7b053b375a32e0e701b4d72f4c6bd8df4b.tar.gz bmcweb-cb7e1e7b053b375a32e0e701b4d72f4c6bd8df4b.zip | |
fw-inventory: Provide BiosVersion in system obj
Created a new fw_utils.hpp to reduce more indentation code in
systems.hpp and also as a base for some future refactoring for common
use cases to access firmware information.
Tested:
- Verified RedfishServiceValidator.py shows no new errors
VERBO - ComputerSystem.v1_0_0.ComputerSystem:BiosVersion
VERBO - value: IBM-witherspoon-OP9-v2.0.10-2.22 <class 'str'>
VERBO - has Type: Edm.String Edm.String
VERBO - is Optional
VERBO - permission OData.Permission/Read
VERBO - Success
- BiosVersion now correctly returned in data
$ curl -k -H "X-Auth-Token: $TOKEN" -X GET https://${BMC_IP}/redfish/v1/Systems/system
{
"@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
"@odata.id": "/redfish/v1/Systems/system",
"@odata.type": "#ComputerSystem.v1_5_1.ComputerSystem",
"Actions": {
"#ComputerSystem.Reset": {
"ResetType@Redfish.AllowableValues": [
"On",
"ForceOff",
"GracefulRestart",
"GracefulShutdown"
],
"target": "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
}
},
"BiosVersion": "IBM-witherspoon-OP9-v2.0.10-2.22",
...
}
Change-Id: I2d7792c724f88aa13bd7b40c0d7f70dd4aa1c807
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Diffstat (limited to 'redfish-core/include')
| -rw-r--r-- | redfish-core/include/utils/fw_utils.hpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/redfish-core/include/utils/fw_utils.hpp b/redfish-core/include/utils/fw_utils.hpp new file mode 100644 index 0000000..18773ae --- /dev/null +++ b/redfish-core/include/utils/fw_utils.hpp @@ -0,0 +1,190 @@ +#pragma once +#include <async_resp.hpp> +#include <string> + +namespace redfish +{ +namespace fw_util +{ +/* @brief String that indicates a bios firmware instance */ +constexpr const char *biosPurpose = + "xyz.openbmc_project.Software.Version.VersionPurpose.Host"; + +/* @brief String that indicates a BMC firmware instance */ +constexpr const char *bmcPurpose = + "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"; + +/** + * @brief Put fw version of input type into async response json structure + * + * @param[i,o] aResp Async response object + * @param[i] fwVersionPurpose Indicates what target to look for + * @param[i] jsonIdxStr Index in aResp->res.jsonValue to write fw ver + * + * @return void + */ +void getActiveFwVersion(std::shared_ptr<AsyncResp> aResp, + const std::string &fwVersionPurpose, + const std::string &jsonIdxStr) +{ + // Get active FW images + crow::connections::systemBus->async_method_call( + [aResp, fwVersionPurpose, + jsonIdxStr](const boost::system::error_code ec, + const std::variant<std::vector<std::string>> &resp) { + if (ec) + { + BMCWEB_LOG_ERROR << "error_code = " << ec; + BMCWEB_LOG_ERROR << "error msg = " << ec.message(); + messages::internalError(aResp->res); + return; + } + const std::vector<std::string> *functionalFw = + std::get_if<std::vector<std::string>>(&resp); + if ((functionalFw == nullptr) || (functionalFw->size() == 0)) + { + BMCWEB_LOG_ERROR << "Zero functional software in system"; + messages::internalError(aResp->res); + return; + } + // example functionalFw: + // v as 2 "/xyz/openbmc_project/software/ace821ef" + // "/xyz/openbmc_project/software/230fb078" + for (auto &fw : *functionalFw) + { + // if can't parse fw id then return + std::string::size_type idPos = fw.rfind("/"); + if (idPos == std::string::npos) + { + messages::internalError(aResp->res); + BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!"; + return; + } + idPos++; + if (idPos >= fw.size()) + { + messages::internalError(aResp->res); + BMCWEB_LOG_DEBUG << "Invalid firmware ID"; + return; + } + std::string swId = fw.substr(idPos); + + // Now find service that hosts it + crow::connections::systemBus->async_method_call( + [aResp, fw, swId, fwVersionPurpose, jsonIdxStr]( + const boost::system::error_code ec, + const std::vector<std::pair< + std::string, std::vector<std::string>>> &objInfo) { + if (ec) + { + BMCWEB_LOG_DEBUG << "error_code = " << ec; + BMCWEB_LOG_DEBUG << "error msg = " << ec.message(); + messages::internalError(aResp->res); + return; + } + // Example objInfo + // a{sas} 1 "org.open_power.Software.Host.Updater" 10 + // "org.freedesktop.DBus.Introspectable" + // "org.freedesktop.DBus.Peer" + // "org.freedesktop.DBus.Properties" + // "org.openbmc.Associations" + // "xyz.openbmc_project.Common.FilePath" + // "xyz.openbmc_project.Object.Delete" + // "xyz.openbmc_project.Software.Activation" + // "xyz.openbmc_project.Software.ExtendedVersion" + // "xyz.openbmc_project.Software.RedundancyPriority" + // "xyz.openbmc_project.Software.Version" + + // Ensure we only got one service back + if (objInfo.size() != 1) + { + BMCWEB_LOG_ERROR << "Invalid Object Size " + << objInfo.size(); + messages::internalError(aResp->res); + return; + } + + // Now grab its version info + crow::connections::systemBus->async_method_call( + [aResp, swId, fwVersionPurpose, jsonIdxStr]( + const boost::system::error_code ec, + const boost::container::flat_map< + std::string, VariantType> &propertiesList) { + if (ec) + { + BMCWEB_LOG_ERROR << "error_code = " << ec; + BMCWEB_LOG_ERROR << "error msg = " + << ec.message(); + messages::internalError(aResp->res); + return; + } + // example propertiesList + // a{sv} 2 "Version" s + // "IBM-witherspoon-OP9-v2.0.10-2.22" "Purpose" + // s + // "xyz.openbmc_project.Software.Version.VersionPurpose.Host" + + boost::container::flat_map< + std::string, VariantType>::const_iterator + it = propertiesList.find("Purpose"); + if (it == propertiesList.end()) + { + BMCWEB_LOG_DEBUG + << "Can't find property \"Purpose\"!"; + messages::internalError(aResp->res); + return; + } + const std::string *swInvPurpose = + std::get_if<std::string>(&it->second); + if (swInvPurpose == nullptr) + { + BMCWEB_LOG_DEBUG << "wrong types for " + "property \"Purpose\"!"; + messages::internalError(aResp->res); + return; + } + + if (*swInvPurpose != fwVersionPurpose) + { + // Not purpose we're looking for + return; + } + it = propertiesList.find("Version"); + if (it == propertiesList.end()) + { + BMCWEB_LOG_DEBUG + << "Can't find property \"Version\"!"; + messages::internalError(aResp->res); + return; + } + const std::string *version = + std::get_if<std::string>(&it->second); + if (version == nullptr) + { + BMCWEB_LOG_DEBUG + << "Error getting fw version"; + messages::internalError(aResp->res); + return; + } + aResp->res.jsonValue[jsonIdxStr] = *version; + }, + objInfo[0].first, fw, + "org.freedesktop.DBus.Properties", "GetAll", + "xyz.openbmc_project.Software.Version"); + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetObject", fw, + std::array<const char *, 1>{ + "xyz.openbmc_project.Software.Activation"}); + } + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/software/functional", + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Association", "endpoints"); + + return; +} +} // namespace fw_util +} // namespace redfish |

