xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision f7e62c142ced153e9400b519bdd66062dd6bbf0e)
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"
24*f7e62c14SMyung Bae #include "utils/asset_utils.hpp"
253ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
263ccb3adbSEd Tanous #include "utils/json_utils.hpp"
27472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
283ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
29fc5ae94dSOliver Brewka #include "utils/systems_utils.hpp"
302b82937eSEd Tanous #include "utils/time_utils.hpp"
31c5d03ff4SJennifer Lee 
32d7857201SEd Tanous #include <asm-generic/errno.h>
33d7857201SEd Tanous 
34fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
35d7857201SEd Tanous #include <boost/beast/http/field.hpp>
36d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
37e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
3833e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
39ef4c65b7SEd Tanous #include <boost/url/format.hpp>
40d7857201SEd Tanous #include <nlohmann/json.hpp>
41d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
431214b7e7SGunnar Mills 
447a1dbc48SGeorge Liu #include <array>
45d7857201SEd Tanous #include <chrono>
46d7857201SEd Tanous #include <cstddef>
47d7857201SEd Tanous #include <cstdint>
48d7857201SEd Tanous #include <functional>
4933e1f122SAndrew Geissler #include <memory>
50d7857201SEd Tanous #include <optional>
51d7857201SEd Tanous #include <ratio>
526b9ac4f2SChris Cain #include <string>
537a1dbc48SGeorge Liu #include <string_view>
54d7857201SEd Tanous #include <tuple>
5520fa6a2cSEd Tanous #include <utility>
566b9ac4f2SChris Cain #include <vector>
57c5b2abe0SLewanczyk, Dawid 
581abe55efSEd Tanous namespace redfish
591abe55efSEd Tanous {
60c5b2abe0SLewanczyk, Dawid 
615c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
625c3e9272SAbhishek Patel     protocolToDBusForSystems{
635c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
645c3e9272SAbhishek Patel 
65cf0e004cSNinad Palsule /*
66cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
67cf0e004cSNinad Palsule  *
68ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
69cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
70cf0e004cSNinad Palsule  *
71cf0e004cSNinad Palsule  * @return None.
72cf0e004cSNinad Palsule  */
73bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
74bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
75cf0e004cSNinad Palsule {
7662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
77cf0e004cSNinad Palsule 
78cf0e004cSNinad Palsule     if (isCpuPresent)
79cf0e004cSNinad Palsule     {
80cf0e004cSNinad Palsule         nlohmann::json& procCount =
81ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
82cf0e004cSNinad Palsule         auto* procCountPtr =
83cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
84cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
85cf0e004cSNinad Palsule         {
86cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
87cf0e004cSNinad Palsule             *procCountPtr += 1;
88cf0e004cSNinad Palsule         }
89cf0e004cSNinad Palsule     }
90cf0e004cSNinad Palsule }
91cf0e004cSNinad Palsule 
92382d6475SAli Ahmed inline void getProcessorProperties(
93ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
94382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
95382d6475SAli Ahmed         properties)
9603fbed92SAli Ahmed {
9762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
9803fbed92SAli Ahmed 
9903fbed92SAli Ahmed     // TODO: Get Model
10003fbed92SAli Ahmed 
101bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
10203fbed92SAli Ahmed 
103bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
104bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
10503fbed92SAli Ahmed 
106bc1d29deSKrzysztof Grobelny     if (!success)
10703fbed92SAli Ahmed     {
108ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
10903fbed92SAli Ahmed         return;
11003fbed92SAli Ahmed     }
11103fbed92SAli Ahmed 
112bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
11303fbed92SAli Ahmed     {
114bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
115ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
116bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
117bc1d29deSKrzysztof Grobelny 
118bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
119bc1d29deSKrzysztof Grobelny         {
120bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
12103fbed92SAli Ahmed         }
12203fbed92SAli Ahmed         else
12303fbed92SAli Ahmed         {
124bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
12503fbed92SAli Ahmed         }
12603fbed92SAli Ahmed     }
12703fbed92SAli Ahmed }
12803fbed92SAli Ahmed 
12903fbed92SAli Ahmed /*
13003fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
13103fbed92SAli Ahmed  *
132ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
13303fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
13403fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
13503fbed92SAli Ahmed  *
13603fbed92SAli Ahmed  * @return None.
13703fbed92SAli Ahmed  */
138504af5a0SPatrick Williams inline void getProcessorSummary(
139504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
140ac106bf6SEd Tanous     const std::string& service, const std::string& path)
14103fbed92SAli Ahmed {
142ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
143382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
144382d6475SAli Ahmed         if (ec3)
145382d6475SAli Ahmed         {
14662598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
147382d6475SAli Ahmed             return;
148382d6475SAli Ahmed         }
149ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
150382d6475SAli Ahmed     };
151382d6475SAli Ahmed 
152cf0e004cSNinad Palsule     // Get the Presence of CPU
153deae6a78SEd Tanous     dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
154deae6a78SEd Tanous                                      path, "xyz.openbmc_project.Inventory.Item",
155deae6a78SEd Tanous                                      "Present", std::move(getCpuPresenceState));
156cf0e004cSNinad Palsule 
157deae6a78SEd Tanous     dbus::utility::getAllProperties(
158deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
159ac106bf6SEd Tanous         [asyncResp, service,
1605e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
161b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
16203fbed92SAli Ahmed             if (ec2)
16303fbed92SAli Ahmed             {
16462598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
165ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16603fbed92SAli Ahmed                 return;
16703fbed92SAli Ahmed             }
168ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
169bc1d29deSKrzysztof Grobelny         });
17003fbed92SAli Ahmed }
17103fbed92SAli Ahmed 
17257e8c9beSAlpana Kumari /*
173cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
174cf0e004cSNinad Palsule  *
175ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
176cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
177cf0e004cSNinad Palsule  *
178cf0e004cSNinad Palsule  * @return None.
179cf0e004cSNinad Palsule  */
180504af5a0SPatrick Williams inline void processMemoryProperties(
181504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
182cf0e004cSNinad Palsule     const dbus::utility::DBusPropertiesMap& properties)
183cf0e004cSNinad Palsule {
18462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
185cf0e004cSNinad Palsule 
186cf0e004cSNinad Palsule     if (properties.empty())
187cf0e004cSNinad Palsule     {
188cf0e004cSNinad Palsule         return;
189cf0e004cSNinad Palsule     }
190cf0e004cSNinad Palsule 
191cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
192cf0e004cSNinad Palsule 
193cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
194cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
195cf0e004cSNinad Palsule         memorySizeInKB);
196cf0e004cSNinad Palsule 
197cf0e004cSNinad Palsule     if (!success)
198cf0e004cSNinad Palsule     {
199ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
200cf0e004cSNinad Palsule         return;
201cf0e004cSNinad Palsule     }
202cf0e004cSNinad Palsule 
203cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
204cf0e004cSNinad Palsule     {
205cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
206ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
207dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
208cf0e004cSNinad Palsule         if (preValue == nullptr)
209cf0e004cSNinad Palsule         {
210ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
211dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
212cf0e004cSNinad Palsule         }
213cf0e004cSNinad Palsule         else
214cf0e004cSNinad Palsule         {
215ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
216dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
217dfb2b408SPriyanga Ramasamy                 *preValue;
218cf0e004cSNinad Palsule         }
219cf0e004cSNinad Palsule     }
220cf0e004cSNinad Palsule }
221cf0e004cSNinad Palsule 
222cf0e004cSNinad Palsule /*
223cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
224cf0e004cSNinad Palsule  *
225ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
226cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
227cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
228cf0e004cSNinad Palsule  *
229cf0e004cSNinad Palsule  * @return None.
230cf0e004cSNinad Palsule  */
231504af5a0SPatrick Williams inline void getMemorySummary(
232504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
233ac106bf6SEd Tanous     const std::string& service, const std::string& path)
234cf0e004cSNinad Palsule {
235deae6a78SEd Tanous     dbus::utility::getAllProperties(
236deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
237ac106bf6SEd Tanous         [asyncResp, service,
238cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
239cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
240cf0e004cSNinad Palsule             if (ec2)
241cf0e004cSNinad Palsule             {
24262598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
243ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
244cf0e004cSNinad Palsule                 return;
245cf0e004cSNinad Palsule             }
24651bd2d8aSGunnar Mills             processMemoryProperties(asyncResp, properties);
247cf0e004cSNinad Palsule         });
248cf0e004cSNinad Palsule }
249cf0e004cSNinad Palsule 
250a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
251a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
252a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
2531abe55efSEd Tanous {
254a974c132SLakshmi Yadlapati     if (ec)
255a974c132SLakshmi Yadlapati     {
256a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
257a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
258a974c132SLakshmi Yadlapati         return;
259a974c132SLakshmi Yadlapati     }
260a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
261a974c132SLakshmi Yadlapati 
262a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
263a974c132SLakshmi Yadlapati 
264a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
265a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
266a974c132SLakshmi Yadlapati 
267a974c132SLakshmi Yadlapati     if (!success)
268a974c132SLakshmi Yadlapati     {
269a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
270a974c132SLakshmi Yadlapati         return;
271a974c132SLakshmi Yadlapati     }
272a974c132SLakshmi Yadlapati 
273a974c132SLakshmi Yadlapati     if (uUID != nullptr)
274a974c132SLakshmi Yadlapati     {
275a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
276a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
277a974c132SLakshmi Yadlapati         {
278a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
279a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
280a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
281a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
282a974c132SLakshmi Yadlapati         }
283a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
284a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
285a974c132SLakshmi Yadlapati     }
286a974c132SLakshmi Yadlapati }
287a974c132SLakshmi Yadlapati 
288504af5a0SPatrick Williams inline void afterGetInventory(
289504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
291a974c132SLakshmi Yadlapati     const dbus::utility::DBusPropertiesMap& propertiesList)
292a974c132SLakshmi Yadlapati {
293a974c132SLakshmi Yadlapati     if (ec)
294a974c132SLakshmi Yadlapati     {
295a974c132SLakshmi Yadlapati         // doesn't have to include this
296a974c132SLakshmi Yadlapati         // interface
297a974c132SLakshmi Yadlapati         return;
298a974c132SLakshmi Yadlapati     }
299a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
300a974c132SLakshmi Yadlapati 
301*f7e62c14SMyung Bae     asset_utils::extractAssetInfo(asyncResp, ""_json_pointer, propertiesList,
302*f7e62c14SMyung Bae                                   false);
303*f7e62c14SMyung Bae 
304a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
305a974c132SLakshmi Yadlapati 
306a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
307*f7e62c14SMyung Bae         dbus_utils::UnpackErrorPrinter(), propertiesList, "SubModel", subModel);
308a974c132SLakshmi Yadlapati 
309a974c132SLakshmi Yadlapati     if (!success)
310a974c132SLakshmi Yadlapati     {
311a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
312a974c132SLakshmi Yadlapati         return;
313a974c132SLakshmi Yadlapati     }
314a974c132SLakshmi Yadlapati 
315a974c132SLakshmi Yadlapati     if (subModel != nullptr)
316a974c132SLakshmi Yadlapati     {
317a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
318a974c132SLakshmi Yadlapati     }
319a974c132SLakshmi Yadlapati 
320a974c132SLakshmi Yadlapati     // Grab the bios version
321a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
322a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
323a974c132SLakshmi Yadlapati }
324a974c132SLakshmi Yadlapati 
325bd79bce8SPatrick Williams inline void afterGetAssetTag(
326bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
327bd79bce8SPatrick Williams     const boost::system::error_code& ec, const std::string& value)
328a974c132SLakshmi Yadlapati {
329a974c132SLakshmi Yadlapati     if (ec)
330a974c132SLakshmi Yadlapati     {
331a974c132SLakshmi Yadlapati         // doesn't have to include this
332a974c132SLakshmi Yadlapati         // interface
333a974c132SLakshmi Yadlapati         return;
334a974c132SLakshmi Yadlapati     }
335a974c132SLakshmi Yadlapati 
336a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
337a974c132SLakshmi Yadlapati }
338a974c132SLakshmi Yadlapati 
339a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
340a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
341a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
342a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
343a974c132SLakshmi Yadlapati {
3441abe55efSEd Tanous     if (ec)
3451abe55efSEd Tanous     {
346b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
347ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
348c5b2abe0SLewanczyk, Dawid         return;
349c5b2abe0SLewanczyk, Dawid     }
350c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
351002d39b4SEd Tanous     for (const std::pair<
352002d39b4SEd Tanous              std::string,
353002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
3541214b7e7SGunnar Mills              object : subtree)
3551abe55efSEd Tanous     {
356c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
35762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
358002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
3591214b7e7SGunnar Mills             connectionNames = object.second;
36026f6976fSEd Tanous         if (connectionNames.empty())
3611abe55efSEd Tanous         {
362c5b2abe0SLewanczyk, Dawid             continue;
363c5b2abe0SLewanczyk, Dawid         }
364029573d4SEd Tanous 
3656c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
3666c34de48SEd Tanous         // BiosVer
36704a258f4SEd Tanous         for (const auto& connection : connectionNames)
3681abe55efSEd Tanous         {
36904a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
3701abe55efSEd Tanous             {
371a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
3721abe55efSEd Tanous                 {
37362598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
3749d3ae10eSAlpana Kumari 
375ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
3765fd0aafbSNinad Palsule                 }
37704a258f4SEd Tanous                 else if (interfaceName ==
37804a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
3791abe55efSEd Tanous                 {
38062598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
38157e8c9beSAlpana Kumari 
382ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
3835fd0aafbSNinad Palsule                 }
384002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
3851abe55efSEd Tanous                 {
38662598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
387bc1d29deSKrzysztof Grobelny 
388deae6a78SEd Tanous                     dbus::utility::getAllProperties(
389a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
390a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
391ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
392b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
3931214b7e7SGunnar Mills                                         properties) {
394a974c132SLakshmi Yadlapati                             afterGetUUID(asyncResp, ec3, properties);
395bc1d29deSKrzysztof Grobelny                         });
396c5b2abe0SLewanczyk, Dawid                 }
397029573d4SEd Tanous                 else if (interfaceName ==
398029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
3991abe55efSEd Tanous                 {
400deae6a78SEd Tanous                     dbus::utility::getAllProperties(
401a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
402bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
403a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
404b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
405a974c132SLakshmi Yadlapati                                         properties) {
406a974c132SLakshmi Yadlapati                             afterGetInventory(asyncResp, ec3, properties);
407bc1d29deSKrzysztof Grobelny                         });
408e4a4b9a9SJames Feist 
409deae6a78SEd Tanous                     dbus::utility::getProperty<std::string>(
410deae6a78SEd Tanous                         connection.first, path,
4111e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4121e1e598dSJonathan Doman                         "AssetTag",
4131e1e598dSJonathan Doman                         "AssetTag",
414a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
415a974c132SLakshmi Yadlapati                 }
416a974c132SLakshmi Yadlapati             }
417a974c132SLakshmi Yadlapati         }
418a974c132SLakshmi Yadlapati     }
419a974c132SLakshmi Yadlapati }
420a974c132SLakshmi Yadlapati 
421a974c132SLakshmi Yadlapati /*
422a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
423a974c132SLakshmi Yadlapati  *
424a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
425a974c132SLakshmi Yadlapati  *
426a974c132SLakshmi Yadlapati  * @return None.
427a974c132SLakshmi Yadlapati  */
428504af5a0SPatrick Williams inline void getComputerSystem(
429504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
430e4a4b9a9SJames Feist {
431a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
432a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
433a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
434a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
435a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
436a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
437a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
438a974c132SLakshmi Yadlapati     };
439a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
440a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
44151bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
442c5b2abe0SLewanczyk, Dawid }
443c5b2abe0SLewanczyk, Dawid 
444c5b2abe0SLewanczyk, Dawid /**
445c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
446c5b2abe0SLewanczyk, Dawid  *
447ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
4485e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
449c5b2abe0SLewanczyk, Dawid  *
450c5b2abe0SLewanczyk, Dawid  * @return None.
451c5b2abe0SLewanczyk, Dawid  */
4525e7c1f31SOliver Brewka inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4535e7c1f31SOliver Brewka                          const uint64_t computerSystemIndex)
4541abe55efSEd Tanous {
45562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
456a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
457a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
458deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
459a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
460deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState",
461ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
4621e1e598dSJonathan Doman                     const std::string& hostState) {
4631abe55efSEd Tanous             if (ec)
4641abe55efSEd Tanous             {
46522228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
46622228c28SAndrew Geissler                 {
46722228c28SAndrew Geissler                     // Service not available, no error, just don't return
46822228c28SAndrew Geissler                     // host state info
46962598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
47022228c28SAndrew Geissler                     return;
47122228c28SAndrew Geissler                 }
47262598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
473ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
474c5b2abe0SLewanczyk, Dawid                 return;
475c5b2abe0SLewanczyk, Dawid             }
4766617338dSEd Tanous 
47762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
478c5b2abe0SLewanczyk, Dawid             // Verify Host State
4791e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
4801abe55efSEd Tanous             {
481bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
482bd79bce8SPatrick Williams                     resource::PowerState::On;
483539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
484539d8c6bSEd Tanous                     resource::State::Enabled;
4851abe55efSEd Tanous             }
4861e1e598dSJonathan Doman             else if (hostState ==
4870fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
4888c888608SGunnar Mills             {
489bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
490bd79bce8SPatrick Williams                     resource::PowerState::On;
491539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
492539d8c6bSEd Tanous                     resource::State::Quiesced;
4938c888608SGunnar Mills             }
4941e1e598dSJonathan Doman             else if (hostState ==
4950fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
49683935af9SAndrew Geissler             {
497bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
498bd79bce8SPatrick Williams                     resource::PowerState::On;
499539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
500539d8c6bSEd Tanous                     resource::State::InTest;
50183935af9SAndrew Geissler             }
5020fda0f12SGeorge Liu             else if (
5031e1e598dSJonathan Doman                 hostState ==
5040fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5051a2a1437SAndrew Geissler             {
506539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
507539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
508539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
509539d8c6bSEd Tanous                     resource::State::Starting;
5101a2a1437SAndrew Geissler             }
511bd79bce8SPatrick Williams             else if (
512bd79bce8SPatrick Williams                 hostState ==
5130fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5141a2a1437SAndrew Geissler             {
515539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
516539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
517539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
518539d8c6bSEd Tanous                     resource::State::Disabled;
5191a2a1437SAndrew Geissler             }
5201abe55efSEd Tanous             else
5211abe55efSEd Tanous             {
522bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
523bd79bce8SPatrick Williams                     resource::PowerState::Off;
524539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
525539d8c6bSEd Tanous                     resource::State::Disabled;
526c5b2abe0SLewanczyk, Dawid             }
5271e1e598dSJonathan Doman         });
528c5b2abe0SLewanczyk, Dawid }
529c5b2abe0SLewanczyk, Dawid 
530c5b2abe0SLewanczyk, Dawid /**
531786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
532491d8ee7SSantosh Puranik  *
533491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
534491d8ee7SSantosh Puranik  *
535491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
536491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
537491d8ee7SSantosh Puranik  */
53823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
539491d8ee7SSantosh Puranik {
540491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
541491d8ee7SSantosh Puranik     {
542491d8ee7SSantosh Puranik         return "None";
543491d8ee7SSantosh Puranik     }
5443174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
545491d8ee7SSantosh Puranik     {
546491d8ee7SSantosh Puranik         return "Hdd";
547491d8ee7SSantosh Puranik     }
5483174e4dfSEd Tanous     if (dbusSource ==
549a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
550491d8ee7SSantosh Puranik     {
551491d8ee7SSantosh Puranik         return "Cd";
552491d8ee7SSantosh Puranik     }
5533174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
554491d8ee7SSantosh Puranik     {
555491d8ee7SSantosh Puranik         return "Pxe";
556491d8ee7SSantosh Puranik     }
5573174e4dfSEd Tanous     if (dbusSource ==
558944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
5599f16b2c1SJennifer Lee     {
5609f16b2c1SJennifer Lee         return "Usb";
5619f16b2c1SJennifer Lee     }
562491d8ee7SSantosh Puranik     return "";
563491d8ee7SSantosh Puranik }
564491d8ee7SSantosh Puranik 
565491d8ee7SSantosh Puranik /**
566cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
567cd9a4666SKonstantin Aladyshev  *
568cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
569cd9a4666SKonstantin Aladyshev  *
570cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
571cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
572cd9a4666SKonstantin Aladyshev  */
573cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
574cd9a4666SKonstantin Aladyshev {
575cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
576cd9a4666SKonstantin Aladyshev     {
577cd9a4666SKonstantin Aladyshev         return "Legacy";
578cd9a4666SKonstantin Aladyshev     }
579cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
580cd9a4666SKonstantin Aladyshev     {
581cd9a4666SKonstantin Aladyshev         return "UEFI";
582cd9a4666SKonstantin Aladyshev     }
583cd9a4666SKonstantin Aladyshev     return "";
584cd9a4666SKonstantin Aladyshev }
585cd9a4666SKonstantin Aladyshev 
586cd9a4666SKonstantin Aladyshev /**
587786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
588491d8ee7SSantosh Puranik  *
589491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
590491d8ee7SSantosh Puranik  *
591491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
592491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
593491d8ee7SSantosh Puranik  */
59423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
595491d8ee7SSantosh Puranik {
596491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
597491d8ee7SSantosh Puranik     {
598491d8ee7SSantosh Puranik         return "None";
599491d8ee7SSantosh Puranik     }
6003174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
601491d8ee7SSantosh Puranik     {
602491d8ee7SSantosh Puranik         return "Diags";
603491d8ee7SSantosh Puranik     }
6043174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
605491d8ee7SSantosh Puranik     {
606491d8ee7SSantosh Puranik         return "BiosSetup";
607491d8ee7SSantosh Puranik     }
608491d8ee7SSantosh Puranik     return "";
609491d8ee7SSantosh Puranik }
610491d8ee7SSantosh Puranik 
611491d8ee7SSantosh Puranik /**
612e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
613e43914b3SAndrew Geissler  *
614e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
615e43914b3SAndrew Geissler  *
616e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
617e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
618e43914b3SAndrew Geissler  */
619e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
620e43914b3SAndrew Geissler {
621e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
622e43914b3SAndrew Geissler     // enum
623e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
624e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
625e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
626e43914b3SAndrew Geissler     {
627e43914b3SAndrew Geissler         rfBpLastState = "None";
628e43914b3SAndrew Geissler     }
629e43914b3SAndrew Geissler     else if (dbusBootProgress ==
630e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
631e43914b3SAndrew Geissler              "PrimaryProcInit")
632e43914b3SAndrew Geissler     {
633e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
634e43914b3SAndrew Geissler     }
635e43914b3SAndrew Geissler     else if (dbusBootProgress ==
636e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
637e43914b3SAndrew Geissler              "BusInit")
638e43914b3SAndrew Geissler     {
639e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
640e43914b3SAndrew Geissler     }
641e43914b3SAndrew Geissler     else if (dbusBootProgress ==
642e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
643e43914b3SAndrew Geissler              "MemoryInit")
644e43914b3SAndrew Geissler     {
645e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
646e43914b3SAndrew Geissler     }
647e43914b3SAndrew Geissler     else if (dbusBootProgress ==
648e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
649e43914b3SAndrew Geissler              "SecondaryProcInit")
650e43914b3SAndrew Geissler     {
651e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
652e43914b3SAndrew Geissler     }
653e43914b3SAndrew Geissler     else if (dbusBootProgress ==
654e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
655e43914b3SAndrew Geissler              "PCIInit")
656e43914b3SAndrew Geissler     {
657e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
658e43914b3SAndrew Geissler     }
659e43914b3SAndrew Geissler     else if (dbusBootProgress ==
660e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
661e43914b3SAndrew Geissler              "SystemSetup")
662e43914b3SAndrew Geissler     {
663e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
664e43914b3SAndrew Geissler     }
665e43914b3SAndrew Geissler     else if (dbusBootProgress ==
666e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
667e43914b3SAndrew Geissler              "SystemInitComplete")
668e43914b3SAndrew Geissler     {
669e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
670e43914b3SAndrew Geissler     }
671e43914b3SAndrew Geissler     else if (dbusBootProgress ==
672e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
673e43914b3SAndrew Geissler              "OSStart")
674e43914b3SAndrew Geissler     {
675e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
676e43914b3SAndrew Geissler     }
677e43914b3SAndrew Geissler     else if (dbusBootProgress ==
678e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
679e43914b3SAndrew Geissler              "OSRunning")
680e43914b3SAndrew Geissler     {
681e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
682e43914b3SAndrew Geissler     }
683e43914b3SAndrew Geissler     else
684e43914b3SAndrew Geissler     {
68562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
686e43914b3SAndrew Geissler         // Just return the default
687e43914b3SAndrew Geissler     }
688e43914b3SAndrew Geissler     return rfBpLastState;
689e43914b3SAndrew Geissler }
690e43914b3SAndrew Geissler 
691e43914b3SAndrew Geissler /**
692786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
693491d8ee7SSantosh Puranik  *
694491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
695944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
696944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
697491d8ee7SSantosh Puranik  *
698944ffaf9SJohnathan Mantey  * @return Integer error code.
699491d8ee7SSantosh Puranik  */
700bd79bce8SPatrick Williams inline int assignBootParameters(
701bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
702bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
703491d8ee7SSantosh Puranik {
704c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
705c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
706944ffaf9SJohnathan Mantey 
707491d8ee7SSantosh Puranik     if (rfSource == "None")
708491d8ee7SSantosh Puranik     {
709944ffaf9SJohnathan Mantey         return 0;
710491d8ee7SSantosh Puranik     }
7113174e4dfSEd Tanous     if (rfSource == "Pxe")
712491d8ee7SSantosh Puranik     {
713944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
714944ffaf9SJohnathan Mantey     }
715944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
716944ffaf9SJohnathan Mantey     {
717944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
718944ffaf9SJohnathan Mantey     }
719944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
720944ffaf9SJohnathan Mantey     {
721944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
722944ffaf9SJohnathan Mantey     }
723944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
724944ffaf9SJohnathan Mantey     {
725944ffaf9SJohnathan Mantey         bootSource =
726944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
727944ffaf9SJohnathan Mantey     }
728944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
729944ffaf9SJohnathan Mantey     {
730944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
731491d8ee7SSantosh Puranik     }
7329f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7339f16b2c1SJennifer Lee     {
734944ffaf9SJohnathan Mantey         bootSource =
735944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7369f16b2c1SJennifer Lee     }
737491d8ee7SSantosh Puranik     else
738491d8ee7SSantosh Puranik     {
73962598e31SEd Tanous         BMCWEB_LOG_DEBUG(
74062598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
74162598e31SEd Tanous             bootSource);
742ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
743944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
744944ffaf9SJohnathan Mantey         return -1;
745491d8ee7SSantosh Puranik     }
746944ffaf9SJohnathan Mantey     return 0;
747491d8ee7SSantosh Puranik }
7481981771bSAli Ahmed 
749978b8803SAndrew Geissler /**
750978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
751978b8803SAndrew Geissler  *
752ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
7535e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
754978b8803SAndrew Geissler  *
755978b8803SAndrew Geissler  * @return None.
756978b8803SAndrew Geissler  */
7575e7c1f31SOliver Brewka inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7585e7c1f31SOliver Brewka                             const uint64_t computerSystemIndex)
759978b8803SAndrew Geissler {
760a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
761a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
762deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
763a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
7641e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
765a52f1d5bSEd Tanous         [asyncResp](const boost::system::error_code ec,
7661e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
767978b8803SAndrew Geissler             if (ec)
768978b8803SAndrew Geissler             {
769978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
770978b8803SAndrew Geissler                 // not found
771978b8803SAndrew Geissler                 return;
772978b8803SAndrew Geissler             }
773978b8803SAndrew Geissler 
77462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
775978b8803SAndrew Geissler 
776ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
777e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
7781e1e598dSJonathan Doman         });
779978b8803SAndrew Geissler }
780491d8ee7SSantosh Puranik 
781491d8ee7SSantosh Puranik /**
782b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
783b6d5d45cSHieu Huynh  *
784ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
7855e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
786b6d5d45cSHieu Huynh  *
787b6d5d45cSHieu Huynh  * @return None.
788b6d5d45cSHieu Huynh  */
789b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
7905e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7915e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
792b6d5d45cSHieu Huynh {
793a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
794a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
795deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
796a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
797b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
798ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
799b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
800b6d5d45cSHieu Huynh             if (ec)
801b6d5d45cSHieu Huynh             {
80262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
803b6d5d45cSHieu Huynh                 return;
804b6d5d45cSHieu Huynh             }
805b6d5d45cSHieu Huynh 
806b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
807b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
808b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
809b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
810b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
811b6d5d45cSHieu Huynh 
812b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
813ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
814b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
815b6d5d45cSHieu Huynh         });
816b6d5d45cSHieu Huynh }
817b6d5d45cSHieu Huynh 
818b6d5d45cSHieu Huynh /**
819c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
820cd9a4666SKonstantin Aladyshev  *
821ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
8225e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
823cd9a4666SKonstantin Aladyshev  *
824cd9a4666SKonstantin Aladyshev  * @return None.
825cd9a4666SKonstantin Aladyshev  */
826504af5a0SPatrick Williams inline void getBootOverrideType(
8275e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8285e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
829cd9a4666SKonstantin Aladyshev {
8305e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
8315e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
8325e7c1f31SOliver Brewka     path /= "boot";
8335e7c1f31SOliver Brewka 
834deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
8355e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
8361e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
837ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8381e1e598dSJonathan Doman                     const std::string& bootType) {
839cd9a4666SKonstantin Aladyshev             if (ec)
840cd9a4666SKonstantin Aladyshev             {
841cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
842cd9a4666SKonstantin Aladyshev                 return;
843cd9a4666SKonstantin Aladyshev             }
844cd9a4666SKonstantin Aladyshev 
84562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
846cd9a4666SKonstantin Aladyshev 
847ac106bf6SEd Tanous             asyncResp->res
848ac106bf6SEd Tanous                 .jsonValue["Boot"]
849002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
850613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
851cd9a4666SKonstantin Aladyshev 
8521e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
853cd9a4666SKonstantin Aladyshev             if (rfType.empty())
854cd9a4666SKonstantin Aladyshev             {
855ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
856cd9a4666SKonstantin Aladyshev                 return;
857cd9a4666SKonstantin Aladyshev             }
858cd9a4666SKonstantin Aladyshev 
859ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
8601e1e598dSJonathan Doman         });
861cd9a4666SKonstantin Aladyshev }
862cd9a4666SKonstantin Aladyshev 
863cd9a4666SKonstantin Aladyshev /**
864c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
865491d8ee7SSantosh Puranik  *
866ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
8675e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
868491d8ee7SSantosh Puranik  *
869491d8ee7SSantosh Puranik  * @return None.
870491d8ee7SSantosh Puranik  */
871504af5a0SPatrick Williams inline void getBootOverrideMode(
8725e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8735e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
874491d8ee7SSantosh Puranik {
8755e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
8765e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
8775e7c1f31SOliver Brewka     path /= "boot";
878deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
8795e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
8801e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
881ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8821e1e598dSJonathan Doman                     const std::string& bootModeStr) {
883491d8ee7SSantosh Puranik             if (ec)
884491d8ee7SSantosh Puranik             {
885b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
886ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
887491d8ee7SSantosh Puranik                 return;
888491d8ee7SSantosh Puranik             }
889491d8ee7SSantosh Puranik 
89062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
891491d8ee7SSantosh Puranik 
89220fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
89320fa6a2cSEd Tanous             allowed.emplace_back("None");
89420fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
89520fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
89620fa6a2cSEd Tanous             allowed.emplace_back("Cd");
89720fa6a2cSEd Tanous             allowed.emplace_back("Diags");
89820fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
89920fa6a2cSEd Tanous             allowed.emplace_back("Usb");
90020fa6a2cSEd Tanous 
901ac106bf6SEd Tanous             asyncResp->res
9020fda0f12SGeorge Liu                 .jsonValue["Boot"]
90320fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
90420fa6a2cSEd Tanous                 std::move(allowed);
9051e1e598dSJonathan Doman             if (bootModeStr !=
906491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
907491d8ee7SSantosh Puranik             {
9081e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
909491d8ee7SSantosh Puranik                 if (!rfMode.empty())
910491d8ee7SSantosh Puranik                 {
911bd79bce8SPatrick Williams                     asyncResp->res
912bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
913491d8ee7SSantosh Puranik                 }
914491d8ee7SSantosh Puranik             }
9151e1e598dSJonathan Doman         });
916491d8ee7SSantosh Puranik }
917491d8ee7SSantosh Puranik 
918491d8ee7SSantosh Puranik /**
919c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
920491d8ee7SSantosh Puranik  *
921ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
9225e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
923491d8ee7SSantosh Puranik  *
924491d8ee7SSantosh Puranik  * @return None.
925491d8ee7SSantosh Puranik  */
926504af5a0SPatrick Williams inline void getBootOverrideSource(
9275e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9285e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
929491d8ee7SSantosh Puranik {
9305e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
9315e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
9325e7c1f31SOliver Brewka     path /= "boot";
9335e7c1f31SOliver Brewka 
934deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
9355e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9361e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
9375e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
9381e1e598dSJonathan Doman                                          const std::string& bootSourceStr) {
939491d8ee7SSantosh Puranik             if (ec)
940491d8ee7SSantosh Puranik             {
9418f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
9428f1a35b9SAllen.Wang                 // Boot Override Source information
9438f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
9448f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
9455ef735c8SNan Zhou                 {
9468f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
947ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
9488f1a35b9SAllen.Wang                 }
949491d8ee7SSantosh Puranik                 return;
950491d8ee7SSantosh Puranik             }
951491d8ee7SSantosh Puranik 
95262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
953491d8ee7SSantosh Puranik 
9541e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
955491d8ee7SSantosh Puranik             if (!rfSource.empty())
956491d8ee7SSantosh Puranik             {
957ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
958ac106bf6SEd Tanous                     rfSource;
959491d8ee7SSantosh Puranik             }
960cd9a4666SKonstantin Aladyshev 
961cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
962cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
9635e7c1f31SOliver Brewka             getBootOverrideMode(asyncResp, computerSystemIndex);
9641e1e598dSJonathan Doman         });
965491d8ee7SSantosh Puranik }
966491d8ee7SSantosh Puranik 
967491d8ee7SSantosh Puranik /**
968c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
969c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
970c21865c4SKonstantin Aladyshev  * state
971491d8ee7SSantosh Puranik  *
972ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
9735e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
9745e7c1f31SOliver Brewka  * @param[in] bootOverrideEnableSetting
975491d8ee7SSantosh Puranik  *
976491d8ee7SSantosh Puranik  * @return None.
977491d8ee7SSantosh Puranik  */
978491d8ee7SSantosh Puranik 
979ac106bf6SEd Tanous inline void processBootOverrideEnable(
980ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9815e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const bool bootOverrideEnableSetting)
982c21865c4SKonstantin Aladyshev {
983c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
984c21865c4SKonstantin Aladyshev     {
985ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
986ac106bf6SEd Tanous             "Disabled";
987c21865c4SKonstantin Aladyshev         return;
988c21865c4SKonstantin Aladyshev     }
989c21865c4SKonstantin Aladyshev 
9905e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
9915e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
9925e7c1f31SOliver Brewka     path /= "boot";
9935e7c1f31SOliver Brewka     path /= "one_time";
9945e7c1f31SOliver Brewka 
995c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
996c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
997deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
9985e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
9991e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1000ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1001491d8ee7SSantosh Puranik             if (ec)
1002491d8ee7SSantosh Puranik             {
1003b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1004ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1005491d8ee7SSantosh Puranik                 return;
1006491d8ee7SSantosh Puranik             }
1007491d8ee7SSantosh Puranik 
1008c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1009c21865c4SKonstantin Aladyshev             {
1010ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1011ac106bf6SEd Tanous                     "Once";
1012c21865c4SKonstantin Aladyshev             }
1013c21865c4SKonstantin Aladyshev             else
1014c21865c4SKonstantin Aladyshev             {
1015ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1016c21865c4SKonstantin Aladyshev                     "Continuous";
1017c21865c4SKonstantin Aladyshev             }
10181e1e598dSJonathan Doman         });
1019491d8ee7SSantosh Puranik }
1020491d8ee7SSantosh Puranik 
1021491d8ee7SSantosh Puranik /**
1022c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1023c21865c4SKonstantin Aladyshev  *
1024ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
10255e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1026c21865c4SKonstantin Aladyshev  *
1027c21865c4SKonstantin Aladyshev  * @return None.
1028c21865c4SKonstantin Aladyshev  */
1029504af5a0SPatrick Williams inline void getBootOverrideEnable(
10305e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10315e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1032c21865c4SKonstantin Aladyshev {
10335e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
10345e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
10355e7c1f31SOliver Brewka     path /= "boot";
10365e7c1f31SOliver Brewka 
1037deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
10385e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
10391e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10405e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
10411e1e598dSJonathan Doman                                          const bool bootOverrideEnable) {
1042c21865c4SKonstantin Aladyshev             if (ec)
1043c21865c4SKonstantin Aladyshev             {
10448f1a35b9SAllen.Wang                 // Service not available, no error, just don't return
10458f1a35b9SAllen.Wang                 // Boot Override Enable information
10468f1a35b9SAllen.Wang                 if (ec.value() != EBADR &&
10478f1a35b9SAllen.Wang                     ec.value() != boost::asio::error::host_unreachable)
10485ef735c8SNan Zhou                 {
10498f1a35b9SAllen.Wang                     BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
1050ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
10518f1a35b9SAllen.Wang                 }
1052c21865c4SKonstantin Aladyshev                 return;
1053c21865c4SKonstantin Aladyshev             }
1054c21865c4SKonstantin Aladyshev 
10555e7c1f31SOliver Brewka             processBootOverrideEnable(asyncResp, computerSystemIndex,
10565e7c1f31SOliver Brewka                                       bootOverrideEnable);
10571e1e598dSJonathan Doman         });
1058c21865c4SKonstantin Aladyshev }
1059c21865c4SKonstantin Aladyshev 
1060c21865c4SKonstantin Aladyshev /**
1061c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1062c21865c4SKonstantin Aladyshev  *
1063ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
10645e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1065c21865c4SKonstantin Aladyshev  *
1066c21865c4SKonstantin Aladyshev  * @return None.
1067c21865c4SKonstantin Aladyshev  */
1068504af5a0SPatrick Williams inline void getBootProperties(
10695e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10705e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1071c21865c4SKonstantin Aladyshev {
107262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1073c21865c4SKonstantin Aladyshev 
10745e7c1f31SOliver Brewka     getBootOverrideSource(asyncResp, computerSystemIndex);
10755e7c1f31SOliver Brewka     getBootOverrideType(asyncResp, computerSystemIndex);
10765e7c1f31SOliver Brewka     getBootOverrideEnable(asyncResp, computerSystemIndex);
1077c21865c4SKonstantin Aladyshev }
1078c21865c4SKonstantin Aladyshev 
1079c21865c4SKonstantin Aladyshev /**
1080c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1081c0557e1aSGunnar Mills  *
1082c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1083c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1084c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1085c0557e1aSGunnar Mills  * last power operation time.
1086c0557e1aSGunnar Mills  *
1087ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1088c0557e1aSGunnar Mills  *
1089c0557e1aSGunnar Mills  * @return None.
1090c0557e1aSGunnar Mills  */
1091504af5a0SPatrick Williams inline void getLastResetTime(
10925e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10935e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1094c0557e1aSGunnar Mills {
109562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1096a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
1097a52f1d5bSEd Tanous         getChassisStateObjectPath(computerSystemIndex);
1098deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
1099a52f1d5bSEd Tanous         getChassisStateServiceName(computerSystemIndex), path,
11001e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1101ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1102ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1103c0557e1aSGunnar Mills             if (ec)
1104c0557e1aSGunnar Mills             {
110562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1106c0557e1aSGunnar Mills                 return;
1107c0557e1aSGunnar Mills             }
1108c0557e1aSGunnar Mills 
1109c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1110c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11111e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1112c0557e1aSGunnar Mills 
1113c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1114ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11152b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11161e1e598dSJonathan Doman         });
1117c0557e1aSGunnar Mills }
1118c0557e1aSGunnar Mills 
1119c0557e1aSGunnar Mills /**
1120797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1121797d5daeSCorey Hardesty  *
1122797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1123797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1124797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1125797d5daeSCorey Hardesty  * dbus.
1126797d5daeSCorey Hardesty  *
1127ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
11285e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1129797d5daeSCorey Hardesty  *
1130797d5daeSCorey Hardesty  * @return None.
1131797d5daeSCorey Hardesty  */
1132ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
11335e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11345e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1135797d5daeSCorey Hardesty {
113662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1137a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
1138a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
1139deae6a78SEd Tanous     dbus::utility::getAllProperties(
1140a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
1141797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1142ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1143ac106bf6SEd Tanous             const boost::system::error_code& ec,
1144797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1145797d5daeSCorey Hardesty             if (ec)
1146797d5daeSCorey Hardesty             {
1147d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1148d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1149797d5daeSCorey Hardesty                 {
1150d39a8c28SAishwary Joshi                     // Service not available, no error, just don't return
1151d39a8c28SAishwary Joshi                     // RebootAttempts information
115262598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1153ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1154797d5daeSCorey Hardesty                 }
1155797d5daeSCorey Hardesty                 return;
1156797d5daeSCorey Hardesty             }
1157797d5daeSCorey Hardesty 
1158797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1159797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1160797d5daeSCorey Hardesty 
1161797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1162bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1163bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1164797d5daeSCorey Hardesty 
1165797d5daeSCorey Hardesty             if (!success)
1166797d5daeSCorey Hardesty             {
1167ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1168797d5daeSCorey Hardesty                 return;
1169797d5daeSCorey Hardesty             }
1170797d5daeSCorey Hardesty 
1171797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1172797d5daeSCorey Hardesty             {
1173ac106bf6SEd Tanous                 asyncResp->res
1174ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1175797d5daeSCorey Hardesty                     *attemptsLeft;
1176797d5daeSCorey Hardesty             }
1177797d5daeSCorey Hardesty 
1178797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1179797d5daeSCorey Hardesty             {
1180ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1181797d5daeSCorey Hardesty                     *retryAttempts;
1182797d5daeSCorey Hardesty             }
1183797d5daeSCorey Hardesty         });
1184797d5daeSCorey Hardesty }
1185797d5daeSCorey Hardesty 
1186797d5daeSCorey Hardesty /**
11876bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11886bd5a8d2SGunnar Mills  *
1189ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
11905e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
11916bd5a8d2SGunnar Mills  *
11926bd5a8d2SGunnar Mills  * @return None.
11936bd5a8d2SGunnar Mills  */
1194504af5a0SPatrick Williams inline void getAutomaticRetryPolicy(
11955e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11965e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
11976bd5a8d2SGunnar Mills {
119862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
11996bd5a8d2SGunnar Mills 
12005e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
12015e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
12025e7c1f31SOliver Brewka     path /= "auto_reboot";
12035e7c1f31SOliver Brewka 
1204deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
12055e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
12061e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12075e7c1f31SOliver Brewka         [asyncResp, computerSystemIndex](const boost::system::error_code& ec,
1208ac106bf6SEd Tanous                                          bool autoRebootEnabled) {
12096bd5a8d2SGunnar Mills             if (ec)
12106bd5a8d2SGunnar Mills             {
1211d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1212d39a8c28SAishwary Joshi                 // AutoReboot information
1213d39a8c28SAishwary Joshi                 if (ec.value() != EBADR &&
1214d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
1215797d5daeSCorey Hardesty                 {
121662598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1217ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1218797d5daeSCorey Hardesty                 }
12196bd5a8d2SGunnar Mills                 return;
12206bd5a8d2SGunnar Mills             }
12216bd5a8d2SGunnar Mills 
122262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1223e05aec50SEd Tanous             if (autoRebootEnabled)
12246bd5a8d2SGunnar Mills             {
1225ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12266bd5a8d2SGunnar Mills                     "RetryAttempts";
12276bd5a8d2SGunnar Mills             }
12286bd5a8d2SGunnar Mills             else
12296bd5a8d2SGunnar Mills             {
1230ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1231ac106bf6SEd Tanous                     "Disabled";
12326bd5a8d2SGunnar Mills             }
12335e7c1f31SOliver Brewka             getAutomaticRebootAttempts(asyncResp, computerSystemIndex);
123469f35306SGunnar Mills 
123569f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
123669f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
123769f35306SGunnar Mills             // RetryAttempts.
123820fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
123920fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
124020fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1241ac106bf6SEd Tanous             asyncResp->res
1242bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1243bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
124420fa6a2cSEd Tanous                 std::move(allowed);
12451e1e598dSJonathan Doman         });
12466bd5a8d2SGunnar Mills }
12476bd5a8d2SGunnar Mills 
12486bd5a8d2SGunnar Mills /**
1249797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1250797d5daeSCorey Hardesty  *
1251ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
12525e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1253797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1254797d5daeSCorey Hardesty  *
1255797d5daeSCorey Hardesty  *@return None.
1256797d5daeSCorey Hardesty  */
1257797d5daeSCorey Hardesty 
1258ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1259ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1260d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const uint32_t retryAttempts)
1261797d5daeSCorey Hardesty {
126262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
1263d43cc6bcSOliver Brewka 
1264d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/AutomaticRetryAttempts",
1265d43cc6bcSOliver Brewka                     getHostStateServiceName(computerSystemIndex),
1266d43cc6bcSOliver Brewka                     getHostStateObjectPath(computerSystemIndex),
1267d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
1268d43cc6bcSOliver Brewka                     "RetryAttempts", retryAttempts);
1269797d5daeSCorey Hardesty }
1270797d5daeSCorey Hardesty 
12718d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12728d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12738d69c668SEd Tanous {
12748d69c668SEd Tanous     if (value ==
12758d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12768d69c668SEd Tanous     {
12778d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
12788d69c668SEd Tanous     }
12798d69c668SEd Tanous     if (value ==
12808d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
12818d69c668SEd Tanous     {
12828d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12838d69c668SEd Tanous     }
12848d69c668SEd Tanous     if (value ==
12853a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
12868d69c668SEd Tanous     {
12878d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
12888d69c668SEd Tanous     }
12898d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
12908d69c668SEd Tanous     {
12918d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12928d69c668SEd Tanous     }
12938d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
12948d69c668SEd Tanous }
1295797d5daeSCorey Hardesty /**
1296c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1297c6a620f2SGeorge Liu  *
1298ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1299c6a620f2SGeorge Liu  *
1300c6a620f2SGeorge Liu  * @return None.
1301c6a620f2SGeorge Liu  */
1302504af5a0SPatrick Williams inline void getPowerRestorePolicy(
13035e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13045e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
1305c6a620f2SGeorge Liu {
130662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1307c6a620f2SGeorge Liu 
13085e7c1f31SOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
13095e7c1f31SOliver Brewka                                          std::to_string(computerSystemIndex));
13105e7c1f31SOliver Brewka     path /= "power_restore_policy";
13115e7c1f31SOliver Brewka 
1312deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
13135e7c1f31SOliver Brewka         "xyz.openbmc_project.Settings", path,
13141e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1315ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13165e7e2dc5SEd Tanous                     const std::string& policy) {
1317c6a620f2SGeorge Liu             if (ec)
1318c6a620f2SGeorge Liu             {
131962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1320c6a620f2SGeorge Liu                 return;
1321c6a620f2SGeorge Liu             }
13228d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
13238d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
13248d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1325c6a620f2SGeorge Liu             {
1326ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1327c6a620f2SGeorge Liu                 return;
1328c6a620f2SGeorge Liu             }
1329c6a620f2SGeorge Liu 
13308d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13311e1e598dSJonathan Doman         });
1332c6a620f2SGeorge Liu }
1333c6a620f2SGeorge Liu 
1334c6a620f2SGeorge Liu /**
13359dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13369dcfe8c1SAlbert Zhang  *
13379dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13389dcfe8c1SAlbert Zhang  *
13399dcfe8c1SAlbert Zhang  * @return None.
13409dcfe8c1SAlbert Zhang  */
1341504af5a0SPatrick Williams inline void getStopBootOnFault(
1342504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13439dcfe8c1SAlbert Zhang {
134462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13459dcfe8c1SAlbert Zhang 
1346deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1347deae6a78SEd Tanous         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
13489dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13499dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13509dcfe8c1SAlbert Zhang             if (ec)
13519dcfe8c1SAlbert Zhang             {
1352d39a8c28SAishwary Joshi                 // Service not available, no error, just don't return
1353d39a8c28SAishwary Joshi                 // StopBootOnFault information
1354d39a8c28SAishwary Joshi                 if (ec.value() != EBADR ||
1355d39a8c28SAishwary Joshi                     ec.value() != boost::asio::error::host_unreachable)
13569dcfe8c1SAlbert Zhang                 {
1357b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13589dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
13599dcfe8c1SAlbert Zhang                 }
13609dcfe8c1SAlbert Zhang                 return;
13619dcfe8c1SAlbert Zhang             }
13629dcfe8c1SAlbert Zhang 
13639dcfe8c1SAlbert Zhang             if (value)
13649dcfe8c1SAlbert Zhang             {
1365539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1366539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
13679dcfe8c1SAlbert Zhang             }
13689dcfe8c1SAlbert Zhang             else
13699dcfe8c1SAlbert Zhang             {
1370539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1371539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
13729dcfe8c1SAlbert Zhang             }
13739dcfe8c1SAlbert Zhang         });
13749dcfe8c1SAlbert Zhang }
13759dcfe8c1SAlbert Zhang 
13765e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBootCallback(
13775e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13785e7c1f31SOliver Brewka     const uint64_t computerSystemIndex, const boost::system::error_code& ec,
13795e7c1f31SOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
13801981771bSAli Ahmed {
13811981771bSAli Ahmed     if (ec)
13821981771bSAli Ahmed     {
13835e7c1f31SOliver Brewka         BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}", ec);
13841981771bSAli Ahmed         // This is an optional D-Bus object so just return if
13851981771bSAli Ahmed         // error occurs
13861981771bSAli Ahmed         return;
13871981771bSAli Ahmed     }
138826f6976fSEd Tanous     if (subtree.empty())
13891981771bSAli Ahmed     {
13901981771bSAli Ahmed         // As noted above, this is an optional interface so just return
13911981771bSAli Ahmed         // if there is no instance found
13921981771bSAli Ahmed         return;
13931981771bSAli Ahmed     }
13941981771bSAli Ahmed 
13955e7c1f31SOliver Brewka     std::string path;
13965e7c1f31SOliver Brewka     std::string service;
13975e7c1f31SOliver Brewka 
13985e7c1f31SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
13991981771bSAli Ahmed     {
14005e7c1f31SOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
14015e7c1f31SOliver Brewka                                                subtree, path, service))
14025e7c1f31SOliver Brewka         {
14031981771bSAli Ahmed             return;
14041981771bSAli Ahmed         }
14055e7c1f31SOliver Brewka     }
14065e7c1f31SOliver Brewka     else
14075e7c1f31SOliver Brewka     {
14081981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14091981771bSAli Ahmed         // field
14101981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14111981771bSAli Ahmed         {
141262598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1413ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14141981771bSAli Ahmed             return;
14151981771bSAli Ahmed         }
14161981771bSAli Ahmed 
14175e7c1f31SOliver Brewka         path = subtree[0].first;
14185e7c1f31SOliver Brewka         service = subtree[0].second.begin()->first;
14195e7c1f31SOliver Brewka     }
14205e7c1f31SOliver Brewka 
14215e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm service {}", service);
14225e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("found tpm path {}", path);
14231981771bSAli Ahmed 
14241981771bSAli Ahmed     // Valid TPM Enable object found, now reading the current value
1425deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
14265e7c1f31SOliver Brewka         service, path, "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
14275e7c1f31SOliver Brewka         [asyncResp](const boost::system::error_code& ec2, bool tpmRequired) {
14288a592810SEd Tanous             if (ec2)
14291981771bSAli Ahmed             {
14305e7c1f31SOliver Brewka                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
14315e7c1f31SOliver Brewka                                  ec2);
1432ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14331981771bSAli Ahmed                 return;
14341981771bSAli Ahmed             }
14351981771bSAli Ahmed 
14361e1e598dSJonathan Doman             if (tpmRequired)
14371981771bSAli Ahmed             {
1438ac106bf6SEd Tanous                 asyncResp->res
1439ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14401981771bSAli Ahmed                     "Required";
14411981771bSAli Ahmed             }
14421981771bSAli Ahmed             else
14431981771bSAli Ahmed             {
1444ac106bf6SEd Tanous                 asyncResp->res
1445ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14461981771bSAli Ahmed                     "Disabled";
14471981771bSAli Ahmed             }
14481e1e598dSJonathan Doman         });
14495e7c1f31SOliver Brewka }
14505e7c1f31SOliver Brewka 
14515e7c1f31SOliver Brewka /**
14525e7c1f31SOliver Brewka  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14535e7c1f31SOliver Brewka  * TPM is required for booting the host.
14545e7c1f31SOliver Brewka  *
14555e7c1f31SOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
14565e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
14575e7c1f31SOliver Brewka  *
14585e7c1f31SOliver Brewka  * @return None.
14595e7c1f31SOliver Brewka  */
14605e7c1f31SOliver Brewka inline void getTrustedModuleRequiredToBoot(
14615e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
14625e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
14635e7c1f31SOliver Brewka {
14645e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
14655e7c1f31SOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
14665e7c1f31SOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
14675e7c1f31SOliver Brewka     dbus::utility::getSubTree(
14685e7c1f31SOliver Brewka         "/", 0, interfaces,
14695e7c1f31SOliver Brewka         std::bind_front(getTrustedModuleRequiredToBootCallback, asyncResp,
14705e7c1f31SOliver Brewka                         computerSystemIndex));
14711981771bSAli Ahmed }
14721981771bSAli Ahmed 
1473d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBootCallback(
1474d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1475d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired,
1476d43cc6bcSOliver Brewka     const boost::system::error_code& ec,
1477d43cc6bcSOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree)
14781c05dae3SAli Ahmed {
14791c05dae3SAli Ahmed     if (ec)
14801c05dae3SAli Ahmed     {
1481d43cc6bcSOliver Brewka         BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}", ec);
1482ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
14831c05dae3SAli Ahmed         return;
14841c05dae3SAli Ahmed     }
148526f6976fSEd Tanous     if (subtree.empty())
14861c05dae3SAli Ahmed     {
1487d43cc6bcSOliver Brewka         messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
14881c05dae3SAli Ahmed                                          "TrustedModuleRequiredToBoot");
14891c05dae3SAli Ahmed         return;
14901c05dae3SAli Ahmed     }
14911c05dae3SAli Ahmed 
1492d43cc6bcSOliver Brewka     std::string path;
1493d43cc6bcSOliver Brewka     std::string serv;
1494d43cc6bcSOliver Brewka 
1495d43cc6bcSOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
14961c05dae3SAli Ahmed     {
1497d43cc6bcSOliver Brewka         if (!indexMatchingSubTreeMapObjectPath(asyncResp, computerSystemIndex,
1498d43cc6bcSOliver Brewka                                                subtree, path, serv))
1499d43cc6bcSOliver Brewka         {
1500d43cc6bcSOliver Brewka             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1501ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15021c05dae3SAli Ahmed             return;
15031c05dae3SAli Ahmed         }
1504d43cc6bcSOliver Brewka     }
1505d43cc6bcSOliver Brewka     else
1506d43cc6bcSOliver Brewka     {
15071c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15081c05dae3SAli Ahmed         // field
15091c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15101c05dae3SAli Ahmed         {
151162598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1512ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15131c05dae3SAli Ahmed             return;
15141c05dae3SAli Ahmed         }
15151c05dae3SAli Ahmed 
1516d43cc6bcSOliver Brewka         path = subtree[0].first;
1517d43cc6bcSOliver Brewka         serv = subtree[0].second.begin()->first;
1518d43cc6bcSOliver Brewka     }
15191c05dae3SAli Ahmed 
15201c05dae3SAli Ahmed     if (serv.empty())
15211c05dae3SAli Ahmed     {
152262598e31SEd Tanous         BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1523ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15241c05dae3SAli Ahmed         return;
15251c05dae3SAli Ahmed     }
15261c05dae3SAli Ahmed 
15271c05dae3SAli Ahmed     // Valid TPM Enable object found, now setting the value
1528d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv, path,
1529d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1530d43cc6bcSOliver Brewka                     tpmRequired);
1531d43cc6bcSOliver Brewka }
1532d43cc6bcSOliver Brewka 
1533d43cc6bcSOliver Brewka /**
1534d43cc6bcSOliver Brewka  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1535d43cc6bcSOliver Brewka  * TPM is required for booting the host.
1536d43cc6bcSOliver Brewka  *
1537d43cc6bcSOliver Brewka  * @param[in] asyncResp     Shared pointer for generating response message.
1538d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1539d43cc6bcSOliver Brewka  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
1540d43cc6bcSOliver Brewka  *
1541d43cc6bcSOliver Brewka  * @return None.
1542d43cc6bcSOliver Brewka  */
1543d43cc6bcSOliver Brewka inline void setTrustedModuleRequiredToBoot(
1544d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1545d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const bool tpmRequired)
1546d43cc6bcSOliver Brewka {
1547d43cc6bcSOliver Brewka     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1548d43cc6bcSOliver Brewka     constexpr std::array<std::string_view, 1> interfaces = {
1549d43cc6bcSOliver Brewka         "xyz.openbmc_project.Control.TPM.Policy"};
1550d43cc6bcSOliver Brewka     dbus::utility::getSubTree(
1551d43cc6bcSOliver Brewka         "/", 0, interfaces,
1552d43cc6bcSOliver Brewka         std::bind_front(setTrustedModuleRequiredToBootCallback, asyncResp,
1553d43cc6bcSOliver Brewka                         computerSystemIndex, tpmRequired));
15541c05dae3SAli Ahmed }
15551c05dae3SAli Ahmed 
15561c05dae3SAli Ahmed /**
1557491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1558491d8ee7SSantosh Puranik  *
1559ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1560d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1561cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1562cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1563cd9a4666SKonstantin Aladyshev  */
1564ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1565d43cc6bcSOliver Brewka                         const uint64_t computerSystemIndex,
1566cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1567cd9a4666SKonstantin Aladyshev {
1568c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1569cd9a4666SKonstantin Aladyshev 
1570c21865c4SKonstantin Aladyshev     if (!bootType)
1571cd9a4666SKonstantin Aladyshev     {
1572c21865c4SKonstantin Aladyshev         return;
1573c21865c4SKonstantin Aladyshev     }
1574c21865c4SKonstantin Aladyshev 
1575cd9a4666SKonstantin Aladyshev     // Source target specified
157662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1577cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1578cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1579cd9a4666SKonstantin Aladyshev     {
1580cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1581cd9a4666SKonstantin Aladyshev     }
1582cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1583cd9a4666SKonstantin Aladyshev     {
1584cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1585cd9a4666SKonstantin Aladyshev     }
1586cd9a4666SKonstantin Aladyshev     else
1587cd9a4666SKonstantin Aladyshev     {
158862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
158962598e31SEd Tanous                          "BootSourceOverrideMode: {}",
159062598e31SEd Tanous                          *bootType);
1591ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1592cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1593cd9a4666SKonstantin Aladyshev         return;
1594cd9a4666SKonstantin Aladyshev     }
1595cd9a4666SKonstantin Aladyshev 
1596cd9a4666SKonstantin Aladyshev     // Act on validated parameters
159762598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1598cd9a4666SKonstantin Aladyshev 
1599d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1600d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1601d43cc6bcSOliver Brewka     path /= "boot";
1602e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1603d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
160487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1605e93abac6SGinu George                     bootTypeStr);
1606cd9a4666SKonstantin Aladyshev }
1607cd9a4666SKonstantin Aladyshev 
1608cd9a4666SKonstantin Aladyshev /**
1609cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1610cd9a4666SKonstantin Aladyshev  *
1611ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1612ac106bf6SEd Tanous  * message.
1613d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1614c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1615c21865c4SKonstantin Aladyshev  * @return Integer error code.
1616c21865c4SKonstantin Aladyshev  */
1617ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1618d43cc6bcSOliver Brewka                           const uint64_t computerSystemIndex,
1619c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1620c21865c4SKonstantin Aladyshev {
1621c21865c4SKonstantin Aladyshev     if (!bootEnable)
1622c21865c4SKonstantin Aladyshev     {
1623c21865c4SKonstantin Aladyshev         return;
1624c21865c4SKonstantin Aladyshev     }
1625c21865c4SKonstantin Aladyshev     // Source target specified
162662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1627c21865c4SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1629c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1630c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1631c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1632c21865c4SKonstantin Aladyshev     {
1633c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1634c21865c4SKonstantin Aladyshev     }
1635c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1636c21865c4SKonstantin Aladyshev     {
1637c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1638c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1639c21865c4SKonstantin Aladyshev     }
1640c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1641c21865c4SKonstantin Aladyshev     {
1642c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1643c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1644c21865c4SKonstantin Aladyshev     }
1645c21865c4SKonstantin Aladyshev     else
1646c21865c4SKonstantin Aladyshev     {
164762598e31SEd Tanous         BMCWEB_LOG_DEBUG(
164862598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
164962598e31SEd Tanous             *bootEnable);
1650ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1651c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1652c21865c4SKonstantin Aladyshev         return;
1653c21865c4SKonstantin Aladyshev     }
1654c21865c4SKonstantin Aladyshev 
1655c21865c4SKonstantin Aladyshev     // Act on validated parameters
165662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1657c21865c4SKonstantin Aladyshev 
1658d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1659d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1660d43cc6bcSOliver Brewka     path /= "boot";
1661e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1662d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
166387c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1664e93abac6SGinu George                     bootOverrideEnable);
1665c21865c4SKonstantin Aladyshev 
1666c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1667c21865c4SKonstantin Aladyshev     {
1668c21865c4SKonstantin Aladyshev         return;
1669c21865c4SKonstantin Aladyshev     }
1670c21865c4SKonstantin Aladyshev 
1671c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1672c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
167362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
167462598e31SEd Tanous                      bootOverridePersistent);
1675c21865c4SKonstantin Aladyshev 
1676d43cc6bcSOliver Brewka     path /= "one_time";
1677e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1678d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
167987c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1680e93abac6SGinu George                     !bootOverridePersistent);
1681c21865c4SKonstantin Aladyshev }
1682c21865c4SKonstantin Aladyshev 
1683c21865c4SKonstantin Aladyshev /**
1684c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1685c21865c4SKonstantin Aladyshev  *
1686ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1687d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1688491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1689491d8ee7SSantosh Puranik  *
1690265c1602SJohnathan Mantey  * @return Integer error code.
1691491d8ee7SSantosh Puranik  */
1692504af5a0SPatrick Williams inline void setBootModeOrSource(
1693504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1694d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1695cd9a4666SKonstantin Aladyshev     const std::optional<std::string>& bootSource)
1696491d8ee7SSantosh Puranik {
1697c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1698c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1699944ffaf9SJohnathan Mantey 
1700c21865c4SKonstantin Aladyshev     if (!bootSource)
1701491d8ee7SSantosh Puranik     {
1702c21865c4SKonstantin Aladyshev         return;
1703c21865c4SKonstantin Aladyshev     }
1704c21865c4SKonstantin Aladyshev 
1705491d8ee7SSantosh Puranik     // Source target specified
170662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1707491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1708ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1709ac106bf6SEd Tanous                              bootModeStr) != 0)
1710491d8ee7SSantosh Puranik     {
171162598e31SEd Tanous         BMCWEB_LOG_DEBUG(
171262598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
171362598e31SEd Tanous             *bootSource);
1714ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1715491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1716491d8ee7SSantosh Puranik         return;
1717491d8ee7SSantosh Puranik     }
1718491d8ee7SSantosh Puranik 
1719944ffaf9SJohnathan Mantey     // Act on validated parameters
172062598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
172162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1722944ffaf9SJohnathan Mantey 
1723d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1724d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1725d43cc6bcSOliver Brewka     path /= "boot";
1726e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1727d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
172887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1729e93abac6SGinu George                     bootSourceStr);
1730e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1731d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
173287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1733e93abac6SGinu George                     bootModeStr);
1734cd9a4666SKonstantin Aladyshev }
1735944ffaf9SJohnathan Mantey 
1736cd9a4666SKonstantin Aladyshev /**
1737c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1738491d8ee7SSantosh Puranik  *
1739ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1740d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1741491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1742cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1743491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1744491d8ee7SSantosh Puranik  *
1745265c1602SJohnathan Mantey  * @return Integer error code.
1746491d8ee7SSantosh Puranik  */
1747c21865c4SKonstantin Aladyshev 
1748504af5a0SPatrick Williams inline void setBootProperties(
1749504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1750d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex,
1751c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootSource,
1752c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootType,
1753c21865c4SKonstantin Aladyshev     const std::optional<std::string>& bootEnable)
1754491d8ee7SSantosh Puranik {
175562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1756491d8ee7SSantosh Puranik 
1757d43cc6bcSOliver Brewka     setBootModeOrSource(asyncResp, computerSystemIndex, bootSource);
1758d43cc6bcSOliver Brewka     setBootType(asyncResp, computerSystemIndex, bootType);
1759d43cc6bcSOliver Brewka     setBootEnable(asyncResp, computerSystemIndex, bootEnable);
1760491d8ee7SSantosh Puranik }
1761491d8ee7SSantosh Puranik 
1762c6a620f2SGeorge Liu /**
176398e386ecSGunnar Mills  * @brief Sets AssetTag
176498e386ecSGunnar Mills  *
1765ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
176698e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
176798e386ecSGunnar Mills  *
176898e386ecSGunnar Mills  * @return None.
176998e386ecSGunnar Mills  */
1770ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
177198e386ecSGunnar Mills                         const std::string& assetTag)
177298e386ecSGunnar Mills {
1773e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1774e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1775e99073f5SGeorge Liu     dbus::utility::getSubTree(
1776e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1777ac106bf6SEd Tanous         [asyncResp,
1778e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1779b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
178098e386ecSGunnar Mills             if (ec)
178198e386ecSGunnar Mills             {
178262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1783ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
178498e386ecSGunnar Mills                 return;
178598e386ecSGunnar Mills             }
178626f6976fSEd Tanous             if (subtree.empty())
178798e386ecSGunnar Mills             {
178862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1789ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
179098e386ecSGunnar Mills                 return;
179198e386ecSGunnar Mills             }
179298e386ecSGunnar Mills             // Assume only 1 system D-Bus object
179398e386ecSGunnar Mills             // Throw an error if there is more than 1
179498e386ecSGunnar Mills             if (subtree.size() > 1)
179598e386ecSGunnar Mills             {
179662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1797ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
179898e386ecSGunnar Mills                 return;
179998e386ecSGunnar Mills             }
180098e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
180198e386ecSGunnar Mills             {
180262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1803ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
180498e386ecSGunnar Mills                 return;
180598e386ecSGunnar Mills             }
180698e386ecSGunnar Mills 
180798e386ecSGunnar Mills             const std::string& path = subtree[0].first;
180898e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
180998e386ecSGunnar Mills 
181098e386ecSGunnar Mills             if (service.empty())
181198e386ecSGunnar Mills             {
181262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1813ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
181498e386ecSGunnar Mills                 return;
181598e386ecSGunnar Mills             }
181698e386ecSGunnar Mills 
1817e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
181887c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1819e93abac6SGinu George                             "AssetTag", assetTag);
1820e99073f5SGeorge Liu         });
182198e386ecSGunnar Mills }
182298e386ecSGunnar Mills 
182398e386ecSGunnar Mills /**
18249dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18259dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18269dcfe8c1SAlbert Zhang  *
18279dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18289dcfe8c1SAlbert Zhang  * stopBootOnFault
18299dcfe8c1SAlbert Zhang  *
18309dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18319dcfe8c1SAlbert Zhang  */
1832504af5a0SPatrick Williams inline std::optional<bool> validstopBootOnFault(
1833504af5a0SPatrick Williams     const std::string& stopBootOnFaultString)
18349dcfe8c1SAlbert Zhang {
18359dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18369dcfe8c1SAlbert Zhang     {
18379dcfe8c1SAlbert Zhang         return true;
18389dcfe8c1SAlbert Zhang     }
18399dcfe8c1SAlbert Zhang 
18409dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18419dcfe8c1SAlbert Zhang     {
18429dcfe8c1SAlbert Zhang         return false;
18439dcfe8c1SAlbert Zhang     }
18449dcfe8c1SAlbert Zhang 
18459dcfe8c1SAlbert Zhang     return std::nullopt;
18469dcfe8c1SAlbert Zhang }
18479dcfe8c1SAlbert Zhang 
18489dcfe8c1SAlbert Zhang /**
18499dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18509dcfe8c1SAlbert Zhang  *
1851fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18529dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18539dcfe8c1SAlbert Zhang  *
18549dcfe8c1SAlbert Zhang  * @return None.
18559dcfe8c1SAlbert Zhang  */
1856504af5a0SPatrick Williams inline void setStopBootOnFault(
1857504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18589dcfe8c1SAlbert Zhang     const std::string& stopBootOnFault)
18599dcfe8c1SAlbert Zhang {
186062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18619dcfe8c1SAlbert Zhang 
18629dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18639dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18649dcfe8c1SAlbert Zhang     {
186562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
186662598e31SEd Tanous                          stopBootOnFault);
1867fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18689dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18699dcfe8c1SAlbert Zhang         return;
18709dcfe8c1SAlbert Zhang     }
18719dcfe8c1SAlbert Zhang 
1872e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1873e93abac6SGinu George                     "xyz.openbmc_project.Settings",
187487c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
187587c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1876fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1877e93abac6SGinu George                     *stopBootEnabled);
18789dcfe8c1SAlbert Zhang }
18799dcfe8c1SAlbert Zhang 
18809dcfe8c1SAlbert Zhang /**
188169f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
188269f35306SGunnar Mills  *
1883ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1884d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
188569f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
188669f35306SGunnar Mills  *
188769f35306SGunnar Mills  * @return None.
188869f35306SGunnar Mills  */
1889504af5a0SPatrick Williams inline void setAutomaticRetry(
1890504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1891d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, const std::string& automaticRetryConfig)
189269f35306SGunnar Mills {
189362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
189469f35306SGunnar Mills 
189569f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1896543f4400SEd Tanous     bool autoRebootEnabled = false;
189769f35306SGunnar Mills 
189869f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
189969f35306SGunnar Mills     {
190069f35306SGunnar Mills         autoRebootEnabled = false;
190169f35306SGunnar Mills     }
190269f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
190369f35306SGunnar Mills     {
190469f35306SGunnar Mills         autoRebootEnabled = true;
190569f35306SGunnar Mills     }
190669f35306SGunnar Mills     else
190769f35306SGunnar Mills     {
190862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
190962598e31SEd Tanous                          automaticRetryConfig);
1910ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
191169f35306SGunnar Mills                                          "AutomaticRetryConfig");
191269f35306SGunnar Mills         return;
191369f35306SGunnar Mills     }
191469f35306SGunnar Mills 
1915d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1916d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1917d43cc6bcSOliver Brewka     path /= "auto_reboot";
1918e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1919d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
192087c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1921e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
192269f35306SGunnar Mills }
192369f35306SGunnar Mills 
19248d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19258d69c668SEd Tanous {
19268d69c668SEd Tanous     if (policy == "AlwaysOn")
19278d69c668SEd Tanous     {
19288d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19298d69c668SEd Tanous     }
19308d69c668SEd Tanous     if (policy == "AlwaysOff")
19318d69c668SEd Tanous     {
19328d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19338d69c668SEd Tanous     }
19348d69c668SEd Tanous     if (policy == "LastState")
19358d69c668SEd Tanous     {
19368d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19378d69c668SEd Tanous     }
19388d69c668SEd Tanous     return "";
19398d69c668SEd Tanous }
19408d69c668SEd Tanous 
194169f35306SGunnar Mills /**
1942c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1943c6a620f2SGeorge Liu  *
1944ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1945d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
1946c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1947c6a620f2SGeorge Liu  *
1948c6a620f2SGeorge Liu  * @return None.
1949c6a620f2SGeorge Liu  */
1950504af5a0SPatrick Williams inline void setPowerRestorePolicy(
1951504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1952d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex, std::string_view policy)
1953c6a620f2SGeorge Liu {
195462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1955c6a620f2SGeorge Liu 
19568d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1957c6a620f2SGeorge Liu 
19588d69c668SEd Tanous     if (powerRestorePolicy.empty())
1959c6a620f2SGeorge Liu     {
1960ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19614e69c904SGunnar Mills                                          "PowerRestorePolicy");
1962c6a620f2SGeorge Liu         return;
1963c6a620f2SGeorge Liu     }
1964c6a620f2SGeorge Liu 
1965d43cc6bcSOliver Brewka     sdbusplus::message::object_path path("/xyz/openbmc_project/control/host" +
1966d43cc6bcSOliver Brewka                                          std::to_string(computerSystemIndex));
1967d43cc6bcSOliver Brewka     path /= "power_restore_policy";
1968d43cc6bcSOliver Brewka     setDbusProperty(asyncResp, "PowerRestorePolicy",
1969d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Settings", path,
1970d43cc6bcSOliver Brewka                     "xyz.openbmc_project.Control.Power.RestorePolicy",
1971d43cc6bcSOliver Brewka                     "PowerRestorePolicy", powerRestorePolicy);
1972c6a620f2SGeorge Liu }
1973c6a620f2SGeorge Liu 
1974a6349918SAppaRao Puli /**
1975a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1976a6349918SAppaRao Puli  *
197725b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
197825b54dbaSEd Tanous  * calls.
1979a6349918SAppaRao Puli  *
1980a6349918SAppaRao Puli  * @return None.
1981a6349918SAppaRao Puli  */
1982504af5a0SPatrick Williams inline void getProvisioningStatus(
1983504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1984a6349918SAppaRao Puli {
198562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1986deae6a78SEd Tanous     dbus::utility::getAllProperties(
1987deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1988deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Attributes",
1989ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1990b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1991b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1992bd79bce8SPatrick Williams                 asyncResp->res
1993bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1994ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
19951d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1996bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
1997bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
199850626f4fSJames Feist 
1999a6349918SAppaRao Puli             if (ec)
2000a6349918SAppaRao Puli             {
200162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2002b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
2003539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2004539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2005a6349918SAppaRao Puli                 return;
2006a6349918SAppaRao Puli             }
2007a6349918SAppaRao Puli 
2008a6349918SAppaRao Puli             const bool* provState = nullptr;
2009a6349918SAppaRao Puli             const bool* lockState = nullptr;
2010bc1d29deSKrzysztof Grobelny 
2011bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2012bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
2013bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
2014bc1d29deSKrzysztof Grobelny 
2015bc1d29deSKrzysztof Grobelny             if (!success)
2016a6349918SAppaRao Puli             {
2017ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2018bc1d29deSKrzysztof Grobelny                 return;
2019a6349918SAppaRao Puli             }
2020a6349918SAppaRao Puli 
2021a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2022a6349918SAppaRao Puli             {
202362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2024ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2025a6349918SAppaRao Puli                 return;
2026a6349918SAppaRao Puli             }
2027a6349918SAppaRao Puli 
202825b54dbaSEd Tanous             if (*provState)
2029a6349918SAppaRao Puli             {
203025b54dbaSEd Tanous                 if (*lockState)
2031a6349918SAppaRao Puli                 {
2032539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2033539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2034a6349918SAppaRao Puli                 }
2035a6349918SAppaRao Puli                 else
2036a6349918SAppaRao Puli                 {
2037539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2038539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2039a6349918SAppaRao Puli                 }
2040a6349918SAppaRao Puli             }
2041a6349918SAppaRao Puli             else
2042a6349918SAppaRao Puli             {
2043539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2044539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2045a6349918SAppaRao Puli             }
2046bc1d29deSKrzysztof Grobelny         });
2047a6349918SAppaRao Puli }
2048a6349918SAppaRao Puli 
2049491d8ee7SSantosh Puranik /**
20506b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20513a2d0424SChris Cain  *
20526b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20533a2d0424SChris Cain  *
20546b9ac4f2SChris Cain  * @return PowerMode enum
20553a2d0424SChris Cain  */
2056504af5a0SPatrick Williams inline computer_system::PowerMode translatePowerModeString(
2057504af5a0SPatrick Williams     const std::string& modeString)
20583a2d0424SChris Cain {
2059b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2060b6655101SChris Cain 
20616b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20623a2d0424SChris Cain     {
20636b9ac4f2SChris Cain         return PowerMode::Static;
20643a2d0424SChris Cain     }
20656b9ac4f2SChris Cain     if (modeString ==
20660fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20673a2d0424SChris Cain     {
20686b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20693a2d0424SChris Cain     }
20706b9ac4f2SChris Cain     if (modeString ==
20710fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20723a2d0424SChris Cain     {
20736b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2074b6655101SChris Cain     }
20756b9ac4f2SChris Cain     if (modeString ==
2076b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2077b6655101SChris Cain     {
20786b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2079b6655101SChris Cain     }
20806b9ac4f2SChris Cain     if (modeString ==
2081b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2082b6655101SChris Cain     {
20836b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2084b6655101SChris Cain     }
20856b9ac4f2SChris Cain     if (modeString ==
2086b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2087b6655101SChris Cain     {
20886b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20893a2d0424SChris Cain     }
20906b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20913a2d0424SChris Cain     {
20926b9ac4f2SChris Cain         return PowerMode::OEM;
20936b9ac4f2SChris Cain     }
20946b9ac4f2SChris Cain     // Any other values would be invalid
20956b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20966b9ac4f2SChris Cain     return PowerMode::Invalid;
20976b9ac4f2SChris Cain }
20986b9ac4f2SChris Cain 
2099504af5a0SPatrick Williams inline void afterGetPowerMode(
2100504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21016b9ac4f2SChris Cain     const boost::system::error_code& ec,
21026b9ac4f2SChris Cain     const dbus::utility::DBusPropertiesMap& properties)
21036b9ac4f2SChris Cain {
21046b9ac4f2SChris Cain     if (ec)
21056b9ac4f2SChris Cain     {
21066b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
21076b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21086b9ac4f2SChris Cain         return;
21096b9ac4f2SChris Cain     }
21106b9ac4f2SChris Cain 
21116b9ac4f2SChris Cain     std::string powerMode;
21126b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
21136b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
21146b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
21156b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21166b9ac4f2SChris Cain 
21176b9ac4f2SChris Cain     if (!success)
21186b9ac4f2SChris Cain     {
21196b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21206b9ac4f2SChris Cain         return;
21216b9ac4f2SChris Cain     }
21226b9ac4f2SChris Cain 
21236b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21246b9ac4f2SChris Cain     if (allowedModes == nullptr)
21256b9ac4f2SChris Cain     {
21266b9ac4f2SChris Cain         modeList.emplace_back("Static");
21276b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21286b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21293a2d0424SChris Cain     }
21303a2d0424SChris Cain     else
21313a2d0424SChris Cain     {
21326b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21336b9ac4f2SChris Cain         {
21346b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21356b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21366b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21376b9ac4f2SChris Cain             {
2138ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21396b9ac4f2SChris Cain                 continue;
21406b9ac4f2SChris Cain             }
21416b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21423a2d0424SChris Cain         }
21433a2d0424SChris Cain     }
21446b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21453a2d0424SChris Cain 
21466b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21476b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21486b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21496b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21506b9ac4f2SChris Cain     {
21516b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21526b9ac4f2SChris Cain         return;
21536b9ac4f2SChris Cain     }
21546b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21556b9ac4f2SChris Cain }
21563a2d0424SChris Cain /**
21573a2d0424SChris Cain  * @brief Retrieves system power mode
21583a2d0424SChris Cain  *
2159ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21603a2d0424SChris Cain  *
21613a2d0424SChris Cain  * @return None.
21623a2d0424SChris Cain  */
2163ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21643a2d0424SChris Cain {
216562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21663a2d0424SChris Cain 
21673a2d0424SChris Cain     // Get Power Mode object path:
2168e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2169e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2170e99073f5SGeorge Liu     dbus::utility::getSubTree(
2171e99073f5SGeorge Liu         "/", 0, interfaces,
2172ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2173b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21743a2d0424SChris Cain             if (ec)
21753a2d0424SChris Cain             {
2176bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2177bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
21783a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
21793a2d0424SChris Cain                 // error occurs
21803a2d0424SChris Cain                 return;
21813a2d0424SChris Cain             }
21823a2d0424SChris Cain             if (subtree.empty())
21833a2d0424SChris Cain             {
21843a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
21853a2d0424SChris Cain                 // if there is no instance found
21863a2d0424SChris Cain                 return;
21873a2d0424SChris Cain             }
21883a2d0424SChris Cain             if (subtree.size() > 1)
21893a2d0424SChris Cain             {
21903a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21913a2d0424SChris Cain                 // error
219262598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
219362598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
219462598e31SEd Tanous                     subtree.size());
2195ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21963a2d0424SChris Cain                 return;
21973a2d0424SChris Cain             }
21983a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21993a2d0424SChris Cain             {
220062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2201ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22023a2d0424SChris Cain                 return;
22033a2d0424SChris Cain             }
22043a2d0424SChris Cain             const std::string& path = subtree[0].first;
22053a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22063a2d0424SChris Cain             if (service.empty())
22073a2d0424SChris Cain             {
220862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2209ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22103a2d0424SChris Cain                 return;
22113a2d0424SChris Cain             }
22126b9ac4f2SChris Cain 
22136b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
2214deae6a78SEd Tanous             dbus::utility::getAllProperties(
22151e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
22166b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2217bd79bce8SPatrick Williams                 [asyncResp](
2218bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
22196b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
22206b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
22211e1e598dSJonathan Doman                 });
2222e99073f5SGeorge Liu         });
22233a2d0424SChris Cain }
22243a2d0424SChris Cain 
22253a2d0424SChris Cain /**
22263a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22273a2d0424SChris Cain  * name associated with that string
22283a2d0424SChris Cain  *
2229ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2230b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22313a2d0424SChris Cain  *
22323a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22333a2d0424SChris Cain  */
2234504af5a0SPatrick Williams inline std::string validatePowerMode(
2235504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2236b6655101SChris Cain     const nlohmann::json& modeValue)
22373a2d0424SChris Cain {
2238b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22393a2d0424SChris Cain     std::string mode;
22403a2d0424SChris Cain 
2241b6655101SChris Cain     if (modeValue == PowerMode::Static)
22423a2d0424SChris Cain     {
22433a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22443a2d0424SChris Cain     }
2245b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22463a2d0424SChris Cain     {
22470fda0f12SGeorge Liu         mode =
22480fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22493a2d0424SChris Cain     }
2250b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22513a2d0424SChris Cain     {
22523a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22533a2d0424SChris Cain     }
2254b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2255b6655101SChris Cain     {
2256b6655101SChris Cain         mode =
2257b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2258b6655101SChris Cain     }
2259b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2260b6655101SChris Cain     {
2261b6655101SChris Cain         mode =
2262b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2263b6655101SChris Cain     }
2264b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2265b6655101SChris Cain     {
2266b6655101SChris Cain         mode =
2267b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2268b6655101SChris Cain     }
22693a2d0424SChris Cain     else
22703a2d0424SChris Cain     {
2271b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2272ac106bf6SEd Tanous                                          "PowerMode");
22733a2d0424SChris Cain     }
22743a2d0424SChris Cain     return mode;
22753a2d0424SChris Cain }
22763a2d0424SChris Cain 
22773a2d0424SChris Cain /**
22783a2d0424SChris Cain  * @brief Sets system power mode.
22793a2d0424SChris Cain  *
2280ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22813a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22823a2d0424SChris Cain  *
22833a2d0424SChris Cain  * @return None.
22843a2d0424SChris Cain  */
2285ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22863a2d0424SChris Cain                          const std::string& pmode)
22873a2d0424SChris Cain {
228862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22893a2d0424SChris Cain 
2290ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22913a2d0424SChris Cain     if (powerMode.empty())
22923a2d0424SChris Cain     {
22933a2d0424SChris Cain         return;
22943a2d0424SChris Cain     }
22953a2d0424SChris Cain 
22963a2d0424SChris Cain     // Get Power Mode object path:
2297e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2298e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2299e99073f5SGeorge Liu     dbus::utility::getSubTree(
2300e99073f5SGeorge Liu         "/", 0, interfaces,
2301ac106bf6SEd Tanous         [asyncResp,
2302e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2303b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23043a2d0424SChris Cain             if (ec)
23053a2d0424SChris Cain             {
2306bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2307bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
23083a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2309ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23103a2d0424SChris Cain                 return;
23113a2d0424SChris Cain             }
23123a2d0424SChris Cain             if (subtree.empty())
23133a2d0424SChris Cain             {
23143a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2315ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23163a2d0424SChris Cain                                            "PowerMode");
23173a2d0424SChris Cain                 return;
23183a2d0424SChris Cain             }
23193a2d0424SChris Cain             if (subtree.size() > 1)
23203a2d0424SChris Cain             {
23213a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
23223a2d0424SChris Cain                 // error
232362598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
232462598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
232562598e31SEd Tanous                     subtree.size());
2326ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23273a2d0424SChris Cain                 return;
23283a2d0424SChris Cain             }
23293a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23303a2d0424SChris Cain             {
233162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2332ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23333a2d0424SChris Cain                 return;
23343a2d0424SChris Cain             }
23353a2d0424SChris Cain             const std::string& path = subtree[0].first;
23363a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
23373a2d0424SChris Cain             if (service.empty())
23383a2d0424SChris Cain             {
233962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2340ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23413a2d0424SChris Cain                 return;
23423a2d0424SChris Cain             }
23433a2d0424SChris Cain 
234462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23453a2d0424SChris Cain 
23463a2d0424SChris Cain             // Set the Power Mode property
2347e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2348bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2349bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2350e99073f5SGeorge Liu         });
23513a2d0424SChris Cain }
23523a2d0424SChris Cain 
23533a2d0424SChris Cain /**
235451709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
235551709ffdSYong Li  *
235651709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
235751709ffdSYong Li  *
235851709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
235951709ffdSYong Li  * translation cannot be done, returns an empty string.
236051709ffdSYong Li  */
236123a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
236251709ffdSYong Li {
236351709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
236451709ffdSYong Li     {
236551709ffdSYong Li         return "None";
236651709ffdSYong Li     }
23673174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
236851709ffdSYong Li     {
236951709ffdSYong Li         return "ResetSystem";
237051709ffdSYong Li     }
23713174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
237251709ffdSYong Li     {
237351709ffdSYong Li         return "PowerDown";
237451709ffdSYong Li     }
23753174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
237651709ffdSYong Li     {
237751709ffdSYong Li         return "PowerCycle";
237851709ffdSYong Li     }
237951709ffdSYong Li 
238051709ffdSYong Li     return "";
238151709ffdSYong Li }
238251709ffdSYong Li 
238351709ffdSYong Li /**
2384c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2385c45f0082SYong Li  *
2386c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2387c45f0082SYong Li  *
2388c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2389c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2390c45f0082SYong Li  */
2391c45f0082SYong Li 
239223a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2393c45f0082SYong Li {
2394c45f0082SYong Li     if (rfAction == "None")
2395c45f0082SYong Li     {
2396c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2397c45f0082SYong Li     }
23983174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2399c45f0082SYong Li     {
2400c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2401c45f0082SYong Li     }
24023174e4dfSEd Tanous     if (rfAction == "PowerDown")
2403c45f0082SYong Li     {
2404c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2405c45f0082SYong Li     }
24063174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2407c45f0082SYong Li     {
2408c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2409c45f0082SYong Li     }
2410c45f0082SYong Li 
2411c45f0082SYong Li     return "";
2412c45f0082SYong Li }
2413c45f0082SYong Li 
2414c45f0082SYong Li /**
241551709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
241651709ffdSYong Li  *
2417ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
241851709ffdSYong Li  *
241951709ffdSYong Li  * @return None.
242051709ffdSYong Li  */
2421504af5a0SPatrick Williams inline void getHostWatchdogTimer(
2422504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
242351709ffdSYong Li {
242462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2425deae6a78SEd Tanous     dbus::utility::getAllProperties(
2426deae6a78SEd Tanous         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2427bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2428ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2429b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
243051709ffdSYong Li             if (ec)
243151709ffdSYong Li             {
243251709ffdSYong Li                 // watchdog service is stopped
243362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
243451709ffdSYong Li                 return;
243551709ffdSYong Li             }
243651709ffdSYong Li 
243762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
243851709ffdSYong Li 
243951709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2440ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
244151709ffdSYong Li 
244251709ffdSYong Li             // watchdog service is running/enabled
2443539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
244451709ffdSYong Li 
2445bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2446bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
244751709ffdSYong Li 
2448bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2449bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2450bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2451bc1d29deSKrzysztof Grobelny 
2452bc1d29deSKrzysztof Grobelny             if (!success)
245351709ffdSYong Li             {
2454ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2455601af5edSChicago Duan                 return;
245651709ffdSYong Li             }
245751709ffdSYong Li 
2458bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
245951709ffdSYong Li             {
2460bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
246151709ffdSYong Li             }
246251709ffdSYong Li 
2463bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2464bc1d29deSKrzysztof Grobelny             {
2465bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
246651709ffdSYong Li                 if (action.empty())
246751709ffdSYong Li                 {
2468ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2469601af5edSChicago Duan                     return;
247051709ffdSYong Li                 }
247151709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
247251709ffdSYong Li             }
2473bc1d29deSKrzysztof Grobelny         });
247451709ffdSYong Li }
247551709ffdSYong Li 
247651709ffdSYong Li /**
2477c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2478c45f0082SYong Li  *
2479ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2480c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2481c45f0082SYong Li  *                       RF request.
2482c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2483c45f0082SYong Li  *
2484c45f0082SYong Li  * @return None.
2485c45f0082SYong Li  */
2486504af5a0SPatrick Williams inline void setWDTProperties(
2487504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2488c45f0082SYong Li     const std::optional<bool> wdtEnable,
2489c45f0082SYong Li     const std::optional<std::string>& wdtTimeOutAction)
2490c45f0082SYong Li {
249162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2492c45f0082SYong Li 
2493c45f0082SYong Li     if (wdtTimeOutAction)
2494c45f0082SYong Li     {
2495c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2496c45f0082SYong Li         // check if TimeOut Action is Valid
2497c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2498c45f0082SYong Li         {
249962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
250062598e31SEd Tanous                              *wdtTimeOutAction);
2501ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2502c45f0082SYong Li                                              "TimeoutAction");
2503c45f0082SYong Li             return;
2504c45f0082SYong Li         }
2505c45f0082SYong Li 
2506e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2507e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
250887c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
250987c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
25109ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2511e93abac6SGinu George                         wdtTimeOutActStr);
2512c45f0082SYong Li     }
2513c45f0082SYong Li 
2514c45f0082SYong Li     if (wdtEnable)
2515c45f0082SYong Li     {
2516e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2517e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
251887c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
251987c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
252087c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2521e93abac6SGinu George                         *wdtEnable);
2522c45f0082SYong Li     }
2523c45f0082SYong Li }
2524c45f0082SYong Li 
252537bbf98cSChris Cain /**
252637bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
252737bbf98cSChris Cain  *
2528ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
252937bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
253037bbf98cSChris Cain  *
253137bbf98cSChris Cain  * @return true if successful
253237bbf98cSChris Cain  */
2533504af5a0SPatrick Williams inline bool parseIpsProperties(
2534504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25351e5b7c88SJiaqing Zhao     const dbus::utility::DBusPropertiesMap& properties)
253637bbf98cSChris Cain {
2537bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2538bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2539bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2540bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2541bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2542bc1d29deSKrzysztof Grobelny 
2543bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2544bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25452661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25462661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25472661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2548bc1d29deSKrzysztof Grobelny 
2549bc1d29deSKrzysztof Grobelny     if (!success)
255037bbf98cSChris Cain     {
255137bbf98cSChris Cain         return false;
255237bbf98cSChris Cain     }
2553bc1d29deSKrzysztof Grobelny 
2554bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
255537bbf98cSChris Cain     {
2556ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
255737bbf98cSChris Cain     }
2558bc1d29deSKrzysztof Grobelny 
2559bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
256037bbf98cSChris Cain     {
2561ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2562bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
256337bbf98cSChris Cain     }
2564bc1d29deSKrzysztof Grobelny 
2565bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2566bc1d29deSKrzysztof Grobelny     {
2567bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2568ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
256937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
257037bbf98cSChris Cain                 .count();
257137bbf98cSChris Cain     }
2572bc1d29deSKrzysztof Grobelny 
2573bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
257437bbf98cSChris Cain     {
2575ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2576bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
257737bbf98cSChris Cain     }
2578bc1d29deSKrzysztof Grobelny 
2579bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
258037bbf98cSChris Cain     {
2581bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2582ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
258337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
258437bbf98cSChris Cain                 .count();
258537bbf98cSChris Cain     }
258637bbf98cSChris Cain 
258737bbf98cSChris Cain     return true;
258837bbf98cSChris Cain }
258937bbf98cSChris Cain 
259037bbf98cSChris Cain /**
25915e7c1f31SOliver Brewka  * @brief Retrieves idle power saver properties over DBUS
259237bbf98cSChris Cain  *
2593ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
259437bbf98cSChris Cain  *
259537bbf98cSChris Cain  * @return None.
259637bbf98cSChris Cain  */
2597504af5a0SPatrick Williams inline void getIdlePowerSaver(
2598504af5a0SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
259937bbf98cSChris Cain {
260062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
260137bbf98cSChris Cain 
260237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2603e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2604e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2605e99073f5SGeorge Liu     dbus::utility::getSubTree(
2606e99073f5SGeorge Liu         "/", 0, interfaces,
2607ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2608b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
260937bbf98cSChris Cain             if (ec)
261037bbf98cSChris Cain             {
2611b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
261262598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
261362598e31SEd Tanous                     ec);
2614ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261537bbf98cSChris Cain                 return;
261637bbf98cSChris Cain             }
261737bbf98cSChris Cain             if (subtree.empty())
261837bbf98cSChris Cain             {
261937bbf98cSChris Cain                 // This is an optional interface so just return
262037bbf98cSChris Cain                 // if there is no instance found
262162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
262237bbf98cSChris Cain                 return;
262337bbf98cSChris Cain             }
262437bbf98cSChris Cain             if (subtree.size() > 1)
262537bbf98cSChris Cain             {
262637bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
262737bbf98cSChris Cain                 // is an error
26285e7c1f31SOliver Brewka                 BMCWEB_LOG_DEBUG(
26295e7c1f31SOliver Brewka                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
263062598e31SEd Tanous                     subtree.size());
2631ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
263237bbf98cSChris Cain                 return;
263337bbf98cSChris Cain             }
263437bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
263537bbf98cSChris Cain             {
263662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2637ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
263837bbf98cSChris Cain                 return;
263937bbf98cSChris Cain             }
264037bbf98cSChris Cain             const std::string& path = subtree[0].first;
264137bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
264237bbf98cSChris Cain             if (service.empty())
264337bbf98cSChris Cain             {
264462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2645ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
264637bbf98cSChris Cain                 return;
264737bbf98cSChris Cain             }
264837bbf98cSChris Cain 
264937bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2650deae6a78SEd Tanous             dbus::utility::getAllProperties(
2651bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2652bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2653bd79bce8SPatrick Williams                 [asyncResp](
2654bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
26551e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
26568a592810SEd Tanous                     if (ec2)
265737bbf98cSChris Cain                     {
265862598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2659bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2660bd79bce8SPatrick Williams                             ec2);
2661ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
266237bbf98cSChris Cain                         return;
266337bbf98cSChris Cain                     }
266437bbf98cSChris Cain 
2665ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
266637bbf98cSChris Cain                     {
2667ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
266837bbf98cSChris Cain                         return;
266937bbf98cSChris Cain                     }
2670bc1d29deSKrzysztof Grobelny                 });
2671e99073f5SGeorge Liu         });
267237bbf98cSChris Cain 
267362598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
267437bbf98cSChris Cain }
267537bbf98cSChris Cain 
267637bbf98cSChris Cain /**
267737bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
267837bbf98cSChris Cain  *
2679ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
268037bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
268137bbf98cSChris Cain  *                       RF request.
268237bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
268337bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
268437bbf98cSChris Cain  * before entering idle state.
268537bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
268637bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
268737bbf98cSChris Cain  * before exiting idle state
268837bbf98cSChris Cain  *
268937bbf98cSChris Cain  * @return None.
269037bbf98cSChris Cain  */
2691bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2692bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
269337bbf98cSChris Cain     const std::optional<bool> ipsEnable,
269437bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
269537bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
269637bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
269737bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
269837bbf98cSChris Cain {
269962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
270037bbf98cSChris Cain 
270137bbf98cSChris Cain     // Get IdlePowerSaver object path:
2702e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2703e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2704e99073f5SGeorge Liu     dbus::utility::getSubTree(
2705e99073f5SGeorge Liu         "/", 0, interfaces,
2706ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2707e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2708b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
270937bbf98cSChris Cain             if (ec)
271037bbf98cSChris Cain             {
2711b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
271262598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
271362598e31SEd Tanous                     ec);
2714ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271537bbf98cSChris Cain                 return;
271637bbf98cSChris Cain             }
271737bbf98cSChris Cain             if (subtree.empty())
271837bbf98cSChris Cain             {
271937bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2720ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
272137bbf98cSChris Cain                                            "IdlePowerSaver");
272237bbf98cSChris Cain                 return;
272337bbf98cSChris Cain             }
272437bbf98cSChris Cain             if (subtree.size() > 1)
272537bbf98cSChris Cain             {
272637bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
272737bbf98cSChris Cain                 // is an error
272862598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
272962598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
273062598e31SEd Tanous                     subtree.size());
2731ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273237bbf98cSChris Cain                 return;
273337bbf98cSChris Cain             }
273437bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
273537bbf98cSChris Cain             {
273662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2737ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273837bbf98cSChris Cain                 return;
273937bbf98cSChris Cain             }
274037bbf98cSChris Cain             const std::string& path = subtree[0].first;
274137bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
274237bbf98cSChris Cain             if (service.empty())
274337bbf98cSChris Cain             {
274462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2745ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
274637bbf98cSChris Cain                 return;
274737bbf98cSChris Cain             }
274837bbf98cSChris Cain 
274937bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
275037bbf98cSChris Cain             // need to be updated
275137bbf98cSChris Cain 
275237bbf98cSChris Cain             if (ipsEnable)
275337bbf98cSChris Cain             {
2754bd79bce8SPatrick Williams                 setDbusProperty(
2755bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
275687c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2757e93abac6SGinu George                     "Enabled", *ipsEnable);
275837bbf98cSChris Cain             }
275937bbf98cSChris Cain             if (ipsEnterUtil)
276037bbf98cSChris Cain             {
2761bd79bce8SPatrick Williams                 setDbusProperty(
2762bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2763e93abac6SGinu George                     service, path,
27649ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2765e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
276637bbf98cSChris Cain             }
276737bbf98cSChris Cain             if (ipsEnterTime)
276837bbf98cSChris Cain             {
276937bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
277037bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2771bd79bce8SPatrick Williams                 setDbusProperty(
2772bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2773bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2774e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
277537bbf98cSChris Cain             }
277637bbf98cSChris Cain             if (ipsExitUtil)
277737bbf98cSChris Cain             {
2778bd79bce8SPatrick Williams                 setDbusProperty(
2779bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2780bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2781e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
278237bbf98cSChris Cain             }
278337bbf98cSChris Cain             if (ipsExitTime)
278437bbf98cSChris Cain             {
278537bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
278637bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2787bd79bce8SPatrick Williams                 setDbusProperty(
2788bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2789bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2790e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
279137bbf98cSChris Cain             }
2792e99073f5SGeorge Liu         });
279337bbf98cSChris Cain 
279462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
279537bbf98cSChris Cain }
279637bbf98cSChris Cain 
2797c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2798dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2799dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2800dd60b9edSEd Tanous {
2801dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2802dd60b9edSEd Tanous     {
2803dd60b9edSEd Tanous         return;
2804dd60b9edSEd Tanous     }
2805dd60b9edSEd Tanous     asyncResp->res.addHeader(
2806dd60b9edSEd Tanous         boost::beast::http::field::link,
2807dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2808dd60b9edSEd Tanous }
2809dd60b9edSEd Tanous 
2810c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2811c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2812c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28131abe55efSEd Tanous {
28143ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2815f4c99e70SEd Tanous     {
2816f4c99e70SEd Tanous         return;
2817f4c99e70SEd Tanous     }
2818dd60b9edSEd Tanous 
2819dd60b9edSEd Tanous     asyncResp->res.addHeader(
2820dd60b9edSEd Tanous         boost::beast::http::field::link,
2821dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28228d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28230f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28248d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28258d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2826462023adSSunitha Harish 
2827fc5ae94dSOliver Brewka     getSystemCollectionMembers(asyncResp);
2828c1e219d5SEd Tanous }
2829c1e219d5SEd Tanous 
2830c1e219d5SEd Tanous /**
28317e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28327e860f15SJohn Edward Broadbent  */
28334f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28347e860f15SJohn Edward Broadbent {
283589492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
283689492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
283789492a15SPatrick Williams     constexpr const char* interfaceName =
28387e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
283989492a15SPatrick Williams     constexpr const char* method = "NMI";
28407e860f15SJohn Edward Broadbent 
2841177612aaSEd Tanous     dbus::utility::async_method_call(
2842177612aaSEd Tanous         asyncResp,
28435e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28447e860f15SJohn Edward Broadbent             if (ec)
28457e860f15SJohn Edward Broadbent             {
284662598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28477e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28487e860f15SJohn Edward Broadbent                 return;
28497e860f15SJohn Edward Broadbent             }
28507e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28517e860f15SJohn Edward Broadbent         },
28527e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28537e860f15SJohn Edward Broadbent }
2854c5b2abe0SLewanczyk, Dawid 
285506c055e7SOliver Brewka /**
285606c055e7SOliver Brewka  * @brief process the POST request after getting the computerSystemIndex
285706c055e7SOliver Brewka  *
285806c055e7SOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
285906c055e7SOliver Brewka  *                                calls
286006c055e7SOliver Brewka  * @param[in] resetType           The requested reset action
286106c055e7SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
286206c055e7SOliver Brewka  *
286306c055e7SOliver Brewka  * @return None
286406c055e7SOliver Brewka  */
286506c055e7SOliver Brewka inline void processComputerSystemResetActionPost(
286606c055e7SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string& resetType,
286706c055e7SOliver Brewka     const uint64_t computerSystemIndex)
2868c1e219d5SEd Tanous {
2869d22c8396SJason M. Bills     // Get the command and host vs. chassis
2870cc340dd9SEd Tanous     std::string command;
2871543f4400SEd Tanous     bool hostCommand = true;
2872d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2873cc340dd9SEd Tanous     {
2874cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2875d22c8396SJason M. Bills         hostCommand = true;
2876d22c8396SJason M. Bills     }
2877d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2878d22c8396SJason M. Bills     {
2879d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2880d22c8396SJason M. Bills         hostCommand = false;
2881d22c8396SJason M. Bills     }
2882d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2883d22c8396SJason M. Bills     {
2884c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
288586a0851aSJason M. Bills         hostCommand = true;
2886cc340dd9SEd Tanous     }
28879712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2888cc340dd9SEd Tanous     {
2889cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2890d22c8396SJason M. Bills         hostCommand = true;
2891cc340dd9SEd Tanous     }
28929712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2893cc340dd9SEd Tanous     {
28940fda0f12SGeorge Liu         command =
28950fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2896d22c8396SJason M. Bills         hostCommand = true;
2897d22c8396SJason M. Bills     }
2898d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2899d22c8396SJason M. Bills     {
290086a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
290186a0851aSJason M. Bills         hostCommand = true;
2902cc340dd9SEd Tanous     }
2903bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2904bfd5b826SLakshminarayana R. Kammath     {
2905bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2906bfd5b826SLakshminarayana R. Kammath         return;
2907bfd5b826SLakshminarayana R. Kammath     }
2908cc340dd9SEd Tanous     else
2909cc340dd9SEd Tanous     {
2910c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2911cc340dd9SEd Tanous         return;
2912cc340dd9SEd Tanous     }
2913cc340dd9SEd Tanous 
2914d22c8396SJason M. Bills     if (hostCommand)
2915d22c8396SJason M. Bills     {
291606c055e7SOliver Brewka         setDbusProperty(asyncResp, "Reset",
291706c055e7SOliver Brewka                         getHostStateServiceName(computerSystemIndex),
291806c055e7SOliver Brewka                         getHostStateObjectPath(computerSystemIndex),
291906c055e7SOliver Brewka                         "xyz.openbmc_project.State.Host",
2920e93abac6SGinu George                         "RequestedHostTransition", command);
2921cc340dd9SEd Tanous     }
2922d22c8396SJason M. Bills     else
2923d22c8396SJason M. Bills     {
292406c055e7SOliver Brewka         setDbusProperty(asyncResp, "Reset",
292506c055e7SOliver Brewka                         getChassisStateServiceName(computerSystemIndex),
292606c055e7SOliver Brewka                         getChassisStateObjectPath(computerSystemIndex),
2927d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2928e93abac6SGinu George                         "RequestedPowerTransition", command);
2929d22c8396SJason M. Bills     }
2930d22c8396SJason M. Bills }
2931cc340dd9SEd Tanous 
293206c055e7SOliver Brewka inline void handleComputerSystemResetActionPost(
293306c055e7SOliver Brewka     crow::App& app, const crow::Request& req,
293406c055e7SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
293506c055e7SOliver Brewka     const std::string& systemName)
293606c055e7SOliver Brewka {
293706c055e7SOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
293806c055e7SOliver Brewka     {
293906c055e7SOliver Brewka         return;
294006c055e7SOliver Brewka     }
294106c055e7SOliver Brewka 
294206c055e7SOliver Brewka     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
294306c055e7SOliver Brewka     {
294406c055e7SOliver Brewka         if (systemName == "hypervisor")
294506c055e7SOliver Brewka         {
294606c055e7SOliver Brewka             handleHypervisorSystemResetPost(req, asyncResp);
294706c055e7SOliver Brewka             return;
294806c055e7SOliver Brewka         }
294906c055e7SOliver Brewka     }
295006c055e7SOliver Brewka 
295106c055e7SOliver Brewka     if (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
295206c055e7SOliver Brewka     {
295306c055e7SOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
295406c055e7SOliver Brewka         {
295506c055e7SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
295606c055e7SOliver Brewka                                        systemName);
295706c055e7SOliver Brewka             return;
295806c055e7SOliver Brewka         }
295906c055e7SOliver Brewka     }
296006c055e7SOliver Brewka 
296106c055e7SOliver Brewka     std::string resetType;
296206c055e7SOliver Brewka     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
296306c055e7SOliver Brewka     {
296406c055e7SOliver Brewka         return;
296506c055e7SOliver Brewka     }
296606c055e7SOliver Brewka 
296706c055e7SOliver Brewka     getComputerSystemIndex(asyncResp, systemName,
296806c055e7SOliver Brewka                            std::bind_front(processComputerSystemResetActionPost,
296906c055e7SOliver Brewka                                            asyncResp, resetType));
297006c055e7SOliver Brewka }
297106c055e7SOliver Brewka 
2972c1e219d5SEd Tanous inline void handleComputerSystemHead(
2973dd60b9edSEd Tanous     App& app, const crow::Request& req,
29747f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29757f3e84a1SEd Tanous     const std::string& /*systemName*/)
2976dd60b9edSEd Tanous {
2977dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2978dd60b9edSEd Tanous     {
2979dd60b9edSEd Tanous         return;
2980dd60b9edSEd Tanous     }
2981dd60b9edSEd Tanous 
2982dd60b9edSEd Tanous     asyncResp->res.addHeader(
2983dd60b9edSEd Tanous         boost::beast::http::field::link,
2984dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2985dd60b9edSEd Tanous }
2986dd60b9edSEd Tanous 
29875c3e9272SAbhishek Patel inline void afterPortRequest(
29885c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29895c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29905c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29915c3e9272SAbhishek Patel {
29925c3e9272SAbhishek Patel     if (ec)
29935c3e9272SAbhishek Patel     {
2994b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29955c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29965c3e9272SAbhishek Patel         return;
29975c3e9272SAbhishek Patel     }
29985c3e9272SAbhishek Patel     for (const auto& data : socketData)
29995c3e9272SAbhishek Patel     {
30005c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
30015c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
30025c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
30035c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
30045c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
30055c3e9272SAbhishek Patel         // need to retrieve port number for
30065c3e9272SAbhishek Patel         // obmc-console-ssh service
30075c3e9272SAbhishek Patel         if (protocolName == "SSH")
30085c3e9272SAbhishek Patel         {
30095c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
301081c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30115c3e9272SAbhishek Patel                                           int portNumber) {
30125c3e9272SAbhishek Patel                 if (ec1)
30135c3e9272SAbhishek Patel                 {
3014b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
30155c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30165c3e9272SAbhishek Patel                     return;
30175c3e9272SAbhishek Patel                 }
30185c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30195c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30205c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30215c3e9272SAbhishek Patel             });
30225c3e9272SAbhishek Patel         }
30235c3e9272SAbhishek Patel     }
30245c3e9272SAbhishek Patel }
3025c1e219d5SEd Tanous 
30265e7c1f31SOliver Brewka /**
30275e7c1f31SOliver Brewka  * @brief process the GET request after getting the computerSystemIndex
30285e7c1f31SOliver Brewka  *
30295e7c1f31SOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
30305e7c1f31SOliver Brewka  *                                calls
30315e7c1f31SOliver Brewka  * @param[in] systemName          Name of the requested system
30325e7c1f31SOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
30335e7c1f31SOliver Brewka  *
30345e7c1f31SOliver Brewka  * @return None
30355e7c1f31SOliver Brewka  */
30365e7c1f31SOliver Brewka inline void processComputerSystemGet(
303722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30385e7c1f31SOliver Brewka     const std::string& systemName, const uint64_t computerSystemIndex)
3039c1e219d5SEd Tanous {
3040dd60b9edSEd Tanous     asyncResp->res.addHeader(
3041dd60b9edSEd Tanous         boost::beast::http::field::link,
3042dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30438d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3044b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
30455e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Name"] = systemName;
30465e7c1f31SOliver Brewka     asyncResp->res.jsonValue["Id"] = systemName;
3047539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3048539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30498d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30508d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3051cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3052dfb2b408SPriyanga Ramasamy         double(0);
30535e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] =
30545e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}", systemName);
305504a258f4SEd Tanous 
30565e7c1f31SOliver Brewka     // Currently not supported on multi-host. TBD
30575e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30585e7c1f31SOliver Brewka     {
30595e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
30605e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Bios", systemName);
30615e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
30625e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Processors",
30635e7c1f31SOliver Brewka                                 systemName);
30645e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
30655e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Memory", systemName);
30665e7c1f31SOliver Brewka         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
30675e7c1f31SOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}/Storage", systemName);
30683179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3069253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
30705e7c1f31SOliver Brewka                                 systemName);
30715e7c1f31SOliver Brewka     }
3072029573d4SEd Tanous 
3073002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3074253f11b8SEd Tanous         boost::urls::format(
30755e7c1f31SOliver Brewka             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset", systemName);
3076c1e219d5SEd Tanous     asyncResp->res
3077c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3078253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
30795e7c1f31SOliver Brewka                             systemName);
3080c5b2abe0SLewanczyk, Dawid 
30815e7c1f31SOliver Brewka     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
30825e7c1f31SOliver Brewka         boost::urls::format("/redfish/v1/Systems/{}/LogServices", systemName);
3083c4bf6374SJason M. Bills 
30841476687dSEd Tanous     nlohmann::json::array_t managedBy;
30851476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3086253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3087253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3088002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3089539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3090539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
30910e8ac5e7SGunnar Mills 
30920e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3093002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3094c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
30951476687dSEd Tanous 
3096c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
30971476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3098c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30991476687dSEd Tanous         "Press ~. to exit console";
31005c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31015c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31020e8ac5e7SGunnar Mills 
310325b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
310425b54dbaSEd Tanous     {
31050e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3106002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
310725b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
310825b54dbaSEd Tanous             4;
3109613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3110613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
311125b54dbaSEd Tanous     }
311213451e39SWilly Tu 
3113eb261e1fSJanet Adkins     if constexpr (BMCWEB_REDFISH_USE_HARDCODED_SYSTEM_LOCATION_INDICATOR)
3114eb261e1fSJanet Adkins     {
3115eb261e1fSJanet Adkins         getSystemLocationIndicatorActive(asyncResp);
3116eb261e1fSJanet Adkins     }
3117eb261e1fSJanet Adkins     else
3118eb261e1fSJanet Adkins     {
31192eaa9279SJanet Adkins         systems_utils::getValidSystemsPath(
31202eaa9279SJanet Adkins             asyncResp, systemName,
31212eaa9279SJanet Adkins             [asyncResp,
31222eaa9279SJanet Adkins              systemName](const std::optional<std::string>& validSystemsPath) {
31232eaa9279SJanet Adkins                 if (validSystemsPath)
31242eaa9279SJanet Adkins                 {
31252eaa9279SJanet Adkins                     getLocationIndicatorActive(asyncResp, *validSystemsPath);
31262eaa9279SJanet Adkins                 }
31272eaa9279SJanet Adkins             });
3128eb261e1fSJanet Adkins     }
31292eaa9279SJanet Adkins 
3130f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3131f664fd8aSJanet Adkins     {
3132a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
3133f664fd8aSJanet Adkins     }
3134f664fd8aSJanet Adkins 
31355e7c1f31SOliver Brewka     // Currently not supported on multi-host.
31365e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31375e7c1f31SOliver Brewka     {
313851bd2d8aSGunnar Mills         getComputerSystem(asyncResp);
31395e7c1f31SOliver Brewka         // Todo: chassis matching could be handled by patch
31405e7c1f31SOliver Brewka         // https://gerrit.openbmc.org/c/openbmc/bmcweb/+/60793
31415e7c1f31SOliver Brewka         getMainChassisId(
31425e7c1f31SOliver Brewka             asyncResp, [](const std::string& chassisId,
31435e7c1f31SOliver Brewka                           const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
31445e7c1f31SOliver Brewka                 nlohmann::json::array_t chassisArray;
31455e7c1f31SOliver Brewka                 nlohmann::json& chassis = chassisArray.emplace_back();
31465e7c1f31SOliver Brewka                 chassis["@odata.id"] =
31475e7c1f31SOliver Brewka                     boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
31485e7c1f31SOliver Brewka                 aRsp->res.jsonValue["Links"]["Chassis"] =
31495e7c1f31SOliver Brewka                     std::move(chassisArray);
31505e7c1f31SOliver Brewka             });
31515e7c1f31SOliver Brewka 
31525e7c1f31SOliver Brewka         pcie_util::getPCIeDeviceList(
31535e7c1f31SOliver Brewka             asyncResp, nlohmann::json::json_pointer("/PCIeDevices"));
31545e7c1f31SOliver Brewka     }
31555e7c1f31SOliver Brewka     getHostState(asyncResp, computerSystemIndex);
31565e7c1f31SOliver Brewka     getBootProperties(asyncResp, computerSystemIndex);
31575e7c1f31SOliver Brewka     getBootProgress(asyncResp, computerSystemIndex);
31585e7c1f31SOliver Brewka     getBootProgressLastStateTime(asyncResp, computerSystemIndex);
315951709ffdSYong Li     getHostWatchdogTimer(asyncResp);
31605e7c1f31SOliver Brewka     getPowerRestorePolicy(asyncResp, computerSystemIndex);
31619dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
31625e7c1f31SOliver Brewka     getAutomaticRetryPolicy(asyncResp, computerSystemIndex);
31635e7c1f31SOliver Brewka     getLastResetTime(asyncResp, computerSystemIndex);
316425b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
316525b54dbaSEd Tanous     {
3166a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
316725b54dbaSEd Tanous     }
31685e7c1f31SOliver Brewka     getTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex);
31693a2d0424SChris Cain     getPowerMode(asyncResp);
317037bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3171c1e219d5SEd Tanous }
3172550a6bf8SJiaqing Zhao 
31735e7c1f31SOliver Brewka inline void handleComputerSystemGet(
31745e7c1f31SOliver Brewka     crow::App& app, const crow::Request& req,
31755e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31765e7c1f31SOliver Brewka     const std::string& systemName)
31775e7c1f31SOliver Brewka {
31785e7c1f31SOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
31795e7c1f31SOliver Brewka     {
31805e7c1f31SOliver Brewka         return;
31815e7c1f31SOliver Brewka     }
31825e7c1f31SOliver Brewka 
31835e7c1f31SOliver Brewka     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
31845e7c1f31SOliver Brewka     {
31855e7c1f31SOliver Brewka         if (systemName == "hypervisor")
31865e7c1f31SOliver Brewka         {
31875e7c1f31SOliver Brewka             handleHypervisorSystemGet(asyncResp);
31885e7c1f31SOliver Brewka             return;
31895e7c1f31SOliver Brewka         }
31905e7c1f31SOliver Brewka     }
31915e7c1f31SOliver Brewka 
31925e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31935e7c1f31SOliver Brewka     {
31945e7c1f31SOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
31955e7c1f31SOliver Brewka         {
31965e7c1f31SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31975e7c1f31SOliver Brewka                                        systemName);
31985e7c1f31SOliver Brewka             return;
31995e7c1f31SOliver Brewka         }
32005e7c1f31SOliver Brewka     }
32015e7c1f31SOliver Brewka 
32025e7c1f31SOliver Brewka     BMCWEB_LOG_DEBUG("requested system = {}", systemName);
32035e7c1f31SOliver Brewka     getComputerSystemIndex(
32045e7c1f31SOliver Brewka         asyncResp, systemName,
32055e7c1f31SOliver Brewka         std::bind_front(processComputerSystemGet, asyncResp, systemName));
32065e7c1f31SOliver Brewka }
32075e7c1f31SOliver Brewka 
3208d43cc6bcSOliver Brewka struct PatchParams
3209c1e219d5SEd Tanous {
32109f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3211cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
321298e386ecSGunnar Mills     std::optional<std::string> assetTag;
3213c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
32143a2d0424SChris Cain     std::optional<std::string> powerMode;
3215550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3216550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3217550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3218550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3219550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3220550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3221797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3222550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
32239dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3224550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3225550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3226550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3227550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3228550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3229d43cc6bcSOliver Brewka };
3230550a6bf8SJiaqing Zhao 
3231d43cc6bcSOliver Brewka /**
3232d43cc6bcSOliver Brewka  * @brief process the POST request after getting the computerSystemIndex
3233d43cc6bcSOliver Brewka  *
3234d43cc6bcSOliver Brewka  * @param[in] asyncResp           Shared pointer for completing asynchronous
3235d43cc6bcSOliver Brewka  *                                calls
3236d43cc6bcSOliver Brewka  * @param[in] patchParams         Struct containing the property we want to
3237d43cc6bcSOliver Brewka  *                                patch
3238d43cc6bcSOliver Brewka  * @param[in] computerSystemIndex Index associated with the requested system
3239d43cc6bcSOliver Brewka  *
3240d43cc6bcSOliver Brewka  * @return None
3241d43cc6bcSOliver Brewka  */
3242d43cc6bcSOliver Brewka 
3243d43cc6bcSOliver Brewka inline void processComputerSystemPatch(
3244d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3245d43cc6bcSOliver Brewka     std::string& systemName, PatchParams& patchParams,
3246d43cc6bcSOliver Brewka     const uint64_t computerSystemIndex)
32476617338dSEd Tanous {
3248f664fd8aSJanet Adkins     if constexpr (!BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3249f664fd8aSJanet Adkins     {
3250d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
3251f664fd8aSJanet Adkins         {
3252f664fd8aSJanet Adkins             messages::propertyUnknown(asyncResp->res, "IndicatorLED");
3253f664fd8aSJanet Adkins             return;
3254f664fd8aSJanet Adkins         }
3255f664fd8aSJanet Adkins     }
3256f664fd8aSJanet Adkins 
3257d43cc6bcSOliver Brewka     if (patchParams.assetTag)
325898e386ecSGunnar Mills     {
3259d43cc6bcSOliver Brewka         setAssetTag(asyncResp, *patchParams.assetTag);
326098e386ecSGunnar Mills     }
326198e386ecSGunnar Mills 
3262d43cc6bcSOliver Brewka     if (patchParams.wdtEnable || patchParams.wdtTimeOutAction)
3263c45f0082SYong Li     {
3264d43cc6bcSOliver Brewka         setWDTProperties(asyncResp, patchParams.wdtEnable,
3265d43cc6bcSOliver Brewka                          patchParams.wdtTimeOutAction);
3266c45f0082SYong Li     }
3267c45f0082SYong Li 
3268d43cc6bcSOliver Brewka     if (patchParams.bootSource || patchParams.bootType ||
3269d43cc6bcSOliver Brewka         patchParams.bootEnable)
327069f35306SGunnar Mills     {
3271d43cc6bcSOliver Brewka         setBootProperties(asyncResp, computerSystemIndex,
3272d43cc6bcSOliver Brewka                           patchParams.bootSource, patchParams.bootType,
3273d43cc6bcSOliver Brewka                           patchParams.bootEnable);
3274491d8ee7SSantosh Puranik     }
3275d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetry)
327669f35306SGunnar Mills     {
3277d43cc6bcSOliver Brewka         setAutomaticRetry(asyncResp, computerSystemIndex,
3278d43cc6bcSOliver Brewka                           *patchParams.bootAutomaticRetry);
327969f35306SGunnar Mills     }
3280ac7e1e0bSAli Ahmed 
3281d43cc6bcSOliver Brewka     if (patchParams.bootAutomaticRetryAttempts)
3282797d5daeSCorey Hardesty     {
3283d43cc6bcSOliver Brewka         setAutomaticRetryAttempts(
3284d43cc6bcSOliver Brewka             asyncResp, computerSystemIndex,
3285d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts.value());
3286797d5daeSCorey Hardesty     }
3287797d5daeSCorey Hardesty 
3288d43cc6bcSOliver Brewka     if (patchParams.bootTrustedModuleRequired)
3289ac7e1e0bSAli Ahmed     {
3290d43cc6bcSOliver Brewka         setTrustedModuleRequiredToBoot(asyncResp, computerSystemIndex,
3291d43cc6bcSOliver Brewka                                        *patchParams.bootTrustedModuleRequired);
329269f35306SGunnar Mills     }
3293265c1602SJohnathan Mantey 
3294d43cc6bcSOliver Brewka     if (patchParams.stopBootOnFault)
32959dcfe8c1SAlbert Zhang     {
3296d43cc6bcSOliver Brewka         setStopBootOnFault(asyncResp, *patchParams.stopBootOnFault);
32979dcfe8c1SAlbert Zhang     }
32989dcfe8c1SAlbert Zhang 
3299d43cc6bcSOliver Brewka     if (patchParams.locationIndicatorActive)
33009f8bfa7cSGunnar Mills     {
3301eb261e1fSJanet Adkins         if constexpr (BMCWEB_REDFISH_USE_HARDCODED_SYSTEM_LOCATION_INDICATOR)
3302eb261e1fSJanet Adkins         {
3303eb261e1fSJanet Adkins             setSystemLocationIndicatorActive(
3304eb261e1fSJanet Adkins                 asyncResp, *patchParams.locationIndicatorActive);
3305eb261e1fSJanet Adkins         }
3306eb261e1fSJanet Adkins         else
3307eb261e1fSJanet Adkins         {
33082eaa9279SJanet Adkins             systems_utils::getValidSystemsPath(
33092eaa9279SJanet Adkins                 asyncResp, systemName,
33102eaa9279SJanet Adkins                 [asyncResp, systemName,
3311d43cc6bcSOliver Brewka                  locationIndicatorActive{*patchParams.locationIndicatorActive}](
33122eaa9279SJanet Adkins                     const std::optional<std::string>& validSystemsPath) {
33132eaa9279SJanet Adkins                     if (!validSystemsPath)
33142eaa9279SJanet Adkins                     {
33152eaa9279SJanet Adkins                         messages::resourceNotFound(asyncResp->res, "Systems",
33162eaa9279SJanet Adkins                                                    systemName);
33172eaa9279SJanet Adkins                         return;
33182eaa9279SJanet Adkins                     }
33192eaa9279SJanet Adkins                     setLocationIndicatorActive(asyncResp, *validSystemsPath,
33202eaa9279SJanet Adkins                                                locationIndicatorActive);
33212eaa9279SJanet Adkins                 });
33229f8bfa7cSGunnar Mills         }
3323eb261e1fSJanet Adkins     }
33249f8bfa7cSGunnar Mills 
3325f664fd8aSJanet Adkins     if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_INDICATORLED)
3326f664fd8aSJanet Adkins     {
3327d43cc6bcSOliver Brewka         if (patchParams.indicatorLed)
33286617338dSEd Tanous         {
3329d43cc6bcSOliver Brewka             setIndicatorLedState(asyncResp, *patchParams.indicatorLed);
3330002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3331d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3332d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
33336617338dSEd Tanous         }
3334f664fd8aSJanet Adkins     }
3335c6a620f2SGeorge Liu 
3336d43cc6bcSOliver Brewka     if (patchParams.powerRestorePolicy)
3337c6a620f2SGeorge Liu     {
3338d43cc6bcSOliver Brewka         setPowerRestorePolicy(asyncResp, computerSystemIndex,
3339d43cc6bcSOliver Brewka                               *patchParams.powerRestorePolicy);
3340c6a620f2SGeorge Liu     }
33413a2d0424SChris Cain 
3342d43cc6bcSOliver Brewka     if (patchParams.powerMode)
33433a2d0424SChris Cain     {
3344d43cc6bcSOliver Brewka         setPowerMode(asyncResp, *patchParams.powerMode);
33453a2d0424SChris Cain     }
334637bbf98cSChris Cain 
3347d43cc6bcSOliver Brewka     if (patchParams.ipsEnable || patchParams.ipsEnterUtil ||
3348d43cc6bcSOliver Brewka         patchParams.ipsEnterTime || patchParams.ipsExitUtil ||
3349d43cc6bcSOliver Brewka         patchParams.ipsExitTime)
335037bbf98cSChris Cain     {
3351d43cc6bcSOliver Brewka         setIdlePowerSaver(asyncResp, patchParams.ipsEnable,
3352d43cc6bcSOliver Brewka                           patchParams.ipsEnterUtil, patchParams.ipsEnterTime,
3353d43cc6bcSOliver Brewka                           patchParams.ipsExitUtil, patchParams.ipsExitTime);
335437bbf98cSChris Cain     }
3355c1e219d5SEd Tanous }
33561cb1a9e6SAppaRao Puli 
3357d43cc6bcSOliver Brewka inline void handleComputerSystemPatch(
3358d43cc6bcSOliver Brewka     crow::App& app, const crow::Request& req,
3359d43cc6bcSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3360d43cc6bcSOliver Brewka     const std::string& systemName)
3361d43cc6bcSOliver Brewka {
3362d43cc6bcSOliver Brewka     PatchParams patchParams;
3363d43cc6bcSOliver Brewka 
3364d43cc6bcSOliver Brewka     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3365d43cc6bcSOliver Brewka     {
3366d43cc6bcSOliver Brewka         return;
3367d43cc6bcSOliver Brewka     }
3368d43cc6bcSOliver Brewka 
3369d43cc6bcSOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3370d43cc6bcSOliver Brewka     {
3371d43cc6bcSOliver Brewka         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3372d43cc6bcSOliver Brewka         {
3373d43cc6bcSOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3374d43cc6bcSOliver Brewka                                        systemName);
3375d43cc6bcSOliver Brewka             return;
3376d43cc6bcSOliver Brewka         }
3377d43cc6bcSOliver Brewka     }
3378d43cc6bcSOliver Brewka 
3379d43cc6bcSOliver Brewka     asyncResp->res.addHeader(
3380d43cc6bcSOliver Brewka         boost::beast::http::field::link,
3381d43cc6bcSOliver Brewka         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3382d43cc6bcSOliver Brewka 
3383d43cc6bcSOliver Brewka     if (!json_util::readJsonPatch(
3384d43cc6bcSOliver Brewka             req, asyncResp->res,                                              //
3385d43cc6bcSOliver Brewka             "AssetTag", patchParams.assetTag,                                 //
3386d43cc6bcSOliver Brewka             "Boot/AutomaticRetryAttempts",
3387d43cc6bcSOliver Brewka             patchParams.bootAutomaticRetryAttempts,                           //
3388d43cc6bcSOliver Brewka             "Boot/AutomaticRetryConfig", patchParams.bootAutomaticRetry,      //
3389d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideEnabled", patchParams.bootEnable,         //
3390d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideMode", patchParams.bootType,              //
3391d43cc6bcSOliver Brewka             "Boot/BootSourceOverrideTarget", patchParams.bootSource,          //
3392d43cc6bcSOliver Brewka             "Boot/StopBootOnFault", patchParams.stopBootOnFault,              //
3393d43cc6bcSOliver Brewka             "Boot/TrustedModuleRequiredToBoot",
3394d43cc6bcSOliver Brewka             patchParams.bootTrustedModuleRequired,                            //
3395d43cc6bcSOliver Brewka             "HostWatchdogTimer/FunctionEnabled", patchParams.wdtEnable,       //
3396d43cc6bcSOliver Brewka             "HostWatchdogTimer/TimeoutAction", patchParams.wdtTimeOutAction,  //
3397d43cc6bcSOliver Brewka             "IdlePowerSaver/Enabled", patchParams.ipsEnable,                  //
3398d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterDwellTimeSeconds", patchParams.ipsEnterTime, //
3399d43cc6bcSOliver Brewka             "IdlePowerSaver/EnterUtilizationPercent",
3400d43cc6bcSOliver Brewka             patchParams.ipsEnterUtil,                                         //
3401d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitDwellTimeSeconds", patchParams.ipsExitTime,   //
3402d43cc6bcSOliver Brewka             "IdlePowerSaver/ExitUtilizationPercent", patchParams.ipsExitUtil, //
3403d43cc6bcSOliver Brewka             "IndicatorLED", patchParams.indicatorLed,                         //
3404d43cc6bcSOliver Brewka             "LocationIndicatorActive", patchParams.locationIndicatorActive,   //
3405d43cc6bcSOliver Brewka             "PowerMode", patchParams.powerMode,                               //
3406d43cc6bcSOliver Brewka             "PowerRestorePolicy", patchParams.powerRestorePolicy))
3407d43cc6bcSOliver Brewka     {
3408d43cc6bcSOliver Brewka         return;
3409d43cc6bcSOliver Brewka     }
3410d43cc6bcSOliver Brewka 
3411d43cc6bcSOliver Brewka     getComputerSystemIndex(asyncResp, systemName,
3412d43cc6bcSOliver Brewka                            std::bind_front(processComputerSystemPatch,
3413d43cc6bcSOliver Brewka                                            asyncResp, systemName, patchParams));
3414d43cc6bcSOliver Brewka }
3415d43cc6bcSOliver Brewka 
341638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3417dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34187f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3419c1e219d5SEd Tanous     const std::string& /*systemName*/)
3420dd60b9edSEd Tanous {
3421dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3422dd60b9edSEd Tanous     {
3423dd60b9edSEd Tanous         return;
3424dd60b9edSEd Tanous     }
3425dd60b9edSEd Tanous     asyncResp->res.addHeader(
3426dd60b9edSEd Tanous         boost::beast::http::field::link,
3427dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3428dd60b9edSEd Tanous }
342933e1f122SAndrew Geissler 
343033e1f122SAndrew Geissler /**
343133e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
343233e1f122SAndrew Geissler  *
343333e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
343433e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
343533e1f122SAndrew Geissler  *
3436efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
343733e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
343833e1f122SAndrew Geissler  * allowableValues.
343933e1f122SAndrew Geissler  */
3440504af5a0SPatrick Williams inline void dbusToRfAllowedHostTransitions(
3441504af5a0SPatrick Williams     const std::string& dbusAllowedHostTran,
344233e1f122SAndrew Geissler     nlohmann::json::array_t& allowableValues)
344333e1f122SAndrew Geissler {
344433e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
344533e1f122SAndrew Geissler     {
344633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
344733e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
344833e1f122SAndrew Geissler     }
344933e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
345033e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
345133e1f122SAndrew Geissler     {
345233e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
345333e1f122SAndrew Geissler     }
345433e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
345533e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
345633e1f122SAndrew Geissler     {
345733e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
345833e1f122SAndrew Geissler     }
345933e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
346033e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
346133e1f122SAndrew Geissler     {
346233e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
346333e1f122SAndrew Geissler     }
346433e1f122SAndrew Geissler     else
346533e1f122SAndrew Geissler     {
346633e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
346733e1f122SAndrew Geissler     }
346833e1f122SAndrew Geissler }
346933e1f122SAndrew Geissler 
347033e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
347133e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
347233e1f122SAndrew Geissler     const boost::system::error_code& ec,
347333e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
347433e1f122SAndrew Geissler {
347533e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
347633e1f122SAndrew Geissler 
347733e1f122SAndrew Geissler     // Supported on all systems currently
347833e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
347933e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
348033e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
348133e1f122SAndrew Geissler 
348233e1f122SAndrew Geissler     if (ec)
348333e1f122SAndrew Geissler     {
3484e715d14bSEd Tanous         if ((ec.value() ==
3485e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3486e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
348733e1f122SAndrew Geissler         {
348833e1f122SAndrew Geissler             // Property not implemented so just return defaults
348933e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
349033e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
349133e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
349233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
349333e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
349433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
349533e1f122SAndrew Geissler         }
349633e1f122SAndrew Geissler         else
349733e1f122SAndrew Geissler         {
349833e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
349933e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
350033e1f122SAndrew Geissler             return;
350133e1f122SAndrew Geissler         }
350233e1f122SAndrew Geissler     }
350333e1f122SAndrew Geissler     else
350433e1f122SAndrew Geissler     {
350533e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
350633e1f122SAndrew Geissler         {
350733e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
350833e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
350933e1f122SAndrew Geissler         }
351033e1f122SAndrew Geissler     }
351133e1f122SAndrew Geissler 
351233e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
351333e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
351433e1f122SAndrew Geissler     parameter["Required"] = true;
3515539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
351633e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
351733e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
351833e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
351933e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
352033e1f122SAndrew Geissler }
352133e1f122SAndrew Geissler 
35225e7c1f31SOliver Brewka inline void getAllowedHostTransitions(
35235e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
35245e7c1f31SOliver Brewka     const uint64_t computerSystemIndex)
35255e7c1f31SOliver Brewka {
3526a52f1d5bSEd Tanous     sdbusplus::message::object_path path =
3527a52f1d5bSEd Tanous         getHostStateObjectPath(computerSystemIndex);
35285e7c1f31SOliver Brewka     dbus::utility::getProperty<std::vector<std::string>>(
3529a52f1d5bSEd Tanous         getHostStateServiceName(computerSystemIndex), path,
35305e7c1f31SOliver Brewka         "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
35315e7c1f31SOliver Brewka         std::bind_front(afterGetAllowedHostTransitions, asyncResp));
35325e7c1f31SOliver Brewka }
35335e7c1f31SOliver Brewka 
3534c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3535c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
353622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3537c1e219d5SEd Tanous     const std::string& systemName)
3538c1e219d5SEd Tanous {
35393ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
354045ca1b86SEd Tanous     {
354145ca1b86SEd Tanous         return;
354245ca1b86SEd Tanous     }
3543746b56f3SAsmitha Karunanithi 
354468896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
354568896206SGunnar Mills     {
3546746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3547746b56f3SAsmitha Karunanithi         {
3548746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3549746b56f3SAsmitha Karunanithi             return;
3550746b56f3SAsmitha Karunanithi         }
355168896206SGunnar Mills     }
3552746b56f3SAsmitha Karunanithi 
35535e7c1f31SOliver Brewka     if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
35545e7c1f31SOliver Brewka     {
3555253f11b8SEd Tanous         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
355622d268cbSEd Tanous         {
355722d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
355822d268cbSEd Tanous                                        systemName);
355922d268cbSEd Tanous             return;
356022d268cbSEd Tanous         }
35615e7c1f31SOliver Brewka     }
356222d268cbSEd Tanous 
3563dd60b9edSEd Tanous     asyncResp->res.addHeader(
3564dd60b9edSEd Tanous         boost::beast::http::field::link,
3565dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35661476687dSEd Tanous 
35675e7c1f31SOliver Brewka     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
35685e7c1f31SOliver Brewka         "/redfish/v1/Systems/{}/ResetActionInfo", systemName);
3569c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35701476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35711476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35723215e700SNan Zhou 
357333e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
35745e7c1f31SOliver Brewka     getComputerSystemIndex(
35755e7c1f31SOliver Brewka         asyncResp, systemName,
35765e7c1f31SOliver Brewka         std::bind_front(getAllowedHostTransitions, asyncResp));
3577c1e219d5SEd Tanous }
35785e7c1f31SOliver Brewka 
3579c1e219d5SEd Tanous /**
3580c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3581c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3582c1e219d5SEd Tanous  */
3583100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3584c1e219d5SEd Tanous {
3585100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3586100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3587100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3588100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3589100afe56SEd Tanous 
3590100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3591100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3592100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3593100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3594100afe56SEd Tanous 
3595100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3596100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3597100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3598100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3599100afe56SEd Tanous 
3600100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3601100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3602100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3603100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3604100afe56SEd Tanous 
3605100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3606100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3607100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3608100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3609100afe56SEd Tanous 
3610100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3611100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3612100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3613100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3614100afe56SEd Tanous 
3615c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3616c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3617c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3618c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3619c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3620c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3621c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3622c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36231cb1a9e6SAppaRao Puli }
3624c5b2abe0SLewanczyk, Dawid } // namespace redfish
3625