xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision a52f1d5b25a0c9c4b6e6a69e5f23fb39b26553bf)
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/verb.hpp>
36e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
3733e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
38ef4c65b7SEd Tanous #include <boost/url/format.hpp>
39d7857201SEd Tanous #include <nlohmann/json.hpp>
40d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
41bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
421214b7e7SGunnar Mills 
437a1dbc48SGeorge Liu #include <array>
44d7857201SEd Tanous #include <chrono>
45d7857201SEd Tanous #include <cstddef>
46d7857201SEd Tanous #include <cstdint>
47d7857201SEd Tanous #include <functional>
4833e1f122SAndrew Geissler #include <memory>
49d7857201SEd Tanous #include <optional>
50d7857201SEd Tanous #include <ratio>
516b9ac4f2SChris Cain #include <string>
527a1dbc48SGeorge Liu #include <string_view>
53d7857201SEd Tanous #include <tuple>
5420fa6a2cSEd Tanous #include <utility>
556b9ac4f2SChris Cain #include <vector>
56c5b2abe0SLewanczyk, Dawid 
571abe55efSEd Tanous namespace redfish
581abe55efSEd Tanous {
59c5b2abe0SLewanczyk, Dawid 
605c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
615c3e9272SAbhishek Patel     protocolToDBusForSystems{
625c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
635c3e9272SAbhishek Patel 
64cf0e004cSNinad Palsule /*
65cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
66cf0e004cSNinad Palsule  *
67ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
68cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
69cf0e004cSNinad Palsule  *
70cf0e004cSNinad Palsule  * @return None.
71cf0e004cSNinad Palsule  */
72bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
73bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
74cf0e004cSNinad Palsule {
7562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
76cf0e004cSNinad Palsule 
77cf0e004cSNinad Palsule     if (isCpuPresent)
78cf0e004cSNinad Palsule     {
79cf0e004cSNinad Palsule         nlohmann::json& procCount =
80ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
81cf0e004cSNinad Palsule         auto* procCountPtr =
82cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
83cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
84cf0e004cSNinad Palsule         {
85cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
86cf0e004cSNinad Palsule             *procCountPtr += 1;
87cf0e004cSNinad Palsule         }
88cf0e004cSNinad Palsule     }
89cf0e004cSNinad Palsule }
90cf0e004cSNinad Palsule 
91382d6475SAli Ahmed inline void getProcessorProperties(
92ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
93382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
94382d6475SAli Ahmed         properties)
9503fbed92SAli Ahmed {
9662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
9703fbed92SAli Ahmed 
9803fbed92SAli Ahmed     // TODO: Get Model
9903fbed92SAli Ahmed 
100bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
10103fbed92SAli Ahmed 
102bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
103bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
10403fbed92SAli Ahmed 
105bc1d29deSKrzysztof Grobelny     if (!success)
10603fbed92SAli Ahmed     {
107ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
10803fbed92SAli Ahmed         return;
10903fbed92SAli Ahmed     }
11003fbed92SAli Ahmed 
111bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
11203fbed92SAli Ahmed     {
113bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
114ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
115bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
116bc1d29deSKrzysztof Grobelny 
117bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
118bc1d29deSKrzysztof Grobelny         {
119bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
12003fbed92SAli Ahmed         }
12103fbed92SAli Ahmed         else
12203fbed92SAli Ahmed         {
123bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
12403fbed92SAli Ahmed         }
12503fbed92SAli Ahmed     }
12603fbed92SAli Ahmed }
12703fbed92SAli Ahmed 
12803fbed92SAli Ahmed /*
12903fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
13003fbed92SAli Ahmed  *
131ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
13203fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
13303fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
13403fbed92SAli Ahmed  *
13503fbed92SAli Ahmed  * @return None.
13603fbed92SAli Ahmed  */
137504af5a0SPatrick Williams inline void getProcessorSummary(
138504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
139ac106bf6SEd Tanous     const std::string& service, const std::string& path)
14003fbed92SAli Ahmed {
141ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
142382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
143382d6475SAli Ahmed         if (ec3)
144382d6475SAli Ahmed         {
14562598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
146382d6475SAli Ahmed             return;
147382d6475SAli Ahmed         }
148ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
149382d6475SAli Ahmed     };
150382d6475SAli Ahmed 
151cf0e004cSNinad Palsule     // Get the Presence of CPU
152deae6a78SEd Tanous     dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
153deae6a78SEd Tanous                                      path, "xyz.openbmc_project.Inventory.Item",
154deae6a78SEd Tanous                                      "Present", std::move(getCpuPresenceState));
155cf0e004cSNinad Palsule 
156deae6a78SEd Tanous     dbus::utility::getAllProperties(
157deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
158ac106bf6SEd Tanous         [asyncResp, service,
1595e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
160b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
16103fbed92SAli Ahmed             if (ec2)
16203fbed92SAli Ahmed             {
16362598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
164ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16503fbed92SAli Ahmed                 return;
16603fbed92SAli Ahmed             }
167ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
168bc1d29deSKrzysztof Grobelny         });
16903fbed92SAli Ahmed }
17003fbed92SAli Ahmed 
17157e8c9beSAlpana Kumari /*
172cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
173cf0e004cSNinad Palsule  *
174ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
175cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
176cf0e004cSNinad Palsule  *
177cf0e004cSNinad Palsule  * @return None.
178cf0e004cSNinad Palsule  */
179504af5a0SPatrick Williams inline void processMemoryProperties(
180504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
181cf0e004cSNinad Palsule     const dbus::utility::DBusPropertiesMap& properties)
182cf0e004cSNinad Palsule {
18362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
184cf0e004cSNinad Palsule 
185cf0e004cSNinad Palsule     if (properties.empty())
186cf0e004cSNinad Palsule     {
187cf0e004cSNinad Palsule         return;
188cf0e004cSNinad Palsule     }
189cf0e004cSNinad Palsule 
190cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
191cf0e004cSNinad Palsule 
192cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
193cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
194cf0e004cSNinad Palsule         memorySizeInKB);
195cf0e004cSNinad Palsule 
196cf0e004cSNinad Palsule     if (!success)
197cf0e004cSNinad Palsule     {
198ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
199cf0e004cSNinad Palsule         return;
200cf0e004cSNinad Palsule     }
201cf0e004cSNinad Palsule 
202cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
203cf0e004cSNinad Palsule     {
204cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
205ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
206dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
207cf0e004cSNinad Palsule         if (preValue == nullptr)
208cf0e004cSNinad Palsule         {
209ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
210dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
211cf0e004cSNinad Palsule         }
212cf0e004cSNinad Palsule         else
213cf0e004cSNinad Palsule         {
214ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
215dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
216dfb2b408SPriyanga Ramasamy                 *preValue;
217cf0e004cSNinad Palsule         }
218cf0e004cSNinad Palsule     }
219cf0e004cSNinad Palsule }
220cf0e004cSNinad Palsule 
221cf0e004cSNinad Palsule /*
222cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
223cf0e004cSNinad Palsule  *
224ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
225cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
226cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
227cf0e004cSNinad Palsule  *
228cf0e004cSNinad Palsule  * @return None.
229cf0e004cSNinad Palsule  */
230504af5a0SPatrick Williams inline void getMemorySummary(
231504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
232ac106bf6SEd Tanous     const std::string& service, const std::string& path)
233cf0e004cSNinad Palsule {
234deae6a78SEd Tanous     dbus::utility::getAllProperties(
235deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
236ac106bf6SEd Tanous         [asyncResp, service,
237cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
238cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
239cf0e004cSNinad Palsule             if (ec2)
240cf0e004cSNinad Palsule             {
24162598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
242ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
243cf0e004cSNinad Palsule                 return;
244cf0e004cSNinad Palsule             }
24551bd2d8aSGunnar Mills             processMemoryProperties(asyncResp, properties);
246cf0e004cSNinad Palsule         });
247cf0e004cSNinad Palsule }
248cf0e004cSNinad Palsule 
249a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
250a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
251a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
2521abe55efSEd Tanous {
253a974c132SLakshmi Yadlapati     if (ec)
254a974c132SLakshmi Yadlapati     {
255a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
256a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
257a974c132SLakshmi Yadlapati         return;
258a974c132SLakshmi Yadlapati     }
259a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
260a974c132SLakshmi Yadlapati 
261a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
262a974c132SLakshmi Yadlapati 
263a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
264a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
265a974c132SLakshmi Yadlapati 
266a974c132SLakshmi Yadlapati     if (!success)
267a974c132SLakshmi Yadlapati     {
268a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
269a974c132SLakshmi Yadlapati         return;
270a974c132SLakshmi Yadlapati     }
271a974c132SLakshmi Yadlapati 
272a974c132SLakshmi Yadlapati     if (uUID != nullptr)
273a974c132SLakshmi Yadlapati     {
274a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
275a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
276a974c132SLakshmi Yadlapati         {
277a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
278a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
279a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
280a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
281a974c132SLakshmi Yadlapati         }
282a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
283a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
284a974c132SLakshmi Yadlapati     }
285a974c132SLakshmi Yadlapati }
286a974c132SLakshmi Yadlapati 
287504af5a0SPatrick Williams inline void afterGetInventory(
288504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
289a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
290a974c132SLakshmi Yadlapati     const dbus::utility::DBusPropertiesMap& propertiesList)
291a974c132SLakshmi Yadlapati {
292a974c132SLakshmi Yadlapati     if (ec)
293a974c132SLakshmi Yadlapati     {
294a974c132SLakshmi Yadlapati         // doesn't have to include this
295a974c132SLakshmi Yadlapati         // interface
296a974c132SLakshmi Yadlapati         return;
297a974c132SLakshmi Yadlapati     }
298a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
299a974c132SLakshmi Yadlapati 
300a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
301a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
302a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
303a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
304a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
305a974c132SLakshmi Yadlapati 
306a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
307a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
308a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
309a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
310a974c132SLakshmi Yadlapati 
311a974c132SLakshmi Yadlapati     if (!success)
312a974c132SLakshmi Yadlapati     {
313a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
314a974c132SLakshmi Yadlapati         return;
315a974c132SLakshmi Yadlapati     }
316a974c132SLakshmi Yadlapati 
317a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
318a974c132SLakshmi Yadlapati     {
319a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
320a974c132SLakshmi Yadlapati     }
321a974c132SLakshmi Yadlapati 
322a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
323a974c132SLakshmi Yadlapati     {
324a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
325a974c132SLakshmi Yadlapati     }
326a974c132SLakshmi Yadlapati 
327a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
328a974c132SLakshmi Yadlapati     {
329a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
330a974c132SLakshmi Yadlapati     }
331a974c132SLakshmi Yadlapati 
332a974c132SLakshmi Yadlapati     if (model != nullptr)
333a974c132SLakshmi Yadlapati     {
334a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
335a974c132SLakshmi Yadlapati     }
336a974c132SLakshmi Yadlapati 
337a974c132SLakshmi Yadlapati     if (subModel != nullptr)
338a974c132SLakshmi Yadlapati     {
339a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
340a974c132SLakshmi Yadlapati     }
341a974c132SLakshmi Yadlapati 
342a974c132SLakshmi Yadlapati     // Grab the bios version
343a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
344a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
345a974c132SLakshmi Yadlapati }
346a974c132SLakshmi Yadlapati 
347bd79bce8SPatrick Williams inline void afterGetAssetTag(
348bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
349bd79bce8SPatrick Williams     const boost::system::error_code& ec, const std::string& value)
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 
358a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
359a974c132SLakshmi Yadlapati }
360a974c132SLakshmi Yadlapati 
361a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
362a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
363a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
364a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
365a974c132SLakshmi Yadlapati {
3661abe55efSEd Tanous     if (ec)
3671abe55efSEd Tanous     {
368b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
369ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
370c5b2abe0SLewanczyk, Dawid         return;
371c5b2abe0SLewanczyk, Dawid     }
372c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
373002d39b4SEd Tanous     for (const std::pair<
374002d39b4SEd Tanous              std::string,
375002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
3761214b7e7SGunnar Mills              object : subtree)
3771abe55efSEd Tanous     {
378c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
37962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
380002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
3811214b7e7SGunnar Mills             connectionNames = object.second;
38226f6976fSEd Tanous         if (connectionNames.empty())
3831abe55efSEd Tanous         {
384c5b2abe0SLewanczyk, Dawid             continue;
385c5b2abe0SLewanczyk, Dawid         }
386029573d4SEd Tanous 
3876c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
3886c34de48SEd Tanous         // BiosVer
38904a258f4SEd Tanous         for (const auto& connection : connectionNames)
3901abe55efSEd Tanous         {
39104a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
3921abe55efSEd Tanous             {
393a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
3941abe55efSEd Tanous                 {
39562598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
3969d3ae10eSAlpana Kumari 
397ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
3985fd0aafbSNinad Palsule                 }
39904a258f4SEd Tanous                 else if (interfaceName ==
40004a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4011abe55efSEd Tanous                 {
40262598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
40357e8c9beSAlpana Kumari 
404ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4055fd0aafbSNinad Palsule                 }
406002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4071abe55efSEd Tanous                 {
40862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
409bc1d29deSKrzysztof Grobelny 
410deae6a78SEd Tanous                     dbus::utility::getAllProperties(
411a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
412a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
413ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
414b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4151214b7e7SGunnar Mills                                         properties) {
416a974c132SLakshmi Yadlapati                             afterGetUUID(asyncResp, ec3, properties);
417bc1d29deSKrzysztof Grobelny                         });
418c5b2abe0SLewanczyk, Dawid                 }
419029573d4SEd Tanous                 else if (interfaceName ==
420029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4211abe55efSEd Tanous                 {
422deae6a78SEd Tanous                     dbus::utility::getAllProperties(
423a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
424bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
425a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
426b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
427a974c132SLakshmi Yadlapati                                         properties) {
428a974c132SLakshmi Yadlapati                             afterGetInventory(asyncResp, ec3, properties);
429bc1d29deSKrzysztof Grobelny                         });
430e4a4b9a9SJames Feist 
431deae6a78SEd Tanous                     dbus::utility::getProperty<std::string>(
432deae6a78SEd Tanous                         connection.first, path,
4331e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4341e1e598dSJonathan Doman                         "AssetTag",
4351e1e598dSJonathan Doman                         "AssetTag",
436a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
437a974c132SLakshmi Yadlapati                 }
438a974c132SLakshmi Yadlapati             }
439a974c132SLakshmi Yadlapati         }
440a974c132SLakshmi Yadlapati     }
441a974c132SLakshmi Yadlapati }
442a974c132SLakshmi Yadlapati 
443a974c132SLakshmi Yadlapati /*
444a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
445a974c132SLakshmi Yadlapati  *
446a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
447a974c132SLakshmi Yadlapati  *
448a974c132SLakshmi Yadlapati  * @return None.
449a974c132SLakshmi Yadlapati  */
450504af5a0SPatrick Williams inline void getComputerSystem(
451504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
452e4a4b9a9SJames Feist {
453a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
454a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
455a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
456a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
457a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
458a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
459a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
460a974c132SLakshmi Yadlapati     };
461a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
462a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
46351bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
464c5b2abe0SLewanczyk, Dawid }
465c5b2abe0SLewanczyk, Dawid 
466c5b2abe0SLewanczyk, Dawid /**
467c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
468c5b2abe0SLewanczyk, Dawid  *
469ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
4705e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
471c5b2abe0SLewanczyk, Dawid  *
472c5b2abe0SLewanczyk, Dawid  * @return None.
473c5b2abe0SLewanczyk, Dawid  */
4745e7c1f31SOliver Brewka inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4755e7c1f31SOliver Brewka                          const uint64_t computerSystemIndex)
4761abe55efSEd Tanous {
47762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
478*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
479*a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
480deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
481*a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
482deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState",
483ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
4841e1e598dSJonathan Doman                     const std::string& hostState) {
4851abe55efSEd Tanous             if (ec)
4861abe55efSEd Tanous             {
48722228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
48822228c28SAndrew Geissler                 {
48922228c28SAndrew Geissler                     // Service not available, no error, just don't return
49022228c28SAndrew Geissler                     // host state info
49162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
49222228c28SAndrew Geissler                     return;
49322228c28SAndrew Geissler                 }
49462598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
495ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
496c5b2abe0SLewanczyk, Dawid                 return;
497c5b2abe0SLewanczyk, Dawid             }
4986617338dSEd Tanous 
49962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
500c5b2abe0SLewanczyk, Dawid             // Verify Host State
5011e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5021abe55efSEd Tanous             {
503bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
504bd79bce8SPatrick Williams                     resource::PowerState::On;
505539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
506539d8c6bSEd Tanous                     resource::State::Enabled;
5071abe55efSEd Tanous             }
5081e1e598dSJonathan Doman             else if (hostState ==
5090fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5108c888608SGunnar Mills             {
511bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
512bd79bce8SPatrick Williams                     resource::PowerState::On;
513539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
514539d8c6bSEd Tanous                     resource::State::Quiesced;
5158c888608SGunnar Mills             }
5161e1e598dSJonathan Doman             else if (hostState ==
5170fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
51883935af9SAndrew Geissler             {
519bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
520bd79bce8SPatrick Williams                     resource::PowerState::On;
521539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
522539d8c6bSEd Tanous                     resource::State::InTest;
52383935af9SAndrew Geissler             }
5240fda0f12SGeorge Liu             else if (
5251e1e598dSJonathan Doman                 hostState ==
5260fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5271a2a1437SAndrew Geissler             {
528539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
529539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
530539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
531539d8c6bSEd Tanous                     resource::State::Starting;
5321a2a1437SAndrew Geissler             }
533bd79bce8SPatrick Williams             else if (
534bd79bce8SPatrick Williams                 hostState ==
5350fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5361a2a1437SAndrew Geissler             {
537539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
538539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
539539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
540539d8c6bSEd Tanous                     resource::State::Disabled;
5411a2a1437SAndrew Geissler             }
5421abe55efSEd Tanous             else
5431abe55efSEd Tanous             {
544bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
545bd79bce8SPatrick Williams                     resource::PowerState::Off;
546539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
547539d8c6bSEd Tanous                     resource::State::Disabled;
548c5b2abe0SLewanczyk, Dawid             }
5491e1e598dSJonathan Doman         });
550c5b2abe0SLewanczyk, Dawid }
551c5b2abe0SLewanczyk, Dawid 
552c5b2abe0SLewanczyk, Dawid /**
553786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
554491d8ee7SSantosh Puranik  *
555491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
556491d8ee7SSantosh Puranik  *
557491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
558491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
559491d8ee7SSantosh Puranik  */
56023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
561491d8ee7SSantosh Puranik {
562491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
563491d8ee7SSantosh Puranik     {
564491d8ee7SSantosh Puranik         return "None";
565491d8ee7SSantosh Puranik     }
5663174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
567491d8ee7SSantosh Puranik     {
568491d8ee7SSantosh Puranik         return "Hdd";
569491d8ee7SSantosh Puranik     }
5703174e4dfSEd Tanous     if (dbusSource ==
571a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
572491d8ee7SSantosh Puranik     {
573491d8ee7SSantosh Puranik         return "Cd";
574491d8ee7SSantosh Puranik     }
5753174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
576491d8ee7SSantosh Puranik     {
577491d8ee7SSantosh Puranik         return "Pxe";
578491d8ee7SSantosh Puranik     }
5793174e4dfSEd Tanous     if (dbusSource ==
580944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
5819f16b2c1SJennifer Lee     {
5829f16b2c1SJennifer Lee         return "Usb";
5839f16b2c1SJennifer Lee     }
584491d8ee7SSantosh Puranik     return "";
585491d8ee7SSantosh Puranik }
586491d8ee7SSantosh Puranik 
587491d8ee7SSantosh Puranik /**
588cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
589cd9a4666SKonstantin Aladyshev  *
590cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
591cd9a4666SKonstantin Aladyshev  *
592cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
593cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
594cd9a4666SKonstantin Aladyshev  */
595cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
596cd9a4666SKonstantin Aladyshev {
597cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
598cd9a4666SKonstantin Aladyshev     {
599cd9a4666SKonstantin Aladyshev         return "Legacy";
600cd9a4666SKonstantin Aladyshev     }
601cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
602cd9a4666SKonstantin Aladyshev     {
603cd9a4666SKonstantin Aladyshev         return "UEFI";
604cd9a4666SKonstantin Aladyshev     }
605cd9a4666SKonstantin Aladyshev     return "";
606cd9a4666SKonstantin Aladyshev }
607cd9a4666SKonstantin Aladyshev 
608cd9a4666SKonstantin Aladyshev /**
609786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
610491d8ee7SSantosh Puranik  *
611491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
612491d8ee7SSantosh Puranik  *
613491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
614491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
615491d8ee7SSantosh Puranik  */
61623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
617491d8ee7SSantosh Puranik {
618491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
619491d8ee7SSantosh Puranik     {
620491d8ee7SSantosh Puranik         return "None";
621491d8ee7SSantosh Puranik     }
6223174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
623491d8ee7SSantosh Puranik     {
624491d8ee7SSantosh Puranik         return "Diags";
625491d8ee7SSantosh Puranik     }
6263174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
627491d8ee7SSantosh Puranik     {
628491d8ee7SSantosh Puranik         return "BiosSetup";
629491d8ee7SSantosh Puranik     }
630491d8ee7SSantosh Puranik     return "";
631491d8ee7SSantosh Puranik }
632491d8ee7SSantosh Puranik 
633491d8ee7SSantosh Puranik /**
634e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
635e43914b3SAndrew Geissler  *
636e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
637e43914b3SAndrew Geissler  *
638e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
639e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
640e43914b3SAndrew Geissler  */
641e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
642e43914b3SAndrew Geissler {
643e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
644e43914b3SAndrew Geissler     // enum
645e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
646e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
647e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
648e43914b3SAndrew Geissler     {
649e43914b3SAndrew Geissler         rfBpLastState = "None";
650e43914b3SAndrew Geissler     }
651e43914b3SAndrew Geissler     else if (dbusBootProgress ==
652e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
653e43914b3SAndrew Geissler              "PrimaryProcInit")
654e43914b3SAndrew Geissler     {
655e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
656e43914b3SAndrew Geissler     }
657e43914b3SAndrew Geissler     else if (dbusBootProgress ==
658e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
659e43914b3SAndrew Geissler              "BusInit")
660e43914b3SAndrew Geissler     {
661e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
662e43914b3SAndrew Geissler     }
663e43914b3SAndrew Geissler     else if (dbusBootProgress ==
664e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
665e43914b3SAndrew Geissler              "MemoryInit")
666e43914b3SAndrew Geissler     {
667e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
668e43914b3SAndrew Geissler     }
669e43914b3SAndrew Geissler     else if (dbusBootProgress ==
670e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
671e43914b3SAndrew Geissler              "SecondaryProcInit")
672e43914b3SAndrew Geissler     {
673e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
674e43914b3SAndrew Geissler     }
675e43914b3SAndrew Geissler     else if (dbusBootProgress ==
676e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
677e43914b3SAndrew Geissler              "PCIInit")
678e43914b3SAndrew Geissler     {
679e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
680e43914b3SAndrew Geissler     }
681e43914b3SAndrew Geissler     else if (dbusBootProgress ==
682e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
683e43914b3SAndrew Geissler              "SystemSetup")
684e43914b3SAndrew Geissler     {
685e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
686e43914b3SAndrew Geissler     }
687e43914b3SAndrew Geissler     else if (dbusBootProgress ==
688e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
689e43914b3SAndrew Geissler              "SystemInitComplete")
690e43914b3SAndrew Geissler     {
691e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
692e43914b3SAndrew Geissler     }
693e43914b3SAndrew Geissler     else if (dbusBootProgress ==
694e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
695e43914b3SAndrew Geissler              "OSStart")
696e43914b3SAndrew Geissler     {
697e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
698e43914b3SAndrew Geissler     }
699e43914b3SAndrew Geissler     else if (dbusBootProgress ==
700e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
701e43914b3SAndrew Geissler              "OSRunning")
702e43914b3SAndrew Geissler     {
703e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
704e43914b3SAndrew Geissler     }
705e43914b3SAndrew Geissler     else
706e43914b3SAndrew Geissler     {
70762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
708e43914b3SAndrew Geissler         // Just return the default
709e43914b3SAndrew Geissler     }
710e43914b3SAndrew Geissler     return rfBpLastState;
711e43914b3SAndrew Geissler }
712e43914b3SAndrew Geissler 
713e43914b3SAndrew Geissler /**
714786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
715491d8ee7SSantosh Puranik  *
716491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
717944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
718944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
719491d8ee7SSantosh Puranik  *
720944ffaf9SJohnathan Mantey  * @return Integer error code.
721491d8ee7SSantosh Puranik  */
722bd79bce8SPatrick Williams inline int assignBootParameters(
723bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
724bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
725491d8ee7SSantosh Puranik {
726c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
727c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
728944ffaf9SJohnathan Mantey 
729491d8ee7SSantosh Puranik     if (rfSource == "None")
730491d8ee7SSantosh Puranik     {
731944ffaf9SJohnathan Mantey         return 0;
732491d8ee7SSantosh Puranik     }
7333174e4dfSEd Tanous     if (rfSource == "Pxe")
734491d8ee7SSantosh Puranik     {
735944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
736944ffaf9SJohnathan Mantey     }
737944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
738944ffaf9SJohnathan Mantey     {
739944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
740944ffaf9SJohnathan Mantey     }
741944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
742944ffaf9SJohnathan Mantey     {
743944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
744944ffaf9SJohnathan Mantey     }
745944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
746944ffaf9SJohnathan Mantey     {
747944ffaf9SJohnathan Mantey         bootSource =
748944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
749944ffaf9SJohnathan Mantey     }
750944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
751944ffaf9SJohnathan Mantey     {
752944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
753491d8ee7SSantosh Puranik     }
7549f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7559f16b2c1SJennifer Lee     {
756944ffaf9SJohnathan Mantey         bootSource =
757944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7589f16b2c1SJennifer Lee     }
759491d8ee7SSantosh Puranik     else
760491d8ee7SSantosh Puranik     {
76162598e31SEd Tanous         BMCWEB_LOG_DEBUG(
76262598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
76362598e31SEd Tanous             bootSource);
764ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
765944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
766944ffaf9SJohnathan Mantey         return -1;
767491d8ee7SSantosh Puranik     }
768944ffaf9SJohnathan Mantey     return 0;
769491d8ee7SSantosh Puranik }
7701981771bSAli Ahmed 
771978b8803SAndrew Geissler /**
772978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
773978b8803SAndrew Geissler  *
774ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
7755e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
776978b8803SAndrew Geissler  *
777978b8803SAndrew Geissler  * @return None.
778978b8803SAndrew Geissler  */
7795e7c1f31SOliver Brewka inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7805e7c1f31SOliver Brewka                             const uint64_t computerSystemIndex)
781978b8803SAndrew Geissler {
782*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
783*a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
784deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
785*a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
7861e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
787*a52f1d5bSEd Tanous         [asyncResp](const boost::system::error_code ec,
7881e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
789978b8803SAndrew Geissler             if (ec)
790978b8803SAndrew Geissler             {
791978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
792978b8803SAndrew Geissler                 // not found
793978b8803SAndrew Geissler                 return;
794978b8803SAndrew Geissler             }
795978b8803SAndrew Geissler 
79662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
797978b8803SAndrew Geissler 
798ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
799e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8001e1e598dSJonathan Doman         });
801978b8803SAndrew Geissler }
802491d8ee7SSantosh Puranik 
803491d8ee7SSantosh Puranik /**
804b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
805b6d5d45cSHieu Huynh  *
806ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
8075e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
808b6d5d45cSHieu Huynh  *
809b6d5d45cSHieu Huynh  * @return None.
810b6d5d45cSHieu Huynh  */
811b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
8125e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8135e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
814b6d5d45cSHieu Huynh {
815*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
816*a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
817deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
818*a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
819b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
820ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
821b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
822b6d5d45cSHieu Huynh             if (ec)
823b6d5d45cSHieu Huynh             {
82462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
825b6d5d45cSHieu Huynh                 return;
826b6d5d45cSHieu Huynh             }
827b6d5d45cSHieu Huynh 
828b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
829b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
830b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
831b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
832b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
833b6d5d45cSHieu Huynh 
834b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
835ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
836b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
837b6d5d45cSHieu Huynh         });
838b6d5d45cSHieu Huynh }
839b6d5d45cSHieu Huynh 
840b6d5d45cSHieu Huynh /**
841c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
842cd9a4666SKonstantin Aladyshev  *
843ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
8445e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
845cd9a4666SKonstantin Aladyshev  *
846cd9a4666SKonstantin Aladyshev  * @return None.
847cd9a4666SKonstantin Aladyshev  */
848504af5a0SPatrick Williams inline void getBootOverrideType(
8495e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8505e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
851cd9a4666SKonstantin Aladyshev {
8525e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
8535e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
8545e7c1f31SOliver Brewka     path /= "boot";
8555e7c1f31SOliver Brewka 
856deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
8575e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
8581e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
859ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8601e1e598dSJonathan Doman                     const std::string& bootType) {
861cd9a4666SKonstantin Aladyshev             if (ec)
862cd9a4666SKonstantin Aladyshev             {
863cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
864cd9a4666SKonstantin Aladyshev                 return;
865cd9a4666SKonstantin Aladyshev             }
866cd9a4666SKonstantin Aladyshev 
86762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
868cd9a4666SKonstantin Aladyshev 
869ac106bf6SEd Tanous             asyncResp->res
870ac106bf6SEd Tanous                 .jsonValue["Boot"]
871002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
872613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
873cd9a4666SKonstantin Aladyshev 
8741e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
875cd9a4666SKonstantin Aladyshev             if (rfType.empty())
876cd9a4666SKonstantin Aladyshev             {
877ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
878cd9a4666SKonstantin Aladyshev                 return;
879cd9a4666SKonstantin Aladyshev             }
880cd9a4666SKonstantin Aladyshev 
881ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8821e1e598dSJonathan Doman         });
883cd9a4666SKonstantin Aladyshev }
884cd9a4666SKonstantin Aladyshev 
885cd9a4666SKonstantin Aladyshev /**
886c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
887491d8ee7SSantosh Puranik  *
888ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
8895e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
890491d8ee7SSantosh Puranik  *
891491d8ee7SSantosh Puranik  * @return None.
892491d8ee7SSantosh Puranik  */
893504af5a0SPatrick Williams inline void getBootOverrideMode(
8945e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8955e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
896491d8ee7SSantosh Puranik {
8975e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
8985e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
8995e7c1f31SOliver Brewka     path /= "boot";
900deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
9015e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9021e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
903ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9041e1e598dSJonathan Doman                     const std::string& bootModeStr) {
905491d8ee7SSantosh Puranik             if (ec)
906491d8ee7SSantosh Puranik             {
907b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
908ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
909491d8ee7SSantosh Puranik                 return;
910491d8ee7SSantosh Puranik             }
911491d8ee7SSantosh Puranik 
91262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
913491d8ee7SSantosh Puranik 
91420fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
91520fa6a2cSEd Tanous             allowed.emplace_back("None");
91620fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
91720fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
91820fa6a2cSEd Tanous             allowed.emplace_back("Cd");
91920fa6a2cSEd Tanous             allowed.emplace_back("Diags");
92020fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
92120fa6a2cSEd Tanous             allowed.emplace_back("Usb");
92220fa6a2cSEd Tanous 
923ac106bf6SEd Tanous             asyncResp->res
9240fda0f12SGeorge Liu                 .jsonValue["Boot"]
92520fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
92620fa6a2cSEd Tanous                 std::move(allowed);
9271e1e598dSJonathan Doman             if (bootModeStr !=
928491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
929491d8ee7SSantosh Puranik             {
9301e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
931491d8ee7SSantosh Puranik                 if (!rfMode.empty())
932491d8ee7SSantosh Puranik                 {
933bd79bce8SPatrick Williams                     asyncResp->res
934bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
935491d8ee7SSantosh Puranik                 }
936491d8ee7SSantosh Puranik             }
9371e1e598dSJonathan Doman         });
938491d8ee7SSantosh Puranik }
939491d8ee7SSantosh Puranik 
940491d8ee7SSantosh Puranik /**
941c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
942491d8ee7SSantosh Puranik  *
943ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
9445e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
945491d8ee7SSantosh Puranik  *
946491d8ee7SSantosh Puranik  * @return None.
947491d8ee7SSantosh Puranik  */
948504af5a0SPatrick Williams inline void getBootOverrideSource(
9495e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9505e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
951491d8ee7SSantosh Puranik {
9525e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
9535e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
9545e7c1f31SOliver Brewka     path /= "boot";
9555e7c1f31SOliver Brewka 
956deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
9575e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9581e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
9595e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
9601e1e598dSJonathan Doman                                          const std::string& bootSourceStr) {
961491d8ee7SSantosh Puranik             if (ec)
962491d8ee7SSantosh Puranik             {
9638f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
9648f1a35b9SAllen.Wang                 // Boot Override Source information
9658f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
9668f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
9675ef735c8SNan Zhou                 {
9688f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
969ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
9708f1a35b9SAllen.Wang                 }
971491d8ee7SSantosh Puranik                 return;
972491d8ee7SSantosh Puranik             }
973491d8ee7SSantosh Puranik 
97462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
975491d8ee7SSantosh Puranik 
9761e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
977491d8ee7SSantosh Puranik             if (!rfSource.empty())
978491d8ee7SSantosh Puranik             {
979ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
980ac106bf6SEd Tanous                     rfSource;
981491d8ee7SSantosh Puranik             }
982cd9a4666SKonstantin Aladyshev 
983cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
984cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
9855e7c1f31SOliver Brewka             getBootOverrideMode(asyncResp, computerSystemIndex);
9861e1e598dSJonathan Doman         });
987491d8ee7SSantosh Puranik }
988491d8ee7SSantosh Puranik 
989491d8ee7SSantosh Puranik /**
990c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
991c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
992c21865c4SKonstantin Aladyshev  * state
993491d8ee7SSantosh Puranik  *
994ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
9955e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
9965e7c1f31SOliver Brewka  * @param[in] bootOverrideEnableSetting
997491d8ee7SSantosh Puranik  *
998491d8ee7SSantosh Puranik  * @return None.
999491d8ee7SSantosh Puranik  */
1000491d8ee7SSantosh Puranik 
1001ac106bf6SEd Tanous inline void processBootOverrideEnable(
1002ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10035e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const bool bootOverrideEnableSetting)
1004c21865c4SKonstantin Aladyshev {
1005c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1006c21865c4SKonstantin Aladyshev     {
1007ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1008ac106bf6SEd Tanous             "Disabled";
1009c21865c4SKonstantin Aladyshev         return;
1010c21865c4SKonstantin Aladyshev     }
1011c21865c4SKonstantin Aladyshev 
10125e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
10135e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
10145e7c1f31SOliver Brewka     path /= "boot";
10155e7c1f31SOliver Brewka     path /= "one_time";
10165e7c1f31SOliver Brewka 
1017c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1018c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1019deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
10205e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
10211e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1022ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1023491d8ee7SSantosh Puranik             if (ec)
1024491d8ee7SSantosh Puranik             {
1025b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1026ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1027491d8ee7SSantosh Puranik                 return;
1028491d8ee7SSantosh Puranik             }
1029491d8ee7SSantosh Puranik 
1030c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1031c21865c4SKonstantin Aladyshev             {
1032ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1033ac106bf6SEd Tanous                     "Once";
1034c21865c4SKonstantin Aladyshev             }
1035c21865c4SKonstantin Aladyshev             else
1036c21865c4SKonstantin Aladyshev             {
1037ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1038c21865c4SKonstantin Aladyshev                     "Continuous";
1039c21865c4SKonstantin Aladyshev             }
10401e1e598dSJonathan Doman         });
1041491d8ee7SSantosh Puranik }
1042491d8ee7SSantosh Puranik 
1043491d8ee7SSantosh Puranik /**
1044c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1045c21865c4SKonstantin Aladyshev  *
1046ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
10475e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1048c21865c4SKonstantin Aladyshev  *
1049c21865c4SKonstantin Aladyshev  * @return None.
1050c21865c4SKonstantin Aladyshev  */
1051504af5a0SPatrick Williams inline void getBootOverrideEnable(
10525e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10535e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1054c21865c4SKonstantin Aladyshev {
10555e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
10565e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
10575e7c1f31SOliver Brewka     path /= "boot";
10585e7c1f31SOliver Brewka 
1059deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
10605e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
10611e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10625e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
10631e1e598dSJonathan Doman                                          const bool bootOverrideEnable) {
1064c21865c4SKonstantin Aladyshev             if (ec)
1065c21865c4SKonstantin Aladyshev             {
10668f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
10678f1a35b9SAllen.Wang                 // Boot Override Enable information
10688f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
10698f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
10705ef735c8SNan Zhou                 {
10718f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
1072ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
10738f1a35b9SAllen.Wang                 }
1074c21865c4SKonstantin Aladyshev                 return;
1075c21865c4SKonstantin Aladyshev             }
1076c21865c4SKonstantin Aladyshev 
10775e7c1f31SOliver Brewka             processBootOverrideEnable(asyncResp, computerSystemIndex,
10785e7c1f31SOliver Brewka                                       bootOverrideEnable);
10791e1e598dSJonathan Doman         });
1080c21865c4SKonstantin Aladyshev }
1081c21865c4SKonstantin Aladyshev 
1082c21865c4SKonstantin Aladyshev /**
1083c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1084c21865c4SKonstantin Aladyshev  *
1085ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
10865e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1087c21865c4SKonstantin Aladyshev  *
1088c21865c4SKonstantin Aladyshev  * @return None.
1089c21865c4SKonstantin Aladyshev  */
1090504af5a0SPatrick Williams inline void getBootProperties(
10915e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10925e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1093c21865c4SKonstantin Aladyshev {
109462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1095c21865c4SKonstantin Aladyshev 
10965e7c1f31SOliver Brewka     getBootOverrideSource(asyncResp, computerSystemIndex);
10975e7c1f31SOliver Brewka     getBootOverrideType(asyncResp, computerSystemIndex);
10985e7c1f31SOliver Brewka     getBootOverrideEnable(asyncResp, computerSystemIndex);
1099c21865c4SKonstantin Aladyshev }
1100c21865c4SKonstantin Aladyshev 
1101c21865c4SKonstantin Aladyshev /**
1102c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1103c0557e1aSGunnar Mills  *
1104c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1105c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1106c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1107c0557e1aSGunnar Mills  * last power operation time.
1108c0557e1aSGunnar Mills  *
1109ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1110c0557e1aSGunnar Mills  *
1111c0557e1aSGunnar Mills  * @return None.
1112c0557e1aSGunnar Mills  */
1113504af5a0SPatrick Williams inline void getLastResetTime(
11145e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11155e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1116c0557e1aSGunnar Mills {
111762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1118*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
1119*a52f1d5bSEd Tanous         getChassisStateObjectPath(computerSystemIndex);
1120deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
1121*a52f1d5bSEd Tanous         getChassisStateServiceName(computerSystemIndex), path,
11221e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1123ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1124ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1125c0557e1aSGunnar Mills             if (ec)
1126c0557e1aSGunnar Mills             {
112762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1128c0557e1aSGunnar Mills                 return;
1129c0557e1aSGunnar Mills             }
1130c0557e1aSGunnar Mills 
1131c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1132c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11331e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1134c0557e1aSGunnar Mills 
1135c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1136ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11372b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11381e1e598dSJonathan Doman         });
1139c0557e1aSGunnar Mills }
1140c0557e1aSGunnar Mills 
1141c0557e1aSGunnar Mills /**
1142797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1143797d5daeSCorey Hardesty  *
1144797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1145797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1146797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1147797d5daeSCorey Hardesty  * dbus.
1148797d5daeSCorey Hardesty  *
1149ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
11505e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1151797d5daeSCorey Hardesty  *
1152797d5daeSCorey Hardesty  * @return None.
1153797d5daeSCorey Hardesty  */
1154ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
11555e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11565e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1157797d5daeSCorey Hardesty {
115862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1159*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
1160*a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
1161deae6a78SEd Tanous     dbus::utility::getAllProperties(
1162*a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
1163797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1164ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1165ac106bf6SEd Tanous             const boost::system::error_code& ec,
1166797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1167797d5daeSCorey Hardesty             if (ec)
1168797d5daeSCorey Hardesty             {
1169d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1170d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1171797d5daeSCorey Hardesty                 {
1172d39a8c28SAishwary Joshi                     // Service not available, no error, just don't return
1173d39a8c28SAishwary Joshi                     // RebootAttempts information
117462598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1175ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1176797d5daeSCorey Hardesty                 }
1177797d5daeSCorey Hardesty                 return;
1178797d5daeSCorey Hardesty             }
1179797d5daeSCorey Hardesty 
1180797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1181797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1182797d5daeSCorey Hardesty 
1183797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1184bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1185bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1186797d5daeSCorey Hardesty 
1187797d5daeSCorey Hardesty             if (!success)
1188797d5daeSCorey Hardesty             {
1189ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1190797d5daeSCorey Hardesty                 return;
1191797d5daeSCorey Hardesty             }
1192797d5daeSCorey Hardesty 
1193797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1194797d5daeSCorey Hardesty             {
1195ac106bf6SEd Tanous                 asyncResp->res
1196ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1197797d5daeSCorey Hardesty                     *attemptsLeft;
1198797d5daeSCorey Hardesty             }
1199797d5daeSCorey Hardesty 
1200797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1201797d5daeSCorey Hardesty             {
1202ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1203797d5daeSCorey Hardesty                     *retryAttempts;
1204797d5daeSCorey Hardesty             }
1205797d5daeSCorey Hardesty         });
1206797d5daeSCorey Hardesty }
1207797d5daeSCorey Hardesty 
1208797d5daeSCorey Hardesty /**
12096bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12106bd5a8d2SGunnar Mills  *
1211ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12125e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
12136bd5a8d2SGunnar Mills  *
12146bd5a8d2SGunnar Mills  * @return None.
12156bd5a8d2SGunnar Mills  */
1216504af5a0SPatrick Williams inline void getAutomaticRetryPolicy(
12175e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12185e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
12196bd5a8d2SGunnar Mills {
122062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12216bd5a8d2SGunnar Mills 
12225e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
12235e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
12245e7c1f31SOliver Brewka     path /= "auto_reboot";
12255e7c1f31SOliver Brewka 
1226deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
12275e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
12281e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12295e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
1230ac106bf6SEd Tanous                                          bool autoRebootEnabled) {
12316bd5a8d2SGunnar Mills             if (ec)
12326bd5a8d2SGunnar Mills             {
1233d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1234d39a8c28SAishwary Joshi                 // AutoReboot information
1235d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1236d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1237797d5daeSCorey Hardesty                 {
123862598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1239ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1240797d5daeSCorey Hardesty                 }
12416bd5a8d2SGunnar Mills                 return;
12426bd5a8d2SGunnar Mills             }
12436bd5a8d2SGunnar Mills 
124462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1245e05aec50SEd Tanous             if (autoRebootEnabled)
12466bd5a8d2SGunnar Mills             {
1247ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12486bd5a8d2SGunnar Mills                     "RetryAttempts";
12496bd5a8d2SGunnar Mills             }
12506bd5a8d2SGunnar Mills             else
12516bd5a8d2SGunnar Mills             {
1252ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1253ac106bf6SEd Tanous                     "Disabled";
12546bd5a8d2SGunnar Mills             }
12555e7c1f31SOliver Brewka             getAutomaticRebootAttempts(asyncResp, computerSystemIndex);
125669f35306SGunnar Mills 
125769f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
125869f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
125969f35306SGunnar Mills             // RetryAttempts.
126020fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
126120fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
126220fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1263ac106bf6SEd Tanous             asyncResp->res
1264bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1265bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
126620fa6a2cSEd Tanous                 std::move(allowed);
12671e1e598dSJonathan Doman         });
12686bd5a8d2SGunnar Mills }
12696bd5a8d2SGunnar Mills 
12706bd5a8d2SGunnar Mills /**
1271797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1272797d5daeSCorey Hardesty  *
1273ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
12745e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1275797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1276797d5daeSCorey Hardesty  *
1277797d5daeSCorey Hardesty  *@return None.
1278797d5daeSCorey Hardesty  */
1279797d5daeSCorey Hardesty 
1280ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1281ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1282d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const uint32_t retryAttempts)
1283797d5daeSCorey Hardesty {
128462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
1285d43cc6bcSOliver Brewka 
1286d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/AutomaticRetryAttempts",
1287d43cc6bcSOliver Brewka                     getHostStateServiceName(computerSystemIndex),
1288d43cc6bcSOliver Brewka                     getHostStateObjectPath(computerSystemIndex),
1289d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
1290d43cc6bcSOliver Brewka                     "RetryAttempts", retryAttempts);
1291797d5daeSCorey Hardesty }
1292797d5daeSCorey Hardesty 
12938d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12948d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12958d69c668SEd Tanous {
12968d69c668SEd Tanous     if (value ==
12978d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12988d69c668SEd Tanous     {
12998d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13008d69c668SEd Tanous     }
13018d69c668SEd Tanous     if (value ==
13028d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13038d69c668SEd Tanous     {
13048d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13058d69c668SEd Tanous     }
13068d69c668SEd Tanous     if (value ==
13073a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13088d69c668SEd Tanous     {
13098d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13108d69c668SEd Tanous     }
13118d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13128d69c668SEd Tanous     {
13138d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13148d69c668SEd Tanous     }
13158d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13168d69c668SEd Tanous }
1317797d5daeSCorey Hardesty /**
1318c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1319c6a620f2SGeorge Liu  *
1320ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1321c6a620f2SGeorge Liu  *
1322c6a620f2SGeorge Liu  * @return None.
1323c6a620f2SGeorge Liu  */
1324504af5a0SPatrick Williams inline void getPowerRestorePolicy(
13255e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13265e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1327c6a620f2SGeorge Liu {
132862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1329c6a620f2SGeorge Liu 
13305e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
13315e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
13325e7c1f31SOliver Brewka     path /= "power_restore_policy";
13335e7c1f31SOliver Brewka 
1334deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
13355e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
13361e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1337ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13385e7e2dc5SEd Tanous                     const std::string& policy) {
1339c6a620f2SGeorge Liu             if (ec)
1340c6a620f2SGeorge Liu             {
134162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1342c6a620f2SGeorge Liu                 return;
1343c6a620f2SGeorge Liu             }
13448d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
13458d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
13468d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1347c6a620f2SGeorge Liu             {
1348ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1349c6a620f2SGeorge Liu                 return;
1350c6a620f2SGeorge Liu             }
1351c6a620f2SGeorge Liu 
13528d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13531e1e598dSJonathan Doman         });
1354c6a620f2SGeorge Liu }
1355c6a620f2SGeorge Liu 
1356c6a620f2SGeorge Liu /**
13579dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13589dcfe8c1SAlbert Zhang  *
13599dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13609dcfe8c1SAlbert Zhang  *
13619dcfe8c1SAlbert Zhang  * @return None.
13629dcfe8c1SAlbert Zhang  */
1363504af5a0SPatrick Williams inline void getStopBootOnFault(
1364504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13659dcfe8c1SAlbert Zhang {
136662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13679dcfe8c1SAlbert Zhang 
1368deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1369deae6a78SEd Tanous         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
13709dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13719dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13729dcfe8c1SAlbert Zhang             if (ec)
13739dcfe8c1SAlbert Zhang             {
1374d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1375d39a8c28SAishwary Joshi                 // StopBootOnFault information
1376d39a8c28SAishwary Joshi                 if (ec.value() != EBADR ||
1377d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
13789dcfe8c1SAlbert Zhang                 {
1379b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13809dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
13819dcfe8c1SAlbert Zhang                 }
13829dcfe8c1SAlbert Zhang                 return;
13839dcfe8c1SAlbert Zhang             }
13849dcfe8c1SAlbert Zhang 
13859dcfe8c1SAlbert Zhang             if (value)
13869dcfe8c1SAlbert Zhang             {
1387539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1388539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
13899dcfe8c1SAlbert Zhang             }
13909dcfe8c1SAlbert Zhang             else
13919dcfe8c1SAlbert Zhang             {
1392539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1393539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
13949dcfe8c1SAlbert Zhang             }
13959dcfe8c1SAlbert Zhang         });
13969dcfe8c1SAlbert Zhang }
13979dcfe8c1SAlbert Zhang 
13985e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBootCallback(
13995e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14005e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const boost::system::error_code& ec,
14015e7c1f31SOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
14021981771bSAli Ahmed {
14031981771bSAli Ahmed     if (ec)
14041981771bSAli Ahmed     {
14055e7c1f31SOliver Brewka         BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", ec);
14061981771bSAli Ahmed         // This is an optional D-Bus object so just return if
14071981771bSAli Ahmed         // error occurs
14081981771bSAli Ahmed         return;
14091981771bSAli Ahmed     }
141026f6976fSEd Tanous     if (subtree.empty())
14111981771bSAli Ahmed     {
14121981771bSAli Ahmed         // As noted above, this is an optional interface so just return
14131981771bSAli Ahmed         // if there is no instance found
14141981771bSAli Ahmed         return;
14151981771bSAli Ahmed     }
14161981771bSAli Ahmed 
14175e7c1f31SOliver Brewka     std::string path;
14185e7c1f31SOliver Brewka     std::string service;
14195e7c1f31SOliver Brewka 
14205e7c1f31SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14211981771bSAli Ahmed     {
14225e7c1f31SOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
14235e7c1f31SOliver Brewka                                                subtree, path, service))
14245e7c1f31SOliver Brewka         {
14251981771bSAli Ahmed             return;
14261981771bSAli Ahmed         }
14275e7c1f31SOliver Brewka     }
14285e7c1f31SOliver Brewka     else
14295e7c1f31SOliver Brewka     {
14301981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14311981771bSAli Ahmed         // field
14321981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14331981771bSAli Ahmed         {
143462598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1435ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14361981771bSAli Ahmed             return;
14371981771bSAli Ahmed         }
14381981771bSAli Ahmed 
14395e7c1f31SOliver Brewka         path = subtree[0].first;
14405e7c1f31SOliver Brewka         service = subtree[0].second.begin()->first;
14415e7c1f31SOliver Brewka     }
14425e7c1f31SOliver Brewka 
14435e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm service {}", service);
14445e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm path {}", path);
14451981771bSAli Ahmed 
14461981771bSAli Ahmed     // Valid TPM Enable object found, now reading the current value
1447deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
14485e7c1f31SOliver Brewka         service, path, "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
14495e7c1f31SOliver Brewka         [asyncResp](const boost::system::error_code& ec2, bool tpmRequired) {
14508a592810SEd Tanous             if (ec2)
14511981771bSAli Ahmed             {
14525e7c1f31SOliver Brewka                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
14535e7c1f31SOliver Brewka                                  ec2);
1454ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14551981771bSAli Ahmed                 return;
14561981771bSAli Ahmed             }
14571981771bSAli Ahmed 
14581e1e598dSJonathan Doman             if (tpmRequired)
14591981771bSAli Ahmed             {
1460ac106bf6SEd Tanous                 asyncResp->res
1461ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14621981771bSAli Ahmed                     "Required";
14631981771bSAli Ahmed             }
14641981771bSAli Ahmed             else
14651981771bSAli Ahmed             {
1466ac106bf6SEd Tanous                 asyncResp->res
1467ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14681981771bSAli Ahmed                     "Disabled";
14691981771bSAli Ahmed             }
14701e1e598dSJonathan Doman         });
14715e7c1f31SOliver Brewka }
14725e7c1f31SOliver Brewka 
14735e7c1f31SOliver Brewka /**
14745e7c1f31SOliver Brewka  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14755e7c1f31SOliver Brewka  * TPM is required for booting the host.
14765e7c1f31SOliver Brewka  *
14775e7c1f31SOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
14785e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
14795e7c1f31SOliver Brewka  *
14805e7c1f31SOliver Brewka  * @return None.
14815e7c1f31SOliver Brewka  */
14825e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBoot(
14835e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14845e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
14855e7c1f31SOliver Brewka {
14865e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
14875e7c1f31SOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
14885e7c1f31SOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
14895e7c1f31SOliver Brewka     dbus::utility::getSubTree(
14905e7c1f31SOliver Brewka         "/", 0, interfaces,
14915e7c1f31SOliver Brewka         std::bind_front(getTrustedModuleRequiredToBootCallback, asyncResp,
14925e7c1f31SOliver Brewka                         computerSystemIndex));
14931981771bSAli Ahmed }
14941981771bSAli Ahmed 
1495d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBootCallback(
1496d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1497d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired,
1498d43cc6bcSOliver Brewka     const boost::system::error_code& ec,
1499d43cc6bcSOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
15001c05dae3SAli Ahmed {
15011c05dae3SAli Ahmed     if (ec)
15021c05dae3SAli Ahmed     {
1503d43cc6bcSOliver Brewka         BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", ec);
1504ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15051c05dae3SAli Ahmed         return;
15061c05dae3SAli Ahmed     }
150726f6976fSEd Tanous     if (subtree.empty())
15081c05dae3SAli Ahmed     {
1509d43cc6bcSOliver Brewka         messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15101c05dae3SAli Ahmed                                          "TrustedModuleRequiredToBoot");
15111c05dae3SAli Ahmed         return;
15121c05dae3SAli Ahmed     }
15131c05dae3SAli Ahmed 
1514d43cc6bcSOliver Brewka     std::string path;
1515d43cc6bcSOliver Brewka     std::string serv;
1516d43cc6bcSOliver Brewka 
1517d43cc6bcSOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
15181c05dae3SAli Ahmed     {
1519d43cc6bcSOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
1520d43cc6bcSOliver Brewka                                                subtree, path, serv))
1521d43cc6bcSOliver Brewka         {
1522d43cc6bcSOliver Brewka             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1523ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15241c05dae3SAli Ahmed             return;
15251c05dae3SAli Ahmed         }
1526d43cc6bcSOliver Brewka     }
1527d43cc6bcSOliver Brewka     else
1528d43cc6bcSOliver Brewka     {
15291c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15301c05dae3SAli Ahmed         // field
15311c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15321c05dae3SAli Ahmed         {
153362598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1534ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15351c05dae3SAli Ahmed             return;
15361c05dae3SAli Ahmed         }
15371c05dae3SAli Ahmed 
1538d43cc6bcSOliver Brewka         path = subtree[0].first;
1539d43cc6bcSOliver Brewka         serv = subtree[0].second.begin()->first;
1540d43cc6bcSOliver Brewka     }
15411c05dae3SAli Ahmed 
15421c05dae3SAli Ahmed     if (serv.empty())
15431c05dae3SAli Ahmed     {
154462598e31SEd Tanous         BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1545ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15461c05dae3SAli Ahmed         return;
15471c05dae3SAli Ahmed     }
15481c05dae3SAli Ahmed 
15491c05dae3SAli Ahmed     // Valid TPM Enable object found, now setting the value
1550d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, path,
1551d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1552d43cc6bcSOliver Brewka                     tpmRequired);
1553d43cc6bcSOliver Brewka }
1554d43cc6bcSOliver Brewka 
1555d43cc6bcSOliver Brewka /**
1556d43cc6bcSOliver Brewka  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1557d43cc6bcSOliver Brewka  * TPM is required for booting the host.
1558d43cc6bcSOliver Brewka  *
1559d43cc6bcSOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
1560d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1561d43cc6bcSOliver Brewka  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
1562d43cc6bcSOliver Brewka  *
1563d43cc6bcSOliver Brewka  * @return None.
1564d43cc6bcSOliver Brewka  */
1565d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBoot(
1566d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1567d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired)
1568d43cc6bcSOliver Brewka {
1569d43cc6bcSOliver Brewka     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1570d43cc6bcSOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
1571d43cc6bcSOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
1572d43cc6bcSOliver Brewka     dbus::utility::getSubTree(
1573d43cc6bcSOliver Brewka         "/", 0, interfaces,
1574d43cc6bcSOliver Brewka         std::bind_front(setTrustedModuleRequiredToBootCallback, asyncResp,
1575d43cc6bcSOliver Brewka                         computerSystemIndex, tpmRequired));
15761c05dae3SAli Ahmed }
15771c05dae3SAli Ahmed 
15781c05dae3SAli Ahmed /**
1579491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1580491d8ee7SSantosh Puranik  *
1581ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1582d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1583cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1584cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1585cd9a4666SKonstantin Aladyshev  */
1586ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1587d43cc6bcSOliver Brewka                         const uint64_t computerSystemIndex,
1588cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1589cd9a4666SKonstantin Aladyshev {
1590c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1591cd9a4666SKonstantin Aladyshev 
1592c21865c4SKonstantin Aladyshev     if (!bootType)
1593cd9a4666SKonstantin Aladyshev     {
1594c21865c4SKonstantin Aladyshev         return;
1595c21865c4SKonstantin Aladyshev     }
1596c21865c4SKonstantin Aladyshev 
1597cd9a4666SKonstantin Aladyshev     // Source target specified
159862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1599cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1600cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1601cd9a4666SKonstantin Aladyshev     {
1602cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1603cd9a4666SKonstantin Aladyshev     }
1604cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1605cd9a4666SKonstantin Aladyshev     {
1606cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1607cd9a4666SKonstantin Aladyshev     }
1608cd9a4666SKonstantin Aladyshev     else
1609cd9a4666SKonstantin Aladyshev     {
161062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
161162598e31SEd Tanous                          "BootSourceOverrideMode: {}",
161262598e31SEd Tanous                          *bootType);
1613ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1614cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1615cd9a4666SKonstantin Aladyshev         return;
1616cd9a4666SKonstantin Aladyshev     }
1617cd9a4666SKonstantin Aladyshev 
1618cd9a4666SKonstantin Aladyshev     // Act on validated parameters
161962598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1620cd9a4666SKonstantin Aladyshev 
1621d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1622d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1623d43cc6bcSOliver Brewka     path /= "boot";
1624e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1625d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
162687c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1627e93abac6SGinu George                     bootTypeStr);
1628cd9a4666SKonstantin Aladyshev }
1629cd9a4666SKonstantin Aladyshev 
1630cd9a4666SKonstantin Aladyshev /**
1631cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1632cd9a4666SKonstantin Aladyshev  *
1633ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1634ac106bf6SEd Tanous  * message.
1635d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1636c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1637c21865c4SKonstantin Aladyshev  * @return Integer error code.
1638c21865c4SKonstantin Aladyshev  */
1639ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1640d43cc6bcSOliver Brewka                           const uint64_t computerSystemIndex,
1641c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1642c21865c4SKonstantin Aladyshev {
1643c21865c4SKonstantin Aladyshev     if (!bootEnable)
1644c21865c4SKonstantin Aladyshev     {
1645c21865c4SKonstantin Aladyshev         return;
1646c21865c4SKonstantin Aladyshev     }
1647c21865c4SKonstantin Aladyshev     // Source target specified
164862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1649c21865c4SKonstantin Aladyshev 
1650c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1651c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1652c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1653c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1654c21865c4SKonstantin Aladyshev     {
1655c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1656c21865c4SKonstantin Aladyshev     }
1657c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1658c21865c4SKonstantin Aladyshev     {
1659c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1660c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1661c21865c4SKonstantin Aladyshev     }
1662c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1663c21865c4SKonstantin Aladyshev     {
1664c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1665c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1666c21865c4SKonstantin Aladyshev     }
1667c21865c4SKonstantin Aladyshev     else
1668c21865c4SKonstantin Aladyshev     {
166962598e31SEd Tanous         BMCWEB_LOG_DEBUG(
167062598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
167162598e31SEd Tanous             *bootEnable);
1672ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1673c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1674c21865c4SKonstantin Aladyshev         return;
1675c21865c4SKonstantin Aladyshev     }
1676c21865c4SKonstantin Aladyshev 
1677c21865c4SKonstantin Aladyshev     // Act on validated parameters
167862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1679c21865c4SKonstantin Aladyshev 
1680d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1681d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1682d43cc6bcSOliver Brewka     path /= "boot";
1683e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1684d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
168587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1686e93abac6SGinu George                     bootOverrideEnable);
1687c21865c4SKonstantin Aladyshev 
1688c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1689c21865c4SKonstantin Aladyshev     {
1690c21865c4SKonstantin Aladyshev         return;
1691c21865c4SKonstantin Aladyshev     }
1692c21865c4SKonstantin Aladyshev 
1693c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1694c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
169562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
169662598e31SEd Tanous                      bootOverridePersistent);
1697c21865c4SKonstantin Aladyshev 
1698d43cc6bcSOliver Brewka     path /= "one_time";
1699e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1700d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
170187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1702e93abac6SGinu George                     !bootOverridePersistent);
1703c21865c4SKonstantin Aladyshev }
1704c21865c4SKonstantin Aladyshev 
1705c21865c4SKonstantin Aladyshev /**
1706c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1707c21865c4SKonstantin Aladyshev  *
1708ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1709d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1710491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1711491d8ee7SSantosh Puranik  *
1712265c1602SJohnathan Mantey  * @return Integer error code.
1713491d8ee7SSantosh Puranik  */
1714504af5a0SPatrick Williams inline void setBootModeOrSource(
1715504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1716d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1717cd9a4666SKonstantin Aladyshev     const std::optional<std::string>& bootSource)
1718491d8ee7SSantosh Puranik {
1719c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1720c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1721944ffaf9SJohnathan Mantey 
1722c21865c4SKonstantin Aladyshev     if (!bootSource)
1723491d8ee7SSantosh Puranik     {
1724c21865c4SKonstantin Aladyshev         return;
1725c21865c4SKonstantin Aladyshev     }
1726c21865c4SKonstantin Aladyshev 
1727491d8ee7SSantosh Puranik     // Source target specified
172862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1729491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1730ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1731ac106bf6SEd Tanous                              bootModeStr) != 0)
1732491d8ee7SSantosh Puranik     {
173362598e31SEd Tanous         BMCWEB_LOG_DEBUG(
173462598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
173562598e31SEd Tanous             *bootSource);
1736ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1737491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1738491d8ee7SSantosh Puranik         return;
1739491d8ee7SSantosh Puranik     }
1740491d8ee7SSantosh Puranik 
1741944ffaf9SJohnathan Mantey     // Act on validated parameters
174262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
174362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1744944ffaf9SJohnathan Mantey 
1745d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1746d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1747d43cc6bcSOliver Brewka     path /= "boot";
1748e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1749d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
175087c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1751e93abac6SGinu George                     bootSourceStr);
1752e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1753d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
175487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1755e93abac6SGinu George                     bootModeStr);
1756cd9a4666SKonstantin Aladyshev }
1757944ffaf9SJohnathan Mantey 
1758cd9a4666SKonstantin Aladyshev /**
1759c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1760491d8ee7SSantosh Puranik  *
1761ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1762d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1763491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1764cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1765491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1766491d8ee7SSantosh Puranik  *
1767265c1602SJohnathan Mantey  * @return Integer error code.
1768491d8ee7SSantosh Puranik  */
1769c21865c4SKonstantin Aladyshev 
1770504af5a0SPatrick Williams inline void setBootProperties(
1771504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1772d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1773c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootSource,
1774c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootType,
1775c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootEnable)
1776491d8ee7SSantosh Puranik {
177762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1778491d8ee7SSantosh Puranik 
1779d43cc6bcSOliver Brewka     setBootModeOrSource(asyncResp, computerSystemIndex, bootSource);
1780d43cc6bcSOliver Brewka     setBootType(asyncResp, computerSystemIndex, bootType);
1781d43cc6bcSOliver Brewka     setBootEnable(asyncResp, computerSystemIndex, bootEnable);
1782491d8ee7SSantosh Puranik }
1783491d8ee7SSantosh Puranik 
1784c6a620f2SGeorge Liu /**
178598e386ecSGunnar Mills  * @brief Sets AssetTag
178698e386ecSGunnar Mills  *
1787ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
178898e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
178998e386ecSGunnar Mills  *
179098e386ecSGunnar Mills  * @return None.
179198e386ecSGunnar Mills  */
1792ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
179398e386ecSGunnar Mills                         const std::string& assetTag)
179498e386ecSGunnar Mills {
1795e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1796e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1797e99073f5SGeorge Liu     dbus::utility::getSubTree(
1798e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1799ac106bf6SEd Tanous         [asyncResp,
1800e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1801b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
180298e386ecSGunnar Mills             if (ec)
180398e386ecSGunnar Mills             {
180462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1805ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
180698e386ecSGunnar Mills                 return;
180798e386ecSGunnar Mills             }
180826f6976fSEd Tanous             if (subtree.empty())
180998e386ecSGunnar Mills             {
181062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1811ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
181298e386ecSGunnar Mills                 return;
181398e386ecSGunnar Mills             }
181498e386ecSGunnar Mills             // Assume only 1 system D-Bus object
181598e386ecSGunnar Mills             // Throw an error if there is more than 1
181698e386ecSGunnar Mills             if (subtree.size() > 1)
181798e386ecSGunnar Mills             {
181862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1819ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
182098e386ecSGunnar Mills                 return;
182198e386ecSGunnar Mills             }
182298e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
182398e386ecSGunnar Mills             {
182462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1825ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
182698e386ecSGunnar Mills                 return;
182798e386ecSGunnar Mills             }
182898e386ecSGunnar Mills 
182998e386ecSGunnar Mills             const std::string& path = subtree[0].first;
183098e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
183198e386ecSGunnar Mills 
183298e386ecSGunnar Mills             if (service.empty())
183398e386ecSGunnar Mills             {
183462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1835ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
183698e386ecSGunnar Mills                 return;
183798e386ecSGunnar Mills             }
183898e386ecSGunnar Mills 
1839e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
184087c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1841e93abac6SGinu George                             "AssetTag", assetTag);
1842e99073f5SGeorge Liu         });
184398e386ecSGunnar Mills }
184498e386ecSGunnar Mills 
184598e386ecSGunnar Mills /**
18469dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18479dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18489dcfe8c1SAlbert Zhang  *
18499dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18509dcfe8c1SAlbert Zhang  * stopBootOnFault
18519dcfe8c1SAlbert Zhang  *
18529dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18539dcfe8c1SAlbert Zhang  */
1854504af5a0SPatrick Williams inline std::optional<bool> validstopBootOnFault(
1855504af5a0SPatrick Williams     const std::string& stopBootOnFaultString)
18569dcfe8c1SAlbert Zhang {
18579dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18589dcfe8c1SAlbert Zhang     {
18599dcfe8c1SAlbert Zhang         return true;
18609dcfe8c1SAlbert Zhang     }
18619dcfe8c1SAlbert Zhang 
18629dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18639dcfe8c1SAlbert Zhang     {
18649dcfe8c1SAlbert Zhang         return false;
18659dcfe8c1SAlbert Zhang     }
18669dcfe8c1SAlbert Zhang 
18679dcfe8c1SAlbert Zhang     return std::nullopt;
18689dcfe8c1SAlbert Zhang }
18699dcfe8c1SAlbert Zhang 
18709dcfe8c1SAlbert Zhang /**
18719dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18729dcfe8c1SAlbert Zhang  *
1873fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18749dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18759dcfe8c1SAlbert Zhang  *
18769dcfe8c1SAlbert Zhang  * @return None.
18779dcfe8c1SAlbert Zhang  */
1878504af5a0SPatrick Williams inline void setStopBootOnFault(
1879504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18809dcfe8c1SAlbert Zhang     const std::string& stopBootOnFault)
18819dcfe8c1SAlbert Zhang {
188262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18839dcfe8c1SAlbert Zhang 
18849dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18859dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18869dcfe8c1SAlbert Zhang     {
188762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
188862598e31SEd Tanous                          stopBootOnFault);
1889fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18909dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18919dcfe8c1SAlbert Zhang         return;
18929dcfe8c1SAlbert Zhang     }
18939dcfe8c1SAlbert Zhang 
1894e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1895e93abac6SGinu George                     "xyz.openbmc_project.Settings",
189687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
189787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1898fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1899e93abac6SGinu George                     *stopBootEnabled);
19009dcfe8c1SAlbert Zhang }
19019dcfe8c1SAlbert Zhang 
19029dcfe8c1SAlbert Zhang /**
190369f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
190469f35306SGunnar Mills  *
1905ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1906d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
190769f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
190869f35306SGunnar Mills  *
190969f35306SGunnar Mills  * @return None.
191069f35306SGunnar Mills  */
1911504af5a0SPatrick Williams inline void setAutomaticRetry(
1912504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1913d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const std::string& automaticRetryConfig)
191469f35306SGunnar Mills {
191562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
191669f35306SGunnar Mills 
191769f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1918543f4400SEd Tanous     bool autoRebootEnabled = false;
191969f35306SGunnar Mills 
192069f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
192169f35306SGunnar Mills     {
192269f35306SGunnar Mills         autoRebootEnabled = false;
192369f35306SGunnar Mills     }
192469f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
192569f35306SGunnar Mills     {
192669f35306SGunnar Mills         autoRebootEnabled = true;
192769f35306SGunnar Mills     }
192869f35306SGunnar Mills     else
192969f35306SGunnar Mills     {
193062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
193162598e31SEd Tanous                          automaticRetryConfig);
1932ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
193369f35306SGunnar Mills                                          "AutomaticRetryConfig");
193469f35306SGunnar Mills         return;
193569f35306SGunnar Mills     }
193669f35306SGunnar Mills 
1937d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1938d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1939d43cc6bcSOliver Brewka     path /= "auto_reboot";
1940e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1941d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
194287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1943e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
194469f35306SGunnar Mills }
194569f35306SGunnar Mills 
19468d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19478d69c668SEd Tanous {
19488d69c668SEd Tanous     if (policy == "AlwaysOn")
19498d69c668SEd Tanous     {
19508d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19518d69c668SEd Tanous     }
19528d69c668SEd Tanous     if (policy == "AlwaysOff")
19538d69c668SEd Tanous     {
19548d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19558d69c668SEd Tanous     }
19568d69c668SEd Tanous     if (policy == "LastState")
19578d69c668SEd Tanous     {
19588d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19598d69c668SEd Tanous     }
19608d69c668SEd Tanous     return "";
19618d69c668SEd Tanous }
19628d69c668SEd Tanous 
196369f35306SGunnar Mills /**
1964c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1965c6a620f2SGeorge Liu  *
1966ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1967d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1968c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1969c6a620f2SGeorge Liu  *
1970c6a620f2SGeorge Liu  * @return None.
1971c6a620f2SGeorge Liu  */
1972504af5a0SPatrick Williams inline void setPowerRestorePolicy(
1973504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1974d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, std::string_view policy)
1975c6a620f2SGeorge Liu {
197662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1977c6a620f2SGeorge Liu 
19788d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1979c6a620f2SGeorge Liu 
19808d69c668SEd Tanous     if (powerRestorePolicy.empty())
1981c6a620f2SGeorge Liu     {
1982ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19834e69c904SGunnar Mills                                          "PowerRestorePolicy");
1984c6a620f2SGeorge Liu         return;
1985c6a620f2SGeorge Liu     }
1986c6a620f2SGeorge Liu 
1987d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1988d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1989d43cc6bcSOliver Brewka     path /= "power_restore_policy";
1990d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "PowerRestorePolicy",
1991d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
1992d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Power.RestorePolicy",
1993d43cc6bcSOliver Brewka                     "PowerRestorePolicy", powerRestorePolicy);
1994c6a620f2SGeorge Liu }
1995c6a620f2SGeorge Liu 
1996a6349918SAppaRao Puli /**
1997a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1998a6349918SAppaRao Puli  *
199925b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
200025b54dbaSEd Tanous  * calls.
2001a6349918SAppaRao Puli  *
2002a6349918SAppaRao Puli  * @return None.
2003a6349918SAppaRao Puli  */
2004504af5a0SPatrick Williams inline void getProvisioningStatus(
2005504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2006a6349918SAppaRao Puli {
200762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2008deae6a78SEd Tanous     dbus::utility::getAllProperties(
2009deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2010deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Attributes",
2011ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2012b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2013b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
2014bd79bce8SPatrick Williams                 asyncResp->res
2015bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2016ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
20171d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
2018bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
2019bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
202050626f4fSJames Feist 
2021a6349918SAppaRao Puli             if (ec)
2022a6349918SAppaRao Puli             {
202362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2024b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
2025539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2026539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2027a6349918SAppaRao Puli                 return;
2028a6349918SAppaRao Puli             }
2029a6349918SAppaRao Puli 
2030a6349918SAppaRao Puli             const bool* provState = nullptr;
2031a6349918SAppaRao Puli             const bool* lockState = nullptr;
2032bc1d29deSKrzysztof Grobelny 
2033bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2034bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
2035bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
2036bc1d29deSKrzysztof Grobelny 
2037bc1d29deSKrzysztof Grobelny             if (!success)
2038a6349918SAppaRao Puli             {
2039ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2040bc1d29deSKrzysztof Grobelny                 return;
2041a6349918SAppaRao Puli             }
2042a6349918SAppaRao Puli 
2043a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2044a6349918SAppaRao Puli             {
204562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2046ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2047a6349918SAppaRao Puli                 return;
2048a6349918SAppaRao Puli             }
2049a6349918SAppaRao Puli 
205025b54dbaSEd Tanous             if (*provState)
2051a6349918SAppaRao Puli             {
205225b54dbaSEd Tanous                 if (*lockState)
2053a6349918SAppaRao Puli                 {
2054539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2055539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2056a6349918SAppaRao Puli                 }
2057a6349918SAppaRao Puli                 else
2058a6349918SAppaRao Puli                 {
2059539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2060539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2061a6349918SAppaRao Puli                 }
2062a6349918SAppaRao Puli             }
2063a6349918SAppaRao Puli             else
2064a6349918SAppaRao Puli             {
2065539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2066539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2067a6349918SAppaRao Puli             }
2068bc1d29deSKrzysztof Grobelny         });
2069a6349918SAppaRao Puli }
2070a6349918SAppaRao Puli 
2071491d8ee7SSantosh Puranik /**
20726b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20733a2d0424SChris Cain  *
20746b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20753a2d0424SChris Cain  *
20766b9ac4f2SChris Cain  * @return PowerMode enum
20773a2d0424SChris Cain  */
2078504af5a0SPatrick Williams inline computer_system::PowerMode translatePowerModeString(
2079504af5a0SPatrick Williams     const std::string& modeString)
20803a2d0424SChris Cain {
2081b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2082b6655101SChris Cain 
20836b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20843a2d0424SChris Cain     {
20856b9ac4f2SChris Cain         return PowerMode::Static;
20863a2d0424SChris Cain     }
20876b9ac4f2SChris Cain     if (modeString ==
20880fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20893a2d0424SChris Cain     {
20906b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20913a2d0424SChris Cain     }
20926b9ac4f2SChris Cain     if (modeString ==
20930fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20943a2d0424SChris Cain     {
20956b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2096b6655101SChris Cain     }
20976b9ac4f2SChris Cain     if (modeString ==
2098b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2099b6655101SChris Cain     {
21006b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2101b6655101SChris Cain     }
21026b9ac4f2SChris Cain     if (modeString ==
2103b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2104b6655101SChris Cain     {
21056b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2106b6655101SChris Cain     }
21076b9ac4f2SChris Cain     if (modeString ==
2108b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2109b6655101SChris Cain     {
21106b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
21113a2d0424SChris Cain     }
21126b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21133a2d0424SChris Cain     {
21146b9ac4f2SChris Cain         return PowerMode::OEM;
21156b9ac4f2SChris Cain     }
21166b9ac4f2SChris Cain     // Any other values would be invalid
21176b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
21186b9ac4f2SChris Cain     return PowerMode::Invalid;
21196b9ac4f2SChris Cain }
21206b9ac4f2SChris Cain 
2121504af5a0SPatrick Williams inline void afterGetPowerMode(
2122504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21236b9ac4f2SChris Cain     const boost::system::error_code& ec,
21246b9ac4f2SChris Cain     const dbus::utility::DBusPropertiesMap& properties)
21256b9ac4f2SChris Cain {
21266b9ac4f2SChris Cain     if (ec)
21276b9ac4f2SChris Cain     {
21286b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
21296b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21306b9ac4f2SChris Cain         return;
21316b9ac4f2SChris Cain     }
21326b9ac4f2SChris Cain 
21336b9ac4f2SChris Cain     std::string powerMode;
21346b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
21356b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
21366b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
21376b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21386b9ac4f2SChris Cain 
21396b9ac4f2SChris Cain     if (!success)
21406b9ac4f2SChris Cain     {
21416b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21426b9ac4f2SChris Cain         return;
21436b9ac4f2SChris Cain     }
21446b9ac4f2SChris Cain 
21456b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21466b9ac4f2SChris Cain     if (allowedModes == nullptr)
21476b9ac4f2SChris Cain     {
21486b9ac4f2SChris Cain         modeList.emplace_back("Static");
21496b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21506b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21513a2d0424SChris Cain     }
21523a2d0424SChris Cain     else
21533a2d0424SChris Cain     {
21546b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21556b9ac4f2SChris Cain         {
21566b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21576b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21586b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21596b9ac4f2SChris Cain             {
2160ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21616b9ac4f2SChris Cain                 continue;
21626b9ac4f2SChris Cain             }
21636b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21643a2d0424SChris Cain         }
21653a2d0424SChris Cain     }
21666b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21673a2d0424SChris Cain 
21686b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21696b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21706b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21716b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21726b9ac4f2SChris Cain     {
21736b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21746b9ac4f2SChris Cain         return;
21756b9ac4f2SChris Cain     }
21766b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21776b9ac4f2SChris Cain }
21783a2d0424SChris Cain /**
21793a2d0424SChris Cain  * @brief Retrieves system power mode
21803a2d0424SChris Cain  *
2181ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21823a2d0424SChris Cain  *
21833a2d0424SChris Cain  * @return None.
21843a2d0424SChris Cain  */
2185ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21863a2d0424SChris Cain {
218762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21883a2d0424SChris Cain 
21893a2d0424SChris Cain     // Get Power Mode object path:
2190e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2191e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2192e99073f5SGeorge Liu     dbus::utility::getSubTree(
2193e99073f5SGeorge Liu         "/", 0, interfaces,
2194ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2195b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21963a2d0424SChris Cain             if (ec)
21973a2d0424SChris Cain             {
2198bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2199bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
22003a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
22013a2d0424SChris Cain                 // error occurs
22023a2d0424SChris Cain                 return;
22033a2d0424SChris Cain             }
22043a2d0424SChris Cain             if (subtree.empty())
22053a2d0424SChris Cain             {
22063a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
22073a2d0424SChris Cain                 // if there is no instance found
22083a2d0424SChris Cain                 return;
22093a2d0424SChris Cain             }
22103a2d0424SChris Cain             if (subtree.size() > 1)
22113a2d0424SChris Cain             {
22123a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22133a2d0424SChris Cain                 // error
221462598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
221562598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
221662598e31SEd Tanous                     subtree.size());
2217ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22183a2d0424SChris Cain                 return;
22193a2d0424SChris Cain             }
22203a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22213a2d0424SChris Cain             {
222262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2223ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22243a2d0424SChris Cain                 return;
22253a2d0424SChris Cain             }
22263a2d0424SChris Cain             const std::string& path = subtree[0].first;
22273a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22283a2d0424SChris Cain             if (service.empty())
22293a2d0424SChris Cain             {
223062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2231ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22323a2d0424SChris Cain                 return;
22333a2d0424SChris Cain             }
22346b9ac4f2SChris Cain 
22356b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
2236deae6a78SEd Tanous             dbus::utility::getAllProperties(
22371e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
22386b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2239bd79bce8SPatrick Williams                 [asyncResp](
2240bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
22416b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
22426b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
22431e1e598dSJonathan Doman                 });
2244e99073f5SGeorge Liu         });
22453a2d0424SChris Cain }
22463a2d0424SChris Cain 
22473a2d0424SChris Cain /**
22483a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22493a2d0424SChris Cain  * name associated with that string
22503a2d0424SChris Cain  *
2251ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2252b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22533a2d0424SChris Cain  *
22543a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22553a2d0424SChris Cain  */
2256504af5a0SPatrick Williams inline std::string validatePowerMode(
2257504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2258b6655101SChris Cain     const nlohmann::json& modeValue)
22593a2d0424SChris Cain {
2260b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22613a2d0424SChris Cain     std::string mode;
22623a2d0424SChris Cain 
2263b6655101SChris Cain     if (modeValue == PowerMode::Static)
22643a2d0424SChris Cain     {
22653a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22663a2d0424SChris Cain     }
2267b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22683a2d0424SChris Cain     {
22690fda0f12SGeorge Liu         mode =
22700fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22713a2d0424SChris Cain     }
2272b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22733a2d0424SChris Cain     {
22743a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22753a2d0424SChris Cain     }
2276b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2277b6655101SChris Cain     {
2278b6655101SChris Cain         mode =
2279b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2280b6655101SChris Cain     }
2281b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2282b6655101SChris Cain     {
2283b6655101SChris Cain         mode =
2284b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2285b6655101SChris Cain     }
2286b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2287b6655101SChris Cain     {
2288b6655101SChris Cain         mode =
2289b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2290b6655101SChris Cain     }
22913a2d0424SChris Cain     else
22923a2d0424SChris Cain     {
2293b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2294ac106bf6SEd Tanous                                          "PowerMode");
22953a2d0424SChris Cain     }
22963a2d0424SChris Cain     return mode;
22973a2d0424SChris Cain }
22983a2d0424SChris Cain 
22993a2d0424SChris Cain /**
23003a2d0424SChris Cain  * @brief Sets system power mode.
23013a2d0424SChris Cain  *
2302ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23033a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23043a2d0424SChris Cain  *
23053a2d0424SChris Cain  * @return None.
23063a2d0424SChris Cain  */
2307ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23083a2d0424SChris Cain                          const std::string& pmode)
23093a2d0424SChris Cain {
231062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
23113a2d0424SChris Cain 
2312ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23133a2d0424SChris Cain     if (powerMode.empty())
23143a2d0424SChris Cain     {
23153a2d0424SChris Cain         return;
23163a2d0424SChris Cain     }
23173a2d0424SChris Cain 
23183a2d0424SChris Cain     // Get Power Mode object path:
2319e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2320e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2321e99073f5SGeorge Liu     dbus::utility::getSubTree(
2322e99073f5SGeorge Liu         "/", 0, interfaces,
2323ac106bf6SEd Tanous         [asyncResp,
2324e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2325b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23263a2d0424SChris Cain             if (ec)
23273a2d0424SChris Cain             {
2328bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2329bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
23303a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2331ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23323a2d0424SChris Cain                 return;
23333a2d0424SChris Cain             }
23343a2d0424SChris Cain             if (subtree.empty())
23353a2d0424SChris Cain             {
23363a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2337ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23383a2d0424SChris Cain                                            "PowerMode");
23393a2d0424SChris Cain                 return;
23403a2d0424SChris Cain             }
23413a2d0424SChris Cain             if (subtree.size() > 1)
23423a2d0424SChris Cain             {
23433a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
23443a2d0424SChris Cain                 // error
234562598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
234662598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
234762598e31SEd Tanous                     subtree.size());
2348ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23493a2d0424SChris Cain                 return;
23503a2d0424SChris Cain             }
23513a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23523a2d0424SChris Cain             {
235362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2354ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23553a2d0424SChris Cain                 return;
23563a2d0424SChris Cain             }
23573a2d0424SChris Cain             const std::string& path = subtree[0].first;
23583a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
23593a2d0424SChris Cain             if (service.empty())
23603a2d0424SChris Cain             {
236162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2362ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23633a2d0424SChris Cain                 return;
23643a2d0424SChris Cain             }
23653a2d0424SChris Cain 
236662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23673a2d0424SChris Cain 
23683a2d0424SChris Cain             // Set the Power Mode property
2369e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2370bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2371bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2372e99073f5SGeorge Liu         });
23733a2d0424SChris Cain }
23743a2d0424SChris Cain 
23753a2d0424SChris Cain /**
237651709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
237751709ffdSYong Li  *
237851709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
237951709ffdSYong Li  *
238051709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
238151709ffdSYong Li  * translation cannot be done, returns an empty string.
238251709ffdSYong Li  */
238323a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
238451709ffdSYong Li {
238551709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
238651709ffdSYong Li     {
238751709ffdSYong Li         return "None";
238851709ffdSYong Li     }
23893174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
239051709ffdSYong Li     {
239151709ffdSYong Li         return "ResetSystem";
239251709ffdSYong Li     }
23933174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
239451709ffdSYong Li     {
239551709ffdSYong Li         return "PowerDown";
239651709ffdSYong Li     }
23973174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
239851709ffdSYong Li     {
239951709ffdSYong Li         return "PowerCycle";
240051709ffdSYong Li     }
240151709ffdSYong Li 
240251709ffdSYong Li     return "";
240351709ffdSYong Li }
240451709ffdSYong Li 
240551709ffdSYong Li /**
2406c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2407c45f0082SYong Li  *
2408c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2409c45f0082SYong Li  *
2410c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2411c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2412c45f0082SYong Li  */
2413c45f0082SYong Li 
241423a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2415c45f0082SYong Li {
2416c45f0082SYong Li     if (rfAction == "None")
2417c45f0082SYong Li     {
2418c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2419c45f0082SYong Li     }
24203174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2421c45f0082SYong Li     {
2422c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2423c45f0082SYong Li     }
24243174e4dfSEd Tanous     if (rfAction == "PowerDown")
2425c45f0082SYong Li     {
2426c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2427c45f0082SYong Li     }
24283174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2429c45f0082SYong Li     {
2430c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2431c45f0082SYong Li     }
2432c45f0082SYong Li 
2433c45f0082SYong Li     return "";
2434c45f0082SYong Li }
2435c45f0082SYong Li 
2436c45f0082SYong Li /**
243751709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
243851709ffdSYong Li  *
2439ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
244051709ffdSYong Li  *
244151709ffdSYong Li  * @return None.
244251709ffdSYong Li  */
2443504af5a0SPatrick Williams inline void getHostWatchdogTimer(
2444504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
244551709ffdSYong Li {
244662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2447deae6a78SEd Tanous     dbus::utility::getAllProperties(
2448deae6a78SEd Tanous         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2449bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2450ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2451b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
245251709ffdSYong Li             if (ec)
245351709ffdSYong Li             {
245451709ffdSYong Li                 // watchdog service is stopped
245562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
245651709ffdSYong Li                 return;
245751709ffdSYong Li             }
245851709ffdSYong Li 
245962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
246051709ffdSYong Li 
246151709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2462ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
246351709ffdSYong Li 
246451709ffdSYong Li             // watchdog service is running/enabled
2465539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
246651709ffdSYong Li 
2467bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2468bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
246951709ffdSYong Li 
2470bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2471bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2472bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2473bc1d29deSKrzysztof Grobelny 
2474bc1d29deSKrzysztof Grobelny             if (!success)
247551709ffdSYong Li             {
2476ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2477601af5edSChicago Duan                 return;
247851709ffdSYong Li             }
247951709ffdSYong Li 
2480bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
248151709ffdSYong Li             {
2482bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
248351709ffdSYong Li             }
248451709ffdSYong Li 
2485bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2486bc1d29deSKrzysztof Grobelny             {
2487bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
248851709ffdSYong Li                 if (action.empty())
248951709ffdSYong Li                 {
2490ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2491601af5edSChicago Duan                     return;
249251709ffdSYong Li                 }
249351709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
249451709ffdSYong Li             }
2495bc1d29deSKrzysztof Grobelny         });
249651709ffdSYong Li }
249751709ffdSYong Li 
249851709ffdSYong Li /**
2499c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2500c45f0082SYong Li  *
2501ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2502c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2503c45f0082SYong Li  *                       RF request.
2504c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2505c45f0082SYong Li  *
2506c45f0082SYong Li  * @return None.
2507c45f0082SYong Li  */
2508504af5a0SPatrick Williams inline void setWDTProperties(
2509504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2510c45f0082SYong Li     const std::optional<bool> wdtEnable,
2511c45f0082SYong Li     const std::optional<std::string>& wdtTimeOutAction)
2512c45f0082SYong Li {
251362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2514c45f0082SYong Li 
2515c45f0082SYong Li     if (wdtTimeOutAction)
2516c45f0082SYong Li     {
2517c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2518c45f0082SYong Li         // check if TimeOut Action is Valid
2519c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2520c45f0082SYong Li         {
252162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
252262598e31SEd Tanous                              *wdtTimeOutAction);
2523ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2524c45f0082SYong Li                                              "TimeoutAction");
2525c45f0082SYong Li             return;
2526c45f0082SYong Li         }
2527c45f0082SYong Li 
2528e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2529e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
253087c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
253187c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
25329ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2533e93abac6SGinu George                         wdtTimeOutActStr);
2534c45f0082SYong Li     }
2535c45f0082SYong Li 
2536c45f0082SYong Li     if (wdtEnable)
2537c45f0082SYong Li     {
2538e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2539e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
254087c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
254187c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
254287c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2543e93abac6SGinu George                         *wdtEnable);
2544c45f0082SYong Li     }
2545c45f0082SYong Li }
2546c45f0082SYong Li 
254737bbf98cSChris Cain /**
254837bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
254937bbf98cSChris Cain  *
2550ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
255137bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
255237bbf98cSChris Cain  *
255337bbf98cSChris Cain  * @return true if successful
255437bbf98cSChris Cain  */
2555504af5a0SPatrick Williams inline bool parseIpsProperties(
2556504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25571e5b7c88SJiaqing Zhao     const dbus::utility::DBusPropertiesMap& properties)
255837bbf98cSChris Cain {
2559bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2560bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2561bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2562bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2563bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2564bc1d29deSKrzysztof Grobelny 
2565bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2566bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25672661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25682661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25692661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2570bc1d29deSKrzysztof Grobelny 
2571bc1d29deSKrzysztof Grobelny     if (!success)
257237bbf98cSChris Cain     {
257337bbf98cSChris Cain         return false;
257437bbf98cSChris Cain     }
2575bc1d29deSKrzysztof Grobelny 
2576bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
257737bbf98cSChris Cain     {
2578ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
257937bbf98cSChris Cain     }
2580bc1d29deSKrzysztof Grobelny 
2581bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
258237bbf98cSChris Cain     {
2583ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2584bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
258537bbf98cSChris Cain     }
2586bc1d29deSKrzysztof Grobelny 
2587bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2588bc1d29deSKrzysztof Grobelny     {
2589bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2590ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
259137bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
259237bbf98cSChris Cain                 .count();
259337bbf98cSChris Cain     }
2594bc1d29deSKrzysztof Grobelny 
2595bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
259637bbf98cSChris Cain     {
2597ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2598bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
259937bbf98cSChris Cain     }
2600bc1d29deSKrzysztof Grobelny 
2601bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
260237bbf98cSChris Cain     {
2603bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2604ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
260537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
260637bbf98cSChris Cain                 .count();
260737bbf98cSChris Cain     }
260837bbf98cSChris Cain 
260937bbf98cSChris Cain     return true;
261037bbf98cSChris Cain }
261137bbf98cSChris Cain 
261237bbf98cSChris Cain /**
26135e7c1f31SOliver Brewka  * @brief Retrieves idle power saver properties over DBUS
261437bbf98cSChris Cain  *
2615ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
261637bbf98cSChris Cain  *
261737bbf98cSChris Cain  * @return None.
261837bbf98cSChris Cain  */
2619504af5a0SPatrick Williams inline void getIdlePowerSaver(
2620504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
262137bbf98cSChris Cain {
262262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
262337bbf98cSChris Cain 
262437bbf98cSChris Cain     // Get IdlePowerSaver object path:
2625e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2626e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2627e99073f5SGeorge Liu     dbus::utility::getSubTree(
2628e99073f5SGeorge Liu         "/", 0, interfaces,
2629ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2630b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
263137bbf98cSChris Cain             if (ec)
263237bbf98cSChris Cain             {
2633b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
263462598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
263562598e31SEd Tanous                     ec);
2636ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
263737bbf98cSChris Cain                 return;
263837bbf98cSChris Cain             }
263937bbf98cSChris Cain             if (subtree.empty())
264037bbf98cSChris Cain             {
264137bbf98cSChris Cain                 // This is an optional interface so just return
264237bbf98cSChris Cain                 // if there is no instance found
264362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
264437bbf98cSChris Cain                 return;
264537bbf98cSChris Cain             }
264637bbf98cSChris Cain             if (subtree.size() > 1)
264737bbf98cSChris Cain             {
264837bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
264937bbf98cSChris Cain                 // is an error
26505e7c1f31SOliver Brewka                 BMCWEB_LOG_DEBUG(
26515e7c1f31SOliver Brewka                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
265262598e31SEd Tanous                     subtree.size());
2653ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
265437bbf98cSChris Cain                 return;
265537bbf98cSChris Cain             }
265637bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
265737bbf98cSChris Cain             {
265862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2659ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
266037bbf98cSChris Cain                 return;
266137bbf98cSChris Cain             }
266237bbf98cSChris Cain             const std::string& path = subtree[0].first;
266337bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
266437bbf98cSChris Cain             if (service.empty())
266537bbf98cSChris Cain             {
266662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2667ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
266837bbf98cSChris Cain                 return;
266937bbf98cSChris Cain             }
267037bbf98cSChris Cain 
267137bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2672deae6a78SEd Tanous             dbus::utility::getAllProperties(
2673bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2674bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2675bd79bce8SPatrick Williams                 [asyncResp](
2676bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
26771e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
26788a592810SEd Tanous                     if (ec2)
267937bbf98cSChris Cain                     {
268062598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2681bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2682bd79bce8SPatrick Williams                             ec2);
2683ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
268437bbf98cSChris Cain                         return;
268537bbf98cSChris Cain                     }
268637bbf98cSChris Cain 
2687ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
268837bbf98cSChris Cain                     {
2689ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
269037bbf98cSChris Cain                         return;
269137bbf98cSChris Cain                     }
2692bc1d29deSKrzysztof Grobelny                 });
2693e99073f5SGeorge Liu         });
269437bbf98cSChris Cain 
269562598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
269637bbf98cSChris Cain }
269737bbf98cSChris Cain 
269837bbf98cSChris Cain /**
269937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
270037bbf98cSChris Cain  *
2701ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
270237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
270337bbf98cSChris Cain  *                       RF request.
270437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
270537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
270637bbf98cSChris Cain  * before entering idle state.
270737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
270837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
270937bbf98cSChris Cain  * before exiting idle state
271037bbf98cSChris Cain  *
271137bbf98cSChris Cain  * @return None.
271237bbf98cSChris Cain  */
2713bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2714bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
271537bbf98cSChris Cain     const std::optional<bool> ipsEnable,
271637bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
271737bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
271837bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
271937bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
272037bbf98cSChris Cain {
272162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
272237bbf98cSChris Cain 
272337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2724e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2725e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2726e99073f5SGeorge Liu     dbus::utility::getSubTree(
2727e99073f5SGeorge Liu         "/", 0, interfaces,
2728ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2729e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2730b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
273137bbf98cSChris Cain             if (ec)
273237bbf98cSChris Cain             {
2733b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
273462598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
273562598e31SEd Tanous                     ec);
2736ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273737bbf98cSChris Cain                 return;
273837bbf98cSChris Cain             }
273937bbf98cSChris Cain             if (subtree.empty())
274037bbf98cSChris Cain             {
274137bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2742ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
274337bbf98cSChris Cain                                            "IdlePowerSaver");
274437bbf98cSChris Cain                 return;
274537bbf98cSChris Cain             }
274637bbf98cSChris Cain             if (subtree.size() > 1)
274737bbf98cSChris Cain             {
274837bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
274937bbf98cSChris Cain                 // is an error
275062598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
275162598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
275262598e31SEd Tanous                     subtree.size());
2753ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
275437bbf98cSChris Cain                 return;
275537bbf98cSChris Cain             }
275637bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
275737bbf98cSChris Cain             {
275862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2759ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
276037bbf98cSChris Cain                 return;
276137bbf98cSChris Cain             }
276237bbf98cSChris Cain             const std::string& path = subtree[0].first;
276337bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
276437bbf98cSChris Cain             if (service.empty())
276537bbf98cSChris Cain             {
276662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2767ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
276837bbf98cSChris Cain                 return;
276937bbf98cSChris Cain             }
277037bbf98cSChris Cain 
277137bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
277237bbf98cSChris Cain             // need to be updated
277337bbf98cSChris Cain 
277437bbf98cSChris Cain             if (ipsEnable)
277537bbf98cSChris Cain             {
2776bd79bce8SPatrick Williams                 setDbusProperty(
2777bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
277887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2779e93abac6SGinu George                     "Enabled", *ipsEnable);
278037bbf98cSChris Cain             }
278137bbf98cSChris Cain             if (ipsEnterUtil)
278237bbf98cSChris Cain             {
2783bd79bce8SPatrick Williams                 setDbusProperty(
2784bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2785e93abac6SGinu George                     service, path,
27869ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2787e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
278837bbf98cSChris Cain             }
278937bbf98cSChris Cain             if (ipsEnterTime)
279037bbf98cSChris Cain             {
279137bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
279237bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2793bd79bce8SPatrick Williams                 setDbusProperty(
2794bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2795bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2796e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
279737bbf98cSChris Cain             }
279837bbf98cSChris Cain             if (ipsExitUtil)
279937bbf98cSChris Cain             {
2800bd79bce8SPatrick Williams                 setDbusProperty(
2801bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2802bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2803e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
280437bbf98cSChris Cain             }
280537bbf98cSChris Cain             if (ipsExitTime)
280637bbf98cSChris Cain             {
280737bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
280837bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2809bd79bce8SPatrick Williams                 setDbusProperty(
2810bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2811bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2812e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
281337bbf98cSChris Cain             }
2814e99073f5SGeorge Liu         });
281537bbf98cSChris Cain 
281662598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
281737bbf98cSChris Cain }
281837bbf98cSChris Cain 
2819c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2820dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2821dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2822dd60b9edSEd Tanous {
2823dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2824dd60b9edSEd Tanous     {
2825dd60b9edSEd Tanous         return;
2826dd60b9edSEd Tanous     }
2827dd60b9edSEd Tanous     asyncResp->res.addHeader(
2828dd60b9edSEd Tanous         boost::beast::http::field::link,
2829dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2830dd60b9edSEd Tanous }
2831dd60b9edSEd Tanous 
2832c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2833c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2834c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28351abe55efSEd Tanous {
28363ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2837f4c99e70SEd Tanous     {
2838f4c99e70SEd Tanous         return;
2839f4c99e70SEd Tanous     }
2840dd60b9edSEd Tanous 
2841dd60b9edSEd Tanous     asyncResp->res.addHeader(
2842dd60b9edSEd Tanous         boost::beast::http::field::link,
2843dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28448d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28450f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28468d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28478d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2848462023adSSunitha Harish 
2849fc5ae94dSOliver Brewka     getSystemCollectionMembers(asyncResp);
2850c1e219d5SEd Tanous }
2851c1e219d5SEd Tanous 
2852c1e219d5SEd Tanous /**
28537e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28547e860f15SJohn Edward Broadbent  */
28554f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28567e860f15SJohn Edward Broadbent {
285789492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
285889492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
285989492a15SPatrick Williams     constexpr const char* interfaceName =
28607e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
286189492a15SPatrick Williams     constexpr const char* method = "NMI";
28627e860f15SJohn Edward Broadbent 
2863177612aaSEd Tanous     dbus::utility::async_method_call(
2864177612aaSEd Tanous         asyncResp,
28655e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28667e860f15SJohn Edward Broadbent             if (ec)
28677e860f15SJohn Edward Broadbent             {
286862598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28697e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28707e860f15SJohn Edward Broadbent                 return;
28717e860f15SJohn Edward Broadbent             }
28727e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28737e860f15SJohn Edward Broadbent         },
28747e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28757e860f15SJohn Edward Broadbent }
2876c5b2abe0SLewanczyk, Dawid 
287706c055e7SOliver Brewka /**
287806c055e7SOliver Brewka  * @brief process the POST request after getting the computerSystemIndex
287906c055e7SOliver Brewka  *
288006c055e7SOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
288106c055e7SOliver Brewka  *                                calls
288206c055e7SOliver Brewka  * @param[in] resetType           The requested reset action
288306c055e7SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
288406c055e7SOliver Brewka  *
288506c055e7SOliver Brewka  * @return None
288606c055e7SOliver Brewka  */
288706c055e7SOliver Brewka inline void processComputerSystemResetActionPost(
288806c055e7SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string& resetType,
288906c055e7SOliver Brewka     const uint64_t computerSystemIndex)
2890c1e219d5SEd Tanous {
2891d22c8396SJason M. Bills     // Get the command and host vs. chassis
2892cc340dd9SEd Tanous     std::string command;
2893543f4400SEd Tanous     bool hostCommand = true;
2894d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2895cc340dd9SEd Tanous     {
2896cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2897d22c8396SJason M. Bills         hostCommand = true;
2898d22c8396SJason M. Bills     }
2899d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2900d22c8396SJason M. Bills     {
2901d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2902d22c8396SJason M. Bills         hostCommand = false;
2903d22c8396SJason M. Bills     }
2904d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2905d22c8396SJason M. Bills     {
2906c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
290786a0851aSJason M. Bills         hostCommand = true;
2908cc340dd9SEd Tanous     }
29099712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2910cc340dd9SEd Tanous     {
2911cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2912d22c8396SJason M. Bills         hostCommand = true;
2913cc340dd9SEd Tanous     }
29149712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2915cc340dd9SEd Tanous     {
29160fda0f12SGeorge Liu         command =
29170fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2918d22c8396SJason M. Bills         hostCommand = true;
2919d22c8396SJason M. Bills     }
2920d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2921d22c8396SJason M. Bills     {
292286a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
292386a0851aSJason M. Bills         hostCommand = true;
2924cc340dd9SEd Tanous     }
2925bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2926bfd5b826SLakshminarayana R. Kammath     {
2927bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2928bfd5b826SLakshminarayana R. Kammath         return;
2929bfd5b826SLakshminarayana R. Kammath     }
2930cc340dd9SEd Tanous     else
2931cc340dd9SEd Tanous     {
2932c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2933cc340dd9SEd Tanous         return;
2934cc340dd9SEd Tanous     }
2935cc340dd9SEd Tanous 
2936d22c8396SJason M. Bills     if (hostCommand)
2937d22c8396SJason M. Bills     {
293806c055e7SOliver Brewka         setDbusProperty(asyncResp, "Reset",
293906c055e7SOliver Brewka                         getHostStateServiceName(computerSystemIndex),
294006c055e7SOliver Brewka                         getHostStateObjectPath(computerSystemIndex),
294106c055e7SOliver Brewka                         "xyz.openbmc_project.State.Host",
2942e93abac6SGinu George                         "RequestedHostTransition", command);
2943cc340dd9SEd Tanous     }
2944d22c8396SJason M. Bills     else
2945d22c8396SJason M. Bills     {
294606c055e7SOliver Brewka         setDbusProperty(asyncResp, "Reset",
294706c055e7SOliver Brewka                         getChassisStateServiceName(computerSystemIndex),
294806c055e7SOliver Brewka                         getChassisStateObjectPath(computerSystemIndex),
2949d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2950e93abac6SGinu George                         "RequestedPowerTransition", command);
2951d22c8396SJason M. Bills     }
2952d22c8396SJason M. Bills }
2953cc340dd9SEd Tanous 
295406c055e7SOliver Brewka inline void handleComputerSystemResetActionPost(
295506c055e7SOliver Brewka     crow::App& app, const crow::Request& req,
295606c055e7SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
295706c055e7SOliver Brewka     const std::string& systemName)
295806c055e7SOliver Brewka {
295906c055e7SOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
296006c055e7SOliver Brewka     {
296106c055e7SOliver Brewka         return;
296206c055e7SOliver Brewka     }
296306c055e7SOliver Brewka 
296406c055e7SOliver Brewka     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
296506c055e7SOliver Brewka     {
296606c055e7SOliver Brewka         if (systemName == "hypervisor")
296706c055e7SOliver Brewka         {
296806c055e7SOliver Brewka             handleHypervisorSystemResetPost(req, asyncResp);
296906c055e7SOliver Brewka             return;
297006c055e7SOliver Brewka         }
297106c055e7SOliver Brewka     }
297206c055e7SOliver Brewka 
297306c055e7SOliver Brewka     if (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
297406c055e7SOliver Brewka     {
297506c055e7SOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
297606c055e7SOliver Brewka         {
297706c055e7SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
297806c055e7SOliver Brewka                                        systemName);
297906c055e7SOliver Brewka             return;
298006c055e7SOliver Brewka         }
298106c055e7SOliver Brewka     }
298206c055e7SOliver Brewka 
298306c055e7SOliver Brewka     std::string resetType;
298406c055e7SOliver Brewka     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
298506c055e7SOliver Brewka     {
298606c055e7SOliver Brewka         return;
298706c055e7SOliver Brewka     }
298806c055e7SOliver Brewka 
298906c055e7SOliver Brewka     getComputerSystemIndex(asyncResp, systemName,
299006c055e7SOliver Brewka                            std::bind_front(processComputerSystemResetActionPost,
299106c055e7SOliver Brewka                                            asyncResp, resetType));
299206c055e7SOliver Brewka }
299306c055e7SOliver Brewka 
2994c1e219d5SEd Tanous inline void handleComputerSystemHead(
2995dd60b9edSEd Tanous     App& app, const crow::Request& req,
29967f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29977f3e84a1SEd Tanous     const std::string& /*systemName*/)
2998dd60b9edSEd Tanous {
2999dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3000dd60b9edSEd Tanous     {
3001dd60b9edSEd Tanous         return;
3002dd60b9edSEd Tanous     }
3003dd60b9edSEd Tanous 
3004dd60b9edSEd Tanous     asyncResp->res.addHeader(
3005dd60b9edSEd Tanous         boost::beast::http::field::link,
3006dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3007dd60b9edSEd Tanous }
3008dd60b9edSEd Tanous 
30095c3e9272SAbhishek Patel inline void afterPortRequest(
30105c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30115c3e9272SAbhishek Patel     const boost::system::error_code& ec,
30125c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
30135c3e9272SAbhishek Patel {
30145c3e9272SAbhishek Patel     if (ec)
30155c3e9272SAbhishek Patel     {
3016b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
30175c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
30185c3e9272SAbhishek Patel         return;
30195c3e9272SAbhishek Patel     }
30205c3e9272SAbhishek Patel     for (const auto& data : socketData)
30215c3e9272SAbhishek Patel     {
30225c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
30235c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
30245c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
30255c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
30265c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
30275c3e9272SAbhishek Patel         // need to retrieve port number for
30285c3e9272SAbhishek Patel         // obmc-console-ssh service
30295c3e9272SAbhishek Patel         if (protocolName == "SSH")
30305c3e9272SAbhishek Patel         {
30315c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
303281c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30335c3e9272SAbhishek Patel                                           int portNumber) {
30345c3e9272SAbhishek Patel                 if (ec1)
30355c3e9272SAbhishek Patel                 {
3036b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
30375c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30385c3e9272SAbhishek Patel                     return;
30395c3e9272SAbhishek Patel                 }
30405c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30415c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30425c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30435c3e9272SAbhishek Patel             });
30445c3e9272SAbhishek Patel         }
30455c3e9272SAbhishek Patel     }
30465c3e9272SAbhishek Patel }
3047c1e219d5SEd Tanous 
30485e7c1f31SOliver Brewka /**
30495e7c1f31SOliver Brewka  * @brief process the GET request after getting the computerSystemIndex
30505e7c1f31SOliver Brewka  *
30515e7c1f31SOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
30525e7c1f31SOliver Brewka  *                                calls
30535e7c1f31SOliver Brewka  * @param[in] systemName          Name of the requested system
30545e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
30555e7c1f31SOliver Brewka  *
30565e7c1f31SOliver Brewka  * @return None
30575e7c1f31SOliver Brewka  */
30585e7c1f31SOliver Brewka inline void processComputerSystemGet(
305922d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30605e7c1f31SOliver Brewka     const std::string& systemName, const uint64_t computerSystemIndex)
3061c1e219d5SEd Tanous {
3062dd60b9edSEd Tanous     asyncResp->res.addHeader(
3063dd60b9edSEd Tanous         boost::beast::http::field::link,
3064dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30658d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3066b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
30675e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Name"] = systemName;
30685e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Id"] = systemName;
3069539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3070539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30718d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30728d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3073cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3074dfb2b408SPriyanga Ramasamy         double(0);
30755e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] =
30765e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}", systemName);
307704a258f4SEd Tanous 
30785e7c1f31SOliver Brewka     // Currently not supported on multi-host. TBD
30795e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30805e7c1f31SOliver Brewka     {
30815e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
30825e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Bios", systemName);
30835e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
30845e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Processors",
30855e7c1f31SOliver Brewka                                 systemName);
30865e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
30875e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Memory", systemName);
30885e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
30895e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Storage", systemName);
30903179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3091253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
30925e7c1f31SOliver Brewka                                 systemName);
30935e7c1f31SOliver Brewka     }
3094029573d4SEd Tanous 
3095002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3096253f11b8SEd Tanous         boost::urls::format(
30975e7c1f31SOliver Brewka             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", systemName);
3098c1e219d5SEd Tanous     asyncResp->res
3099c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3100253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
31015e7c1f31SOliver Brewka                             systemName);
3102c5b2abe0SLewanczyk, Dawid 
31035e7c1f31SOliver Brewka     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
31045e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}/LogServices", systemName);
3105c4bf6374SJason M. Bills 
31061476687dSEd Tanous     nlohmann::json::array_t managedBy;
31071476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3108253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3109253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3110002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3111539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3112539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
31130e8ac5e7SGunnar Mills 
31140e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3115002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3116c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
31171476687dSEd Tanous 
3118c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
31191476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3120c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31211476687dSEd Tanous         "Press ~. to exit console";
31225c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31235c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31240e8ac5e7SGunnar Mills 
312525b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
312625b54dbaSEd Tanous     {
31270e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3128002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
312925b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
313025b54dbaSEd Tanous             4;
3131613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3132613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
313325b54dbaSEd Tanous     }
313413451e39SWilly Tu 
31352eaa9279SJanet Adkins     systems_utils::getValidSystemsPath(
31362eaa9279SJanet Adkins         asyncResp, systemName,
31372eaa9279SJanet Adkins         [asyncResp,
31382eaa9279SJanet Adkins          systemName](const std::optional<std::string>& validSystemsPath) {
31392eaa9279SJanet Adkins             if (validSystemsPath)
31402eaa9279SJanet Adkins             {
31412eaa9279SJanet Adkins                 getLocationIndicatorActive(asyncResp, *validSystemsPath);
31422eaa9279SJanet Adkins             }
31432eaa9279SJanet Adkins         });
31442eaa9279SJanet Adkins 
3145f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3146f664fd8aSJanet Adkins     {
3147a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
3148f664fd8aSJanet Adkins     }
3149f664fd8aSJanet Adkins 
31505e7c1f31SOliver Brewka     // Currently not supported on multi-host.
31515e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31525e7c1f31SOliver Brewka     {
315351bd2d8aSGunnar Mills         getComputerSystem(asyncResp);
31545e7c1f31SOliver Brewka         // Todo: chassis matching could be handled by patch
31555e7c1f31SOliver Brewka         // https://gerrit.openbmc.org/c/openbmc/bmcweb/+/60793
31565e7c1f31SOliver Brewka         getMainChassisId(
31575e7c1f31SOliver Brewka             asyncResp, [](const std::string& chassisId,
31585e7c1f31SOliver Brewka                           const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
31595e7c1f31SOliver Brewka                 nlohmann::json::array_t chassisArray;
31605e7c1f31SOliver Brewka                 nlohmann::json& chassis = chassisArray.emplace_back();
31615e7c1f31SOliver Brewka                 chassis["@odata.id"] =
31625e7c1f31SOliver Brewka                     boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
31635e7c1f31SOliver Brewka                 aRsp->res.jsonValue["Links"]["Chassis"] =
31645e7c1f31SOliver Brewka                     std::move(chassisArray);
31655e7c1f31SOliver Brewka             });
31665e7c1f31SOliver Brewka 
31675e7c1f31SOliver Brewka         pcie_util::getPCIeDeviceList(
31685e7c1f31SOliver Brewka             asyncResp, nlohmann::json::json_pointer("/PCIeDevices"));
31695e7c1f31SOliver Brewka     }
31705e7c1f31SOliver Brewka     getHostState(asyncResp, computerSystemIndex);
31715e7c1f31SOliver Brewka     getBootProperties(asyncResp, computerSystemIndex);
31725e7c1f31SOliver Brewka     getBootProgress(asyncResp, computerSystemIndex);
31735e7c1f31SOliver Brewka     getBootProgressLastStateTime(asyncResp, computerSystemIndex);
317451709ffdSYong Li     getHostWatchdogTimer(asyncResp);
31755e7c1f31SOliver Brewka     getPowerRestorePolicy(asyncResp, computerSystemIndex);
31769dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
31775e7c1f31SOliver Brewka     getAutomaticRetryPolicy(asyncResp, computerSystemIndex);
31785e7c1f31SOliver Brewka     getLastResetTime(asyncResp, computerSystemIndex);
317925b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
318025b54dbaSEd Tanous     {
3181a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
318225b54dbaSEd Tanous     }
31835e7c1f31SOliver Brewka     getTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex);
31843a2d0424SChris Cain     getPowerMode(asyncResp);
318537bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3186c1e219d5SEd Tanous }
3187550a6bf8SJiaqing Zhao 
31885e7c1f31SOliver Brewka inline void handleComputerSystemGet(
31895e7c1f31SOliver Brewka     crow::App& app, const crow::Request& req,
31905e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31915e7c1f31SOliver Brewka     const std::string& systemName)
31925e7c1f31SOliver Brewka {
31935e7c1f31SOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
31945e7c1f31SOliver Brewka     {
31955e7c1f31SOliver Brewka         return;
31965e7c1f31SOliver Brewka     }
31975e7c1f31SOliver Brewka 
31985e7c1f31SOliver Brewka     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
31995e7c1f31SOliver Brewka     {
32005e7c1f31SOliver Brewka         if (systemName == "hypervisor")
32015e7c1f31SOliver Brewka         {
32025e7c1f31SOliver Brewka             handleHypervisorSystemGet(asyncResp);
32035e7c1f31SOliver Brewka             return;
32045e7c1f31SOliver Brewka         }
32055e7c1f31SOliver Brewka     }
32065e7c1f31SOliver Brewka 
32075e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
32085e7c1f31SOliver Brewka     {
32095e7c1f31SOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
32105e7c1f31SOliver Brewka         {
32115e7c1f31SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32125e7c1f31SOliver Brewka                                        systemName);
32135e7c1f31SOliver Brewka             return;
32145e7c1f31SOliver Brewka         }
32155e7c1f31SOliver Brewka     }
32165e7c1f31SOliver Brewka 
32175e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("requested system = {}", systemName);
32185e7c1f31SOliver Brewka     getComputerSystemIndex(
32195e7c1f31SOliver Brewka         asyncResp, systemName,
32205e7c1f31SOliver Brewka         std::bind_front(processComputerSystemGet, asyncResp, systemName));
32215e7c1f31SOliver Brewka }
32225e7c1f31SOliver Brewka 
3223d43cc6bcSOliver Brewka struct PatchParams
3224c1e219d5SEd Tanous {
32259f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3226cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
322798e386ecSGunnar Mills     std::optional<std::string> assetTag;
3228c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
32293a2d0424SChris Cain     std::optional<std::string> powerMode;
3230550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3231550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3232550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3233550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3234550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3235550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3236797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3237550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
32389dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3239550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3240550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3241550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3242550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3243550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3244d43cc6bcSOliver Brewka };
3245550a6bf8SJiaqing Zhao 
3246d43cc6bcSOliver Brewka /**
3247d43cc6bcSOliver Brewka  * @brief process the POST request after getting the computerSystemIndex
3248d43cc6bcSOliver Brewka  *
3249d43cc6bcSOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
3250d43cc6bcSOliver Brewka  *                                calls
3251d43cc6bcSOliver Brewka  * @param[in] patchParams         Struct containing the property we want to
3252d43cc6bcSOliver Brewka  *                                patch
3253d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
3254d43cc6bcSOliver Brewka  *
3255d43cc6bcSOliver Brewka  * @return None
3256d43cc6bcSOliver Brewka  */
3257d43cc6bcSOliver Brewka 
3258d43cc6bcSOliver Brewka inline void processComputerSystemPatch(
3259d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3260d43cc6bcSOliver Brewka     std::string& systemName, PatchParams& patchParams,
3261d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex)
32626617338dSEd Tanous {
3263f664fd8aSJanet Adkins     if constexpr (!BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3264f664fd8aSJanet Adkins     {
3265d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
3266f664fd8aSJanet Adkins         {
3267f664fd8aSJanet Adkins             messages::propertyUnknown(asyncResp->res, "IndicatorLED");
3268f664fd8aSJanet Adkins             return;
3269f664fd8aSJanet Adkins         }
3270f664fd8aSJanet Adkins     }
3271f664fd8aSJanet Adkins 
3272d43cc6bcSOliver Brewka     if (patchParams.assetTag)
327398e386ecSGunnar Mills     {
3274d43cc6bcSOliver Brewka         setAssetTag(asyncResp, *patchParams.assetTag);
327598e386ecSGunnar Mills     }
327698e386ecSGunnar Mills 
3277d43cc6bcSOliver Brewka     if (patchParams.wdtEnable || patchParams.wdtTimeOutAction)
3278c45f0082SYong Li     {
3279d43cc6bcSOliver Brewka         setWDTProperties(asyncResp, patchParams.wdtEnable,
3280d43cc6bcSOliver Brewka                          patchParams.wdtTimeOutAction);
3281c45f0082SYong Li     }
3282c45f0082SYong Li 
3283d43cc6bcSOliver Brewka     if (patchParams.bootSource || patchParams.bootType ||
3284d43cc6bcSOliver Brewka         patchParams.bootEnable)
328569f35306SGunnar Mills     {
3286d43cc6bcSOliver Brewka         setBootProperties(asyncResp, computerSystemIndex,
3287d43cc6bcSOliver Brewka                           patchParams.bootSource, patchParams.bootType,
3288d43cc6bcSOliver Brewka                           patchParams.bootEnable);
3289491d8ee7SSantosh Puranik     }
3290d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetry)
329169f35306SGunnar Mills     {
3292d43cc6bcSOliver Brewka         setAutomaticRetry(asyncResp, computerSystemIndex,
3293d43cc6bcSOliver Brewka                           *patchParams.bootAutomaticRetry);
329469f35306SGunnar Mills     }
3295ac7e1e0bSAli Ahmed 
3296d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetryAttempts)
3297797d5daeSCorey Hardesty     {
3298d43cc6bcSOliver Brewka         setAutomaticRetryAttempts(
3299d43cc6bcSOliver Brewka             asyncResp, computerSystemIndex,
3300d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts.value());
3301797d5daeSCorey Hardesty     }
3302797d5daeSCorey Hardesty 
3303d43cc6bcSOliver Brewka     if (patchParams.bootTrustedModuleRequired)
3304ac7e1e0bSAli Ahmed     {
3305d43cc6bcSOliver Brewka         setTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex,
3306d43cc6bcSOliver Brewka                                        *patchParams.bootTrustedModuleRequired);
330769f35306SGunnar Mills     }
3308265c1602SJohnathan Mantey 
3309d43cc6bcSOliver Brewka     if (patchParams.stopBootOnFault)
33109dcfe8c1SAlbert Zhang     {
3311d43cc6bcSOliver Brewka         setStopBootOnFault(asyncResp, *patchParams.stopBootOnFault);
33129dcfe8c1SAlbert Zhang     }
33139dcfe8c1SAlbert Zhang 
3314d43cc6bcSOliver Brewka     if (patchParams.locationIndicatorActive)
33159f8bfa7cSGunnar Mills     {
33162eaa9279SJanet Adkins         systems_utils::getValidSystemsPath(
33172eaa9279SJanet Adkins             asyncResp, systemName,
33182eaa9279SJanet Adkins             [asyncResp, systemName,
3319d43cc6bcSOliver Brewka              locationIndicatorActive{*patchParams.locationIndicatorActive}](
33202eaa9279SJanet Adkins                 const std::optional<std::string>& validSystemsPath) {
33212eaa9279SJanet Adkins                 if (!validSystemsPath)
33222eaa9279SJanet Adkins                 {
33232eaa9279SJanet Adkins                     messages::resourceNotFound(asyncResp->res, "Systems",
33242eaa9279SJanet Adkins                                                systemName);
33252eaa9279SJanet Adkins                     return;
33262eaa9279SJanet Adkins                 }
33272eaa9279SJanet Adkins                 setLocationIndicatorActive(asyncResp, *validSystemsPath,
33282eaa9279SJanet Adkins                                            locationIndicatorActive);
33292eaa9279SJanet Adkins             });
33309f8bfa7cSGunnar Mills     }
33319f8bfa7cSGunnar Mills 
3332f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3333f664fd8aSJanet Adkins     {
3334d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
33356617338dSEd Tanous         {
3336d43cc6bcSOliver Brewka             setIndicatorLedState(asyncResp, *patchParams.indicatorLed);
3337002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3338d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3339d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
33406617338dSEd Tanous         }
3341f664fd8aSJanet Adkins     }
3342c6a620f2SGeorge Liu 
3343d43cc6bcSOliver Brewka     if (patchParams.powerRestorePolicy)
3344c6a620f2SGeorge Liu     {
3345d43cc6bcSOliver Brewka         setPowerRestorePolicy(asyncResp, computerSystemIndex,
3346d43cc6bcSOliver Brewka                               *patchParams.powerRestorePolicy);
3347c6a620f2SGeorge Liu     }
33483a2d0424SChris Cain 
3349d43cc6bcSOliver Brewka     if (patchParams.powerMode)
33503a2d0424SChris Cain     {
3351d43cc6bcSOliver Brewka         setPowerMode(asyncResp, *patchParams.powerMode);
33523a2d0424SChris Cain     }
335337bbf98cSChris Cain 
3354d43cc6bcSOliver Brewka     if (patchParams.ipsEnable || patchParams.ipsEnterUtil ||
3355d43cc6bcSOliver Brewka         patchParams.ipsEnterTime || patchParams.ipsExitUtil ||
3356d43cc6bcSOliver Brewka         patchParams.ipsExitTime)
335737bbf98cSChris Cain     {
3358d43cc6bcSOliver Brewka         setIdlePowerSaver(asyncResp, patchParams.ipsEnable,
3359d43cc6bcSOliver Brewka                           patchParams.ipsEnterUtil, patchParams.ipsEnterTime,
3360d43cc6bcSOliver Brewka                           patchParams.ipsExitUtil, patchParams.ipsExitTime);
336137bbf98cSChris Cain     }
3362c1e219d5SEd Tanous }
33631cb1a9e6SAppaRao Puli 
3364d43cc6bcSOliver Brewka inline void handleComputerSystemPatch(
3365d43cc6bcSOliver Brewka     crow::App& app, const crow::Request& req,
3366d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3367d43cc6bcSOliver Brewka     const std::string& systemName)
3368d43cc6bcSOliver Brewka {
3369d43cc6bcSOliver Brewka     PatchParams patchParams;
3370d43cc6bcSOliver Brewka 
3371d43cc6bcSOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3372d43cc6bcSOliver Brewka     {
3373d43cc6bcSOliver Brewka         return;
3374d43cc6bcSOliver Brewka     }
3375d43cc6bcSOliver Brewka 
3376d43cc6bcSOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3377d43cc6bcSOliver Brewka     {
3378d43cc6bcSOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3379d43cc6bcSOliver Brewka         {
3380d43cc6bcSOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3381d43cc6bcSOliver Brewka                                        systemName);
3382d43cc6bcSOliver Brewka             return;
3383d43cc6bcSOliver Brewka         }
3384d43cc6bcSOliver Brewka     }
3385d43cc6bcSOliver Brewka 
3386d43cc6bcSOliver Brewka     asyncResp->res.addHeader(
3387d43cc6bcSOliver Brewka         boost::beast::http::field::link,
3388d43cc6bcSOliver Brewka         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3389d43cc6bcSOliver Brewka 
3390d43cc6bcSOliver Brewka     if (!json_util::readJsonPatch(
3391d43cc6bcSOliver Brewka             req, asyncResp->res,                                              //
3392d43cc6bcSOliver Brewka             "AssetTag", patchParams.assetTag,                                 //
3393d43cc6bcSOliver Brewka             "Boot/AutomaticRetryAttempts",
3394d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts,                           //
3395d43cc6bcSOliver Brewka             "Boot/AutomaticRetryConfig", patchParams.bootAutomaticRetry,      //
3396d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideEnabled", patchParams.bootEnable,         //
3397d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideMode", patchParams.bootType,              //
3398d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideTarget", patchParams.bootSource,          //
3399d43cc6bcSOliver Brewka             "Boot/StopBootOnFault", patchParams.stopBootOnFault,              //
3400d43cc6bcSOliver Brewka             "Boot/TrustedModuleRequiredToBoot",
3401d43cc6bcSOliver Brewka             patchParams.bootTrustedModuleRequired,                            //
3402d43cc6bcSOliver Brewka             "HostWatchdogTimer/FunctionEnabled", patchParams.wdtEnable,       //
3403d43cc6bcSOliver Brewka             "HostWatchdogTimer/TimeoutAction", patchParams.wdtTimeOutAction,  //
3404d43cc6bcSOliver Brewka             "IdlePowerSaver/Enabled", patchParams.ipsEnable,                  //
3405d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterDwellTimeSeconds", patchParams.ipsEnterTime, //
3406d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterUtilizationPercent",
3407d43cc6bcSOliver Brewka             patchParams.ipsEnterUtil,                                         //
3408d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitDwellTimeSeconds", patchParams.ipsExitTime,   //
3409d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitUtilizationPercent", patchParams.ipsExitUtil, //
3410d43cc6bcSOliver Brewka             "IndicatorLED", patchParams.indicatorLed,                         //
3411d43cc6bcSOliver Brewka             "LocationIndicatorActive", patchParams.locationIndicatorActive,   //
3412d43cc6bcSOliver Brewka             "PowerMode", patchParams.powerMode,                               //
3413d43cc6bcSOliver Brewka             "PowerRestorePolicy", patchParams.powerRestorePolicy))
3414d43cc6bcSOliver Brewka     {
3415d43cc6bcSOliver Brewka         return;
3416d43cc6bcSOliver Brewka     }
3417d43cc6bcSOliver Brewka 
3418d43cc6bcSOliver Brewka     getComputerSystemIndex(asyncResp, systemName,
3419d43cc6bcSOliver Brewka                            std::bind_front(processComputerSystemPatch,
3420d43cc6bcSOliver Brewka                                            asyncResp, systemName, patchParams));
3421d43cc6bcSOliver Brewka }
3422d43cc6bcSOliver Brewka 
342338c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3424dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34257f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3426c1e219d5SEd Tanous     const std::string& /*systemName*/)
3427dd60b9edSEd Tanous {
3428dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3429dd60b9edSEd Tanous     {
3430dd60b9edSEd Tanous         return;
3431dd60b9edSEd Tanous     }
3432dd60b9edSEd Tanous     asyncResp->res.addHeader(
3433dd60b9edSEd Tanous         boost::beast::http::field::link,
3434dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3435dd60b9edSEd Tanous }
343633e1f122SAndrew Geissler 
343733e1f122SAndrew Geissler /**
343833e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
343933e1f122SAndrew Geissler  *
344033e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
344133e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
344233e1f122SAndrew Geissler  *
3443efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
344433e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
344533e1f122SAndrew Geissler  * allowableValues.
344633e1f122SAndrew Geissler  */
3447504af5a0SPatrick Williams inline void dbusToRfAllowedHostTransitions(
3448504af5a0SPatrick Williams     const std::string& dbusAllowedHostTran,
344933e1f122SAndrew Geissler     nlohmann::json::array_t& allowableValues)
345033e1f122SAndrew Geissler {
345133e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
345233e1f122SAndrew Geissler     {
345333e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
345433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
345533e1f122SAndrew Geissler     }
345633e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
345733e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
345833e1f122SAndrew Geissler     {
345933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
346033e1f122SAndrew Geissler     }
346133e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
346233e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
346333e1f122SAndrew Geissler     {
346433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
346533e1f122SAndrew Geissler     }
346633e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
346733e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
346833e1f122SAndrew Geissler     {
346933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
347033e1f122SAndrew Geissler     }
347133e1f122SAndrew Geissler     else
347233e1f122SAndrew Geissler     {
347333e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
347433e1f122SAndrew Geissler     }
347533e1f122SAndrew Geissler }
347633e1f122SAndrew Geissler 
347733e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
347833e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
347933e1f122SAndrew Geissler     const boost::system::error_code& ec,
348033e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
348133e1f122SAndrew Geissler {
348233e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
348333e1f122SAndrew Geissler 
348433e1f122SAndrew Geissler     // Supported on all systems currently
348533e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
348633e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
348733e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
348833e1f122SAndrew Geissler 
348933e1f122SAndrew Geissler     if (ec)
349033e1f122SAndrew Geissler     {
3491e715d14bSEd Tanous         if ((ec.value() ==
3492e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3493e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
349433e1f122SAndrew Geissler         {
349533e1f122SAndrew Geissler             // Property not implemented so just return defaults
349633e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
349733e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
349833e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
349933e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
350033e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
350133e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
350233e1f122SAndrew Geissler         }
350333e1f122SAndrew Geissler         else
350433e1f122SAndrew Geissler         {
350533e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
350633e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
350733e1f122SAndrew Geissler             return;
350833e1f122SAndrew Geissler         }
350933e1f122SAndrew Geissler     }
351033e1f122SAndrew Geissler     else
351133e1f122SAndrew Geissler     {
351233e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
351333e1f122SAndrew Geissler         {
351433e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
351533e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
351633e1f122SAndrew Geissler         }
351733e1f122SAndrew Geissler     }
351833e1f122SAndrew Geissler 
351933e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
352033e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
352133e1f122SAndrew Geissler     parameter["Required"] = true;
3522539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
352333e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
352433e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
352533e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
352633e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
352733e1f122SAndrew Geissler }
352833e1f122SAndrew Geissler 
35295e7c1f31SOliver Brewka inline void getAllowedHostTransitions(
35305e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
35315e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
35325e7c1f31SOliver Brewka {
3533*a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
3534*a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
35355e7c1f31SOliver Brewka     dbus::utility::getProperty<std::vector<std::string>>(
3536*a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
35375e7c1f31SOliver Brewka         "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
35385e7c1f31SOliver Brewka         std::bind_front(afterGetAllowedHostTransitions, asyncResp));
35395e7c1f31SOliver Brewka }
35405e7c1f31SOliver Brewka 
3541c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3542c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
354322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3544c1e219d5SEd Tanous     const std::string& systemName)
3545c1e219d5SEd Tanous {
35463ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
354745ca1b86SEd Tanous     {
354845ca1b86SEd Tanous         return;
354945ca1b86SEd Tanous     }
3550746b56f3SAsmitha Karunanithi 
355168896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
355268896206SGunnar Mills     {
3553746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3554746b56f3SAsmitha Karunanithi         {
3555746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3556746b56f3SAsmitha Karunanithi             return;
3557746b56f3SAsmitha Karunanithi         }
355868896206SGunnar Mills     }
3559746b56f3SAsmitha Karunanithi 
35605e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
35615e7c1f31SOliver Brewka     {
3562253f11b8SEd Tanous         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
356322d268cbSEd Tanous         {
356422d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
356522d268cbSEd Tanous                                        systemName);
356622d268cbSEd Tanous             return;
356722d268cbSEd Tanous         }
35685e7c1f31SOliver Brewka     }
356922d268cbSEd Tanous 
3570dd60b9edSEd Tanous     asyncResp->res.addHeader(
3571dd60b9edSEd Tanous         boost::beast::http::field::link,
3572dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35731476687dSEd Tanous 
35745e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
35755e7c1f31SOliver Brewka         "/redfish/v1/Systems/{}/ResetActionInfo", systemName);
3576c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35771476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35781476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35793215e700SNan Zhou 
358033e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
35815e7c1f31SOliver Brewka     getComputerSystemIndex(
35825e7c1f31SOliver Brewka         asyncResp, systemName,
35835e7c1f31SOliver Brewka         std::bind_front(getAllowedHostTransitions, asyncResp));
3584c1e219d5SEd Tanous }
35855e7c1f31SOliver Brewka 
3586c1e219d5SEd Tanous /**
3587c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3588c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3589c1e219d5SEd Tanous  */
3590100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3591c1e219d5SEd Tanous {
3592100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3593100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3594100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3595100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3596100afe56SEd Tanous 
3597100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3598100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3599100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3600100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3601100afe56SEd Tanous 
3602100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3603100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3604100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3605100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3606100afe56SEd Tanous 
3607100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3608100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3609100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3610100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3611100afe56SEd Tanous 
3612100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3613100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3614100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3615100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3616100afe56SEd Tanous 
3617100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3618100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3619100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3620100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3621100afe56SEd Tanous 
3622c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3623c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3624c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3625c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3626c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3627c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3628c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3629c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36301cb1a9e6SAppaRao Puli }
3631c5b2abe0SLewanczyk, Dawid } // namespace redfish
3632