summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch
diff options
context:
space:
mode:
authorJason M. Bills <jason.m.bills@linux.intel.com>2021-08-26 23:18:00 +0300
committerJason M. Bills <jason.m.bills@linux.intel.com>2021-08-27 19:05:02 +0300
commit6f106a0a4ce15fe0678d4ffefd572e6978c72597 (patch)
treed98626c9763ad9048ac9bfd8269e12eced18d496 /meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch
parentae908254d22318b9e27acf6e5e28d1a4ab5e2195 (diff)
downloadopenbmc-6f106a0a4ce15fe0678d4ffefd572e6978c72597.tar.xz
Update to internal 0.70
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch')
-rw-r--r--[-rwxr-xr-x]meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch651
1 files changed, 390 insertions, 261 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch
index a76990262..b689748ea 100755..100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0001-Firmware-update-configuration-changes.patch
@@ -1,6 +1,6 @@
-From d5f2e8b00bc5f8a727a1ef678941c4993c3ea7a6 Mon Sep 17 00:00:00 2001
+From c65d6f4a6d2939335608957fba25e5c8a445813e Mon Sep 17 00:00:00 2001
From: Vikram Bodireddy <vikram.bodireddy@intel.com>
-Date: Wed, 18 Nov 2020 17:14:41 +0530
+Date: Mon, 28 Jun 2021 21:56:18 +0530
Subject: [PATCH] Firmware update configuration changes
This commit will provide user to PATCH the below firmware update
@@ -39,24 +39,32 @@ Tested:
- Successfully ran redfish validater with no new errors.
-Change-Id: I44e1743fd76aa37c7b8affa49a3e05f808187037
Signed-off-by: Vikram Bodireddy <vikram.bodireddy@intel.com>
-Signed-off-by: Helen Huang <he.huang@intel.com>
-Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
---
- redfish-core/lib/update_service.hpp | 338 ++++++++++++++++--
+ redfish-core/lib/update_service.hpp | 456 ++++++++++++++----
static/redfish/v1/$metadata/index.xml | 3 +
- .../JsonSchemas/OemUpdateService/index.json | 69 ++++
- .../redfish/v1/schema/OemUpdateService_v1.xml | 40 +++
- 4 files changed, 421 insertions(+), 29 deletions(-)
+ .../JsonSchemas/OemUpdateService/index.json | 69 +++
+ .../redfish/v1/schema/OemUpdateService_v1.xml | 40 ++
+ 4 files changed, 481 insertions(+), 87 deletions(-)
create mode 100644 static/redfish/v1/JsonSchemas/OemUpdateService/index.json
create mode 100644 static/redfish/v1/schema/OemUpdateService_v1.xml
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
-index ca1234f..0a9f81a 100644
+index 663d48b..70c58d4 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
-@@ -32,6 +32,17 @@ static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateErrorMatcher;
+@@ -26,7 +26,9 @@
+
+ namespace redfish
+ {
+-
++// params for multiple firmware targets
++std::vector<std::string> httpPushUriTargets;
++bool httpPushUriTargetBusy = false;
+ // Match signals added on software path
+ static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
+ static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateErrorMatcher;
+@@ -34,6 +36,17 @@ static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateErrorMatcher;
static bool fwUpdateInProgress = false;
// Timer for software available
static std::unique_ptr<boost::asio::steady_timer> fwAvailableTimer;
@@ -72,15 +80,15 @@ index ca1234f..0a9f81a 100644
+static constexpr const char* activationsStandBySpare =
+ "xyz.openbmc_project.Software.Activation.Activations.StandbySpare";
- static void cleanUp()
+ inline static void cleanUp()
{
-@@ -40,28 +51,120 @@ static void cleanUp()
+@@ -42,28 +55,120 @@ inline static void cleanUp()
fwUpdateErrorMatcher = nullptr;
}
- static void activateImage(const std::string& objPath,
-- const std::string& service)
-+ const std::string& service,
-+ const std::vector<std::string>& imgUriTargets)
+ inline static void activateImage(const std::string& objPath,
+- const std::string& service)
++ const std::string& service,
++ const std::vector<std::string>& imgUriTargets)
{
BMCWEB_LOG_DEBUG << "Activate image for " << objPath << " " << service;
+ // If targets is empty, it will apply to the active.
@@ -113,14 +121,14 @@ index ca1234f..0a9f81a 100644
+ const boost::system::error_code ec,
+ const crow::openbmc_mapper::GetSubTreeType& subtree) {
+ if (ec || !subtree.size())
- {
-- BMCWEB_LOG_DEBUG << "error_code = " << errorCode;
-- BMCWEB_LOG_DEBUG << "error msg = " << errorCode.message();
++ {
+ return;
+ }
+
+ for (const auto& [invObjPath, invDict] : subtree)
-+ {
+ {
+- BMCWEB_LOG_DEBUG << "error_code = " << errorCode;
+- BMCWEB_LOG_DEBUG << "error msg = " << errorCode.message();
+ std::size_t idPos = invObjPath.rfind("/");
+ if ((idPos == std::string::npos) ||
+ ((idPos + 1) >= invObjPath.size()))
@@ -205,7 +213,7 @@ index ca1234f..0a9f81a 100644
sdbusplus::message::message& m,
const crow::Request& req)
{
-@@ -74,22 +177,24 @@ static void
+@@ -76,22 +181,24 @@ static void
m.read(objPath, interfacesProperties);
@@ -234,7 +242,7 @@ index ca1234f..0a9f81a 100644
BMCWEB_LOG_DEBUG << "error msg = "
<< errorCode.message();
if (asyncResp)
-@@ -116,7 +221,7 @@ static void
+@@ -118,7 +225,7 @@ static void
// is added
fwAvailableTimer = nullptr;
@@ -243,7 +251,7 @@ index ca1234f..0a9f81a 100644
if (asyncResp)
{
std::shared_ptr<task::TaskData> task =
-@@ -248,8 +353,7 @@ static void
+@@ -250,8 +357,7 @@ static void
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
"xyz.openbmc_project.ObjectMapper", "GetObject", objPath.str,
@@ -253,7 +261,7 @@ index ca1234f..0a9f81a 100644
}
}
}
-@@ -259,7 +363,7 @@ static void
+@@ -261,7 +367,7 @@ static void
static void monitorForSoftwareAvailable(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const crow::Request& req, const std::string& url,
@@ -262,7 +270,7 @@ index ca1234f..0a9f81a 100644
{
// Only allow one FW update at a time
if (fwUpdateInProgress != false)
-@@ -299,9 +403,10 @@ static void monitorForSoftwareAvailable(
+@@ -301,9 +407,10 @@ static void monitorForSoftwareAvailable(
}
});
@@ -275,291 +283,412 @@ index ca1234f..0a9f81a 100644
};
fwUpdateInProgress = true;
-@@ -477,12 +582,15 @@ class UpdateServiceActionsSimpleUpdate : public Node
- std::string fwFile = imageURI.substr(separator + 1);
- BMCWEB_LOG_DEBUG << "Server: " << tftpServer + " File: " << fwFile;
+@@ -468,12 +575,15 @@ inline void requestRoutesUpdateServiceActionsSimpleUpdate(App& app)
+ std::string fwFile = imageURI.substr(separator + 1);
+ BMCWEB_LOG_DEBUG << "Server: " << tftpServer + " File: " << fwFile;
-+ // We will pass empty targets and its handled in activation.
-+ std::vector<std::string> httpUriTargets;
++ // We will pass empty targets and its handled in activation.
++ std::vector<std::string> httpUriTargets;
+
- // Setup callback for when new software detected
- // Give TFTP 10 minutes to complete
- monitorForSoftwareAvailable(
- asyncResp, req,
- "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate",
-- 600);
-+ httpUriTargets, 600);
+ // Setup callback for when new software detected
+ // Give TFTP 10 minutes to complete
+ monitorForSoftwareAvailable(
+ asyncResp, req,
+ "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate",
+- 600);
++ httpUriTargets, 600);
- // TFTP can take up to 10 minutes depending on image size and
- // connection speed. Return to caller as soon as the TFTP operation
-@@ -516,7 +624,8 @@ class UpdateServiceActionsSimpleUpdate : public Node
- class UpdateService : public Node
- {
- public:
-- UpdateService(App& app) : Node(app, "/redfish/v1/UpdateService/")
-+ UpdateService(App& app) :
-+ Node(app, "/redfish/v1/UpdateService/"), httpPushUriTargetBusy(false)
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
-@@ -528,6 +637,8 @@ class UpdateService : public Node
- }
-
- private:
-+ std::vector<std::string> httpPushUriTargets;
-+ bool httpPushUriTargetBusy;
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&, const std::vector<std::string>&) override
- {
-@@ -538,6 +649,9 @@ class UpdateService : public Node
- asyncResp->res.jsonValue["Description"] = "Service for Software Update";
- asyncResp->res.jsonValue["Name"] = "Update Service";
- asyncResp->res.jsonValue["HttpPushUri"] = "/redfish/v1/UpdateService";
-+ asyncResp->res.jsonValue["HttpPushUriTargets"] = httpPushUriTargets;
-+ asyncResp->res.jsonValue["HttpPushUriTargetsBusy"] =
-+ httpPushUriTargetBusy;
- // UpdateService cannot be disabled
- asyncResp->res.jsonValue["ServiceEnabled"] = true;
- asyncResp->res.jsonValue["FirmwareInventory"] = {
-@@ -587,6 +701,32 @@ class UpdateService : public Node
- "/xyz/openbmc_project/software/apply_time",
- "org.freedesktop.DBus.Properties", "Get",
- "xyz.openbmc_project.Software.ApplyTime", "RequestedApplyTime");
+ // TFTP can take up to 10 minutes depending on image size and
+ // connection speed. Return to caller as soon as the TFTP operation
+@@ -522,6 +632,9 @@ inline void requestRoutesUpdateService(App& app)
+ asyncResp->res.jsonValue["Name"] = "Update Service";
+ asyncResp->res.jsonValue["HttpPushUri"] =
+ "/redfish/v1/UpdateService";
++ asyncResp->res.jsonValue["HttpPushUriTargets"] = httpPushUriTargets;
++ asyncResp->res.jsonValue["HttpPushUriTargetsBusy"] =
++ httpPushUriTargetBusy;
+ // UpdateService cannot be disabled
+ asyncResp->res.jsonValue["ServiceEnabled"] = true;
+ asyncResp->res.jsonValue["FirmwareInventory"] = {
+@@ -536,7 +649,8 @@ inline void requestRoutesUpdateService(App& app)
+ asyncResp->res
+ .jsonValue["Actions"]["#UpdateService.SimpleUpdate"];
+ updateSvcSimpleUpdate["target"] =
+- "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate";
++ "/redfish/v1/UpdateService/Actions/"
++ "UpdateService.SimpleUpdate";
+ updateSvcSimpleUpdate["TransferProtocol@Redfish.AllowableValues"] =
+ {"TFTP"};
+ #endif
+@@ -578,89 +692,258 @@ inline void requestRoutesUpdateService(App& app)
+ "/xyz/openbmc_project/software/apply_time",
+ "org.freedesktop.DBus.Properties", "Get",
+ "xyz.openbmc_project.Software.ApplyTime", "RequestedApplyTime");
+
-+ // Get the ApplyOptions value
-+ crow::connections::systemBus->async_method_call(
-+ [asyncResp](const boost::system::error_code ec,
-+ const std::variant<bool> applyOption) {
-+ if (ec)
-+ {
-+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-+ messages::internalError(asyncResp->res);
-+ return;
-+ }
++ // Get the ApplyOptions value
++ crow::connections::systemBus->async_method_call(
++ [asyncResp](const boost::system::error_code ec,
++ const std::variant<bool> applyOption) {
++ if (ec)
++ {
++ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
++ messages::internalError(asyncResp->res);
++ return;
++ }
+
-+ const bool* b = std::get_if<bool>(&applyOption);
++ const bool* b = std::get_if<bool>(&applyOption);
+
-+ if (b)
-+ {
-+ asyncResp->res
-+ .jsonValue["Oem"]["ApplyOptions"]["@odata.type"] =
-+ "#OemUpdateService.ApplyOptions";
-+ asyncResp->res
-+ .jsonValue["Oem"]["ApplyOptions"]["ClearConfig"] = *b;
-+ }
-+ },
-+ "xyz.openbmc_project.Software.BMC.Updater",
-+ "/xyz/openbmc_project/software", "org.freedesktop.DBus.Properties",
-+ "Get", "xyz.openbmc_project.Software.ApplyOptions", "ClearConfig");
- }
-
- void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-@@ -596,12 +736,61 @@ class UpdateService : public Node
- BMCWEB_LOG_DEBUG << "doPatch...";
-
- std::optional<nlohmann::json> pushUriOptions;
-+ std::optional<std::vector<std::string>> imgTargets;
-+ std::optional<bool> imgTargetBusy;
-+ std::optional<nlohmann::json> oemProps;
++ if (b)
++ {
++ asyncResp->res
++ .jsonValue["Oem"]["ApplyOptions"]["@odata.type"] =
++ "#OemUpdateService.ApplyOptions";
++ asyncResp->res
++ .jsonValue["Oem"]["ApplyOptions"]["ClearConfig"] =
++ *b;
++ }
++ },
++ "xyz.openbmc_project.Software.BMC.Updater",
++ "/xyz/openbmc_project/software",
++ "org.freedesktop.DBus.Properties", "Get",
++ "xyz.openbmc_project.Software.ApplyOptions", "ClearConfig");
+ });
+
- if (!json_util::readJson(req, asyncResp->res, "HttpPushUriOptions",
-- pushUriOptions))
-+ pushUriOptions, "HttpPushUriTargets",
-+ imgTargets, "HttpPushUriTargetsBusy",
-+ imgTargetBusy, "Oem", oemProps))
- {
-+ BMCWEB_LOG_DEBUG << "UpdateService doPatch: Invalid request body";
- return;
- }
-
-+ if (oemProps)
-+ {
-+ std::optional<nlohmann::json> applyOptions;
+ BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/")
+ .privileges(redfish::privileges::patchUpdateService)
+- .methods(boost::beast::http::verb::patch)(
+- [](const crow::Request& req,
+- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+- BMCWEB_LOG_DEBUG << "doPatch...";
++ .methods(
++ boost::beast::http::verb::
++ patch)([](const crow::Request& req,
++ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
++ BMCWEB_LOG_DEBUG << "doPatch...";
+
-+ if (!json_util::readJson(*oemProps, asyncResp->res, "ApplyOptions",
-+ applyOptions))
++ std::optional<nlohmann::json> pushUriOptions;
++ std::optional<std::vector<std::string>> imgTargets;
++ std::optional<bool> imgTargetBusy;
++ std::optional<nlohmann::json> oemProps;
++ if (!json_util::readJson(req, asyncResp->res, "HttpPushUriOptions",
++ pushUriOptions, "HttpPushUriTargets",
++ imgTargets, "HttpPushUriTargetsBusy",
++ imgTargetBusy, "Oem", oemProps))
+ {
++ BMCWEB_LOG_DEBUG
++ << "UpdateService doPatch: Invalid request body";
+ return;
+ }
+
-+ if (applyOptions)
++ if (oemProps)
+ {
-+ std::optional<bool> clearConfig;
-+ if (!json_util::readJson(*applyOptions, asyncResp->res,
-+ "ClearConfig", clearConfig))
++ std::optional<nlohmann::json> applyOptions;
++
++ if (!json_util::readJson(*oemProps, asyncResp->res,
++ "ApplyOptions", applyOptions))
+ {
+ return;
+ }
+
-+ if (clearConfig)
++ if (applyOptions)
+ {
-+ // Set the requested image apply time value
-+ crow::connections::systemBus->async_method_call(
-+ [asyncResp](const boost::system::error_code ec) {
-+ if (ec)
-+ {
-+ BMCWEB_LOG_ERROR << "D-Bus responses error: "
-+ << ec;
-+ messages::internalError(asyncResp->res);
-+ return;
-+ }
-+ messages::success(asyncResp->res);
-+ },
-+ "xyz.openbmc_project.Software.BMC.Updater",
-+ "/xyz/openbmc_project/software",
-+ "org.freedesktop.DBus.Properties", "Set",
-+ "xyz.openbmc_project.Software.ApplyOptions",
-+ "ClearConfig", std::variant<bool>{*clearConfig});
++ std::optional<bool> clearConfig;
++ if (!json_util::readJson(*applyOptions, asyncResp->res,
++ "ClearConfig", clearConfig))
++ {
++ return;
++ }
+
+- std::optional<nlohmann::json> pushUriOptions;
+- if (!json_util::readJson(req, asyncResp->res,
+- "HttpPushUriOptions", pushUriOptions))
++ if (clearConfig)
++ {
++ // Set the requested image apply time value
++ crow::connections::systemBus->async_method_call(
++ [asyncResp](const boost::system::error_code ec) {
++ if (ec)
++ {
++ BMCWEB_LOG_ERROR
++ << "D-Bus responses error: " << ec;
++ messages::internalError(asyncResp->res);
++ return;
++ }
++ messages::success(asyncResp->res);
++ },
++ "xyz.openbmc_project.Software.BMC.Updater",
++ "/xyz/openbmc_project/software",
++ "org.freedesktop.DBus.Properties", "Set",
++ "xyz.openbmc_project.Software.ApplyOptions",
++ "ClearConfig", std::variant<bool>{*clearConfig});
++ }
+ }
+ }
-+ }
-+
- if (pushUriOptions)
- {
- std::optional<nlohmann::json> pushUriApplyTime;
-@@ -666,6 +855,98 @@ class UpdateService : public Node
- }
- }
- }
-+
-+ if (imgTargetBusy)
-+ {
-+ if ((httpPushUriTargetBusy) && (*imgTargetBusy))
++ if (pushUriOptions)
+ {
-+ BMCWEB_LOG_DEBUG
-+ << "Other client has reserved the HttpPushUriTargets "
-+ "property for firmware updates.";
-+ messages::resourceInUse(asyncResp->res);
-+ return;
++ std::optional<nlohmann::json> pushUriApplyTime;
++ if (!json_util::readJson(*pushUriOptions, asyncResp->res,
++ "HttpPushUriApplyTime",
++ pushUriApplyTime))
+ {
+ return;
+ }
+
+- if (pushUriOptions)
++ if (pushUriApplyTime)
+ {
+- std::optional<nlohmann::json> pushUriApplyTime;
+- if (!json_util::readJson(*pushUriOptions, asyncResp->res,
+- "HttpPushUriApplyTime",
+- pushUriApplyTime))
++ std::optional<std::string> applyTime;
++ if (!json_util::readJson(*pushUriApplyTime, asyncResp->res,
++ "ApplyTime", applyTime))
+ {
+ return;
+ }
+
+- if (pushUriApplyTime)
++ if (applyTime)
+ {
+- std::optional<std::string> applyTime;
+- if (!json_util::readJson(*pushUriApplyTime,
+- asyncResp->res, "ApplyTime",
+- applyTime))
++ std::string applyTimeNewVal;
++ if (applyTime == "Immediate")
++ {
++ applyTimeNewVal =
++ "xyz.openbmc_project.Software.ApplyTime."
++ "RequestedApplyTimes.Immediate";
++ }
++ else if (applyTime == "OnReset")
+ {
++ applyTimeNewVal =
++ "xyz.openbmc_project.Software.ApplyTime."
++ "RequestedApplyTimes.OnReset";
++ }
++ else
++ {
++ BMCWEB_LOG_INFO
++ << "ApplyTime value is not in the list of "
++ "acceptable values";
++ messages::propertyValueNotInList(
++ asyncResp->res, *applyTime, "ApplyTime");
+ return;
+ }
+
+- if (applyTime)
++ // Set the requested image apply time value
++ crow::connections::systemBus->async_method_call(
++ [asyncResp](const boost::system::error_code ec) {
++ if (ec)
++ {
++ BMCWEB_LOG_ERROR
++ << "D-Bus responses error: " << ec;
++ messages::internalError(asyncResp->res);
++ return;
++ }
++ messages::success(asyncResp->res);
++ },
++ "xyz.openbmc_project.Settings",
++ "/xyz/openbmc_project/software/apply_time",
++ "org.freedesktop.DBus.Properties", "Set",
++ "xyz.openbmc_project.Software.ApplyTime",
++ "RequestedApplyTime",
++ std::variant<std::string>{applyTimeNewVal});
++ }
++ }
+ }
-+
-+ if (imgTargets)
++ if (imgTargetBusy)
+ {
-+ if (!(*imgTargetBusy))
++ if ((httpPushUriTargetBusy) && (*imgTargetBusy))
+ {
+ BMCWEB_LOG_DEBUG
-+ << "UpdateService doPatch: httpPushUriTargetBusy "
-+ "should be "
-+ "true before setting httpPushUriTargets";
-+ messages::invalidObject(asyncResp->res,
-+ "HttpPushUriTargetsBusy");
++ << "Other client has reserved the HttpPushUriTargets "
++ "property for firmware updates.";
++ messages::resourceInUse(asyncResp->res);
+ return;
+ }
-+ if ((*imgTargets).size() != 0)
++
++ if (imgTargets)
+ {
-+ // TODO: Now we support max one target becuase
-+ // software-manager code support one activation per object.
-+ // It will be enhanced to multiple targets for single image
-+ // in future. For now, consider first target alone.
-+ if ((*imgTargets).size() != 1)
++ if (!(*imgTargetBusy))
+ {
++ BMCWEB_LOG_DEBUG
++ << "UpdateService doPatch: httpPushUriTargetBusy "
++ "should be "
++ "true before setting httpPushUriTargets";
+ messages::invalidObject(asyncResp->res,
-+ "HttpPushUriTargets");
++ "HttpPushUriTargetsBusy");
+ return;
+ }
-+ crow::connections::systemBus->async_method_call(
-+ [this, asyncResp, uriTargets{*imgTargets},
-+ targetBusy{*imgTargetBusy}](
-+ const boost::system::error_code ec,
-+ const std::vector<std::string> swInvPaths) {
-+ if (ec)
-+ {
-+ return;
-+ }
-+
-+ bool swInvObjFound = false;
-+ for (const std::string& path : swInvPaths)
-+ {
-+ std::size_t idPos = path.rfind("/");
-+ if ((idPos == std::string::npos) ||
-+ ((idPos + 1) >= path.size()))
++ if ((*imgTargets).size() != 0)
++ {
++ // TODO: Now we support max one target becuase
++ // software-manager code support one activation per
++ // object. It will be enhanced to multiple targets for
++ // single image in future. For now, consider first
++ // target alone.
++ if ((*imgTargets).size() != 1)
+ {
+- std::string applyTimeNewVal;
+- if (applyTime == "Immediate")
+- {
+- applyTimeNewVal =
+- "xyz.openbmc_project.Software.ApplyTime."
+- "RequestedApplyTimes.Immediate";
+- }
+- else if (applyTime == "OnReset")
+- {
+- applyTimeNewVal =
+- "xyz.openbmc_project.Software.ApplyTime."
+- "RequestedApplyTimes.OnReset";
+- }
+- else
+- {
+- BMCWEB_LOG_INFO
+- << "ApplyTime value is not in the list of "
+- "acceptable values";
+- messages::propertyValueNotInList(
+- asyncResp->res, *applyTime, "ApplyTime");
+- return;
+- }
++ messages::invalidObject(asyncResp->res,
++ "HttpPushUriTargets");
++ return;
++ }
++ crow::connections::systemBus->async_method_call(
++ [asyncResp, uriTargets{*imgTargets},
++ targetBusy{*imgTargetBusy}](
++ const boost::system::error_code ec,
++ const std::vector<std::string> swInvPaths) {
++ if (ec)
+ {
-+ messages::internalError(asyncResp->res);
-+ BMCWEB_LOG_DEBUG
-+ << "Can't parse firmware ID!!";
+ return;
+ }
-+ std::string swId = path.substr(idPos + 1);
+
+- // Set the requested image apply time value
+- crow::connections::systemBus->async_method_call(
+- [asyncResp](
+- const boost::system::error_code ec) {
+- if (ec)
++ bool swInvObjFound = false;
++ for (const std::string& path : swInvPaths)
++ {
++ std::size_t idPos = path.rfind("/");
++ if ((idPos == std::string::npos) ||
++ ((idPos + 1) >= path.size()))
+ {
+- BMCWEB_LOG_ERROR
+- << "D-Bus responses error: " << ec;
+ messages::internalError(asyncResp->res);
++ BMCWEB_LOG_DEBUG
++ << "Can't parse firmware ID!!";
+ return;
+ }
+- messages::success(asyncResp->res);
+- },
+- "xyz.openbmc_project.Settings",
+- "/xyz/openbmc_project/software/apply_time",
+- "org.freedesktop.DBus.Properties", "Set",
+- "xyz.openbmc_project.Software.ApplyTime",
+- "RequestedApplyTime",
+- std::variant<std::string>{applyTimeNewVal});
+- }
++ std::string swId = path.substr(idPos + 1);
+
-+ if (swId == uriTargets[0])
++ if (swId == uriTargets[0])
++ {
++ swInvObjFound = true;
++ break;
++ }
++ }
++ if (!swInvObjFound)
+ {
-+ swInvObjFound = true;
-+ break;
++ messages::invalidObject(
++ asyncResp->res, "HttpPushUriTargets");
++ return;
+ }
-+ }
-+ if (!swInvObjFound)
-+ {
-+ messages::invalidObject(asyncResp->res,
-+ "HttpPushUriTargets");
-+ return;
-+ }
-+ this->httpPushUriTargetBusy = targetBusy;
-+ this->httpPushUriTargets = uriTargets;
-+ },
-+ "xyz.openbmc_project.ObjectMapper",
-+ "/xyz/openbmc_project/object_mapper",
-+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-+ "/", static_cast<int32_t>(0),
-+ std::array<const char*, 1>{versionIntf});
-+ }
++ httpPushUriTargetBusy = targetBusy;
++ httpPushUriTargets = uriTargets;
++ },
++ "xyz.openbmc_project.ObjectMapper",
++ "/xyz/openbmc_project/object_mapper",
++ "xyz.openbmc_project.ObjectMapper",
++ "GetSubTreePaths", "/", static_cast<int32_t>(0),
++ std::array<const char*, 1>{versionIntf});
++ }
++ else
++ {
++ httpPushUriTargetBusy = *imgTargetBusy;
++ httpPushUriTargets = *imgTargets;
+ }
+ }
+- });
+ else
+ {
+ httpPushUriTargetBusy = *imgTargetBusy;
-+ httpPushUriTargets = *imgTargets;
+ }
+ }
-+ else
-+ {
-+ httpPushUriTargetBusy = *imgTargetBusy;
-+ }
-+ }
- }
-
- void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-@@ -675,8 +956,8 @@ class UpdateService : public Node
- BMCWEB_LOG_DEBUG << "doPost...";
++ });
++
+ BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/")
+ .privileges(redfish::privileges::postUpdateService)
+ .methods(boost::beast::http::verb::post)(
+@@ -670,7 +953,8 @@ inline void requestRoutesUpdateService(App& app)
- // Setup callback for when new software detected
-- monitorForSoftwareAvailable(asyncResp, req,
-- "/redfish/v1/UpdateService");
-+ monitorForSoftwareAvailable(asyncResp, req, "/redfish/v1/UpdateService",
-+ httpPushUriTargets);
+ // Setup callback for when new software detected
+ monitorForSoftwareAvailable(asyncResp, req,
+- "/redfish/v1/UpdateService");
++ "/redfish/v1/UpdateService",
++ httpPushUriTargets);
- std::string filepath(
- "/tmp/images/" +
-@@ -759,7 +1040,7 @@ class SoftwareInventoryCollection : public Node
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree",
- "/xyz/openbmc_project/software", static_cast<int32_t>(0),
-- std::array<const char*, 1>{"xyz.openbmc_project.Software.Version"});
-+ std::array<const char*, 1>{versionIntf});
- }
- };
+ std::string filepath("/tmp/images/" +
+ boost::uuids::to_string(
+@@ -683,7 +967,7 @@ inline void requestRoutesUpdateService(App& app)
+ out.close();
+ BMCWEB_LOG_DEBUG << "file upload complete!!";
+ });
+-}
++} // namespace redfish
-@@ -940,7 +1221,7 @@ class SoftwareInventory : public Node
- },
- obj.second[0].first, obj.first,
- "org.freedesktop.DBus.Properties", "GetAll",
-- "xyz.openbmc_project.Software.Version");
-+ versionIntf);
- }
- if (!found)
- {
-@@ -961,8 +1242,7 @@ class SoftwareInventory : public Node
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/",
-- static_cast<int32_t>(0),
-- std::array<const char*, 1>{"xyz.openbmc_project.Software.Version"});
-+ static_cast<int32_t>(0), std::array<const char*, 1>{versionIntf});
- }
- };
+ inline void requestRoutesSoftwareInventoryCollection(App& app)
+ {
+@@ -746,8 +1030,7 @@ inline void requestRoutesSoftwareInventoryCollection(App& app)
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/software", static_cast<int32_t>(0),
+- std::array<const char*, 1>{
+- "xyz.openbmc_project.Software.Version"});
++ std::array<const char*, 1>{versionIntf});
+ });
+ }
+ /* Fill related item links (i.e. bmc, bios) in for inventory */
+@@ -911,7 +1194,7 @@ inline void requestRoutesSoftwareInventory(App& app)
+ },
+ obj.second[0].first, obj.first,
+ "org.freedesktop.DBus.Properties", "GetAll",
+- "xyz.openbmc_project.Software.Version");
++ versionIntf);
+ }
+ if (!found)
+ {
+@@ -935,8 +1218,7 @@ inline void requestRoutesSoftwareInventory(App& app)
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/",
+ static_cast<int32_t>(0),
+- std::array<const char*, 1>{
+- "xyz.openbmc_project.Software.Version"});
++ std::array<const char*, 1>{versionIntf});
+ });
+ }
diff --git a/static/redfish/v1/$metadata/index.xml b/static/redfish/v1/$metadata/index.xml
-index 9d9fd1f..6cbc0d1 100644
+index eba38bf..876ebfb 100644
--- a/static/redfish/v1/$metadata/index.xml
+++ b/static/redfish/v1/$metadata/index.xml
-@@ -2145,6 +2145,9 @@
+@@ -2346,6 +2346,9 @@
<edmx:Reference Uri="/redfish/v1/schema/OemComputerSystem_v1.xml">
<edmx:Include Namespace="OemComputerSystem"/>
</edmx:Reference>