xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*40e9b92eSEd 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"
91e1e598dSJonathan Doman #include "dbus_singleton.hpp"
107a1dbc48SGeorge Liu #include "dbus_utility.hpp"
11539d8c6bSEd Tanous #include "generated/enums/action_info.hpp"
128d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
13539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp"
1433e1f122SAndrew Geissler #include "generated/enums/resource.hpp"
15746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
161c8fba97SJames Feist #include "led.hpp"
17f4c99e70SEd Tanous #include "query.hpp"
18c5d03ff4SJennifer Lee #include "redfish_util.hpp"
193ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
203ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
213ccb3adbSEd Tanous #include "utils/json_utils.hpp"
22472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
233ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
242b82937eSEd Tanous #include "utils/time_utils.hpp"
25c5d03ff4SJennifer Lee 
26fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
279712f8acSEd Tanous #include <boost/container/flat_map.hpp>
28e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
2933e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
30ef4c65b7SEd Tanous #include <boost/url/format.hpp>
311e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
32fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
33bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
341214b7e7SGunnar Mills 
357a1dbc48SGeorge Liu #include <array>
3633e1f122SAndrew Geissler #include <memory>
376b9ac4f2SChris Cain #include <string>
387a1dbc48SGeorge Liu #include <string_view>
3920fa6a2cSEd Tanous #include <utility>
40abf2add6SEd Tanous #include <variant>
416b9ac4f2SChris Cain #include <vector>
42c5b2abe0SLewanczyk, Dawid 
431abe55efSEd Tanous namespace redfish
441abe55efSEd Tanous {
45c5b2abe0SLewanczyk, Dawid 
465c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
475c3e9272SAbhishek Patel     protocolToDBusForSystems{
485c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
495c3e9272SAbhishek Patel 
509d3ae10eSAlpana Kumari /**
519d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
529d3ae10eSAlpana Kumari  *
53ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
549d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
559d3ae10eSAlpana Kumari  *
569d3ae10eSAlpana Kumari  * @return None.
579d3ae10eSAlpana Kumari  */
58bd79bce8SPatrick Williams inline void updateDimmProperties(
59bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
609d3ae10eSAlpana Kumari {
6162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
629d3ae10eSAlpana Kumari 
639d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
649d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
659d3ae10eSAlpana Kumari     // ENABLED.
6602cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
67ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
689d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
699d3ae10eSAlpana Kumari     {
70e05aec50SEd Tanous         if (isDimmFunctional)
719d3ae10eSAlpana Kumari         {
72ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
739d3ae10eSAlpana Kumari                 "Enabled";
749d3ae10eSAlpana Kumari         }
759d3ae10eSAlpana Kumari     }
769d3ae10eSAlpana Kumari }
779d3ae10eSAlpana Kumari 
7857e8c9beSAlpana Kumari /*
7957e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8057e8c9beSAlpana Kumari  *        CPU Functional State
8157e8c9beSAlpana Kumari  *
82ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
8357e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
8457e8c9beSAlpana Kumari  *
8557e8c9beSAlpana Kumari  * @return None.
8657e8c9beSAlpana Kumari  */
87ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
88ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
8957e8c9beSAlpana Kumari {
9062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
9157e8c9beSAlpana Kumari 
9202cad96eSEd Tanous     const nlohmann::json& prevProcState =
93ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
9457e8c9beSAlpana Kumari 
9557e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
9657e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
9757e8c9beSAlpana Kumari     // Functional.
9857e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
9957e8c9beSAlpana Kumari     {
100e05aec50SEd Tanous         if (isCpuFunctional)
10157e8c9beSAlpana Kumari         {
102ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10357e8c9beSAlpana Kumari                 "Enabled";
10457e8c9beSAlpana Kumari         }
10557e8c9beSAlpana Kumari     }
10657e8c9beSAlpana Kumari }
10757e8c9beSAlpana Kumari 
108cf0e004cSNinad Palsule /*
109cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
110cf0e004cSNinad Palsule  *
111ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
112cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
113cf0e004cSNinad Palsule  *
114cf0e004cSNinad Palsule  * @return None.
115cf0e004cSNinad Palsule  */
116bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
117bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
118cf0e004cSNinad Palsule {
11962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
120cf0e004cSNinad Palsule 
121cf0e004cSNinad Palsule     if (isCpuPresent)
122cf0e004cSNinad Palsule     {
123cf0e004cSNinad Palsule         nlohmann::json& procCount =
124ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
125cf0e004cSNinad Palsule         auto* procCountPtr =
126cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
127cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
128cf0e004cSNinad Palsule         {
129cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
130cf0e004cSNinad Palsule             *procCountPtr += 1;
131cf0e004cSNinad Palsule         }
132cf0e004cSNinad Palsule     }
133cf0e004cSNinad Palsule }
134cf0e004cSNinad Palsule 
135382d6475SAli Ahmed inline void getProcessorProperties(
136ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
137382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
138382d6475SAli Ahmed         properties)
13903fbed92SAli Ahmed {
14062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
14103fbed92SAli Ahmed 
14203fbed92SAli Ahmed     // TODO: Get Model
14303fbed92SAli Ahmed 
144bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
14503fbed92SAli Ahmed 
146bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
147bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
14803fbed92SAli Ahmed 
149bc1d29deSKrzysztof Grobelny     if (!success)
15003fbed92SAli Ahmed     {
151ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15203fbed92SAli Ahmed         return;
15303fbed92SAli Ahmed     }
15403fbed92SAli Ahmed 
155bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
15603fbed92SAli Ahmed     {
157bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
158ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
159bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
160bc1d29deSKrzysztof Grobelny 
161bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
162bc1d29deSKrzysztof Grobelny         {
163bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
16403fbed92SAli Ahmed         }
16503fbed92SAli Ahmed         else
16603fbed92SAli Ahmed         {
167bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
16803fbed92SAli Ahmed         }
16903fbed92SAli Ahmed     }
17003fbed92SAli Ahmed }
17103fbed92SAli Ahmed 
17203fbed92SAli Ahmed /*
17303fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
17403fbed92SAli Ahmed  *
175ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
17603fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
17703fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
17803fbed92SAli Ahmed  *
17903fbed92SAli Ahmed  * @return None.
18003fbed92SAli Ahmed  */
181ac106bf6SEd Tanous inline void
182ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
183ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
18403fbed92SAli Ahmed {
185ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
186382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
187382d6475SAli Ahmed         if (ec3)
188382d6475SAli Ahmed         {
18962598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
190382d6475SAli Ahmed             return;
191382d6475SAli Ahmed         }
192ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
193382d6475SAli Ahmed     };
194382d6475SAli Ahmed 
195cf0e004cSNinad Palsule     // Get the Presence of CPU
196deae6a78SEd Tanous     dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
197deae6a78SEd Tanous                                      path, "xyz.openbmc_project.Inventory.Item",
198deae6a78SEd Tanous                                      "Present", std::move(getCpuPresenceState));
199cf0e004cSNinad Palsule 
200deae6a78SEd Tanous     dbus::utility::getAllProperties(
201deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
202ac106bf6SEd Tanous         [asyncResp, service,
2035e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
204b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
20503fbed92SAli Ahmed             if (ec2)
20603fbed92SAli Ahmed             {
20762598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
208ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
20903fbed92SAli Ahmed                 return;
21003fbed92SAli Ahmed             }
211ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
212bc1d29deSKrzysztof Grobelny         });
21303fbed92SAli Ahmed }
21403fbed92SAli Ahmed 
21557e8c9beSAlpana Kumari /*
216cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
217cf0e004cSNinad Palsule  *
218ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
219cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
220cf0e004cSNinad Palsule  *
221cf0e004cSNinad Palsule  * @return None.
222cf0e004cSNinad Palsule  */
223cf0e004cSNinad Palsule inline void
224ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
225cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
226cf0e004cSNinad Palsule {
22762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
228cf0e004cSNinad Palsule 
229cf0e004cSNinad Palsule     if (properties.empty())
230cf0e004cSNinad Palsule     {
231cf0e004cSNinad Palsule         return;
232cf0e004cSNinad Palsule     }
233cf0e004cSNinad Palsule 
234cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
235cf0e004cSNinad Palsule 
236cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
237cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
238cf0e004cSNinad Palsule         memorySizeInKB);
239cf0e004cSNinad Palsule 
240cf0e004cSNinad Palsule     if (!success)
241cf0e004cSNinad Palsule     {
242ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
243cf0e004cSNinad Palsule         return;
244cf0e004cSNinad Palsule     }
245cf0e004cSNinad Palsule 
246cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
247cf0e004cSNinad Palsule     {
248cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
249ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
250dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
251cf0e004cSNinad Palsule         if (preValue == nullptr)
252cf0e004cSNinad Palsule         {
253ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
254dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
255cf0e004cSNinad Palsule         }
256cf0e004cSNinad Palsule         else
257cf0e004cSNinad Palsule         {
258ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
259dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
260dfb2b408SPriyanga Ramasamy                 *preValue;
261cf0e004cSNinad Palsule         }
262cf0e004cSNinad Palsule     }
263cf0e004cSNinad Palsule }
264cf0e004cSNinad Palsule 
265cf0e004cSNinad Palsule /*
266cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
267cf0e004cSNinad Palsule  *
268ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
269cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
270cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
271cf0e004cSNinad Palsule  *
272cf0e004cSNinad Palsule  * @return None.
273cf0e004cSNinad Palsule  */
274ac106bf6SEd Tanous inline void
275ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
276ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
277cf0e004cSNinad Palsule {
278deae6a78SEd Tanous     dbus::utility::getAllProperties(
279deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
280ac106bf6SEd Tanous         [asyncResp, service,
281cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
282cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
283cf0e004cSNinad Palsule             if (ec2)
284cf0e004cSNinad Palsule             {
28562598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
286ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
287cf0e004cSNinad Palsule                 return;
288cf0e004cSNinad Palsule             }
28951bd2d8aSGunnar Mills             processMemoryProperties(asyncResp, properties);
290cf0e004cSNinad Palsule         });
291cf0e004cSNinad Palsule }
292cf0e004cSNinad Palsule 
293a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
294a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
295a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
2961abe55efSEd Tanous {
297a974c132SLakshmi Yadlapati     if (ec)
298a974c132SLakshmi Yadlapati     {
299a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
300a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
301a974c132SLakshmi Yadlapati         return;
302a974c132SLakshmi Yadlapati     }
303a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
304a974c132SLakshmi Yadlapati 
305a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
306a974c132SLakshmi Yadlapati 
307a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
308a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
309a974c132SLakshmi Yadlapati 
310a974c132SLakshmi Yadlapati     if (!success)
311a974c132SLakshmi Yadlapati     {
312a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
313a974c132SLakshmi Yadlapati         return;
314a974c132SLakshmi Yadlapati     }
315a974c132SLakshmi Yadlapati 
316a974c132SLakshmi Yadlapati     if (uUID != nullptr)
317a974c132SLakshmi Yadlapati     {
318a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
319a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
320a974c132SLakshmi Yadlapati         {
321a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
322a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
323a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
324a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
325a974c132SLakshmi Yadlapati         }
326a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
327a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
328a974c132SLakshmi Yadlapati     }
329a974c132SLakshmi Yadlapati }
330a974c132SLakshmi Yadlapati 
331a974c132SLakshmi Yadlapati inline void
332a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
333a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
334a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
335a974c132SLakshmi Yadlapati {
336a974c132SLakshmi Yadlapati     if (ec)
337a974c132SLakshmi Yadlapati     {
338a974c132SLakshmi Yadlapati         // doesn't have to include this
339a974c132SLakshmi Yadlapati         // interface
340a974c132SLakshmi Yadlapati         return;
341a974c132SLakshmi Yadlapati     }
342a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
343a974c132SLakshmi Yadlapati 
344a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
345a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
346a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
347a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
348a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
349a974c132SLakshmi Yadlapati 
350a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
351a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
352a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
353a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
354a974c132SLakshmi Yadlapati 
355a974c132SLakshmi Yadlapati     if (!success)
356a974c132SLakshmi Yadlapati     {
357a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
358a974c132SLakshmi Yadlapati         return;
359a974c132SLakshmi Yadlapati     }
360a974c132SLakshmi Yadlapati 
361a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
362a974c132SLakshmi Yadlapati     {
363a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
364a974c132SLakshmi Yadlapati     }
365a974c132SLakshmi Yadlapati 
366a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
367a974c132SLakshmi Yadlapati     {
368a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
369a974c132SLakshmi Yadlapati     }
370a974c132SLakshmi Yadlapati 
371a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
372a974c132SLakshmi Yadlapati     {
373a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
374a974c132SLakshmi Yadlapati     }
375a974c132SLakshmi Yadlapati 
376a974c132SLakshmi Yadlapati     if (model != nullptr)
377a974c132SLakshmi Yadlapati     {
378a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
379a974c132SLakshmi Yadlapati     }
380a974c132SLakshmi Yadlapati 
381a974c132SLakshmi Yadlapati     if (subModel != nullptr)
382a974c132SLakshmi Yadlapati     {
383a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
384a974c132SLakshmi Yadlapati     }
385a974c132SLakshmi Yadlapati 
386a974c132SLakshmi Yadlapati     // Grab the bios version
387a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
388a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
389a974c132SLakshmi Yadlapati }
390a974c132SLakshmi Yadlapati 
391bd79bce8SPatrick Williams inline void afterGetAssetTag(
392bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
393bd79bce8SPatrick Williams     const boost::system::error_code& ec, const std::string& value)
394a974c132SLakshmi Yadlapati {
395a974c132SLakshmi Yadlapati     if (ec)
396a974c132SLakshmi Yadlapati     {
397a974c132SLakshmi Yadlapati         // doesn't have to include this
398a974c132SLakshmi Yadlapati         // interface
399a974c132SLakshmi Yadlapati         return;
400a974c132SLakshmi Yadlapati     }
401a974c132SLakshmi Yadlapati 
402a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
403a974c132SLakshmi Yadlapati }
404a974c132SLakshmi Yadlapati 
405a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
406a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
407a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
408a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
409a974c132SLakshmi Yadlapati {
4101abe55efSEd Tanous     if (ec)
4111abe55efSEd Tanous     {
412b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
413ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
414c5b2abe0SLewanczyk, Dawid         return;
415c5b2abe0SLewanczyk, Dawid     }
416c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
417002d39b4SEd Tanous     for (const std::pair<
418002d39b4SEd Tanous              std::string,
419002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4201214b7e7SGunnar Mills              object : subtree)
4211abe55efSEd Tanous     {
422c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
42362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
424002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4251214b7e7SGunnar Mills             connectionNames = object.second;
42626f6976fSEd Tanous         if (connectionNames.empty())
4271abe55efSEd Tanous         {
428c5b2abe0SLewanczyk, Dawid             continue;
429c5b2abe0SLewanczyk, Dawid         }
430029573d4SEd Tanous 
4316c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4326c34de48SEd Tanous         // BiosVer
43304a258f4SEd Tanous         for (const auto& connection : connectionNames)
4341abe55efSEd Tanous         {
43504a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4361abe55efSEd Tanous             {
437a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4381abe55efSEd Tanous                 {
43962598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4409d3ae10eSAlpana Kumari 
441ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4425fd0aafbSNinad Palsule                 }
44304a258f4SEd Tanous                 else if (interfaceName ==
44404a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4451abe55efSEd Tanous                 {
44662598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
44757e8c9beSAlpana Kumari 
448ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4495fd0aafbSNinad Palsule                 }
450002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4511abe55efSEd Tanous                 {
45262598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
453bc1d29deSKrzysztof Grobelny 
454deae6a78SEd Tanous                     dbus::utility::getAllProperties(
455a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
456a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
457ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
458b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4591214b7e7SGunnar Mills                                         properties) {
460a974c132SLakshmi Yadlapati                             afterGetUUID(asyncResp, ec3, properties);
461bc1d29deSKrzysztof Grobelny                         });
462c5b2abe0SLewanczyk, Dawid                 }
463029573d4SEd Tanous                 else if (interfaceName ==
464029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4651abe55efSEd Tanous                 {
466deae6a78SEd Tanous                     dbus::utility::getAllProperties(
467a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
468bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
469a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
470b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
471a974c132SLakshmi Yadlapati                                         properties) {
472a974c132SLakshmi Yadlapati                             afterGetInventory(asyncResp, ec3, properties);
473bc1d29deSKrzysztof Grobelny                         });
474e4a4b9a9SJames Feist 
475deae6a78SEd Tanous                     dbus::utility::getProperty<std::string>(
476deae6a78SEd Tanous                         connection.first, path,
4771e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4781e1e598dSJonathan Doman                         "AssetTag",
4791e1e598dSJonathan Doman                         "AssetTag",
480a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
481a974c132SLakshmi Yadlapati                 }
482a974c132SLakshmi Yadlapati             }
483a974c132SLakshmi Yadlapati         }
484a974c132SLakshmi Yadlapati     }
485a974c132SLakshmi Yadlapati }
486a974c132SLakshmi Yadlapati 
487a974c132SLakshmi Yadlapati /*
488a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
489a974c132SLakshmi Yadlapati  *
490a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
491a974c132SLakshmi Yadlapati  *
492a974c132SLakshmi Yadlapati  * @return None.
493a974c132SLakshmi Yadlapati  */
494a974c132SLakshmi Yadlapati inline void
49551bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
496e4a4b9a9SJames Feist {
497a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
498a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
499a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
500a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
501a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
502a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
503a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
504a974c132SLakshmi Yadlapati     };
505a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
506a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
50751bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
508c5b2abe0SLewanczyk, Dawid }
509c5b2abe0SLewanczyk, Dawid 
510c5b2abe0SLewanczyk, Dawid /**
511c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
512c5b2abe0SLewanczyk, Dawid  *
513ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
514c5b2abe0SLewanczyk, Dawid  *
515c5b2abe0SLewanczyk, Dawid  * @return None.
516c5b2abe0SLewanczyk, Dawid  */
517ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5181abe55efSEd Tanous {
51962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
520deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
521deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
522deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState",
523ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5241e1e598dSJonathan Doman                     const std::string& hostState) {
5251abe55efSEd Tanous             if (ec)
5261abe55efSEd Tanous             {
52722228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
52822228c28SAndrew Geissler                 {
52922228c28SAndrew Geissler                     // Service not available, no error, just don't return
53022228c28SAndrew Geissler                     // host state info
53162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
53222228c28SAndrew Geissler                     return;
53322228c28SAndrew Geissler                 }
53462598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
535ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
536c5b2abe0SLewanczyk, Dawid                 return;
537c5b2abe0SLewanczyk, Dawid             }
5386617338dSEd Tanous 
53962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
540c5b2abe0SLewanczyk, Dawid             // Verify Host State
5411e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5421abe55efSEd Tanous             {
543bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
544bd79bce8SPatrick Williams                     resource::PowerState::On;
545539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
546539d8c6bSEd Tanous                     resource::State::Enabled;
5471abe55efSEd Tanous             }
5481e1e598dSJonathan Doman             else if (hostState ==
5490fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5508c888608SGunnar Mills             {
551bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
552bd79bce8SPatrick Williams                     resource::PowerState::On;
553539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
554539d8c6bSEd Tanous                     resource::State::Quiesced;
5558c888608SGunnar Mills             }
5561e1e598dSJonathan Doman             else if (hostState ==
5570fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
55883935af9SAndrew Geissler             {
559bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
560bd79bce8SPatrick Williams                     resource::PowerState::On;
561539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
562539d8c6bSEd Tanous                     resource::State::InTest;
56383935af9SAndrew Geissler             }
5640fda0f12SGeorge Liu             else if (
5651e1e598dSJonathan Doman                 hostState ==
5660fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5671a2a1437SAndrew Geissler             {
568539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
569539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
570539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
571539d8c6bSEd Tanous                     resource::State::Starting;
5721a2a1437SAndrew Geissler             }
573bd79bce8SPatrick Williams             else if (
574bd79bce8SPatrick Williams                 hostState ==
5750fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5761a2a1437SAndrew Geissler             {
577539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
578539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
579539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
580539d8c6bSEd Tanous                     resource::State::Disabled;
5811a2a1437SAndrew Geissler             }
5821abe55efSEd Tanous             else
5831abe55efSEd Tanous             {
584bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
585bd79bce8SPatrick Williams                     resource::PowerState::Off;
586539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
587539d8c6bSEd Tanous                     resource::State::Disabled;
588c5b2abe0SLewanczyk, Dawid             }
5891e1e598dSJonathan Doman         });
590c5b2abe0SLewanczyk, Dawid }
591c5b2abe0SLewanczyk, Dawid 
592c5b2abe0SLewanczyk, Dawid /**
593786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
594491d8ee7SSantosh Puranik  *
595491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
596491d8ee7SSantosh Puranik  *
597491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
598491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
599491d8ee7SSantosh Puranik  */
60023a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
601491d8ee7SSantosh Puranik {
602491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
603491d8ee7SSantosh Puranik     {
604491d8ee7SSantosh Puranik         return "None";
605491d8ee7SSantosh Puranik     }
6063174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
607491d8ee7SSantosh Puranik     {
608491d8ee7SSantosh Puranik         return "Hdd";
609491d8ee7SSantosh Puranik     }
6103174e4dfSEd Tanous     if (dbusSource ==
611a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
612491d8ee7SSantosh Puranik     {
613491d8ee7SSantosh Puranik         return "Cd";
614491d8ee7SSantosh Puranik     }
6153174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
616491d8ee7SSantosh Puranik     {
617491d8ee7SSantosh Puranik         return "Pxe";
618491d8ee7SSantosh Puranik     }
6193174e4dfSEd Tanous     if (dbusSource ==
620944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6219f16b2c1SJennifer Lee     {
6229f16b2c1SJennifer Lee         return "Usb";
6239f16b2c1SJennifer Lee     }
624491d8ee7SSantosh Puranik     return "";
625491d8ee7SSantosh Puranik }
626491d8ee7SSantosh Puranik 
627491d8ee7SSantosh Puranik /**
628cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
629cd9a4666SKonstantin Aladyshev  *
630cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
631cd9a4666SKonstantin Aladyshev  *
632cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
633cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
634cd9a4666SKonstantin Aladyshev  */
635cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
636cd9a4666SKonstantin Aladyshev {
637cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
638cd9a4666SKonstantin Aladyshev     {
639cd9a4666SKonstantin Aladyshev         return "Legacy";
640cd9a4666SKonstantin Aladyshev     }
641cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
642cd9a4666SKonstantin Aladyshev     {
643cd9a4666SKonstantin Aladyshev         return "UEFI";
644cd9a4666SKonstantin Aladyshev     }
645cd9a4666SKonstantin Aladyshev     return "";
646cd9a4666SKonstantin Aladyshev }
647cd9a4666SKonstantin Aladyshev 
648cd9a4666SKonstantin Aladyshev /**
649786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
650491d8ee7SSantosh Puranik  *
651491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
652491d8ee7SSantosh Puranik  *
653491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
654491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
655491d8ee7SSantosh Puranik  */
65623a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
657491d8ee7SSantosh Puranik {
658491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
659491d8ee7SSantosh Puranik     {
660491d8ee7SSantosh Puranik         return "None";
661491d8ee7SSantosh Puranik     }
6623174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
663491d8ee7SSantosh Puranik     {
664491d8ee7SSantosh Puranik         return "Diags";
665491d8ee7SSantosh Puranik     }
6663174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
667491d8ee7SSantosh Puranik     {
668491d8ee7SSantosh Puranik         return "BiosSetup";
669491d8ee7SSantosh Puranik     }
670491d8ee7SSantosh Puranik     return "";
671491d8ee7SSantosh Puranik }
672491d8ee7SSantosh Puranik 
673491d8ee7SSantosh Puranik /**
674e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
675e43914b3SAndrew Geissler  *
676e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
677e43914b3SAndrew Geissler  *
678e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
679e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
680e43914b3SAndrew Geissler  */
681e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
682e43914b3SAndrew Geissler {
683e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
684e43914b3SAndrew Geissler     // enum
685e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
686e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
687e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
688e43914b3SAndrew Geissler     {
689e43914b3SAndrew Geissler         rfBpLastState = "None";
690e43914b3SAndrew Geissler     }
691e43914b3SAndrew Geissler     else if (dbusBootProgress ==
692e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
693e43914b3SAndrew Geissler              "PrimaryProcInit")
694e43914b3SAndrew Geissler     {
695e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
696e43914b3SAndrew Geissler     }
697e43914b3SAndrew Geissler     else if (dbusBootProgress ==
698e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
699e43914b3SAndrew Geissler              "BusInit")
700e43914b3SAndrew Geissler     {
701e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
702e43914b3SAndrew Geissler     }
703e43914b3SAndrew Geissler     else if (dbusBootProgress ==
704e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
705e43914b3SAndrew Geissler              "MemoryInit")
706e43914b3SAndrew Geissler     {
707e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
708e43914b3SAndrew Geissler     }
709e43914b3SAndrew Geissler     else if (dbusBootProgress ==
710e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
711e43914b3SAndrew Geissler              "SecondaryProcInit")
712e43914b3SAndrew Geissler     {
713e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
714e43914b3SAndrew Geissler     }
715e43914b3SAndrew Geissler     else if (dbusBootProgress ==
716e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
717e43914b3SAndrew Geissler              "PCIInit")
718e43914b3SAndrew Geissler     {
719e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
720e43914b3SAndrew Geissler     }
721e43914b3SAndrew Geissler     else if (dbusBootProgress ==
722e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
723e43914b3SAndrew Geissler              "SystemSetup")
724e43914b3SAndrew Geissler     {
725e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
726e43914b3SAndrew Geissler     }
727e43914b3SAndrew Geissler     else if (dbusBootProgress ==
728e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
729e43914b3SAndrew Geissler              "SystemInitComplete")
730e43914b3SAndrew Geissler     {
731e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
732e43914b3SAndrew Geissler     }
733e43914b3SAndrew Geissler     else if (dbusBootProgress ==
734e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
735e43914b3SAndrew Geissler              "OSStart")
736e43914b3SAndrew Geissler     {
737e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
738e43914b3SAndrew Geissler     }
739e43914b3SAndrew Geissler     else if (dbusBootProgress ==
740e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
741e43914b3SAndrew Geissler              "OSRunning")
742e43914b3SAndrew Geissler     {
743e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
744e43914b3SAndrew Geissler     }
745e43914b3SAndrew Geissler     else
746e43914b3SAndrew Geissler     {
74762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
748e43914b3SAndrew Geissler         // Just return the default
749e43914b3SAndrew Geissler     }
750e43914b3SAndrew Geissler     return rfBpLastState;
751e43914b3SAndrew Geissler }
752e43914b3SAndrew Geissler 
753e43914b3SAndrew Geissler /**
754786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
755491d8ee7SSantosh Puranik  *
756491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
757944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
758944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
759491d8ee7SSantosh Puranik  *
760944ffaf9SJohnathan Mantey  * @return Integer error code.
761491d8ee7SSantosh Puranik  */
762bd79bce8SPatrick Williams inline int assignBootParameters(
763bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
764bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
765491d8ee7SSantosh Puranik {
766c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
767c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
768944ffaf9SJohnathan Mantey 
769491d8ee7SSantosh Puranik     if (rfSource == "None")
770491d8ee7SSantosh Puranik     {
771944ffaf9SJohnathan Mantey         return 0;
772491d8ee7SSantosh Puranik     }
7733174e4dfSEd Tanous     if (rfSource == "Pxe")
774491d8ee7SSantosh Puranik     {
775944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
776944ffaf9SJohnathan Mantey     }
777944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
778944ffaf9SJohnathan Mantey     {
779944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
780944ffaf9SJohnathan Mantey     }
781944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
782944ffaf9SJohnathan Mantey     {
783944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
784944ffaf9SJohnathan Mantey     }
785944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
786944ffaf9SJohnathan Mantey     {
787944ffaf9SJohnathan Mantey         bootSource =
788944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
789944ffaf9SJohnathan Mantey     }
790944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
791944ffaf9SJohnathan Mantey     {
792944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
793491d8ee7SSantosh Puranik     }
7949f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7959f16b2c1SJennifer Lee     {
796944ffaf9SJohnathan Mantey         bootSource =
797944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7989f16b2c1SJennifer Lee     }
799491d8ee7SSantosh Puranik     else
800491d8ee7SSantosh Puranik     {
80162598e31SEd Tanous         BMCWEB_LOG_DEBUG(
80262598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
80362598e31SEd Tanous             bootSource);
804ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
805944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
806944ffaf9SJohnathan Mantey         return -1;
807491d8ee7SSantosh Puranik     }
808944ffaf9SJohnathan Mantey     return 0;
809491d8ee7SSantosh Puranik }
8101981771bSAli Ahmed 
811978b8803SAndrew Geissler /**
812978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
813978b8803SAndrew Geissler  *
814ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
815978b8803SAndrew Geissler  *
816978b8803SAndrew Geissler  * @return None.
817978b8803SAndrew Geissler  */
818ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
819978b8803SAndrew Geissler {
820deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
821deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
8221e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
823ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8241e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
825978b8803SAndrew Geissler             if (ec)
826978b8803SAndrew Geissler             {
827978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
828978b8803SAndrew Geissler                 // not found
829978b8803SAndrew Geissler                 return;
830978b8803SAndrew Geissler             }
831978b8803SAndrew Geissler 
83262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
833978b8803SAndrew Geissler 
834ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
835e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8361e1e598dSJonathan Doman         });
837978b8803SAndrew Geissler }
838491d8ee7SSantosh Puranik 
839491d8ee7SSantosh Puranik /**
840b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
841b6d5d45cSHieu Huynh  *
842ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
843b6d5d45cSHieu Huynh  *
844b6d5d45cSHieu Huynh  * @return None.
845b6d5d45cSHieu Huynh  */
846b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
847ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
848b6d5d45cSHieu Huynh {
849deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
850deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
851b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
852ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
853b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
854b6d5d45cSHieu Huynh             if (ec)
855b6d5d45cSHieu Huynh             {
85662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
857b6d5d45cSHieu Huynh                 return;
858b6d5d45cSHieu Huynh             }
859b6d5d45cSHieu Huynh 
860b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
861b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
862b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
863b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
864b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
865b6d5d45cSHieu Huynh 
866b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
867ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
868b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
869b6d5d45cSHieu Huynh         });
870b6d5d45cSHieu Huynh }
871b6d5d45cSHieu Huynh 
872b6d5d45cSHieu Huynh /**
873c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
874cd9a4666SKonstantin Aladyshev  *
875ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
876cd9a4666SKonstantin Aladyshev  *
877cd9a4666SKonstantin Aladyshev  * @return None.
878cd9a4666SKonstantin Aladyshev  */
879cd9a4666SKonstantin Aladyshev 
880ac106bf6SEd Tanous inline void
881ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
882cd9a4666SKonstantin Aladyshev {
883deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
884deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
8851e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8861e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
887ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8881e1e598dSJonathan Doman                     const std::string& bootType) {
889cd9a4666SKonstantin Aladyshev             if (ec)
890cd9a4666SKonstantin Aladyshev             {
891cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
892cd9a4666SKonstantin Aladyshev                 return;
893cd9a4666SKonstantin Aladyshev             }
894cd9a4666SKonstantin Aladyshev 
89562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
896cd9a4666SKonstantin Aladyshev 
897ac106bf6SEd Tanous             asyncResp->res
898ac106bf6SEd Tanous                 .jsonValue["Boot"]
899002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
900613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
901cd9a4666SKonstantin Aladyshev 
9021e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
903cd9a4666SKonstantin Aladyshev             if (rfType.empty())
904cd9a4666SKonstantin Aladyshev             {
905ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
906cd9a4666SKonstantin Aladyshev                 return;
907cd9a4666SKonstantin Aladyshev             }
908cd9a4666SKonstantin Aladyshev 
909ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9101e1e598dSJonathan Doman         });
911cd9a4666SKonstantin Aladyshev }
912cd9a4666SKonstantin Aladyshev 
913cd9a4666SKonstantin Aladyshev /**
914c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
915491d8ee7SSantosh Puranik  *
916ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
917491d8ee7SSantosh Puranik  *
918491d8ee7SSantosh Puranik  * @return None.
919491d8ee7SSantosh Puranik  */
920c21865c4SKonstantin Aladyshev 
921ac106bf6SEd Tanous inline void
922ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
923491d8ee7SSantosh Puranik {
924deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
925deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
9261e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9271e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
928ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9291e1e598dSJonathan Doman                     const std::string& bootModeStr) {
930491d8ee7SSantosh Puranik             if (ec)
931491d8ee7SSantosh Puranik             {
932b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
933ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
934491d8ee7SSantosh Puranik                 return;
935491d8ee7SSantosh Puranik             }
936491d8ee7SSantosh Puranik 
93762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
938491d8ee7SSantosh Puranik 
93920fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
94020fa6a2cSEd Tanous             allowed.emplace_back("None");
94120fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
94220fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
94320fa6a2cSEd Tanous             allowed.emplace_back("Cd");
94420fa6a2cSEd Tanous             allowed.emplace_back("Diags");
94520fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
94620fa6a2cSEd Tanous             allowed.emplace_back("Usb");
94720fa6a2cSEd Tanous 
948ac106bf6SEd Tanous             asyncResp->res
9490fda0f12SGeorge Liu                 .jsonValue["Boot"]
95020fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
95120fa6a2cSEd Tanous                 std::move(allowed);
9521e1e598dSJonathan Doman             if (bootModeStr !=
953491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
954491d8ee7SSantosh Puranik             {
9551e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
956491d8ee7SSantosh Puranik                 if (!rfMode.empty())
957491d8ee7SSantosh Puranik                 {
958bd79bce8SPatrick Williams                     asyncResp->res
959bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
960491d8ee7SSantosh Puranik                 }
961491d8ee7SSantosh Puranik             }
9621e1e598dSJonathan Doman         });
963491d8ee7SSantosh Puranik }
964491d8ee7SSantosh Puranik 
965491d8ee7SSantosh Puranik /**
966c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
967491d8ee7SSantosh Puranik  *
968ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
969491d8ee7SSantosh Puranik  *
970491d8ee7SSantosh Puranik  * @return None.
971491d8ee7SSantosh Puranik  */
972c21865c4SKonstantin Aladyshev 
973c21865c4SKonstantin Aladyshev inline void
974ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
975491d8ee7SSantosh Puranik {
976deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
977deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
9781e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9791e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
980ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9811e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
982491d8ee7SSantosh Puranik             if (ec)
983491d8ee7SSantosh Puranik             {
9845ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
9855ef735c8SNan Zhou                 {
9865ef735c8SNan Zhou                     return;
9875ef735c8SNan Zhou                 }
988b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
989ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
990491d8ee7SSantosh Puranik                 return;
991491d8ee7SSantosh Puranik             }
992491d8ee7SSantosh Puranik 
99362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
994491d8ee7SSantosh Puranik 
9951e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
996491d8ee7SSantosh Puranik             if (!rfSource.empty())
997491d8ee7SSantosh Puranik             {
998ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
999ac106bf6SEd Tanous                     rfSource;
1000491d8ee7SSantosh Puranik             }
1001cd9a4666SKonstantin Aladyshev 
1002cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1003cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1004ac106bf6SEd Tanous             getBootOverrideMode(asyncResp);
10051e1e598dSJonathan Doman         });
1006491d8ee7SSantosh Puranik }
1007491d8ee7SSantosh Puranik 
1008491d8ee7SSantosh Puranik /**
1009c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1010c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1011c21865c4SKonstantin Aladyshev  * state
1012491d8ee7SSantosh Puranik  *
1013ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1014491d8ee7SSantosh Puranik  *
1015491d8ee7SSantosh Puranik  * @return None.
1016491d8ee7SSantosh Puranik  */
1017491d8ee7SSantosh Puranik 
1018ac106bf6SEd Tanous inline void processBootOverrideEnable(
1019ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1020c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1021c21865c4SKonstantin Aladyshev {
1022c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1023c21865c4SKonstantin Aladyshev     {
1024ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1025ac106bf6SEd Tanous             "Disabled";
1026c21865c4SKonstantin Aladyshev         return;
1027c21865c4SKonstantin Aladyshev     }
1028c21865c4SKonstantin Aladyshev 
1029c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1030c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1031deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1032deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
10331e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10341e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1035ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1036491d8ee7SSantosh Puranik             if (ec)
1037491d8ee7SSantosh Puranik             {
1038b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1039ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1040491d8ee7SSantosh Puranik                 return;
1041491d8ee7SSantosh Puranik             }
1042491d8ee7SSantosh Puranik 
1043c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1044c21865c4SKonstantin Aladyshev             {
1045ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1046ac106bf6SEd Tanous                     "Once";
1047c21865c4SKonstantin Aladyshev             }
1048c21865c4SKonstantin Aladyshev             else
1049c21865c4SKonstantin Aladyshev             {
1050ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1051c21865c4SKonstantin Aladyshev                     "Continuous";
1052c21865c4SKonstantin Aladyshev             }
10531e1e598dSJonathan Doman         });
1054491d8ee7SSantosh Puranik }
1055491d8ee7SSantosh Puranik 
1056491d8ee7SSantosh Puranik /**
1057c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1058c21865c4SKonstantin Aladyshev  *
1059ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1060c21865c4SKonstantin Aladyshev  *
1061c21865c4SKonstantin Aladyshev  * @return None.
1062c21865c4SKonstantin Aladyshev  */
1063c21865c4SKonstantin Aladyshev 
1064c21865c4SKonstantin Aladyshev inline void
1065ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1066c21865c4SKonstantin Aladyshev {
1067deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1068deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
10691e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10701e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1071ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10721e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1073c21865c4SKonstantin Aladyshev             if (ec)
1074c21865c4SKonstantin Aladyshev             {
10755ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
10765ef735c8SNan Zhou                 {
10775ef735c8SNan Zhou                     return;
10785ef735c8SNan Zhou                 }
1079b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1080ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1081c21865c4SKonstantin Aladyshev                 return;
1082c21865c4SKonstantin Aladyshev             }
1083c21865c4SKonstantin Aladyshev 
1084ac106bf6SEd Tanous             processBootOverrideEnable(asyncResp, bootOverrideEnable);
10851e1e598dSJonathan Doman         });
1086c21865c4SKonstantin Aladyshev }
1087c21865c4SKonstantin Aladyshev 
1088c21865c4SKonstantin Aladyshev /**
1089c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1090c21865c4SKonstantin Aladyshev  *
1091ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1092c21865c4SKonstantin Aladyshev  *
1093c21865c4SKonstantin Aladyshev  * @return None.
1094c21865c4SKonstantin Aladyshev  */
1095ac106bf6SEd Tanous inline void
1096ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1097c21865c4SKonstantin Aladyshev {
109862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1099c21865c4SKonstantin Aladyshev 
1100ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1101ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1102ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1103c21865c4SKonstantin Aladyshev }
1104c21865c4SKonstantin Aladyshev 
1105c21865c4SKonstantin Aladyshev /**
1106c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1107c0557e1aSGunnar Mills  *
1108c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1109c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1110c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1111c0557e1aSGunnar Mills  * last power operation time.
1112c0557e1aSGunnar Mills  *
1113ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1114c0557e1aSGunnar Mills  *
1115c0557e1aSGunnar Mills  * @return None.
1116c0557e1aSGunnar Mills  */
1117ac106bf6SEd Tanous inline void
1118ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1119c0557e1aSGunnar Mills {
112062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1121c0557e1aSGunnar Mills 
1122deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
1123deae6a78SEd Tanous         "xyz.openbmc_project.State.Chassis",
11241e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11251e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1126ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1127ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1128c0557e1aSGunnar Mills             if (ec)
1129c0557e1aSGunnar Mills             {
113062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1131c0557e1aSGunnar Mills                 return;
1132c0557e1aSGunnar Mills             }
1133c0557e1aSGunnar Mills 
1134c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1135c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11361e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1137c0557e1aSGunnar Mills 
1138c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1139ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11402b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11411e1e598dSJonathan Doman         });
1142c0557e1aSGunnar Mills }
1143c0557e1aSGunnar Mills 
1144c0557e1aSGunnar Mills /**
1145797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1146797d5daeSCorey Hardesty  *
1147797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1148797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1149797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1150797d5daeSCorey Hardesty  * dbus.
1151797d5daeSCorey Hardesty  *
1152ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1153797d5daeSCorey Hardesty  *
1154797d5daeSCorey Hardesty  * @return None.
1155797d5daeSCorey Hardesty  */
1156ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1157ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1158797d5daeSCorey Hardesty {
115962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1160797d5daeSCorey Hardesty 
1161deae6a78SEd Tanous     dbus::utility::getAllProperties(
1162deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1163797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1164ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1165ac106bf6SEd Tanous             const boost::system::error_code& ec,
1166797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1167797d5daeSCorey Hardesty             if (ec)
1168797d5daeSCorey Hardesty             {
1169797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1170797d5daeSCorey Hardesty                 {
117162598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1172ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1173797d5daeSCorey Hardesty                 }
1174797d5daeSCorey Hardesty                 return;
1175797d5daeSCorey Hardesty             }
1176797d5daeSCorey Hardesty 
1177797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1178797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1179797d5daeSCorey Hardesty 
1180797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1181bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1182bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1183797d5daeSCorey Hardesty 
1184797d5daeSCorey Hardesty             if (!success)
1185797d5daeSCorey Hardesty             {
1186ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1187797d5daeSCorey Hardesty                 return;
1188797d5daeSCorey Hardesty             }
1189797d5daeSCorey Hardesty 
1190797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1191797d5daeSCorey Hardesty             {
1192ac106bf6SEd Tanous                 asyncResp->res
1193ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1194797d5daeSCorey Hardesty                     *attemptsLeft;
1195797d5daeSCorey Hardesty             }
1196797d5daeSCorey Hardesty 
1197797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1198797d5daeSCorey Hardesty             {
1199ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1200797d5daeSCorey Hardesty                     *retryAttempts;
1201797d5daeSCorey Hardesty             }
1202797d5daeSCorey Hardesty         });
1203797d5daeSCorey Hardesty }
1204797d5daeSCorey Hardesty 
1205797d5daeSCorey Hardesty /**
12066bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12076bd5a8d2SGunnar Mills  *
1208ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12096bd5a8d2SGunnar Mills  *
12106bd5a8d2SGunnar Mills  * @return None.
12116bd5a8d2SGunnar Mills  */
1212797d5daeSCorey Hardesty inline void
1213ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12146bd5a8d2SGunnar Mills {
121562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12166bd5a8d2SGunnar Mills 
1217deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1218deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
12191e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12201e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1221ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1222ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12236bd5a8d2SGunnar Mills             if (ec)
12246bd5a8d2SGunnar Mills             {
1225797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1226797d5daeSCorey Hardesty                 {
122762598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1228ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1229797d5daeSCorey Hardesty                 }
12306bd5a8d2SGunnar Mills                 return;
12316bd5a8d2SGunnar Mills             }
12326bd5a8d2SGunnar Mills 
123362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1234e05aec50SEd Tanous             if (autoRebootEnabled)
12356bd5a8d2SGunnar Mills             {
1236ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12376bd5a8d2SGunnar Mills                     "RetryAttempts";
12386bd5a8d2SGunnar Mills             }
12396bd5a8d2SGunnar Mills             else
12406bd5a8d2SGunnar Mills             {
1241ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1242ac106bf6SEd Tanous                     "Disabled";
12436bd5a8d2SGunnar Mills             }
1244ac106bf6SEd Tanous             getAutomaticRebootAttempts(asyncResp);
124569f35306SGunnar Mills 
124669f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
124769f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
124869f35306SGunnar Mills             // RetryAttempts.
124920fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
125020fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
125120fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1252ac106bf6SEd Tanous             asyncResp->res
1253bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1254bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
125520fa6a2cSEd Tanous                 std::move(allowed);
12561e1e598dSJonathan Doman         });
12576bd5a8d2SGunnar Mills }
12586bd5a8d2SGunnar Mills 
12596bd5a8d2SGunnar Mills /**
1260797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1261797d5daeSCorey Hardesty  *
1262ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1263797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1264797d5daeSCorey Hardesty  *
1265797d5daeSCorey Hardesty  *@return None.
1266797d5daeSCorey Hardesty  */
1267797d5daeSCorey Hardesty 
1268ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1269ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1270797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1271797d5daeSCorey Hardesty {
127262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
127387c44966SAsmitha Karunanithi     setDbusProperty(
1274e93abac6SGinu George         asyncResp, "Boot/AutomaticRetryAttempts",
1275e93abac6SGinu George         "xyz.openbmc_project.State.Host",
127687c44966SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
12779ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1278e93abac6SGinu George         retryAttempts);
1279797d5daeSCorey Hardesty }
1280797d5daeSCorey Hardesty 
12818d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12828d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12838d69c668SEd Tanous {
12848d69c668SEd Tanous     if (value ==
12858d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12868d69c668SEd Tanous     {
12878d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
12888d69c668SEd Tanous     }
12898d69c668SEd Tanous     if (value ==
12908d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
12918d69c668SEd Tanous     {
12928d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12938d69c668SEd Tanous     }
12948d69c668SEd Tanous     if (value ==
12953a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
12968d69c668SEd Tanous     {
12978d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
12988d69c668SEd Tanous     }
12998d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13008d69c668SEd Tanous     {
13018d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13028d69c668SEd Tanous     }
13038d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13048d69c668SEd Tanous }
1305797d5daeSCorey Hardesty /**
1306c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1307c6a620f2SGeorge Liu  *
1308ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1309c6a620f2SGeorge Liu  *
1310c6a620f2SGeorge Liu  * @return None.
1311c6a620f2SGeorge Liu  */
13128d1b46d7Szhanghch05 inline void
1313ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1314c6a620f2SGeorge Liu {
131562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1316c6a620f2SGeorge Liu 
1317deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
1318deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
13191e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13201e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1321ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13225e7e2dc5SEd Tanous                     const std::string& policy) {
1323c6a620f2SGeorge Liu             if (ec)
1324c6a620f2SGeorge Liu             {
132562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1326c6a620f2SGeorge Liu                 return;
1327c6a620f2SGeorge Liu             }
13288d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
13298d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
13308d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1331c6a620f2SGeorge Liu             {
1332ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1333c6a620f2SGeorge Liu                 return;
1334c6a620f2SGeorge Liu             }
1335c6a620f2SGeorge Liu 
13368d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13371e1e598dSJonathan Doman         });
1338c6a620f2SGeorge Liu }
1339c6a620f2SGeorge Liu 
1340c6a620f2SGeorge Liu /**
13419dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13429dcfe8c1SAlbert Zhang  *
13439dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13449dcfe8c1SAlbert Zhang  *
13459dcfe8c1SAlbert Zhang  * @return None.
13469dcfe8c1SAlbert Zhang  */
13479dcfe8c1SAlbert Zhang inline void
13489dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13499dcfe8c1SAlbert Zhang {
135062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13519dcfe8c1SAlbert Zhang 
1352deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1353deae6a78SEd Tanous         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
13549dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13559dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13569dcfe8c1SAlbert Zhang             if (ec)
13579dcfe8c1SAlbert Zhang             {
13589dcfe8c1SAlbert Zhang                 if (ec.value() != EBADR)
13599dcfe8c1SAlbert Zhang                 {
1360b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13619dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
13629dcfe8c1SAlbert Zhang                 }
13639dcfe8c1SAlbert Zhang                 return;
13649dcfe8c1SAlbert Zhang             }
13659dcfe8c1SAlbert Zhang 
13669dcfe8c1SAlbert Zhang             if (value)
13679dcfe8c1SAlbert Zhang             {
1368539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1369539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
13709dcfe8c1SAlbert Zhang             }
13719dcfe8c1SAlbert Zhang             else
13729dcfe8c1SAlbert Zhang             {
1373539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1374539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
13759dcfe8c1SAlbert Zhang             }
13769dcfe8c1SAlbert Zhang         });
13779dcfe8c1SAlbert Zhang }
13789dcfe8c1SAlbert Zhang 
13799dcfe8c1SAlbert Zhang /**
13801981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13811981771bSAli Ahmed  * TPM is required for booting the host.
13821981771bSAli Ahmed  *
1383ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
13841981771bSAli Ahmed  *
13851981771bSAli Ahmed  * @return None.
13861981771bSAli Ahmed  */
13871981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1388ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13891981771bSAli Ahmed {
139062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1391e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1392e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1393e99073f5SGeorge Liu     dbus::utility::getSubTree(
1394e99073f5SGeorge Liu         "/", 0, interfaces,
1395ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1396b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
13971981771bSAli Ahmed             if (ec)
13981981771bSAli Ahmed             {
1399bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
1400bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
14011981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
14021981771bSAli Ahmed                 // error occurs
14031981771bSAli Ahmed                 return;
14041981771bSAli Ahmed             }
140526f6976fSEd Tanous             if (subtree.empty())
14061981771bSAli Ahmed             {
14071981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
14081981771bSAli Ahmed                 // if there is no instance found
14091981771bSAli Ahmed                 return;
14101981771bSAli Ahmed             }
14111981771bSAli Ahmed 
14121981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
14131981771bSAli Ahmed             if (subtree.size() > 1)
14141981771bSAli Ahmed             {
141562598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
141662598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
141762598e31SEd Tanous                     subtree.size());
14181981771bSAli Ahmed                 // Throw an internal Error and return
1419ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14201981771bSAli Ahmed                 return;
14211981771bSAli Ahmed             }
14221981771bSAli Ahmed 
14231981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14241981771bSAli Ahmed             // field
14251981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14261981771bSAli Ahmed             {
142762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1428ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14291981771bSAli Ahmed                 return;
14301981771bSAli Ahmed             }
14311981771bSAli Ahmed 
14321981771bSAli Ahmed             const std::string& path = subtree[0].first;
14331981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14341981771bSAli Ahmed 
14351981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
1436deae6a78SEd Tanous             dbus::utility::getProperty<bool>(
1437deae6a78SEd Tanous                 serv, path, "xyz.openbmc_project.Control.TPM.Policy",
1438deae6a78SEd Tanous                 "TPMEnable",
1439ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2,
1440ac106bf6SEd Tanous                             bool tpmRequired) {
14418a592810SEd Tanous                     if (ec2)
14421981771bSAli Ahmed                     {
1443bd79bce8SPatrick Williams                         BMCWEB_LOG_ERROR(
1444bd79bce8SPatrick Williams                             "D-BUS response error on TPM.Policy Get{}", ec2);
1445ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
14461981771bSAli Ahmed                         return;
14471981771bSAli Ahmed                     }
14481981771bSAli Ahmed 
14491e1e598dSJonathan Doman                     if (tpmRequired)
14501981771bSAli Ahmed                     {
1451ac106bf6SEd Tanous                         asyncResp->res
1452ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14531981771bSAli Ahmed                             "Required";
14541981771bSAli Ahmed                     }
14551981771bSAli Ahmed                     else
14561981771bSAli Ahmed                     {
1457ac106bf6SEd Tanous                         asyncResp->res
1458ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14591981771bSAli Ahmed                             "Disabled";
14601981771bSAli Ahmed                     }
14611e1e598dSJonathan Doman                 });
1462e99073f5SGeorge Liu         });
14631981771bSAli Ahmed }
14641981771bSAli Ahmed 
14651981771bSAli Ahmed /**
14661c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14671c05dae3SAli Ahmed  * TPM is required for booting the host.
14681c05dae3SAli Ahmed  *
1469ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14701c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14711c05dae3SAli Ahmed  *
14721c05dae3SAli Ahmed  * @return None.
14731c05dae3SAli Ahmed  */
14741c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1475ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14761c05dae3SAli Ahmed {
147762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1478e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1479e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1480e99073f5SGeorge Liu     dbus::utility::getSubTree(
1481e99073f5SGeorge Liu         "/", 0, interfaces,
1482ac106bf6SEd Tanous         [asyncResp,
1483e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1484e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14851c05dae3SAli Ahmed             if (ec)
14861c05dae3SAli Ahmed             {
1487bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
1488bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
1489ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14901c05dae3SAli Ahmed                 return;
14911c05dae3SAli Ahmed             }
149226f6976fSEd Tanous             if (subtree.empty())
14931c05dae3SAli Ahmed             {
1494bd79bce8SPatrick Williams                 messages::propertyValueNotInList(asyncResp->res,
1495bd79bce8SPatrick Williams                                                  "ComputerSystem",
14961c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
14971c05dae3SAli Ahmed                 return;
14981c05dae3SAli Ahmed             }
14991c05dae3SAli Ahmed 
15001c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
15011c05dae3SAli Ahmed             if (subtree.size() > 1)
15021c05dae3SAli Ahmed             {
150362598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
150462598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
150562598e31SEd Tanous                     subtree.size());
15061c05dae3SAli Ahmed                 // Throw an internal Error and return
1507ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15081c05dae3SAli Ahmed                 return;
15091c05dae3SAli Ahmed             }
15101c05dae3SAli Ahmed 
15111c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
15121c05dae3SAli Ahmed             // field
15131c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15141c05dae3SAli Ahmed             {
151562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1516ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15171c05dae3SAli Ahmed                 return;
15181c05dae3SAli Ahmed             }
15191c05dae3SAli Ahmed 
15201c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
15211c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
15221c05dae3SAli Ahmed 
15231c05dae3SAli Ahmed             if (serv.empty())
15241c05dae3SAli Ahmed             {
152562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1526ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15271c05dae3SAli Ahmed                 return;
15281c05dae3SAli Ahmed             }
15291c05dae3SAli Ahmed 
15301c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
1531e93abac6SGinu George             setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1532e93abac6SGinu George                             path, "xyz.openbmc_project.Control.TPM.Policy",
1533e93abac6SGinu George                             "TPMEnable", tpmRequired);
1534e99073f5SGeorge Liu         });
15351c05dae3SAli Ahmed }
15361c05dae3SAli Ahmed 
15371c05dae3SAli Ahmed /**
1538491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1539491d8ee7SSantosh Puranik  *
1540ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1541cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1542cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1543cd9a4666SKonstantin Aladyshev  */
1544ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1545cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1546cd9a4666SKonstantin Aladyshev {
1547c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1548cd9a4666SKonstantin Aladyshev 
1549c21865c4SKonstantin Aladyshev     if (!bootType)
1550cd9a4666SKonstantin Aladyshev     {
1551c21865c4SKonstantin Aladyshev         return;
1552c21865c4SKonstantin Aladyshev     }
1553c21865c4SKonstantin Aladyshev 
1554cd9a4666SKonstantin Aladyshev     // Source target specified
155562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1556cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1557cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1558cd9a4666SKonstantin Aladyshev     {
1559cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1560cd9a4666SKonstantin Aladyshev     }
1561cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1562cd9a4666SKonstantin Aladyshev     {
1563cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1564cd9a4666SKonstantin Aladyshev     }
1565cd9a4666SKonstantin Aladyshev     else
1566cd9a4666SKonstantin Aladyshev     {
156762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
156862598e31SEd Tanous                          "BootSourceOverrideMode: {}",
156962598e31SEd Tanous                          *bootType);
1570ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1571cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1572cd9a4666SKonstantin Aladyshev         return;
1573cd9a4666SKonstantin Aladyshev     }
1574cd9a4666SKonstantin Aladyshev 
1575cd9a4666SKonstantin Aladyshev     // Act on validated parameters
157662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1577cd9a4666SKonstantin Aladyshev 
1578e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1579e93abac6SGinu George                     "xyz.openbmc_project.Settings",
158087c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
158187c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
158287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1583e93abac6SGinu George                     bootTypeStr);
1584cd9a4666SKonstantin Aladyshev }
1585cd9a4666SKonstantin Aladyshev 
1586cd9a4666SKonstantin Aladyshev /**
1587cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1588cd9a4666SKonstantin Aladyshev  *
1589ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1590ac106bf6SEd Tanous  * message.
1591c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1592c21865c4SKonstantin Aladyshev  * @return Integer error code.
1593c21865c4SKonstantin Aladyshev  */
1594ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1595c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1596c21865c4SKonstantin Aladyshev {
1597c21865c4SKonstantin Aladyshev     if (!bootEnable)
1598c21865c4SKonstantin Aladyshev     {
1599c21865c4SKonstantin Aladyshev         return;
1600c21865c4SKonstantin Aladyshev     }
1601c21865c4SKonstantin Aladyshev     // Source target specified
160262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1603c21865c4SKonstantin Aladyshev 
1604c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1605c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1606c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1607c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1608c21865c4SKonstantin Aladyshev     {
1609c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1610c21865c4SKonstantin Aladyshev     }
1611c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1612c21865c4SKonstantin Aladyshev     {
1613c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1614c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1615c21865c4SKonstantin Aladyshev     }
1616c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1617c21865c4SKonstantin Aladyshev     {
1618c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1619c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1620c21865c4SKonstantin Aladyshev     }
1621c21865c4SKonstantin Aladyshev     else
1622c21865c4SKonstantin Aladyshev     {
162362598e31SEd Tanous         BMCWEB_LOG_DEBUG(
162462598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
162562598e31SEd Tanous             *bootEnable);
1626ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1627c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1628c21865c4SKonstantin Aladyshev         return;
1629c21865c4SKonstantin Aladyshev     }
1630c21865c4SKonstantin Aladyshev 
1631c21865c4SKonstantin Aladyshev     // Act on validated parameters
163262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1633c21865c4SKonstantin Aladyshev 
1634e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1635e93abac6SGinu George                     "xyz.openbmc_project.Settings",
163687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
163787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
163887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1639e93abac6SGinu George                     bootOverrideEnable);
1640c21865c4SKonstantin Aladyshev 
1641c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1642c21865c4SKonstantin Aladyshev     {
1643c21865c4SKonstantin Aladyshev         return;
1644c21865c4SKonstantin Aladyshev     }
1645c21865c4SKonstantin Aladyshev 
1646c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1647c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
164862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
164962598e31SEd Tanous                      bootOverridePersistent);
1650c21865c4SKonstantin Aladyshev 
1651e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1652e93abac6SGinu George                     "xyz.openbmc_project.Settings",
165387c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
165487c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot/one_time"),
165587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1656e93abac6SGinu George                     !bootOverridePersistent);
1657c21865c4SKonstantin Aladyshev }
1658c21865c4SKonstantin Aladyshev 
1659c21865c4SKonstantin Aladyshev /**
1660c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1661c21865c4SKonstantin Aladyshev  *
1662ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1663491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1664491d8ee7SSantosh Puranik  *
1665265c1602SJohnathan Mantey  * @return Integer error code.
1666491d8ee7SSantosh Puranik  */
1667ac106bf6SEd Tanous inline void
1668ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1669cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1670491d8ee7SSantosh Puranik {
1671c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1672c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1673944ffaf9SJohnathan Mantey 
1674c21865c4SKonstantin Aladyshev     if (!bootSource)
1675491d8ee7SSantosh Puranik     {
1676c21865c4SKonstantin Aladyshev         return;
1677c21865c4SKonstantin Aladyshev     }
1678c21865c4SKonstantin Aladyshev 
1679491d8ee7SSantosh Puranik     // Source target specified
168062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1681491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1682ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1683ac106bf6SEd Tanous                              bootModeStr) != 0)
1684491d8ee7SSantosh Puranik     {
168562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
168662598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
168762598e31SEd Tanous             *bootSource);
1688ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1689491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1690491d8ee7SSantosh Puranik         return;
1691491d8ee7SSantosh Puranik     }
1692491d8ee7SSantosh Puranik 
1693944ffaf9SJohnathan Mantey     // Act on validated parameters
169462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
169562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1696944ffaf9SJohnathan Mantey 
1697e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1698e93abac6SGinu George                     "xyz.openbmc_project.Settings",
169987c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
170087c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
170187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1702e93abac6SGinu George                     bootSourceStr);
1703e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1704e93abac6SGinu George                     "xyz.openbmc_project.Settings",
170587c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
170687c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
170787c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1708e93abac6SGinu George                     bootModeStr);
1709cd9a4666SKonstantin Aladyshev }
1710944ffaf9SJohnathan Mantey 
1711cd9a4666SKonstantin Aladyshev /**
1712c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1713491d8ee7SSantosh Puranik  *
1714ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1715491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1716cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1717491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1718491d8ee7SSantosh Puranik  *
1719265c1602SJohnathan Mantey  * @return Integer error code.
1720491d8ee7SSantosh Puranik  */
1721c21865c4SKonstantin Aladyshev 
1722ac106bf6SEd Tanous inline void
1723ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1724c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1725c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1726c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1727491d8ee7SSantosh Puranik {
172862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1729491d8ee7SSantosh Puranik 
1730ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1731ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1732ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1733491d8ee7SSantosh Puranik }
1734491d8ee7SSantosh Puranik 
1735c6a620f2SGeorge Liu /**
173698e386ecSGunnar Mills  * @brief Sets AssetTag
173798e386ecSGunnar Mills  *
1738ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
173998e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
174098e386ecSGunnar Mills  *
174198e386ecSGunnar Mills  * @return None.
174298e386ecSGunnar Mills  */
1743ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
174498e386ecSGunnar Mills                         const std::string& assetTag)
174598e386ecSGunnar Mills {
1746e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1747e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1748e99073f5SGeorge Liu     dbus::utility::getSubTree(
1749e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1750ac106bf6SEd Tanous         [asyncResp,
1751e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1752b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
175398e386ecSGunnar Mills             if (ec)
175498e386ecSGunnar Mills             {
175562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1756ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
175798e386ecSGunnar Mills                 return;
175898e386ecSGunnar Mills             }
175926f6976fSEd Tanous             if (subtree.empty())
176098e386ecSGunnar Mills             {
176162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1762ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
176398e386ecSGunnar Mills                 return;
176498e386ecSGunnar Mills             }
176598e386ecSGunnar Mills             // Assume only 1 system D-Bus object
176698e386ecSGunnar Mills             // Throw an error if there is more than 1
176798e386ecSGunnar Mills             if (subtree.size() > 1)
176898e386ecSGunnar Mills             {
176962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1770ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
177198e386ecSGunnar Mills                 return;
177298e386ecSGunnar Mills             }
177398e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
177498e386ecSGunnar Mills             {
177562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1776ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
177798e386ecSGunnar Mills                 return;
177898e386ecSGunnar Mills             }
177998e386ecSGunnar Mills 
178098e386ecSGunnar Mills             const std::string& path = subtree[0].first;
178198e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
178298e386ecSGunnar Mills 
178398e386ecSGunnar Mills             if (service.empty())
178498e386ecSGunnar Mills             {
178562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1786ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
178798e386ecSGunnar Mills                 return;
178898e386ecSGunnar Mills             }
178998e386ecSGunnar Mills 
1790e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
179187c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1792e93abac6SGinu George                             "AssetTag", assetTag);
1793e99073f5SGeorge Liu         });
179498e386ecSGunnar Mills }
179598e386ecSGunnar Mills 
179698e386ecSGunnar Mills /**
17979dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
17989dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
17999dcfe8c1SAlbert Zhang  *
18009dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18019dcfe8c1SAlbert Zhang  * stopBootOnFault
18029dcfe8c1SAlbert Zhang  *
18039dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18049dcfe8c1SAlbert Zhang  */
18059dcfe8c1SAlbert Zhang inline std::optional<bool>
18069dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
18079dcfe8c1SAlbert Zhang {
18089dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18099dcfe8c1SAlbert Zhang     {
18109dcfe8c1SAlbert Zhang         return true;
18119dcfe8c1SAlbert Zhang     }
18129dcfe8c1SAlbert Zhang 
18139dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18149dcfe8c1SAlbert Zhang     {
18159dcfe8c1SAlbert Zhang         return false;
18169dcfe8c1SAlbert Zhang     }
18179dcfe8c1SAlbert Zhang 
18189dcfe8c1SAlbert Zhang     return std::nullopt;
18199dcfe8c1SAlbert Zhang }
18209dcfe8c1SAlbert Zhang 
18219dcfe8c1SAlbert Zhang /**
18229dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18239dcfe8c1SAlbert Zhang  *
1824fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18259dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18269dcfe8c1SAlbert Zhang  *
18279dcfe8c1SAlbert Zhang  * @return None.
18289dcfe8c1SAlbert Zhang  */
1829fc3edfddSEd Tanous inline void
1830fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18319dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18329dcfe8c1SAlbert Zhang {
183362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18349dcfe8c1SAlbert Zhang 
18359dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18369dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18379dcfe8c1SAlbert Zhang     {
183862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
183962598e31SEd Tanous                          stopBootOnFault);
1840fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18419dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18429dcfe8c1SAlbert Zhang         return;
18439dcfe8c1SAlbert Zhang     }
18449dcfe8c1SAlbert Zhang 
1845e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1846e93abac6SGinu George                     "xyz.openbmc_project.Settings",
184787c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
184887c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1849fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1850e93abac6SGinu George                     *stopBootEnabled);
18519dcfe8c1SAlbert Zhang }
18529dcfe8c1SAlbert Zhang 
18539dcfe8c1SAlbert Zhang /**
185469f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
185569f35306SGunnar Mills  *
1856ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
185769f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
185869f35306SGunnar Mills  *
185969f35306SGunnar Mills  * @return None.
186069f35306SGunnar Mills  */
1861ac106bf6SEd Tanous inline void
1862ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1863f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
186469f35306SGunnar Mills {
186562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
186669f35306SGunnar Mills 
186769f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1868543f4400SEd Tanous     bool autoRebootEnabled = false;
186969f35306SGunnar Mills 
187069f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
187169f35306SGunnar Mills     {
187269f35306SGunnar Mills         autoRebootEnabled = false;
187369f35306SGunnar Mills     }
187469f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
187569f35306SGunnar Mills     {
187669f35306SGunnar Mills         autoRebootEnabled = true;
187769f35306SGunnar Mills     }
187869f35306SGunnar Mills     else
187969f35306SGunnar Mills     {
188062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
188162598e31SEd Tanous                          automaticRetryConfig);
1882ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
188369f35306SGunnar Mills                                          "AutomaticRetryConfig");
188469f35306SGunnar Mills         return;
188569f35306SGunnar Mills     }
188669f35306SGunnar Mills 
1887e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1888e93abac6SGinu George                     "xyz.openbmc_project.Settings",
188987c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
189087c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/auto_reboot"),
189187c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1892e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
189369f35306SGunnar Mills }
189469f35306SGunnar Mills 
18958d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
18968d69c668SEd Tanous {
18978d69c668SEd Tanous     if (policy == "AlwaysOn")
18988d69c668SEd Tanous     {
18998d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19008d69c668SEd Tanous     }
19018d69c668SEd Tanous     if (policy == "AlwaysOff")
19028d69c668SEd Tanous     {
19038d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19048d69c668SEd Tanous     }
19058d69c668SEd Tanous     if (policy == "LastState")
19068d69c668SEd Tanous     {
19078d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19088d69c668SEd Tanous     }
19098d69c668SEd Tanous     return "";
19108d69c668SEd Tanous }
19118d69c668SEd Tanous 
191269f35306SGunnar Mills /**
1913c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1914c6a620f2SGeorge Liu  *
1915ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1916c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1917c6a620f2SGeorge Liu  *
1918c6a620f2SGeorge Liu  * @return None.
1919c6a620f2SGeorge Liu  */
19208d1b46d7Szhanghch05 inline void
1921ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19228d69c668SEd Tanous                           std::string_view policy)
1923c6a620f2SGeorge Liu {
192462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1925c6a620f2SGeorge Liu 
19268d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1927c6a620f2SGeorge Liu 
19288d69c668SEd Tanous     if (powerRestorePolicy.empty())
1929c6a620f2SGeorge Liu     {
1930ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19314e69c904SGunnar Mills                                          "PowerRestorePolicy");
1932c6a620f2SGeorge Liu         return;
1933c6a620f2SGeorge Liu     }
1934c6a620f2SGeorge Liu 
193587c44966SAsmitha Karunanithi     setDbusProperty(
1936e93abac6SGinu George         asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
193787c44966SAsmitha Karunanithi         sdbusplus::message::object_path(
193887c44966SAsmitha Karunanithi             "/xyz/openbmc_project/control/host0/power_restore_policy"),
19399ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1940e93abac6SGinu George         powerRestorePolicy);
1941c6a620f2SGeorge Liu }
1942c6a620f2SGeorge Liu 
1943a6349918SAppaRao Puli /**
1944a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1945a6349918SAppaRao Puli  *
194625b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
194725b54dbaSEd Tanous  * calls.
1948a6349918SAppaRao Puli  *
1949a6349918SAppaRao Puli  * @return None.
1950a6349918SAppaRao Puli  */
195125b54dbaSEd Tanous inline void
195225b54dbaSEd Tanous     getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1953a6349918SAppaRao Puli {
195462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1955deae6a78SEd Tanous     dbus::utility::getAllProperties(
1956deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1957deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Attributes",
1958ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1959b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1960b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1961bd79bce8SPatrick Williams                 asyncResp->res
1962bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1963ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
19641d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1965bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
1966bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
196750626f4fSJames Feist 
1968a6349918SAppaRao Puli             if (ec)
1969a6349918SAppaRao Puli             {
197062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1971b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1972539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
1973539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
1974a6349918SAppaRao Puli                 return;
1975a6349918SAppaRao Puli             }
1976a6349918SAppaRao Puli 
1977a6349918SAppaRao Puli             const bool* provState = nullptr;
1978a6349918SAppaRao Puli             const bool* lockState = nullptr;
1979bc1d29deSKrzysztof Grobelny 
1980bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
1981bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1982bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
1983bc1d29deSKrzysztof Grobelny 
1984bc1d29deSKrzysztof Grobelny             if (!success)
1985a6349918SAppaRao Puli             {
1986ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1987bc1d29deSKrzysztof Grobelny                 return;
1988a6349918SAppaRao Puli             }
1989a6349918SAppaRao Puli 
1990a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1991a6349918SAppaRao Puli             {
199262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
1993ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1994a6349918SAppaRao Puli                 return;
1995a6349918SAppaRao Puli             }
1996a6349918SAppaRao Puli 
199725b54dbaSEd Tanous             if (*provState)
1998a6349918SAppaRao Puli             {
199925b54dbaSEd Tanous                 if (*lockState)
2000a6349918SAppaRao Puli                 {
2001539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2002539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2003a6349918SAppaRao Puli                 }
2004a6349918SAppaRao Puli                 else
2005a6349918SAppaRao Puli                 {
2006539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2007539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2008a6349918SAppaRao Puli                 }
2009a6349918SAppaRao Puli             }
2010a6349918SAppaRao Puli             else
2011a6349918SAppaRao Puli             {
2012539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2013539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2014a6349918SAppaRao Puli             }
2015bc1d29deSKrzysztof Grobelny         });
2016a6349918SAppaRao Puli }
2017a6349918SAppaRao Puli 
2018491d8ee7SSantosh Puranik /**
20196b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20203a2d0424SChris Cain  *
20216b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20223a2d0424SChris Cain  *
20236b9ac4f2SChris Cain  * @return PowerMode enum
20243a2d0424SChris Cain  */
20256b9ac4f2SChris Cain inline computer_system::PowerMode
20266b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
20273a2d0424SChris Cain {
2028b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2029b6655101SChris Cain 
20306b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20313a2d0424SChris Cain     {
20326b9ac4f2SChris Cain         return PowerMode::Static;
20333a2d0424SChris Cain     }
20346b9ac4f2SChris Cain     if (modeString ==
20350fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20363a2d0424SChris Cain     {
20376b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20383a2d0424SChris Cain     }
20396b9ac4f2SChris Cain     if (modeString ==
20400fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20413a2d0424SChris Cain     {
20426b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2043b6655101SChris Cain     }
20446b9ac4f2SChris Cain     if (modeString ==
2045b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2046b6655101SChris Cain     {
20476b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2048b6655101SChris Cain     }
20496b9ac4f2SChris Cain     if (modeString ==
2050b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2051b6655101SChris Cain     {
20526b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2053b6655101SChris Cain     }
20546b9ac4f2SChris Cain     if (modeString ==
2055b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2056b6655101SChris Cain     {
20576b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20583a2d0424SChris Cain     }
20596b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20603a2d0424SChris Cain     {
20616b9ac4f2SChris Cain         return PowerMode::OEM;
20626b9ac4f2SChris Cain     }
20636b9ac4f2SChris Cain     // Any other values would be invalid
20646b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20656b9ac4f2SChris Cain     return PowerMode::Invalid;
20666b9ac4f2SChris Cain }
20676b9ac4f2SChris Cain 
20686b9ac4f2SChris Cain inline void
20696b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20706b9ac4f2SChris Cain                       const boost::system::error_code& ec,
20716b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
20726b9ac4f2SChris Cain {
20736b9ac4f2SChris Cain     if (ec)
20746b9ac4f2SChris Cain     {
20756b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
20766b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20776b9ac4f2SChris Cain         return;
20786b9ac4f2SChris Cain     }
20796b9ac4f2SChris Cain 
20806b9ac4f2SChris Cain     std::string powerMode;
20816b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
20826b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
20836b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
20846b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
20856b9ac4f2SChris Cain 
20866b9ac4f2SChris Cain     if (!success)
20876b9ac4f2SChris Cain     {
20886b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20896b9ac4f2SChris Cain         return;
20906b9ac4f2SChris Cain     }
20916b9ac4f2SChris Cain 
20926b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
20936b9ac4f2SChris Cain     if (allowedModes == nullptr)
20946b9ac4f2SChris Cain     {
20956b9ac4f2SChris Cain         modeList.emplace_back("Static");
20966b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
20976b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
20983a2d0424SChris Cain     }
20993a2d0424SChris Cain     else
21003a2d0424SChris Cain     {
21016b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21026b9ac4f2SChris Cain         {
21036b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21046b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21056b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21066b9ac4f2SChris Cain             {
2107ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21086b9ac4f2SChris Cain                 continue;
21096b9ac4f2SChris Cain             }
21106b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21113a2d0424SChris Cain         }
21123a2d0424SChris Cain     }
21136b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21143a2d0424SChris Cain 
21156b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21166b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21176b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21186b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21196b9ac4f2SChris Cain     {
21206b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21216b9ac4f2SChris Cain         return;
21226b9ac4f2SChris Cain     }
21236b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21246b9ac4f2SChris Cain }
21253a2d0424SChris Cain /**
21263a2d0424SChris Cain  * @brief Retrieves system power mode
21273a2d0424SChris Cain  *
2128ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21293a2d0424SChris Cain  *
21303a2d0424SChris Cain  * @return None.
21313a2d0424SChris Cain  */
2132ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21333a2d0424SChris Cain {
213462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21353a2d0424SChris Cain 
21363a2d0424SChris Cain     // Get Power Mode object path:
2137e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2138e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2139e99073f5SGeorge Liu     dbus::utility::getSubTree(
2140e99073f5SGeorge Liu         "/", 0, interfaces,
2141ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2142b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21433a2d0424SChris Cain             if (ec)
21443a2d0424SChris Cain             {
2145bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2146bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
21473a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
21483a2d0424SChris Cain                 // error occurs
21493a2d0424SChris Cain                 return;
21503a2d0424SChris Cain             }
21513a2d0424SChris Cain             if (subtree.empty())
21523a2d0424SChris Cain             {
21533a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
21543a2d0424SChris Cain                 // if there is no instance found
21553a2d0424SChris Cain                 return;
21563a2d0424SChris Cain             }
21573a2d0424SChris Cain             if (subtree.size() > 1)
21583a2d0424SChris Cain             {
21593a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21603a2d0424SChris Cain                 // error
216162598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
216262598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
216362598e31SEd Tanous                     subtree.size());
2164ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21653a2d0424SChris Cain                 return;
21663a2d0424SChris Cain             }
21673a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21683a2d0424SChris Cain             {
216962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2170ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21713a2d0424SChris Cain                 return;
21723a2d0424SChris Cain             }
21733a2d0424SChris Cain             const std::string& path = subtree[0].first;
21743a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21753a2d0424SChris Cain             if (service.empty())
21763a2d0424SChris Cain             {
217762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2178ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21793a2d0424SChris Cain                 return;
21803a2d0424SChris Cain             }
21816b9ac4f2SChris Cain 
21826b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
2183deae6a78SEd Tanous             dbus::utility::getAllProperties(
21841e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
21856b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2186bd79bce8SPatrick Williams                 [asyncResp](
2187bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
21886b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
21896b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
21901e1e598dSJonathan Doman                 });
2191e99073f5SGeorge Liu         });
21923a2d0424SChris Cain }
21933a2d0424SChris Cain 
21943a2d0424SChris Cain /**
21953a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21963a2d0424SChris Cain  * name associated with that string
21973a2d0424SChris Cain  *
2198ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2199b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22003a2d0424SChris Cain  *
22013a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22023a2d0424SChris Cain  */
22033a2d0424SChris Cain inline std::string
2204ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2205b6655101SChris Cain                       const nlohmann::json& modeValue)
22063a2d0424SChris Cain {
2207b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22083a2d0424SChris Cain     std::string mode;
22093a2d0424SChris Cain 
2210b6655101SChris Cain     if (modeValue == PowerMode::Static)
22113a2d0424SChris Cain     {
22123a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22133a2d0424SChris Cain     }
2214b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22153a2d0424SChris Cain     {
22160fda0f12SGeorge Liu         mode =
22170fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22183a2d0424SChris Cain     }
2219b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22203a2d0424SChris Cain     {
22213a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22223a2d0424SChris Cain     }
2223b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2224b6655101SChris Cain     {
2225b6655101SChris Cain         mode =
2226b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2227b6655101SChris Cain     }
2228b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2229b6655101SChris Cain     {
2230b6655101SChris Cain         mode =
2231b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2232b6655101SChris Cain     }
2233b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2234b6655101SChris Cain     {
2235b6655101SChris Cain         mode =
2236b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2237b6655101SChris Cain     }
22383a2d0424SChris Cain     else
22393a2d0424SChris Cain     {
2240b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2241ac106bf6SEd Tanous                                          "PowerMode");
22423a2d0424SChris Cain     }
22433a2d0424SChris Cain     return mode;
22443a2d0424SChris Cain }
22453a2d0424SChris Cain 
22463a2d0424SChris Cain /**
22473a2d0424SChris Cain  * @brief Sets system power mode.
22483a2d0424SChris Cain  *
2249ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22503a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22513a2d0424SChris Cain  *
22523a2d0424SChris Cain  * @return None.
22533a2d0424SChris Cain  */
2254ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22553a2d0424SChris Cain                          const std::string& pmode)
22563a2d0424SChris Cain {
225762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22583a2d0424SChris Cain 
2259ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22603a2d0424SChris Cain     if (powerMode.empty())
22613a2d0424SChris Cain     {
22623a2d0424SChris Cain         return;
22633a2d0424SChris Cain     }
22643a2d0424SChris Cain 
22653a2d0424SChris Cain     // Get Power Mode object path:
2266e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2267e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2268e99073f5SGeorge Liu     dbus::utility::getSubTree(
2269e99073f5SGeorge Liu         "/", 0, interfaces,
2270ac106bf6SEd Tanous         [asyncResp,
2271e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2272b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22733a2d0424SChris Cain             if (ec)
22743a2d0424SChris Cain             {
2275bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2276bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
22773a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2278ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22793a2d0424SChris Cain                 return;
22803a2d0424SChris Cain             }
22813a2d0424SChris Cain             if (subtree.empty())
22823a2d0424SChris Cain             {
22833a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2284ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22853a2d0424SChris Cain                                            "PowerMode");
22863a2d0424SChris Cain                 return;
22873a2d0424SChris Cain             }
22883a2d0424SChris Cain             if (subtree.size() > 1)
22893a2d0424SChris Cain             {
22903a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22913a2d0424SChris Cain                 // error
229262598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
229362598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
229462598e31SEd Tanous                     subtree.size());
2295ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22963a2d0424SChris Cain                 return;
22973a2d0424SChris Cain             }
22983a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22993a2d0424SChris Cain             {
230062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2301ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23023a2d0424SChris Cain                 return;
23033a2d0424SChris Cain             }
23043a2d0424SChris Cain             const std::string& path = subtree[0].first;
23053a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
23063a2d0424SChris Cain             if (service.empty())
23073a2d0424SChris Cain             {
230862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2309ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23103a2d0424SChris Cain                 return;
23113a2d0424SChris Cain             }
23123a2d0424SChris Cain 
231362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23143a2d0424SChris Cain 
23153a2d0424SChris Cain             // Set the Power Mode property
2316e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2317bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2318bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2319e99073f5SGeorge Liu         });
23203a2d0424SChris Cain }
23213a2d0424SChris Cain 
23223a2d0424SChris Cain /**
232351709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
232451709ffdSYong Li  *
232551709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
232651709ffdSYong Li  *
232751709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
232851709ffdSYong Li  * translation cannot be done, returns an empty string.
232951709ffdSYong Li  */
233023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
233151709ffdSYong Li {
233251709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
233351709ffdSYong Li     {
233451709ffdSYong Li         return "None";
233551709ffdSYong Li     }
23363174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
233751709ffdSYong Li     {
233851709ffdSYong Li         return "ResetSystem";
233951709ffdSYong Li     }
23403174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
234151709ffdSYong Li     {
234251709ffdSYong Li         return "PowerDown";
234351709ffdSYong Li     }
23443174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
234551709ffdSYong Li     {
234651709ffdSYong Li         return "PowerCycle";
234751709ffdSYong Li     }
234851709ffdSYong Li 
234951709ffdSYong Li     return "";
235051709ffdSYong Li }
235151709ffdSYong Li 
235251709ffdSYong Li /**
2353c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2354c45f0082SYong Li  *
2355c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2356c45f0082SYong Li  *
2357c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2358c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2359c45f0082SYong Li  */
2360c45f0082SYong Li 
236123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2362c45f0082SYong Li {
2363c45f0082SYong Li     if (rfAction == "None")
2364c45f0082SYong Li     {
2365c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2366c45f0082SYong Li     }
23673174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2368c45f0082SYong Li     {
2369c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2370c45f0082SYong Li     }
23713174e4dfSEd Tanous     if (rfAction == "PowerDown")
2372c45f0082SYong Li     {
2373c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2374c45f0082SYong Li     }
23753174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2376c45f0082SYong Li     {
2377c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2378c45f0082SYong Li     }
2379c45f0082SYong Li 
2380c45f0082SYong Li     return "";
2381c45f0082SYong Li }
2382c45f0082SYong Li 
2383c45f0082SYong Li /**
238451709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
238551709ffdSYong Li  *
2386ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
238751709ffdSYong Li  *
238851709ffdSYong Li  * @return None.
238951709ffdSYong Li  */
23908d1b46d7Szhanghch05 inline void
2391ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
239251709ffdSYong Li {
239362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2394deae6a78SEd Tanous     dbus::utility::getAllProperties(
2395deae6a78SEd Tanous         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2396bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2397ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2398b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
239951709ffdSYong Li             if (ec)
240051709ffdSYong Li             {
240151709ffdSYong Li                 // watchdog service is stopped
240262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
240351709ffdSYong Li                 return;
240451709ffdSYong Li             }
240551709ffdSYong Li 
240662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
240751709ffdSYong Li 
240851709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2409ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
241051709ffdSYong Li 
241151709ffdSYong Li             // watchdog service is running/enabled
2412539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
241351709ffdSYong Li 
2414bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2415bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
241651709ffdSYong Li 
2417bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2418bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2419bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2420bc1d29deSKrzysztof Grobelny 
2421bc1d29deSKrzysztof Grobelny             if (!success)
242251709ffdSYong Li             {
2423ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2424601af5edSChicago Duan                 return;
242551709ffdSYong Li             }
242651709ffdSYong Li 
2427bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
242851709ffdSYong Li             {
2429bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
243051709ffdSYong Li             }
243151709ffdSYong Li 
2432bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2433bc1d29deSKrzysztof Grobelny             {
2434bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
243551709ffdSYong Li                 if (action.empty())
243651709ffdSYong Li                 {
2437ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2438601af5edSChicago Duan                     return;
243951709ffdSYong Li                 }
244051709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
244151709ffdSYong Li             }
2442bc1d29deSKrzysztof Grobelny         });
244351709ffdSYong Li }
244451709ffdSYong Li 
244551709ffdSYong Li /**
2446c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2447c45f0082SYong Li  *
2448ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2449c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2450c45f0082SYong Li  *                       RF request.
2451c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2452c45f0082SYong Li  *
2453c45f0082SYong Li  * @return None.
2454c45f0082SYong Li  */
2455ac106bf6SEd Tanous inline void
2456ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2457c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2458c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2459c45f0082SYong Li {
246062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2461c45f0082SYong Li 
2462c45f0082SYong Li     if (wdtTimeOutAction)
2463c45f0082SYong Li     {
2464c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2465c45f0082SYong Li         // check if TimeOut Action is Valid
2466c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2467c45f0082SYong Li         {
246862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
246962598e31SEd Tanous                              *wdtTimeOutAction);
2470ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2471c45f0082SYong Li                                              "TimeoutAction");
2472c45f0082SYong Li             return;
2473c45f0082SYong Li         }
2474c45f0082SYong Li 
2475e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2476e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
247787c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
247887c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
24799ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2480e93abac6SGinu George                         wdtTimeOutActStr);
2481c45f0082SYong Li     }
2482c45f0082SYong Li 
2483c45f0082SYong Li     if (wdtEnable)
2484c45f0082SYong Li     {
2485e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2486e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
248787c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
248887c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
248987c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2490e93abac6SGinu George                         *wdtEnable);
2491c45f0082SYong Li     }
2492c45f0082SYong Li }
2493c45f0082SYong Li 
249437bbf98cSChris Cain /**
249537bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
249637bbf98cSChris Cain  *
2497ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
249837bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
249937bbf98cSChris Cain  *
250037bbf98cSChris Cain  * @return true if successful
250137bbf98cSChris Cain  */
25021e5b7c88SJiaqing Zhao inline bool
2503ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25041e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
250537bbf98cSChris Cain {
2506bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2507bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2508bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2509bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2510bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2511bc1d29deSKrzysztof Grobelny 
2512bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2513bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25142661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25152661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25162661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2517bc1d29deSKrzysztof Grobelny 
2518bc1d29deSKrzysztof Grobelny     if (!success)
251937bbf98cSChris Cain     {
252037bbf98cSChris Cain         return false;
252137bbf98cSChris Cain     }
2522bc1d29deSKrzysztof Grobelny 
2523bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
252437bbf98cSChris Cain     {
2525ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
252637bbf98cSChris Cain     }
2527bc1d29deSKrzysztof Grobelny 
2528bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
252937bbf98cSChris Cain     {
2530ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2531bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
253237bbf98cSChris Cain     }
2533bc1d29deSKrzysztof Grobelny 
2534bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2535bc1d29deSKrzysztof Grobelny     {
2536bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2537ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
253837bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
253937bbf98cSChris Cain                 .count();
254037bbf98cSChris Cain     }
2541bc1d29deSKrzysztof Grobelny 
2542bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
254337bbf98cSChris Cain     {
2544ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2545bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
254637bbf98cSChris Cain     }
2547bc1d29deSKrzysztof Grobelny 
2548bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
254937bbf98cSChris Cain     {
2550bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2551ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
255237bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
255337bbf98cSChris Cain                 .count();
255437bbf98cSChris Cain     }
255537bbf98cSChris Cain 
255637bbf98cSChris Cain     return true;
255737bbf98cSChris Cain }
255837bbf98cSChris Cain 
255937bbf98cSChris Cain /**
256037bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
256137bbf98cSChris Cain  *
2562ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
256337bbf98cSChris Cain  *
256437bbf98cSChris Cain  * @return None.
256537bbf98cSChris Cain  */
2566ac106bf6SEd Tanous inline void
2567ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
256837bbf98cSChris Cain {
256962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
257037bbf98cSChris Cain 
257137bbf98cSChris Cain     // Get IdlePowerSaver object path:
2572e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2573e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2574e99073f5SGeorge Liu     dbus::utility::getSubTree(
2575e99073f5SGeorge Liu         "/", 0, interfaces,
2576ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2577b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
257837bbf98cSChris Cain             if (ec)
257937bbf98cSChris Cain             {
2580b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
258162598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
258262598e31SEd Tanous                     ec);
2583ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
258437bbf98cSChris Cain                 return;
258537bbf98cSChris Cain             }
258637bbf98cSChris Cain             if (subtree.empty())
258737bbf98cSChris Cain             {
258837bbf98cSChris Cain                 // This is an optional interface so just return
258937bbf98cSChris Cain                 // if there is no instance found
259062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
259137bbf98cSChris Cain                 return;
259237bbf98cSChris Cain             }
259337bbf98cSChris Cain             if (subtree.size() > 1)
259437bbf98cSChris Cain             {
259537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
259637bbf98cSChris Cain                 // is an error
259762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
259862598e31SEd Tanous                                  "Power.IdlePowerSaver objects: {}",
259962598e31SEd Tanous                                  subtree.size());
2600ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
260137bbf98cSChris Cain                 return;
260237bbf98cSChris Cain             }
260337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
260437bbf98cSChris Cain             {
260562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2606ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
260737bbf98cSChris Cain                 return;
260837bbf98cSChris Cain             }
260937bbf98cSChris Cain             const std::string& path = subtree[0].first;
261037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
261137bbf98cSChris Cain             if (service.empty())
261237bbf98cSChris Cain             {
261362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2614ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261537bbf98cSChris Cain                 return;
261637bbf98cSChris Cain             }
261737bbf98cSChris Cain 
261837bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2619deae6a78SEd Tanous             dbus::utility::getAllProperties(
2620bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2621bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2622bd79bce8SPatrick Williams                 [asyncResp](
2623bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
26241e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
26258a592810SEd Tanous                     if (ec2)
262637bbf98cSChris Cain                     {
262762598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2628bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2629bd79bce8SPatrick Williams                             ec2);
2630ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
263137bbf98cSChris Cain                         return;
263237bbf98cSChris Cain                     }
263337bbf98cSChris Cain 
2634ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
263537bbf98cSChris Cain                     {
2636ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
263737bbf98cSChris Cain                         return;
263837bbf98cSChris Cain                     }
2639bc1d29deSKrzysztof Grobelny                 });
2640e99073f5SGeorge Liu         });
264137bbf98cSChris Cain 
264262598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
264337bbf98cSChris Cain }
264437bbf98cSChris Cain 
264537bbf98cSChris Cain /**
264637bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
264737bbf98cSChris Cain  *
2648ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
264937bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
265037bbf98cSChris Cain  *                       RF request.
265137bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
265237bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
265337bbf98cSChris Cain  * before entering idle state.
265437bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
265537bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
265637bbf98cSChris Cain  * before exiting idle state
265737bbf98cSChris Cain  *
265837bbf98cSChris Cain  * @return None.
265937bbf98cSChris Cain  */
2660bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2661bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
266237bbf98cSChris Cain     const std::optional<bool> ipsEnable,
266337bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
266437bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
266537bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
266637bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
266737bbf98cSChris Cain {
266862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
266937bbf98cSChris Cain 
267037bbf98cSChris Cain     // Get IdlePowerSaver object path:
2671e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2672e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2673e99073f5SGeorge Liu     dbus::utility::getSubTree(
2674e99073f5SGeorge Liu         "/", 0, interfaces,
2675ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2676e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2677b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
267837bbf98cSChris Cain             if (ec)
267937bbf98cSChris Cain             {
2680b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
268162598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
268262598e31SEd Tanous                     ec);
2683ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
268437bbf98cSChris Cain                 return;
268537bbf98cSChris Cain             }
268637bbf98cSChris Cain             if (subtree.empty())
268737bbf98cSChris Cain             {
268837bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2689ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
269037bbf98cSChris Cain                                            "IdlePowerSaver");
269137bbf98cSChris Cain                 return;
269237bbf98cSChris Cain             }
269337bbf98cSChris Cain             if (subtree.size() > 1)
269437bbf98cSChris Cain             {
269537bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
269637bbf98cSChris Cain                 // is an error
269762598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
269862598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
269962598e31SEd Tanous                     subtree.size());
2700ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
270137bbf98cSChris Cain                 return;
270237bbf98cSChris Cain             }
270337bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
270437bbf98cSChris Cain             {
270562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2706ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
270737bbf98cSChris Cain                 return;
270837bbf98cSChris Cain             }
270937bbf98cSChris Cain             const std::string& path = subtree[0].first;
271037bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
271137bbf98cSChris Cain             if (service.empty())
271237bbf98cSChris Cain             {
271362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2714ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271537bbf98cSChris Cain                 return;
271637bbf98cSChris Cain             }
271737bbf98cSChris Cain 
271837bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
271937bbf98cSChris Cain             // need to be updated
272037bbf98cSChris Cain 
272137bbf98cSChris Cain             if (ipsEnable)
272237bbf98cSChris Cain             {
2723bd79bce8SPatrick Williams                 setDbusProperty(
2724bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
272587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2726e93abac6SGinu George                     "Enabled", *ipsEnable);
272737bbf98cSChris Cain             }
272837bbf98cSChris Cain             if (ipsEnterUtil)
272937bbf98cSChris Cain             {
2730bd79bce8SPatrick Williams                 setDbusProperty(
2731bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2732e93abac6SGinu George                     service, path,
27339ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2734e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
273537bbf98cSChris Cain             }
273637bbf98cSChris Cain             if (ipsEnterTime)
273737bbf98cSChris Cain             {
273837bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
273937bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2740bd79bce8SPatrick Williams                 setDbusProperty(
2741bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2742bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2743e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
274437bbf98cSChris Cain             }
274537bbf98cSChris Cain             if (ipsExitUtil)
274637bbf98cSChris Cain             {
2747bd79bce8SPatrick Williams                 setDbusProperty(
2748bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2749bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2750e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
275137bbf98cSChris Cain             }
275237bbf98cSChris Cain             if (ipsExitTime)
275337bbf98cSChris Cain             {
275437bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
275537bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2756bd79bce8SPatrick Williams                 setDbusProperty(
2757bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2758bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2759e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
276037bbf98cSChris Cain             }
2761e99073f5SGeorge Liu         });
276237bbf98cSChris Cain 
276362598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
276437bbf98cSChris Cain }
276537bbf98cSChris Cain 
2766c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2767dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2768dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2769dd60b9edSEd Tanous {
2770dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2771dd60b9edSEd Tanous     {
2772dd60b9edSEd Tanous         return;
2773dd60b9edSEd Tanous     }
2774dd60b9edSEd Tanous     asyncResp->res.addHeader(
2775dd60b9edSEd Tanous         boost::beast::http::field::link,
2776dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2777dd60b9edSEd Tanous }
2778dd60b9edSEd Tanous 
2779c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2780c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2781c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27821abe55efSEd Tanous {
27833ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2784f4c99e70SEd Tanous     {
2785f4c99e70SEd Tanous         return;
2786f4c99e70SEd Tanous     }
2787dd60b9edSEd Tanous 
2788dd60b9edSEd Tanous     asyncResp->res.addHeader(
2789dd60b9edSEd Tanous         boost::beast::http::field::link,
2790dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
27918d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
27920f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
27938d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
27948d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2795462023adSSunitha Harish 
27967f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27977f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
279825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
27997f3e84a1SEd Tanous     {
28007f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
28017f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28027f3e84a1SEd Tanous         return;
28037f3e84a1SEd Tanous     }
28047f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
28057f3e84a1SEd Tanous     nlohmann::json::object_t system;
2806253f11b8SEd Tanous     system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2807253f11b8SEd Tanous                                               BMCWEB_REDFISH_SYSTEM_URI_NAME);
28087f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
280968896206SGunnar Mills 
281068896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2811462023adSSunitha Harish     {
281262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
281368896206SGunnar Mills         asyncResp->res.jsonValue["Members@odata.count"] = 2;
281468896206SGunnar Mills 
28151476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2816002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
281768896206SGunnar Mills         ifaceArray.emplace_back(std::move(hypervisor));
281868896206SGunnar Mills     }
2819c1e219d5SEd Tanous }
2820c1e219d5SEd Tanous 
2821c1e219d5SEd Tanous /**
28227e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28237e860f15SJohn Edward Broadbent  */
28244f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28257e860f15SJohn Edward Broadbent {
282689492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
282789492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
282889492a15SPatrick Williams     constexpr const char* interfaceName =
28297e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
283089492a15SPatrick Williams     constexpr const char* method = "NMI";
28317e860f15SJohn Edward Broadbent 
28327e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28335e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28347e860f15SJohn Edward Broadbent             if (ec)
28357e860f15SJohn Edward Broadbent             {
283662598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28377e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28387e860f15SJohn Edward Broadbent                 return;
28397e860f15SJohn Edward Broadbent             }
28407e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28417e860f15SJohn Edward Broadbent         },
28427e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28437e860f15SJohn Edward Broadbent }
2844c5b2abe0SLewanczyk, Dawid 
2845c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2846c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
28477f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2848c1e219d5SEd Tanous     const std::string& systemName)
2849c1e219d5SEd Tanous {
28503ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
285145ca1b86SEd Tanous     {
285245ca1b86SEd Tanous         return;
285345ca1b86SEd Tanous     }
2854dd7090e6SGunnar Mills 
2855dd7090e6SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2856dd7090e6SGunnar Mills     {
2857dd7090e6SGunnar Mills         if (systemName == "hypervisor")
2858dd7090e6SGunnar Mills         {
2859dd7090e6SGunnar Mills             handleHypervisorSystemResetPost(req, asyncResp);
2860dd7090e6SGunnar Mills             return;
2861dd7090e6SGunnar Mills         }
2862dd7090e6SGunnar Mills     }
2863dd7090e6SGunnar Mills 
2864253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2865c1e219d5SEd Tanous     {
2866c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2867c1e219d5SEd Tanous                                    systemName);
2868c1e219d5SEd Tanous         return;
2869c1e219d5SEd Tanous     }
287025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28717f3e84a1SEd Tanous     {
28727f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28737f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2874c1e219d5SEd Tanous                                    systemName);
28757f3e84a1SEd Tanous         return;
28767f3e84a1SEd Tanous     }
28779712f8acSEd Tanous     std::string resetType;
2878c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2879cc340dd9SEd Tanous     {
2880cc340dd9SEd Tanous         return;
2881cc340dd9SEd Tanous     }
2882cc340dd9SEd Tanous 
2883d22c8396SJason M. Bills     // Get the command and host vs. chassis
2884cc340dd9SEd Tanous     std::string command;
2885543f4400SEd Tanous     bool hostCommand = true;
2886d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2887cc340dd9SEd Tanous     {
2888cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2889d22c8396SJason M. Bills         hostCommand = true;
2890d22c8396SJason M. Bills     }
2891d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2892d22c8396SJason M. Bills     {
2893d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2894d22c8396SJason M. Bills         hostCommand = false;
2895d22c8396SJason M. Bills     }
2896d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2897d22c8396SJason M. Bills     {
2898c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
289986a0851aSJason M. Bills         hostCommand = true;
2900cc340dd9SEd Tanous     }
29019712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2902cc340dd9SEd Tanous     {
2903cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2904d22c8396SJason M. Bills         hostCommand = true;
2905cc340dd9SEd Tanous     }
29069712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2907cc340dd9SEd Tanous     {
29080fda0f12SGeorge Liu         command =
29090fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2910d22c8396SJason M. Bills         hostCommand = true;
2911d22c8396SJason M. Bills     }
2912d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2913d22c8396SJason M. Bills     {
291486a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
291586a0851aSJason M. Bills         hostCommand = true;
2916cc340dd9SEd Tanous     }
2917bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2918bfd5b826SLakshminarayana R. Kammath     {
2919bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2920bfd5b826SLakshminarayana R. Kammath         return;
2921bfd5b826SLakshminarayana R. Kammath     }
2922cc340dd9SEd Tanous     else
2923cc340dd9SEd Tanous     {
2924c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2925cc340dd9SEd Tanous         return;
2926cc340dd9SEd Tanous     }
2927d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
2928cc340dd9SEd Tanous 
2929d22c8396SJason M. Bills     if (hostCommand)
2930d22c8396SJason M. Bills     {
2931e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
2932d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
2933e93abac6SGinu George                         "RequestedHostTransition", command);
2934cc340dd9SEd Tanous     }
2935d22c8396SJason M. Bills     else
2936d22c8396SJason M. Bills     {
2937e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
2938d02aad39SEd Tanous                         statePath / "chassis0",
2939d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2940e93abac6SGinu George                         "RequestedPowerTransition", command);
2941d22c8396SJason M. Bills     }
2942d22c8396SJason M. Bills }
2943cc340dd9SEd Tanous 
2944c1e219d5SEd Tanous inline void handleComputerSystemHead(
2945dd60b9edSEd Tanous     App& app, const crow::Request& req,
29467f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29477f3e84a1SEd Tanous     const std::string& /*systemName*/)
2948dd60b9edSEd Tanous {
2949dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2950dd60b9edSEd Tanous     {
2951dd60b9edSEd Tanous         return;
2952dd60b9edSEd Tanous     }
2953dd60b9edSEd Tanous 
2954dd60b9edSEd Tanous     asyncResp->res.addHeader(
2955dd60b9edSEd Tanous         boost::beast::http::field::link,
2956dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2957dd60b9edSEd Tanous }
2958dd60b9edSEd Tanous 
29595c3e9272SAbhishek Patel inline void afterPortRequest(
29605c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29615c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29625c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29635c3e9272SAbhishek Patel {
29645c3e9272SAbhishek Patel     if (ec)
29655c3e9272SAbhishek Patel     {
2966b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29675c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29685c3e9272SAbhishek Patel         return;
29695c3e9272SAbhishek Patel     }
29705c3e9272SAbhishek Patel     for (const auto& data : socketData)
29715c3e9272SAbhishek Patel     {
29725c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29735c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29745c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29755c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29765c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29775c3e9272SAbhishek Patel         // need to retrieve port number for
29785c3e9272SAbhishek Patel         // obmc-console-ssh service
29795c3e9272SAbhishek Patel         if (protocolName == "SSH")
29805c3e9272SAbhishek Patel         {
29815c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
298281c4e330SEd Tanous                                           const boost::system::error_code& ec1,
29835c3e9272SAbhishek Patel                                           int portNumber) {
29845c3e9272SAbhishek Patel                 if (ec1)
29855c3e9272SAbhishek Patel                 {
2986b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
29875c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
29885c3e9272SAbhishek Patel                     return;
29895c3e9272SAbhishek Patel                 }
29905c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
29915c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
29925c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
29935c3e9272SAbhishek Patel             });
29945c3e9272SAbhishek Patel         }
29955c3e9272SAbhishek Patel     }
29965c3e9272SAbhishek Patel }
2997c1e219d5SEd Tanous 
2998c1e219d5SEd Tanous inline void
2999c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
300022d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3001c1e219d5SEd Tanous                             const std::string& systemName)
3002c1e219d5SEd Tanous {
30033ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
300445ca1b86SEd Tanous     {
300545ca1b86SEd Tanous         return;
300645ca1b86SEd Tanous     }
3007746b56f3SAsmitha Karunanithi 
300825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30097f3e84a1SEd Tanous     {
30107f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30117f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
30127f3e84a1SEd Tanous                                    systemName);
30137f3e84a1SEd Tanous         return;
30147f3e84a1SEd Tanous     }
30157f3e84a1SEd Tanous 
301668896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
301768896206SGunnar Mills     {
3018746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3019746b56f3SAsmitha Karunanithi         {
3020746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3021746b56f3SAsmitha Karunanithi             return;
3022746b56f3SAsmitha Karunanithi         }
302368896206SGunnar Mills     }
3024746b56f3SAsmitha Karunanithi 
3025253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
302622d268cbSEd Tanous     {
302722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
302822d268cbSEd Tanous                                    systemName);
302922d268cbSEd Tanous         return;
303022d268cbSEd Tanous     }
3031dd60b9edSEd Tanous     asyncResp->res.addHeader(
3032dd60b9edSEd Tanous         boost::beast::http::field::link,
3033dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30348d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3035b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
3036253f11b8SEd Tanous     asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3037253f11b8SEd Tanous     asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3038539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3039539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30408d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30418d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3042cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3043dfb2b408SPriyanga Ramasamy         double(0);
3044253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3045253f11b8SEd Tanous         "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
304604a258f4SEd Tanous 
3047253f11b8SEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3048253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3049253f11b8SEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3050253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3051253f11b8SEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3052253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
30533179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3054253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3055253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3056029573d4SEd Tanous 
3057002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3058253f11b8SEd Tanous         boost::urls::format(
3059253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3060253f11b8SEd Tanous             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3061c1e219d5SEd Tanous     asyncResp->res
3062c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3063253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3064253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3065c5b2abe0SLewanczyk, Dawid 
3066253f11b8SEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3067253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3068253f11b8SEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3069253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3070c4bf6374SJason M. Bills 
30711476687dSEd Tanous     nlohmann::json::array_t managedBy;
30721476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3073253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3074253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3075002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3076539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3077539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
30780e8ac5e7SGunnar Mills 
30790e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3080002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3081c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
30821476687dSEd Tanous 
3083c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
30841476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3085c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30861476687dSEd Tanous         "Press ~. to exit console";
30875c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
30885c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
30890e8ac5e7SGunnar Mills 
309025b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
309125b54dbaSEd Tanous     {
30920e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3093002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
309425b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
309525b54dbaSEd Tanous             4;
3096613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3097613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
309825b54dbaSEd Tanous     }
309913451e39SWilly Tu 
3100bd79bce8SPatrick Williams     getMainChassisId(
3101bd79bce8SPatrick Williams         asyncResp, [](const std::string& chassisId,
31028d1b46d7Szhanghch05                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3103b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3104b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3105bd79bce8SPatrick Williams             chassis["@odata.id"] =
3106bd79bce8SPatrick Williams                 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3107002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3108c5d03ff4SJennifer Lee         });
3109a3002228SAppaRao Puli 
311059a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
31119f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3112a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
311351bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
31146c34de48SEd Tanous     getHostState(asyncResp);
3115491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3116978b8803SAndrew Geissler     getBootProgress(asyncResp);
3117b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
311870c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
311970c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
312051709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3121c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
31229dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3123797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3124c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
312525b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
312625b54dbaSEd Tanous     {
3127a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
312825b54dbaSEd Tanous     }
31291981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
31303a2d0424SChris Cain     getPowerMode(asyncResp);
313137bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3132c1e219d5SEd Tanous }
3133550a6bf8SJiaqing Zhao 
3134c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3135c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
313622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3137c1e219d5SEd Tanous     const std::string& systemName)
3138c1e219d5SEd Tanous {
31393ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
314045ca1b86SEd Tanous     {
314145ca1b86SEd Tanous         return;
314245ca1b86SEd Tanous     }
314325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31447f3e84a1SEd Tanous     {
31457f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31467f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31477f3e84a1SEd Tanous                                    systemName);
31487f3e84a1SEd Tanous         return;
31497f3e84a1SEd Tanous     }
3150253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
315122d268cbSEd Tanous     {
315222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
315322d268cbSEd Tanous                                    systemName);
315422d268cbSEd Tanous         return;
315522d268cbSEd Tanous     }
315622d268cbSEd Tanous 
3157dd60b9edSEd Tanous     asyncResp->res.addHeader(
3158dd60b9edSEd Tanous         boost::beast::http::field::link,
3159dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3160dd60b9edSEd Tanous 
31619f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3162cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
316398e386ecSGunnar Mills     std::optional<std::string> assetTag;
3164c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
31653a2d0424SChris Cain     std::optional<std::string> powerMode;
3166550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3167550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3168550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3169550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3170550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3171550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3172797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3173550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
31749dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3175550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3176550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3177550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3178550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3179550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3180550a6bf8SJiaqing Zhao 
3181afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
3182afc474aeSMyung Bae             req, asyncResp->res, //
3183afc474aeSMyung Bae             "AssetTag", assetTag, //
3184afc474aeSMyung Bae             "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3185afc474aeSMyung Bae             "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3186afc474aeSMyung Bae             "Boot/BootSourceOverrideEnabled", bootEnable, //
3187afc474aeSMyung Bae             "Boot/BootSourceOverrideMode", bootType, //
3188afc474aeSMyung Bae             "Boot/BootSourceOverrideTarget", bootSource, //
3189afc474aeSMyung Bae             "Boot/StopBootOnFault", stopBootOnFault, //
3190afc474aeSMyung Bae             "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3191afc474aeSMyung Bae             "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3192afc474aeSMyung Bae             "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3193afc474aeSMyung Bae             "IdlePowerSaver/Enabled", ipsEnable, //
3194afc474aeSMyung Bae             "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3195afc474aeSMyung Bae             "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3196afc474aeSMyung Bae             "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3197afc474aeSMyung Bae             "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3198afc474aeSMyung Bae             "IndicatorLED", indicatorLed, //
3199afc474aeSMyung Bae             "LocationIndicatorActive", locationIndicatorActive, //
3200afc474aeSMyung Bae             "PowerMode", powerMode, //
3201afc474aeSMyung Bae             "PowerRestorePolicy", powerRestorePolicy //
3202afc474aeSMyung Bae             ))
32036617338dSEd Tanous     {
32046617338dSEd Tanous         return;
32056617338dSEd Tanous     }
3206491d8ee7SSantosh Puranik 
32078d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3208c45f0082SYong Li 
320998e386ecSGunnar Mills     if (assetTag)
321098e386ecSGunnar Mills     {
321198e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
321298e386ecSGunnar Mills     }
321398e386ecSGunnar Mills 
3214550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3215c45f0082SYong Li     {
3216f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3217c45f0082SYong Li     }
3218c45f0082SYong Li 
3219cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
322069f35306SGunnar Mills     {
3221002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3222491d8ee7SSantosh Puranik     }
3223550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
322469f35306SGunnar Mills     {
3225550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
322669f35306SGunnar Mills     }
3227ac7e1e0bSAli Ahmed 
3228797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3229797d5daeSCorey Hardesty     {
3230797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3231797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3232797d5daeSCorey Hardesty     }
3233797d5daeSCorey Hardesty 
3234550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3235ac7e1e0bSAli Ahmed     {
3236c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
323769f35306SGunnar Mills     }
3238265c1602SJohnathan Mantey 
32399dcfe8c1SAlbert Zhang     if (stopBootOnFault)
32409dcfe8c1SAlbert Zhang     {
32419dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
32429dcfe8c1SAlbert Zhang     }
32439dcfe8c1SAlbert Zhang 
32449f8bfa7cSGunnar Mills     if (locationIndicatorActive)
32459f8bfa7cSGunnar Mills     {
324659a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32479f8bfa7cSGunnar Mills     }
32489f8bfa7cSGunnar Mills 
32497e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
32507e860f15SJohn Edward Broadbent     // passed
32519712f8acSEd Tanous     if (indicatorLed)
32526617338dSEd Tanous     {
3253f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3254002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3255d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3256d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
32576617338dSEd Tanous     }
3258c6a620f2SGeorge Liu 
3259c6a620f2SGeorge Liu     if (powerRestorePolicy)
3260c6a620f2SGeorge Liu     {
32614e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3262c6a620f2SGeorge Liu     }
32633a2d0424SChris Cain 
32643a2d0424SChris Cain     if (powerMode)
32653a2d0424SChris Cain     {
32663a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
32673a2d0424SChris Cain     }
326837bbf98cSChris Cain 
3269c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
327037bbf98cSChris Cain     {
3271002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3272002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
327337bbf98cSChris Cain     }
3274c1e219d5SEd Tanous }
32751cb1a9e6SAppaRao Puli 
327638c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3277dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
32787f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3279c1e219d5SEd Tanous     const std::string& /*systemName*/)
3280dd60b9edSEd Tanous {
3281dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3282dd60b9edSEd Tanous     {
3283dd60b9edSEd Tanous         return;
3284dd60b9edSEd Tanous     }
3285dd60b9edSEd Tanous     asyncResp->res.addHeader(
3286dd60b9edSEd Tanous         boost::beast::http::field::link,
3287dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3288dd60b9edSEd Tanous }
328933e1f122SAndrew Geissler 
329033e1f122SAndrew Geissler /**
329133e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
329233e1f122SAndrew Geissler  *
329333e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
329433e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
329533e1f122SAndrew Geissler  *
3296efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
329733e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
329833e1f122SAndrew Geissler  * allowableValues.
329933e1f122SAndrew Geissler  */
330033e1f122SAndrew Geissler inline void
330133e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
330233e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
330333e1f122SAndrew Geissler {
330433e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
330533e1f122SAndrew Geissler     {
330633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
330733e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
330833e1f122SAndrew Geissler     }
330933e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
331033e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
331133e1f122SAndrew Geissler     {
331233e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
331333e1f122SAndrew Geissler     }
331433e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
331533e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
331633e1f122SAndrew Geissler     {
331733e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
331833e1f122SAndrew Geissler     }
331933e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
332033e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
332133e1f122SAndrew Geissler     {
332233e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
332333e1f122SAndrew Geissler     }
332433e1f122SAndrew Geissler     else
332533e1f122SAndrew Geissler     {
332633e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
332733e1f122SAndrew Geissler     }
332833e1f122SAndrew Geissler }
332933e1f122SAndrew Geissler 
333033e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
333133e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
333233e1f122SAndrew Geissler     const boost::system::error_code& ec,
333333e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
333433e1f122SAndrew Geissler {
333533e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
333633e1f122SAndrew Geissler 
333733e1f122SAndrew Geissler     // Supported on all systems currently
333833e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
333933e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
334033e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
334133e1f122SAndrew Geissler 
334233e1f122SAndrew Geissler     if (ec)
334333e1f122SAndrew Geissler     {
3344e715d14bSEd Tanous         if ((ec.value() ==
3345e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3346e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
334733e1f122SAndrew Geissler         {
334833e1f122SAndrew Geissler             // Property not implemented so just return defaults
334933e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
335033e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
335133e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
335233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
335333e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
335433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
335533e1f122SAndrew Geissler         }
335633e1f122SAndrew Geissler         else
335733e1f122SAndrew Geissler         {
335833e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
335933e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
336033e1f122SAndrew Geissler             return;
336133e1f122SAndrew Geissler         }
336233e1f122SAndrew Geissler     }
336333e1f122SAndrew Geissler     else
336433e1f122SAndrew Geissler     {
336533e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
336633e1f122SAndrew Geissler         {
336733e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
336833e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
336933e1f122SAndrew Geissler         }
337033e1f122SAndrew Geissler     }
337133e1f122SAndrew Geissler 
337233e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
337333e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
337433e1f122SAndrew Geissler     parameter["Required"] = true;
3375539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
337633e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
337733e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
337833e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
337933e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
338033e1f122SAndrew Geissler }
338133e1f122SAndrew Geissler 
3382c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3383c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
338422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3385c1e219d5SEd Tanous     const std::string& systemName)
3386c1e219d5SEd Tanous {
33873ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
338845ca1b86SEd Tanous     {
338945ca1b86SEd Tanous         return;
339045ca1b86SEd Tanous     }
339125b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
33927f3e84a1SEd Tanous     {
33937f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
33947f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33957f3e84a1SEd Tanous                                    systemName);
33967f3e84a1SEd Tanous         return;
33977f3e84a1SEd Tanous     }
3398746b56f3SAsmitha Karunanithi 
339968896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
340068896206SGunnar Mills     {
3401746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3402746b56f3SAsmitha Karunanithi         {
3403746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3404746b56f3SAsmitha Karunanithi             return;
3405746b56f3SAsmitha Karunanithi         }
340668896206SGunnar Mills     }
3407746b56f3SAsmitha Karunanithi 
3408253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
340922d268cbSEd Tanous     {
341022d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
341122d268cbSEd Tanous                                    systemName);
341222d268cbSEd Tanous         return;
341322d268cbSEd Tanous     }
341422d268cbSEd Tanous 
3415dd60b9edSEd Tanous     asyncResp->res.addHeader(
3416dd60b9edSEd Tanous         boost::beast::http::field::link,
3417dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34181476687dSEd Tanous 
34191476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
3420253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3421253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3422c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34231476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34241476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34253215e700SNan Zhou 
342633e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
3427deae6a78SEd Tanous     dbus::utility::getProperty<std::vector<std::string>>(
3428deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
3429deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
343033e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
343133e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
3432bd79bce8SPatrick Williams             afterGetAllowedHostTransitions(asyncResp, ec,
3433bd79bce8SPatrick Williams                                            allowedHostTransitions);
343433e1f122SAndrew Geissler         });
3435c1e219d5SEd Tanous }
3436c1e219d5SEd Tanous /**
3437c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3438c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3439c1e219d5SEd Tanous  */
3440100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3441c1e219d5SEd Tanous {
3442100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3443100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3444100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3445100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3446100afe56SEd Tanous 
3447100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3448100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3449100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3450100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3451100afe56SEd Tanous 
3452100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3453100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3454100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3455100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3456100afe56SEd Tanous 
3457100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3458100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3459100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3460100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3461100afe56SEd Tanous 
3462100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3463100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3464100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3465100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3466100afe56SEd Tanous 
3467100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3468100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3469100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3470100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3471100afe56SEd Tanous 
3472c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3473c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3474c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3475c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3476c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3477c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3478c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3479c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
34801cb1a9e6SAppaRao Puli }
3481c5b2abe0SLewanczyk, Dawid } // namespace redfish
3482