xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision d43cc6bcbc8b1d6f4c8a6e8945c9a6a34a6aaca8)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
4c5b2abe0SLewanczyk, Dawid #pragma once
5c5b2abe0SLewanczyk, Dawid 
613451e39SWilly Tu #include "bmcweb_config.h"
713451e39SWilly Tu 
83ccb3adbSEd Tanous #include "app.hpp"
9d7857201SEd Tanous #include "async_resp.hpp"
101e1e598dSJonathan Doman #include "dbus_singleton.hpp"
117a1dbc48SGeorge Liu #include "dbus_utility.hpp"
12d7857201SEd Tanous #include "error_messages.hpp"
13539d8c6bSEd Tanous #include "generated/enums/action_info.hpp"
148d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
15539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp"
1633e1f122SAndrew Geissler #include "generated/enums/resource.hpp"
17d7857201SEd Tanous #include "http_request.hpp"
18746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
191c8fba97SJames Feist #include "led.hpp"
20d7857201SEd Tanous #include "logging.hpp"
21f4c99e70SEd Tanous #include "query.hpp"
22c5d03ff4SJennifer Lee #include "redfish_util.hpp"
233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
243ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
253ccb3adbSEd Tanous #include "utils/json_utils.hpp"
26472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
273ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
28fc5ae94dSOliver Brewka #include "utils/systems_utils.hpp"
292b82937eSEd Tanous #include "utils/time_utils.hpp"
30c5d03ff4SJennifer Lee 
31d7857201SEd Tanous #include <asm-generic/errno.h>
32d7857201SEd Tanous 
33fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
34d7857201SEd Tanous #include <boost/beast/http/field.hpp>
35d7857201SEd Tanous #include <boost/beast/http/status.hpp>
36d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
37e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
3833e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
39ef4c65b7SEd Tanous #include <boost/url/format.hpp>
40d7857201SEd Tanous #include <nlohmann/json.hpp>
41d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
431214b7e7SGunnar Mills 
447a1dbc48SGeorge Liu #include <array>
45d7857201SEd Tanous #include <chrono>
46d7857201SEd Tanous #include <cstddef>
47d7857201SEd Tanous #include <cstdint>
48d7857201SEd Tanous #include <functional>
4933e1f122SAndrew Geissler #include <memory>
50d7857201SEd Tanous #include <optional>
51d7857201SEd Tanous #include <ratio>
526b9ac4f2SChris Cain #include <string>
537a1dbc48SGeorge Liu #include <string_view>
54d7857201SEd Tanous #include <tuple>
5520fa6a2cSEd Tanous #include <utility>
566b9ac4f2SChris Cain #include <vector>
57c5b2abe0SLewanczyk, Dawid 
581abe55efSEd Tanous namespace redfish
591abe55efSEd Tanous {
60c5b2abe0SLewanczyk, Dawid 
615c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
625c3e9272SAbhishek Patel     protocolToDBusForSystems{
635c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
645c3e9272SAbhishek Patel 
659d3ae10eSAlpana Kumari /**
669d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
679d3ae10eSAlpana Kumari  *
68ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
699d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
709d3ae10eSAlpana Kumari  *
719d3ae10eSAlpana Kumari  * @return None.
729d3ae10eSAlpana Kumari  */
73bd79bce8SPatrick Williams inline void updateDimmProperties(
74bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
759d3ae10eSAlpana Kumari {
7662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
779d3ae10eSAlpana Kumari 
789d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
799d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
809d3ae10eSAlpana Kumari     // ENABLED.
8102cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
82ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
839d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
849d3ae10eSAlpana Kumari     {
85e05aec50SEd Tanous         if (isDimmFunctional)
869d3ae10eSAlpana Kumari         {
87ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
889d3ae10eSAlpana Kumari                 "Enabled";
899d3ae10eSAlpana Kumari         }
909d3ae10eSAlpana Kumari     }
919d3ae10eSAlpana Kumari }
929d3ae10eSAlpana Kumari 
9357e8c9beSAlpana Kumari /*
9457e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9557e8c9beSAlpana Kumari  *        CPU Functional State
9657e8c9beSAlpana Kumari  *
97ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9857e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9957e8c9beSAlpana Kumari  *
10057e8c9beSAlpana Kumari  * @return None.
10157e8c9beSAlpana Kumari  */
102ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
103ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10457e8c9beSAlpana Kumari {
10562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10657e8c9beSAlpana Kumari 
10702cad96eSEd Tanous     const nlohmann::json& prevProcState =
108ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10957e8c9beSAlpana Kumari 
11057e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
11157e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11257e8c9beSAlpana Kumari     // Functional.
11357e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11457e8c9beSAlpana Kumari     {
115e05aec50SEd Tanous         if (isCpuFunctional)
11657e8c9beSAlpana Kumari         {
117ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11857e8c9beSAlpana Kumari                 "Enabled";
11957e8c9beSAlpana Kumari         }
12057e8c9beSAlpana Kumari     }
12157e8c9beSAlpana Kumari }
12257e8c9beSAlpana Kumari 
123cf0e004cSNinad Palsule /*
124cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
125cf0e004cSNinad Palsule  *
126ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
127cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
128cf0e004cSNinad Palsule  *
129cf0e004cSNinad Palsule  * @return None.
130cf0e004cSNinad Palsule  */
131bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
132bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
133cf0e004cSNinad Palsule {
13462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
135cf0e004cSNinad Palsule 
136cf0e004cSNinad Palsule     if (isCpuPresent)
137cf0e004cSNinad Palsule     {
138cf0e004cSNinad Palsule         nlohmann::json& procCount =
139ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
140cf0e004cSNinad Palsule         auto* procCountPtr =
141cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
142cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
143cf0e004cSNinad Palsule         {
144cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
145cf0e004cSNinad Palsule             *procCountPtr += 1;
146cf0e004cSNinad Palsule         }
147cf0e004cSNinad Palsule     }
148cf0e004cSNinad Palsule }
149cf0e004cSNinad Palsule 
150382d6475SAli Ahmed inline void getProcessorProperties(
151ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
152382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
153382d6475SAli Ahmed         properties)
15403fbed92SAli Ahmed {
15562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15603fbed92SAli Ahmed 
15703fbed92SAli Ahmed     // TODO: Get Model
15803fbed92SAli Ahmed 
159bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
16003fbed92SAli Ahmed 
161bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
162bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16303fbed92SAli Ahmed 
164bc1d29deSKrzysztof Grobelny     if (!success)
16503fbed92SAli Ahmed     {
166ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16703fbed92SAli Ahmed         return;
16803fbed92SAli Ahmed     }
16903fbed92SAli Ahmed 
170bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
17103fbed92SAli Ahmed     {
172bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
173ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
174bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
175bc1d29deSKrzysztof Grobelny 
176bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
177bc1d29deSKrzysztof Grobelny         {
178bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17903fbed92SAli Ahmed         }
18003fbed92SAli Ahmed         else
18103fbed92SAli Ahmed         {
182bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18303fbed92SAli Ahmed         }
18403fbed92SAli Ahmed     }
18503fbed92SAli Ahmed }
18603fbed92SAli Ahmed 
18703fbed92SAli Ahmed /*
18803fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18903fbed92SAli Ahmed  *
190ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
19103fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
19203fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19303fbed92SAli Ahmed  *
19403fbed92SAli Ahmed  * @return None.
19503fbed92SAli Ahmed  */
196504af5a0SPatrick Williams inline void getProcessorSummary(
197504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
198ac106bf6SEd Tanous     const std::string& service, const std::string& path)
19903fbed92SAli Ahmed {
200ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
201382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
202382d6475SAli Ahmed         if (ec3)
203382d6475SAli Ahmed         {
20462598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
205382d6475SAli Ahmed             return;
206382d6475SAli Ahmed         }
207ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
208382d6475SAli Ahmed     };
209382d6475SAli Ahmed 
210cf0e004cSNinad Palsule     // Get the Presence of CPU
211deae6a78SEd Tanous     dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
212deae6a78SEd Tanous                                      path, "xyz.openbmc_project.Inventory.Item",
213deae6a78SEd Tanous                                      "Present", std::move(getCpuPresenceState));
214cf0e004cSNinad Palsule 
215deae6a78SEd Tanous     dbus::utility::getAllProperties(
216deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
217ac106bf6SEd Tanous         [asyncResp, service,
2185e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
219b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22003fbed92SAli Ahmed             if (ec2)
22103fbed92SAli Ahmed             {
22262598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
223ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22403fbed92SAli Ahmed                 return;
22503fbed92SAli Ahmed             }
226ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
227bc1d29deSKrzysztof Grobelny         });
22803fbed92SAli Ahmed }
22903fbed92SAli Ahmed 
23057e8c9beSAlpana Kumari /*
231cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
232cf0e004cSNinad Palsule  *
233ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
234cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
235cf0e004cSNinad Palsule  *
236cf0e004cSNinad Palsule  * @return None.
237cf0e004cSNinad Palsule  */
238504af5a0SPatrick Williams inline void processMemoryProperties(
239504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
240cf0e004cSNinad Palsule     const dbus::utility::DBusPropertiesMap& properties)
241cf0e004cSNinad Palsule {
24262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
243cf0e004cSNinad Palsule 
244cf0e004cSNinad Palsule     if (properties.empty())
245cf0e004cSNinad Palsule     {
246cf0e004cSNinad Palsule         return;
247cf0e004cSNinad Palsule     }
248cf0e004cSNinad Palsule 
249cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
250cf0e004cSNinad Palsule 
251cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
252cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
253cf0e004cSNinad Palsule         memorySizeInKB);
254cf0e004cSNinad Palsule 
255cf0e004cSNinad Palsule     if (!success)
256cf0e004cSNinad Palsule     {
257ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
258cf0e004cSNinad Palsule         return;
259cf0e004cSNinad Palsule     }
260cf0e004cSNinad Palsule 
261cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
262cf0e004cSNinad Palsule     {
263cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
264ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
265dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
266cf0e004cSNinad Palsule         if (preValue == nullptr)
267cf0e004cSNinad Palsule         {
268ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
269dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
270cf0e004cSNinad Palsule         }
271cf0e004cSNinad Palsule         else
272cf0e004cSNinad Palsule         {
273ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
274dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
275dfb2b408SPriyanga Ramasamy                 *preValue;
276cf0e004cSNinad Palsule         }
277cf0e004cSNinad Palsule     }
278cf0e004cSNinad Palsule }
279cf0e004cSNinad Palsule 
280cf0e004cSNinad Palsule /*
281cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
282cf0e004cSNinad Palsule  *
283ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
284cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
285cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
286cf0e004cSNinad Palsule  *
287cf0e004cSNinad Palsule  * @return None.
288cf0e004cSNinad Palsule  */
289504af5a0SPatrick Williams inline void getMemorySummary(
290504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
291ac106bf6SEd Tanous     const std::string& service, const std::string& path)
292cf0e004cSNinad Palsule {
293deae6a78SEd Tanous     dbus::utility::getAllProperties(
294deae6a78SEd Tanous         service, path, "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 
346504af5a0SPatrick Williams inline void afterGetInventory(
347504af5a0SPatrick Williams     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 
469deae6a78SEd Tanous                     dbus::utility::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                 {
481deae6a78SEd Tanous                     dbus::utility::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 
490deae6a78SEd Tanous                     dbus::utility::getProperty<std::string>(
491deae6a78SEd Tanous                         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  */
509504af5a0SPatrick Williams inline void getComputerSystem(
510504af5a0SPatrick Williams     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.
5295e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
530c5b2abe0SLewanczyk, Dawid  *
531c5b2abe0SLewanczyk, Dawid  * @return None.
532c5b2abe0SLewanczyk, Dawid  */
5335e7c1f31SOliver Brewka inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5345e7c1f31SOliver Brewka                          const uint64_t computerSystemIndex)
5351abe55efSEd Tanous {
53662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
5375e7c1f31SOliver Brewka 
538deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
5395e7c1f31SOliver Brewka         getHostStateServiceName(computerSystemIndex),
5405e7c1f31SOliver Brewka         getHostStateObjectPath(computerSystemIndex),
541deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState",
542ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5431e1e598dSJonathan Doman                     const std::string& hostState) {
5441abe55efSEd Tanous             if (ec)
5451abe55efSEd Tanous             {
54622228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
54722228c28SAndrew Geissler                 {
54822228c28SAndrew Geissler                     // Service not available, no error, just don't return
54922228c28SAndrew Geissler                     // host state info
55062598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
55122228c28SAndrew Geissler                     return;
55222228c28SAndrew Geissler                 }
55362598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
554ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
555c5b2abe0SLewanczyk, Dawid                 return;
556c5b2abe0SLewanczyk, Dawid             }
5576617338dSEd Tanous 
55862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
559c5b2abe0SLewanczyk, Dawid             // Verify Host State
5601e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5611abe55efSEd Tanous             {
562bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
563bd79bce8SPatrick Williams                     resource::PowerState::On;
564539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
565539d8c6bSEd Tanous                     resource::State::Enabled;
5661abe55efSEd Tanous             }
5671e1e598dSJonathan Doman             else if (hostState ==
5680fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5698c888608SGunnar Mills             {
570bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
571bd79bce8SPatrick Williams                     resource::PowerState::On;
572539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
573539d8c6bSEd Tanous                     resource::State::Quiesced;
5748c888608SGunnar Mills             }
5751e1e598dSJonathan Doman             else if (hostState ==
5760fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57783935af9SAndrew Geissler             {
578bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
579bd79bce8SPatrick Williams                     resource::PowerState::On;
580539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
581539d8c6bSEd Tanous                     resource::State::InTest;
58283935af9SAndrew Geissler             }
5830fda0f12SGeorge Liu             else if (
5841e1e598dSJonathan Doman                 hostState ==
5850fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5861a2a1437SAndrew Geissler             {
587539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
588539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
589539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
590539d8c6bSEd Tanous                     resource::State::Starting;
5911a2a1437SAndrew Geissler             }
592bd79bce8SPatrick Williams             else if (
593bd79bce8SPatrick Williams                 hostState ==
5940fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5951a2a1437SAndrew Geissler             {
596539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
597539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
598539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
599539d8c6bSEd Tanous                     resource::State::Disabled;
6001a2a1437SAndrew Geissler             }
6011abe55efSEd Tanous             else
6021abe55efSEd Tanous             {
603bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
604bd79bce8SPatrick Williams                     resource::PowerState::Off;
605539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
606539d8c6bSEd Tanous                     resource::State::Disabled;
607c5b2abe0SLewanczyk, Dawid             }
6081e1e598dSJonathan Doman         });
609c5b2abe0SLewanczyk, Dawid }
610c5b2abe0SLewanczyk, Dawid 
611c5b2abe0SLewanczyk, Dawid /**
612786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
613491d8ee7SSantosh Puranik  *
614491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
615491d8ee7SSantosh Puranik  *
616491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
617491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
618491d8ee7SSantosh Puranik  */
61923a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
620491d8ee7SSantosh Puranik {
621491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
622491d8ee7SSantosh Puranik     {
623491d8ee7SSantosh Puranik         return "None";
624491d8ee7SSantosh Puranik     }
6253174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
626491d8ee7SSantosh Puranik     {
627491d8ee7SSantosh Puranik         return "Hdd";
628491d8ee7SSantosh Puranik     }
6293174e4dfSEd Tanous     if (dbusSource ==
630a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
631491d8ee7SSantosh Puranik     {
632491d8ee7SSantosh Puranik         return "Cd";
633491d8ee7SSantosh Puranik     }
6343174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
635491d8ee7SSantosh Puranik     {
636491d8ee7SSantosh Puranik         return "Pxe";
637491d8ee7SSantosh Puranik     }
6383174e4dfSEd Tanous     if (dbusSource ==
639944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6409f16b2c1SJennifer Lee     {
6419f16b2c1SJennifer Lee         return "Usb";
6429f16b2c1SJennifer Lee     }
643491d8ee7SSantosh Puranik     return "";
644491d8ee7SSantosh Puranik }
645491d8ee7SSantosh Puranik 
646491d8ee7SSantosh Puranik /**
647cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
648cd9a4666SKonstantin Aladyshev  *
649cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
650cd9a4666SKonstantin Aladyshev  *
651cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
652cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
653cd9a4666SKonstantin Aladyshev  */
654cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
655cd9a4666SKonstantin Aladyshev {
656cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
657cd9a4666SKonstantin Aladyshev     {
658cd9a4666SKonstantin Aladyshev         return "Legacy";
659cd9a4666SKonstantin Aladyshev     }
660cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
661cd9a4666SKonstantin Aladyshev     {
662cd9a4666SKonstantin Aladyshev         return "UEFI";
663cd9a4666SKonstantin Aladyshev     }
664cd9a4666SKonstantin Aladyshev     return "";
665cd9a4666SKonstantin Aladyshev }
666cd9a4666SKonstantin Aladyshev 
667cd9a4666SKonstantin Aladyshev /**
668786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
669491d8ee7SSantosh Puranik  *
670491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
671491d8ee7SSantosh Puranik  *
672491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
673491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
674491d8ee7SSantosh Puranik  */
67523a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
676491d8ee7SSantosh Puranik {
677491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
678491d8ee7SSantosh Puranik     {
679491d8ee7SSantosh Puranik         return "None";
680491d8ee7SSantosh Puranik     }
6813174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
682491d8ee7SSantosh Puranik     {
683491d8ee7SSantosh Puranik         return "Diags";
684491d8ee7SSantosh Puranik     }
6853174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
686491d8ee7SSantosh Puranik     {
687491d8ee7SSantosh Puranik         return "BiosSetup";
688491d8ee7SSantosh Puranik     }
689491d8ee7SSantosh Puranik     return "";
690491d8ee7SSantosh Puranik }
691491d8ee7SSantosh Puranik 
692491d8ee7SSantosh Puranik /**
693e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
694e43914b3SAndrew Geissler  *
695e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
696e43914b3SAndrew Geissler  *
697e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
698e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
699e43914b3SAndrew Geissler  */
700e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
701e43914b3SAndrew Geissler {
702e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
703e43914b3SAndrew Geissler     // enum
704e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
705e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
706e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
707e43914b3SAndrew Geissler     {
708e43914b3SAndrew Geissler         rfBpLastState = "None";
709e43914b3SAndrew Geissler     }
710e43914b3SAndrew Geissler     else if (dbusBootProgress ==
711e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
712e43914b3SAndrew Geissler              "PrimaryProcInit")
713e43914b3SAndrew Geissler     {
714e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
715e43914b3SAndrew Geissler     }
716e43914b3SAndrew Geissler     else if (dbusBootProgress ==
717e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
718e43914b3SAndrew Geissler              "BusInit")
719e43914b3SAndrew Geissler     {
720e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
721e43914b3SAndrew Geissler     }
722e43914b3SAndrew Geissler     else if (dbusBootProgress ==
723e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
724e43914b3SAndrew Geissler              "MemoryInit")
725e43914b3SAndrew Geissler     {
726e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
727e43914b3SAndrew Geissler     }
728e43914b3SAndrew Geissler     else if (dbusBootProgress ==
729e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
730e43914b3SAndrew Geissler              "SecondaryProcInit")
731e43914b3SAndrew Geissler     {
732e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
733e43914b3SAndrew Geissler     }
734e43914b3SAndrew Geissler     else if (dbusBootProgress ==
735e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
736e43914b3SAndrew Geissler              "PCIInit")
737e43914b3SAndrew Geissler     {
738e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
739e43914b3SAndrew Geissler     }
740e43914b3SAndrew Geissler     else if (dbusBootProgress ==
741e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
742e43914b3SAndrew Geissler              "SystemSetup")
743e43914b3SAndrew Geissler     {
744e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
745e43914b3SAndrew Geissler     }
746e43914b3SAndrew Geissler     else if (dbusBootProgress ==
747e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
748e43914b3SAndrew Geissler              "SystemInitComplete")
749e43914b3SAndrew Geissler     {
750e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
751e43914b3SAndrew Geissler     }
752e43914b3SAndrew Geissler     else if (dbusBootProgress ==
753e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
754e43914b3SAndrew Geissler              "OSStart")
755e43914b3SAndrew Geissler     {
756e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
757e43914b3SAndrew Geissler     }
758e43914b3SAndrew Geissler     else if (dbusBootProgress ==
759e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
760e43914b3SAndrew Geissler              "OSRunning")
761e43914b3SAndrew Geissler     {
762e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
763e43914b3SAndrew Geissler     }
764e43914b3SAndrew Geissler     else
765e43914b3SAndrew Geissler     {
76662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
767e43914b3SAndrew Geissler         // Just return the default
768e43914b3SAndrew Geissler     }
769e43914b3SAndrew Geissler     return rfBpLastState;
770e43914b3SAndrew Geissler }
771e43914b3SAndrew Geissler 
772e43914b3SAndrew Geissler /**
773786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
774491d8ee7SSantosh Puranik  *
775491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
776944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
777944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
778491d8ee7SSantosh Puranik  *
779944ffaf9SJohnathan Mantey  * @return Integer error code.
780491d8ee7SSantosh Puranik  */
781bd79bce8SPatrick Williams inline int assignBootParameters(
782bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
783bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
784491d8ee7SSantosh Puranik {
785c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
786c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
787944ffaf9SJohnathan Mantey 
788491d8ee7SSantosh Puranik     if (rfSource == "None")
789491d8ee7SSantosh Puranik     {
790944ffaf9SJohnathan Mantey         return 0;
791491d8ee7SSantosh Puranik     }
7923174e4dfSEd Tanous     if (rfSource == "Pxe")
793491d8ee7SSantosh Puranik     {
794944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
795944ffaf9SJohnathan Mantey     }
796944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
797944ffaf9SJohnathan Mantey     {
798944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
799944ffaf9SJohnathan Mantey     }
800944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
801944ffaf9SJohnathan Mantey     {
802944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
803944ffaf9SJohnathan Mantey     }
804944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
805944ffaf9SJohnathan Mantey     {
806944ffaf9SJohnathan Mantey         bootSource =
807944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
808944ffaf9SJohnathan Mantey     }
809944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
810944ffaf9SJohnathan Mantey     {
811944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
812491d8ee7SSantosh Puranik     }
8139f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8149f16b2c1SJennifer Lee     {
815944ffaf9SJohnathan Mantey         bootSource =
816944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8179f16b2c1SJennifer Lee     }
818491d8ee7SSantosh Puranik     else
819491d8ee7SSantosh Puranik     {
82062598e31SEd Tanous         BMCWEB_LOG_DEBUG(
82162598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
82262598e31SEd Tanous             bootSource);
823ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
824944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
825944ffaf9SJohnathan Mantey         return -1;
826491d8ee7SSantosh Puranik     }
827944ffaf9SJohnathan Mantey     return 0;
828491d8ee7SSantosh Puranik }
8291981771bSAli Ahmed 
830978b8803SAndrew Geissler /**
831978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
832978b8803SAndrew Geissler  *
833ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
8345e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
835978b8803SAndrew Geissler  *
836978b8803SAndrew Geissler  * @return None.
837978b8803SAndrew Geissler  */
8385e7c1f31SOliver Brewka inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8395e7c1f31SOliver Brewka                             const uint64_t computerSystemIndex)
840978b8803SAndrew Geissler {
841deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
8425e7c1f31SOliver Brewka         getHostStateServiceName(computerSystemIndex),
8435e7c1f31SOliver Brewka         getHostStateObjectPath(computerSystemIndex),
8441e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
845ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8461e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
847978b8803SAndrew Geissler             if (ec)
848978b8803SAndrew Geissler             {
849978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
850978b8803SAndrew Geissler                 // not found
851978b8803SAndrew Geissler                 return;
852978b8803SAndrew Geissler             }
853978b8803SAndrew Geissler 
85462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
855978b8803SAndrew Geissler 
856ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
857e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8581e1e598dSJonathan Doman         });
859978b8803SAndrew Geissler }
860491d8ee7SSantosh Puranik 
861491d8ee7SSantosh Puranik /**
862b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
863b6d5d45cSHieu Huynh  *
864ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
8655e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
866b6d5d45cSHieu Huynh  *
867b6d5d45cSHieu Huynh  * @return None.
868b6d5d45cSHieu Huynh  */
869b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
8705e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8715e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
872b6d5d45cSHieu Huynh {
873deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
8745e7c1f31SOliver Brewka         getHostStateServiceName(computerSystemIndex),
8755e7c1f31SOliver Brewka         getHostStateObjectPath(computerSystemIndex),
876b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
877ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
878b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
879b6d5d45cSHieu Huynh             if (ec)
880b6d5d45cSHieu Huynh             {
88162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
882b6d5d45cSHieu Huynh                 return;
883b6d5d45cSHieu Huynh             }
884b6d5d45cSHieu Huynh 
885b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
886b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
887b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
888b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
889b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
890b6d5d45cSHieu Huynh 
891b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
892ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
893b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
894b6d5d45cSHieu Huynh         });
895b6d5d45cSHieu Huynh }
896b6d5d45cSHieu Huynh 
897b6d5d45cSHieu Huynh /**
898c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
899cd9a4666SKonstantin Aladyshev  *
900ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
9015e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
902cd9a4666SKonstantin Aladyshev  *
903cd9a4666SKonstantin Aladyshev  * @return None.
904cd9a4666SKonstantin Aladyshev  */
905504af5a0SPatrick Williams inline void getBootOverrideType(
9065e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9075e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
908cd9a4666SKonstantin Aladyshev {
9095e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
9105e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
9115e7c1f31SOliver Brewka     path /= "boot";
9125e7c1f31SOliver Brewka 
913deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
9145e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9151e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
916ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9171e1e598dSJonathan Doman                     const std::string& bootType) {
918cd9a4666SKonstantin Aladyshev             if (ec)
919cd9a4666SKonstantin Aladyshev             {
920cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
921cd9a4666SKonstantin Aladyshev                 return;
922cd9a4666SKonstantin Aladyshev             }
923cd9a4666SKonstantin Aladyshev 
92462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
925cd9a4666SKonstantin Aladyshev 
926ac106bf6SEd Tanous             asyncResp->res
927ac106bf6SEd Tanous                 .jsonValue["Boot"]
928002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
929613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
930cd9a4666SKonstantin Aladyshev 
9311e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
932cd9a4666SKonstantin Aladyshev             if (rfType.empty())
933cd9a4666SKonstantin Aladyshev             {
934ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
935cd9a4666SKonstantin Aladyshev                 return;
936cd9a4666SKonstantin Aladyshev             }
937cd9a4666SKonstantin Aladyshev 
938ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9391e1e598dSJonathan Doman         });
940cd9a4666SKonstantin Aladyshev }
941cd9a4666SKonstantin Aladyshev 
942cd9a4666SKonstantin Aladyshev /**
943c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
944491d8ee7SSantosh Puranik  *
945ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
9465e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
947491d8ee7SSantosh Puranik  *
948491d8ee7SSantosh Puranik  * @return None.
949491d8ee7SSantosh Puranik  */
950504af5a0SPatrick Williams inline void getBootOverrideMode(
9515e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9525e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
953491d8ee7SSantosh Puranik {
9545e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
9555e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
9565e7c1f31SOliver Brewka     path /= "boot";
957deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
9585e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9591e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
960ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9611e1e598dSJonathan Doman                     const std::string& bootModeStr) {
962491d8ee7SSantosh Puranik             if (ec)
963491d8ee7SSantosh Puranik             {
964b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
965ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
966491d8ee7SSantosh Puranik                 return;
967491d8ee7SSantosh Puranik             }
968491d8ee7SSantosh Puranik 
96962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
970491d8ee7SSantosh Puranik 
97120fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
97220fa6a2cSEd Tanous             allowed.emplace_back("None");
97320fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
97420fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
97520fa6a2cSEd Tanous             allowed.emplace_back("Cd");
97620fa6a2cSEd Tanous             allowed.emplace_back("Diags");
97720fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
97820fa6a2cSEd Tanous             allowed.emplace_back("Usb");
97920fa6a2cSEd Tanous 
980ac106bf6SEd Tanous             asyncResp->res
9810fda0f12SGeorge Liu                 .jsonValue["Boot"]
98220fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
98320fa6a2cSEd Tanous                 std::move(allowed);
9841e1e598dSJonathan Doman             if (bootModeStr !=
985491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
986491d8ee7SSantosh Puranik             {
9871e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
988491d8ee7SSantosh Puranik                 if (!rfMode.empty())
989491d8ee7SSantosh Puranik                 {
990bd79bce8SPatrick Williams                     asyncResp->res
991bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
992491d8ee7SSantosh Puranik                 }
993491d8ee7SSantosh Puranik             }
9941e1e598dSJonathan Doman         });
995491d8ee7SSantosh Puranik }
996491d8ee7SSantosh Puranik 
997491d8ee7SSantosh Puranik /**
998c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
999491d8ee7SSantosh Puranik  *
1000ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
10015e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1002491d8ee7SSantosh Puranik  *
1003491d8ee7SSantosh Puranik  * @return None.
1004491d8ee7SSantosh Puranik  */
1005504af5a0SPatrick Williams inline void getBootOverrideSource(
10065e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10075e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1008491d8ee7SSantosh Puranik {
10095e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
10105e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
10115e7c1f31SOliver Brewka     path /= "boot";
10125e7c1f31SOliver Brewka 
1013deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
10145e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
10151e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
10165e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
10171e1e598dSJonathan Doman                                          const std::string& bootSourceStr) {
1018491d8ee7SSantosh Puranik             if (ec)
1019491d8ee7SSantosh Puranik             {
10208f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
10218f1a35b9SAllen.Wang                 // Boot Override Source information
10228f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
10238f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
10245ef735c8SNan Zhou                 {
10258f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
1026ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
10278f1a35b9SAllen.Wang                 }
1028491d8ee7SSantosh Puranik                 return;
1029491d8ee7SSantosh Puranik             }
1030491d8ee7SSantosh Puranik 
103162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1032491d8ee7SSantosh Puranik 
10331e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
1034491d8ee7SSantosh Puranik             if (!rfSource.empty())
1035491d8ee7SSantosh Puranik             {
1036ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1037ac106bf6SEd Tanous                     rfSource;
1038491d8ee7SSantosh Puranik             }
1039cd9a4666SKonstantin Aladyshev 
1040cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1041cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
10425e7c1f31SOliver Brewka             getBootOverrideMode(asyncResp, computerSystemIndex);
10431e1e598dSJonathan Doman         });
1044491d8ee7SSantosh Puranik }
1045491d8ee7SSantosh Puranik 
1046491d8ee7SSantosh Puranik /**
1047c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1048c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1049c21865c4SKonstantin Aladyshev  * state
1050491d8ee7SSantosh Puranik  *
1051ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
10525e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
10535e7c1f31SOliver Brewka  * @param[in] bootOverrideEnableSetting
1054491d8ee7SSantosh Puranik  *
1055491d8ee7SSantosh Puranik  * @return None.
1056491d8ee7SSantosh Puranik  */
1057491d8ee7SSantosh Puranik 
1058ac106bf6SEd Tanous inline void processBootOverrideEnable(
1059ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10605e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const bool bootOverrideEnableSetting)
1061c21865c4SKonstantin Aladyshev {
1062c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1063c21865c4SKonstantin Aladyshev     {
1064ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1065ac106bf6SEd Tanous             "Disabled";
1066c21865c4SKonstantin Aladyshev         return;
1067c21865c4SKonstantin Aladyshev     }
1068c21865c4SKonstantin Aladyshev 
10695e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
10705e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
10715e7c1f31SOliver Brewka     path /= "boot";
10725e7c1f31SOliver Brewka     path /= "one_time";
10735e7c1f31SOliver Brewka 
1074c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1075c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1076deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
10775e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
10781e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1079ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1080491d8ee7SSantosh Puranik             if (ec)
1081491d8ee7SSantosh Puranik             {
1082b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1083ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1084491d8ee7SSantosh Puranik                 return;
1085491d8ee7SSantosh Puranik             }
1086491d8ee7SSantosh Puranik 
1087c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1088c21865c4SKonstantin Aladyshev             {
1089ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1090ac106bf6SEd Tanous                     "Once";
1091c21865c4SKonstantin Aladyshev             }
1092c21865c4SKonstantin Aladyshev             else
1093c21865c4SKonstantin Aladyshev             {
1094ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1095c21865c4SKonstantin Aladyshev                     "Continuous";
1096c21865c4SKonstantin Aladyshev             }
10971e1e598dSJonathan Doman         });
1098491d8ee7SSantosh Puranik }
1099491d8ee7SSantosh Puranik 
1100491d8ee7SSantosh Puranik /**
1101c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1102c21865c4SKonstantin Aladyshev  *
1103ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
11045e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1105c21865c4SKonstantin Aladyshev  *
1106c21865c4SKonstantin Aladyshev  * @return None.
1107c21865c4SKonstantin Aladyshev  */
1108504af5a0SPatrick Williams inline void getBootOverrideEnable(
11095e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11105e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1111c21865c4SKonstantin Aladyshev {
11125e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
11135e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
11145e7c1f31SOliver Brewka     path /= "boot";
11155e7c1f31SOliver Brewka 
1116deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
11175e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
11181e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
11195e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
11201e1e598dSJonathan Doman                                          const bool bootOverrideEnable) {
1121c21865c4SKonstantin Aladyshev             if (ec)
1122c21865c4SKonstantin Aladyshev             {
11238f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
11248f1a35b9SAllen.Wang                 // Boot Override Enable information
11258f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
11268f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
11275ef735c8SNan Zhou                 {
11288f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
1129ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
11308f1a35b9SAllen.Wang                 }
1131c21865c4SKonstantin Aladyshev                 return;
1132c21865c4SKonstantin Aladyshev             }
1133c21865c4SKonstantin Aladyshev 
11345e7c1f31SOliver Brewka             processBootOverrideEnable(asyncResp, computerSystemIndex,
11355e7c1f31SOliver Brewka                                       bootOverrideEnable);
11361e1e598dSJonathan Doman         });
1137c21865c4SKonstantin Aladyshev }
1138c21865c4SKonstantin Aladyshev 
1139c21865c4SKonstantin Aladyshev /**
1140c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1141c21865c4SKonstantin Aladyshev  *
1142ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
11435e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1144c21865c4SKonstantin Aladyshev  *
1145c21865c4SKonstantin Aladyshev  * @return None.
1146c21865c4SKonstantin Aladyshev  */
1147504af5a0SPatrick Williams inline void getBootProperties(
11485e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11495e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1150c21865c4SKonstantin Aladyshev {
115162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1152c21865c4SKonstantin Aladyshev 
11535e7c1f31SOliver Brewka     getBootOverrideSource(asyncResp, computerSystemIndex);
11545e7c1f31SOliver Brewka     getBootOverrideType(asyncResp, computerSystemIndex);
11555e7c1f31SOliver Brewka     getBootOverrideEnable(asyncResp, computerSystemIndex);
1156c21865c4SKonstantin Aladyshev }
1157c21865c4SKonstantin Aladyshev 
1158c21865c4SKonstantin Aladyshev /**
1159c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1160c0557e1aSGunnar Mills  *
1161c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1162c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1163c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1164c0557e1aSGunnar Mills  * last power operation time.
1165c0557e1aSGunnar Mills  *
1166ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1167c0557e1aSGunnar Mills  *
1168c0557e1aSGunnar Mills  * @return None.
1169c0557e1aSGunnar Mills  */
1170504af5a0SPatrick Williams inline void getLastResetTime(
11715e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11725e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1173c0557e1aSGunnar Mills {
117462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1175c0557e1aSGunnar Mills 
1176deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
11775e7c1f31SOliver Brewka         getChassisStateServiceName(computerSystemIndex),
11785e7c1f31SOliver Brewka         getChassisStateObjectPath(computerSystemIndex),
11791e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1180ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1181ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1182c0557e1aSGunnar Mills             if (ec)
1183c0557e1aSGunnar Mills             {
118462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1185c0557e1aSGunnar Mills                 return;
1186c0557e1aSGunnar Mills             }
1187c0557e1aSGunnar Mills 
1188c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1189c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11901e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1191c0557e1aSGunnar Mills 
1192c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1193ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11942b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11951e1e598dSJonathan Doman         });
1196c0557e1aSGunnar Mills }
1197c0557e1aSGunnar Mills 
1198c0557e1aSGunnar Mills /**
1199797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1200797d5daeSCorey Hardesty  *
1201797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1202797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1203797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1204797d5daeSCorey Hardesty  * dbus.
1205797d5daeSCorey Hardesty  *
1206ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12075e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1208797d5daeSCorey Hardesty  *
1209797d5daeSCorey Hardesty  * @return None.
1210797d5daeSCorey Hardesty  */
1211ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
12125e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12135e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1214797d5daeSCorey Hardesty {
121562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1216797d5daeSCorey Hardesty 
1217deae6a78SEd Tanous     dbus::utility::getAllProperties(
12185e7c1f31SOliver Brewka         getHostStateServiceName(computerSystemIndex),
12195e7c1f31SOliver Brewka         getHostStateObjectPath(computerSystemIndex),
1220797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1221ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1222ac106bf6SEd Tanous             const boost::system::error_code& ec,
1223797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1224797d5daeSCorey Hardesty             if (ec)
1225797d5daeSCorey Hardesty             {
1226d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1227d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1228797d5daeSCorey Hardesty                 {
1229d39a8c28SAishwary Joshi                     // Service not available, no error, just don't return
1230d39a8c28SAishwary Joshi                     // RebootAttempts information
123162598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1232ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1233797d5daeSCorey Hardesty                 }
1234797d5daeSCorey Hardesty                 return;
1235797d5daeSCorey Hardesty             }
1236797d5daeSCorey Hardesty 
1237797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1238797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1239797d5daeSCorey Hardesty 
1240797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1241bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1242bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1243797d5daeSCorey Hardesty 
1244797d5daeSCorey Hardesty             if (!success)
1245797d5daeSCorey Hardesty             {
1246ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1247797d5daeSCorey Hardesty                 return;
1248797d5daeSCorey Hardesty             }
1249797d5daeSCorey Hardesty 
1250797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1251797d5daeSCorey Hardesty             {
1252ac106bf6SEd Tanous                 asyncResp->res
1253ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1254797d5daeSCorey Hardesty                     *attemptsLeft;
1255797d5daeSCorey Hardesty             }
1256797d5daeSCorey Hardesty 
1257797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1258797d5daeSCorey Hardesty             {
1259ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1260797d5daeSCorey Hardesty                     *retryAttempts;
1261797d5daeSCorey Hardesty             }
1262797d5daeSCorey Hardesty         });
1263797d5daeSCorey Hardesty }
1264797d5daeSCorey Hardesty 
1265797d5daeSCorey Hardesty /**
12666bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12676bd5a8d2SGunnar Mills  *
1268ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12695e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
12706bd5a8d2SGunnar Mills  *
12716bd5a8d2SGunnar Mills  * @return None.
12726bd5a8d2SGunnar Mills  */
1273504af5a0SPatrick Williams inline void getAutomaticRetryPolicy(
12745e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12755e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
12766bd5a8d2SGunnar Mills {
127762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12786bd5a8d2SGunnar Mills 
12795e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
12805e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
12815e7c1f31SOliver Brewka     path /= "auto_reboot";
12825e7c1f31SOliver Brewka 
1283deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
12845e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
12851e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12865e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
1287ac106bf6SEd Tanous                                          bool autoRebootEnabled) {
12886bd5a8d2SGunnar Mills             if (ec)
12896bd5a8d2SGunnar Mills             {
1290d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1291d39a8c28SAishwary Joshi                 // AutoReboot information
1292d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1293d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1294797d5daeSCorey Hardesty                 {
129562598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1296ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1297797d5daeSCorey Hardesty                 }
12986bd5a8d2SGunnar Mills                 return;
12996bd5a8d2SGunnar Mills             }
13006bd5a8d2SGunnar Mills 
130162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1302e05aec50SEd Tanous             if (autoRebootEnabled)
13036bd5a8d2SGunnar Mills             {
1304ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13056bd5a8d2SGunnar Mills                     "RetryAttempts";
13066bd5a8d2SGunnar Mills             }
13076bd5a8d2SGunnar Mills             else
13086bd5a8d2SGunnar Mills             {
1309ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1310ac106bf6SEd Tanous                     "Disabled";
13116bd5a8d2SGunnar Mills             }
13125e7c1f31SOliver Brewka             getAutomaticRebootAttempts(asyncResp, computerSystemIndex);
131369f35306SGunnar Mills 
131469f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
131569f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
131669f35306SGunnar Mills             // RetryAttempts.
131720fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
131820fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
131920fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1320ac106bf6SEd Tanous             asyncResp->res
1321bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1322bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
132320fa6a2cSEd Tanous                 std::move(allowed);
13241e1e598dSJonathan Doman         });
13256bd5a8d2SGunnar Mills }
13266bd5a8d2SGunnar Mills 
13276bd5a8d2SGunnar Mills /**
1328797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1329797d5daeSCorey Hardesty  *
1330ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
13315e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1332797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1333797d5daeSCorey Hardesty  *
1334797d5daeSCorey Hardesty  *@return None.
1335797d5daeSCorey Hardesty  */
1336797d5daeSCorey Hardesty 
1337ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1338ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1339*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const uint32_t retryAttempts)
1340797d5daeSCorey Hardesty {
134162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
1342*d43cc6bcSOliver Brewka 
1343*d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/AutomaticRetryAttempts",
1344*d43cc6bcSOliver Brewka                     getHostStateServiceName(computerSystemIndex),
1345*d43cc6bcSOliver Brewka                     getHostStateObjectPath(computerSystemIndex),
1346*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
1347*d43cc6bcSOliver Brewka                     "RetryAttempts", retryAttempts);
1348797d5daeSCorey Hardesty }
1349797d5daeSCorey Hardesty 
13508d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13518d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13528d69c668SEd Tanous {
13538d69c668SEd Tanous     if (value ==
13548d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13558d69c668SEd Tanous     {
13568d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13578d69c668SEd Tanous     }
13588d69c668SEd Tanous     if (value ==
13598d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13608d69c668SEd Tanous     {
13618d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13628d69c668SEd Tanous     }
13638d69c668SEd Tanous     if (value ==
13643a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13658d69c668SEd Tanous     {
13668d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13678d69c668SEd Tanous     }
13688d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13698d69c668SEd Tanous     {
13708d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13718d69c668SEd Tanous     }
13728d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13738d69c668SEd Tanous }
1374797d5daeSCorey Hardesty /**
1375c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1376c6a620f2SGeorge Liu  *
1377ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1378c6a620f2SGeorge Liu  *
1379c6a620f2SGeorge Liu  * @return None.
1380c6a620f2SGeorge Liu  */
1381504af5a0SPatrick Williams inline void getPowerRestorePolicy(
13825e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13835e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1384c6a620f2SGeorge Liu {
138562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1386c6a620f2SGeorge Liu 
13875e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
13885e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
13895e7c1f31SOliver Brewka     path /= "power_restore_policy";
13905e7c1f31SOliver Brewka 
1391deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
13925e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
13931e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1394ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13955e7e2dc5SEd Tanous                     const std::string& policy) {
1396c6a620f2SGeorge Liu             if (ec)
1397c6a620f2SGeorge Liu             {
139862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1399c6a620f2SGeorge Liu                 return;
1400c6a620f2SGeorge Liu             }
14018d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
14028d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
14038d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1404c6a620f2SGeorge Liu             {
1405ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1406c6a620f2SGeorge Liu                 return;
1407c6a620f2SGeorge Liu             }
1408c6a620f2SGeorge Liu 
14098d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14101e1e598dSJonathan Doman         });
1411c6a620f2SGeorge Liu }
1412c6a620f2SGeorge Liu 
1413c6a620f2SGeorge Liu /**
14149dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14159dcfe8c1SAlbert Zhang  *
14169dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14179dcfe8c1SAlbert Zhang  *
14189dcfe8c1SAlbert Zhang  * @return None.
14199dcfe8c1SAlbert Zhang  */
1420504af5a0SPatrick Williams inline void getStopBootOnFault(
1421504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14229dcfe8c1SAlbert Zhang {
142362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
14249dcfe8c1SAlbert Zhang 
1425deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1426deae6a78SEd Tanous         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
14279dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14289dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14299dcfe8c1SAlbert Zhang             if (ec)
14309dcfe8c1SAlbert Zhang             {
1431d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1432d39a8c28SAishwary Joshi                 // StopBootOnFault information
1433d39a8c28SAishwary Joshi                 if (ec.value() != EBADR ||
1434d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
14359dcfe8c1SAlbert Zhang                 {
1436b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
14379dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
14389dcfe8c1SAlbert Zhang                 }
14399dcfe8c1SAlbert Zhang                 return;
14409dcfe8c1SAlbert Zhang             }
14419dcfe8c1SAlbert Zhang 
14429dcfe8c1SAlbert Zhang             if (value)
14439dcfe8c1SAlbert Zhang             {
1444539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1445539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
14469dcfe8c1SAlbert Zhang             }
14479dcfe8c1SAlbert Zhang             else
14489dcfe8c1SAlbert Zhang             {
1449539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1450539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
14519dcfe8c1SAlbert Zhang             }
14529dcfe8c1SAlbert Zhang         });
14539dcfe8c1SAlbert Zhang }
14549dcfe8c1SAlbert Zhang 
14555e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBootCallback(
14565e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14575e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const boost::system::error_code& ec,
14585e7c1f31SOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
14591981771bSAli Ahmed {
14601981771bSAli Ahmed     if (ec)
14611981771bSAli Ahmed     {
14625e7c1f31SOliver Brewka         BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", ec);
14631981771bSAli Ahmed         // This is an optional D-Bus object so just return if
14641981771bSAli Ahmed         // error occurs
14651981771bSAli Ahmed         return;
14661981771bSAli Ahmed     }
146726f6976fSEd Tanous     if (subtree.empty())
14681981771bSAli Ahmed     {
14691981771bSAli Ahmed         // As noted above, this is an optional interface so just return
14701981771bSAli Ahmed         // if there is no instance found
14711981771bSAli Ahmed         return;
14721981771bSAli Ahmed     }
14731981771bSAli Ahmed 
14745e7c1f31SOliver Brewka     std::string path;
14755e7c1f31SOliver Brewka     std::string service;
14765e7c1f31SOliver Brewka 
14775e7c1f31SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14781981771bSAli Ahmed     {
14795e7c1f31SOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
14805e7c1f31SOliver Brewka                                                subtree, path, service))
14815e7c1f31SOliver Brewka         {
14821981771bSAli Ahmed             return;
14831981771bSAli Ahmed         }
14845e7c1f31SOliver Brewka     }
14855e7c1f31SOliver Brewka     else
14865e7c1f31SOliver Brewka     {
14871981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14881981771bSAli Ahmed         // field
14891981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14901981771bSAli Ahmed         {
149162598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1492ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14931981771bSAli Ahmed             return;
14941981771bSAli Ahmed         }
14951981771bSAli Ahmed 
14965e7c1f31SOliver Brewka         path = subtree[0].first;
14975e7c1f31SOliver Brewka         service = subtree[0].second.begin()->first;
14985e7c1f31SOliver Brewka     }
14995e7c1f31SOliver Brewka 
15005e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm service {}", service);
15015e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm path {}", path);
15021981771bSAli Ahmed 
15031981771bSAli Ahmed     // Valid TPM Enable object found, now reading the current value
1504deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
15055e7c1f31SOliver Brewka         service, path, "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
15065e7c1f31SOliver Brewka         [asyncResp](const boost::system::error_code& ec2, bool tpmRequired) {
15078a592810SEd Tanous             if (ec2)
15081981771bSAli Ahmed             {
15095e7c1f31SOliver Brewka                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
15105e7c1f31SOliver Brewka                                  ec2);
1511ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15121981771bSAli Ahmed                 return;
15131981771bSAli Ahmed             }
15141981771bSAli Ahmed 
15151e1e598dSJonathan Doman             if (tpmRequired)
15161981771bSAli Ahmed             {
1517ac106bf6SEd Tanous                 asyncResp->res
1518ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15191981771bSAli Ahmed                     "Required";
15201981771bSAli Ahmed             }
15211981771bSAli Ahmed             else
15221981771bSAli Ahmed             {
1523ac106bf6SEd Tanous                 asyncResp->res
1524ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15251981771bSAli Ahmed                     "Disabled";
15261981771bSAli Ahmed             }
15271e1e598dSJonathan Doman         });
15285e7c1f31SOliver Brewka }
15295e7c1f31SOliver Brewka 
15305e7c1f31SOliver Brewka /**
15315e7c1f31SOliver Brewka  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
15325e7c1f31SOliver Brewka  * TPM is required for booting the host.
15335e7c1f31SOliver Brewka  *
15345e7c1f31SOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
15355e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
15365e7c1f31SOliver Brewka  *
15375e7c1f31SOliver Brewka  * @return None.
15385e7c1f31SOliver Brewka  */
15395e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBoot(
15405e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
15415e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
15425e7c1f31SOliver Brewka {
15435e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
15445e7c1f31SOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
15455e7c1f31SOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
15465e7c1f31SOliver Brewka     dbus::utility::getSubTree(
15475e7c1f31SOliver Brewka         "/", 0, interfaces,
15485e7c1f31SOliver Brewka         std::bind_front(getTrustedModuleRequiredToBootCallback, asyncResp,
15495e7c1f31SOliver Brewka                         computerSystemIndex));
15501981771bSAli Ahmed }
15511981771bSAli Ahmed 
1552*d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBootCallback(
1553*d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1554*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired,
1555*d43cc6bcSOliver Brewka     const boost::system::error_code& ec,
1556*d43cc6bcSOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
15571c05dae3SAli Ahmed {
15581c05dae3SAli Ahmed     if (ec)
15591c05dae3SAli Ahmed     {
1560*d43cc6bcSOliver Brewka         BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", ec);
1561ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15621c05dae3SAli Ahmed         return;
15631c05dae3SAli Ahmed     }
156426f6976fSEd Tanous     if (subtree.empty())
15651c05dae3SAli Ahmed     {
1566*d43cc6bcSOliver Brewka         messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15671c05dae3SAli Ahmed                                          "TrustedModuleRequiredToBoot");
15681c05dae3SAli Ahmed         return;
15691c05dae3SAli Ahmed     }
15701c05dae3SAli Ahmed 
1571*d43cc6bcSOliver Brewka     std::string path;
1572*d43cc6bcSOliver Brewka     std::string serv;
1573*d43cc6bcSOliver Brewka 
1574*d43cc6bcSOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
15751c05dae3SAli Ahmed     {
1576*d43cc6bcSOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
1577*d43cc6bcSOliver Brewka                                                subtree, path, serv))
1578*d43cc6bcSOliver Brewka         {
1579*d43cc6bcSOliver Brewka             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1580ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15811c05dae3SAli Ahmed             return;
15821c05dae3SAli Ahmed         }
1583*d43cc6bcSOliver Brewka     }
1584*d43cc6bcSOliver Brewka     else
1585*d43cc6bcSOliver Brewka     {
15861c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15871c05dae3SAli Ahmed         // field
15881c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15891c05dae3SAli Ahmed         {
159062598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1591ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15921c05dae3SAli Ahmed             return;
15931c05dae3SAli Ahmed         }
15941c05dae3SAli Ahmed 
1595*d43cc6bcSOliver Brewka         path = subtree[0].first;
1596*d43cc6bcSOliver Brewka         serv = subtree[0].second.begin()->first;
1597*d43cc6bcSOliver Brewka     }
15981c05dae3SAli Ahmed 
15991c05dae3SAli Ahmed     if (serv.empty())
16001c05dae3SAli Ahmed     {
160162598e31SEd Tanous         BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1602ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16031c05dae3SAli Ahmed         return;
16041c05dae3SAli Ahmed     }
16051c05dae3SAli Ahmed 
16061c05dae3SAli Ahmed     // Valid TPM Enable object found, now setting the value
1607*d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, path,
1608*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1609*d43cc6bcSOliver Brewka                     tpmRequired);
1610*d43cc6bcSOliver Brewka }
1611*d43cc6bcSOliver Brewka 
1612*d43cc6bcSOliver Brewka /**
1613*d43cc6bcSOliver Brewka  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1614*d43cc6bcSOliver Brewka  * TPM is required for booting the host.
1615*d43cc6bcSOliver Brewka  *
1616*d43cc6bcSOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
1617*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1618*d43cc6bcSOliver Brewka  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
1619*d43cc6bcSOliver Brewka  *
1620*d43cc6bcSOliver Brewka  * @return None.
1621*d43cc6bcSOliver Brewka  */
1622*d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBoot(
1623*d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1624*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired)
1625*d43cc6bcSOliver Brewka {
1626*d43cc6bcSOliver Brewka     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1627*d43cc6bcSOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
1628*d43cc6bcSOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
1629*d43cc6bcSOliver Brewka     dbus::utility::getSubTree(
1630*d43cc6bcSOliver Brewka         "/", 0, interfaces,
1631*d43cc6bcSOliver Brewka         std::bind_front(setTrustedModuleRequiredToBootCallback, asyncResp,
1632*d43cc6bcSOliver Brewka                         computerSystemIndex, tpmRequired));
16331c05dae3SAli Ahmed }
16341c05dae3SAli Ahmed 
16351c05dae3SAli Ahmed /**
1636491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1637491d8ee7SSantosh Puranik  *
1638ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1639*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1640cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1641cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1642cd9a4666SKonstantin Aladyshev  */
1643ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1644*d43cc6bcSOliver Brewka                         const uint64_t computerSystemIndex,
1645cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1646cd9a4666SKonstantin Aladyshev {
1647c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1648cd9a4666SKonstantin Aladyshev 
1649c21865c4SKonstantin Aladyshev     if (!bootType)
1650cd9a4666SKonstantin Aladyshev     {
1651c21865c4SKonstantin Aladyshev         return;
1652c21865c4SKonstantin Aladyshev     }
1653c21865c4SKonstantin Aladyshev 
1654cd9a4666SKonstantin Aladyshev     // Source target specified
165562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1656cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1657cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1658cd9a4666SKonstantin Aladyshev     {
1659cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1660cd9a4666SKonstantin Aladyshev     }
1661cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1662cd9a4666SKonstantin Aladyshev     {
1663cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1664cd9a4666SKonstantin Aladyshev     }
1665cd9a4666SKonstantin Aladyshev     else
1666cd9a4666SKonstantin Aladyshev     {
166762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
166862598e31SEd Tanous                          "BootSourceOverrideMode: {}",
166962598e31SEd Tanous                          *bootType);
1670ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1671cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1672cd9a4666SKonstantin Aladyshev         return;
1673cd9a4666SKonstantin Aladyshev     }
1674cd9a4666SKonstantin Aladyshev 
1675cd9a4666SKonstantin Aladyshev     // Act on validated parameters
167662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1677cd9a4666SKonstantin Aladyshev 
1678*d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1679*d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1680*d43cc6bcSOliver Brewka     path /= "boot";
1681e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1682*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
168387c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1684e93abac6SGinu George                     bootTypeStr);
1685cd9a4666SKonstantin Aladyshev }
1686cd9a4666SKonstantin Aladyshev 
1687cd9a4666SKonstantin Aladyshev /**
1688cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1689cd9a4666SKonstantin Aladyshev  *
1690ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1691ac106bf6SEd Tanous  * message.
1692*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1693c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1694c21865c4SKonstantin Aladyshev  * @return Integer error code.
1695c21865c4SKonstantin Aladyshev  */
1696ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1697*d43cc6bcSOliver Brewka                           const uint64_t computerSystemIndex,
1698c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1699c21865c4SKonstantin Aladyshev {
1700c21865c4SKonstantin Aladyshev     if (!bootEnable)
1701c21865c4SKonstantin Aladyshev     {
1702c21865c4SKonstantin Aladyshev         return;
1703c21865c4SKonstantin Aladyshev     }
1704c21865c4SKonstantin Aladyshev     // Source target specified
170562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1706c21865c4SKonstantin Aladyshev 
1707c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1708c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1709c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1710c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1711c21865c4SKonstantin Aladyshev     {
1712c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1713c21865c4SKonstantin Aladyshev     }
1714c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1715c21865c4SKonstantin Aladyshev     {
1716c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1717c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1718c21865c4SKonstantin Aladyshev     }
1719c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1720c21865c4SKonstantin Aladyshev     {
1721c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1722c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1723c21865c4SKonstantin Aladyshev     }
1724c21865c4SKonstantin Aladyshev     else
1725c21865c4SKonstantin Aladyshev     {
172662598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172762598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
172862598e31SEd Tanous             *bootEnable);
1729ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1730c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1731c21865c4SKonstantin Aladyshev         return;
1732c21865c4SKonstantin Aladyshev     }
1733c21865c4SKonstantin Aladyshev 
1734c21865c4SKonstantin Aladyshev     // Act on validated parameters
173562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1736c21865c4SKonstantin Aladyshev 
1737*d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1738*d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1739*d43cc6bcSOliver Brewka     path /= "boot";
1740e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1741*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
174287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1743e93abac6SGinu George                     bootOverrideEnable);
1744c21865c4SKonstantin Aladyshev 
1745c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1746c21865c4SKonstantin Aladyshev     {
1747c21865c4SKonstantin Aladyshev         return;
1748c21865c4SKonstantin Aladyshev     }
1749c21865c4SKonstantin Aladyshev 
1750c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1751c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
175262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
175362598e31SEd Tanous                      bootOverridePersistent);
1754c21865c4SKonstantin Aladyshev 
1755*d43cc6bcSOliver Brewka     path /= "one_time";
1756e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1757*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
175887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1759e93abac6SGinu George                     !bootOverridePersistent);
1760c21865c4SKonstantin Aladyshev }
1761c21865c4SKonstantin Aladyshev 
1762c21865c4SKonstantin Aladyshev /**
1763c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1764c21865c4SKonstantin Aladyshev  *
1765ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1766*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1767491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1768491d8ee7SSantosh Puranik  *
1769265c1602SJohnathan Mantey  * @return Integer error code.
1770491d8ee7SSantosh Puranik  */
1771504af5a0SPatrick Williams inline void setBootModeOrSource(
1772504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1773*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1774cd9a4666SKonstantin Aladyshev     const std::optional<std::string>& bootSource)
1775491d8ee7SSantosh Puranik {
1776c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1777c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1778944ffaf9SJohnathan Mantey 
1779c21865c4SKonstantin Aladyshev     if (!bootSource)
1780491d8ee7SSantosh Puranik     {
1781c21865c4SKonstantin Aladyshev         return;
1782c21865c4SKonstantin Aladyshev     }
1783c21865c4SKonstantin Aladyshev 
1784491d8ee7SSantosh Puranik     // Source target specified
178562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1786491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1787ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1788ac106bf6SEd Tanous                              bootModeStr) != 0)
1789491d8ee7SSantosh Puranik     {
179062598e31SEd Tanous         BMCWEB_LOG_DEBUG(
179162598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
179262598e31SEd Tanous             *bootSource);
1793ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1794491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1795491d8ee7SSantosh Puranik         return;
1796491d8ee7SSantosh Puranik     }
1797491d8ee7SSantosh Puranik 
1798944ffaf9SJohnathan Mantey     // Act on validated parameters
179962598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
180062598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1801944ffaf9SJohnathan Mantey 
1802*d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1803*d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1804*d43cc6bcSOliver Brewka     path /= "boot";
1805e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1806*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
180787c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1808e93abac6SGinu George                     bootSourceStr);
1809e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1810*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
181187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1812e93abac6SGinu George                     bootModeStr);
1813cd9a4666SKonstantin Aladyshev }
1814944ffaf9SJohnathan Mantey 
1815cd9a4666SKonstantin Aladyshev /**
1816c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1817491d8ee7SSantosh Puranik  *
1818ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1819*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1820491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1821cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1822491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1823491d8ee7SSantosh Puranik  *
1824265c1602SJohnathan Mantey  * @return Integer error code.
1825491d8ee7SSantosh Puranik  */
1826c21865c4SKonstantin Aladyshev 
1827504af5a0SPatrick Williams inline void setBootProperties(
1828504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1829*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1830c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootSource,
1831c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootType,
1832c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootEnable)
1833491d8ee7SSantosh Puranik {
183462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1835491d8ee7SSantosh Puranik 
1836*d43cc6bcSOliver Brewka     setBootModeOrSource(asyncResp, computerSystemIndex, bootSource);
1837*d43cc6bcSOliver Brewka     setBootType(asyncResp, computerSystemIndex, bootType);
1838*d43cc6bcSOliver Brewka     setBootEnable(asyncResp, computerSystemIndex, bootEnable);
1839491d8ee7SSantosh Puranik }
1840491d8ee7SSantosh Puranik 
1841c6a620f2SGeorge Liu /**
184298e386ecSGunnar Mills  * @brief Sets AssetTag
184398e386ecSGunnar Mills  *
1844ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
184598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
184698e386ecSGunnar Mills  *
184798e386ecSGunnar Mills  * @return None.
184898e386ecSGunnar Mills  */
1849ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
185098e386ecSGunnar Mills                         const std::string& assetTag)
185198e386ecSGunnar Mills {
1852e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1853e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1854e99073f5SGeorge Liu     dbus::utility::getSubTree(
1855e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1856ac106bf6SEd Tanous         [asyncResp,
1857e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1858b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
185998e386ecSGunnar Mills             if (ec)
186098e386ecSGunnar Mills             {
186162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1862ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
186398e386ecSGunnar Mills                 return;
186498e386ecSGunnar Mills             }
186526f6976fSEd Tanous             if (subtree.empty())
186698e386ecSGunnar Mills             {
186762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1868ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
186998e386ecSGunnar Mills                 return;
187098e386ecSGunnar Mills             }
187198e386ecSGunnar Mills             // Assume only 1 system D-Bus object
187298e386ecSGunnar Mills             // Throw an error if there is more than 1
187398e386ecSGunnar Mills             if (subtree.size() > 1)
187498e386ecSGunnar Mills             {
187562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1876ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
187798e386ecSGunnar Mills                 return;
187898e386ecSGunnar Mills             }
187998e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
188098e386ecSGunnar Mills             {
188162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1882ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
188398e386ecSGunnar Mills                 return;
188498e386ecSGunnar Mills             }
188598e386ecSGunnar Mills 
188698e386ecSGunnar Mills             const std::string& path = subtree[0].first;
188798e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
188898e386ecSGunnar Mills 
188998e386ecSGunnar Mills             if (service.empty())
189098e386ecSGunnar Mills             {
189162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1892ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
189398e386ecSGunnar Mills                 return;
189498e386ecSGunnar Mills             }
189598e386ecSGunnar Mills 
1896e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
189787c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1898e93abac6SGinu George                             "AssetTag", assetTag);
1899e99073f5SGeorge Liu         });
190098e386ecSGunnar Mills }
190198e386ecSGunnar Mills 
190298e386ecSGunnar Mills /**
19039dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19049dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19059dcfe8c1SAlbert Zhang  *
19069dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19079dcfe8c1SAlbert Zhang  * stopBootOnFault
19089dcfe8c1SAlbert Zhang  *
19099dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19109dcfe8c1SAlbert Zhang  */
1911504af5a0SPatrick Williams inline std::optional<bool> validstopBootOnFault(
1912504af5a0SPatrick Williams     const std::string& stopBootOnFaultString)
19139dcfe8c1SAlbert Zhang {
19149dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19159dcfe8c1SAlbert Zhang     {
19169dcfe8c1SAlbert Zhang         return true;
19179dcfe8c1SAlbert Zhang     }
19189dcfe8c1SAlbert Zhang 
19199dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19209dcfe8c1SAlbert Zhang     {
19219dcfe8c1SAlbert Zhang         return false;
19229dcfe8c1SAlbert Zhang     }
19239dcfe8c1SAlbert Zhang 
19249dcfe8c1SAlbert Zhang     return std::nullopt;
19259dcfe8c1SAlbert Zhang }
19269dcfe8c1SAlbert Zhang 
19279dcfe8c1SAlbert Zhang /**
19289dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19299dcfe8c1SAlbert Zhang  *
1930fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
19319dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19329dcfe8c1SAlbert Zhang  *
19339dcfe8c1SAlbert Zhang  * @return None.
19349dcfe8c1SAlbert Zhang  */
1935504af5a0SPatrick Williams inline void setStopBootOnFault(
1936504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19379dcfe8c1SAlbert Zhang     const std::string& stopBootOnFault)
19389dcfe8c1SAlbert Zhang {
193962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
19409dcfe8c1SAlbert Zhang 
19419dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19429dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19439dcfe8c1SAlbert Zhang     {
194462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
194562598e31SEd Tanous                          stopBootOnFault);
1946fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19479dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19489dcfe8c1SAlbert Zhang         return;
19499dcfe8c1SAlbert Zhang     }
19509dcfe8c1SAlbert Zhang 
1951e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1952e93abac6SGinu George                     "xyz.openbmc_project.Settings",
195387c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
195487c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1955fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1956e93abac6SGinu George                     *stopBootEnabled);
19579dcfe8c1SAlbert Zhang }
19589dcfe8c1SAlbert Zhang 
19599dcfe8c1SAlbert Zhang /**
196069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
196169f35306SGunnar Mills  *
1962ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1963*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
196469f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
196569f35306SGunnar Mills  *
196669f35306SGunnar Mills  * @return None.
196769f35306SGunnar Mills  */
1968504af5a0SPatrick Williams inline void setAutomaticRetry(
1969504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1970*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const std::string& automaticRetryConfig)
197169f35306SGunnar Mills {
197262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
197369f35306SGunnar Mills 
197469f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1975543f4400SEd Tanous     bool autoRebootEnabled = false;
197669f35306SGunnar Mills 
197769f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
197869f35306SGunnar Mills     {
197969f35306SGunnar Mills         autoRebootEnabled = false;
198069f35306SGunnar Mills     }
198169f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
198269f35306SGunnar Mills     {
198369f35306SGunnar Mills         autoRebootEnabled = true;
198469f35306SGunnar Mills     }
198569f35306SGunnar Mills     else
198669f35306SGunnar Mills     {
198762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
198862598e31SEd Tanous                          automaticRetryConfig);
1989ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
199069f35306SGunnar Mills                                          "AutomaticRetryConfig");
199169f35306SGunnar Mills         return;
199269f35306SGunnar Mills     }
199369f35306SGunnar Mills 
1994*d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1995*d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1996*d43cc6bcSOliver Brewka     path /= "auto_reboot";
1997e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1998*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
199987c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
2000e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
200169f35306SGunnar Mills }
200269f35306SGunnar Mills 
20038d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20048d69c668SEd Tanous {
20058d69c668SEd Tanous     if (policy == "AlwaysOn")
20068d69c668SEd Tanous     {
20078d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20088d69c668SEd Tanous     }
20098d69c668SEd Tanous     if (policy == "AlwaysOff")
20108d69c668SEd Tanous     {
20118d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20128d69c668SEd Tanous     }
20138d69c668SEd Tanous     if (policy == "LastState")
20148d69c668SEd Tanous     {
20158d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20168d69c668SEd Tanous     }
20178d69c668SEd Tanous     return "";
20188d69c668SEd Tanous }
20198d69c668SEd Tanous 
202069f35306SGunnar Mills /**
2021c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2022c6a620f2SGeorge Liu  *
2023ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2024*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
2025c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2026c6a620f2SGeorge Liu  *
2027c6a620f2SGeorge Liu  * @return None.
2028c6a620f2SGeorge Liu  */
2029504af5a0SPatrick Williams inline void setPowerRestorePolicy(
2030504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2031*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, std::string_view policy)
2032c6a620f2SGeorge Liu {
203362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2034c6a620f2SGeorge Liu 
20358d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2036c6a620f2SGeorge Liu 
20378d69c668SEd Tanous     if (powerRestorePolicy.empty())
2038c6a620f2SGeorge Liu     {
2039ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20404e69c904SGunnar Mills                                          "PowerRestorePolicy");
2041c6a620f2SGeorge Liu         return;
2042c6a620f2SGeorge Liu     }
2043c6a620f2SGeorge Liu 
2044*d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
2045*d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
2046*d43cc6bcSOliver Brewka     path /= "power_restore_policy";
2047*d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "PowerRestorePolicy",
2048*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
2049*d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Power.RestorePolicy",
2050*d43cc6bcSOliver Brewka                     "PowerRestorePolicy", powerRestorePolicy);
2051c6a620f2SGeorge Liu }
2052c6a620f2SGeorge Liu 
2053a6349918SAppaRao Puli /**
2054a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2055a6349918SAppaRao Puli  *
205625b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
205725b54dbaSEd Tanous  * calls.
2058a6349918SAppaRao Puli  *
2059a6349918SAppaRao Puli  * @return None.
2060a6349918SAppaRao Puli  */
2061504af5a0SPatrick Williams inline void getProvisioningStatus(
2062504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2063a6349918SAppaRao Puli {
206462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2065deae6a78SEd Tanous     dbus::utility::getAllProperties(
2066deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2067deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Attributes",
2068ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2069b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2070b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
2071bd79bce8SPatrick Williams                 asyncResp->res
2072bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2073ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
20741d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
2075bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
2076bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
207750626f4fSJames Feist 
2078a6349918SAppaRao Puli             if (ec)
2079a6349918SAppaRao Puli             {
208062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2081b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
2082539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2083539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2084a6349918SAppaRao Puli                 return;
2085a6349918SAppaRao Puli             }
2086a6349918SAppaRao Puli 
2087a6349918SAppaRao Puli             const bool* provState = nullptr;
2088a6349918SAppaRao Puli             const bool* lockState = nullptr;
2089bc1d29deSKrzysztof Grobelny 
2090bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2091bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
2092bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
2093bc1d29deSKrzysztof Grobelny 
2094bc1d29deSKrzysztof Grobelny             if (!success)
2095a6349918SAppaRao Puli             {
2096ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2097bc1d29deSKrzysztof Grobelny                 return;
2098a6349918SAppaRao Puli             }
2099a6349918SAppaRao Puli 
2100a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2101a6349918SAppaRao Puli             {
210262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2103ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2104a6349918SAppaRao Puli                 return;
2105a6349918SAppaRao Puli             }
2106a6349918SAppaRao Puli 
210725b54dbaSEd Tanous             if (*provState)
2108a6349918SAppaRao Puli             {
210925b54dbaSEd Tanous                 if (*lockState)
2110a6349918SAppaRao Puli                 {
2111539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2112539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2113a6349918SAppaRao Puli                 }
2114a6349918SAppaRao Puli                 else
2115a6349918SAppaRao Puli                 {
2116539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2117539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2118a6349918SAppaRao Puli                 }
2119a6349918SAppaRao Puli             }
2120a6349918SAppaRao Puli             else
2121a6349918SAppaRao Puli             {
2122539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2123539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2124a6349918SAppaRao Puli             }
2125bc1d29deSKrzysztof Grobelny         });
2126a6349918SAppaRao Puli }
2127a6349918SAppaRao Puli 
2128491d8ee7SSantosh Puranik /**
21296b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
21303a2d0424SChris Cain  *
21316b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
21323a2d0424SChris Cain  *
21336b9ac4f2SChris Cain  * @return PowerMode enum
21343a2d0424SChris Cain  */
2135504af5a0SPatrick Williams inline computer_system::PowerMode translatePowerModeString(
2136504af5a0SPatrick Williams     const std::string& modeString)
21373a2d0424SChris Cain {
2138b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2139b6655101SChris Cain 
21406b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21413a2d0424SChris Cain     {
21426b9ac4f2SChris Cain         return PowerMode::Static;
21433a2d0424SChris Cain     }
21446b9ac4f2SChris Cain     if (modeString ==
21450fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21463a2d0424SChris Cain     {
21476b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
21483a2d0424SChris Cain     }
21496b9ac4f2SChris Cain     if (modeString ==
21500fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21513a2d0424SChris Cain     {
21526b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2153b6655101SChris Cain     }
21546b9ac4f2SChris Cain     if (modeString ==
2155b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2156b6655101SChris Cain     {
21576b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2158b6655101SChris Cain     }
21596b9ac4f2SChris Cain     if (modeString ==
2160b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2161b6655101SChris Cain     {
21626b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2163b6655101SChris Cain     }
21646b9ac4f2SChris Cain     if (modeString ==
2165b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2166b6655101SChris Cain     {
21676b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
21683a2d0424SChris Cain     }
21696b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21703a2d0424SChris Cain     {
21716b9ac4f2SChris Cain         return PowerMode::OEM;
21726b9ac4f2SChris Cain     }
21736b9ac4f2SChris Cain     // Any other values would be invalid
21746b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
21756b9ac4f2SChris Cain     return PowerMode::Invalid;
21766b9ac4f2SChris Cain }
21776b9ac4f2SChris Cain 
2178504af5a0SPatrick Williams inline void afterGetPowerMode(
2179504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21806b9ac4f2SChris Cain     const boost::system::error_code& ec,
21816b9ac4f2SChris Cain     const dbus::utility::DBusPropertiesMap& properties)
21826b9ac4f2SChris Cain {
21836b9ac4f2SChris Cain     if (ec)
21846b9ac4f2SChris Cain     {
21856b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
21866b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21876b9ac4f2SChris Cain         return;
21886b9ac4f2SChris Cain     }
21896b9ac4f2SChris Cain 
21906b9ac4f2SChris Cain     std::string powerMode;
21916b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
21926b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
21936b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
21946b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21956b9ac4f2SChris Cain 
21966b9ac4f2SChris Cain     if (!success)
21976b9ac4f2SChris Cain     {
21986b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21996b9ac4f2SChris Cain         return;
22006b9ac4f2SChris Cain     }
22016b9ac4f2SChris Cain 
22026b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
22036b9ac4f2SChris Cain     if (allowedModes == nullptr)
22046b9ac4f2SChris Cain     {
22056b9ac4f2SChris Cain         modeList.emplace_back("Static");
22066b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
22076b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
22083a2d0424SChris Cain     }
22093a2d0424SChris Cain     else
22103a2d0424SChris Cain     {
22116b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
22126b9ac4f2SChris Cain         {
22136b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
22146b9ac4f2SChris Cain                 translatePowerModeString(aMode);
22156b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
22166b9ac4f2SChris Cain             {
2217ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22186b9ac4f2SChris Cain                 continue;
22196b9ac4f2SChris Cain             }
22206b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
22213a2d0424SChris Cain         }
22223a2d0424SChris Cain     }
22236b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
22243a2d0424SChris Cain 
22256b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
22266b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
22276b9ac4f2SChris Cain         translatePowerModeString(powerMode);
22286b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
22296b9ac4f2SChris Cain     {
22306b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
22316b9ac4f2SChris Cain         return;
22326b9ac4f2SChris Cain     }
22336b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
22346b9ac4f2SChris Cain }
22353a2d0424SChris Cain /**
22363a2d0424SChris Cain  * @brief Retrieves system power mode
22373a2d0424SChris Cain  *
2238ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22393a2d0424SChris Cain  *
22403a2d0424SChris Cain  * @return None.
22413a2d0424SChris Cain  */
2242ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22433a2d0424SChris Cain {
224462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22453a2d0424SChris Cain 
22463a2d0424SChris Cain     // Get Power Mode object path:
2247e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2248e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2249e99073f5SGeorge Liu     dbus::utility::getSubTree(
2250e99073f5SGeorge Liu         "/", 0, interfaces,
2251ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2252b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22533a2d0424SChris Cain             if (ec)
22543a2d0424SChris Cain             {
2255bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2256bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
22573a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
22583a2d0424SChris Cain                 // error occurs
22593a2d0424SChris Cain                 return;
22603a2d0424SChris Cain             }
22613a2d0424SChris Cain             if (subtree.empty())
22623a2d0424SChris Cain             {
22633a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
22643a2d0424SChris Cain                 // if there is no instance found
22653a2d0424SChris Cain                 return;
22663a2d0424SChris Cain             }
22673a2d0424SChris Cain             if (subtree.size() > 1)
22683a2d0424SChris Cain             {
22693a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22703a2d0424SChris Cain                 // error
227162598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
227262598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
227362598e31SEd Tanous                     subtree.size());
2274ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22753a2d0424SChris Cain                 return;
22763a2d0424SChris Cain             }
22773a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22783a2d0424SChris Cain             {
227962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2280ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22813a2d0424SChris Cain                 return;
22823a2d0424SChris Cain             }
22833a2d0424SChris Cain             const std::string& path = subtree[0].first;
22843a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22853a2d0424SChris Cain             if (service.empty())
22863a2d0424SChris Cain             {
228762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2288ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22893a2d0424SChris Cain                 return;
22903a2d0424SChris Cain             }
22916b9ac4f2SChris Cain 
22926b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
2293deae6a78SEd Tanous             dbus::utility::getAllProperties(
22941e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
22956b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2296bd79bce8SPatrick Williams                 [asyncResp](
2297bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
22986b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
22996b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
23001e1e598dSJonathan Doman                 });
2301e99073f5SGeorge Liu         });
23023a2d0424SChris Cain }
23033a2d0424SChris Cain 
23043a2d0424SChris Cain /**
23053a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
23063a2d0424SChris Cain  * name associated with that string
23073a2d0424SChris Cain  *
2308ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2309b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
23103a2d0424SChris Cain  *
23113a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
23123a2d0424SChris Cain  */
2313504af5a0SPatrick Williams inline std::string validatePowerMode(
2314504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2315b6655101SChris Cain     const nlohmann::json& modeValue)
23163a2d0424SChris Cain {
2317b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
23183a2d0424SChris Cain     std::string mode;
23193a2d0424SChris Cain 
2320b6655101SChris Cain     if (modeValue == PowerMode::Static)
23213a2d0424SChris Cain     {
23223a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
23233a2d0424SChris Cain     }
2324b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
23253a2d0424SChris Cain     {
23260fda0f12SGeorge Liu         mode =
23270fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23283a2d0424SChris Cain     }
2329b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
23303a2d0424SChris Cain     {
23313a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23323a2d0424SChris Cain     }
2333b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2334b6655101SChris Cain     {
2335b6655101SChris Cain         mode =
2336b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2337b6655101SChris Cain     }
2338b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2339b6655101SChris Cain     {
2340b6655101SChris Cain         mode =
2341b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2342b6655101SChris Cain     }
2343b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2344b6655101SChris Cain     {
2345b6655101SChris Cain         mode =
2346b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2347b6655101SChris Cain     }
23483a2d0424SChris Cain     else
23493a2d0424SChris Cain     {
2350b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2351ac106bf6SEd Tanous                                          "PowerMode");
23523a2d0424SChris Cain     }
23533a2d0424SChris Cain     return mode;
23543a2d0424SChris Cain }
23553a2d0424SChris Cain 
23563a2d0424SChris Cain /**
23573a2d0424SChris Cain  * @brief Sets system power mode.
23583a2d0424SChris Cain  *
2359ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23603a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23613a2d0424SChris Cain  *
23623a2d0424SChris Cain  * @return None.
23633a2d0424SChris Cain  */
2364ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23653a2d0424SChris Cain                          const std::string& pmode)
23663a2d0424SChris Cain {
236762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
23683a2d0424SChris Cain 
2369ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23703a2d0424SChris Cain     if (powerMode.empty())
23713a2d0424SChris Cain     {
23723a2d0424SChris Cain         return;
23733a2d0424SChris Cain     }
23743a2d0424SChris Cain 
23753a2d0424SChris Cain     // Get Power Mode object path:
2376e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2377e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2378e99073f5SGeorge Liu     dbus::utility::getSubTree(
2379e99073f5SGeorge Liu         "/", 0, interfaces,
2380ac106bf6SEd Tanous         [asyncResp,
2381e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2382b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23833a2d0424SChris Cain             if (ec)
23843a2d0424SChris Cain             {
2385bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2386bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
23873a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2388ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23893a2d0424SChris Cain                 return;
23903a2d0424SChris Cain             }
23913a2d0424SChris Cain             if (subtree.empty())
23923a2d0424SChris Cain             {
23933a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2394ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23953a2d0424SChris Cain                                            "PowerMode");
23963a2d0424SChris Cain                 return;
23973a2d0424SChris Cain             }
23983a2d0424SChris Cain             if (subtree.size() > 1)
23993a2d0424SChris Cain             {
24003a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
24013a2d0424SChris Cain                 // error
240262598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
240362598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
240462598e31SEd Tanous                     subtree.size());
2405ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24063a2d0424SChris Cain                 return;
24073a2d0424SChris Cain             }
24083a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
24093a2d0424SChris Cain             {
241062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2411ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24123a2d0424SChris Cain                 return;
24133a2d0424SChris Cain             }
24143a2d0424SChris Cain             const std::string& path = subtree[0].first;
24153a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
24163a2d0424SChris Cain             if (service.empty())
24173a2d0424SChris Cain             {
241862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2419ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24203a2d0424SChris Cain                 return;
24213a2d0424SChris Cain             }
24223a2d0424SChris Cain 
242362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
24243a2d0424SChris Cain 
24253a2d0424SChris Cain             // Set the Power Mode property
2426e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2427bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2428bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2429e99073f5SGeorge Liu         });
24303a2d0424SChris Cain }
24313a2d0424SChris Cain 
24323a2d0424SChris Cain /**
243351709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
243451709ffdSYong Li  *
243551709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
243651709ffdSYong Li  *
243751709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
243851709ffdSYong Li  * translation cannot be done, returns an empty string.
243951709ffdSYong Li  */
244023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
244151709ffdSYong Li {
244251709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
244351709ffdSYong Li     {
244451709ffdSYong Li         return "None";
244551709ffdSYong Li     }
24463174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
244751709ffdSYong Li     {
244851709ffdSYong Li         return "ResetSystem";
244951709ffdSYong Li     }
24503174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
245151709ffdSYong Li     {
245251709ffdSYong Li         return "PowerDown";
245351709ffdSYong Li     }
24543174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
245551709ffdSYong Li     {
245651709ffdSYong Li         return "PowerCycle";
245751709ffdSYong Li     }
245851709ffdSYong Li 
245951709ffdSYong Li     return "";
246051709ffdSYong Li }
246151709ffdSYong Li 
246251709ffdSYong Li /**
2463c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2464c45f0082SYong Li  *
2465c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2466c45f0082SYong Li  *
2467c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2468c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2469c45f0082SYong Li  */
2470c45f0082SYong Li 
247123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2472c45f0082SYong Li {
2473c45f0082SYong Li     if (rfAction == "None")
2474c45f0082SYong Li     {
2475c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2476c45f0082SYong Li     }
24773174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2478c45f0082SYong Li     {
2479c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2480c45f0082SYong Li     }
24813174e4dfSEd Tanous     if (rfAction == "PowerDown")
2482c45f0082SYong Li     {
2483c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2484c45f0082SYong Li     }
24853174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2486c45f0082SYong Li     {
2487c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2488c45f0082SYong Li     }
2489c45f0082SYong Li 
2490c45f0082SYong Li     return "";
2491c45f0082SYong Li }
2492c45f0082SYong Li 
2493c45f0082SYong Li /**
249451709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
249551709ffdSYong Li  *
2496ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
249751709ffdSYong Li  *
249851709ffdSYong Li  * @return None.
249951709ffdSYong Li  */
2500504af5a0SPatrick Williams inline void getHostWatchdogTimer(
2501504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
250251709ffdSYong Li {
250362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2504deae6a78SEd Tanous     dbus::utility::getAllProperties(
2505deae6a78SEd Tanous         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2506bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2507ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2508b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
250951709ffdSYong Li             if (ec)
251051709ffdSYong Li             {
251151709ffdSYong Li                 // watchdog service is stopped
251262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
251351709ffdSYong Li                 return;
251451709ffdSYong Li             }
251551709ffdSYong Li 
251662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
251751709ffdSYong Li 
251851709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2519ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
252051709ffdSYong Li 
252151709ffdSYong Li             // watchdog service is running/enabled
2522539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
252351709ffdSYong Li 
2524bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2525bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
252651709ffdSYong Li 
2527bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2528bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2529bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2530bc1d29deSKrzysztof Grobelny 
2531bc1d29deSKrzysztof Grobelny             if (!success)
253251709ffdSYong Li             {
2533ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2534601af5edSChicago Duan                 return;
253551709ffdSYong Li             }
253651709ffdSYong Li 
2537bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
253851709ffdSYong Li             {
2539bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
254051709ffdSYong Li             }
254151709ffdSYong Li 
2542bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2543bc1d29deSKrzysztof Grobelny             {
2544bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
254551709ffdSYong Li                 if (action.empty())
254651709ffdSYong Li                 {
2547ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2548601af5edSChicago Duan                     return;
254951709ffdSYong Li                 }
255051709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
255151709ffdSYong Li             }
2552bc1d29deSKrzysztof Grobelny         });
255351709ffdSYong Li }
255451709ffdSYong Li 
255551709ffdSYong Li /**
2556c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2557c45f0082SYong Li  *
2558ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2559c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2560c45f0082SYong Li  *                       RF request.
2561c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2562c45f0082SYong Li  *
2563c45f0082SYong Li  * @return None.
2564c45f0082SYong Li  */
2565504af5a0SPatrick Williams inline void setWDTProperties(
2566504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2567c45f0082SYong Li     const std::optional<bool> wdtEnable,
2568c45f0082SYong Li     const std::optional<std::string>& wdtTimeOutAction)
2569c45f0082SYong Li {
257062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2571c45f0082SYong Li 
2572c45f0082SYong Li     if (wdtTimeOutAction)
2573c45f0082SYong Li     {
2574c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2575c45f0082SYong Li         // check if TimeOut Action is Valid
2576c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2577c45f0082SYong Li         {
257862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
257962598e31SEd Tanous                              *wdtTimeOutAction);
2580ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2581c45f0082SYong Li                                              "TimeoutAction");
2582c45f0082SYong Li             return;
2583c45f0082SYong Li         }
2584c45f0082SYong Li 
2585e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2586e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
258787c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
258887c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
25899ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2590e93abac6SGinu George                         wdtTimeOutActStr);
2591c45f0082SYong Li     }
2592c45f0082SYong Li 
2593c45f0082SYong Li     if (wdtEnable)
2594c45f0082SYong Li     {
2595e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2596e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
259787c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
259887c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
259987c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2600e93abac6SGinu George                         *wdtEnable);
2601c45f0082SYong Li     }
2602c45f0082SYong Li }
2603c45f0082SYong Li 
260437bbf98cSChris Cain /**
260537bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
260637bbf98cSChris Cain  *
2607ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
260837bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
260937bbf98cSChris Cain  *
261037bbf98cSChris Cain  * @return true if successful
261137bbf98cSChris Cain  */
2612504af5a0SPatrick Williams inline bool parseIpsProperties(
2613504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26141e5b7c88SJiaqing Zhao     const dbus::utility::DBusPropertiesMap& properties)
261537bbf98cSChris Cain {
2616bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2617bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2618bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2619bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2620bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2621bc1d29deSKrzysztof Grobelny 
2622bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2623bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26242661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26252661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26262661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2627bc1d29deSKrzysztof Grobelny 
2628bc1d29deSKrzysztof Grobelny     if (!success)
262937bbf98cSChris Cain     {
263037bbf98cSChris Cain         return false;
263137bbf98cSChris Cain     }
2632bc1d29deSKrzysztof Grobelny 
2633bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
263437bbf98cSChris Cain     {
2635ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
263637bbf98cSChris Cain     }
2637bc1d29deSKrzysztof Grobelny 
2638bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
263937bbf98cSChris Cain     {
2640ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2641bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
264237bbf98cSChris Cain     }
2643bc1d29deSKrzysztof Grobelny 
2644bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2645bc1d29deSKrzysztof Grobelny     {
2646bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2647ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
264837bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
264937bbf98cSChris Cain                 .count();
265037bbf98cSChris Cain     }
2651bc1d29deSKrzysztof Grobelny 
2652bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
265337bbf98cSChris Cain     {
2654ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2655bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
265637bbf98cSChris Cain     }
2657bc1d29deSKrzysztof Grobelny 
2658bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
265937bbf98cSChris Cain     {
2660bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2661ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
266237bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
266337bbf98cSChris Cain                 .count();
266437bbf98cSChris Cain     }
266537bbf98cSChris Cain 
266637bbf98cSChris Cain     return true;
266737bbf98cSChris Cain }
266837bbf98cSChris Cain 
266937bbf98cSChris Cain /**
26705e7c1f31SOliver Brewka  * @brief Retrieves idle power saver properties over DBUS
267137bbf98cSChris Cain  *
2672ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
267337bbf98cSChris Cain  *
267437bbf98cSChris Cain  * @return None.
267537bbf98cSChris Cain  */
2676504af5a0SPatrick Williams inline void getIdlePowerSaver(
2677504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
267837bbf98cSChris Cain {
267962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
268037bbf98cSChris Cain 
268137bbf98cSChris Cain     // Get IdlePowerSaver object path:
2682e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2683e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2684e99073f5SGeorge Liu     dbus::utility::getSubTree(
2685e99073f5SGeorge Liu         "/", 0, interfaces,
2686ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2687b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
268837bbf98cSChris Cain             if (ec)
268937bbf98cSChris Cain             {
2690b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
269162598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
269262598e31SEd Tanous                     ec);
2693ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
269437bbf98cSChris Cain                 return;
269537bbf98cSChris Cain             }
269637bbf98cSChris Cain             if (subtree.empty())
269737bbf98cSChris Cain             {
269837bbf98cSChris Cain                 // This is an optional interface so just return
269937bbf98cSChris Cain                 // if there is no instance found
270062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
270137bbf98cSChris Cain                 return;
270237bbf98cSChris Cain             }
270337bbf98cSChris Cain             if (subtree.size() > 1)
270437bbf98cSChris Cain             {
270537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
270637bbf98cSChris Cain                 // is an error
27075e7c1f31SOliver Brewka                 BMCWEB_LOG_DEBUG(
27085e7c1f31SOliver Brewka                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
270962598e31SEd Tanous                     subtree.size());
2710ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271137bbf98cSChris Cain                 return;
271237bbf98cSChris Cain             }
271337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
271437bbf98cSChris Cain             {
271562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2716ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271737bbf98cSChris Cain                 return;
271837bbf98cSChris Cain             }
271937bbf98cSChris Cain             const std::string& path = subtree[0].first;
272037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
272137bbf98cSChris Cain             if (service.empty())
272237bbf98cSChris Cain             {
272362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2724ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272537bbf98cSChris Cain                 return;
272637bbf98cSChris Cain             }
272737bbf98cSChris Cain 
272837bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2729deae6a78SEd Tanous             dbus::utility::getAllProperties(
2730bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2731bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2732bd79bce8SPatrick Williams                 [asyncResp](
2733bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
27341e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
27358a592810SEd Tanous                     if (ec2)
273637bbf98cSChris Cain                     {
273762598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2738bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2739bd79bce8SPatrick Williams                             ec2);
2740ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
274137bbf98cSChris Cain                         return;
274237bbf98cSChris Cain                     }
274337bbf98cSChris Cain 
2744ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
274537bbf98cSChris Cain                     {
2746ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
274737bbf98cSChris Cain                         return;
274837bbf98cSChris Cain                     }
2749bc1d29deSKrzysztof Grobelny                 });
2750e99073f5SGeorge Liu         });
275137bbf98cSChris Cain 
275262598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
275337bbf98cSChris Cain }
275437bbf98cSChris Cain 
275537bbf98cSChris Cain /**
275637bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
275737bbf98cSChris Cain  *
2758ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
275937bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
276037bbf98cSChris Cain  *                       RF request.
276137bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
276237bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
276337bbf98cSChris Cain  * before entering idle state.
276437bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
276537bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
276637bbf98cSChris Cain  * before exiting idle state
276737bbf98cSChris Cain  *
276837bbf98cSChris Cain  * @return None.
276937bbf98cSChris Cain  */
2770bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2771bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
277237bbf98cSChris Cain     const std::optional<bool> ipsEnable,
277337bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
277437bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
277537bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
277637bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
277737bbf98cSChris Cain {
277862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
277937bbf98cSChris Cain 
278037bbf98cSChris Cain     // Get IdlePowerSaver object path:
2781e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2782e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2783e99073f5SGeorge Liu     dbus::utility::getSubTree(
2784e99073f5SGeorge Liu         "/", 0, interfaces,
2785ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2786e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2787b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
278837bbf98cSChris Cain             if (ec)
278937bbf98cSChris Cain             {
2790b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
279162598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
279262598e31SEd Tanous                     ec);
2793ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
279437bbf98cSChris Cain                 return;
279537bbf98cSChris Cain             }
279637bbf98cSChris Cain             if (subtree.empty())
279737bbf98cSChris Cain             {
279837bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2799ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
280037bbf98cSChris Cain                                            "IdlePowerSaver");
280137bbf98cSChris Cain                 return;
280237bbf98cSChris Cain             }
280337bbf98cSChris Cain             if (subtree.size() > 1)
280437bbf98cSChris Cain             {
280537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
280637bbf98cSChris Cain                 // is an error
280762598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
280862598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
280962598e31SEd Tanous                     subtree.size());
2810ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
281137bbf98cSChris Cain                 return;
281237bbf98cSChris Cain             }
281337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
281437bbf98cSChris Cain             {
281562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2816ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
281737bbf98cSChris Cain                 return;
281837bbf98cSChris Cain             }
281937bbf98cSChris Cain             const std::string& path = subtree[0].first;
282037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
282137bbf98cSChris Cain             if (service.empty())
282237bbf98cSChris Cain             {
282362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2824ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
282537bbf98cSChris Cain                 return;
282637bbf98cSChris Cain             }
282737bbf98cSChris Cain 
282837bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
282937bbf98cSChris Cain             // need to be updated
283037bbf98cSChris Cain 
283137bbf98cSChris Cain             if (ipsEnable)
283237bbf98cSChris Cain             {
2833bd79bce8SPatrick Williams                 setDbusProperty(
2834bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
283587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2836e93abac6SGinu George                     "Enabled", *ipsEnable);
283737bbf98cSChris Cain             }
283837bbf98cSChris Cain             if (ipsEnterUtil)
283937bbf98cSChris Cain             {
2840bd79bce8SPatrick Williams                 setDbusProperty(
2841bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2842e93abac6SGinu George                     service, path,
28439ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2844e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
284537bbf98cSChris Cain             }
284637bbf98cSChris Cain             if (ipsEnterTime)
284737bbf98cSChris Cain             {
284837bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
284937bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2850bd79bce8SPatrick Williams                 setDbusProperty(
2851bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2852bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2853e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
285437bbf98cSChris Cain             }
285537bbf98cSChris Cain             if (ipsExitUtil)
285637bbf98cSChris Cain             {
2857bd79bce8SPatrick Williams                 setDbusProperty(
2858bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2859bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2860e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
286137bbf98cSChris Cain             }
286237bbf98cSChris Cain             if (ipsExitTime)
286337bbf98cSChris Cain             {
286437bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
286537bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2866bd79bce8SPatrick Williams                 setDbusProperty(
2867bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2868bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2869e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
287037bbf98cSChris Cain             }
2871e99073f5SGeorge Liu         });
287237bbf98cSChris Cain 
287362598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
287437bbf98cSChris Cain }
287537bbf98cSChris Cain 
2876c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2877dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2878dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2879dd60b9edSEd Tanous {
2880dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2881dd60b9edSEd Tanous     {
2882dd60b9edSEd Tanous         return;
2883dd60b9edSEd Tanous     }
2884dd60b9edSEd Tanous     asyncResp->res.addHeader(
2885dd60b9edSEd Tanous         boost::beast::http::field::link,
2886dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2887dd60b9edSEd Tanous }
2888dd60b9edSEd Tanous 
2889c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2890c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2891c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28921abe55efSEd Tanous {
28933ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2894f4c99e70SEd Tanous     {
2895f4c99e70SEd Tanous         return;
2896f4c99e70SEd Tanous     }
2897dd60b9edSEd Tanous 
2898dd60b9edSEd Tanous     asyncResp->res.addHeader(
2899dd60b9edSEd Tanous         boost::beast::http::field::link,
2900dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29018d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29020f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29038d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29048d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2905462023adSSunitha Harish 
2906fc5ae94dSOliver Brewka     getSystemCollectionMembers(asyncResp);
2907c1e219d5SEd Tanous }
2908c1e219d5SEd Tanous 
2909c1e219d5SEd Tanous /**
29107e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
29117e860f15SJohn Edward Broadbent  */
29124f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29137e860f15SJohn Edward Broadbent {
291489492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
291589492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
291689492a15SPatrick Williams     constexpr const char* interfaceName =
29177e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
291889492a15SPatrick Williams     constexpr const char* method = "NMI";
29197e860f15SJohn Edward Broadbent 
2920177612aaSEd Tanous     dbus::utility::async_method_call(
2921177612aaSEd Tanous         asyncResp,
29225e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
29237e860f15SJohn Edward Broadbent             if (ec)
29247e860f15SJohn Edward Broadbent             {
292562598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
29267e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
29277e860f15SJohn Edward Broadbent                 return;
29287e860f15SJohn Edward Broadbent             }
29297e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
29307e860f15SJohn Edward Broadbent         },
29317e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29327e860f15SJohn Edward Broadbent }
2933c5b2abe0SLewanczyk, Dawid 
2934c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2935c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
29367f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2937c1e219d5SEd Tanous     const std::string& systemName)
2938c1e219d5SEd Tanous {
29393ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
294045ca1b86SEd Tanous     {
294145ca1b86SEd Tanous         return;
294245ca1b86SEd Tanous     }
2943dd7090e6SGunnar Mills 
2944dd7090e6SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2945dd7090e6SGunnar Mills     {
2946dd7090e6SGunnar Mills         if (systemName == "hypervisor")
2947dd7090e6SGunnar Mills         {
2948dd7090e6SGunnar Mills             handleHypervisorSystemResetPost(req, asyncResp);
2949dd7090e6SGunnar Mills             return;
2950dd7090e6SGunnar Mills         }
2951dd7090e6SGunnar Mills     }
2952dd7090e6SGunnar Mills 
2953253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2954c1e219d5SEd Tanous     {
2955c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2956c1e219d5SEd Tanous                                    systemName);
2957c1e219d5SEd Tanous         return;
2958c1e219d5SEd Tanous     }
295925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
29607f3e84a1SEd Tanous     {
29617f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29627f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2963c1e219d5SEd Tanous                                    systemName);
29647f3e84a1SEd Tanous         return;
29657f3e84a1SEd Tanous     }
29669712f8acSEd Tanous     std::string resetType;
2967c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2968cc340dd9SEd Tanous     {
2969cc340dd9SEd Tanous         return;
2970cc340dd9SEd Tanous     }
2971cc340dd9SEd Tanous 
2972d22c8396SJason M. Bills     // Get the command and host vs. chassis
2973cc340dd9SEd Tanous     std::string command;
2974543f4400SEd Tanous     bool hostCommand = true;
2975d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2976cc340dd9SEd Tanous     {
2977cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2978d22c8396SJason M. Bills         hostCommand = true;
2979d22c8396SJason M. Bills     }
2980d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2981d22c8396SJason M. Bills     {
2982d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2983d22c8396SJason M. Bills         hostCommand = false;
2984d22c8396SJason M. Bills     }
2985d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2986d22c8396SJason M. Bills     {
2987c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
298886a0851aSJason M. Bills         hostCommand = true;
2989cc340dd9SEd Tanous     }
29909712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2991cc340dd9SEd Tanous     {
2992cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2993d22c8396SJason M. Bills         hostCommand = true;
2994cc340dd9SEd Tanous     }
29959712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2996cc340dd9SEd Tanous     {
29970fda0f12SGeorge Liu         command =
29980fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2999d22c8396SJason M. Bills         hostCommand = true;
3000d22c8396SJason M. Bills     }
3001d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3002d22c8396SJason M. Bills     {
300386a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
300486a0851aSJason M. Bills         hostCommand = true;
3005cc340dd9SEd Tanous     }
3006bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3007bfd5b826SLakshminarayana R. Kammath     {
3008bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3009bfd5b826SLakshminarayana R. Kammath         return;
3010bfd5b826SLakshminarayana R. Kammath     }
3011cc340dd9SEd Tanous     else
3012cc340dd9SEd Tanous     {
3013c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3014cc340dd9SEd Tanous         return;
3015cc340dd9SEd Tanous     }
3016d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
3017cc340dd9SEd Tanous 
3018d22c8396SJason M. Bills     if (hostCommand)
3019d22c8396SJason M. Bills     {
3020e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
3021d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
3022e93abac6SGinu George                         "RequestedHostTransition", command);
3023cc340dd9SEd Tanous     }
3024d22c8396SJason M. Bills     else
3025d22c8396SJason M. Bills     {
3026e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
3027d02aad39SEd Tanous                         statePath / "chassis0",
3028d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
3029e93abac6SGinu George                         "RequestedPowerTransition", command);
3030d22c8396SJason M. Bills     }
3031d22c8396SJason M. Bills }
3032cc340dd9SEd Tanous 
3033c1e219d5SEd Tanous inline void handleComputerSystemHead(
3034dd60b9edSEd Tanous     App& app, const crow::Request& req,
30357f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30367f3e84a1SEd Tanous     const std::string& /*systemName*/)
3037dd60b9edSEd Tanous {
3038dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3039dd60b9edSEd Tanous     {
3040dd60b9edSEd Tanous         return;
3041dd60b9edSEd Tanous     }
3042dd60b9edSEd Tanous 
3043dd60b9edSEd Tanous     asyncResp->res.addHeader(
3044dd60b9edSEd Tanous         boost::beast::http::field::link,
3045dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3046dd60b9edSEd Tanous }
3047dd60b9edSEd Tanous 
30485c3e9272SAbhishek Patel inline void afterPortRequest(
30495c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30505c3e9272SAbhishek Patel     const boost::system::error_code& ec,
30515c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
30525c3e9272SAbhishek Patel {
30535c3e9272SAbhishek Patel     if (ec)
30545c3e9272SAbhishek Patel     {
3055b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
30565c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
30575c3e9272SAbhishek Patel         return;
30585c3e9272SAbhishek Patel     }
30595c3e9272SAbhishek Patel     for (const auto& data : socketData)
30605c3e9272SAbhishek Patel     {
30615c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
30625c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
30635c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
30645c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
30655c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
30665c3e9272SAbhishek Patel         // need to retrieve port number for
30675c3e9272SAbhishek Patel         // obmc-console-ssh service
30685c3e9272SAbhishek Patel         if (protocolName == "SSH")
30695c3e9272SAbhishek Patel         {
30705c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
307181c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30725c3e9272SAbhishek Patel                                           int portNumber) {
30735c3e9272SAbhishek Patel                 if (ec1)
30745c3e9272SAbhishek Patel                 {
3075b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
30765c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30775c3e9272SAbhishek Patel                     return;
30785c3e9272SAbhishek Patel                 }
30795c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30805c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30815c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30825c3e9272SAbhishek Patel             });
30835c3e9272SAbhishek Patel         }
30845c3e9272SAbhishek Patel     }
30855c3e9272SAbhishek Patel }
3086c1e219d5SEd Tanous 
30875e7c1f31SOliver Brewka /**
30885e7c1f31SOliver Brewka  * @brief process the GET request after getting the computerSystemIndex
30895e7c1f31SOliver Brewka  *
30905e7c1f31SOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
30915e7c1f31SOliver Brewka  *                                calls
30925e7c1f31SOliver Brewka  * @param[in] systemName          Name of the requested system
30935e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
30945e7c1f31SOliver Brewka  *
30955e7c1f31SOliver Brewka  * @return None
30965e7c1f31SOliver Brewka  */
30975e7c1f31SOliver Brewka inline void processComputerSystemGet(
309822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30995e7c1f31SOliver Brewka     const std::string& systemName, const uint64_t computerSystemIndex)
3100c1e219d5SEd Tanous {
3101dd60b9edSEd Tanous     asyncResp->res.addHeader(
3102dd60b9edSEd Tanous         boost::beast::http::field::link,
3103dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
31048d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3105b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
31065e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Name"] = systemName;
31075e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Id"] = systemName;
3108539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3109539d8c6bSEd Tanous         computer_system::SystemType::Physical;
31108d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
31118d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3112cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3113dfb2b408SPriyanga Ramasamy         double(0);
31145e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] =
31155e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}", systemName);
311604a258f4SEd Tanous 
31175e7c1f31SOliver Brewka     // Currently not supported on multi-host. TBD
31185e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31195e7c1f31SOliver Brewka     {
31205e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
31215e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Bios", systemName);
31225e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
31235e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Processors",
31245e7c1f31SOliver Brewka                                 systemName);
31255e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
31265e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Memory", systemName);
31275e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
31285e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Storage", systemName);
31293179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3130253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
31315e7c1f31SOliver Brewka                                 systemName);
31325e7c1f31SOliver Brewka     }
3133029573d4SEd Tanous 
3134002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3135253f11b8SEd Tanous         boost::urls::format(
31365e7c1f31SOliver Brewka             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", systemName);
3137c1e219d5SEd Tanous     asyncResp->res
3138c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3139253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
31405e7c1f31SOliver Brewka                             systemName);
3141c5b2abe0SLewanczyk, Dawid 
31425e7c1f31SOliver Brewka     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
31435e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}/LogServices", systemName);
3144c4bf6374SJason M. Bills 
31451476687dSEd Tanous     nlohmann::json::array_t managedBy;
31461476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3147253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3148253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3149002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3150539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3151539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
31520e8ac5e7SGunnar Mills 
31530e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3154002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3155c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
31561476687dSEd Tanous 
3157c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
31581476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3159c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31601476687dSEd Tanous         "Press ~. to exit console";
31615c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31625c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31630e8ac5e7SGunnar Mills 
316425b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
316525b54dbaSEd Tanous     {
31660e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3167002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
316825b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
316925b54dbaSEd Tanous             4;
3170613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3171613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
317225b54dbaSEd Tanous     }
317313451e39SWilly Tu 
31742eaa9279SJanet Adkins     systems_utils::getValidSystemsPath(
31752eaa9279SJanet Adkins         asyncResp, systemName,
31762eaa9279SJanet Adkins         [asyncResp,
31772eaa9279SJanet Adkins          systemName](const std::optional<std::string>& validSystemsPath) {
31782eaa9279SJanet Adkins             if (validSystemsPath)
31792eaa9279SJanet Adkins             {
31802eaa9279SJanet Adkins                 getLocationIndicatorActive(asyncResp, *validSystemsPath);
31812eaa9279SJanet Adkins             }
31822eaa9279SJanet Adkins         });
31832eaa9279SJanet Adkins 
3184f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3185f664fd8aSJanet Adkins     {
3186a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
3187f664fd8aSJanet Adkins     }
3188f664fd8aSJanet Adkins 
31895e7c1f31SOliver Brewka     // Currently not supported on multi-host.
31905e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31915e7c1f31SOliver Brewka     {
319251bd2d8aSGunnar Mills         getComputerSystem(asyncResp);
31935e7c1f31SOliver Brewka         // Todo: chassis matching could be handled by patch
31945e7c1f31SOliver Brewka         // https://gerrit.openbmc.org/c/openbmc/bmcweb/+/60793
31955e7c1f31SOliver Brewka         getMainChassisId(
31965e7c1f31SOliver Brewka             asyncResp, [](const std::string& chassisId,
31975e7c1f31SOliver Brewka                           const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
31985e7c1f31SOliver Brewka                 nlohmann::json::array_t chassisArray;
31995e7c1f31SOliver Brewka                 nlohmann::json& chassis = chassisArray.emplace_back();
32005e7c1f31SOliver Brewka                 chassis["@odata.id"] =
32015e7c1f31SOliver Brewka                     boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
32025e7c1f31SOliver Brewka                 aRsp->res.jsonValue["Links"]["Chassis"] =
32035e7c1f31SOliver Brewka                     std::move(chassisArray);
32045e7c1f31SOliver Brewka             });
32055e7c1f31SOliver Brewka 
32065e7c1f31SOliver Brewka         pcie_util::getPCIeDeviceList(
32075e7c1f31SOliver Brewka             asyncResp, nlohmann::json::json_pointer("/PCIeDevices"));
32085e7c1f31SOliver Brewka     }
32095e7c1f31SOliver Brewka     getHostState(asyncResp, computerSystemIndex);
32105e7c1f31SOliver Brewka     getBootProperties(asyncResp, computerSystemIndex);
32115e7c1f31SOliver Brewka     getBootProgress(asyncResp, computerSystemIndex);
32125e7c1f31SOliver Brewka     getBootProgressLastStateTime(asyncResp, computerSystemIndex);
321351709ffdSYong Li     getHostWatchdogTimer(asyncResp);
32145e7c1f31SOliver Brewka     getPowerRestorePolicy(asyncResp, computerSystemIndex);
32159dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
32165e7c1f31SOliver Brewka     getAutomaticRetryPolicy(asyncResp, computerSystemIndex);
32175e7c1f31SOliver Brewka     getLastResetTime(asyncResp, computerSystemIndex);
321825b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
321925b54dbaSEd Tanous     {
3220a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
322125b54dbaSEd Tanous     }
32225e7c1f31SOliver Brewka     getTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex);
32233a2d0424SChris Cain     getPowerMode(asyncResp);
322437bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3225c1e219d5SEd Tanous }
3226550a6bf8SJiaqing Zhao 
32275e7c1f31SOliver Brewka inline void handleComputerSystemGet(
32285e7c1f31SOliver Brewka     crow::App& app, const crow::Request& req,
32295e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32305e7c1f31SOliver Brewka     const std::string& systemName)
32315e7c1f31SOliver Brewka {
32325e7c1f31SOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
32335e7c1f31SOliver Brewka     {
32345e7c1f31SOliver Brewka         return;
32355e7c1f31SOliver Brewka     }
32365e7c1f31SOliver Brewka 
32375e7c1f31SOliver Brewka     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
32385e7c1f31SOliver Brewka     {
32395e7c1f31SOliver Brewka         if (systemName == "hypervisor")
32405e7c1f31SOliver Brewka         {
32415e7c1f31SOliver Brewka             handleHypervisorSystemGet(asyncResp);
32425e7c1f31SOliver Brewka             return;
32435e7c1f31SOliver Brewka         }
32445e7c1f31SOliver Brewka     }
32455e7c1f31SOliver Brewka 
32465e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
32475e7c1f31SOliver Brewka     {
32485e7c1f31SOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
32495e7c1f31SOliver Brewka         {
32505e7c1f31SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32515e7c1f31SOliver Brewka                                        systemName);
32525e7c1f31SOliver Brewka             return;
32535e7c1f31SOliver Brewka         }
32545e7c1f31SOliver Brewka     }
32555e7c1f31SOliver Brewka 
32565e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("requested system = {}", systemName);
32575e7c1f31SOliver Brewka     getComputerSystemIndex(
32585e7c1f31SOliver Brewka         asyncResp, systemName,
32595e7c1f31SOliver Brewka         std::bind_front(processComputerSystemGet, asyncResp, systemName));
32605e7c1f31SOliver Brewka }
32615e7c1f31SOliver Brewka 
3262*d43cc6bcSOliver Brewka struct PatchParams
3263c1e219d5SEd Tanous {
32649f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3265cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
326698e386ecSGunnar Mills     std::optional<std::string> assetTag;
3267c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
32683a2d0424SChris Cain     std::optional<std::string> powerMode;
3269550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3270550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3271550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3272550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3273550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3274550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3275797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3276550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
32779dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3278550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3279550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3280550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3281550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3282550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3283*d43cc6bcSOliver Brewka };
3284550a6bf8SJiaqing Zhao 
3285*d43cc6bcSOliver Brewka /**
3286*d43cc6bcSOliver Brewka  * @brief process the POST request after getting the computerSystemIndex
3287*d43cc6bcSOliver Brewka  *
3288*d43cc6bcSOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
3289*d43cc6bcSOliver Brewka  *                                calls
3290*d43cc6bcSOliver Brewka  * @param[in] patchParams         Struct containing the property we want to
3291*d43cc6bcSOliver Brewka  *                                patch
3292*d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
3293*d43cc6bcSOliver Brewka  *
3294*d43cc6bcSOliver Brewka  * @return None
3295*d43cc6bcSOliver Brewka  */
3296*d43cc6bcSOliver Brewka 
3297*d43cc6bcSOliver Brewka inline void processComputerSystemPatch(
3298*d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3299*d43cc6bcSOliver Brewka     std::string& systemName, PatchParams& patchParams,
3300*d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex)
33016617338dSEd Tanous {
3302f664fd8aSJanet Adkins     if constexpr (!BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3303f664fd8aSJanet Adkins     {
3304*d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
3305f664fd8aSJanet Adkins         {
3306f664fd8aSJanet Adkins             messages::propertyUnknown(asyncResp->res, "IndicatorLED");
3307f664fd8aSJanet Adkins             return;
3308f664fd8aSJanet Adkins         }
3309f664fd8aSJanet Adkins     }
3310f664fd8aSJanet Adkins 
3311*d43cc6bcSOliver Brewka     if (patchParams.assetTag)
331298e386ecSGunnar Mills     {
3313*d43cc6bcSOliver Brewka         setAssetTag(asyncResp, *patchParams.assetTag);
331498e386ecSGunnar Mills     }
331598e386ecSGunnar Mills 
3316*d43cc6bcSOliver Brewka     if (patchParams.wdtEnable || patchParams.wdtTimeOutAction)
3317c45f0082SYong Li     {
3318*d43cc6bcSOliver Brewka         setWDTProperties(asyncResp, patchParams.wdtEnable,
3319*d43cc6bcSOliver Brewka                          patchParams.wdtTimeOutAction);
3320c45f0082SYong Li     }
3321c45f0082SYong Li 
3322*d43cc6bcSOliver Brewka     if (patchParams.bootSource || patchParams.bootType ||
3323*d43cc6bcSOliver Brewka         patchParams.bootEnable)
332469f35306SGunnar Mills     {
3325*d43cc6bcSOliver Brewka         setBootProperties(asyncResp, computerSystemIndex,
3326*d43cc6bcSOliver Brewka                           patchParams.bootSource, patchParams.bootType,
3327*d43cc6bcSOliver Brewka                           patchParams.bootEnable);
3328491d8ee7SSantosh Puranik     }
3329*d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetry)
333069f35306SGunnar Mills     {
3331*d43cc6bcSOliver Brewka         setAutomaticRetry(asyncResp, computerSystemIndex,
3332*d43cc6bcSOliver Brewka                           *patchParams.bootAutomaticRetry);
333369f35306SGunnar Mills     }
3334ac7e1e0bSAli Ahmed 
3335*d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetryAttempts)
3336797d5daeSCorey Hardesty     {
3337*d43cc6bcSOliver Brewka         setAutomaticRetryAttempts(
3338*d43cc6bcSOliver Brewka             asyncResp, computerSystemIndex,
3339*d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts.value());
3340797d5daeSCorey Hardesty     }
3341797d5daeSCorey Hardesty 
3342*d43cc6bcSOliver Brewka     if (patchParams.bootTrustedModuleRequired)
3343ac7e1e0bSAli Ahmed     {
3344*d43cc6bcSOliver Brewka         setTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex,
3345*d43cc6bcSOliver Brewka                                        *patchParams.bootTrustedModuleRequired);
334669f35306SGunnar Mills     }
3347265c1602SJohnathan Mantey 
3348*d43cc6bcSOliver Brewka     if (patchParams.stopBootOnFault)
33499dcfe8c1SAlbert Zhang     {
3350*d43cc6bcSOliver Brewka         setStopBootOnFault(asyncResp, *patchParams.stopBootOnFault);
33519dcfe8c1SAlbert Zhang     }
33529dcfe8c1SAlbert Zhang 
3353*d43cc6bcSOliver Brewka     if (patchParams.locationIndicatorActive)
33549f8bfa7cSGunnar Mills     {
33552eaa9279SJanet Adkins         systems_utils::getValidSystemsPath(
33562eaa9279SJanet Adkins             asyncResp, systemName,
33572eaa9279SJanet Adkins             [asyncResp, systemName,
3358*d43cc6bcSOliver Brewka              locationIndicatorActive{*patchParams.locationIndicatorActive}](
33592eaa9279SJanet Adkins                 const std::optional<std::string>& validSystemsPath) {
33602eaa9279SJanet Adkins                 if (!validSystemsPath)
33612eaa9279SJanet Adkins                 {
33622eaa9279SJanet Adkins                     messages::resourceNotFound(asyncResp->res, "Systems",
33632eaa9279SJanet Adkins                                                systemName);
33642eaa9279SJanet Adkins                     return;
33652eaa9279SJanet Adkins                 }
33662eaa9279SJanet Adkins                 setLocationIndicatorActive(asyncResp, *validSystemsPath,
33672eaa9279SJanet Adkins                                            locationIndicatorActive);
33682eaa9279SJanet Adkins             });
33699f8bfa7cSGunnar Mills     }
33709f8bfa7cSGunnar Mills 
3371f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3372f664fd8aSJanet Adkins     {
3373*d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
33746617338dSEd Tanous         {
3375*d43cc6bcSOliver Brewka             setIndicatorLedState(asyncResp, *patchParams.indicatorLed);
3376002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3377d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3378d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
33796617338dSEd Tanous         }
3380f664fd8aSJanet Adkins     }
3381c6a620f2SGeorge Liu 
3382*d43cc6bcSOliver Brewka     if (patchParams.powerRestorePolicy)
3383c6a620f2SGeorge Liu     {
3384*d43cc6bcSOliver Brewka         setPowerRestorePolicy(asyncResp, computerSystemIndex,
3385*d43cc6bcSOliver Brewka                               *patchParams.powerRestorePolicy);
3386c6a620f2SGeorge Liu     }
33873a2d0424SChris Cain 
3388*d43cc6bcSOliver Brewka     if (patchParams.powerMode)
33893a2d0424SChris Cain     {
3390*d43cc6bcSOliver Brewka         setPowerMode(asyncResp, *patchParams.powerMode);
33913a2d0424SChris Cain     }
339237bbf98cSChris Cain 
3393*d43cc6bcSOliver Brewka     if (patchParams.ipsEnable || patchParams.ipsEnterUtil ||
3394*d43cc6bcSOliver Brewka         patchParams.ipsEnterTime || patchParams.ipsExitUtil ||
3395*d43cc6bcSOliver Brewka         patchParams.ipsExitTime)
339637bbf98cSChris Cain     {
3397*d43cc6bcSOliver Brewka         setIdlePowerSaver(asyncResp, patchParams.ipsEnable,
3398*d43cc6bcSOliver Brewka                           patchParams.ipsEnterUtil, patchParams.ipsEnterTime,
3399*d43cc6bcSOliver Brewka                           patchParams.ipsExitUtil, patchParams.ipsExitTime);
340037bbf98cSChris Cain     }
3401c1e219d5SEd Tanous }
34021cb1a9e6SAppaRao Puli 
3403*d43cc6bcSOliver Brewka inline void handleComputerSystemPatch(
3404*d43cc6bcSOliver Brewka     crow::App& app, const crow::Request& req,
3405*d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3406*d43cc6bcSOliver Brewka     const std::string& systemName)
3407*d43cc6bcSOliver Brewka {
3408*d43cc6bcSOliver Brewka     PatchParams patchParams;
3409*d43cc6bcSOliver Brewka 
3410*d43cc6bcSOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3411*d43cc6bcSOliver Brewka     {
3412*d43cc6bcSOliver Brewka         return;
3413*d43cc6bcSOliver Brewka     }
3414*d43cc6bcSOliver Brewka 
3415*d43cc6bcSOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3416*d43cc6bcSOliver Brewka     {
3417*d43cc6bcSOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3418*d43cc6bcSOliver Brewka         {
3419*d43cc6bcSOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3420*d43cc6bcSOliver Brewka                                        systemName);
3421*d43cc6bcSOliver Brewka             return;
3422*d43cc6bcSOliver Brewka         }
3423*d43cc6bcSOliver Brewka     }
3424*d43cc6bcSOliver Brewka 
3425*d43cc6bcSOliver Brewka     asyncResp->res.addHeader(
3426*d43cc6bcSOliver Brewka         boost::beast::http::field::link,
3427*d43cc6bcSOliver Brewka         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3428*d43cc6bcSOliver Brewka 
3429*d43cc6bcSOliver Brewka     if (!json_util::readJsonPatch(
3430*d43cc6bcSOliver Brewka             req, asyncResp->res,                                              //
3431*d43cc6bcSOliver Brewka             "AssetTag", patchParams.assetTag,                                 //
3432*d43cc6bcSOliver Brewka             "Boot/AutomaticRetryAttempts",
3433*d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts,                           //
3434*d43cc6bcSOliver Brewka             "Boot/AutomaticRetryConfig", patchParams.bootAutomaticRetry,      //
3435*d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideEnabled", patchParams.bootEnable,         //
3436*d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideMode", patchParams.bootType,              //
3437*d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideTarget", patchParams.bootSource,          //
3438*d43cc6bcSOliver Brewka             "Boot/StopBootOnFault", patchParams.stopBootOnFault,              //
3439*d43cc6bcSOliver Brewka             "Boot/TrustedModuleRequiredToBoot",
3440*d43cc6bcSOliver Brewka             patchParams.bootTrustedModuleRequired,                            //
3441*d43cc6bcSOliver Brewka             "HostWatchdogTimer/FunctionEnabled", patchParams.wdtEnable,       //
3442*d43cc6bcSOliver Brewka             "HostWatchdogTimer/TimeoutAction", patchParams.wdtTimeOutAction,  //
3443*d43cc6bcSOliver Brewka             "IdlePowerSaver/Enabled", patchParams.ipsEnable,                  //
3444*d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterDwellTimeSeconds", patchParams.ipsEnterTime, //
3445*d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterUtilizationPercent",
3446*d43cc6bcSOliver Brewka             patchParams.ipsEnterUtil,                                         //
3447*d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitDwellTimeSeconds", patchParams.ipsExitTime,   //
3448*d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitUtilizationPercent", patchParams.ipsExitUtil, //
3449*d43cc6bcSOliver Brewka             "IndicatorLED", patchParams.indicatorLed,                         //
3450*d43cc6bcSOliver Brewka             "LocationIndicatorActive", patchParams.locationIndicatorActive,   //
3451*d43cc6bcSOliver Brewka             "PowerMode", patchParams.powerMode,                               //
3452*d43cc6bcSOliver Brewka             "PowerRestorePolicy", patchParams.powerRestorePolicy))
3453*d43cc6bcSOliver Brewka     {
3454*d43cc6bcSOliver Brewka         return;
3455*d43cc6bcSOliver Brewka     }
3456*d43cc6bcSOliver Brewka 
3457*d43cc6bcSOliver Brewka     getComputerSystemIndex(asyncResp, systemName,
3458*d43cc6bcSOliver Brewka                            std::bind_front(processComputerSystemPatch,
3459*d43cc6bcSOliver Brewka                                            asyncResp, systemName, patchParams));
3460*d43cc6bcSOliver Brewka }
3461*d43cc6bcSOliver Brewka 
346238c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3463dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34647f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3465c1e219d5SEd Tanous     const std::string& /*systemName*/)
3466dd60b9edSEd Tanous {
3467dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3468dd60b9edSEd Tanous     {
3469dd60b9edSEd Tanous         return;
3470dd60b9edSEd Tanous     }
3471dd60b9edSEd Tanous     asyncResp->res.addHeader(
3472dd60b9edSEd Tanous         boost::beast::http::field::link,
3473dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3474dd60b9edSEd Tanous }
347533e1f122SAndrew Geissler 
347633e1f122SAndrew Geissler /**
347733e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
347833e1f122SAndrew Geissler  *
347933e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
348033e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
348133e1f122SAndrew Geissler  *
3482efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
348333e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
348433e1f122SAndrew Geissler  * allowableValues.
348533e1f122SAndrew Geissler  */
3486504af5a0SPatrick Williams inline void dbusToRfAllowedHostTransitions(
3487504af5a0SPatrick Williams     const std::string& dbusAllowedHostTran,
348833e1f122SAndrew Geissler     nlohmann::json::array_t& allowableValues)
348933e1f122SAndrew Geissler {
349033e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
349133e1f122SAndrew Geissler     {
349233e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
349333e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
349433e1f122SAndrew Geissler     }
349533e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
349633e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
349733e1f122SAndrew Geissler     {
349833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
349933e1f122SAndrew Geissler     }
350033e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
350133e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
350233e1f122SAndrew Geissler     {
350333e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
350433e1f122SAndrew Geissler     }
350533e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
350633e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
350733e1f122SAndrew Geissler     {
350833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
350933e1f122SAndrew Geissler     }
351033e1f122SAndrew Geissler     else
351133e1f122SAndrew Geissler     {
351233e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
351333e1f122SAndrew Geissler     }
351433e1f122SAndrew Geissler }
351533e1f122SAndrew Geissler 
351633e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
351733e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
351833e1f122SAndrew Geissler     const boost::system::error_code& ec,
351933e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
352033e1f122SAndrew Geissler {
352133e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
352233e1f122SAndrew Geissler 
352333e1f122SAndrew Geissler     // Supported on all systems currently
352433e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
352533e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
352633e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
352733e1f122SAndrew Geissler 
352833e1f122SAndrew Geissler     if (ec)
352933e1f122SAndrew Geissler     {
3530e715d14bSEd Tanous         if ((ec.value() ==
3531e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3532e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
353333e1f122SAndrew Geissler         {
353433e1f122SAndrew Geissler             // Property not implemented so just return defaults
353533e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
353633e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
353733e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
353833e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
353933e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
354033e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
354133e1f122SAndrew Geissler         }
354233e1f122SAndrew Geissler         else
354333e1f122SAndrew Geissler         {
354433e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
354533e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
354633e1f122SAndrew Geissler             return;
354733e1f122SAndrew Geissler         }
354833e1f122SAndrew Geissler     }
354933e1f122SAndrew Geissler     else
355033e1f122SAndrew Geissler     {
355133e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
355233e1f122SAndrew Geissler         {
355333e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
355433e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
355533e1f122SAndrew Geissler         }
355633e1f122SAndrew Geissler     }
355733e1f122SAndrew Geissler 
355833e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
355933e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
356033e1f122SAndrew Geissler     parameter["Required"] = true;
3561539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
356233e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
356333e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
356433e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
356533e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
356633e1f122SAndrew Geissler }
356733e1f122SAndrew Geissler 
35685e7c1f31SOliver Brewka inline void getAllowedHostTransitions(
35695e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
35705e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
35715e7c1f31SOliver Brewka {
35725e7c1f31SOliver Brewka     dbus::utility::getProperty<std::vector<std::string>>(
35735e7c1f31SOliver Brewka         getHostStateServiceName(computerSystemIndex),
35745e7c1f31SOliver Brewka         getHostStateObjectPath(computerSystemIndex),
35755e7c1f31SOliver Brewka         "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
35765e7c1f31SOliver Brewka         std::bind_front(afterGetAllowedHostTransitions, asyncResp));
35775e7c1f31SOliver Brewka }
35785e7c1f31SOliver Brewka 
3579c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3580c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
358122d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3582c1e219d5SEd Tanous     const std::string& systemName)
3583c1e219d5SEd Tanous {
35843ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
358545ca1b86SEd Tanous     {
358645ca1b86SEd Tanous         return;
358745ca1b86SEd Tanous     }
3588746b56f3SAsmitha Karunanithi 
358968896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
359068896206SGunnar Mills     {
3591746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3592746b56f3SAsmitha Karunanithi         {
3593746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3594746b56f3SAsmitha Karunanithi             return;
3595746b56f3SAsmitha Karunanithi         }
359668896206SGunnar Mills     }
3597746b56f3SAsmitha Karunanithi 
35985e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
35995e7c1f31SOliver Brewka     {
3600253f11b8SEd Tanous         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
360122d268cbSEd Tanous         {
360222d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
360322d268cbSEd Tanous                                        systemName);
360422d268cbSEd Tanous             return;
360522d268cbSEd Tanous         }
36065e7c1f31SOliver Brewka     }
360722d268cbSEd Tanous 
3608dd60b9edSEd Tanous     asyncResp->res.addHeader(
3609dd60b9edSEd Tanous         boost::beast::http::field::link,
3610dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
36111476687dSEd Tanous 
36125e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
36135e7c1f31SOliver Brewka         "/redfish/v1/Systems/{}/ResetActionInfo", systemName);
3614c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
36151476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
36161476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
36173215e700SNan Zhou 
361833e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
36195e7c1f31SOliver Brewka     getComputerSystemIndex(
36205e7c1f31SOliver Brewka         asyncResp, systemName,
36215e7c1f31SOliver Brewka         std::bind_front(getAllowedHostTransitions, asyncResp));
3622c1e219d5SEd Tanous }
36235e7c1f31SOliver Brewka 
3624c1e219d5SEd Tanous /**
3625c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3626c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3627c1e219d5SEd Tanous  */
3628100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3629c1e219d5SEd Tanous {
3630100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3631100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3632100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3633100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3634100afe56SEd Tanous 
3635100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3636100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3637100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3638100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3639100afe56SEd Tanous 
3640100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3641100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3642100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3643100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3644100afe56SEd Tanous 
3645100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3646100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3647100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3648100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3649100afe56SEd Tanous 
3650100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3651100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3652100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3653100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3654100afe56SEd Tanous 
3655100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3656100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3657100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3658100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3659100afe56SEd Tanous 
3660c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3661c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3662c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3663c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3664c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3665c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3666c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3667c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36681cb1a9e6SAppaRao Puli }
3669c5b2abe0SLewanczyk, Dawid } // namespace redfish
3670