summaryrefslogtreecommitdiffstats
path: root/redfish-core/include
diff options
context:
space:
mode:
authorAndrew Geissler <geissonator@yahoo.com>2019-02-19 13:05:38 -0600
committerAndrew Geissler <geissonator@yahoo.com>2019-04-05 20:54:21 +0000
commitcb7e1e7b053b375a32e0e701b4d72f4c6bd8df4b (patch)
treef0c61e3b2cf5cb5c214e339875c7ab43f6d4f4cf /redfish-core/include
parentc6c91d49187bf4cc186a52f8765a356fd8d164ec (diff)
downloadbmcweb-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.hpp190
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
OpenPOWER on IntegriCloud