xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision afc474aef028555fc0a6deb425bdad86f0a34db6)
1c5b2abe0SLewanczyk, Dawid /*
26be832e2SEd Tanous Copyright (c) 2018 Intel Corporation
36be832e2SEd Tanous 
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous 
86be832e2SEd Tanous       http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous 
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
1813451e39SWilly Tu #include "bmcweb_config.h"
1913451e39SWilly Tu 
203ccb3adbSEd Tanous #include "app.hpp"
211e1e598dSJonathan Doman #include "dbus_singleton.hpp"
227a1dbc48SGeorge Liu #include "dbus_utility.hpp"
23539d8c6bSEd Tanous #include "generated/enums/action_info.hpp"
248d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
25539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp"
2633e1f122SAndrew Geissler #include "generated/enums/resource.hpp"
27746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
281c8fba97SJames Feist #include "led.hpp"
29f4c99e70SEd Tanous #include "query.hpp"
30c5d03ff4SJennifer Lee #include "redfish_util.hpp"
313ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
323ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
333ccb3adbSEd Tanous #include "utils/json_utils.hpp"
34472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
353ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
362b82937eSEd Tanous #include "utils/time_utils.hpp"
37c5d03ff4SJennifer Lee 
38fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
399712f8acSEd Tanous #include <boost/container/flat_map.hpp>
40e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
4133e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
42ef4c65b7SEd Tanous #include <boost/url/format.hpp>
431e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
44fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
45bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
461214b7e7SGunnar Mills 
477a1dbc48SGeorge Liu #include <array>
4833e1f122SAndrew Geissler #include <memory>
496b9ac4f2SChris Cain #include <string>
507a1dbc48SGeorge Liu #include <string_view>
5120fa6a2cSEd Tanous #include <utility>
52abf2add6SEd Tanous #include <variant>
536b9ac4f2SChris Cain #include <vector>
54c5b2abe0SLewanczyk, Dawid 
551abe55efSEd Tanous namespace redfish
561abe55efSEd Tanous {
57c5b2abe0SLewanczyk, Dawid 
585c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
595c3e9272SAbhishek Patel     protocolToDBusForSystems{
605c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
615c3e9272SAbhishek Patel 
629d3ae10eSAlpana Kumari /**
639d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
649d3ae10eSAlpana Kumari  *
65ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
669d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
679d3ae10eSAlpana Kumari  *
689d3ae10eSAlpana Kumari  * @return None.
699d3ae10eSAlpana Kumari  */
70bd79bce8SPatrick Williams inline void updateDimmProperties(
71bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
729d3ae10eSAlpana Kumari {
7362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
749d3ae10eSAlpana Kumari 
759d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
769d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
779d3ae10eSAlpana Kumari     // ENABLED.
7802cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
79ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
809d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
819d3ae10eSAlpana Kumari     {
82e05aec50SEd Tanous         if (isDimmFunctional)
839d3ae10eSAlpana Kumari         {
84ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
859d3ae10eSAlpana Kumari                 "Enabled";
869d3ae10eSAlpana Kumari         }
879d3ae10eSAlpana Kumari     }
889d3ae10eSAlpana Kumari }
899d3ae10eSAlpana Kumari 
9057e8c9beSAlpana Kumari /*
9157e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9257e8c9beSAlpana Kumari  *        CPU Functional State
9357e8c9beSAlpana Kumari  *
94ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9557e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9657e8c9beSAlpana Kumari  *
9757e8c9beSAlpana Kumari  * @return None.
9857e8c9beSAlpana Kumari  */
99ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
100ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10157e8c9beSAlpana Kumari {
10262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10357e8c9beSAlpana Kumari 
10402cad96eSEd Tanous     const nlohmann::json& prevProcState =
105ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10657e8c9beSAlpana Kumari 
10757e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10857e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10957e8c9beSAlpana Kumari     // Functional.
11057e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11157e8c9beSAlpana Kumari     {
112e05aec50SEd Tanous         if (isCpuFunctional)
11357e8c9beSAlpana Kumari         {
114ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11557e8c9beSAlpana Kumari                 "Enabled";
11657e8c9beSAlpana Kumari         }
11757e8c9beSAlpana Kumari     }
11857e8c9beSAlpana Kumari }
11957e8c9beSAlpana Kumari 
120cf0e004cSNinad Palsule /*
121cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
122cf0e004cSNinad Palsule  *
123ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
124cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
125cf0e004cSNinad Palsule  *
126cf0e004cSNinad Palsule  * @return None.
127cf0e004cSNinad Palsule  */
128bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
129bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
130cf0e004cSNinad Palsule {
13162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
132cf0e004cSNinad Palsule 
133cf0e004cSNinad Palsule     if (isCpuPresent)
134cf0e004cSNinad Palsule     {
135cf0e004cSNinad Palsule         nlohmann::json& procCount =
136ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
137cf0e004cSNinad Palsule         auto* procCountPtr =
138cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
139cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
140cf0e004cSNinad Palsule         {
141cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
142cf0e004cSNinad Palsule             *procCountPtr += 1;
143cf0e004cSNinad Palsule         }
144cf0e004cSNinad Palsule     }
145cf0e004cSNinad Palsule }
146cf0e004cSNinad Palsule 
147382d6475SAli Ahmed inline void getProcessorProperties(
148ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
149382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150382d6475SAli Ahmed         properties)
15103fbed92SAli Ahmed {
15262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15303fbed92SAli Ahmed 
15403fbed92SAli Ahmed     // TODO: Get Model
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15703fbed92SAli Ahmed 
158bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
159bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16003fbed92SAli Ahmed 
161bc1d29deSKrzysztof Grobelny     if (!success)
16203fbed92SAli Ahmed     {
163ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16403fbed92SAli Ahmed         return;
16503fbed92SAli Ahmed     }
16603fbed92SAli Ahmed 
167bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16803fbed92SAli Ahmed     {
169bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
170ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
171bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
172bc1d29deSKrzysztof Grobelny 
173bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
174bc1d29deSKrzysztof Grobelny         {
175bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17603fbed92SAli Ahmed         }
17703fbed92SAli Ahmed         else
17803fbed92SAli Ahmed         {
179bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18003fbed92SAli Ahmed         }
18103fbed92SAli Ahmed     }
18203fbed92SAli Ahmed }
18303fbed92SAli Ahmed 
18403fbed92SAli Ahmed /*
18503fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18603fbed92SAli Ahmed  *
187ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18803fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18903fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19003fbed92SAli Ahmed  *
19103fbed92SAli Ahmed  * @return None.
19203fbed92SAli Ahmed  */
193ac106bf6SEd Tanous inline void
194ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19603fbed92SAli Ahmed {
197ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
199382d6475SAli Ahmed         if (ec3)
200382d6475SAli Ahmed         {
20162598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
202382d6475SAli Ahmed             return;
203382d6475SAli Ahmed         }
204ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
205382d6475SAli Ahmed     };
206382d6475SAli Ahmed 
207cf0e004cSNinad Palsule     // Get the Presence of CPU
208cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
209cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
210cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
211cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
212cf0e004cSNinad Palsule 
213bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
214bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
215bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
216ac106bf6SEd Tanous         [asyncResp, service,
2175e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
218b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21903fbed92SAli Ahmed             if (ec2)
22003fbed92SAli Ahmed             {
22162598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
222ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22303fbed92SAli Ahmed                 return;
22403fbed92SAli Ahmed             }
225ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
226bc1d29deSKrzysztof Grobelny         });
22703fbed92SAli Ahmed }
22803fbed92SAli Ahmed 
22957e8c9beSAlpana Kumari /*
230cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
231cf0e004cSNinad Palsule  *
232ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
233cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
234cf0e004cSNinad Palsule  *
235cf0e004cSNinad Palsule  * @return None.
236cf0e004cSNinad Palsule  */
237cf0e004cSNinad Palsule inline void
238ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
239cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
240cf0e004cSNinad Palsule {
24162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
242cf0e004cSNinad Palsule 
243cf0e004cSNinad Palsule     if (properties.empty())
244cf0e004cSNinad Palsule     {
245cf0e004cSNinad Palsule         return;
246cf0e004cSNinad Palsule     }
247cf0e004cSNinad Palsule 
248cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
249cf0e004cSNinad Palsule 
250cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
251cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
252cf0e004cSNinad Palsule         memorySizeInKB);
253cf0e004cSNinad Palsule 
254cf0e004cSNinad Palsule     if (!success)
255cf0e004cSNinad Palsule     {
256ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
257cf0e004cSNinad Palsule         return;
258cf0e004cSNinad Palsule     }
259cf0e004cSNinad Palsule 
260cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
261cf0e004cSNinad Palsule     {
262cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
263ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
264dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
265cf0e004cSNinad Palsule         if (preValue == nullptr)
266cf0e004cSNinad Palsule         {
267ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
268dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
269cf0e004cSNinad Palsule         }
270cf0e004cSNinad Palsule         else
271cf0e004cSNinad Palsule         {
272ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
273dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
274dfb2b408SPriyanga Ramasamy                 *preValue;
275cf0e004cSNinad Palsule         }
276cf0e004cSNinad Palsule     }
277cf0e004cSNinad Palsule }
278cf0e004cSNinad Palsule 
279cf0e004cSNinad Palsule /*
280cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
281cf0e004cSNinad Palsule  *
282ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
283cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
284cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
285cf0e004cSNinad Palsule  *
286cf0e004cSNinad Palsule  * @return None.
287cf0e004cSNinad Palsule  */
288ac106bf6SEd Tanous inline void
289ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
291cf0e004cSNinad Palsule {
292cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
293cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
294cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
295ac106bf6SEd Tanous         [asyncResp, service,
296cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
297cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
298cf0e004cSNinad Palsule             if (ec2)
299cf0e004cSNinad Palsule             {
30062598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
301ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
302cf0e004cSNinad Palsule                 return;
303cf0e004cSNinad Palsule             }
30451bd2d8aSGunnar Mills             processMemoryProperties(asyncResp, properties);
305cf0e004cSNinad Palsule         });
306cf0e004cSNinad Palsule }
307cf0e004cSNinad Palsule 
308a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
309a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
310a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3111abe55efSEd Tanous {
312a974c132SLakshmi Yadlapati     if (ec)
313a974c132SLakshmi Yadlapati     {
314a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
315a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
316a974c132SLakshmi Yadlapati         return;
317a974c132SLakshmi Yadlapati     }
318a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
319a974c132SLakshmi Yadlapati 
320a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
321a974c132SLakshmi Yadlapati 
322a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
323a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
324a974c132SLakshmi Yadlapati 
325a974c132SLakshmi Yadlapati     if (!success)
326a974c132SLakshmi Yadlapati     {
327a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
328a974c132SLakshmi Yadlapati         return;
329a974c132SLakshmi Yadlapati     }
330a974c132SLakshmi Yadlapati 
331a974c132SLakshmi Yadlapati     if (uUID != nullptr)
332a974c132SLakshmi Yadlapati     {
333a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
334a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
335a974c132SLakshmi Yadlapati         {
336a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
337a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
338a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
339a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
340a974c132SLakshmi Yadlapati         }
341a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
342a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
343a974c132SLakshmi Yadlapati     }
344a974c132SLakshmi Yadlapati }
345a974c132SLakshmi Yadlapati 
346a974c132SLakshmi Yadlapati inline void
347a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
349a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
350a974c132SLakshmi Yadlapati {
351a974c132SLakshmi Yadlapati     if (ec)
352a974c132SLakshmi Yadlapati     {
353a974c132SLakshmi Yadlapati         // doesn't have to include this
354a974c132SLakshmi Yadlapati         // interface
355a974c132SLakshmi Yadlapati         return;
356a974c132SLakshmi Yadlapati     }
357a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
358a974c132SLakshmi Yadlapati 
359a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
360a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
361a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
362a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
363a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
364a974c132SLakshmi Yadlapati 
365a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
366a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
367a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
368a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
369a974c132SLakshmi Yadlapati 
370a974c132SLakshmi Yadlapati     if (!success)
371a974c132SLakshmi Yadlapati     {
372a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
373a974c132SLakshmi Yadlapati         return;
374a974c132SLakshmi Yadlapati     }
375a974c132SLakshmi Yadlapati 
376a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
377a974c132SLakshmi Yadlapati     {
378a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
379a974c132SLakshmi Yadlapati     }
380a974c132SLakshmi Yadlapati 
381a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
382a974c132SLakshmi Yadlapati     {
383a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
384a974c132SLakshmi Yadlapati     }
385a974c132SLakshmi Yadlapati 
386a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
387a974c132SLakshmi Yadlapati     {
388a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
389a974c132SLakshmi Yadlapati     }
390a974c132SLakshmi Yadlapati 
391a974c132SLakshmi Yadlapati     if (model != nullptr)
392a974c132SLakshmi Yadlapati     {
393a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
394a974c132SLakshmi Yadlapati     }
395a974c132SLakshmi Yadlapati 
396a974c132SLakshmi Yadlapati     if (subModel != nullptr)
397a974c132SLakshmi Yadlapati     {
398a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
399a974c132SLakshmi Yadlapati     }
400a974c132SLakshmi Yadlapati 
401a974c132SLakshmi Yadlapati     // Grab the bios version
402a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
403a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
404a974c132SLakshmi Yadlapati }
405a974c132SLakshmi Yadlapati 
406bd79bce8SPatrick Williams inline void afterGetAssetTag(
407bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
408bd79bce8SPatrick Williams     const boost::system::error_code& ec, const std::string& value)
409a974c132SLakshmi Yadlapati {
410a974c132SLakshmi Yadlapati     if (ec)
411a974c132SLakshmi Yadlapati     {
412a974c132SLakshmi Yadlapati         // doesn't have to include this
413a974c132SLakshmi Yadlapati         // interface
414a974c132SLakshmi Yadlapati         return;
415a974c132SLakshmi Yadlapati     }
416a974c132SLakshmi Yadlapati 
417a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
418a974c132SLakshmi Yadlapati }
419a974c132SLakshmi Yadlapati 
420a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
421a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
422a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
423a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
424a974c132SLakshmi Yadlapati {
4251abe55efSEd Tanous     if (ec)
4261abe55efSEd Tanous     {
427b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
428ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
429c5b2abe0SLewanczyk, Dawid         return;
430c5b2abe0SLewanczyk, Dawid     }
431c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
432002d39b4SEd Tanous     for (const std::pair<
433002d39b4SEd Tanous              std::string,
434002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4351214b7e7SGunnar Mills              object : subtree)
4361abe55efSEd Tanous     {
437c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
43862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
439002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4401214b7e7SGunnar Mills             connectionNames = object.second;
44126f6976fSEd Tanous         if (connectionNames.empty())
4421abe55efSEd Tanous         {
443c5b2abe0SLewanczyk, Dawid             continue;
444c5b2abe0SLewanczyk, Dawid         }
445029573d4SEd Tanous 
4466c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4476c34de48SEd Tanous         // BiosVer
44804a258f4SEd Tanous         for (const auto& connection : connectionNames)
4491abe55efSEd Tanous         {
45004a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4511abe55efSEd Tanous             {
452a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4531abe55efSEd Tanous                 {
45462598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4559d3ae10eSAlpana Kumari 
456ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4575fd0aafbSNinad Palsule                 }
45804a258f4SEd Tanous                 else if (interfaceName ==
45904a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4601abe55efSEd Tanous                 {
46162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
46257e8c9beSAlpana Kumari 
463ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4645fd0aafbSNinad Palsule                 }
465002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4661abe55efSEd Tanous                 {
46762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
468bc1d29deSKrzysztof Grobelny 
469bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
470a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
471a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
472ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
473b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4741214b7e7SGunnar Mills                                         properties) {
475a974c132SLakshmi Yadlapati                             afterGetUUID(asyncResp, ec3, properties);
476bc1d29deSKrzysztof Grobelny                         });
477c5b2abe0SLewanczyk, Dawid                 }
478029573d4SEd Tanous                 else if (interfaceName ==
479029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4801abe55efSEd Tanous                 {
481bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
482a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
483bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
484a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
485b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
486a974c132SLakshmi Yadlapati                                         properties) {
487a974c132SLakshmi Yadlapati                             afterGetInventory(asyncResp, ec3, properties);
488bc1d29deSKrzysztof Grobelny                         });
489e4a4b9a9SJames Feist 
4901e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
491a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
4921e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4931e1e598dSJonathan Doman                         "AssetTag",
4941e1e598dSJonathan Doman                         "AssetTag",
495a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
496a974c132SLakshmi Yadlapati                 }
497a974c132SLakshmi Yadlapati             }
498a974c132SLakshmi Yadlapati         }
499a974c132SLakshmi Yadlapati     }
500a974c132SLakshmi Yadlapati }
501a974c132SLakshmi Yadlapati 
502a974c132SLakshmi Yadlapati /*
503a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
504a974c132SLakshmi Yadlapati  *
505a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
506a974c132SLakshmi Yadlapati  *
507a974c132SLakshmi Yadlapati  * @return None.
508a974c132SLakshmi Yadlapati  */
509a974c132SLakshmi Yadlapati inline void
51051bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
511e4a4b9a9SJames Feist {
512a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
513a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
514a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
515a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
516a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
517a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
518a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
519a974c132SLakshmi Yadlapati     };
520a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
521a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
52251bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
523c5b2abe0SLewanczyk, Dawid }
524c5b2abe0SLewanczyk, Dawid 
525c5b2abe0SLewanczyk, Dawid /**
526c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
527c5b2abe0SLewanczyk, Dawid  *
528ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
529c5b2abe0SLewanczyk, Dawid  *
530c5b2abe0SLewanczyk, Dawid  * @return None.
531c5b2abe0SLewanczyk, Dawid  */
532ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5331abe55efSEd Tanous {
53462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
5351e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5361e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5371e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5381e1e598dSJonathan Doman         "CurrentHostState",
539ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5401e1e598dSJonathan Doman                     const std::string& hostState) {
5411abe55efSEd Tanous             if (ec)
5421abe55efSEd Tanous             {
54322228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
54422228c28SAndrew Geissler                 {
54522228c28SAndrew Geissler                     // Service not available, no error, just don't return
54622228c28SAndrew Geissler                     // host state info
54762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
54822228c28SAndrew Geissler                     return;
54922228c28SAndrew Geissler                 }
55062598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
551ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
552c5b2abe0SLewanczyk, Dawid                 return;
553c5b2abe0SLewanczyk, Dawid             }
5546617338dSEd Tanous 
55562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
556c5b2abe0SLewanczyk, Dawid             // Verify Host State
5571e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5581abe55efSEd Tanous             {
559bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
560bd79bce8SPatrick Williams                     resource::PowerState::On;
561539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
562539d8c6bSEd Tanous                     resource::State::Enabled;
5631abe55efSEd Tanous             }
5641e1e598dSJonathan Doman             else if (hostState ==
5650fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5668c888608SGunnar Mills             {
567bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
568bd79bce8SPatrick Williams                     resource::PowerState::On;
569539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
570539d8c6bSEd Tanous                     resource::State::Quiesced;
5718c888608SGunnar Mills             }
5721e1e598dSJonathan Doman             else if (hostState ==
5730fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57483935af9SAndrew Geissler             {
575bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
576bd79bce8SPatrick Williams                     resource::PowerState::On;
577539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
578539d8c6bSEd Tanous                     resource::State::InTest;
57983935af9SAndrew Geissler             }
5800fda0f12SGeorge Liu             else if (
5811e1e598dSJonathan Doman                 hostState ==
5820fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5831a2a1437SAndrew Geissler             {
584539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
585539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
586539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
587539d8c6bSEd Tanous                     resource::State::Starting;
5881a2a1437SAndrew Geissler             }
589bd79bce8SPatrick Williams             else if (
590bd79bce8SPatrick Williams                 hostState ==
5910fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5921a2a1437SAndrew Geissler             {
593539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
594539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
595539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
596539d8c6bSEd Tanous                     resource::State::Disabled;
5971a2a1437SAndrew Geissler             }
5981abe55efSEd Tanous             else
5991abe55efSEd Tanous             {
600bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
601bd79bce8SPatrick Williams                     resource::PowerState::Off;
602539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
603539d8c6bSEd Tanous                     resource::State::Disabled;
604c5b2abe0SLewanczyk, Dawid             }
6051e1e598dSJonathan Doman         });
606c5b2abe0SLewanczyk, Dawid }
607c5b2abe0SLewanczyk, Dawid 
608c5b2abe0SLewanczyk, Dawid /**
609786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
610491d8ee7SSantosh Puranik  *
611491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
612491d8ee7SSantosh Puranik  *
613491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
614491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
615491d8ee7SSantosh Puranik  */
61623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
617491d8ee7SSantosh Puranik {
618491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
619491d8ee7SSantosh Puranik     {
620491d8ee7SSantosh Puranik         return "None";
621491d8ee7SSantosh Puranik     }
6223174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
623491d8ee7SSantosh Puranik     {
624491d8ee7SSantosh Puranik         return "Hdd";
625491d8ee7SSantosh Puranik     }
6263174e4dfSEd Tanous     if (dbusSource ==
627a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
628491d8ee7SSantosh Puranik     {
629491d8ee7SSantosh Puranik         return "Cd";
630491d8ee7SSantosh Puranik     }
6313174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
632491d8ee7SSantosh Puranik     {
633491d8ee7SSantosh Puranik         return "Pxe";
634491d8ee7SSantosh Puranik     }
6353174e4dfSEd Tanous     if (dbusSource ==
636944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6379f16b2c1SJennifer Lee     {
6389f16b2c1SJennifer Lee         return "Usb";
6399f16b2c1SJennifer Lee     }
640491d8ee7SSantosh Puranik     return "";
641491d8ee7SSantosh Puranik }
642491d8ee7SSantosh Puranik 
643491d8ee7SSantosh Puranik /**
644cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
645cd9a4666SKonstantin Aladyshev  *
646cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
647cd9a4666SKonstantin Aladyshev  *
648cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
649cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
650cd9a4666SKonstantin Aladyshev  */
651cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
652cd9a4666SKonstantin Aladyshev {
653cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
654cd9a4666SKonstantin Aladyshev     {
655cd9a4666SKonstantin Aladyshev         return "Legacy";
656cd9a4666SKonstantin Aladyshev     }
657cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
658cd9a4666SKonstantin Aladyshev     {
659cd9a4666SKonstantin Aladyshev         return "UEFI";
660cd9a4666SKonstantin Aladyshev     }
661cd9a4666SKonstantin Aladyshev     return "";
662cd9a4666SKonstantin Aladyshev }
663cd9a4666SKonstantin Aladyshev 
664cd9a4666SKonstantin Aladyshev /**
665786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
666491d8ee7SSantosh Puranik  *
667491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
668491d8ee7SSantosh Puranik  *
669491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
670491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
671491d8ee7SSantosh Puranik  */
67223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
673491d8ee7SSantosh Puranik {
674491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
675491d8ee7SSantosh Puranik     {
676491d8ee7SSantosh Puranik         return "None";
677491d8ee7SSantosh Puranik     }
6783174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
679491d8ee7SSantosh Puranik     {
680491d8ee7SSantosh Puranik         return "Diags";
681491d8ee7SSantosh Puranik     }
6823174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
683491d8ee7SSantosh Puranik     {
684491d8ee7SSantosh Puranik         return "BiosSetup";
685491d8ee7SSantosh Puranik     }
686491d8ee7SSantosh Puranik     return "";
687491d8ee7SSantosh Puranik }
688491d8ee7SSantosh Puranik 
689491d8ee7SSantosh Puranik /**
690e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
691e43914b3SAndrew Geissler  *
692e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
693e43914b3SAndrew Geissler  *
694e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
695e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
696e43914b3SAndrew Geissler  */
697e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
698e43914b3SAndrew Geissler {
699e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
700e43914b3SAndrew Geissler     // enum
701e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
702e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
703e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
704e43914b3SAndrew Geissler     {
705e43914b3SAndrew Geissler         rfBpLastState = "None";
706e43914b3SAndrew Geissler     }
707e43914b3SAndrew Geissler     else if (dbusBootProgress ==
708e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
709e43914b3SAndrew Geissler              "PrimaryProcInit")
710e43914b3SAndrew Geissler     {
711e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
712e43914b3SAndrew Geissler     }
713e43914b3SAndrew Geissler     else if (dbusBootProgress ==
714e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715e43914b3SAndrew Geissler              "BusInit")
716e43914b3SAndrew Geissler     {
717e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
718e43914b3SAndrew Geissler     }
719e43914b3SAndrew Geissler     else if (dbusBootProgress ==
720e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721e43914b3SAndrew Geissler              "MemoryInit")
722e43914b3SAndrew Geissler     {
723e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
724e43914b3SAndrew Geissler     }
725e43914b3SAndrew Geissler     else if (dbusBootProgress ==
726e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727e43914b3SAndrew Geissler              "SecondaryProcInit")
728e43914b3SAndrew Geissler     {
729e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
730e43914b3SAndrew Geissler     }
731e43914b3SAndrew Geissler     else if (dbusBootProgress ==
732e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733e43914b3SAndrew Geissler              "PCIInit")
734e43914b3SAndrew Geissler     {
735e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
736e43914b3SAndrew Geissler     }
737e43914b3SAndrew Geissler     else if (dbusBootProgress ==
738e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739e43914b3SAndrew Geissler              "SystemSetup")
740e43914b3SAndrew Geissler     {
741e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
742e43914b3SAndrew Geissler     }
743e43914b3SAndrew Geissler     else if (dbusBootProgress ==
744e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745e43914b3SAndrew Geissler              "SystemInitComplete")
746e43914b3SAndrew Geissler     {
747e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
748e43914b3SAndrew Geissler     }
749e43914b3SAndrew Geissler     else if (dbusBootProgress ==
750e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
751e43914b3SAndrew Geissler              "OSStart")
752e43914b3SAndrew Geissler     {
753e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
754e43914b3SAndrew Geissler     }
755e43914b3SAndrew Geissler     else if (dbusBootProgress ==
756e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
757e43914b3SAndrew Geissler              "OSRunning")
758e43914b3SAndrew Geissler     {
759e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
760e43914b3SAndrew Geissler     }
761e43914b3SAndrew Geissler     else
762e43914b3SAndrew Geissler     {
76362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
764e43914b3SAndrew Geissler         // Just return the default
765e43914b3SAndrew Geissler     }
766e43914b3SAndrew Geissler     return rfBpLastState;
767e43914b3SAndrew Geissler }
768e43914b3SAndrew Geissler 
769e43914b3SAndrew Geissler /**
770786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
771491d8ee7SSantosh Puranik  *
772491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
773944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
774944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
775491d8ee7SSantosh Puranik  *
776944ffaf9SJohnathan Mantey  * @return Integer error code.
777491d8ee7SSantosh Puranik  */
778bd79bce8SPatrick Williams inline int assignBootParameters(
779bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
780bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
781491d8ee7SSantosh Puranik {
782c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
783c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
784944ffaf9SJohnathan Mantey 
785491d8ee7SSantosh Puranik     if (rfSource == "None")
786491d8ee7SSantosh Puranik     {
787944ffaf9SJohnathan Mantey         return 0;
788491d8ee7SSantosh Puranik     }
7893174e4dfSEd Tanous     if (rfSource == "Pxe")
790491d8ee7SSantosh Puranik     {
791944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
792944ffaf9SJohnathan Mantey     }
793944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
794944ffaf9SJohnathan Mantey     {
795944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
796944ffaf9SJohnathan Mantey     }
797944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
798944ffaf9SJohnathan Mantey     {
799944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
800944ffaf9SJohnathan Mantey     }
801944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
802944ffaf9SJohnathan Mantey     {
803944ffaf9SJohnathan Mantey         bootSource =
804944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
805944ffaf9SJohnathan Mantey     }
806944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
807944ffaf9SJohnathan Mantey     {
808944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
809491d8ee7SSantosh Puranik     }
8109f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8119f16b2c1SJennifer Lee     {
812944ffaf9SJohnathan Mantey         bootSource =
813944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8149f16b2c1SJennifer Lee     }
815491d8ee7SSantosh Puranik     else
816491d8ee7SSantosh Puranik     {
81762598e31SEd Tanous         BMCWEB_LOG_DEBUG(
81862598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
81962598e31SEd Tanous             bootSource);
820ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
821944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
822944ffaf9SJohnathan Mantey         return -1;
823491d8ee7SSantosh Puranik     }
824944ffaf9SJohnathan Mantey     return 0;
825491d8ee7SSantosh Puranik }
8261981771bSAli Ahmed 
827978b8803SAndrew Geissler /**
828978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
829978b8803SAndrew Geissler  *
830ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
831978b8803SAndrew Geissler  *
832978b8803SAndrew Geissler  * @return None.
833978b8803SAndrew Geissler  */
834ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
835978b8803SAndrew Geissler {
8361e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8371e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8381e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8391e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
840ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8411e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
842978b8803SAndrew Geissler             if (ec)
843978b8803SAndrew Geissler             {
844978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
845978b8803SAndrew Geissler                 // not found
846978b8803SAndrew Geissler                 return;
847978b8803SAndrew Geissler             }
848978b8803SAndrew Geissler 
84962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
850978b8803SAndrew Geissler 
851ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
852e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8531e1e598dSJonathan Doman         });
854978b8803SAndrew Geissler }
855491d8ee7SSantosh Puranik 
856491d8ee7SSantosh Puranik /**
857b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
858b6d5d45cSHieu Huynh  *
859ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
860b6d5d45cSHieu Huynh  *
861b6d5d45cSHieu Huynh  * @return None.
862b6d5d45cSHieu Huynh  */
863b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
864ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
865b6d5d45cSHieu Huynh {
866b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
867b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
868b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
869b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
870ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
871b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
872b6d5d45cSHieu Huynh             if (ec)
873b6d5d45cSHieu Huynh             {
87462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
875b6d5d45cSHieu Huynh                 return;
876b6d5d45cSHieu Huynh             }
877b6d5d45cSHieu Huynh 
878b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
879b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
880b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
881b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
882b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
883b6d5d45cSHieu Huynh 
884b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
885ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
886b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
887b6d5d45cSHieu Huynh         });
888b6d5d45cSHieu Huynh }
889b6d5d45cSHieu Huynh 
890b6d5d45cSHieu Huynh /**
891c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
892cd9a4666SKonstantin Aladyshev  *
893ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
894cd9a4666SKonstantin Aladyshev  *
895cd9a4666SKonstantin Aladyshev  * @return None.
896cd9a4666SKonstantin Aladyshev  */
897cd9a4666SKonstantin Aladyshev 
898ac106bf6SEd Tanous inline void
899ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
900cd9a4666SKonstantin Aladyshev {
9011e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9021e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9031e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9041e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
905ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9061e1e598dSJonathan Doman                     const std::string& bootType) {
907cd9a4666SKonstantin Aladyshev             if (ec)
908cd9a4666SKonstantin Aladyshev             {
909cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
910cd9a4666SKonstantin Aladyshev                 return;
911cd9a4666SKonstantin Aladyshev             }
912cd9a4666SKonstantin Aladyshev 
91362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
914cd9a4666SKonstantin Aladyshev 
915ac106bf6SEd Tanous             asyncResp->res
916ac106bf6SEd Tanous                 .jsonValue["Boot"]
917002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
918613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
919cd9a4666SKonstantin Aladyshev 
9201e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
921cd9a4666SKonstantin Aladyshev             if (rfType.empty())
922cd9a4666SKonstantin Aladyshev             {
923ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
924cd9a4666SKonstantin Aladyshev                 return;
925cd9a4666SKonstantin Aladyshev             }
926cd9a4666SKonstantin Aladyshev 
927ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9281e1e598dSJonathan Doman         });
929cd9a4666SKonstantin Aladyshev }
930cd9a4666SKonstantin Aladyshev 
931cd9a4666SKonstantin Aladyshev /**
932c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
933491d8ee7SSantosh Puranik  *
934ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
935491d8ee7SSantosh Puranik  *
936491d8ee7SSantosh Puranik  * @return None.
937491d8ee7SSantosh Puranik  */
938c21865c4SKonstantin Aladyshev 
939ac106bf6SEd Tanous inline void
940ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
941491d8ee7SSantosh Puranik {
9421e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9431e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9441e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9451e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
946ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9471e1e598dSJonathan Doman                     const std::string& bootModeStr) {
948491d8ee7SSantosh Puranik             if (ec)
949491d8ee7SSantosh Puranik             {
950b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
951ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
952491d8ee7SSantosh Puranik                 return;
953491d8ee7SSantosh Puranik             }
954491d8ee7SSantosh Puranik 
95562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
956491d8ee7SSantosh Puranik 
95720fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
95820fa6a2cSEd Tanous             allowed.emplace_back("None");
95920fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
96020fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
96120fa6a2cSEd Tanous             allowed.emplace_back("Cd");
96220fa6a2cSEd Tanous             allowed.emplace_back("Diags");
96320fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
96420fa6a2cSEd Tanous             allowed.emplace_back("Usb");
96520fa6a2cSEd Tanous 
966ac106bf6SEd Tanous             asyncResp->res
9670fda0f12SGeorge Liu                 .jsonValue["Boot"]
96820fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
96920fa6a2cSEd Tanous                 std::move(allowed);
9701e1e598dSJonathan Doman             if (bootModeStr !=
971491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
972491d8ee7SSantosh Puranik             {
9731e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
974491d8ee7SSantosh Puranik                 if (!rfMode.empty())
975491d8ee7SSantosh Puranik                 {
976bd79bce8SPatrick Williams                     asyncResp->res
977bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
978491d8ee7SSantosh Puranik                 }
979491d8ee7SSantosh Puranik             }
9801e1e598dSJonathan Doman         });
981491d8ee7SSantosh Puranik }
982491d8ee7SSantosh Puranik 
983491d8ee7SSantosh Puranik /**
984c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
985491d8ee7SSantosh Puranik  *
986ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
987491d8ee7SSantosh Puranik  *
988491d8ee7SSantosh Puranik  * @return None.
989491d8ee7SSantosh Puranik  */
990c21865c4SKonstantin Aladyshev 
991c21865c4SKonstantin Aladyshev inline void
992ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
993491d8ee7SSantosh Puranik {
9941e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9951e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9961e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9971e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
998ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9991e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1000491d8ee7SSantosh Puranik             if (ec)
1001491d8ee7SSantosh Puranik             {
10025ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
10035ef735c8SNan Zhou                 {
10045ef735c8SNan Zhou                     return;
10055ef735c8SNan Zhou                 }
1006b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1007ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1008491d8ee7SSantosh Puranik                 return;
1009491d8ee7SSantosh Puranik             }
1010491d8ee7SSantosh Puranik 
101162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1012491d8ee7SSantosh Puranik 
10131e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
1014491d8ee7SSantosh Puranik             if (!rfSource.empty())
1015491d8ee7SSantosh Puranik             {
1016ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1017ac106bf6SEd Tanous                     rfSource;
1018491d8ee7SSantosh Puranik             }
1019cd9a4666SKonstantin Aladyshev 
1020cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1021cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1022ac106bf6SEd Tanous             getBootOverrideMode(asyncResp);
10231e1e598dSJonathan Doman         });
1024491d8ee7SSantosh Puranik }
1025491d8ee7SSantosh Puranik 
1026491d8ee7SSantosh Puranik /**
1027c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1028c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1029c21865c4SKonstantin Aladyshev  * state
1030491d8ee7SSantosh Puranik  *
1031ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1032491d8ee7SSantosh Puranik  *
1033491d8ee7SSantosh Puranik  * @return None.
1034491d8ee7SSantosh Puranik  */
1035491d8ee7SSantosh Puranik 
1036ac106bf6SEd Tanous inline void processBootOverrideEnable(
1037ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1038c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1039c21865c4SKonstantin Aladyshev {
1040c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1041c21865c4SKonstantin Aladyshev     {
1042ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1043ac106bf6SEd Tanous             "Disabled";
1044c21865c4SKonstantin Aladyshev         return;
1045c21865c4SKonstantin Aladyshev     }
1046c21865c4SKonstantin Aladyshev 
1047c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1048c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10491e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10501e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10511e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10521e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1053ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1054491d8ee7SSantosh Puranik             if (ec)
1055491d8ee7SSantosh Puranik             {
1056b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1057ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1058491d8ee7SSantosh Puranik                 return;
1059491d8ee7SSantosh Puranik             }
1060491d8ee7SSantosh Puranik 
1061c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1062c21865c4SKonstantin Aladyshev             {
1063ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1064ac106bf6SEd Tanous                     "Once";
1065c21865c4SKonstantin Aladyshev             }
1066c21865c4SKonstantin Aladyshev             else
1067c21865c4SKonstantin Aladyshev             {
1068ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1069c21865c4SKonstantin Aladyshev                     "Continuous";
1070c21865c4SKonstantin Aladyshev             }
10711e1e598dSJonathan Doman         });
1072491d8ee7SSantosh Puranik }
1073491d8ee7SSantosh Puranik 
1074491d8ee7SSantosh Puranik /**
1075c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1076c21865c4SKonstantin Aladyshev  *
1077ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1078c21865c4SKonstantin Aladyshev  *
1079c21865c4SKonstantin Aladyshev  * @return None.
1080c21865c4SKonstantin Aladyshev  */
1081c21865c4SKonstantin Aladyshev 
1082c21865c4SKonstantin Aladyshev inline void
1083ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1084c21865c4SKonstantin Aladyshev {
10851e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10861e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10871e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10881e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1089ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10901e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1091c21865c4SKonstantin Aladyshev             if (ec)
1092c21865c4SKonstantin Aladyshev             {
10935ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
10945ef735c8SNan Zhou                 {
10955ef735c8SNan Zhou                     return;
10965ef735c8SNan Zhou                 }
1097b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1098ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1099c21865c4SKonstantin Aladyshev                 return;
1100c21865c4SKonstantin Aladyshev             }
1101c21865c4SKonstantin Aladyshev 
1102ac106bf6SEd Tanous             processBootOverrideEnable(asyncResp, bootOverrideEnable);
11031e1e598dSJonathan Doman         });
1104c21865c4SKonstantin Aladyshev }
1105c21865c4SKonstantin Aladyshev 
1106c21865c4SKonstantin Aladyshev /**
1107c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1108c21865c4SKonstantin Aladyshev  *
1109ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1110c21865c4SKonstantin Aladyshev  *
1111c21865c4SKonstantin Aladyshev  * @return None.
1112c21865c4SKonstantin Aladyshev  */
1113ac106bf6SEd Tanous inline void
1114ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1115c21865c4SKonstantin Aladyshev {
111662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1117c21865c4SKonstantin Aladyshev 
1118ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1119ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1120ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1121c21865c4SKonstantin Aladyshev }
1122c21865c4SKonstantin Aladyshev 
1123c21865c4SKonstantin Aladyshev /**
1124c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1125c0557e1aSGunnar Mills  *
1126c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1127c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1128c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1129c0557e1aSGunnar Mills  * last power operation time.
1130c0557e1aSGunnar Mills  *
1131ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1132c0557e1aSGunnar Mills  *
1133c0557e1aSGunnar Mills  * @return None.
1134c0557e1aSGunnar Mills  */
1135ac106bf6SEd Tanous inline void
1136ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1137c0557e1aSGunnar Mills {
113862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1139c0557e1aSGunnar Mills 
11401e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11411e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11421e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11431e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1144ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1145ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1146c0557e1aSGunnar Mills             if (ec)
1147c0557e1aSGunnar Mills             {
114862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1149c0557e1aSGunnar Mills                 return;
1150c0557e1aSGunnar Mills             }
1151c0557e1aSGunnar Mills 
1152c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1153c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11541e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1155c0557e1aSGunnar Mills 
1156c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1157ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11582b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11591e1e598dSJonathan Doman         });
1160c0557e1aSGunnar Mills }
1161c0557e1aSGunnar Mills 
1162c0557e1aSGunnar Mills /**
1163797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1164797d5daeSCorey Hardesty  *
1165797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1166797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1167797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1168797d5daeSCorey Hardesty  * dbus.
1169797d5daeSCorey Hardesty  *
1170ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1171797d5daeSCorey Hardesty  *
1172797d5daeSCorey Hardesty  * @return None.
1173797d5daeSCorey Hardesty  */
1174ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1175ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1176797d5daeSCorey Hardesty {
117762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1178797d5daeSCorey Hardesty 
1179797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1180797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1181797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1182797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1183ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1184ac106bf6SEd Tanous             const boost::system::error_code& ec,
1185797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1186797d5daeSCorey Hardesty             if (ec)
1187797d5daeSCorey Hardesty             {
1188797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1189797d5daeSCorey Hardesty                 {
119062598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1191ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1192797d5daeSCorey Hardesty                 }
1193797d5daeSCorey Hardesty                 return;
1194797d5daeSCorey Hardesty             }
1195797d5daeSCorey Hardesty 
1196797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1197797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1198797d5daeSCorey Hardesty 
1199797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1200bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1201bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1202797d5daeSCorey Hardesty 
1203797d5daeSCorey Hardesty             if (!success)
1204797d5daeSCorey Hardesty             {
1205ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1206797d5daeSCorey Hardesty                 return;
1207797d5daeSCorey Hardesty             }
1208797d5daeSCorey Hardesty 
1209797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1210797d5daeSCorey Hardesty             {
1211ac106bf6SEd Tanous                 asyncResp->res
1212ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1213797d5daeSCorey Hardesty                     *attemptsLeft;
1214797d5daeSCorey Hardesty             }
1215797d5daeSCorey Hardesty 
1216797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1217797d5daeSCorey Hardesty             {
1218ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1219797d5daeSCorey Hardesty                     *retryAttempts;
1220797d5daeSCorey Hardesty             }
1221797d5daeSCorey Hardesty         });
1222797d5daeSCorey Hardesty }
1223797d5daeSCorey Hardesty 
1224797d5daeSCorey Hardesty /**
12256bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12266bd5a8d2SGunnar Mills  *
1227ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12286bd5a8d2SGunnar Mills  *
12296bd5a8d2SGunnar Mills  * @return None.
12306bd5a8d2SGunnar Mills  */
1231797d5daeSCorey Hardesty inline void
1232ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12336bd5a8d2SGunnar Mills {
123462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12356bd5a8d2SGunnar Mills 
12361e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12371e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12381e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12391e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1240ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1241ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12426bd5a8d2SGunnar Mills             if (ec)
12436bd5a8d2SGunnar Mills             {
1244797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1245797d5daeSCorey Hardesty                 {
124662598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1247ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1248797d5daeSCorey Hardesty                 }
12496bd5a8d2SGunnar Mills                 return;
12506bd5a8d2SGunnar Mills             }
12516bd5a8d2SGunnar Mills 
125262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1253e05aec50SEd Tanous             if (autoRebootEnabled)
12546bd5a8d2SGunnar Mills             {
1255ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12566bd5a8d2SGunnar Mills                     "RetryAttempts";
12576bd5a8d2SGunnar Mills             }
12586bd5a8d2SGunnar Mills             else
12596bd5a8d2SGunnar Mills             {
1260ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1261ac106bf6SEd Tanous                     "Disabled";
12626bd5a8d2SGunnar Mills             }
1263ac106bf6SEd Tanous             getAutomaticRebootAttempts(asyncResp);
126469f35306SGunnar Mills 
126569f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
126669f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
126769f35306SGunnar Mills             // RetryAttempts.
126820fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
126920fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
127020fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1271ac106bf6SEd Tanous             asyncResp->res
1272bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1273bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
127420fa6a2cSEd Tanous                 std::move(allowed);
12751e1e598dSJonathan Doman         });
12766bd5a8d2SGunnar Mills }
12776bd5a8d2SGunnar Mills 
12786bd5a8d2SGunnar Mills /**
1279797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1280797d5daeSCorey Hardesty  *
1281ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1282797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1283797d5daeSCorey Hardesty  *
1284797d5daeSCorey Hardesty  *@return None.
1285797d5daeSCorey Hardesty  */
1286797d5daeSCorey Hardesty 
1287ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1288ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1289797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1290797d5daeSCorey Hardesty {
129162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
129287c44966SAsmitha Karunanithi     setDbusProperty(
1293e93abac6SGinu George         asyncResp, "Boot/AutomaticRetryAttempts",
1294e93abac6SGinu George         "xyz.openbmc_project.State.Host",
129587c44966SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
12969ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1297e93abac6SGinu George         retryAttempts);
1298797d5daeSCorey Hardesty }
1299797d5daeSCorey Hardesty 
13008d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13018d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13028d69c668SEd Tanous {
13038d69c668SEd Tanous     if (value ==
13048d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13058d69c668SEd Tanous     {
13068d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13078d69c668SEd Tanous     }
13088d69c668SEd Tanous     if (value ==
13098d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13108d69c668SEd Tanous     {
13118d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13128d69c668SEd Tanous     }
13138d69c668SEd Tanous     if (value ==
13143a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13158d69c668SEd Tanous     {
13168d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13178d69c668SEd Tanous     }
13188d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13198d69c668SEd Tanous     {
13208d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13218d69c668SEd Tanous     }
13228d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13238d69c668SEd Tanous }
1324797d5daeSCorey Hardesty /**
1325c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1326c6a620f2SGeorge Liu  *
1327ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1328c6a620f2SGeorge Liu  *
1329c6a620f2SGeorge Liu  * @return None.
1330c6a620f2SGeorge Liu  */
13318d1b46d7Szhanghch05 inline void
1332ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1333c6a620f2SGeorge Liu {
133462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1335c6a620f2SGeorge Liu 
13361e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13371e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13381e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13391e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1340ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13415e7e2dc5SEd Tanous                     const std::string& policy) {
1342c6a620f2SGeorge Liu             if (ec)
1343c6a620f2SGeorge Liu             {
134462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1345c6a620f2SGeorge Liu                 return;
1346c6a620f2SGeorge Liu             }
13478d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
13488d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
13498d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1350c6a620f2SGeorge Liu             {
1351ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1352c6a620f2SGeorge Liu                 return;
1353c6a620f2SGeorge Liu             }
1354c6a620f2SGeorge Liu 
13558d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13561e1e598dSJonathan Doman         });
1357c6a620f2SGeorge Liu }
1358c6a620f2SGeorge Liu 
1359c6a620f2SGeorge Liu /**
13609dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13619dcfe8c1SAlbert Zhang  *
13629dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13639dcfe8c1SAlbert Zhang  *
13649dcfe8c1SAlbert Zhang  * @return None.
13659dcfe8c1SAlbert Zhang  */
13669dcfe8c1SAlbert Zhang inline void
13679dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13689dcfe8c1SAlbert Zhang {
136962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13709dcfe8c1SAlbert Zhang 
13719dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
13729dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13739dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
13749dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13759dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13769dcfe8c1SAlbert Zhang             if (ec)
13779dcfe8c1SAlbert Zhang             {
13789dcfe8c1SAlbert Zhang                 if (ec.value() != EBADR)
13799dcfe8c1SAlbert Zhang                 {
1380b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13819dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
13829dcfe8c1SAlbert Zhang                 }
13839dcfe8c1SAlbert Zhang                 return;
13849dcfe8c1SAlbert Zhang             }
13859dcfe8c1SAlbert Zhang 
13869dcfe8c1SAlbert Zhang             if (value)
13879dcfe8c1SAlbert Zhang             {
1388539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1389539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
13909dcfe8c1SAlbert Zhang             }
13919dcfe8c1SAlbert Zhang             else
13929dcfe8c1SAlbert Zhang             {
1393539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1394539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
13959dcfe8c1SAlbert Zhang             }
13969dcfe8c1SAlbert Zhang         });
13979dcfe8c1SAlbert Zhang }
13989dcfe8c1SAlbert Zhang 
13999dcfe8c1SAlbert Zhang /**
14001981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14011981771bSAli Ahmed  * TPM is required for booting the host.
14021981771bSAli Ahmed  *
1403ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14041981771bSAli Ahmed  *
14051981771bSAli Ahmed  * @return None.
14061981771bSAli Ahmed  */
14071981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1408ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14091981771bSAli Ahmed {
141062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1411e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1412e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1413e99073f5SGeorge Liu     dbus::utility::getSubTree(
1414e99073f5SGeorge Liu         "/", 0, interfaces,
1415ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1416b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14171981771bSAli Ahmed             if (ec)
14181981771bSAli Ahmed             {
1419bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
1420bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
14211981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
14221981771bSAli Ahmed                 // error occurs
14231981771bSAli Ahmed                 return;
14241981771bSAli Ahmed             }
142526f6976fSEd Tanous             if (subtree.empty())
14261981771bSAli Ahmed             {
14271981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
14281981771bSAli Ahmed                 // if there is no instance found
14291981771bSAli Ahmed                 return;
14301981771bSAli Ahmed             }
14311981771bSAli Ahmed 
14321981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
14331981771bSAli Ahmed             if (subtree.size() > 1)
14341981771bSAli Ahmed             {
143562598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
143662598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
143762598e31SEd Tanous                     subtree.size());
14381981771bSAli Ahmed                 // Throw an internal Error and return
1439ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14401981771bSAli Ahmed                 return;
14411981771bSAli Ahmed             }
14421981771bSAli Ahmed 
14431981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14441981771bSAli Ahmed             // field
14451981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14461981771bSAli Ahmed             {
144762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1448ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14491981771bSAli Ahmed                 return;
14501981771bSAli Ahmed             }
14511981771bSAli Ahmed 
14521981771bSAli Ahmed             const std::string& path = subtree[0].first;
14531981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14541981771bSAli Ahmed 
14551981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
14561e1e598dSJonathan Doman             sdbusplus::asio::getProperty<bool>(
14571e1e598dSJonathan Doman                 *crow::connections::systemBus, serv, path,
14581e1e598dSJonathan Doman                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1459ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2,
1460ac106bf6SEd Tanous                             bool tpmRequired) {
14618a592810SEd Tanous                     if (ec2)
14621981771bSAli Ahmed                     {
1463bd79bce8SPatrick Williams                         BMCWEB_LOG_ERROR(
1464bd79bce8SPatrick Williams                             "D-BUS response error on TPM.Policy Get{}", ec2);
1465ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
14661981771bSAli Ahmed                         return;
14671981771bSAli Ahmed                     }
14681981771bSAli Ahmed 
14691e1e598dSJonathan Doman                     if (tpmRequired)
14701981771bSAli Ahmed                     {
1471ac106bf6SEd Tanous                         asyncResp->res
1472ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14731981771bSAli Ahmed                             "Required";
14741981771bSAli Ahmed                     }
14751981771bSAli Ahmed                     else
14761981771bSAli Ahmed                     {
1477ac106bf6SEd Tanous                         asyncResp->res
1478ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14791981771bSAli Ahmed                             "Disabled";
14801981771bSAli Ahmed                     }
14811e1e598dSJonathan Doman                 });
1482e99073f5SGeorge Liu         });
14831981771bSAli Ahmed }
14841981771bSAli Ahmed 
14851981771bSAli Ahmed /**
14861c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14871c05dae3SAli Ahmed  * TPM is required for booting the host.
14881c05dae3SAli Ahmed  *
1489ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14901c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14911c05dae3SAli Ahmed  *
14921c05dae3SAli Ahmed  * @return None.
14931c05dae3SAli Ahmed  */
14941c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1495ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14961c05dae3SAli Ahmed {
149762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1498e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1499e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1500e99073f5SGeorge Liu     dbus::utility::getSubTree(
1501e99073f5SGeorge Liu         "/", 0, interfaces,
1502ac106bf6SEd Tanous         [asyncResp,
1503e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1504e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15051c05dae3SAli Ahmed             if (ec)
15061c05dae3SAli Ahmed             {
1507bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
1508bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
1509ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15101c05dae3SAli Ahmed                 return;
15111c05dae3SAli Ahmed             }
151226f6976fSEd Tanous             if (subtree.empty())
15131c05dae3SAli Ahmed             {
1514bd79bce8SPatrick Williams                 messages::propertyValueNotInList(asyncResp->res,
1515bd79bce8SPatrick Williams                                                  "ComputerSystem",
15161c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
15171c05dae3SAli Ahmed                 return;
15181c05dae3SAli Ahmed             }
15191c05dae3SAli Ahmed 
15201c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
15211c05dae3SAli Ahmed             if (subtree.size() > 1)
15221c05dae3SAli Ahmed             {
152362598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
152462598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
152562598e31SEd Tanous                     subtree.size());
15261c05dae3SAli Ahmed                 // Throw an internal Error and return
1527ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15281c05dae3SAli Ahmed                 return;
15291c05dae3SAli Ahmed             }
15301c05dae3SAli Ahmed 
15311c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
15321c05dae3SAli Ahmed             // field
15331c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15341c05dae3SAli Ahmed             {
153562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1536ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15371c05dae3SAli Ahmed                 return;
15381c05dae3SAli Ahmed             }
15391c05dae3SAli Ahmed 
15401c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
15411c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
15421c05dae3SAli Ahmed 
15431c05dae3SAli Ahmed             if (serv.empty())
15441c05dae3SAli Ahmed             {
154562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1546ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15471c05dae3SAli Ahmed                 return;
15481c05dae3SAli Ahmed             }
15491c05dae3SAli Ahmed 
15501c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
1551e93abac6SGinu George             setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1552e93abac6SGinu George                             path, "xyz.openbmc_project.Control.TPM.Policy",
1553e93abac6SGinu George                             "TPMEnable", tpmRequired);
1554e99073f5SGeorge Liu         });
15551c05dae3SAli Ahmed }
15561c05dae3SAli Ahmed 
15571c05dae3SAli Ahmed /**
1558491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1559491d8ee7SSantosh Puranik  *
1560ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1561cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1562cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1563cd9a4666SKonstantin Aladyshev  */
1564ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1565cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1566cd9a4666SKonstantin Aladyshev {
1567c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1568cd9a4666SKonstantin Aladyshev 
1569c21865c4SKonstantin Aladyshev     if (!bootType)
1570cd9a4666SKonstantin Aladyshev     {
1571c21865c4SKonstantin Aladyshev         return;
1572c21865c4SKonstantin Aladyshev     }
1573c21865c4SKonstantin Aladyshev 
1574cd9a4666SKonstantin Aladyshev     // Source target specified
157562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1576cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1577cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1578cd9a4666SKonstantin Aladyshev     {
1579cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1580cd9a4666SKonstantin Aladyshev     }
1581cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1582cd9a4666SKonstantin Aladyshev     {
1583cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1584cd9a4666SKonstantin Aladyshev     }
1585cd9a4666SKonstantin Aladyshev     else
1586cd9a4666SKonstantin Aladyshev     {
158762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
158862598e31SEd Tanous                          "BootSourceOverrideMode: {}",
158962598e31SEd Tanous                          *bootType);
1590ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1591cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1592cd9a4666SKonstantin Aladyshev         return;
1593cd9a4666SKonstantin Aladyshev     }
1594cd9a4666SKonstantin Aladyshev 
1595cd9a4666SKonstantin Aladyshev     // Act on validated parameters
159662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1597cd9a4666SKonstantin Aladyshev 
1598e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1599e93abac6SGinu George                     "xyz.openbmc_project.Settings",
160087c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
160187c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
160287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1603e93abac6SGinu George                     bootTypeStr);
1604cd9a4666SKonstantin Aladyshev }
1605cd9a4666SKonstantin Aladyshev 
1606cd9a4666SKonstantin Aladyshev /**
1607cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1608cd9a4666SKonstantin Aladyshev  *
1609ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1610ac106bf6SEd Tanous  * message.
1611c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1612c21865c4SKonstantin Aladyshev  * @return Integer error code.
1613c21865c4SKonstantin Aladyshev  */
1614ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1615c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1616c21865c4SKonstantin Aladyshev {
1617c21865c4SKonstantin Aladyshev     if (!bootEnable)
1618c21865c4SKonstantin Aladyshev     {
1619c21865c4SKonstantin Aladyshev         return;
1620c21865c4SKonstantin Aladyshev     }
1621c21865c4SKonstantin Aladyshev     // Source target specified
162262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1623c21865c4SKonstantin Aladyshev 
1624c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1625c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1626c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1627c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1628c21865c4SKonstantin Aladyshev     {
1629c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1630c21865c4SKonstantin Aladyshev     }
1631c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1632c21865c4SKonstantin Aladyshev     {
1633c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1634c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1635c21865c4SKonstantin Aladyshev     }
1636c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1637c21865c4SKonstantin Aladyshev     {
1638c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1639c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1640c21865c4SKonstantin Aladyshev     }
1641c21865c4SKonstantin Aladyshev     else
1642c21865c4SKonstantin Aladyshev     {
164362598e31SEd Tanous         BMCWEB_LOG_DEBUG(
164462598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
164562598e31SEd Tanous             *bootEnable);
1646ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1647c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1648c21865c4SKonstantin Aladyshev         return;
1649c21865c4SKonstantin Aladyshev     }
1650c21865c4SKonstantin Aladyshev 
1651c21865c4SKonstantin Aladyshev     // Act on validated parameters
165262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1653c21865c4SKonstantin Aladyshev 
1654e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1655e93abac6SGinu George                     "xyz.openbmc_project.Settings",
165687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
165787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
165887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1659e93abac6SGinu George                     bootOverrideEnable);
1660c21865c4SKonstantin Aladyshev 
1661c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1662c21865c4SKonstantin Aladyshev     {
1663c21865c4SKonstantin Aladyshev         return;
1664c21865c4SKonstantin Aladyshev     }
1665c21865c4SKonstantin Aladyshev 
1666c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1667c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
166862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
166962598e31SEd Tanous                      bootOverridePersistent);
1670c21865c4SKonstantin Aladyshev 
1671e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1672e93abac6SGinu George                     "xyz.openbmc_project.Settings",
167387c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
167487c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot/one_time"),
167587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1676e93abac6SGinu George                     !bootOverridePersistent);
1677c21865c4SKonstantin Aladyshev }
1678c21865c4SKonstantin Aladyshev 
1679c21865c4SKonstantin Aladyshev /**
1680c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1681c21865c4SKonstantin Aladyshev  *
1682ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1683491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1684491d8ee7SSantosh Puranik  *
1685265c1602SJohnathan Mantey  * @return Integer error code.
1686491d8ee7SSantosh Puranik  */
1687ac106bf6SEd Tanous inline void
1688ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1689cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1690491d8ee7SSantosh Puranik {
1691c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1692c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1693944ffaf9SJohnathan Mantey 
1694c21865c4SKonstantin Aladyshev     if (!bootSource)
1695491d8ee7SSantosh Puranik     {
1696c21865c4SKonstantin Aladyshev         return;
1697c21865c4SKonstantin Aladyshev     }
1698c21865c4SKonstantin Aladyshev 
1699491d8ee7SSantosh Puranik     // Source target specified
170062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1701491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1702ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1703ac106bf6SEd Tanous                              bootModeStr) != 0)
1704491d8ee7SSantosh Puranik     {
170562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
170662598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
170762598e31SEd Tanous             *bootSource);
1708ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1709491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1710491d8ee7SSantosh Puranik         return;
1711491d8ee7SSantosh Puranik     }
1712491d8ee7SSantosh Puranik 
1713944ffaf9SJohnathan Mantey     // Act on validated parameters
171462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
171562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1716944ffaf9SJohnathan Mantey 
1717e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1718e93abac6SGinu George                     "xyz.openbmc_project.Settings",
171987c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
172087c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
172187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1722e93abac6SGinu George                     bootSourceStr);
1723e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1724e93abac6SGinu George                     "xyz.openbmc_project.Settings",
172587c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
172687c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
172787c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1728e93abac6SGinu George                     bootModeStr);
1729cd9a4666SKonstantin Aladyshev }
1730944ffaf9SJohnathan Mantey 
1731cd9a4666SKonstantin Aladyshev /**
1732c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1733491d8ee7SSantosh Puranik  *
1734ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1735491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1736cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1737491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1738491d8ee7SSantosh Puranik  *
1739265c1602SJohnathan Mantey  * @return Integer error code.
1740491d8ee7SSantosh Puranik  */
1741c21865c4SKonstantin Aladyshev 
1742ac106bf6SEd Tanous inline void
1743ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1744c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1745c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1746c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1747491d8ee7SSantosh Puranik {
174862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1749491d8ee7SSantosh Puranik 
1750ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1751ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1752ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1753491d8ee7SSantosh Puranik }
1754491d8ee7SSantosh Puranik 
1755c6a620f2SGeorge Liu /**
175698e386ecSGunnar Mills  * @brief Sets AssetTag
175798e386ecSGunnar Mills  *
1758ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
175998e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
176098e386ecSGunnar Mills  *
176198e386ecSGunnar Mills  * @return None.
176298e386ecSGunnar Mills  */
1763ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
176498e386ecSGunnar Mills                         const std::string& assetTag)
176598e386ecSGunnar Mills {
1766e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1767e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1768e99073f5SGeorge Liu     dbus::utility::getSubTree(
1769e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1770ac106bf6SEd Tanous         [asyncResp,
1771e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1772b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
177398e386ecSGunnar Mills             if (ec)
177498e386ecSGunnar Mills             {
177562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1776ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
177798e386ecSGunnar Mills                 return;
177898e386ecSGunnar Mills             }
177926f6976fSEd Tanous             if (subtree.empty())
178098e386ecSGunnar Mills             {
178162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1782ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
178398e386ecSGunnar Mills                 return;
178498e386ecSGunnar Mills             }
178598e386ecSGunnar Mills             // Assume only 1 system D-Bus object
178698e386ecSGunnar Mills             // Throw an error if there is more than 1
178798e386ecSGunnar Mills             if (subtree.size() > 1)
178898e386ecSGunnar Mills             {
178962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1790ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
179198e386ecSGunnar Mills                 return;
179298e386ecSGunnar Mills             }
179398e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
179498e386ecSGunnar Mills             {
179562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1796ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
179798e386ecSGunnar Mills                 return;
179898e386ecSGunnar Mills             }
179998e386ecSGunnar Mills 
180098e386ecSGunnar Mills             const std::string& path = subtree[0].first;
180198e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
180298e386ecSGunnar Mills 
180398e386ecSGunnar Mills             if (service.empty())
180498e386ecSGunnar Mills             {
180562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1806ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
180798e386ecSGunnar Mills                 return;
180898e386ecSGunnar Mills             }
180998e386ecSGunnar Mills 
1810e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
181187c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1812e93abac6SGinu George                             "AssetTag", assetTag);
1813e99073f5SGeorge Liu         });
181498e386ecSGunnar Mills }
181598e386ecSGunnar Mills 
181698e386ecSGunnar Mills /**
18179dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18189dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18199dcfe8c1SAlbert Zhang  *
18209dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18219dcfe8c1SAlbert Zhang  * stopBootOnFault
18229dcfe8c1SAlbert Zhang  *
18239dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18249dcfe8c1SAlbert Zhang  */
18259dcfe8c1SAlbert Zhang inline std::optional<bool>
18269dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
18279dcfe8c1SAlbert Zhang {
18289dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18299dcfe8c1SAlbert Zhang     {
18309dcfe8c1SAlbert Zhang         return true;
18319dcfe8c1SAlbert Zhang     }
18329dcfe8c1SAlbert Zhang 
18339dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18349dcfe8c1SAlbert Zhang     {
18359dcfe8c1SAlbert Zhang         return false;
18369dcfe8c1SAlbert Zhang     }
18379dcfe8c1SAlbert Zhang 
18389dcfe8c1SAlbert Zhang     return std::nullopt;
18399dcfe8c1SAlbert Zhang }
18409dcfe8c1SAlbert Zhang 
18419dcfe8c1SAlbert Zhang /**
18429dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18439dcfe8c1SAlbert Zhang  *
1844fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18459dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18469dcfe8c1SAlbert Zhang  *
18479dcfe8c1SAlbert Zhang  * @return None.
18489dcfe8c1SAlbert Zhang  */
1849fc3edfddSEd Tanous inline void
1850fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18519dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18529dcfe8c1SAlbert Zhang {
185362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18549dcfe8c1SAlbert Zhang 
18559dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18569dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18579dcfe8c1SAlbert Zhang     {
185862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
185962598e31SEd Tanous                          stopBootOnFault);
1860fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18619dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18629dcfe8c1SAlbert Zhang         return;
18639dcfe8c1SAlbert Zhang     }
18649dcfe8c1SAlbert Zhang 
1865e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1866e93abac6SGinu George                     "xyz.openbmc_project.Settings",
186787c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
186887c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1869fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1870e93abac6SGinu George                     *stopBootEnabled);
18719dcfe8c1SAlbert Zhang }
18729dcfe8c1SAlbert Zhang 
18739dcfe8c1SAlbert Zhang /**
187469f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
187569f35306SGunnar Mills  *
1876ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
187769f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
187869f35306SGunnar Mills  *
187969f35306SGunnar Mills  * @return None.
188069f35306SGunnar Mills  */
1881ac106bf6SEd Tanous inline void
1882ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1883f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
188469f35306SGunnar Mills {
188562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
188669f35306SGunnar Mills 
188769f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1888543f4400SEd Tanous     bool autoRebootEnabled = false;
188969f35306SGunnar Mills 
189069f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
189169f35306SGunnar Mills     {
189269f35306SGunnar Mills         autoRebootEnabled = false;
189369f35306SGunnar Mills     }
189469f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
189569f35306SGunnar Mills     {
189669f35306SGunnar Mills         autoRebootEnabled = true;
189769f35306SGunnar Mills     }
189869f35306SGunnar Mills     else
189969f35306SGunnar Mills     {
190062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
190162598e31SEd Tanous                          automaticRetryConfig);
1902ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
190369f35306SGunnar Mills                                          "AutomaticRetryConfig");
190469f35306SGunnar Mills         return;
190569f35306SGunnar Mills     }
190669f35306SGunnar Mills 
1907e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1908e93abac6SGinu George                     "xyz.openbmc_project.Settings",
190987c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
191087c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/auto_reboot"),
191187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1912e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
191369f35306SGunnar Mills }
191469f35306SGunnar Mills 
19158d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19168d69c668SEd Tanous {
19178d69c668SEd Tanous     if (policy == "AlwaysOn")
19188d69c668SEd Tanous     {
19198d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19208d69c668SEd Tanous     }
19218d69c668SEd Tanous     if (policy == "AlwaysOff")
19228d69c668SEd Tanous     {
19238d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19248d69c668SEd Tanous     }
19258d69c668SEd Tanous     if (policy == "LastState")
19268d69c668SEd Tanous     {
19278d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19288d69c668SEd Tanous     }
19298d69c668SEd Tanous     return "";
19308d69c668SEd Tanous }
19318d69c668SEd Tanous 
193269f35306SGunnar Mills /**
1933c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1934c6a620f2SGeorge Liu  *
1935ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1936c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1937c6a620f2SGeorge Liu  *
1938c6a620f2SGeorge Liu  * @return None.
1939c6a620f2SGeorge Liu  */
19408d1b46d7Szhanghch05 inline void
1941ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19428d69c668SEd Tanous                           std::string_view policy)
1943c6a620f2SGeorge Liu {
194462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1945c6a620f2SGeorge Liu 
19468d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1947c6a620f2SGeorge Liu 
19488d69c668SEd Tanous     if (powerRestorePolicy.empty())
1949c6a620f2SGeorge Liu     {
1950ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19514e69c904SGunnar Mills                                          "PowerRestorePolicy");
1952c6a620f2SGeorge Liu         return;
1953c6a620f2SGeorge Liu     }
1954c6a620f2SGeorge Liu 
195587c44966SAsmitha Karunanithi     setDbusProperty(
1956e93abac6SGinu George         asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
195787c44966SAsmitha Karunanithi         sdbusplus::message::object_path(
195887c44966SAsmitha Karunanithi             "/xyz/openbmc_project/control/host0/power_restore_policy"),
19599ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1960e93abac6SGinu George         powerRestorePolicy);
1961c6a620f2SGeorge Liu }
1962c6a620f2SGeorge Liu 
1963a6349918SAppaRao Puli /**
1964a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1965a6349918SAppaRao Puli  *
196625b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
196725b54dbaSEd Tanous  * calls.
1968a6349918SAppaRao Puli  *
1969a6349918SAppaRao Puli  * @return None.
1970a6349918SAppaRao Puli  */
197125b54dbaSEd Tanous inline void
197225b54dbaSEd Tanous     getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1973a6349918SAppaRao Puli {
197462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1975bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1976bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1977bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1978ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1979b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1980b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1981bd79bce8SPatrick Williams                 asyncResp->res
1982bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1983ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
19841d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1985bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
1986bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
198750626f4fSJames Feist 
1988a6349918SAppaRao Puli             if (ec)
1989a6349918SAppaRao Puli             {
199062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1991b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1992539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
1993539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
1994a6349918SAppaRao Puli                 return;
1995a6349918SAppaRao Puli             }
1996a6349918SAppaRao Puli 
1997a6349918SAppaRao Puli             const bool* provState = nullptr;
1998a6349918SAppaRao Puli             const bool* lockState = nullptr;
1999bc1d29deSKrzysztof Grobelny 
2000bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2001bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
2002bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
2003bc1d29deSKrzysztof Grobelny 
2004bc1d29deSKrzysztof Grobelny             if (!success)
2005a6349918SAppaRao Puli             {
2006ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2007bc1d29deSKrzysztof Grobelny                 return;
2008a6349918SAppaRao Puli             }
2009a6349918SAppaRao Puli 
2010a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2011a6349918SAppaRao Puli             {
201262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2013ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2014a6349918SAppaRao Puli                 return;
2015a6349918SAppaRao Puli             }
2016a6349918SAppaRao Puli 
201725b54dbaSEd Tanous             if (*provState)
2018a6349918SAppaRao Puli             {
201925b54dbaSEd Tanous                 if (*lockState)
2020a6349918SAppaRao Puli                 {
2021539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2022539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2023a6349918SAppaRao Puli                 }
2024a6349918SAppaRao Puli                 else
2025a6349918SAppaRao Puli                 {
2026539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2027539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2028a6349918SAppaRao Puli                 }
2029a6349918SAppaRao Puli             }
2030a6349918SAppaRao Puli             else
2031a6349918SAppaRao Puli             {
2032539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2033539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2034a6349918SAppaRao Puli             }
2035bc1d29deSKrzysztof Grobelny         });
2036a6349918SAppaRao Puli }
2037a6349918SAppaRao Puli 
2038491d8ee7SSantosh Puranik /**
20396b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20403a2d0424SChris Cain  *
20416b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20423a2d0424SChris Cain  *
20436b9ac4f2SChris Cain  * @return PowerMode enum
20443a2d0424SChris Cain  */
20456b9ac4f2SChris Cain inline computer_system::PowerMode
20466b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
20473a2d0424SChris Cain {
2048b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2049b6655101SChris Cain 
20506b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20513a2d0424SChris Cain     {
20526b9ac4f2SChris Cain         return PowerMode::Static;
20533a2d0424SChris Cain     }
20546b9ac4f2SChris Cain     if (modeString ==
20550fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20563a2d0424SChris Cain     {
20576b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20583a2d0424SChris Cain     }
20596b9ac4f2SChris Cain     if (modeString ==
20600fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20613a2d0424SChris Cain     {
20626b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2063b6655101SChris Cain     }
20646b9ac4f2SChris Cain     if (modeString ==
2065b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2066b6655101SChris Cain     {
20676b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2068b6655101SChris Cain     }
20696b9ac4f2SChris Cain     if (modeString ==
2070b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2071b6655101SChris Cain     {
20726b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2073b6655101SChris Cain     }
20746b9ac4f2SChris Cain     if (modeString ==
2075b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2076b6655101SChris Cain     {
20776b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20783a2d0424SChris Cain     }
20796b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20803a2d0424SChris Cain     {
20816b9ac4f2SChris Cain         return PowerMode::OEM;
20826b9ac4f2SChris Cain     }
20836b9ac4f2SChris Cain     // Any other values would be invalid
20846b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20856b9ac4f2SChris Cain     return PowerMode::Invalid;
20866b9ac4f2SChris Cain }
20876b9ac4f2SChris Cain 
20886b9ac4f2SChris Cain inline void
20896b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20906b9ac4f2SChris Cain                       const boost::system::error_code& ec,
20916b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
20926b9ac4f2SChris Cain {
20936b9ac4f2SChris Cain     if (ec)
20946b9ac4f2SChris Cain     {
20956b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
20966b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20976b9ac4f2SChris Cain         return;
20986b9ac4f2SChris Cain     }
20996b9ac4f2SChris Cain 
21006b9ac4f2SChris Cain     std::string powerMode;
21016b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
21026b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
21036b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
21046b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21056b9ac4f2SChris Cain 
21066b9ac4f2SChris Cain     if (!success)
21076b9ac4f2SChris Cain     {
21086b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21096b9ac4f2SChris Cain         return;
21106b9ac4f2SChris Cain     }
21116b9ac4f2SChris Cain 
21126b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21136b9ac4f2SChris Cain     if (allowedModes == nullptr)
21146b9ac4f2SChris Cain     {
21156b9ac4f2SChris Cain         modeList.emplace_back("Static");
21166b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21176b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21183a2d0424SChris Cain     }
21193a2d0424SChris Cain     else
21203a2d0424SChris Cain     {
21216b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21226b9ac4f2SChris Cain         {
21236b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21246b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21256b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21266b9ac4f2SChris Cain             {
2127ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21286b9ac4f2SChris Cain                 continue;
21296b9ac4f2SChris Cain             }
21306b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21313a2d0424SChris Cain         }
21323a2d0424SChris Cain     }
21336b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21343a2d0424SChris Cain 
21356b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21366b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21376b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21386b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21396b9ac4f2SChris Cain     {
21406b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21416b9ac4f2SChris Cain         return;
21426b9ac4f2SChris Cain     }
21436b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21446b9ac4f2SChris Cain }
21453a2d0424SChris Cain /**
21463a2d0424SChris Cain  * @brief Retrieves system power mode
21473a2d0424SChris Cain  *
2148ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21493a2d0424SChris Cain  *
21503a2d0424SChris Cain  * @return None.
21513a2d0424SChris Cain  */
2152ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21533a2d0424SChris Cain {
215462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21553a2d0424SChris Cain 
21563a2d0424SChris Cain     // Get Power Mode object path:
2157e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2158e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2159e99073f5SGeorge Liu     dbus::utility::getSubTree(
2160e99073f5SGeorge Liu         "/", 0, interfaces,
2161ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2162b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21633a2d0424SChris Cain             if (ec)
21643a2d0424SChris Cain             {
2165bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2166bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
21673a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
21683a2d0424SChris Cain                 // error occurs
21693a2d0424SChris Cain                 return;
21703a2d0424SChris Cain             }
21713a2d0424SChris Cain             if (subtree.empty())
21723a2d0424SChris Cain             {
21733a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
21743a2d0424SChris Cain                 // if there is no instance found
21753a2d0424SChris Cain                 return;
21763a2d0424SChris Cain             }
21773a2d0424SChris Cain             if (subtree.size() > 1)
21783a2d0424SChris Cain             {
21793a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21803a2d0424SChris Cain                 // error
218162598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
218262598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
218362598e31SEd Tanous                     subtree.size());
2184ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21853a2d0424SChris Cain                 return;
21863a2d0424SChris Cain             }
21873a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21883a2d0424SChris Cain             {
218962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2190ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21913a2d0424SChris Cain                 return;
21923a2d0424SChris Cain             }
21933a2d0424SChris Cain             const std::string& path = subtree[0].first;
21943a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21953a2d0424SChris Cain             if (service.empty())
21963a2d0424SChris Cain             {
219762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2198ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21993a2d0424SChris Cain                 return;
22003a2d0424SChris Cain             }
22016b9ac4f2SChris Cain 
22026b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
22036b9ac4f2SChris Cain             sdbusplus::asio::getAllProperties(
22041e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
22056b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2206bd79bce8SPatrick Williams                 [asyncResp](
2207bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
22086b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
22096b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
22101e1e598dSJonathan Doman                 });
2211e99073f5SGeorge Liu         });
22123a2d0424SChris Cain }
22133a2d0424SChris Cain 
22143a2d0424SChris Cain /**
22153a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22163a2d0424SChris Cain  * name associated with that string
22173a2d0424SChris Cain  *
2218ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2219b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22203a2d0424SChris Cain  *
22213a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22223a2d0424SChris Cain  */
22233a2d0424SChris Cain inline std::string
2224ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2225b6655101SChris Cain                       const nlohmann::json& modeValue)
22263a2d0424SChris Cain {
2227b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22283a2d0424SChris Cain     std::string mode;
22293a2d0424SChris Cain 
2230b6655101SChris Cain     if (modeValue == PowerMode::Static)
22313a2d0424SChris Cain     {
22323a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22333a2d0424SChris Cain     }
2234b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22353a2d0424SChris Cain     {
22360fda0f12SGeorge Liu         mode =
22370fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22383a2d0424SChris Cain     }
2239b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22403a2d0424SChris Cain     {
22413a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22423a2d0424SChris Cain     }
2243b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2244b6655101SChris Cain     {
2245b6655101SChris Cain         mode =
2246b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2247b6655101SChris Cain     }
2248b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2249b6655101SChris Cain     {
2250b6655101SChris Cain         mode =
2251b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2252b6655101SChris Cain     }
2253b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2254b6655101SChris Cain     {
2255b6655101SChris Cain         mode =
2256b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2257b6655101SChris Cain     }
22583a2d0424SChris Cain     else
22593a2d0424SChris Cain     {
2260b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2261ac106bf6SEd Tanous                                          "PowerMode");
22623a2d0424SChris Cain     }
22633a2d0424SChris Cain     return mode;
22643a2d0424SChris Cain }
22653a2d0424SChris Cain 
22663a2d0424SChris Cain /**
22673a2d0424SChris Cain  * @brief Sets system power mode.
22683a2d0424SChris Cain  *
2269ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22703a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22713a2d0424SChris Cain  *
22723a2d0424SChris Cain  * @return None.
22733a2d0424SChris Cain  */
2274ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22753a2d0424SChris Cain                          const std::string& pmode)
22763a2d0424SChris Cain {
227762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22783a2d0424SChris Cain 
2279ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22803a2d0424SChris Cain     if (powerMode.empty())
22813a2d0424SChris Cain     {
22823a2d0424SChris Cain         return;
22833a2d0424SChris Cain     }
22843a2d0424SChris Cain 
22853a2d0424SChris Cain     // Get Power Mode object path:
2286e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2287e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2288e99073f5SGeorge Liu     dbus::utility::getSubTree(
2289e99073f5SGeorge Liu         "/", 0, interfaces,
2290ac106bf6SEd Tanous         [asyncResp,
2291e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2292b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22933a2d0424SChris Cain             if (ec)
22943a2d0424SChris Cain             {
2295bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2296bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
22973a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2298ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22993a2d0424SChris Cain                 return;
23003a2d0424SChris Cain             }
23013a2d0424SChris Cain             if (subtree.empty())
23023a2d0424SChris Cain             {
23033a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2304ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23053a2d0424SChris Cain                                            "PowerMode");
23063a2d0424SChris Cain                 return;
23073a2d0424SChris Cain             }
23083a2d0424SChris Cain             if (subtree.size() > 1)
23093a2d0424SChris Cain             {
23103a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
23113a2d0424SChris Cain                 // error
231262598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
231362598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
231462598e31SEd Tanous                     subtree.size());
2315ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23163a2d0424SChris Cain                 return;
23173a2d0424SChris Cain             }
23183a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23193a2d0424SChris Cain             {
232062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2321ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23223a2d0424SChris Cain                 return;
23233a2d0424SChris Cain             }
23243a2d0424SChris Cain             const std::string& path = subtree[0].first;
23253a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
23263a2d0424SChris Cain             if (service.empty())
23273a2d0424SChris Cain             {
232862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2329ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23303a2d0424SChris Cain                 return;
23313a2d0424SChris Cain             }
23323a2d0424SChris Cain 
233362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23343a2d0424SChris Cain 
23353a2d0424SChris Cain             // Set the Power Mode property
2336e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2337bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2338bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2339e99073f5SGeorge Liu         });
23403a2d0424SChris Cain }
23413a2d0424SChris Cain 
23423a2d0424SChris Cain /**
234351709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
234451709ffdSYong Li  *
234551709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
234651709ffdSYong Li  *
234751709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
234851709ffdSYong Li  * translation cannot be done, returns an empty string.
234951709ffdSYong Li  */
235023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
235151709ffdSYong Li {
235251709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
235351709ffdSYong Li     {
235451709ffdSYong Li         return "None";
235551709ffdSYong Li     }
23563174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
235751709ffdSYong Li     {
235851709ffdSYong Li         return "ResetSystem";
235951709ffdSYong Li     }
23603174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
236151709ffdSYong Li     {
236251709ffdSYong Li         return "PowerDown";
236351709ffdSYong Li     }
23643174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
236551709ffdSYong Li     {
236651709ffdSYong Li         return "PowerCycle";
236751709ffdSYong Li     }
236851709ffdSYong Li 
236951709ffdSYong Li     return "";
237051709ffdSYong Li }
237151709ffdSYong Li 
237251709ffdSYong Li /**
2373c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2374c45f0082SYong Li  *
2375c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2376c45f0082SYong Li  *
2377c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2378c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2379c45f0082SYong Li  */
2380c45f0082SYong Li 
238123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2382c45f0082SYong Li {
2383c45f0082SYong Li     if (rfAction == "None")
2384c45f0082SYong Li     {
2385c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2386c45f0082SYong Li     }
23873174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2388c45f0082SYong Li     {
2389c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2390c45f0082SYong Li     }
23913174e4dfSEd Tanous     if (rfAction == "PowerDown")
2392c45f0082SYong Li     {
2393c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2394c45f0082SYong Li     }
23953174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2396c45f0082SYong Li     {
2397c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2398c45f0082SYong Li     }
2399c45f0082SYong Li 
2400c45f0082SYong Li     return "";
2401c45f0082SYong Li }
2402c45f0082SYong Li 
2403c45f0082SYong Li /**
240451709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
240551709ffdSYong Li  *
2406ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
240751709ffdSYong Li  *
240851709ffdSYong Li  * @return None.
240951709ffdSYong Li  */
24108d1b46d7Szhanghch05 inline void
2411ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
241251709ffdSYong Li {
241362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2414bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2415bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2416bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2417bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2418ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2419b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
242051709ffdSYong Li             if (ec)
242151709ffdSYong Li             {
242251709ffdSYong Li                 // watchdog service is stopped
242362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
242451709ffdSYong Li                 return;
242551709ffdSYong Li             }
242651709ffdSYong Li 
242762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
242851709ffdSYong Li 
242951709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2430ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
243151709ffdSYong Li 
243251709ffdSYong Li             // watchdog service is running/enabled
2433539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
243451709ffdSYong Li 
2435bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2436bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
243751709ffdSYong Li 
2438bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2439bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2440bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2441bc1d29deSKrzysztof Grobelny 
2442bc1d29deSKrzysztof Grobelny             if (!success)
244351709ffdSYong Li             {
2444ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2445601af5edSChicago Duan                 return;
244651709ffdSYong Li             }
244751709ffdSYong Li 
2448bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
244951709ffdSYong Li             {
2450bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
245151709ffdSYong Li             }
245251709ffdSYong Li 
2453bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2454bc1d29deSKrzysztof Grobelny             {
2455bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
245651709ffdSYong Li                 if (action.empty())
245751709ffdSYong Li                 {
2458ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2459601af5edSChicago Duan                     return;
246051709ffdSYong Li                 }
246151709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
246251709ffdSYong Li             }
2463bc1d29deSKrzysztof Grobelny         });
246451709ffdSYong Li }
246551709ffdSYong Li 
246651709ffdSYong Li /**
2467c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2468c45f0082SYong Li  *
2469ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2470c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2471c45f0082SYong Li  *                       RF request.
2472c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2473c45f0082SYong Li  *
2474c45f0082SYong Li  * @return None.
2475c45f0082SYong Li  */
2476ac106bf6SEd Tanous inline void
2477ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2478c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2479c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2480c45f0082SYong Li {
248162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2482c45f0082SYong Li 
2483c45f0082SYong Li     if (wdtTimeOutAction)
2484c45f0082SYong Li     {
2485c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2486c45f0082SYong Li         // check if TimeOut Action is Valid
2487c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2488c45f0082SYong Li         {
248962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
249062598e31SEd Tanous                              *wdtTimeOutAction);
2491ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2492c45f0082SYong Li                                              "TimeoutAction");
2493c45f0082SYong Li             return;
2494c45f0082SYong Li         }
2495c45f0082SYong Li 
2496e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2497e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
249887c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
249987c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
25009ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2501e93abac6SGinu George                         wdtTimeOutActStr);
2502c45f0082SYong Li     }
2503c45f0082SYong Li 
2504c45f0082SYong Li     if (wdtEnable)
2505c45f0082SYong Li     {
2506e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2507e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
250887c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
250987c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
251087c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2511e93abac6SGinu George                         *wdtEnable);
2512c45f0082SYong Li     }
2513c45f0082SYong Li }
2514c45f0082SYong Li 
251537bbf98cSChris Cain /**
251637bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
251737bbf98cSChris Cain  *
2518ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
251937bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
252037bbf98cSChris Cain  *
252137bbf98cSChris Cain  * @return true if successful
252237bbf98cSChris Cain  */
25231e5b7c88SJiaqing Zhao inline bool
2524ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25251e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
252637bbf98cSChris Cain {
2527bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2528bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2529bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2530bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2531bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2532bc1d29deSKrzysztof Grobelny 
2533bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2534bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25352661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25362661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25372661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2538bc1d29deSKrzysztof Grobelny 
2539bc1d29deSKrzysztof Grobelny     if (!success)
254037bbf98cSChris Cain     {
254137bbf98cSChris Cain         return false;
254237bbf98cSChris Cain     }
2543bc1d29deSKrzysztof Grobelny 
2544bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
254537bbf98cSChris Cain     {
2546ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
254737bbf98cSChris Cain     }
2548bc1d29deSKrzysztof Grobelny 
2549bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
255037bbf98cSChris Cain     {
2551ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2552bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
255337bbf98cSChris Cain     }
2554bc1d29deSKrzysztof Grobelny 
2555bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2556bc1d29deSKrzysztof Grobelny     {
2557bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2558ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
255937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
256037bbf98cSChris Cain                 .count();
256137bbf98cSChris Cain     }
2562bc1d29deSKrzysztof Grobelny 
2563bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
256437bbf98cSChris Cain     {
2565ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2566bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
256737bbf98cSChris Cain     }
2568bc1d29deSKrzysztof Grobelny 
2569bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
257037bbf98cSChris Cain     {
2571bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2572ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
257337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
257437bbf98cSChris Cain                 .count();
257537bbf98cSChris Cain     }
257637bbf98cSChris Cain 
257737bbf98cSChris Cain     return true;
257837bbf98cSChris Cain }
257937bbf98cSChris Cain 
258037bbf98cSChris Cain /**
258137bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
258237bbf98cSChris Cain  *
2583ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
258437bbf98cSChris Cain  *
258537bbf98cSChris Cain  * @return None.
258637bbf98cSChris Cain  */
2587ac106bf6SEd Tanous inline void
2588ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
258937bbf98cSChris Cain {
259062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
259137bbf98cSChris Cain 
259237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2593e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2594e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2595e99073f5SGeorge Liu     dbus::utility::getSubTree(
2596e99073f5SGeorge Liu         "/", 0, interfaces,
2597ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2598b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
259937bbf98cSChris Cain             if (ec)
260037bbf98cSChris Cain             {
2601b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
260262598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
260362598e31SEd Tanous                     ec);
2604ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
260537bbf98cSChris Cain                 return;
260637bbf98cSChris Cain             }
260737bbf98cSChris Cain             if (subtree.empty())
260837bbf98cSChris Cain             {
260937bbf98cSChris Cain                 // This is an optional interface so just return
261037bbf98cSChris Cain                 // if there is no instance found
261162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
261237bbf98cSChris Cain                 return;
261337bbf98cSChris Cain             }
261437bbf98cSChris Cain             if (subtree.size() > 1)
261537bbf98cSChris Cain             {
261637bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
261737bbf98cSChris Cain                 // is an error
261862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
261962598e31SEd Tanous                                  "Power.IdlePowerSaver objects: {}",
262062598e31SEd Tanous                                  subtree.size());
2621ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
262237bbf98cSChris Cain                 return;
262337bbf98cSChris Cain             }
262437bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
262537bbf98cSChris Cain             {
262662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2627ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
262837bbf98cSChris Cain                 return;
262937bbf98cSChris Cain             }
263037bbf98cSChris Cain             const std::string& path = subtree[0].first;
263137bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
263237bbf98cSChris Cain             if (service.empty())
263337bbf98cSChris Cain             {
263462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2635ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
263637bbf98cSChris Cain                 return;
263737bbf98cSChris Cain             }
263837bbf98cSChris Cain 
263937bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2640bc1d29deSKrzysztof Grobelny             sdbusplus::asio::getAllProperties(
2641bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2642bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2643bd79bce8SPatrick Williams                 [asyncResp](
2644bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
26451e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
26468a592810SEd Tanous                     if (ec2)
264737bbf98cSChris Cain                     {
264862598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2649bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2650bd79bce8SPatrick Williams                             ec2);
2651ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
265237bbf98cSChris Cain                         return;
265337bbf98cSChris Cain                     }
265437bbf98cSChris Cain 
2655ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
265637bbf98cSChris Cain                     {
2657ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
265837bbf98cSChris Cain                         return;
265937bbf98cSChris Cain                     }
2660bc1d29deSKrzysztof Grobelny                 });
2661e99073f5SGeorge Liu         });
266237bbf98cSChris Cain 
266362598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
266437bbf98cSChris Cain }
266537bbf98cSChris Cain 
266637bbf98cSChris Cain /**
266737bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
266837bbf98cSChris Cain  *
2669ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
267037bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
267137bbf98cSChris Cain  *                       RF request.
267237bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
267337bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
267437bbf98cSChris Cain  * before entering idle state.
267537bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
267637bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
267737bbf98cSChris Cain  * before exiting idle state
267837bbf98cSChris Cain  *
267937bbf98cSChris Cain  * @return None.
268037bbf98cSChris Cain  */
2681bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2682bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
268337bbf98cSChris Cain     const std::optional<bool> ipsEnable,
268437bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
268537bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
268637bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
268737bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
268837bbf98cSChris Cain {
268962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
269037bbf98cSChris Cain 
269137bbf98cSChris Cain     // Get IdlePowerSaver object path:
2692e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2693e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2694e99073f5SGeorge Liu     dbus::utility::getSubTree(
2695e99073f5SGeorge Liu         "/", 0, interfaces,
2696ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2697e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2698b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
269937bbf98cSChris Cain             if (ec)
270037bbf98cSChris Cain             {
2701b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
270262598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
270362598e31SEd Tanous                     ec);
2704ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
270537bbf98cSChris Cain                 return;
270637bbf98cSChris Cain             }
270737bbf98cSChris Cain             if (subtree.empty())
270837bbf98cSChris Cain             {
270937bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2710ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
271137bbf98cSChris Cain                                            "IdlePowerSaver");
271237bbf98cSChris Cain                 return;
271337bbf98cSChris Cain             }
271437bbf98cSChris Cain             if (subtree.size() > 1)
271537bbf98cSChris Cain             {
271637bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
271737bbf98cSChris Cain                 // is an error
271862598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
271962598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
272062598e31SEd Tanous                     subtree.size());
2721ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272237bbf98cSChris Cain                 return;
272337bbf98cSChris Cain             }
272437bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
272537bbf98cSChris Cain             {
272662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2727ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272837bbf98cSChris Cain                 return;
272937bbf98cSChris Cain             }
273037bbf98cSChris Cain             const std::string& path = subtree[0].first;
273137bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
273237bbf98cSChris Cain             if (service.empty())
273337bbf98cSChris Cain             {
273462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2735ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273637bbf98cSChris Cain                 return;
273737bbf98cSChris Cain             }
273837bbf98cSChris Cain 
273937bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
274037bbf98cSChris Cain             // need to be updated
274137bbf98cSChris Cain 
274237bbf98cSChris Cain             if (ipsEnable)
274337bbf98cSChris Cain             {
2744bd79bce8SPatrick Williams                 setDbusProperty(
2745bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
274687c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2747e93abac6SGinu George                     "Enabled", *ipsEnable);
274837bbf98cSChris Cain             }
274937bbf98cSChris Cain             if (ipsEnterUtil)
275037bbf98cSChris Cain             {
2751bd79bce8SPatrick Williams                 setDbusProperty(
2752bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2753e93abac6SGinu George                     service, path,
27549ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2755e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
275637bbf98cSChris Cain             }
275737bbf98cSChris Cain             if (ipsEnterTime)
275837bbf98cSChris Cain             {
275937bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
276037bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2761bd79bce8SPatrick Williams                 setDbusProperty(
2762bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2763bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2764e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
276537bbf98cSChris Cain             }
276637bbf98cSChris Cain             if (ipsExitUtil)
276737bbf98cSChris Cain             {
2768bd79bce8SPatrick Williams                 setDbusProperty(
2769bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2770bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2771e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
277237bbf98cSChris Cain             }
277337bbf98cSChris Cain             if (ipsExitTime)
277437bbf98cSChris Cain             {
277537bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
277637bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2777bd79bce8SPatrick Williams                 setDbusProperty(
2778bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2779bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2780e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
278137bbf98cSChris Cain             }
2782e99073f5SGeorge Liu         });
278337bbf98cSChris Cain 
278462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
278537bbf98cSChris Cain }
278637bbf98cSChris Cain 
2787c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2788dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2789dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2790dd60b9edSEd Tanous {
2791dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2792dd60b9edSEd Tanous     {
2793dd60b9edSEd Tanous         return;
2794dd60b9edSEd Tanous     }
2795dd60b9edSEd Tanous     asyncResp->res.addHeader(
2796dd60b9edSEd Tanous         boost::beast::http::field::link,
2797dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2798dd60b9edSEd Tanous }
2799dd60b9edSEd Tanous 
2800c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2801c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2802c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28031abe55efSEd Tanous {
28043ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2805f4c99e70SEd Tanous     {
2806f4c99e70SEd Tanous         return;
2807f4c99e70SEd Tanous     }
2808dd60b9edSEd Tanous 
2809dd60b9edSEd Tanous     asyncResp->res.addHeader(
2810dd60b9edSEd Tanous         boost::beast::http::field::link,
2811dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28128d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28130f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28148d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28158d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2816462023adSSunitha Harish 
28177f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
28187f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
281925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28207f3e84a1SEd Tanous     {
28217f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
28227f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28237f3e84a1SEd Tanous         return;
28247f3e84a1SEd Tanous     }
28257f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
28267f3e84a1SEd Tanous     nlohmann::json::object_t system;
2827253f11b8SEd Tanous     system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2828253f11b8SEd Tanous                                               BMCWEB_REDFISH_SYSTEM_URI_NAME);
28297f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
283068896206SGunnar Mills 
283168896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2832462023adSSunitha Harish     {
283362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
283468896206SGunnar Mills         asyncResp->res.jsonValue["Members@odata.count"] = 2;
283568896206SGunnar Mills 
28361476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2837002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
283868896206SGunnar Mills         ifaceArray.emplace_back(std::move(hypervisor));
283968896206SGunnar Mills     }
2840c1e219d5SEd Tanous }
2841c1e219d5SEd Tanous 
2842c1e219d5SEd Tanous /**
28437e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28447e860f15SJohn Edward Broadbent  */
28454f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28467e860f15SJohn Edward Broadbent {
284789492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
284889492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
284989492a15SPatrick Williams     constexpr const char* interfaceName =
28507e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
285189492a15SPatrick Williams     constexpr const char* method = "NMI";
28527e860f15SJohn Edward Broadbent 
28537e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28545e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28557e860f15SJohn Edward Broadbent             if (ec)
28567e860f15SJohn Edward Broadbent             {
285762598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28587e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28597e860f15SJohn Edward Broadbent                 return;
28607e860f15SJohn Edward Broadbent             }
28617e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28627e860f15SJohn Edward Broadbent         },
28637e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28647e860f15SJohn Edward Broadbent }
2865c5b2abe0SLewanczyk, Dawid 
2866c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2867c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
28687f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2869c1e219d5SEd Tanous     const std::string& systemName)
2870c1e219d5SEd Tanous {
28713ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
287245ca1b86SEd Tanous     {
287345ca1b86SEd Tanous         return;
287445ca1b86SEd Tanous     }
2875dd7090e6SGunnar Mills 
2876dd7090e6SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2877dd7090e6SGunnar Mills     {
2878dd7090e6SGunnar Mills         if (systemName == "hypervisor")
2879dd7090e6SGunnar Mills         {
2880dd7090e6SGunnar Mills             handleHypervisorSystemResetPost(req, asyncResp);
2881dd7090e6SGunnar Mills             return;
2882dd7090e6SGunnar Mills         }
2883dd7090e6SGunnar Mills     }
2884dd7090e6SGunnar Mills 
2885253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2886c1e219d5SEd Tanous     {
2887c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2888c1e219d5SEd Tanous                                    systemName);
2889c1e219d5SEd Tanous         return;
2890c1e219d5SEd Tanous     }
289125b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28927f3e84a1SEd Tanous     {
28937f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28947f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2895c1e219d5SEd Tanous                                    systemName);
28967f3e84a1SEd Tanous         return;
28977f3e84a1SEd Tanous     }
28989712f8acSEd Tanous     std::string resetType;
2899c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2900cc340dd9SEd Tanous     {
2901cc340dd9SEd Tanous         return;
2902cc340dd9SEd Tanous     }
2903cc340dd9SEd Tanous 
2904d22c8396SJason M. Bills     // Get the command and host vs. chassis
2905cc340dd9SEd Tanous     std::string command;
2906543f4400SEd Tanous     bool hostCommand = true;
2907d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2908cc340dd9SEd Tanous     {
2909cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2910d22c8396SJason M. Bills         hostCommand = true;
2911d22c8396SJason M. Bills     }
2912d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2913d22c8396SJason M. Bills     {
2914d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2915d22c8396SJason M. Bills         hostCommand = false;
2916d22c8396SJason M. Bills     }
2917d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2918d22c8396SJason M. Bills     {
2919c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
292086a0851aSJason M. Bills         hostCommand = true;
2921cc340dd9SEd Tanous     }
29229712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2923cc340dd9SEd Tanous     {
2924cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2925d22c8396SJason M. Bills         hostCommand = true;
2926cc340dd9SEd Tanous     }
29279712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2928cc340dd9SEd Tanous     {
29290fda0f12SGeorge Liu         command =
29300fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2931d22c8396SJason M. Bills         hostCommand = true;
2932d22c8396SJason M. Bills     }
2933d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2934d22c8396SJason M. Bills     {
293586a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
293686a0851aSJason M. Bills         hostCommand = true;
2937cc340dd9SEd Tanous     }
2938bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2939bfd5b826SLakshminarayana R. Kammath     {
2940bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2941bfd5b826SLakshminarayana R. Kammath         return;
2942bfd5b826SLakshminarayana R. Kammath     }
2943cc340dd9SEd Tanous     else
2944cc340dd9SEd Tanous     {
2945c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2946cc340dd9SEd Tanous         return;
2947cc340dd9SEd Tanous     }
2948d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
2949cc340dd9SEd Tanous 
2950d22c8396SJason M. Bills     if (hostCommand)
2951d22c8396SJason M. Bills     {
2952e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
2953d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
2954e93abac6SGinu George                         "RequestedHostTransition", command);
2955cc340dd9SEd Tanous     }
2956d22c8396SJason M. Bills     else
2957d22c8396SJason M. Bills     {
2958e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
2959d02aad39SEd Tanous                         statePath / "chassis0",
2960d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2961e93abac6SGinu George                         "RequestedPowerTransition", command);
2962d22c8396SJason M. Bills     }
2963d22c8396SJason M. Bills }
2964cc340dd9SEd Tanous 
2965c1e219d5SEd Tanous inline void handleComputerSystemHead(
2966dd60b9edSEd Tanous     App& app, const crow::Request& req,
29677f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29687f3e84a1SEd Tanous     const std::string& /*systemName*/)
2969dd60b9edSEd Tanous {
2970dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2971dd60b9edSEd Tanous     {
2972dd60b9edSEd Tanous         return;
2973dd60b9edSEd Tanous     }
2974dd60b9edSEd Tanous 
2975dd60b9edSEd Tanous     asyncResp->res.addHeader(
2976dd60b9edSEd Tanous         boost::beast::http::field::link,
2977dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2978dd60b9edSEd Tanous }
2979dd60b9edSEd Tanous 
29805c3e9272SAbhishek Patel inline void afterPortRequest(
29815c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29825c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29835c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29845c3e9272SAbhishek Patel {
29855c3e9272SAbhishek Patel     if (ec)
29865c3e9272SAbhishek Patel     {
2987b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29885c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29895c3e9272SAbhishek Patel         return;
29905c3e9272SAbhishek Patel     }
29915c3e9272SAbhishek Patel     for (const auto& data : socketData)
29925c3e9272SAbhishek Patel     {
29935c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29945c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29955c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29965c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29975c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29985c3e9272SAbhishek Patel         // need to retrieve port number for
29995c3e9272SAbhishek Patel         // obmc-console-ssh service
30005c3e9272SAbhishek Patel         if (protocolName == "SSH")
30015c3e9272SAbhishek Patel         {
30025c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
300381c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30045c3e9272SAbhishek Patel                                           int portNumber) {
30055c3e9272SAbhishek Patel                 if (ec1)
30065c3e9272SAbhishek Patel                 {
3007b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
30085c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30095c3e9272SAbhishek Patel                     return;
30105c3e9272SAbhishek Patel                 }
30115c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30125c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30135c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30145c3e9272SAbhishek Patel             });
30155c3e9272SAbhishek Patel         }
30165c3e9272SAbhishek Patel     }
30175c3e9272SAbhishek Patel }
3018c1e219d5SEd Tanous 
3019c1e219d5SEd Tanous inline void
3020c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
302122d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3022c1e219d5SEd Tanous                             const std::string& systemName)
3023c1e219d5SEd Tanous {
30243ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
302545ca1b86SEd Tanous     {
302645ca1b86SEd Tanous         return;
302745ca1b86SEd Tanous     }
3028746b56f3SAsmitha Karunanithi 
302925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30307f3e84a1SEd Tanous     {
30317f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30327f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
30337f3e84a1SEd Tanous                                    systemName);
30347f3e84a1SEd Tanous         return;
30357f3e84a1SEd Tanous     }
30367f3e84a1SEd Tanous 
303768896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
303868896206SGunnar Mills     {
3039746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3040746b56f3SAsmitha Karunanithi         {
3041746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3042746b56f3SAsmitha Karunanithi             return;
3043746b56f3SAsmitha Karunanithi         }
304468896206SGunnar Mills     }
3045746b56f3SAsmitha Karunanithi 
3046253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
304722d268cbSEd Tanous     {
304822d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
304922d268cbSEd Tanous                                    systemName);
305022d268cbSEd Tanous         return;
305122d268cbSEd Tanous     }
3052dd60b9edSEd Tanous     asyncResp->res.addHeader(
3053dd60b9edSEd Tanous         boost::beast::http::field::link,
3054dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30558d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3056b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
3057253f11b8SEd Tanous     asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3058253f11b8SEd Tanous     asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3059539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3060539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30618d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30628d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3063cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3064dfb2b408SPriyanga Ramasamy         double(0);
3065253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3066253f11b8SEd Tanous         "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
306704a258f4SEd Tanous 
3068253f11b8SEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3069253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3070253f11b8SEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3071253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3072253f11b8SEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3073253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
30743179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3075253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3076253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3077029573d4SEd Tanous 
3078002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3079253f11b8SEd Tanous         boost::urls::format(
3080253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3081253f11b8SEd Tanous             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3082c1e219d5SEd Tanous     asyncResp->res
3083c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3084253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3085253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3086c5b2abe0SLewanczyk, Dawid 
3087253f11b8SEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3088253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3089253f11b8SEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3090253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3091c4bf6374SJason M. Bills 
30921476687dSEd Tanous     nlohmann::json::array_t managedBy;
30931476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3094253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3095253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3096002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3097539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3098539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
30990e8ac5e7SGunnar Mills 
31000e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3101002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3102c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
31031476687dSEd Tanous 
3104c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
31051476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3106c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31071476687dSEd Tanous         "Press ~. to exit console";
31085c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31095c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31100e8ac5e7SGunnar Mills 
311125b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
311225b54dbaSEd Tanous     {
31130e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3114002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
311525b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
311625b54dbaSEd Tanous             4;
3117613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3118613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
311925b54dbaSEd Tanous     }
312013451e39SWilly Tu 
3121bd79bce8SPatrick Williams     getMainChassisId(
3122bd79bce8SPatrick Williams         asyncResp, [](const std::string& chassisId,
31238d1b46d7Szhanghch05                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3124b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3125b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3126bd79bce8SPatrick Williams             chassis["@odata.id"] =
3127bd79bce8SPatrick Williams                 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3128002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3129c5d03ff4SJennifer Lee         });
3130a3002228SAppaRao Puli 
313159a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
31329f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3133a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
313451bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
31356c34de48SEd Tanous     getHostState(asyncResp);
3136491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3137978b8803SAndrew Geissler     getBootProgress(asyncResp);
3138b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
313970c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
314070c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
314151709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3142c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
31439dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3144797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3145c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
314625b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
314725b54dbaSEd Tanous     {
3148a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
314925b54dbaSEd Tanous     }
31501981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
31513a2d0424SChris Cain     getPowerMode(asyncResp);
315237bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3153c1e219d5SEd Tanous }
3154550a6bf8SJiaqing Zhao 
3155c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3156c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
315722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3158c1e219d5SEd Tanous     const std::string& systemName)
3159c1e219d5SEd Tanous {
31603ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
316145ca1b86SEd Tanous     {
316245ca1b86SEd Tanous         return;
316345ca1b86SEd Tanous     }
316425b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31657f3e84a1SEd Tanous     {
31667f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31677f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31687f3e84a1SEd Tanous                                    systemName);
31697f3e84a1SEd Tanous         return;
31707f3e84a1SEd Tanous     }
3171253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
317222d268cbSEd Tanous     {
317322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
317422d268cbSEd Tanous                                    systemName);
317522d268cbSEd Tanous         return;
317622d268cbSEd Tanous     }
317722d268cbSEd Tanous 
3178dd60b9edSEd Tanous     asyncResp->res.addHeader(
3179dd60b9edSEd Tanous         boost::beast::http::field::link,
3180dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3181dd60b9edSEd Tanous 
31829f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3183cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
318498e386ecSGunnar Mills     std::optional<std::string> assetTag;
3185c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
31863a2d0424SChris Cain     std::optional<std::string> powerMode;
3187550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3188550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3189550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3190550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3191550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3192550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3193797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3194550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
31959dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3196550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3197550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3198550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3199550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3200550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3201550a6bf8SJiaqing Zhao 
3202*afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
3203*afc474aeSMyung Bae             req, asyncResp->res, //
3204*afc474aeSMyung Bae             "AssetTag", assetTag, //
3205*afc474aeSMyung Bae             "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3206*afc474aeSMyung Bae             "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3207*afc474aeSMyung Bae             "Boot/BootSourceOverrideEnabled", bootEnable, //
3208*afc474aeSMyung Bae             "Boot/BootSourceOverrideMode", bootType, //
3209*afc474aeSMyung Bae             "Boot/BootSourceOverrideTarget", bootSource, //
3210*afc474aeSMyung Bae             "Boot/StopBootOnFault", stopBootOnFault, //
3211*afc474aeSMyung Bae             "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3212*afc474aeSMyung Bae             "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3213*afc474aeSMyung Bae             "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3214*afc474aeSMyung Bae             "IdlePowerSaver/Enabled", ipsEnable, //
3215*afc474aeSMyung Bae             "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3216*afc474aeSMyung Bae             "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3217*afc474aeSMyung Bae             "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3218*afc474aeSMyung Bae             "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3219*afc474aeSMyung Bae             "IndicatorLED", indicatorLed, //
3220*afc474aeSMyung Bae             "LocationIndicatorActive", locationIndicatorActive, //
3221*afc474aeSMyung Bae             "PowerMode", powerMode, //
3222*afc474aeSMyung Bae             "PowerRestorePolicy", powerRestorePolicy //
3223*afc474aeSMyung Bae             ))
32246617338dSEd Tanous     {
32256617338dSEd Tanous         return;
32266617338dSEd Tanous     }
3227491d8ee7SSantosh Puranik 
32288d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3229c45f0082SYong Li 
323098e386ecSGunnar Mills     if (assetTag)
323198e386ecSGunnar Mills     {
323298e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
323398e386ecSGunnar Mills     }
323498e386ecSGunnar Mills 
3235550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3236c45f0082SYong Li     {
3237f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3238c45f0082SYong Li     }
3239c45f0082SYong Li 
3240cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
324169f35306SGunnar Mills     {
3242002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3243491d8ee7SSantosh Puranik     }
3244550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
324569f35306SGunnar Mills     {
3246550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
324769f35306SGunnar Mills     }
3248ac7e1e0bSAli Ahmed 
3249797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3250797d5daeSCorey Hardesty     {
3251797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3252797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3253797d5daeSCorey Hardesty     }
3254797d5daeSCorey Hardesty 
3255550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3256ac7e1e0bSAli Ahmed     {
3257c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
325869f35306SGunnar Mills     }
3259265c1602SJohnathan Mantey 
32609dcfe8c1SAlbert Zhang     if (stopBootOnFault)
32619dcfe8c1SAlbert Zhang     {
32629dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
32639dcfe8c1SAlbert Zhang     }
32649dcfe8c1SAlbert Zhang 
32659f8bfa7cSGunnar Mills     if (locationIndicatorActive)
32669f8bfa7cSGunnar Mills     {
326759a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32689f8bfa7cSGunnar Mills     }
32699f8bfa7cSGunnar Mills 
32707e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
32717e860f15SJohn Edward Broadbent     // passed
32729712f8acSEd Tanous     if (indicatorLed)
32736617338dSEd Tanous     {
3274f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3275002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3276d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3277d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
32786617338dSEd Tanous     }
3279c6a620f2SGeorge Liu 
3280c6a620f2SGeorge Liu     if (powerRestorePolicy)
3281c6a620f2SGeorge Liu     {
32824e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3283c6a620f2SGeorge Liu     }
32843a2d0424SChris Cain 
32853a2d0424SChris Cain     if (powerMode)
32863a2d0424SChris Cain     {
32873a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
32883a2d0424SChris Cain     }
328937bbf98cSChris Cain 
3290c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
329137bbf98cSChris Cain     {
3292002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3293002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
329437bbf98cSChris Cain     }
3295c1e219d5SEd Tanous }
32961cb1a9e6SAppaRao Puli 
329738c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3298dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
32997f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3300c1e219d5SEd Tanous     const std::string& /*systemName*/)
3301dd60b9edSEd Tanous {
3302dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3303dd60b9edSEd Tanous     {
3304dd60b9edSEd Tanous         return;
3305dd60b9edSEd Tanous     }
3306dd60b9edSEd Tanous     asyncResp->res.addHeader(
3307dd60b9edSEd Tanous         boost::beast::http::field::link,
3308dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3309dd60b9edSEd Tanous }
331033e1f122SAndrew Geissler 
331133e1f122SAndrew Geissler /**
331233e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
331333e1f122SAndrew Geissler  *
331433e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
331533e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
331633e1f122SAndrew Geissler  *
3317efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
331833e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
331933e1f122SAndrew Geissler  * allowableValues.
332033e1f122SAndrew Geissler  */
332133e1f122SAndrew Geissler inline void
332233e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
332333e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
332433e1f122SAndrew Geissler {
332533e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
332633e1f122SAndrew Geissler     {
332733e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
332833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
332933e1f122SAndrew Geissler     }
333033e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
333133e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
333233e1f122SAndrew Geissler     {
333333e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
333433e1f122SAndrew Geissler     }
333533e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
333633e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
333733e1f122SAndrew Geissler     {
333833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
333933e1f122SAndrew Geissler     }
334033e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
334133e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
334233e1f122SAndrew Geissler     {
334333e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
334433e1f122SAndrew Geissler     }
334533e1f122SAndrew Geissler     else
334633e1f122SAndrew Geissler     {
334733e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
334833e1f122SAndrew Geissler     }
334933e1f122SAndrew Geissler }
335033e1f122SAndrew Geissler 
335133e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
335233e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
335333e1f122SAndrew Geissler     const boost::system::error_code& ec,
335433e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
335533e1f122SAndrew Geissler {
335633e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
335733e1f122SAndrew Geissler 
335833e1f122SAndrew Geissler     // Supported on all systems currently
335933e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
336033e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
336133e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
336233e1f122SAndrew Geissler 
336333e1f122SAndrew Geissler     if (ec)
336433e1f122SAndrew Geissler     {
3365e715d14bSEd Tanous         if ((ec.value() ==
3366e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3367e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
336833e1f122SAndrew Geissler         {
336933e1f122SAndrew Geissler             // Property not implemented so just return defaults
337033e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
337133e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
337233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
337333e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
337433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
337533e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
337633e1f122SAndrew Geissler         }
337733e1f122SAndrew Geissler         else
337833e1f122SAndrew Geissler         {
337933e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
338033e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
338133e1f122SAndrew Geissler             return;
338233e1f122SAndrew Geissler         }
338333e1f122SAndrew Geissler     }
338433e1f122SAndrew Geissler     else
338533e1f122SAndrew Geissler     {
338633e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
338733e1f122SAndrew Geissler         {
338833e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
338933e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
339033e1f122SAndrew Geissler         }
339133e1f122SAndrew Geissler     }
339233e1f122SAndrew Geissler 
339333e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
339433e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
339533e1f122SAndrew Geissler     parameter["Required"] = true;
3396539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
339733e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
339833e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
339933e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
340033e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
340133e1f122SAndrew Geissler }
340233e1f122SAndrew Geissler 
3403c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3404c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
340522d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3406c1e219d5SEd Tanous     const std::string& systemName)
3407c1e219d5SEd Tanous {
34083ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
340945ca1b86SEd Tanous     {
341045ca1b86SEd Tanous         return;
341145ca1b86SEd Tanous     }
341225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
34137f3e84a1SEd Tanous     {
34147f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34157f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34167f3e84a1SEd Tanous                                    systemName);
34177f3e84a1SEd Tanous         return;
34187f3e84a1SEd Tanous     }
3419746b56f3SAsmitha Karunanithi 
342068896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
342168896206SGunnar Mills     {
3422746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3423746b56f3SAsmitha Karunanithi         {
3424746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3425746b56f3SAsmitha Karunanithi             return;
3426746b56f3SAsmitha Karunanithi         }
342768896206SGunnar Mills     }
3428746b56f3SAsmitha Karunanithi 
3429253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
343022d268cbSEd Tanous     {
343122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
343222d268cbSEd Tanous                                    systemName);
343322d268cbSEd Tanous         return;
343422d268cbSEd Tanous     }
343522d268cbSEd Tanous 
3436dd60b9edSEd Tanous     asyncResp->res.addHeader(
3437dd60b9edSEd Tanous         boost::beast::http::field::link,
3438dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34391476687dSEd Tanous 
34401476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
3441253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3442253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3443c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34441476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34451476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34463215e700SNan Zhou 
344733e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
344833e1f122SAndrew Geissler     sdbusplus::asio::getProperty<std::vector<std::string>>(
344933e1f122SAndrew Geissler         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
345033e1f122SAndrew Geissler         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
345133e1f122SAndrew Geissler         "AllowedHostTransitions",
345233e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
345333e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
3454bd79bce8SPatrick Williams             afterGetAllowedHostTransitions(asyncResp, ec,
3455bd79bce8SPatrick Williams                                            allowedHostTransitions);
345633e1f122SAndrew Geissler         });
3457c1e219d5SEd Tanous }
3458c1e219d5SEd Tanous /**
3459c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3460c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3461c1e219d5SEd Tanous  */
3462100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3463c1e219d5SEd Tanous {
3464100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3465100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3466100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3467100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3468100afe56SEd Tanous 
3469100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3470100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3471100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3472100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3473100afe56SEd Tanous 
3474100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3475100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3476100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3477100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3478100afe56SEd Tanous 
3479100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3480100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3481100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3482100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3483100afe56SEd Tanous 
3484100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3485100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3486100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3487100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3488100afe56SEd Tanous 
3489100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3490100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3491100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3492100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3493100afe56SEd Tanous 
3494c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3495c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3496c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3497c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3498c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3499c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3500c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3501c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
35021cb1a9e6SAppaRao Puli }
3503c5b2abe0SLewanczyk, Dawid } // namespace redfish
3504