xref: /openbmc/bmcweb/features/redfish/include/utils/sw_utils.hpp (revision 3544d2a719c8bb7b07f9a39f61a3770ec84b909f)
1eee0013eSWilly Tu #pragma once
23ccb3adbSEd Tanous #include "async_resp.hpp"
33ccb3adbSEd Tanous #include "dbus_utility.hpp"
43ccb3adbSEd Tanous #include "error_messages.hpp"
53ccb3adbSEd Tanous #include "generated/enums/resource.hpp"
6eddfc437SWilly Tu #include "http/utility.hpp"
73ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
83ccb3adbSEd Tanous 
9e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
10ef4c65b7SEd Tanous #include <boost/url/format.hpp>
11eee0013eSWilly Tu #include <sdbusplus/asio/property.hpp>
12d1bde9e5SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
13eee0013eSWilly Tu 
14eee0013eSWilly Tu #include <algorithm>
15e99073f5SGeorge Liu #include <array>
16*3544d2a7SEd Tanous #include <ranges>
17eee0013eSWilly Tu #include <string>
18e99073f5SGeorge Liu #include <string_view>
19eee0013eSWilly Tu #include <vector>
20eee0013eSWilly Tu 
21eee0013eSWilly Tu namespace redfish
22eee0013eSWilly Tu {
23eee0013eSWilly Tu namespace sw_util
24eee0013eSWilly Tu {
25eee0013eSWilly Tu /* @brief String that indicates a bios software instance */
26eee0013eSWilly Tu constexpr const char* biosPurpose =
27eee0013eSWilly Tu     "xyz.openbmc_project.Software.Version.VersionPurpose.Host";
28eee0013eSWilly Tu 
29eee0013eSWilly Tu /* @brief String that indicates a BMC software instance */
30eee0013eSWilly Tu constexpr const char* bmcPurpose =
31eee0013eSWilly Tu     "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
32eee0013eSWilly Tu 
33eee0013eSWilly Tu /**
34eee0013eSWilly Tu  * @brief Populate the running software version and image links
35eee0013eSWilly Tu  *
36ac106bf6SEd Tanous  * @param[i,o] asyncResp             Async response object
37eee0013eSWilly Tu  * @param[i]   swVersionPurpose  Indicates what target to look for
38ac106bf6SEd Tanous  * @param[i]   activeVersionPropName  Index in asyncResp->res.jsonValue to write
39eee0013eSWilly Tu  * the running software version to
40ac106bf6SEd Tanous  * @param[i]   populateLinkToImages  Populate asyncResp->res "Links"
41eee0013eSWilly Tu  * "ActiveSoftwareImage" with a link to the running software image and
42eee0013eSWilly Tu  * "SoftwareImages" with a link to the all its software images
43eee0013eSWilly Tu  *
44eee0013eSWilly Tu  * @return void
45eee0013eSWilly Tu  */
46ac106bf6SEd Tanous inline void populateSoftwareInformation(
47ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
48eee0013eSWilly Tu     const std::string& swVersionPurpose,
49ac106bf6SEd Tanous     const std::string& activeVersionPropName, const bool populateLinkToImages)
50eee0013eSWilly Tu {
51eee0013eSWilly Tu     // Used later to determine running (known on Redfish as active) Sw images
52a4eb761aSGeorge Liu     dbus::utility::getAssociationEndPoints(
53eee0013eSWilly Tu         "/xyz/openbmc_project/software/functional",
54ac106bf6SEd Tanous         [asyncResp, swVersionPurpose, activeVersionPropName,
55ac106bf6SEd Tanous          populateLinkToImages](
56a4eb761aSGeorge Liu             const boost::system::error_code& ec,
57a4eb761aSGeorge Liu             const dbus::utility::MapperEndPoints& functionalSw) {
5862598e31SEd Tanous         BMCWEB_LOG_DEBUG("populateSoftwareInformation enter");
59eee0013eSWilly Tu         if (ec)
60eee0013eSWilly Tu         {
6162598e31SEd Tanous             BMCWEB_LOG_ERROR("error_code = {}", ec);
6262598e31SEd Tanous             BMCWEB_LOG_ERROR("error msg = {}", ec.message());
63ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
64eee0013eSWilly Tu             return;
65eee0013eSWilly Tu         }
66eee0013eSWilly Tu 
67eee0013eSWilly Tu         if (functionalSw.empty())
68eee0013eSWilly Tu         {
69eee0013eSWilly Tu             // Could keep going and try to populate SoftwareImages but
70eee0013eSWilly Tu             // something is seriously wrong, so just fail
7162598e31SEd Tanous             BMCWEB_LOG_ERROR("Zero functional software in system");
72ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
73eee0013eSWilly Tu             return;
74eee0013eSWilly Tu         }
75eee0013eSWilly Tu 
76eee0013eSWilly Tu         std::vector<std::string> functionalSwIds;
77eee0013eSWilly Tu         // example functionalSw:
78eee0013eSWilly Tu         // v as 2 "/xyz/openbmc_project/software/ace821ef"
79eee0013eSWilly Tu         //        "/xyz/openbmc_project/software/230fb078"
80c6830d5fSGunnar Mills         for (const auto& sw : functionalSw)
81eee0013eSWilly Tu         {
82c6830d5fSGunnar Mills             sdbusplus::message::object_path path(sw);
83eee0013eSWilly Tu             std::string leaf = path.filename();
84eee0013eSWilly Tu             if (leaf.empty())
85eee0013eSWilly Tu             {
86eee0013eSWilly Tu                 continue;
87eee0013eSWilly Tu             }
88eee0013eSWilly Tu 
89eee0013eSWilly Tu             functionalSwIds.push_back(leaf);
90eee0013eSWilly Tu         }
91eee0013eSWilly Tu 
92e99073f5SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces = {
93e99073f5SGeorge Liu             "xyz.openbmc_project.Software.Version"};
94e99073f5SGeorge Liu         dbus::utility::getSubTree(
95e99073f5SGeorge Liu             "/xyz/openbmc_project/software", 0, interfaces,
96ac106bf6SEd Tanous             [asyncResp, swVersionPurpose, activeVersionPropName,
97eee0013eSWilly Tu              populateLinkToImages, functionalSwIds](
98e99073f5SGeorge Liu                 const boost::system::error_code& ec2,
99eee0013eSWilly Tu                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
100eee0013eSWilly Tu             if (ec2)
101eee0013eSWilly Tu             {
10262598e31SEd Tanous                 BMCWEB_LOG_ERROR("error_code = {}", ec2);
10362598e31SEd Tanous                 BMCWEB_LOG_ERROR("error msg = {}", ec2.message());
104ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
105eee0013eSWilly Tu                 return;
106eee0013eSWilly Tu             }
107eee0013eSWilly Tu 
10862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found {} images", subtree.size());
109eee0013eSWilly Tu 
110eee0013eSWilly Tu             for (const std::pair<std::string,
111eee0013eSWilly Tu                                  std::vector<std::pair<
112eee0013eSWilly Tu                                      std::string, std::vector<std::string>>>>&
113eee0013eSWilly Tu                      obj : subtree)
114eee0013eSWilly Tu             {
115eee0013eSWilly Tu                 sdbusplus::message::object_path path(obj.first);
116eee0013eSWilly Tu                 std::string swId = path.filename();
117eee0013eSWilly Tu                 if (swId.empty())
118eee0013eSWilly Tu                 {
119ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
12062598e31SEd Tanous                     BMCWEB_LOG_ERROR("Invalid software ID");
121eee0013eSWilly Tu 
122eee0013eSWilly Tu                     return;
123eee0013eSWilly Tu                 }
124eee0013eSWilly Tu 
125eee0013eSWilly Tu                 bool runningImage = false;
126eee0013eSWilly Tu                 // Look at Ids from
127eee0013eSWilly Tu                 // /xyz/openbmc_project/software/functional
128eee0013eSWilly Tu                 // to determine if this is a running image
129*3544d2a7SEd Tanous                 if (std::ranges::find(functionalSwIds, swId) !=
130*3544d2a7SEd Tanous                     functionalSwIds.end())
131eee0013eSWilly Tu                 {
132eee0013eSWilly Tu                     runningImage = true;
133eee0013eSWilly Tu                 }
134eee0013eSWilly Tu 
135eee0013eSWilly Tu                 // Now grab its version info
136d1bde9e5SKrzysztof Grobelny                 sdbusplus::asio::getAllProperties(
137d1bde9e5SKrzysztof Grobelny                     *crow::connections::systemBus, obj.second[0].first,
138d1bde9e5SKrzysztof Grobelny                     obj.first, "xyz.openbmc_project.Software.Version",
139ac106bf6SEd Tanous                     [asyncResp, swId, runningImage, swVersionPurpose,
140eee0013eSWilly Tu                      activeVersionPropName, populateLinkToImages](
1415e7e2dc5SEd Tanous                         const boost::system::error_code& ec3,
142eee0013eSWilly Tu                         const dbus::utility::DBusPropertiesMap&
143eee0013eSWilly Tu                             propertiesList) {
144eee0013eSWilly Tu                     if (ec3)
145eee0013eSWilly Tu                     {
14662598e31SEd Tanous                         BMCWEB_LOG_ERROR("error_code = {}", ec3);
14762598e31SEd Tanous                         BMCWEB_LOG_ERROR("error msg = {}", ec3.message());
148eee0013eSWilly Tu                         // Have seen the code update app delete the D-Bus
149eee0013eSWilly Tu                         // object, during code update, between the call to
150eee0013eSWilly Tu                         // mapper and here. Just leave these properties off if
151eee0013eSWilly Tu                         // resource not found.
152eee0013eSWilly Tu                         if (ec3.value() == EBADR)
153eee0013eSWilly Tu                         {
154eee0013eSWilly Tu                             return;
155eee0013eSWilly Tu                         }
156ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
157eee0013eSWilly Tu                         return;
158eee0013eSWilly Tu                     }
159eee0013eSWilly Tu                     // example propertiesList
160eee0013eSWilly Tu                     // a{sv} 2 "Version" s
161eee0013eSWilly Tu                     // "IBM-witherspoon-OP9-v2.0.10-2.22" "Purpose"
162eee0013eSWilly Tu                     // s
163eee0013eSWilly Tu                     // "xyz.openbmc_project.Software.Version.VersionPurpose.Host"
164d1bde9e5SKrzysztof Grobelny                     const std::string* version = nullptr;
165d1bde9e5SKrzysztof Grobelny                     const std::string* swInvPurpose = nullptr;
166d1bde9e5SKrzysztof Grobelny 
167d1bde9e5SKrzysztof Grobelny                     const bool success = sdbusplus::unpackPropertiesNoThrow(
168d1bde9e5SKrzysztof Grobelny                         dbus_utils::UnpackErrorPrinter(), propertiesList,
169d1bde9e5SKrzysztof Grobelny                         "Purpose", swInvPurpose, "Version", version);
170d1bde9e5SKrzysztof Grobelny 
171d1bde9e5SKrzysztof Grobelny                     if (!success)
172eee0013eSWilly Tu                     {
173ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
174eee0013eSWilly Tu                         return;
175eee0013eSWilly Tu                     }
176eee0013eSWilly Tu 
177d1bde9e5SKrzysztof Grobelny                     if (version == nullptr || version->empty())
178eee0013eSWilly Tu                     {
179ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
180eee0013eSWilly Tu                         return;
181eee0013eSWilly Tu                     }
182d1bde9e5SKrzysztof Grobelny                     if (swInvPurpose == nullptr ||
183d1bde9e5SKrzysztof Grobelny                         *swInvPurpose != swVersionPurpose)
184eee0013eSWilly Tu                     {
185eee0013eSWilly Tu                         // Not purpose we're looking for
186eee0013eSWilly Tu                         return;
187eee0013eSWilly Tu                     }
188eee0013eSWilly Tu 
18962598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Image ID: {}", swId);
19062598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Running image: {}", runningImage);
19162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Image purpose: {}", *swInvPurpose);
192d1bde9e5SKrzysztof Grobelny 
193eee0013eSWilly Tu                     if (populateLinkToImages)
194eee0013eSWilly Tu                     {
195eee0013eSWilly Tu                         nlohmann::json& softwareImageMembers =
196ac106bf6SEd Tanous                             asyncResp->res.jsonValue["Links"]["SoftwareImages"];
197eee0013eSWilly Tu                         // Firmware images are at
198eee0013eSWilly Tu                         // /redfish/v1/UpdateService/FirmwareInventory/<Id>
199eee0013eSWilly Tu                         // e.g. .../FirmwareInventory/82d3ec86
200613dabeaSEd Tanous                         nlohmann::json::object_t member;
201ef4c65b7SEd Tanous                         member["@odata.id"] = boost::urls::format(
202ef4c65b7SEd Tanous                             "/redfish/v1/UpdateService/FirmwareInventory/{}",
203ef4c65b7SEd Tanous                             swId);
204b2ba3072SPatrick Williams                         softwareImageMembers.emplace_back(std::move(member));
205ac106bf6SEd Tanous                         asyncResp->res
206eee0013eSWilly Tu                             .jsonValue["Links"]["SoftwareImages@odata.count"] =
207eee0013eSWilly Tu                             softwareImageMembers.size();
208eee0013eSWilly Tu 
209eee0013eSWilly Tu                         if (runningImage)
210eee0013eSWilly Tu                         {
211613dabeaSEd Tanous                             nlohmann::json::object_t runningMember;
212ef4c65b7SEd Tanous                             runningMember["@odata.id"] = boost::urls::format(
213ef4c65b7SEd Tanous                                 "/redfish/v1/UpdateService/FirmwareInventory/{}",
214ef4c65b7SEd Tanous                                 swId);
215eee0013eSWilly Tu                             // Create the link to the running image
216ac106bf6SEd Tanous                             asyncResp->res
217613dabeaSEd Tanous                                 .jsonValue["Links"]["ActiveSoftwareImage"] =
218613dabeaSEd Tanous                                 std::move(runningMember);
219eee0013eSWilly Tu                         }
220eee0013eSWilly Tu                     }
221eee0013eSWilly Tu                     if (!activeVersionPropName.empty() && runningImage)
222eee0013eSWilly Tu                     {
223ac106bf6SEd Tanous                         asyncResp->res.jsonValue[activeVersionPropName] =
224ac106bf6SEd Tanous                             *version;
225eee0013eSWilly Tu                     }
226d1bde9e5SKrzysztof Grobelny                     });
227eee0013eSWilly Tu             }
228e99073f5SGeorge Liu             });
229eee0013eSWilly Tu         });
230eee0013eSWilly Tu }
231eee0013eSWilly Tu 
232eee0013eSWilly Tu /**
233eee0013eSWilly Tu  * @brief Translate input swState to Redfish state
234eee0013eSWilly Tu  *
235eee0013eSWilly Tu  * This function will return the corresponding Redfish state
236eee0013eSWilly Tu  *
237eee0013eSWilly Tu  * @param[i]   swState  The OpenBMC software state
238eee0013eSWilly Tu  *
239eee0013eSWilly Tu  * @return The corresponding Redfish state
240eee0013eSWilly Tu  */
2410ec8b83dSEd Tanous inline resource::State getRedfishSwState(const std::string& swState)
242eee0013eSWilly Tu {
243eee0013eSWilly Tu     if (swState == "xyz.openbmc_project.Software.Activation.Activations.Active")
244eee0013eSWilly Tu     {
2450ec8b83dSEd Tanous         return resource::State::Enabled;
246eee0013eSWilly Tu     }
247eee0013eSWilly Tu     if (swState == "xyz.openbmc_project.Software.Activation."
248eee0013eSWilly Tu                    "Activations.Activating")
249eee0013eSWilly Tu     {
2500ec8b83dSEd Tanous         return resource::State::Updating;
251eee0013eSWilly Tu     }
252eee0013eSWilly Tu     if (swState == "xyz.openbmc_project.Software.Activation."
253eee0013eSWilly Tu                    "Activations.StandbySpare")
254eee0013eSWilly Tu     {
2550ec8b83dSEd Tanous         return resource::State::StandbySpare;
256eee0013eSWilly Tu     }
25762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Default sw state {} to Disabled", swState);
2580ec8b83dSEd Tanous     return resource::State::Disabled;
259eee0013eSWilly Tu }
260eee0013eSWilly Tu 
261eee0013eSWilly Tu /**
262eee0013eSWilly Tu  * @brief Translate input swState to Redfish health state
263eee0013eSWilly Tu  *
264eee0013eSWilly Tu  * This function will return the corresponding Redfish health state
265eee0013eSWilly Tu  *
266eee0013eSWilly Tu  * @param[i]   swState  The OpenBMC software state
267eee0013eSWilly Tu  *
268eee0013eSWilly Tu  * @return The corresponding Redfish health state
269eee0013eSWilly Tu  */
270eee0013eSWilly Tu inline std::string getRedfishSwHealth(const std::string& swState)
271eee0013eSWilly Tu {
272eee0013eSWilly Tu     if ((swState ==
273eee0013eSWilly Tu          "xyz.openbmc_project.Software.Activation.Activations.Active") ||
274eee0013eSWilly Tu         (swState == "xyz.openbmc_project.Software.Activation.Activations."
275eee0013eSWilly Tu                     "Activating") ||
276eee0013eSWilly Tu         (swState ==
277eee0013eSWilly Tu          "xyz.openbmc_project.Software.Activation.Activations.Ready"))
278eee0013eSWilly Tu     {
279eee0013eSWilly Tu         return "OK";
280eee0013eSWilly Tu     }
28162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Sw state {} to Warning", swState);
282eee0013eSWilly Tu     return "Warning";
283eee0013eSWilly Tu }
284eee0013eSWilly Tu 
285eee0013eSWilly Tu /**
286eee0013eSWilly Tu  * @brief Put status of input swId into json response
287eee0013eSWilly Tu  *
288eee0013eSWilly Tu  * This function will put the appropriate Redfish state of the input
289eee0013eSWilly Tu  * software id to ["Status"]["State"] within the json response
290eee0013eSWilly Tu  *
291ac106bf6SEd Tanous  * @param[i,o] asyncResp    Async response object
292eee0013eSWilly Tu  * @param[i]   swId     The software ID to get status for
293eee0013eSWilly Tu  * @param[i]   dbusSvc  The dbus service implementing the software object
294eee0013eSWilly Tu  *
295eee0013eSWilly Tu  * @return void
296eee0013eSWilly Tu  */
297eee0013eSWilly Tu inline void getSwStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
298eee0013eSWilly Tu                         const std::shared_ptr<std::string>& swId,
299eee0013eSWilly Tu                         const std::string& dbusSvc)
300eee0013eSWilly Tu {
30162598e31SEd Tanous     BMCWEB_LOG_DEBUG("getSwStatus: swId {} svc {}", *swId, dbusSvc);
302eee0013eSWilly Tu 
303d1bde9e5SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
304d1bde9e5SKrzysztof Grobelny         *crow::connections::systemBus, dbusSvc,
305d1bde9e5SKrzysztof Grobelny         "/xyz/openbmc_project/software/" + *swId,
306d1bde9e5SKrzysztof Grobelny         "xyz.openbmc_project.Software.Activation",
307eee0013eSWilly Tu         [asyncResp,
3088b24275dSEd Tanous          swId](const boost::system::error_code& ec,
309eee0013eSWilly Tu                const dbus::utility::DBusPropertiesMap& propertiesList) {
3108b24275dSEd Tanous         if (ec)
311eee0013eSWilly Tu         {
312eee0013eSWilly Tu             // not all swtypes are updateable, this is ok
313eee0013eSWilly Tu             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
314eee0013eSWilly Tu             return;
315eee0013eSWilly Tu         }
316d1bde9e5SKrzysztof Grobelny 
317eee0013eSWilly Tu         const std::string* swInvActivation = nullptr;
318d1bde9e5SKrzysztof Grobelny 
319d1bde9e5SKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
320d1bde9e5SKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), propertiesList, "Activation",
321d1bde9e5SKrzysztof Grobelny             swInvActivation);
322d1bde9e5SKrzysztof Grobelny 
323d1bde9e5SKrzysztof Grobelny         if (!success)
324eee0013eSWilly Tu         {
325d1bde9e5SKrzysztof Grobelny             messages::internalError(asyncResp->res);
326d1bde9e5SKrzysztof Grobelny             return;
327eee0013eSWilly Tu         }
328eee0013eSWilly Tu 
329eee0013eSWilly Tu         if (swInvActivation == nullptr)
330eee0013eSWilly Tu         {
331eee0013eSWilly Tu             messages::internalError(asyncResp->res);
332eee0013eSWilly Tu             return;
333eee0013eSWilly Tu         }
334d1bde9e5SKrzysztof Grobelny 
33562598e31SEd Tanous         BMCWEB_LOG_DEBUG("getSwStatus: Activation {}", *swInvActivation);
336eee0013eSWilly Tu         asyncResp->res.jsonValue["Status"]["State"] =
337eee0013eSWilly Tu             getRedfishSwState(*swInvActivation);
338eee0013eSWilly Tu         asyncResp->res.jsonValue["Status"]["Health"] =
339eee0013eSWilly Tu             getRedfishSwHealth(*swInvActivation);
340d1bde9e5SKrzysztof Grobelny         });
341eee0013eSWilly Tu }
342eee0013eSWilly Tu 
343eee0013eSWilly Tu /**
344eee0013eSWilly Tu  * @brief Updates programmable status of input swId into json response
345eee0013eSWilly Tu  *
346eee0013eSWilly Tu  * This function checks whether software inventory component
347eee0013eSWilly Tu  * can be programmable or not and fill's the "Updatable"
348eee0013eSWilly Tu  * Property.
349eee0013eSWilly Tu  *
350eee0013eSWilly Tu  * @param[i,o] asyncResp  Async response object
351eee0013eSWilly Tu  * @param[i]   swId       The software ID
352eee0013eSWilly Tu  */
353eee0013eSWilly Tu inline void
354eee0013eSWilly Tu     getSwUpdatableStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
355eee0013eSWilly Tu                          const std::shared_ptr<std::string>& swId)
356eee0013eSWilly Tu {
3576c3e9451SGeorge Liu     dbus::utility::getAssociationEndPoints(
358eee0013eSWilly Tu         "/xyz/openbmc_project/software/updateable",
3595e7e2dc5SEd Tanous         [asyncResp, swId](const boost::system::error_code& ec,
3606c3e9451SGeorge Liu                           const dbus::utility::MapperEndPoints& objPaths) {
361eee0013eSWilly Tu         if (ec)
362eee0013eSWilly Tu         {
36362598e31SEd Tanous             BMCWEB_LOG_DEBUG(" error_code = {} error msg =  {}", ec,
36462598e31SEd Tanous                              ec.message());
365eee0013eSWilly Tu             // System can exist with no updateable software,
366eee0013eSWilly Tu             // so don't throw error here.
367eee0013eSWilly Tu             return;
368eee0013eSWilly Tu         }
369eee0013eSWilly Tu         std::string reqSwObjPath = "/xyz/openbmc_project/software/" + *swId;
370eee0013eSWilly Tu 
371*3544d2a7SEd Tanous         if (std::ranges::find(objPaths, reqSwObjPath) != objPaths.end())
372eee0013eSWilly Tu         {
37383edb08fSGunnar Mills             asyncResp->res.jsonValue["Updateable"] = true;
374eee0013eSWilly Tu             return;
375eee0013eSWilly Tu         }
376eee0013eSWilly Tu         });
377eee0013eSWilly Tu }
378eee0013eSWilly Tu 
379eee0013eSWilly Tu } // namespace sw_util
380eee0013eSWilly Tu } // namespace redfish
381