xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision deae6a789444debc4724fb6902fc5def299afbee)
1c5b2abe0SLewanczyk, Dawid /*
26be832e2SEd Tanous Copyright (c) 2018 Intel Corporation
36be832e2SEd Tanous 
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous 
86be832e2SEd Tanous       http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous 
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
1813451e39SWilly Tu #include "bmcweb_config.h"
1913451e39SWilly Tu 
203ccb3adbSEd Tanous #include "app.hpp"
211e1e598dSJonathan Doman #include "dbus_singleton.hpp"
227a1dbc48SGeorge Liu #include "dbus_utility.hpp"
23539d8c6bSEd Tanous #include "generated/enums/action_info.hpp"
248d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
25539d8c6bSEd Tanous #include "generated/enums/open_bmc_computer_system.hpp"
2633e1f122SAndrew Geissler #include "generated/enums/resource.hpp"
27746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
281c8fba97SJames Feist #include "led.hpp"
29f4c99e70SEd Tanous #include "query.hpp"
30c5d03ff4SJennifer Lee #include "redfish_util.hpp"
313ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
323ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
333ccb3adbSEd Tanous #include "utils/json_utils.hpp"
34472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
353ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
362b82937eSEd Tanous #include "utils/time_utils.hpp"
37c5d03ff4SJennifer Lee 
38fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
399712f8acSEd Tanous #include <boost/container/flat_map.hpp>
40e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
4133e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
42ef4c65b7SEd Tanous #include <boost/url/format.hpp>
431e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
44fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
45bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
461214b7e7SGunnar Mills 
477a1dbc48SGeorge Liu #include <array>
4833e1f122SAndrew Geissler #include <memory>
496b9ac4f2SChris Cain #include <string>
507a1dbc48SGeorge Liu #include <string_view>
5120fa6a2cSEd Tanous #include <utility>
52abf2add6SEd Tanous #include <variant>
536b9ac4f2SChris Cain #include <vector>
54c5b2abe0SLewanczyk, Dawid 
551abe55efSEd Tanous namespace redfish
561abe55efSEd Tanous {
57c5b2abe0SLewanczyk, Dawid 
585c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
595c3e9272SAbhishek Patel     protocolToDBusForSystems{
605c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
615c3e9272SAbhishek Patel 
629d3ae10eSAlpana Kumari /**
639d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
649d3ae10eSAlpana Kumari  *
65ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
669d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
679d3ae10eSAlpana Kumari  *
689d3ae10eSAlpana Kumari  * @return None.
699d3ae10eSAlpana Kumari  */
70bd79bce8SPatrick Williams inline void updateDimmProperties(
71bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
729d3ae10eSAlpana Kumari {
7362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
749d3ae10eSAlpana Kumari 
759d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
769d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
779d3ae10eSAlpana Kumari     // ENABLED.
7802cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
79ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
809d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
819d3ae10eSAlpana Kumari     {
82e05aec50SEd Tanous         if (isDimmFunctional)
839d3ae10eSAlpana Kumari         {
84ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
859d3ae10eSAlpana Kumari                 "Enabled";
869d3ae10eSAlpana Kumari         }
879d3ae10eSAlpana Kumari     }
889d3ae10eSAlpana Kumari }
899d3ae10eSAlpana Kumari 
9057e8c9beSAlpana Kumari /*
9157e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9257e8c9beSAlpana Kumari  *        CPU Functional State
9357e8c9beSAlpana Kumari  *
94ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9557e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9657e8c9beSAlpana Kumari  *
9757e8c9beSAlpana Kumari  * @return None.
9857e8c9beSAlpana Kumari  */
99ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
100ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10157e8c9beSAlpana Kumari {
10262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10357e8c9beSAlpana Kumari 
10402cad96eSEd Tanous     const nlohmann::json& prevProcState =
105ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10657e8c9beSAlpana Kumari 
10757e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10857e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10957e8c9beSAlpana Kumari     // Functional.
11057e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11157e8c9beSAlpana Kumari     {
112e05aec50SEd Tanous         if (isCpuFunctional)
11357e8c9beSAlpana Kumari         {
114ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11557e8c9beSAlpana Kumari                 "Enabled";
11657e8c9beSAlpana Kumari         }
11757e8c9beSAlpana Kumari     }
11857e8c9beSAlpana Kumari }
11957e8c9beSAlpana Kumari 
120cf0e004cSNinad Palsule /*
121cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
122cf0e004cSNinad Palsule  *
123ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
124cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
125cf0e004cSNinad Palsule  *
126cf0e004cSNinad Palsule  * @return None.
127cf0e004cSNinad Palsule  */
128bd79bce8SPatrick Williams inline void modifyCpuPresenceState(
129bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
130cf0e004cSNinad Palsule {
13162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
132cf0e004cSNinad Palsule 
133cf0e004cSNinad Palsule     if (isCpuPresent)
134cf0e004cSNinad Palsule     {
135cf0e004cSNinad Palsule         nlohmann::json& procCount =
136ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
137cf0e004cSNinad Palsule         auto* procCountPtr =
138cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
139cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
140cf0e004cSNinad Palsule         {
141cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
142cf0e004cSNinad Palsule             *procCountPtr += 1;
143cf0e004cSNinad Palsule         }
144cf0e004cSNinad Palsule     }
145cf0e004cSNinad Palsule }
146cf0e004cSNinad Palsule 
147382d6475SAli Ahmed inline void getProcessorProperties(
148ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
149382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150382d6475SAli Ahmed         properties)
15103fbed92SAli Ahmed {
15262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15303fbed92SAli Ahmed 
15403fbed92SAli Ahmed     // TODO: Get Model
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15703fbed92SAli Ahmed 
158bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
159bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16003fbed92SAli Ahmed 
161bc1d29deSKrzysztof Grobelny     if (!success)
16203fbed92SAli Ahmed     {
163ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16403fbed92SAli Ahmed         return;
16503fbed92SAli Ahmed     }
16603fbed92SAli Ahmed 
167bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16803fbed92SAli Ahmed     {
169bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
170ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
171bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
172bc1d29deSKrzysztof Grobelny 
173bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
174bc1d29deSKrzysztof Grobelny         {
175bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17603fbed92SAli Ahmed         }
17703fbed92SAli Ahmed         else
17803fbed92SAli Ahmed         {
179bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18003fbed92SAli Ahmed         }
18103fbed92SAli Ahmed     }
18203fbed92SAli Ahmed }
18303fbed92SAli Ahmed 
18403fbed92SAli Ahmed /*
18503fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18603fbed92SAli Ahmed  *
187ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18803fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18903fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19003fbed92SAli Ahmed  *
19103fbed92SAli Ahmed  * @return None.
19203fbed92SAli Ahmed  */
193ac106bf6SEd Tanous inline void
194ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19603fbed92SAli Ahmed {
197ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
199382d6475SAli Ahmed         if (ec3)
200382d6475SAli Ahmed         {
20162598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
202382d6475SAli Ahmed             return;
203382d6475SAli Ahmed         }
204ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
205382d6475SAli Ahmed     };
206382d6475SAli Ahmed 
207cf0e004cSNinad Palsule     // Get the Presence of CPU
208*deae6a78SEd Tanous     dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
209*deae6a78SEd Tanous                                      path, "xyz.openbmc_project.Inventory.Item",
210*deae6a78SEd Tanous                                      "Present", std::move(getCpuPresenceState));
211cf0e004cSNinad Palsule 
212*deae6a78SEd Tanous     dbus::utility::getAllProperties(
213*deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
214ac106bf6SEd Tanous         [asyncResp, service,
2155e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
216b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21703fbed92SAli Ahmed             if (ec2)
21803fbed92SAli Ahmed             {
21962598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
220ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22103fbed92SAli Ahmed                 return;
22203fbed92SAli Ahmed             }
223ac106bf6SEd Tanous             getProcessorProperties(asyncResp, properties);
224bc1d29deSKrzysztof Grobelny         });
22503fbed92SAli Ahmed }
22603fbed92SAli Ahmed 
22757e8c9beSAlpana Kumari /*
228cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
229cf0e004cSNinad Palsule  *
230ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
231cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
232cf0e004cSNinad Palsule  *
233cf0e004cSNinad Palsule  * @return None.
234cf0e004cSNinad Palsule  */
235cf0e004cSNinad Palsule inline void
236ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
237cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
238cf0e004cSNinad Palsule {
23962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
240cf0e004cSNinad Palsule 
241cf0e004cSNinad Palsule     if (properties.empty())
242cf0e004cSNinad Palsule     {
243cf0e004cSNinad Palsule         return;
244cf0e004cSNinad Palsule     }
245cf0e004cSNinad Palsule 
246cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
247cf0e004cSNinad Palsule 
248cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
249cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
250cf0e004cSNinad Palsule         memorySizeInKB);
251cf0e004cSNinad Palsule 
252cf0e004cSNinad Palsule     if (!success)
253cf0e004cSNinad Palsule     {
254ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
255cf0e004cSNinad Palsule         return;
256cf0e004cSNinad Palsule     }
257cf0e004cSNinad Palsule 
258cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
259cf0e004cSNinad Palsule     {
260cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
261ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
262dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
263cf0e004cSNinad Palsule         if (preValue == nullptr)
264cf0e004cSNinad Palsule         {
265ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
266dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
267cf0e004cSNinad Palsule         }
268cf0e004cSNinad Palsule         else
269cf0e004cSNinad Palsule         {
270ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
271dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
272dfb2b408SPriyanga Ramasamy                 *preValue;
273cf0e004cSNinad Palsule         }
274cf0e004cSNinad Palsule     }
275cf0e004cSNinad Palsule }
276cf0e004cSNinad Palsule 
277cf0e004cSNinad Palsule /*
278cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
279cf0e004cSNinad Palsule  *
280ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
281cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
282cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
283cf0e004cSNinad Palsule  *
284cf0e004cSNinad Palsule  * @return None.
285cf0e004cSNinad Palsule  */
286ac106bf6SEd Tanous inline void
287ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
288ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
289cf0e004cSNinad Palsule {
290*deae6a78SEd Tanous     dbus::utility::getAllProperties(
291*deae6a78SEd Tanous         service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
292ac106bf6SEd Tanous         [asyncResp, service,
293cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
294cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
295cf0e004cSNinad Palsule             if (ec2)
296cf0e004cSNinad Palsule             {
29762598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
298ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
299cf0e004cSNinad Palsule                 return;
300cf0e004cSNinad Palsule             }
30151bd2d8aSGunnar Mills             processMemoryProperties(asyncResp, properties);
302cf0e004cSNinad Palsule         });
303cf0e004cSNinad Palsule }
304cf0e004cSNinad Palsule 
305a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
306a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
307a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3081abe55efSEd Tanous {
309a974c132SLakshmi Yadlapati     if (ec)
310a974c132SLakshmi Yadlapati     {
311a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
312a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
313a974c132SLakshmi Yadlapati         return;
314a974c132SLakshmi Yadlapati     }
315a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
316a974c132SLakshmi Yadlapati 
317a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
318a974c132SLakshmi Yadlapati 
319a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
320a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
321a974c132SLakshmi Yadlapati 
322a974c132SLakshmi Yadlapati     if (!success)
323a974c132SLakshmi Yadlapati     {
324a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
325a974c132SLakshmi Yadlapati         return;
326a974c132SLakshmi Yadlapati     }
327a974c132SLakshmi Yadlapati 
328a974c132SLakshmi Yadlapati     if (uUID != nullptr)
329a974c132SLakshmi Yadlapati     {
330a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
331a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
332a974c132SLakshmi Yadlapati         {
333a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
334a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
335a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
336a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
337a974c132SLakshmi Yadlapati         }
338a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
339a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
340a974c132SLakshmi Yadlapati     }
341a974c132SLakshmi Yadlapati }
342a974c132SLakshmi Yadlapati 
343a974c132SLakshmi Yadlapati inline void
344a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
345a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
346a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
347a974c132SLakshmi Yadlapati {
348a974c132SLakshmi Yadlapati     if (ec)
349a974c132SLakshmi Yadlapati     {
350a974c132SLakshmi Yadlapati         // doesn't have to include this
351a974c132SLakshmi Yadlapati         // interface
352a974c132SLakshmi Yadlapati         return;
353a974c132SLakshmi Yadlapati     }
354a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
355a974c132SLakshmi Yadlapati 
356a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
357a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
358a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
359a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
360a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
361a974c132SLakshmi Yadlapati 
362a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
363a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
364a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
365a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
366a974c132SLakshmi Yadlapati 
367a974c132SLakshmi Yadlapati     if (!success)
368a974c132SLakshmi Yadlapati     {
369a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
370a974c132SLakshmi Yadlapati         return;
371a974c132SLakshmi Yadlapati     }
372a974c132SLakshmi Yadlapati 
373a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
374a974c132SLakshmi Yadlapati     {
375a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
376a974c132SLakshmi Yadlapati     }
377a974c132SLakshmi Yadlapati 
378a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
379a974c132SLakshmi Yadlapati     {
380a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
381a974c132SLakshmi Yadlapati     }
382a974c132SLakshmi Yadlapati 
383a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
384a974c132SLakshmi Yadlapati     {
385a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
386a974c132SLakshmi Yadlapati     }
387a974c132SLakshmi Yadlapati 
388a974c132SLakshmi Yadlapati     if (model != nullptr)
389a974c132SLakshmi Yadlapati     {
390a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
391a974c132SLakshmi Yadlapati     }
392a974c132SLakshmi Yadlapati 
393a974c132SLakshmi Yadlapati     if (subModel != nullptr)
394a974c132SLakshmi Yadlapati     {
395a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
396a974c132SLakshmi Yadlapati     }
397a974c132SLakshmi Yadlapati 
398a974c132SLakshmi Yadlapati     // Grab the bios version
399a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
400a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
401a974c132SLakshmi Yadlapati }
402a974c132SLakshmi Yadlapati 
403bd79bce8SPatrick Williams inline void afterGetAssetTag(
404bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
405bd79bce8SPatrick Williams     const boost::system::error_code& ec, const std::string& value)
406a974c132SLakshmi Yadlapati {
407a974c132SLakshmi Yadlapati     if (ec)
408a974c132SLakshmi Yadlapati     {
409a974c132SLakshmi Yadlapati         // doesn't have to include this
410a974c132SLakshmi Yadlapati         // interface
411a974c132SLakshmi Yadlapati         return;
412a974c132SLakshmi Yadlapati     }
413a974c132SLakshmi Yadlapati 
414a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
415a974c132SLakshmi Yadlapati }
416a974c132SLakshmi Yadlapati 
417a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
418a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
419a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
420a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
421a974c132SLakshmi Yadlapati {
4221abe55efSEd Tanous     if (ec)
4231abe55efSEd Tanous     {
424b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
425ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
426c5b2abe0SLewanczyk, Dawid         return;
427c5b2abe0SLewanczyk, Dawid     }
428c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
429002d39b4SEd Tanous     for (const std::pair<
430002d39b4SEd Tanous              std::string,
431002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4321214b7e7SGunnar Mills              object : subtree)
4331abe55efSEd Tanous     {
434c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
43562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
436002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4371214b7e7SGunnar Mills             connectionNames = object.second;
43826f6976fSEd Tanous         if (connectionNames.empty())
4391abe55efSEd Tanous         {
440c5b2abe0SLewanczyk, Dawid             continue;
441c5b2abe0SLewanczyk, Dawid         }
442029573d4SEd Tanous 
4436c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4446c34de48SEd Tanous         // BiosVer
44504a258f4SEd Tanous         for (const auto& connection : connectionNames)
4461abe55efSEd Tanous         {
44704a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4481abe55efSEd Tanous             {
449a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4501abe55efSEd Tanous                 {
45162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4529d3ae10eSAlpana Kumari 
453ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4545fd0aafbSNinad Palsule                 }
45504a258f4SEd Tanous                 else if (interfaceName ==
45604a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4571abe55efSEd Tanous                 {
45862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
45957e8c9beSAlpana Kumari 
460ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4615fd0aafbSNinad Palsule                 }
462002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4631abe55efSEd Tanous                 {
46462598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
465bc1d29deSKrzysztof Grobelny 
466*deae6a78SEd Tanous                     dbus::utility::getAllProperties(
467a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
468a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
469ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
470b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4711214b7e7SGunnar Mills                                         properties) {
472a974c132SLakshmi Yadlapati                             afterGetUUID(asyncResp, ec3, properties);
473bc1d29deSKrzysztof Grobelny                         });
474c5b2abe0SLewanczyk, Dawid                 }
475029573d4SEd Tanous                 else if (interfaceName ==
476029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4771abe55efSEd Tanous                 {
478*deae6a78SEd Tanous                     dbus::utility::getAllProperties(
479a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
480bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
481a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
482b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
483a974c132SLakshmi Yadlapati                                         properties) {
484a974c132SLakshmi Yadlapati                             afterGetInventory(asyncResp, ec3, properties);
485bc1d29deSKrzysztof Grobelny                         });
486e4a4b9a9SJames Feist 
487*deae6a78SEd Tanous                     dbus::utility::getProperty<std::string>(
488*deae6a78SEd Tanous                         connection.first, path,
4891e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4901e1e598dSJonathan Doman                         "AssetTag",
4911e1e598dSJonathan Doman                         "AssetTag",
492a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
493a974c132SLakshmi Yadlapati                 }
494a974c132SLakshmi Yadlapati             }
495a974c132SLakshmi Yadlapati         }
496a974c132SLakshmi Yadlapati     }
497a974c132SLakshmi Yadlapati }
498a974c132SLakshmi Yadlapati 
499a974c132SLakshmi Yadlapati /*
500a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
501a974c132SLakshmi Yadlapati  *
502a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
503a974c132SLakshmi Yadlapati  *
504a974c132SLakshmi Yadlapati  * @return None.
505a974c132SLakshmi Yadlapati  */
506a974c132SLakshmi Yadlapati inline void
50751bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
508e4a4b9a9SJames Feist {
509a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
510a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
511a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
512a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
513a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
514a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
515a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
516a974c132SLakshmi Yadlapati     };
517a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
518a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
51951bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
520c5b2abe0SLewanczyk, Dawid }
521c5b2abe0SLewanczyk, Dawid 
522c5b2abe0SLewanczyk, Dawid /**
523c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
524c5b2abe0SLewanczyk, Dawid  *
525ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
526c5b2abe0SLewanczyk, Dawid  *
527c5b2abe0SLewanczyk, Dawid  * @return None.
528c5b2abe0SLewanczyk, Dawid  */
529ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5301abe55efSEd Tanous {
53162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
532*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
533*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
534*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState",
535ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5361e1e598dSJonathan Doman                     const std::string& hostState) {
5371abe55efSEd Tanous             if (ec)
5381abe55efSEd Tanous             {
53922228c28SAndrew Geissler                 if (ec == boost::system::errc::host_unreachable)
54022228c28SAndrew Geissler                 {
54122228c28SAndrew Geissler                     // Service not available, no error, just don't return
54222228c28SAndrew Geissler                     // host state info
54362598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Service not available {}", ec);
54422228c28SAndrew Geissler                     return;
54522228c28SAndrew Geissler                 }
54662598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
547ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
548c5b2abe0SLewanczyk, Dawid                 return;
549c5b2abe0SLewanczyk, Dawid             }
5506617338dSEd Tanous 
55162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Host state: {}", hostState);
552c5b2abe0SLewanczyk, Dawid             // Verify Host State
5531e1e598dSJonathan Doman             if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5541abe55efSEd Tanous             {
555bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
556bd79bce8SPatrick Williams                     resource::PowerState::On;
557539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
558539d8c6bSEd Tanous                     resource::State::Enabled;
5591abe55efSEd Tanous             }
5601e1e598dSJonathan Doman             else if (hostState ==
5610fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.Quiesced")
5628c888608SGunnar Mills             {
563bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
564bd79bce8SPatrick Williams                     resource::PowerState::On;
565539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
566539d8c6bSEd Tanous                     resource::State::Quiesced;
5678c888608SGunnar Mills             }
5681e1e598dSJonathan Doman             else if (hostState ==
5690fda0f12SGeorge Liu                      "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57083935af9SAndrew Geissler             {
571bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
572bd79bce8SPatrick Williams                     resource::PowerState::On;
573539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
574539d8c6bSEd Tanous                     resource::State::InTest;
57583935af9SAndrew Geissler             }
5760fda0f12SGeorge Liu             else if (
5771e1e598dSJonathan Doman                 hostState ==
5780fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5791a2a1437SAndrew Geissler             {
580539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
581539d8c6bSEd Tanous                     resource::PowerState::PoweringOn;
582539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
583539d8c6bSEd Tanous                     resource::State::Starting;
5841a2a1437SAndrew Geissler             }
585bd79bce8SPatrick Williams             else if (
586bd79bce8SPatrick Williams                 hostState ==
5870fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5881a2a1437SAndrew Geissler             {
589539d8c6bSEd Tanous                 asyncResp->res.jsonValue["PowerState"] =
590539d8c6bSEd Tanous                     resource::PowerState::PoweringOff;
591539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
592539d8c6bSEd Tanous                     resource::State::Disabled;
5931a2a1437SAndrew Geissler             }
5941abe55efSEd Tanous             else
5951abe55efSEd Tanous             {
596bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["PowerState"] =
597bd79bce8SPatrick Williams                     resource::PowerState::Off;
598539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
599539d8c6bSEd Tanous                     resource::State::Disabled;
600c5b2abe0SLewanczyk, Dawid             }
6011e1e598dSJonathan Doman         });
602c5b2abe0SLewanczyk, Dawid }
603c5b2abe0SLewanczyk, Dawid 
604c5b2abe0SLewanczyk, Dawid /**
605786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
606491d8ee7SSantosh Puranik  *
607491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
608491d8ee7SSantosh Puranik  *
609491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
610491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
611491d8ee7SSantosh Puranik  */
61223a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
613491d8ee7SSantosh Puranik {
614491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
615491d8ee7SSantosh Puranik     {
616491d8ee7SSantosh Puranik         return "None";
617491d8ee7SSantosh Puranik     }
6183174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
619491d8ee7SSantosh Puranik     {
620491d8ee7SSantosh Puranik         return "Hdd";
621491d8ee7SSantosh Puranik     }
6223174e4dfSEd Tanous     if (dbusSource ==
623a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
624491d8ee7SSantosh Puranik     {
625491d8ee7SSantosh Puranik         return "Cd";
626491d8ee7SSantosh Puranik     }
6273174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
628491d8ee7SSantosh Puranik     {
629491d8ee7SSantosh Puranik         return "Pxe";
630491d8ee7SSantosh Puranik     }
6313174e4dfSEd Tanous     if (dbusSource ==
632944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6339f16b2c1SJennifer Lee     {
6349f16b2c1SJennifer Lee         return "Usb";
6359f16b2c1SJennifer Lee     }
636491d8ee7SSantosh Puranik     return "";
637491d8ee7SSantosh Puranik }
638491d8ee7SSantosh Puranik 
639491d8ee7SSantosh Puranik /**
640cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
641cd9a4666SKonstantin Aladyshev  *
642cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
643cd9a4666SKonstantin Aladyshev  *
644cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
645cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
646cd9a4666SKonstantin Aladyshev  */
647cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
648cd9a4666SKonstantin Aladyshev {
649cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
650cd9a4666SKonstantin Aladyshev     {
651cd9a4666SKonstantin Aladyshev         return "Legacy";
652cd9a4666SKonstantin Aladyshev     }
653cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
654cd9a4666SKonstantin Aladyshev     {
655cd9a4666SKonstantin Aladyshev         return "UEFI";
656cd9a4666SKonstantin Aladyshev     }
657cd9a4666SKonstantin Aladyshev     return "";
658cd9a4666SKonstantin Aladyshev }
659cd9a4666SKonstantin Aladyshev 
660cd9a4666SKonstantin Aladyshev /**
661786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
662491d8ee7SSantosh Puranik  *
663491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
664491d8ee7SSantosh Puranik  *
665491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
666491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
667491d8ee7SSantosh Puranik  */
66823a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
669491d8ee7SSantosh Puranik {
670491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
671491d8ee7SSantosh Puranik     {
672491d8ee7SSantosh Puranik         return "None";
673491d8ee7SSantosh Puranik     }
6743174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
675491d8ee7SSantosh Puranik     {
676491d8ee7SSantosh Puranik         return "Diags";
677491d8ee7SSantosh Puranik     }
6783174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
679491d8ee7SSantosh Puranik     {
680491d8ee7SSantosh Puranik         return "BiosSetup";
681491d8ee7SSantosh Puranik     }
682491d8ee7SSantosh Puranik     return "";
683491d8ee7SSantosh Puranik }
684491d8ee7SSantosh Puranik 
685491d8ee7SSantosh Puranik /**
686e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
687e43914b3SAndrew Geissler  *
688e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
689e43914b3SAndrew Geissler  *
690e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
691e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
692e43914b3SAndrew Geissler  */
693e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
694e43914b3SAndrew Geissler {
695e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
696e43914b3SAndrew Geissler     // enum
697e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
698e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
699e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
700e43914b3SAndrew Geissler     {
701e43914b3SAndrew Geissler         rfBpLastState = "None";
702e43914b3SAndrew Geissler     }
703e43914b3SAndrew Geissler     else if (dbusBootProgress ==
704e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
705e43914b3SAndrew Geissler              "PrimaryProcInit")
706e43914b3SAndrew Geissler     {
707e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
708e43914b3SAndrew Geissler     }
709e43914b3SAndrew Geissler     else if (dbusBootProgress ==
710e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
711e43914b3SAndrew Geissler              "BusInit")
712e43914b3SAndrew Geissler     {
713e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
714e43914b3SAndrew Geissler     }
715e43914b3SAndrew Geissler     else if (dbusBootProgress ==
716e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
717e43914b3SAndrew Geissler              "MemoryInit")
718e43914b3SAndrew Geissler     {
719e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
720e43914b3SAndrew Geissler     }
721e43914b3SAndrew Geissler     else if (dbusBootProgress ==
722e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
723e43914b3SAndrew Geissler              "SecondaryProcInit")
724e43914b3SAndrew Geissler     {
725e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
726e43914b3SAndrew Geissler     }
727e43914b3SAndrew Geissler     else if (dbusBootProgress ==
728e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
729e43914b3SAndrew Geissler              "PCIInit")
730e43914b3SAndrew Geissler     {
731e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
732e43914b3SAndrew Geissler     }
733e43914b3SAndrew Geissler     else if (dbusBootProgress ==
734e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
735e43914b3SAndrew Geissler              "SystemSetup")
736e43914b3SAndrew Geissler     {
737e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
738e43914b3SAndrew Geissler     }
739e43914b3SAndrew Geissler     else if (dbusBootProgress ==
740e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
741e43914b3SAndrew Geissler              "SystemInitComplete")
742e43914b3SAndrew Geissler     {
743e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
744e43914b3SAndrew Geissler     }
745e43914b3SAndrew Geissler     else if (dbusBootProgress ==
746e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
747e43914b3SAndrew Geissler              "OSStart")
748e43914b3SAndrew Geissler     {
749e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
750e43914b3SAndrew Geissler     }
751e43914b3SAndrew Geissler     else if (dbusBootProgress ==
752e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
753e43914b3SAndrew Geissler              "OSRunning")
754e43914b3SAndrew Geissler     {
755e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
756e43914b3SAndrew Geissler     }
757e43914b3SAndrew Geissler     else
758e43914b3SAndrew Geissler     {
75962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
760e43914b3SAndrew Geissler         // Just return the default
761e43914b3SAndrew Geissler     }
762e43914b3SAndrew Geissler     return rfBpLastState;
763e43914b3SAndrew Geissler }
764e43914b3SAndrew Geissler 
765e43914b3SAndrew Geissler /**
766786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
767491d8ee7SSantosh Puranik  *
768491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
769944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
770944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
771491d8ee7SSantosh Puranik  *
772944ffaf9SJohnathan Mantey  * @return Integer error code.
773491d8ee7SSantosh Puranik  */
774bd79bce8SPatrick Williams inline int assignBootParameters(
775bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
776bd79bce8SPatrick Williams     const std::string& rfSource, std::string& bootSource, std::string& bootMode)
777491d8ee7SSantosh Puranik {
778c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
779c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
780944ffaf9SJohnathan Mantey 
781491d8ee7SSantosh Puranik     if (rfSource == "None")
782491d8ee7SSantosh Puranik     {
783944ffaf9SJohnathan Mantey         return 0;
784491d8ee7SSantosh Puranik     }
7853174e4dfSEd Tanous     if (rfSource == "Pxe")
786491d8ee7SSantosh Puranik     {
787944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
788944ffaf9SJohnathan Mantey     }
789944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
790944ffaf9SJohnathan Mantey     {
791944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
792944ffaf9SJohnathan Mantey     }
793944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
794944ffaf9SJohnathan Mantey     {
795944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
796944ffaf9SJohnathan Mantey     }
797944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
798944ffaf9SJohnathan Mantey     {
799944ffaf9SJohnathan Mantey         bootSource =
800944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
801944ffaf9SJohnathan Mantey     }
802944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
803944ffaf9SJohnathan Mantey     {
804944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
805491d8ee7SSantosh Puranik     }
8069f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8079f16b2c1SJennifer Lee     {
808944ffaf9SJohnathan Mantey         bootSource =
809944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8109f16b2c1SJennifer Lee     }
811491d8ee7SSantosh Puranik     else
812491d8ee7SSantosh Puranik     {
81362598e31SEd Tanous         BMCWEB_LOG_DEBUG(
81462598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
81562598e31SEd Tanous             bootSource);
816ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
817944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
818944ffaf9SJohnathan Mantey         return -1;
819491d8ee7SSantosh Puranik     }
820944ffaf9SJohnathan Mantey     return 0;
821491d8ee7SSantosh Puranik }
8221981771bSAli Ahmed 
823978b8803SAndrew Geissler /**
824978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
825978b8803SAndrew Geissler  *
826ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
827978b8803SAndrew Geissler  *
828978b8803SAndrew Geissler  * @return None.
829978b8803SAndrew Geissler  */
830ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
831978b8803SAndrew Geissler {
832*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
833*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
8341e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
835ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8361e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
837978b8803SAndrew Geissler             if (ec)
838978b8803SAndrew Geissler             {
839978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
840978b8803SAndrew Geissler                 // not found
841978b8803SAndrew Geissler                 return;
842978b8803SAndrew Geissler             }
843978b8803SAndrew Geissler 
84462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
845978b8803SAndrew Geissler 
846ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastState"] =
847e43914b3SAndrew Geissler                 dbusToRfBootProgress(bootProgressStr);
8481e1e598dSJonathan Doman         });
849978b8803SAndrew Geissler }
850491d8ee7SSantosh Puranik 
851491d8ee7SSantosh Puranik /**
852b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
853b6d5d45cSHieu Huynh  *
854ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
855b6d5d45cSHieu Huynh  *
856b6d5d45cSHieu Huynh  * @return None.
857b6d5d45cSHieu Huynh  */
858b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
859ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
860b6d5d45cSHieu Huynh {
861*deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
862*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
863b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
864ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
865b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
866b6d5d45cSHieu Huynh             if (ec)
867b6d5d45cSHieu Huynh             {
86862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
869b6d5d45cSHieu Huynh                 return;
870b6d5d45cSHieu Huynh             }
871b6d5d45cSHieu Huynh 
872b6d5d45cSHieu Huynh             // BootProgressLastUpdate is the last time the BootProgress property
873b6d5d45cSHieu Huynh             // was updated. The time is the Epoch time, number of microseconds
874b6d5d45cSHieu Huynh             // since 1 Jan 1970 00::00::00 UTC."
875b6d5d45cSHieu Huynh             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
876b6d5d45cSHieu Huynh             // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
877b6d5d45cSHieu Huynh 
878b6d5d45cSHieu Huynh             // Convert to ISO 8601 standard
879ac106bf6SEd Tanous             asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
880b6d5d45cSHieu Huynh                 redfish::time_utils::getDateTimeUintUs(lastStateTime);
881b6d5d45cSHieu Huynh         });
882b6d5d45cSHieu Huynh }
883b6d5d45cSHieu Huynh 
884b6d5d45cSHieu Huynh /**
885c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
886cd9a4666SKonstantin Aladyshev  *
887ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
888cd9a4666SKonstantin Aladyshev  *
889cd9a4666SKonstantin Aladyshev  * @return None.
890cd9a4666SKonstantin Aladyshev  */
891cd9a4666SKonstantin Aladyshev 
892ac106bf6SEd Tanous inline void
893ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
894cd9a4666SKonstantin Aladyshev {
895*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
896*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
8971e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8981e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
899ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9001e1e598dSJonathan Doman                     const std::string& bootType) {
901cd9a4666SKonstantin Aladyshev             if (ec)
902cd9a4666SKonstantin Aladyshev             {
903cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
904cd9a4666SKonstantin Aladyshev                 return;
905cd9a4666SKonstantin Aladyshev             }
906cd9a4666SKonstantin Aladyshev 
90762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
908cd9a4666SKonstantin Aladyshev 
909ac106bf6SEd Tanous             asyncResp->res
910ac106bf6SEd Tanous                 .jsonValue["Boot"]
911002d39b4SEd Tanous                           ["BootSourceOverrideMode@Redfish.AllowableValues"] =
912613dabeaSEd Tanous                 nlohmann::json::array_t({"Legacy", "UEFI"});
913cd9a4666SKonstantin Aladyshev 
9141e1e598dSJonathan Doman             auto rfType = dbusToRfBootType(bootType);
915cd9a4666SKonstantin Aladyshev             if (rfType.empty())
916cd9a4666SKonstantin Aladyshev             {
917ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
918cd9a4666SKonstantin Aladyshev                 return;
919cd9a4666SKonstantin Aladyshev             }
920cd9a4666SKonstantin Aladyshev 
921ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9221e1e598dSJonathan Doman         });
923cd9a4666SKonstantin Aladyshev }
924cd9a4666SKonstantin Aladyshev 
925cd9a4666SKonstantin Aladyshev /**
926c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
927491d8ee7SSantosh Puranik  *
928ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
929491d8ee7SSantosh Puranik  *
930491d8ee7SSantosh Puranik  * @return None.
931491d8ee7SSantosh Puranik  */
932c21865c4SKonstantin Aladyshev 
933ac106bf6SEd Tanous inline void
934ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
935491d8ee7SSantosh Puranik {
936*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
937*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
9381e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9391e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
940ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9411e1e598dSJonathan Doman                     const std::string& bootModeStr) {
942491d8ee7SSantosh Puranik             if (ec)
943491d8ee7SSantosh Puranik             {
944b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
945ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
946491d8ee7SSantosh Puranik                 return;
947491d8ee7SSantosh Puranik             }
948491d8ee7SSantosh Puranik 
94962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
950491d8ee7SSantosh Puranik 
95120fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
95220fa6a2cSEd Tanous             allowed.emplace_back("None");
95320fa6a2cSEd Tanous             allowed.emplace_back("Pxe");
95420fa6a2cSEd Tanous             allowed.emplace_back("Hdd");
95520fa6a2cSEd Tanous             allowed.emplace_back("Cd");
95620fa6a2cSEd Tanous             allowed.emplace_back("Diags");
95720fa6a2cSEd Tanous             allowed.emplace_back("BiosSetup");
95820fa6a2cSEd Tanous             allowed.emplace_back("Usb");
95920fa6a2cSEd Tanous 
960ac106bf6SEd Tanous             asyncResp->res
9610fda0f12SGeorge Liu                 .jsonValue["Boot"]
96220fa6a2cSEd Tanous                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
96320fa6a2cSEd Tanous                 std::move(allowed);
9641e1e598dSJonathan Doman             if (bootModeStr !=
965491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
966491d8ee7SSantosh Puranik             {
9671e1e598dSJonathan Doman                 auto rfMode = dbusToRfBootMode(bootModeStr);
968491d8ee7SSantosh Puranik                 if (!rfMode.empty())
969491d8ee7SSantosh Puranik                 {
970bd79bce8SPatrick Williams                     asyncResp->res
971bd79bce8SPatrick Williams                         .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
972491d8ee7SSantosh Puranik                 }
973491d8ee7SSantosh Puranik             }
9741e1e598dSJonathan Doman         });
975491d8ee7SSantosh Puranik }
976491d8ee7SSantosh Puranik 
977491d8ee7SSantosh Puranik /**
978c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
979491d8ee7SSantosh Puranik  *
980ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
981491d8ee7SSantosh Puranik  *
982491d8ee7SSantosh Puranik  * @return None.
983491d8ee7SSantosh Puranik  */
984c21865c4SKonstantin Aladyshev 
985c21865c4SKonstantin Aladyshev inline void
986ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
987491d8ee7SSantosh Puranik {
988*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
989*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
9901e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9911e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
992ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9931e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
994491d8ee7SSantosh Puranik             if (ec)
995491d8ee7SSantosh Puranik             {
9965ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
9975ef735c8SNan Zhou                 {
9985ef735c8SNan Zhou                     return;
9995ef735c8SNan Zhou                 }
1000b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1001ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1002491d8ee7SSantosh Puranik                 return;
1003491d8ee7SSantosh Puranik             }
1004491d8ee7SSantosh Puranik 
100562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1006491d8ee7SSantosh Puranik 
10071e1e598dSJonathan Doman             auto rfSource = dbusToRfBootSource(bootSourceStr);
1008491d8ee7SSantosh Puranik             if (!rfSource.empty())
1009491d8ee7SSantosh Puranik             {
1010ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1011ac106bf6SEd Tanous                     rfSource;
1012491d8ee7SSantosh Puranik             }
1013cd9a4666SKonstantin Aladyshev 
1014cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1015cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1016ac106bf6SEd Tanous             getBootOverrideMode(asyncResp);
10171e1e598dSJonathan Doman         });
1018491d8ee7SSantosh Puranik }
1019491d8ee7SSantosh Puranik 
1020491d8ee7SSantosh Puranik /**
1021c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1022c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1023c21865c4SKonstantin Aladyshev  * state
1024491d8ee7SSantosh Puranik  *
1025ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1026491d8ee7SSantosh Puranik  *
1027491d8ee7SSantosh Puranik  * @return None.
1028491d8ee7SSantosh Puranik  */
1029491d8ee7SSantosh Puranik 
1030ac106bf6SEd Tanous inline void processBootOverrideEnable(
1031ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1032c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1033c21865c4SKonstantin Aladyshev {
1034c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1035c21865c4SKonstantin Aladyshev     {
1036ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1037ac106bf6SEd Tanous             "Disabled";
1038c21865c4SKonstantin Aladyshev         return;
1039c21865c4SKonstantin Aladyshev     }
1040c21865c4SKonstantin Aladyshev 
1041c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1042c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1043*deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1044*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
10451e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10461e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1047ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1048491d8ee7SSantosh Puranik             if (ec)
1049491d8ee7SSantosh Puranik             {
1050b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1051ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1052491d8ee7SSantosh Puranik                 return;
1053491d8ee7SSantosh Puranik             }
1054491d8ee7SSantosh Puranik 
1055c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1056c21865c4SKonstantin Aladyshev             {
1057ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1058ac106bf6SEd Tanous                     "Once";
1059c21865c4SKonstantin Aladyshev             }
1060c21865c4SKonstantin Aladyshev             else
1061c21865c4SKonstantin Aladyshev             {
1062ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1063c21865c4SKonstantin Aladyshev                     "Continuous";
1064c21865c4SKonstantin Aladyshev             }
10651e1e598dSJonathan Doman         });
1066491d8ee7SSantosh Puranik }
1067491d8ee7SSantosh Puranik 
1068491d8ee7SSantosh Puranik /**
1069c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1070c21865c4SKonstantin Aladyshev  *
1071ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1072c21865c4SKonstantin Aladyshev  *
1073c21865c4SKonstantin Aladyshev  * @return None.
1074c21865c4SKonstantin Aladyshev  */
1075c21865c4SKonstantin Aladyshev 
1076c21865c4SKonstantin Aladyshev inline void
1077ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1078c21865c4SKonstantin Aladyshev {
1079*deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1080*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
10811e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10821e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1083ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10841e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1085c21865c4SKonstantin Aladyshev             if (ec)
1086c21865c4SKonstantin Aladyshev             {
10875ef735c8SNan Zhou                 if (ec.value() == boost::asio::error::host_unreachable)
10885ef735c8SNan Zhou                 {
10895ef735c8SNan Zhou                     return;
10905ef735c8SNan Zhou                 }
1091b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1092ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1093c21865c4SKonstantin Aladyshev                 return;
1094c21865c4SKonstantin Aladyshev             }
1095c21865c4SKonstantin Aladyshev 
1096ac106bf6SEd Tanous             processBootOverrideEnable(asyncResp, bootOverrideEnable);
10971e1e598dSJonathan Doman         });
1098c21865c4SKonstantin Aladyshev }
1099c21865c4SKonstantin Aladyshev 
1100c21865c4SKonstantin Aladyshev /**
1101c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1102c21865c4SKonstantin Aladyshev  *
1103ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1104c21865c4SKonstantin Aladyshev  *
1105c21865c4SKonstantin Aladyshev  * @return None.
1106c21865c4SKonstantin Aladyshev  */
1107ac106bf6SEd Tanous inline void
1108ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1109c21865c4SKonstantin Aladyshev {
111062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1111c21865c4SKonstantin Aladyshev 
1112ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1113ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1114ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1115c21865c4SKonstantin Aladyshev }
1116c21865c4SKonstantin Aladyshev 
1117c21865c4SKonstantin Aladyshev /**
1118c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1119c0557e1aSGunnar Mills  *
1120c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1121c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1122c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1123c0557e1aSGunnar Mills  * last power operation time.
1124c0557e1aSGunnar Mills  *
1125ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1126c0557e1aSGunnar Mills  *
1127c0557e1aSGunnar Mills  * @return None.
1128c0557e1aSGunnar Mills  */
1129ac106bf6SEd Tanous inline void
1130ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1131c0557e1aSGunnar Mills {
113262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1133c0557e1aSGunnar Mills 
1134*deae6a78SEd Tanous     dbus::utility::getProperty<uint64_t>(
1135*deae6a78SEd Tanous         "xyz.openbmc_project.State.Chassis",
11361e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11371e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1138ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1139ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1140c0557e1aSGunnar Mills             if (ec)
1141c0557e1aSGunnar Mills             {
114262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1143c0557e1aSGunnar Mills                 return;
1144c0557e1aSGunnar Mills             }
1145c0557e1aSGunnar Mills 
1146c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1147c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11481e1e598dSJonathan Doman             uint64_t lastResetTimeStamp = lastResetTime / 1000;
1149c0557e1aSGunnar Mills 
1150c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1151ac106bf6SEd Tanous             asyncResp->res.jsonValue["LastResetTime"] =
11522b82937eSEd Tanous                 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11531e1e598dSJonathan Doman         });
1154c0557e1aSGunnar Mills }
1155c0557e1aSGunnar Mills 
1156c0557e1aSGunnar Mills /**
1157797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1158797d5daeSCorey Hardesty  *
1159797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1160797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1161797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1162797d5daeSCorey Hardesty  * dbus.
1163797d5daeSCorey Hardesty  *
1164ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1165797d5daeSCorey Hardesty  *
1166797d5daeSCorey Hardesty  * @return None.
1167797d5daeSCorey Hardesty  */
1168ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1169ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1170797d5daeSCorey Hardesty {
117162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1172797d5daeSCorey Hardesty 
1173*deae6a78SEd Tanous     dbus::utility::getAllProperties(
1174*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1175797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1176ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1177ac106bf6SEd Tanous             const boost::system::error_code& ec,
1178797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1179797d5daeSCorey Hardesty             if (ec)
1180797d5daeSCorey Hardesty             {
1181797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1182797d5daeSCorey Hardesty                 {
118362598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1184ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1185797d5daeSCorey Hardesty                 }
1186797d5daeSCorey Hardesty                 return;
1187797d5daeSCorey Hardesty             }
1188797d5daeSCorey Hardesty 
1189797d5daeSCorey Hardesty             const uint32_t* attemptsLeft = nullptr;
1190797d5daeSCorey Hardesty             const uint32_t* retryAttempts = nullptr;
1191797d5daeSCorey Hardesty 
1192797d5daeSCorey Hardesty             const bool success = sdbusplus::unpackPropertiesNoThrow(
1193bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1194bd79bce8SPatrick Williams                 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
1195797d5daeSCorey Hardesty 
1196797d5daeSCorey Hardesty             if (!success)
1197797d5daeSCorey Hardesty             {
1198ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1199797d5daeSCorey Hardesty                 return;
1200797d5daeSCorey Hardesty             }
1201797d5daeSCorey Hardesty 
1202797d5daeSCorey Hardesty             if (attemptsLeft != nullptr)
1203797d5daeSCorey Hardesty             {
1204ac106bf6SEd Tanous                 asyncResp->res
1205ac106bf6SEd Tanous                     .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1206797d5daeSCorey Hardesty                     *attemptsLeft;
1207797d5daeSCorey Hardesty             }
1208797d5daeSCorey Hardesty 
1209797d5daeSCorey Hardesty             if (retryAttempts != nullptr)
1210797d5daeSCorey Hardesty             {
1211ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1212797d5daeSCorey Hardesty                     *retryAttempts;
1213797d5daeSCorey Hardesty             }
1214797d5daeSCorey Hardesty         });
1215797d5daeSCorey Hardesty }
1216797d5daeSCorey Hardesty 
1217797d5daeSCorey Hardesty /**
12186bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12196bd5a8d2SGunnar Mills  *
1220ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12216bd5a8d2SGunnar Mills  *
12226bd5a8d2SGunnar Mills  * @return None.
12236bd5a8d2SGunnar Mills  */
1224797d5daeSCorey Hardesty inline void
1225ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12266bd5a8d2SGunnar Mills {
122762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12286bd5a8d2SGunnar Mills 
1229*deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1230*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
12311e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12321e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1233ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1234ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12356bd5a8d2SGunnar Mills             if (ec)
12366bd5a8d2SGunnar Mills             {
1237797d5daeSCorey Hardesty                 if (ec.value() != EBADR)
1238797d5daeSCorey Hardesty                 {
123962598e31SEd Tanous                     BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1240ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1241797d5daeSCorey Hardesty                 }
12426bd5a8d2SGunnar Mills                 return;
12436bd5a8d2SGunnar Mills             }
12446bd5a8d2SGunnar Mills 
124562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1246e05aec50SEd Tanous             if (autoRebootEnabled)
12476bd5a8d2SGunnar Mills             {
1248ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12496bd5a8d2SGunnar Mills                     "RetryAttempts";
12506bd5a8d2SGunnar Mills             }
12516bd5a8d2SGunnar Mills             else
12526bd5a8d2SGunnar Mills             {
1253ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1254ac106bf6SEd Tanous                     "Disabled";
12556bd5a8d2SGunnar Mills             }
1256ac106bf6SEd Tanous             getAutomaticRebootAttempts(asyncResp);
125769f35306SGunnar Mills 
125869f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
125969f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
126069f35306SGunnar Mills             // RetryAttempts.
126120fa6a2cSEd Tanous             nlohmann::json::array_t allowed;
126220fa6a2cSEd Tanous             allowed.emplace_back("Disabled");
126320fa6a2cSEd Tanous             allowed.emplace_back("RetryAttempts");
1264ac106bf6SEd Tanous             asyncResp->res
1265bd79bce8SPatrick Williams                 .jsonValue["Boot"]
1266bd79bce8SPatrick Williams                           ["AutomaticRetryConfig@Redfish.AllowableValues"] =
126720fa6a2cSEd Tanous                 std::move(allowed);
12681e1e598dSJonathan Doman         });
12696bd5a8d2SGunnar Mills }
12706bd5a8d2SGunnar Mills 
12716bd5a8d2SGunnar Mills /**
1272797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1273797d5daeSCorey Hardesty  *
1274ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1275797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1276797d5daeSCorey Hardesty  *
1277797d5daeSCorey Hardesty  *@return None.
1278797d5daeSCorey Hardesty  */
1279797d5daeSCorey Hardesty 
1280ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1281ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1282797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1283797d5daeSCorey Hardesty {
128462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
128587c44966SAsmitha Karunanithi     setDbusProperty(
1286e93abac6SGinu George         asyncResp, "Boot/AutomaticRetryAttempts",
1287e93abac6SGinu George         "xyz.openbmc_project.State.Host",
128887c44966SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
12899ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1290e93abac6SGinu George         retryAttempts);
1291797d5daeSCorey Hardesty }
1292797d5daeSCorey Hardesty 
12938d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12948d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12958d69c668SEd Tanous {
12968d69c668SEd Tanous     if (value ==
12978d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12988d69c668SEd Tanous     {
12998d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13008d69c668SEd Tanous     }
13018d69c668SEd Tanous     if (value ==
13028d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13038d69c668SEd Tanous     {
13048d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13058d69c668SEd Tanous     }
13068d69c668SEd Tanous     if (value ==
13073a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13088d69c668SEd Tanous     {
13098d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13108d69c668SEd Tanous     }
13118d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13128d69c668SEd Tanous     {
13138d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13148d69c668SEd Tanous     }
13158d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13168d69c668SEd Tanous }
1317797d5daeSCorey Hardesty /**
1318c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1319c6a620f2SGeorge Liu  *
1320ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1321c6a620f2SGeorge Liu  *
1322c6a620f2SGeorge Liu  * @return None.
1323c6a620f2SGeorge Liu  */
13248d1b46d7Szhanghch05 inline void
1325ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1326c6a620f2SGeorge Liu {
132762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1328c6a620f2SGeorge Liu 
1329*deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
1330*deae6a78SEd Tanous         "xyz.openbmc_project.Settings",
13311e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13321e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1333ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13345e7e2dc5SEd Tanous                     const std::string& policy) {
1335c6a620f2SGeorge Liu             if (ec)
1336c6a620f2SGeorge Liu             {
133762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1338c6a620f2SGeorge Liu                 return;
1339c6a620f2SGeorge Liu             }
13408d69c668SEd Tanous             computer_system::PowerRestorePolicyTypes restore =
13418d69c668SEd Tanous                 redfishPowerRestorePolicyFromDbus(policy);
13428d69c668SEd Tanous             if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1343c6a620f2SGeorge Liu             {
1344ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1345c6a620f2SGeorge Liu                 return;
1346c6a620f2SGeorge Liu             }
1347c6a620f2SGeorge Liu 
13488d69c668SEd Tanous             asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13491e1e598dSJonathan Doman         });
1350c6a620f2SGeorge Liu }
1351c6a620f2SGeorge Liu 
1352c6a620f2SGeorge Liu /**
13539dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13549dcfe8c1SAlbert Zhang  *
13559dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13569dcfe8c1SAlbert Zhang  *
13579dcfe8c1SAlbert Zhang  * @return None.
13589dcfe8c1SAlbert Zhang  */
13599dcfe8c1SAlbert Zhang inline void
13609dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13619dcfe8c1SAlbert Zhang {
136262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13639dcfe8c1SAlbert Zhang 
1364*deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
1365*deae6a78SEd Tanous         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
13669dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13679dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13689dcfe8c1SAlbert Zhang             if (ec)
13699dcfe8c1SAlbert Zhang             {
13709dcfe8c1SAlbert Zhang                 if (ec.value() != EBADR)
13719dcfe8c1SAlbert Zhang                 {
1372b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13739dcfe8c1SAlbert Zhang                     messages::internalError(asyncResp->res);
13749dcfe8c1SAlbert Zhang                 }
13759dcfe8c1SAlbert Zhang                 return;
13769dcfe8c1SAlbert Zhang             }
13779dcfe8c1SAlbert Zhang 
13789dcfe8c1SAlbert Zhang             if (value)
13799dcfe8c1SAlbert Zhang             {
1380539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1381539d8c6bSEd Tanous                     computer_system::StopBootOnFault::AnyFault;
13829dcfe8c1SAlbert Zhang             }
13839dcfe8c1SAlbert Zhang             else
13849dcfe8c1SAlbert Zhang             {
1385539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1386539d8c6bSEd Tanous                     computer_system::StopBootOnFault::Never;
13879dcfe8c1SAlbert Zhang             }
13889dcfe8c1SAlbert Zhang         });
13899dcfe8c1SAlbert Zhang }
13909dcfe8c1SAlbert Zhang 
13919dcfe8c1SAlbert Zhang /**
13921981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13931981771bSAli Ahmed  * TPM is required for booting the host.
13941981771bSAli Ahmed  *
1395ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
13961981771bSAli Ahmed  *
13971981771bSAli Ahmed  * @return None.
13981981771bSAli Ahmed  */
13991981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1400ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14011981771bSAli Ahmed {
140262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1403e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1404e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1405e99073f5SGeorge Liu     dbus::utility::getSubTree(
1406e99073f5SGeorge Liu         "/", 0, interfaces,
1407ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1408b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14091981771bSAli Ahmed             if (ec)
14101981771bSAli Ahmed             {
1411bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
1412bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
14131981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
14141981771bSAli Ahmed                 // error occurs
14151981771bSAli Ahmed                 return;
14161981771bSAli Ahmed             }
141726f6976fSEd Tanous             if (subtree.empty())
14181981771bSAli Ahmed             {
14191981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
14201981771bSAli Ahmed                 // if there is no instance found
14211981771bSAli Ahmed                 return;
14221981771bSAli Ahmed             }
14231981771bSAli Ahmed 
14241981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
14251981771bSAli Ahmed             if (subtree.size() > 1)
14261981771bSAli Ahmed             {
142762598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
142862598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
142962598e31SEd Tanous                     subtree.size());
14301981771bSAli Ahmed                 // Throw an internal Error and return
1431ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14321981771bSAli Ahmed                 return;
14331981771bSAli Ahmed             }
14341981771bSAli Ahmed 
14351981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14361981771bSAli Ahmed             // field
14371981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14381981771bSAli Ahmed             {
143962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1440ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14411981771bSAli Ahmed                 return;
14421981771bSAli Ahmed             }
14431981771bSAli Ahmed 
14441981771bSAli Ahmed             const std::string& path = subtree[0].first;
14451981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14461981771bSAli Ahmed 
14471981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
1448*deae6a78SEd Tanous             dbus::utility::getProperty<bool>(
1449*deae6a78SEd Tanous                 serv, path, "xyz.openbmc_project.Control.TPM.Policy",
1450*deae6a78SEd Tanous                 "TPMEnable",
1451ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2,
1452ac106bf6SEd Tanous                             bool tpmRequired) {
14538a592810SEd Tanous                     if (ec2)
14541981771bSAli Ahmed                     {
1455bd79bce8SPatrick Williams                         BMCWEB_LOG_ERROR(
1456bd79bce8SPatrick Williams                             "D-BUS response error on TPM.Policy Get{}", ec2);
1457ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
14581981771bSAli Ahmed                         return;
14591981771bSAli Ahmed                     }
14601981771bSAli Ahmed 
14611e1e598dSJonathan Doman                     if (tpmRequired)
14621981771bSAli Ahmed                     {
1463ac106bf6SEd Tanous                         asyncResp->res
1464ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14651981771bSAli Ahmed                             "Required";
14661981771bSAli Ahmed                     }
14671981771bSAli Ahmed                     else
14681981771bSAli Ahmed                     {
1469ac106bf6SEd Tanous                         asyncResp->res
1470ac106bf6SEd Tanous                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14711981771bSAli Ahmed                             "Disabled";
14721981771bSAli Ahmed                     }
14731e1e598dSJonathan Doman                 });
1474e99073f5SGeorge Liu         });
14751981771bSAli Ahmed }
14761981771bSAli Ahmed 
14771981771bSAli Ahmed /**
14781c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14791c05dae3SAli Ahmed  * TPM is required for booting the host.
14801c05dae3SAli Ahmed  *
1481ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14821c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14831c05dae3SAli Ahmed  *
14841c05dae3SAli Ahmed  * @return None.
14851c05dae3SAli Ahmed  */
14861c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1487ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14881c05dae3SAli Ahmed {
148962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1490e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1491e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1492e99073f5SGeorge Liu     dbus::utility::getSubTree(
1493e99073f5SGeorge Liu         "/", 0, interfaces,
1494ac106bf6SEd Tanous         [asyncResp,
1495e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1496e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14971c05dae3SAli Ahmed             if (ec)
14981c05dae3SAli Ahmed             {
1499bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
1500bd79bce8SPatrick Williams                     "DBUS response error on TPM.Policy GetSubTree{}", ec);
1501ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15021c05dae3SAli Ahmed                 return;
15031c05dae3SAli Ahmed             }
150426f6976fSEd Tanous             if (subtree.empty())
15051c05dae3SAli Ahmed             {
1506bd79bce8SPatrick Williams                 messages::propertyValueNotInList(asyncResp->res,
1507bd79bce8SPatrick Williams                                                  "ComputerSystem",
15081c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
15091c05dae3SAli Ahmed                 return;
15101c05dae3SAli Ahmed             }
15111c05dae3SAli Ahmed 
15121c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
15131c05dae3SAli Ahmed             if (subtree.size() > 1)
15141c05dae3SAli Ahmed             {
151562598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
151662598e31SEd Tanous                     "DBUS response has more than 1 TPM Enable object:{}",
151762598e31SEd Tanous                     subtree.size());
15181c05dae3SAli Ahmed                 // Throw an internal Error and return
1519ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15201c05dae3SAli Ahmed                 return;
15211c05dae3SAli Ahmed             }
15221c05dae3SAli Ahmed 
15231c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
15241c05dae3SAli Ahmed             // field
15251c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15261c05dae3SAli Ahmed             {
152762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1528ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15291c05dae3SAli Ahmed                 return;
15301c05dae3SAli Ahmed             }
15311c05dae3SAli Ahmed 
15321c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
15331c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
15341c05dae3SAli Ahmed 
15351c05dae3SAli Ahmed             if (serv.empty())
15361c05dae3SAli Ahmed             {
153762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1538ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15391c05dae3SAli Ahmed                 return;
15401c05dae3SAli Ahmed             }
15411c05dae3SAli Ahmed 
15421c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
1543e93abac6SGinu George             setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1544e93abac6SGinu George                             path, "xyz.openbmc_project.Control.TPM.Policy",
1545e93abac6SGinu George                             "TPMEnable", tpmRequired);
1546e99073f5SGeorge Liu         });
15471c05dae3SAli Ahmed }
15481c05dae3SAli Ahmed 
15491c05dae3SAli Ahmed /**
1550491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1551491d8ee7SSantosh Puranik  *
1552ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1553cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1554cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1555cd9a4666SKonstantin Aladyshev  */
1556ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1557cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1558cd9a4666SKonstantin Aladyshev {
1559c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1560cd9a4666SKonstantin Aladyshev 
1561c21865c4SKonstantin Aladyshev     if (!bootType)
1562cd9a4666SKonstantin Aladyshev     {
1563c21865c4SKonstantin Aladyshev         return;
1564c21865c4SKonstantin Aladyshev     }
1565c21865c4SKonstantin Aladyshev 
1566cd9a4666SKonstantin Aladyshev     // Source target specified
156762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1568cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1569cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1570cd9a4666SKonstantin Aladyshev     {
1571cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1572cd9a4666SKonstantin Aladyshev     }
1573cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1574cd9a4666SKonstantin Aladyshev     {
1575cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1576cd9a4666SKonstantin Aladyshev     }
1577cd9a4666SKonstantin Aladyshev     else
1578cd9a4666SKonstantin Aladyshev     {
157962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
158062598e31SEd Tanous                          "BootSourceOverrideMode: {}",
158162598e31SEd Tanous                          *bootType);
1582ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1583cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1584cd9a4666SKonstantin Aladyshev         return;
1585cd9a4666SKonstantin Aladyshev     }
1586cd9a4666SKonstantin Aladyshev 
1587cd9a4666SKonstantin Aladyshev     // Act on validated parameters
158862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1589cd9a4666SKonstantin Aladyshev 
1590e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1591e93abac6SGinu George                     "xyz.openbmc_project.Settings",
159287c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
159387c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
159487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1595e93abac6SGinu George                     bootTypeStr);
1596cd9a4666SKonstantin Aladyshev }
1597cd9a4666SKonstantin Aladyshev 
1598cd9a4666SKonstantin Aladyshev /**
1599cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1600cd9a4666SKonstantin Aladyshev  *
1601ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1602ac106bf6SEd Tanous  * message.
1603c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1604c21865c4SKonstantin Aladyshev  * @return Integer error code.
1605c21865c4SKonstantin Aladyshev  */
1606ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1607c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1608c21865c4SKonstantin Aladyshev {
1609c21865c4SKonstantin Aladyshev     if (!bootEnable)
1610c21865c4SKonstantin Aladyshev     {
1611c21865c4SKonstantin Aladyshev         return;
1612c21865c4SKonstantin Aladyshev     }
1613c21865c4SKonstantin Aladyshev     // Source target specified
161462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1615c21865c4SKonstantin Aladyshev 
1616c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1617c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1618c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1619c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1620c21865c4SKonstantin Aladyshev     {
1621c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1622c21865c4SKonstantin Aladyshev     }
1623c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1624c21865c4SKonstantin Aladyshev     {
1625c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1626c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1627c21865c4SKonstantin Aladyshev     }
1628c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1629c21865c4SKonstantin Aladyshev     {
1630c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1631c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1632c21865c4SKonstantin Aladyshev     }
1633c21865c4SKonstantin Aladyshev     else
1634c21865c4SKonstantin Aladyshev     {
163562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
163662598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
163762598e31SEd Tanous             *bootEnable);
1638ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1639c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1640c21865c4SKonstantin Aladyshev         return;
1641c21865c4SKonstantin Aladyshev     }
1642c21865c4SKonstantin Aladyshev 
1643c21865c4SKonstantin Aladyshev     // Act on validated parameters
164462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1645c21865c4SKonstantin Aladyshev 
1646e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1647e93abac6SGinu George                     "xyz.openbmc_project.Settings",
164887c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
164987c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
165087c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1651e93abac6SGinu George                     bootOverrideEnable);
1652c21865c4SKonstantin Aladyshev 
1653c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1654c21865c4SKonstantin Aladyshev     {
1655c21865c4SKonstantin Aladyshev         return;
1656c21865c4SKonstantin Aladyshev     }
1657c21865c4SKonstantin Aladyshev 
1658c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1659c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
166062598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
166162598e31SEd Tanous                      bootOverridePersistent);
1662c21865c4SKonstantin Aladyshev 
1663e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1664e93abac6SGinu George                     "xyz.openbmc_project.Settings",
166587c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
166687c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot/one_time"),
166787c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1668e93abac6SGinu George                     !bootOverridePersistent);
1669c21865c4SKonstantin Aladyshev }
1670c21865c4SKonstantin Aladyshev 
1671c21865c4SKonstantin Aladyshev /**
1672c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1673c21865c4SKonstantin Aladyshev  *
1674ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1675491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1676491d8ee7SSantosh Puranik  *
1677265c1602SJohnathan Mantey  * @return Integer error code.
1678491d8ee7SSantosh Puranik  */
1679ac106bf6SEd Tanous inline void
1680ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1681cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1682491d8ee7SSantosh Puranik {
1683c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1684c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1685944ffaf9SJohnathan Mantey 
1686c21865c4SKonstantin Aladyshev     if (!bootSource)
1687491d8ee7SSantosh Puranik     {
1688c21865c4SKonstantin Aladyshev         return;
1689c21865c4SKonstantin Aladyshev     }
1690c21865c4SKonstantin Aladyshev 
1691491d8ee7SSantosh Puranik     // Source target specified
169262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1693491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1694ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1695ac106bf6SEd Tanous                              bootModeStr) != 0)
1696491d8ee7SSantosh Puranik     {
169762598e31SEd Tanous         BMCWEB_LOG_DEBUG(
169862598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
169962598e31SEd Tanous             *bootSource);
1700ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1701491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1702491d8ee7SSantosh Puranik         return;
1703491d8ee7SSantosh Puranik     }
1704491d8ee7SSantosh Puranik 
1705944ffaf9SJohnathan Mantey     // Act on validated parameters
170662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
170762598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1708944ffaf9SJohnathan Mantey 
1709e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1710e93abac6SGinu George                     "xyz.openbmc_project.Settings",
171187c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
171287c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
171387c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1714e93abac6SGinu George                     bootSourceStr);
1715e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1716e93abac6SGinu George                     "xyz.openbmc_project.Settings",
171787c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
171887c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
171987c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1720e93abac6SGinu George                     bootModeStr);
1721cd9a4666SKonstantin Aladyshev }
1722944ffaf9SJohnathan Mantey 
1723cd9a4666SKonstantin Aladyshev /**
1724c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1725491d8ee7SSantosh Puranik  *
1726ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1727491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1728cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1729491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1730491d8ee7SSantosh Puranik  *
1731265c1602SJohnathan Mantey  * @return Integer error code.
1732491d8ee7SSantosh Puranik  */
1733c21865c4SKonstantin Aladyshev 
1734ac106bf6SEd Tanous inline void
1735ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1736c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1737c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1738c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1739491d8ee7SSantosh Puranik {
174062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1741491d8ee7SSantosh Puranik 
1742ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1743ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1744ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1745491d8ee7SSantosh Puranik }
1746491d8ee7SSantosh Puranik 
1747c6a620f2SGeorge Liu /**
174898e386ecSGunnar Mills  * @brief Sets AssetTag
174998e386ecSGunnar Mills  *
1750ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
175198e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
175298e386ecSGunnar Mills  *
175398e386ecSGunnar Mills  * @return None.
175498e386ecSGunnar Mills  */
1755ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
175698e386ecSGunnar Mills                         const std::string& assetTag)
175798e386ecSGunnar Mills {
1758e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1759e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1760e99073f5SGeorge Liu     dbus::utility::getSubTree(
1761e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1762ac106bf6SEd Tanous         [asyncResp,
1763e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1764b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
176598e386ecSGunnar Mills             if (ec)
176698e386ecSGunnar Mills             {
176762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1768ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
176998e386ecSGunnar Mills                 return;
177098e386ecSGunnar Mills             }
177126f6976fSEd Tanous             if (subtree.empty())
177298e386ecSGunnar Mills             {
177362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1774ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
177598e386ecSGunnar Mills                 return;
177698e386ecSGunnar Mills             }
177798e386ecSGunnar Mills             // Assume only 1 system D-Bus object
177898e386ecSGunnar Mills             // Throw an error if there is more than 1
177998e386ecSGunnar Mills             if (subtree.size() > 1)
178098e386ecSGunnar Mills             {
178162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1782ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
178398e386ecSGunnar Mills                 return;
178498e386ecSGunnar Mills             }
178598e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
178698e386ecSGunnar Mills             {
178762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1788ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
178998e386ecSGunnar Mills                 return;
179098e386ecSGunnar Mills             }
179198e386ecSGunnar Mills 
179298e386ecSGunnar Mills             const std::string& path = subtree[0].first;
179398e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
179498e386ecSGunnar Mills 
179598e386ecSGunnar Mills             if (service.empty())
179698e386ecSGunnar Mills             {
179762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1798ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
179998e386ecSGunnar Mills                 return;
180098e386ecSGunnar Mills             }
180198e386ecSGunnar Mills 
1802e93abac6SGinu George             setDbusProperty(asyncResp, "AssetTag", service, path,
180387c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1804e93abac6SGinu George                             "AssetTag", assetTag);
1805e99073f5SGeorge Liu         });
180698e386ecSGunnar Mills }
180798e386ecSGunnar Mills 
180898e386ecSGunnar Mills /**
18099dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18109dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18119dcfe8c1SAlbert Zhang  *
18129dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18139dcfe8c1SAlbert Zhang  * stopBootOnFault
18149dcfe8c1SAlbert Zhang  *
18159dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18169dcfe8c1SAlbert Zhang  */
18179dcfe8c1SAlbert Zhang inline std::optional<bool>
18189dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
18199dcfe8c1SAlbert Zhang {
18209dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18219dcfe8c1SAlbert Zhang     {
18229dcfe8c1SAlbert Zhang         return true;
18239dcfe8c1SAlbert Zhang     }
18249dcfe8c1SAlbert Zhang 
18259dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18269dcfe8c1SAlbert Zhang     {
18279dcfe8c1SAlbert Zhang         return false;
18289dcfe8c1SAlbert Zhang     }
18299dcfe8c1SAlbert Zhang 
18309dcfe8c1SAlbert Zhang     return std::nullopt;
18319dcfe8c1SAlbert Zhang }
18329dcfe8c1SAlbert Zhang 
18339dcfe8c1SAlbert Zhang /**
18349dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18359dcfe8c1SAlbert Zhang  *
1836fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18379dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18389dcfe8c1SAlbert Zhang  *
18399dcfe8c1SAlbert Zhang  * @return None.
18409dcfe8c1SAlbert Zhang  */
1841fc3edfddSEd Tanous inline void
1842fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18439dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18449dcfe8c1SAlbert Zhang {
184562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18469dcfe8c1SAlbert Zhang 
18479dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18489dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18499dcfe8c1SAlbert Zhang     {
185062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
185162598e31SEd Tanous                          stopBootOnFault);
1852fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18539dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18549dcfe8c1SAlbert Zhang         return;
18559dcfe8c1SAlbert Zhang     }
18569dcfe8c1SAlbert Zhang 
1857e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1858e93abac6SGinu George                     "xyz.openbmc_project.Settings",
185987c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
186087c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1861fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1862e93abac6SGinu George                     *stopBootEnabled);
18639dcfe8c1SAlbert Zhang }
18649dcfe8c1SAlbert Zhang 
18659dcfe8c1SAlbert Zhang /**
186669f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
186769f35306SGunnar Mills  *
1868ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
186969f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
187069f35306SGunnar Mills  *
187169f35306SGunnar Mills  * @return None.
187269f35306SGunnar Mills  */
1873ac106bf6SEd Tanous inline void
1874ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1875f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
187669f35306SGunnar Mills {
187762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
187869f35306SGunnar Mills 
187969f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1880543f4400SEd Tanous     bool autoRebootEnabled = false;
188169f35306SGunnar Mills 
188269f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
188369f35306SGunnar Mills     {
188469f35306SGunnar Mills         autoRebootEnabled = false;
188569f35306SGunnar Mills     }
188669f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
188769f35306SGunnar Mills     {
188869f35306SGunnar Mills         autoRebootEnabled = true;
188969f35306SGunnar Mills     }
189069f35306SGunnar Mills     else
189169f35306SGunnar Mills     {
189262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
189362598e31SEd Tanous                          automaticRetryConfig);
1894ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
189569f35306SGunnar Mills                                          "AutomaticRetryConfig");
189669f35306SGunnar Mills         return;
189769f35306SGunnar Mills     }
189869f35306SGunnar Mills 
1899e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1900e93abac6SGinu George                     "xyz.openbmc_project.Settings",
190187c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
190287c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/auto_reboot"),
190387c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1904e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
190569f35306SGunnar Mills }
190669f35306SGunnar Mills 
19078d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19088d69c668SEd Tanous {
19098d69c668SEd Tanous     if (policy == "AlwaysOn")
19108d69c668SEd Tanous     {
19118d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19128d69c668SEd Tanous     }
19138d69c668SEd Tanous     if (policy == "AlwaysOff")
19148d69c668SEd Tanous     {
19158d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19168d69c668SEd Tanous     }
19178d69c668SEd Tanous     if (policy == "LastState")
19188d69c668SEd Tanous     {
19198d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19208d69c668SEd Tanous     }
19218d69c668SEd Tanous     return "";
19228d69c668SEd Tanous }
19238d69c668SEd Tanous 
192469f35306SGunnar Mills /**
1925c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1926c6a620f2SGeorge Liu  *
1927ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1928c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1929c6a620f2SGeorge Liu  *
1930c6a620f2SGeorge Liu  * @return None.
1931c6a620f2SGeorge Liu  */
19328d1b46d7Szhanghch05 inline void
1933ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19348d69c668SEd Tanous                           std::string_view policy)
1935c6a620f2SGeorge Liu {
193662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1937c6a620f2SGeorge Liu 
19388d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1939c6a620f2SGeorge Liu 
19408d69c668SEd Tanous     if (powerRestorePolicy.empty())
1941c6a620f2SGeorge Liu     {
1942ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19434e69c904SGunnar Mills                                          "PowerRestorePolicy");
1944c6a620f2SGeorge Liu         return;
1945c6a620f2SGeorge Liu     }
1946c6a620f2SGeorge Liu 
194787c44966SAsmitha Karunanithi     setDbusProperty(
1948e93abac6SGinu George         asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
194987c44966SAsmitha Karunanithi         sdbusplus::message::object_path(
195087c44966SAsmitha Karunanithi             "/xyz/openbmc_project/control/host0/power_restore_policy"),
19519ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1952e93abac6SGinu George         powerRestorePolicy);
1953c6a620f2SGeorge Liu }
1954c6a620f2SGeorge Liu 
1955a6349918SAppaRao Puli /**
1956a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1957a6349918SAppaRao Puli  *
195825b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
195925b54dbaSEd Tanous  * calls.
1960a6349918SAppaRao Puli  *
1961a6349918SAppaRao Puli  * @return None.
1962a6349918SAppaRao Puli  */
196325b54dbaSEd Tanous inline void
196425b54dbaSEd Tanous     getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1965a6349918SAppaRao Puli {
196662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1967*deae6a78SEd Tanous     dbus::utility::getAllProperties(
1968*deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1969*deae6a78SEd Tanous         "xyz.openbmc_project.PFR.Attributes",
1970ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1971b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1972b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1973bd79bce8SPatrick Williams                 asyncResp->res
1974bd79bce8SPatrick Williams                     .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1975ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
19761d834d49SEd Tanous                 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1977bd79bce8SPatrick Williams             oemPFR["@odata.type"] =
1978bd79bce8SPatrick Williams                 "#OpenBMCComputerSystem.FirmwareProvisioning";
197950626f4fSJames Feist 
1980a6349918SAppaRao Puli             if (ec)
1981a6349918SAppaRao Puli             {
198262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1983b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1984539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
1985539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
1986a6349918SAppaRao Puli                 return;
1987a6349918SAppaRao Puli             }
1988a6349918SAppaRao Puli 
1989a6349918SAppaRao Puli             const bool* provState = nullptr;
1990a6349918SAppaRao Puli             const bool* lockState = nullptr;
1991bc1d29deSKrzysztof Grobelny 
1992bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
1993bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
1994bd79bce8SPatrick Williams                 "UfmProvisioned", provState, "UfmLocked", lockState);
1995bc1d29deSKrzysztof Grobelny 
1996bc1d29deSKrzysztof Grobelny             if (!success)
1997a6349918SAppaRao Puli             {
1998ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1999bc1d29deSKrzysztof Grobelny                 return;
2000a6349918SAppaRao Puli             }
2001a6349918SAppaRao Puli 
2002a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2003a6349918SAppaRao Puli             {
200462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2005ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2006a6349918SAppaRao Puli                 return;
2007a6349918SAppaRao Puli             }
2008a6349918SAppaRao Puli 
200925b54dbaSEd Tanous             if (*provState)
2010a6349918SAppaRao Puli             {
201125b54dbaSEd Tanous                 if (*lockState)
2012a6349918SAppaRao Puli                 {
2013539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2014539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedAndLocked;
2015a6349918SAppaRao Puli                 }
2016a6349918SAppaRao Puli                 else
2017a6349918SAppaRao Puli                 {
2018539d8c6bSEd Tanous                     oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2019539d8c6bSEd Tanous                         FirmwareProvisioningStatus::ProvisionedButNotLocked;
2020a6349918SAppaRao Puli                 }
2021a6349918SAppaRao Puli             }
2022a6349918SAppaRao Puli             else
2023a6349918SAppaRao Puli             {
2024539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2025539d8c6bSEd Tanous                     FirmwareProvisioningStatus::NotProvisioned;
2026a6349918SAppaRao Puli             }
2027bc1d29deSKrzysztof Grobelny         });
2028a6349918SAppaRao Puli }
2029a6349918SAppaRao Puli 
2030491d8ee7SSantosh Puranik /**
20316b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20323a2d0424SChris Cain  *
20336b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20343a2d0424SChris Cain  *
20356b9ac4f2SChris Cain  * @return PowerMode enum
20363a2d0424SChris Cain  */
20376b9ac4f2SChris Cain inline computer_system::PowerMode
20386b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
20393a2d0424SChris Cain {
2040b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2041b6655101SChris Cain 
20426b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20433a2d0424SChris Cain     {
20446b9ac4f2SChris Cain         return PowerMode::Static;
20453a2d0424SChris Cain     }
20466b9ac4f2SChris Cain     if (modeString ==
20470fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20483a2d0424SChris Cain     {
20496b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20503a2d0424SChris Cain     }
20516b9ac4f2SChris Cain     if (modeString ==
20520fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20533a2d0424SChris Cain     {
20546b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2055b6655101SChris Cain     }
20566b9ac4f2SChris Cain     if (modeString ==
2057b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2058b6655101SChris Cain     {
20596b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2060b6655101SChris Cain     }
20616b9ac4f2SChris Cain     if (modeString ==
2062b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2063b6655101SChris Cain     {
20646b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2065b6655101SChris Cain     }
20666b9ac4f2SChris Cain     if (modeString ==
2067b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2068b6655101SChris Cain     {
20696b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20703a2d0424SChris Cain     }
20716b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20723a2d0424SChris Cain     {
20736b9ac4f2SChris Cain         return PowerMode::OEM;
20746b9ac4f2SChris Cain     }
20756b9ac4f2SChris Cain     // Any other values would be invalid
20766b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20776b9ac4f2SChris Cain     return PowerMode::Invalid;
20786b9ac4f2SChris Cain }
20796b9ac4f2SChris Cain 
20806b9ac4f2SChris Cain inline void
20816b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20826b9ac4f2SChris Cain                       const boost::system::error_code& ec,
20836b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
20846b9ac4f2SChris Cain {
20856b9ac4f2SChris Cain     if (ec)
20866b9ac4f2SChris Cain     {
20876b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
20886b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20896b9ac4f2SChris Cain         return;
20906b9ac4f2SChris Cain     }
20916b9ac4f2SChris Cain 
20926b9ac4f2SChris Cain     std::string powerMode;
20936b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
20946b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
20956b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
20966b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
20976b9ac4f2SChris Cain 
20986b9ac4f2SChris Cain     if (!success)
20996b9ac4f2SChris Cain     {
21006b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21016b9ac4f2SChris Cain         return;
21026b9ac4f2SChris Cain     }
21036b9ac4f2SChris Cain 
21046b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21056b9ac4f2SChris Cain     if (allowedModes == nullptr)
21066b9ac4f2SChris Cain     {
21076b9ac4f2SChris Cain         modeList.emplace_back("Static");
21086b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21096b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21103a2d0424SChris Cain     }
21113a2d0424SChris Cain     else
21123a2d0424SChris Cain     {
21136b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21146b9ac4f2SChris Cain         {
21156b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21166b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21176b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21186b9ac4f2SChris Cain             {
2119ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21206b9ac4f2SChris Cain                 continue;
21216b9ac4f2SChris Cain             }
21226b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21233a2d0424SChris Cain         }
21243a2d0424SChris Cain     }
21256b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21263a2d0424SChris Cain 
21276b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21286b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21296b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21306b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21316b9ac4f2SChris Cain     {
21326b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21336b9ac4f2SChris Cain         return;
21346b9ac4f2SChris Cain     }
21356b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21366b9ac4f2SChris Cain }
21373a2d0424SChris Cain /**
21383a2d0424SChris Cain  * @brief Retrieves system power mode
21393a2d0424SChris Cain  *
2140ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21413a2d0424SChris Cain  *
21423a2d0424SChris Cain  * @return None.
21433a2d0424SChris Cain  */
2144ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21453a2d0424SChris Cain {
214662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21473a2d0424SChris Cain 
21483a2d0424SChris Cain     // Get Power Mode object path:
2149e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2150e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2151e99073f5SGeorge Liu     dbus::utility::getSubTree(
2152e99073f5SGeorge Liu         "/", 0, interfaces,
2153ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2154b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21553a2d0424SChris Cain             if (ec)
21563a2d0424SChris Cain             {
2157bd79bce8SPatrick Williams                 BMCWEB_LOG_DEBUG(
2158bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
21593a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
21603a2d0424SChris Cain                 // error occurs
21613a2d0424SChris Cain                 return;
21623a2d0424SChris Cain             }
21633a2d0424SChris Cain             if (subtree.empty())
21643a2d0424SChris Cain             {
21653a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
21663a2d0424SChris Cain                 // if there is no instance found
21673a2d0424SChris Cain                 return;
21683a2d0424SChris Cain             }
21693a2d0424SChris Cain             if (subtree.size() > 1)
21703a2d0424SChris Cain             {
21713a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21723a2d0424SChris Cain                 // error
217362598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
217462598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
217562598e31SEd Tanous                     subtree.size());
2176ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21773a2d0424SChris Cain                 return;
21783a2d0424SChris Cain             }
21793a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21803a2d0424SChris Cain             {
218162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2182ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21833a2d0424SChris Cain                 return;
21843a2d0424SChris Cain             }
21853a2d0424SChris Cain             const std::string& path = subtree[0].first;
21863a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21873a2d0424SChris Cain             if (service.empty())
21883a2d0424SChris Cain             {
218962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2190ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21913a2d0424SChris Cain                 return;
21923a2d0424SChris Cain             }
21936b9ac4f2SChris Cain 
21946b9ac4f2SChris Cain             // Valid Power Mode object found, now read the mode properties
2195*deae6a78SEd Tanous             dbus::utility::getAllProperties(
21961e1e598dSJonathan Doman                 *crow::connections::systemBus, service, path,
21976b9ac4f2SChris Cain                 "xyz.openbmc_project.Control.Power.Mode",
2198bd79bce8SPatrick Williams                 [asyncResp](
2199bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
22006b9ac4f2SChris Cain                     const dbus::utility::DBusPropertiesMap& properties) {
22016b9ac4f2SChris Cain                     afterGetPowerMode(asyncResp, ec2, properties);
22021e1e598dSJonathan Doman                 });
2203e99073f5SGeorge Liu         });
22043a2d0424SChris Cain }
22053a2d0424SChris Cain 
22063a2d0424SChris Cain /**
22073a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22083a2d0424SChris Cain  * name associated with that string
22093a2d0424SChris Cain  *
2210ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2211b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22123a2d0424SChris Cain  *
22133a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22143a2d0424SChris Cain  */
22153a2d0424SChris Cain inline std::string
2216ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2217b6655101SChris Cain                       const nlohmann::json& modeValue)
22183a2d0424SChris Cain {
2219b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22203a2d0424SChris Cain     std::string mode;
22213a2d0424SChris Cain 
2222b6655101SChris Cain     if (modeValue == PowerMode::Static)
22233a2d0424SChris Cain     {
22243a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22253a2d0424SChris Cain     }
2226b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22273a2d0424SChris Cain     {
22280fda0f12SGeorge Liu         mode =
22290fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22303a2d0424SChris Cain     }
2231b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22323a2d0424SChris Cain     {
22333a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22343a2d0424SChris Cain     }
2235b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2236b6655101SChris Cain     {
2237b6655101SChris Cain         mode =
2238b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2239b6655101SChris Cain     }
2240b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2241b6655101SChris Cain     {
2242b6655101SChris Cain         mode =
2243b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2244b6655101SChris Cain     }
2245b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2246b6655101SChris Cain     {
2247b6655101SChris Cain         mode =
2248b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2249b6655101SChris Cain     }
22503a2d0424SChris Cain     else
22513a2d0424SChris Cain     {
2252b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2253ac106bf6SEd Tanous                                          "PowerMode");
22543a2d0424SChris Cain     }
22553a2d0424SChris Cain     return mode;
22563a2d0424SChris Cain }
22573a2d0424SChris Cain 
22583a2d0424SChris Cain /**
22593a2d0424SChris Cain  * @brief Sets system power mode.
22603a2d0424SChris Cain  *
2261ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22623a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22633a2d0424SChris Cain  *
22643a2d0424SChris Cain  * @return None.
22653a2d0424SChris Cain  */
2266ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22673a2d0424SChris Cain                          const std::string& pmode)
22683a2d0424SChris Cain {
226962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22703a2d0424SChris Cain 
2271ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22723a2d0424SChris Cain     if (powerMode.empty())
22733a2d0424SChris Cain     {
22743a2d0424SChris Cain         return;
22753a2d0424SChris Cain     }
22763a2d0424SChris Cain 
22773a2d0424SChris Cain     // Get Power Mode object path:
2278e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2279e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2280e99073f5SGeorge Liu     dbus::utility::getSubTree(
2281e99073f5SGeorge Liu         "/", 0, interfaces,
2282ac106bf6SEd Tanous         [asyncResp,
2283e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2284b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22853a2d0424SChris Cain             if (ec)
22863a2d0424SChris Cain             {
2287bd79bce8SPatrick Williams                 BMCWEB_LOG_ERROR(
2288bd79bce8SPatrick Williams                     "DBUS response error on Power.Mode GetSubTree {}", ec);
22893a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2290ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22913a2d0424SChris Cain                 return;
22923a2d0424SChris Cain             }
22933a2d0424SChris Cain             if (subtree.empty())
22943a2d0424SChris Cain             {
22953a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2296ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22973a2d0424SChris Cain                                            "PowerMode");
22983a2d0424SChris Cain                 return;
22993a2d0424SChris Cain             }
23003a2d0424SChris Cain             if (subtree.size() > 1)
23013a2d0424SChris Cain             {
23023a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
23033a2d0424SChris Cain                 // error
230462598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
230562598e31SEd Tanous                     "Found more than 1 system D-Bus Power.Mode objects: {}",
230662598e31SEd Tanous                     subtree.size());
2307ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23083a2d0424SChris Cain                 return;
23093a2d0424SChris Cain             }
23103a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23113a2d0424SChris Cain             {
231262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2313ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23143a2d0424SChris Cain                 return;
23153a2d0424SChris Cain             }
23163a2d0424SChris Cain             const std::string& path = subtree[0].first;
23173a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
23183a2d0424SChris Cain             if (service.empty())
23193a2d0424SChris Cain             {
232062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2321ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23223a2d0424SChris Cain                 return;
23233a2d0424SChris Cain             }
23243a2d0424SChris Cain 
232562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23263a2d0424SChris Cain 
23273a2d0424SChris Cain             // Set the Power Mode property
2328e93abac6SGinu George             setDbusProperty(asyncResp, "PowerMode", service, path,
2329bd79bce8SPatrick Williams                             "xyz.openbmc_project.Control.Power.Mode",
2330bd79bce8SPatrick Williams                             "PowerMode", powerMode);
2331e99073f5SGeorge Liu         });
23323a2d0424SChris Cain }
23333a2d0424SChris Cain 
23343a2d0424SChris Cain /**
233551709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
233651709ffdSYong Li  *
233751709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
233851709ffdSYong Li  *
233951709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
234051709ffdSYong Li  * translation cannot be done, returns an empty string.
234151709ffdSYong Li  */
234223a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
234351709ffdSYong Li {
234451709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
234551709ffdSYong Li     {
234651709ffdSYong Li         return "None";
234751709ffdSYong Li     }
23483174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
234951709ffdSYong Li     {
235051709ffdSYong Li         return "ResetSystem";
235151709ffdSYong Li     }
23523174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
235351709ffdSYong Li     {
235451709ffdSYong Li         return "PowerDown";
235551709ffdSYong Li     }
23563174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
235751709ffdSYong Li     {
235851709ffdSYong Li         return "PowerCycle";
235951709ffdSYong Li     }
236051709ffdSYong Li 
236151709ffdSYong Li     return "";
236251709ffdSYong Li }
236351709ffdSYong Li 
236451709ffdSYong Li /**
2365c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2366c45f0082SYong Li  *
2367c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2368c45f0082SYong Li  *
2369c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2370c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2371c45f0082SYong Li  */
2372c45f0082SYong Li 
237323a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2374c45f0082SYong Li {
2375c45f0082SYong Li     if (rfAction == "None")
2376c45f0082SYong Li     {
2377c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2378c45f0082SYong Li     }
23793174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2380c45f0082SYong Li     {
2381c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2382c45f0082SYong Li     }
23833174e4dfSEd Tanous     if (rfAction == "PowerDown")
2384c45f0082SYong Li     {
2385c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2386c45f0082SYong Li     }
23873174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2388c45f0082SYong Li     {
2389c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2390c45f0082SYong Li     }
2391c45f0082SYong Li 
2392c45f0082SYong Li     return "";
2393c45f0082SYong Li }
2394c45f0082SYong Li 
2395c45f0082SYong Li /**
239651709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
239751709ffdSYong Li  *
2398ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
239951709ffdSYong Li  *
240051709ffdSYong Li  * @return None.
240151709ffdSYong Li  */
24028d1b46d7Szhanghch05 inline void
2403ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
240451709ffdSYong Li {
240562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2406*deae6a78SEd Tanous     dbus::utility::getAllProperties(
2407*deae6a78SEd Tanous         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
2408bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2409ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2410b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
241151709ffdSYong Li             if (ec)
241251709ffdSYong Li             {
241351709ffdSYong Li                 // watchdog service is stopped
241462598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
241551709ffdSYong Li                 return;
241651709ffdSYong Li             }
241751709ffdSYong Li 
241862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
241951709ffdSYong Li 
242051709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
2421ac106bf6SEd Tanous                 asyncResp->res.jsonValue["HostWatchdogTimer"];
242251709ffdSYong Li 
242351709ffdSYong Li             // watchdog service is running/enabled
2424539d8c6bSEd Tanous             hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
242551709ffdSYong Li 
2426bc1d29deSKrzysztof Grobelny             const bool* enabled = nullptr;
2427bc1d29deSKrzysztof Grobelny             const std::string* expireAction = nullptr;
242851709ffdSYong Li 
2429bc1d29deSKrzysztof Grobelny             const bool success = sdbusplus::unpackPropertiesNoThrow(
2430bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2431bd79bce8SPatrick Williams                 enabled, "ExpireAction", expireAction);
2432bc1d29deSKrzysztof Grobelny 
2433bc1d29deSKrzysztof Grobelny             if (!success)
243451709ffdSYong Li             {
2435ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2436601af5edSChicago Duan                 return;
243751709ffdSYong Li             }
243851709ffdSYong Li 
2439bc1d29deSKrzysztof Grobelny             if (enabled != nullptr)
244051709ffdSYong Li             {
2441bc1d29deSKrzysztof Grobelny                 hostWatchdogTimer["FunctionEnabled"] = *enabled;
244251709ffdSYong Li             }
244351709ffdSYong Li 
2444bc1d29deSKrzysztof Grobelny             if (expireAction != nullptr)
2445bc1d29deSKrzysztof Grobelny             {
2446bc1d29deSKrzysztof Grobelny                 std::string action = dbusToRfWatchdogAction(*expireAction);
244751709ffdSYong Li                 if (action.empty())
244851709ffdSYong Li                 {
2449ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2450601af5edSChicago Duan                     return;
245151709ffdSYong Li                 }
245251709ffdSYong Li                 hostWatchdogTimer["TimeoutAction"] = action;
245351709ffdSYong Li             }
2454bc1d29deSKrzysztof Grobelny         });
245551709ffdSYong Li }
245651709ffdSYong Li 
245751709ffdSYong Li /**
2458c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2459c45f0082SYong Li  *
2460ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2461c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2462c45f0082SYong Li  *                       RF request.
2463c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2464c45f0082SYong Li  *
2465c45f0082SYong Li  * @return None.
2466c45f0082SYong Li  */
2467ac106bf6SEd Tanous inline void
2468ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2469c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2470c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2471c45f0082SYong Li {
247262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2473c45f0082SYong Li 
2474c45f0082SYong Li     if (wdtTimeOutAction)
2475c45f0082SYong Li     {
2476c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2477c45f0082SYong Li         // check if TimeOut Action is Valid
2478c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2479c45f0082SYong Li         {
248062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
248162598e31SEd Tanous                              *wdtTimeOutAction);
2482ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2483c45f0082SYong Li                                              "TimeoutAction");
2484c45f0082SYong Li             return;
2485c45f0082SYong Li         }
2486c45f0082SYong Li 
2487e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2488e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
248987c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
249087c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
24919ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2492e93abac6SGinu George                         wdtTimeOutActStr);
2493c45f0082SYong Li     }
2494c45f0082SYong Li 
2495c45f0082SYong Li     if (wdtEnable)
2496c45f0082SYong Li     {
2497e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2498e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
249987c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
250087c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
250187c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2502e93abac6SGinu George                         *wdtEnable);
2503c45f0082SYong Li     }
2504c45f0082SYong Li }
2505c45f0082SYong Li 
250637bbf98cSChris Cain /**
250737bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
250837bbf98cSChris Cain  *
2509ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
251037bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
251137bbf98cSChris Cain  *
251237bbf98cSChris Cain  * @return true if successful
251337bbf98cSChris Cain  */
25141e5b7c88SJiaqing Zhao inline bool
2515ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25161e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
251737bbf98cSChris Cain {
2518bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2519bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2520bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2521bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2522bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2523bc1d29deSKrzysztof Grobelny 
2524bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2525bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25262661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25272661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25282661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2529bc1d29deSKrzysztof Grobelny 
2530bc1d29deSKrzysztof Grobelny     if (!success)
253137bbf98cSChris Cain     {
253237bbf98cSChris Cain         return false;
253337bbf98cSChris Cain     }
2534bc1d29deSKrzysztof Grobelny 
2535bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
253637bbf98cSChris Cain     {
2537ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
253837bbf98cSChris Cain     }
2539bc1d29deSKrzysztof Grobelny 
2540bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
254137bbf98cSChris Cain     {
2542ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2543bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
254437bbf98cSChris Cain     }
2545bc1d29deSKrzysztof Grobelny 
2546bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2547bc1d29deSKrzysztof Grobelny     {
2548bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2549ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
255037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
255137bbf98cSChris Cain                 .count();
255237bbf98cSChris Cain     }
2553bc1d29deSKrzysztof Grobelny 
2554bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
255537bbf98cSChris Cain     {
2556ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2557bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
255837bbf98cSChris Cain     }
2559bc1d29deSKrzysztof Grobelny 
2560bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
256137bbf98cSChris Cain     {
2562bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2563ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
256437bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
256537bbf98cSChris Cain                 .count();
256637bbf98cSChris Cain     }
256737bbf98cSChris Cain 
256837bbf98cSChris Cain     return true;
256937bbf98cSChris Cain }
257037bbf98cSChris Cain 
257137bbf98cSChris Cain /**
257237bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
257337bbf98cSChris Cain  *
2574ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
257537bbf98cSChris Cain  *
257637bbf98cSChris Cain  * @return None.
257737bbf98cSChris Cain  */
2578ac106bf6SEd Tanous inline void
2579ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
258037bbf98cSChris Cain {
258162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
258237bbf98cSChris Cain 
258337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2584e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2585e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2586e99073f5SGeorge Liu     dbus::utility::getSubTree(
2587e99073f5SGeorge Liu         "/", 0, interfaces,
2588ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2589b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
259037bbf98cSChris Cain             if (ec)
259137bbf98cSChris Cain             {
2592b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
259362598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
259462598e31SEd Tanous                     ec);
2595ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
259637bbf98cSChris Cain                 return;
259737bbf98cSChris Cain             }
259837bbf98cSChris Cain             if (subtree.empty())
259937bbf98cSChris Cain             {
260037bbf98cSChris Cain                 // This is an optional interface so just return
260137bbf98cSChris Cain                 // if there is no instance found
260262598e31SEd Tanous                 BMCWEB_LOG_DEBUG("No instances found");
260337bbf98cSChris Cain                 return;
260437bbf98cSChris Cain             }
260537bbf98cSChris Cain             if (subtree.size() > 1)
260637bbf98cSChris Cain             {
260737bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
260837bbf98cSChris Cain                 // is an error
260962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
261062598e31SEd Tanous                                  "Power.IdlePowerSaver objects: {}",
261162598e31SEd Tanous                                  subtree.size());
2612ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261337bbf98cSChris Cain                 return;
261437bbf98cSChris Cain             }
261537bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
261637bbf98cSChris Cain             {
261762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2618ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261937bbf98cSChris Cain                 return;
262037bbf98cSChris Cain             }
262137bbf98cSChris Cain             const std::string& path = subtree[0].first;
262237bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
262337bbf98cSChris Cain             if (service.empty())
262437bbf98cSChris Cain             {
262562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2626ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
262737bbf98cSChris Cain                 return;
262837bbf98cSChris Cain             }
262937bbf98cSChris Cain 
263037bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
2631*deae6a78SEd Tanous             dbus::utility::getAllProperties(
2632bc1d29deSKrzysztof Grobelny                 *crow::connections::systemBus, service, path,
2633bc1d29deSKrzysztof Grobelny                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2634bd79bce8SPatrick Williams                 [asyncResp](
2635bd79bce8SPatrick Williams                     const boost::system::error_code& ec2,
26361e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
26378a592810SEd Tanous                     if (ec2)
263837bbf98cSChris Cain                     {
263962598e31SEd Tanous                         BMCWEB_LOG_ERROR(
2640bd79bce8SPatrick Williams                             "DBUS response error on IdlePowerSaver GetAll: {}",
2641bd79bce8SPatrick Williams                             ec2);
2642ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
264337bbf98cSChris Cain                         return;
264437bbf98cSChris Cain                     }
264537bbf98cSChris Cain 
2646ac106bf6SEd Tanous                     if (!parseIpsProperties(asyncResp, properties))
264737bbf98cSChris Cain                     {
2648ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
264937bbf98cSChris Cain                         return;
265037bbf98cSChris Cain                     }
2651bc1d29deSKrzysztof Grobelny                 });
2652e99073f5SGeorge Liu         });
265337bbf98cSChris Cain 
265462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
265537bbf98cSChris Cain }
265637bbf98cSChris Cain 
265737bbf98cSChris Cain /**
265837bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
265937bbf98cSChris Cain  *
2660ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
266137bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
266237bbf98cSChris Cain  *                       RF request.
266337bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
266437bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
266537bbf98cSChris Cain  * before entering idle state.
266637bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
266737bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
266837bbf98cSChris Cain  * before exiting idle state
266937bbf98cSChris Cain  *
267037bbf98cSChris Cain  * @return None.
267137bbf98cSChris Cain  */
2672bd79bce8SPatrick Williams inline void setIdlePowerSaver(
2673bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
267437bbf98cSChris Cain     const std::optional<bool> ipsEnable,
267537bbf98cSChris Cain     const std::optional<uint8_t> ipsEnterUtil,
267637bbf98cSChris Cain     const std::optional<uint64_t> ipsEnterTime,
267737bbf98cSChris Cain     const std::optional<uint8_t> ipsExitUtil,
267837bbf98cSChris Cain     const std::optional<uint64_t> ipsExitTime)
267937bbf98cSChris Cain {
268062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
268137bbf98cSChris Cain 
268237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2683e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2684e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2685e99073f5SGeorge Liu     dbus::utility::getSubTree(
2686e99073f5SGeorge Liu         "/", 0, interfaces,
2687ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2688e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2689b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
269037bbf98cSChris Cain             if (ec)
269137bbf98cSChris Cain             {
2692b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
269362598e31SEd Tanous                     "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
269462598e31SEd Tanous                     ec);
2695ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
269637bbf98cSChris Cain                 return;
269737bbf98cSChris Cain             }
269837bbf98cSChris Cain             if (subtree.empty())
269937bbf98cSChris Cain             {
270037bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
2701ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
270237bbf98cSChris Cain                                            "IdlePowerSaver");
270337bbf98cSChris Cain                 return;
270437bbf98cSChris Cain             }
270537bbf98cSChris Cain             if (subtree.size() > 1)
270637bbf98cSChris Cain             {
270737bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
270837bbf98cSChris Cain                 // is an error
270962598e31SEd Tanous                 BMCWEB_LOG_DEBUG(
271062598e31SEd Tanous                     "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
271162598e31SEd Tanous                     subtree.size());
2712ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271337bbf98cSChris Cain                 return;
271437bbf98cSChris Cain             }
271537bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
271637bbf98cSChris Cain             {
271762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2718ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271937bbf98cSChris Cain                 return;
272037bbf98cSChris Cain             }
272137bbf98cSChris Cain             const std::string& path = subtree[0].first;
272237bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
272337bbf98cSChris Cain             if (service.empty())
272437bbf98cSChris Cain             {
272562598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2726ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272737bbf98cSChris Cain                 return;
272837bbf98cSChris Cain             }
272937bbf98cSChris Cain 
273037bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
273137bbf98cSChris Cain             // need to be updated
273237bbf98cSChris Cain 
273337bbf98cSChris Cain             if (ipsEnable)
273437bbf98cSChris Cain             {
2735bd79bce8SPatrick Williams                 setDbusProperty(
2736bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/Enabled", service, path,
273787c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2738e93abac6SGinu George                     "Enabled", *ipsEnable);
273937bbf98cSChris Cain             }
274037bbf98cSChris Cain             if (ipsEnterUtil)
274137bbf98cSChris Cain             {
2742bd79bce8SPatrick Williams                 setDbusProperty(
2743bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2744e93abac6SGinu George                     service, path,
27459ae226faSGeorge Liu                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2746e93abac6SGinu George                     "EnterUtilizationPercent", *ipsEnterUtil);
274737bbf98cSChris Cain             }
274837bbf98cSChris Cain             if (ipsEnterTime)
274937bbf98cSChris Cain             {
275037bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
275137bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2752bd79bce8SPatrick Williams                 setDbusProperty(
2753bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2754bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2755e93abac6SGinu George                     "EnterDwellTime", timeMilliseconds);
275637bbf98cSChris Cain             }
275737bbf98cSChris Cain             if (ipsExitUtil)
275837bbf98cSChris Cain             {
2759bd79bce8SPatrick Williams                 setDbusProperty(
2760bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2761bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2762e93abac6SGinu George                     "ExitUtilizationPercent", *ipsExitUtil);
276337bbf98cSChris Cain             }
276437bbf98cSChris Cain             if (ipsExitTime)
276537bbf98cSChris Cain             {
276637bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
276737bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2768bd79bce8SPatrick Williams                 setDbusProperty(
2769bd79bce8SPatrick Williams                     asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2770bd79bce8SPatrick Williams                     path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2771e93abac6SGinu George                     "ExitDwellTime", timeMilliseconds);
277237bbf98cSChris Cain             }
2773e99073f5SGeorge Liu         });
277437bbf98cSChris Cain 
277562598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
277637bbf98cSChris Cain }
277737bbf98cSChris Cain 
2778c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2779dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2780dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2781dd60b9edSEd Tanous {
2782dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2783dd60b9edSEd Tanous     {
2784dd60b9edSEd Tanous         return;
2785dd60b9edSEd Tanous     }
2786dd60b9edSEd Tanous     asyncResp->res.addHeader(
2787dd60b9edSEd Tanous         boost::beast::http::field::link,
2788dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2789dd60b9edSEd Tanous }
2790dd60b9edSEd Tanous 
2791c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2792c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2793c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27941abe55efSEd Tanous {
27953ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2796f4c99e70SEd Tanous     {
2797f4c99e70SEd Tanous         return;
2798f4c99e70SEd Tanous     }
2799dd60b9edSEd Tanous 
2800dd60b9edSEd Tanous     asyncResp->res.addHeader(
2801dd60b9edSEd Tanous         boost::beast::http::field::link,
2802dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28038d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28040f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28058d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28068d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2807462023adSSunitha Harish 
28087f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
28097f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
281025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28117f3e84a1SEd Tanous     {
28127f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
28137f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28147f3e84a1SEd Tanous         return;
28157f3e84a1SEd Tanous     }
28167f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
28177f3e84a1SEd Tanous     nlohmann::json::object_t system;
2818253f11b8SEd Tanous     system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2819253f11b8SEd Tanous                                               BMCWEB_REDFISH_SYSTEM_URI_NAME);
28207f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
282168896206SGunnar Mills 
282268896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2823462023adSSunitha Harish     {
282462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
282568896206SGunnar Mills         asyncResp->res.jsonValue["Members@odata.count"] = 2;
282668896206SGunnar Mills 
28271476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2828002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
282968896206SGunnar Mills         ifaceArray.emplace_back(std::move(hypervisor));
283068896206SGunnar Mills     }
2831c1e219d5SEd Tanous }
2832c1e219d5SEd Tanous 
2833c1e219d5SEd Tanous /**
28347e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28357e860f15SJohn Edward Broadbent  */
28364f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28377e860f15SJohn Edward Broadbent {
283889492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
283989492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
284089492a15SPatrick Williams     constexpr const char* interfaceName =
28417e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
284289492a15SPatrick Williams     constexpr const char* method = "NMI";
28437e860f15SJohn Edward Broadbent 
28447e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28455e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28467e860f15SJohn Edward Broadbent             if (ec)
28477e860f15SJohn Edward Broadbent             {
284862598e31SEd Tanous                 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28497e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28507e860f15SJohn Edward Broadbent                 return;
28517e860f15SJohn Edward Broadbent             }
28527e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28537e860f15SJohn Edward Broadbent         },
28547e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28557e860f15SJohn Edward Broadbent }
2856c5b2abe0SLewanczyk, Dawid 
2857c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2858c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
28597f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2860c1e219d5SEd Tanous     const std::string& systemName)
2861c1e219d5SEd Tanous {
28623ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
286345ca1b86SEd Tanous     {
286445ca1b86SEd Tanous         return;
286545ca1b86SEd Tanous     }
2866dd7090e6SGunnar Mills 
2867dd7090e6SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2868dd7090e6SGunnar Mills     {
2869dd7090e6SGunnar Mills         if (systemName == "hypervisor")
2870dd7090e6SGunnar Mills         {
2871dd7090e6SGunnar Mills             handleHypervisorSystemResetPost(req, asyncResp);
2872dd7090e6SGunnar Mills             return;
2873dd7090e6SGunnar Mills         }
2874dd7090e6SGunnar Mills     }
2875dd7090e6SGunnar Mills 
2876253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2877c1e219d5SEd Tanous     {
2878c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2879c1e219d5SEd Tanous                                    systemName);
2880c1e219d5SEd Tanous         return;
2881c1e219d5SEd Tanous     }
288225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28837f3e84a1SEd Tanous     {
28847f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28857f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2886c1e219d5SEd Tanous                                    systemName);
28877f3e84a1SEd Tanous         return;
28887f3e84a1SEd Tanous     }
28899712f8acSEd Tanous     std::string resetType;
2890c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2891cc340dd9SEd Tanous     {
2892cc340dd9SEd Tanous         return;
2893cc340dd9SEd Tanous     }
2894cc340dd9SEd Tanous 
2895d22c8396SJason M. Bills     // Get the command and host vs. chassis
2896cc340dd9SEd Tanous     std::string command;
2897543f4400SEd Tanous     bool hostCommand = true;
2898d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2899cc340dd9SEd Tanous     {
2900cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2901d22c8396SJason M. Bills         hostCommand = true;
2902d22c8396SJason M. Bills     }
2903d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2904d22c8396SJason M. Bills     {
2905d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2906d22c8396SJason M. Bills         hostCommand = false;
2907d22c8396SJason M. Bills     }
2908d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2909d22c8396SJason M. Bills     {
2910c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
291186a0851aSJason M. Bills         hostCommand = true;
2912cc340dd9SEd Tanous     }
29139712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2914cc340dd9SEd Tanous     {
2915cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2916d22c8396SJason M. Bills         hostCommand = true;
2917cc340dd9SEd Tanous     }
29189712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2919cc340dd9SEd Tanous     {
29200fda0f12SGeorge Liu         command =
29210fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2922d22c8396SJason M. Bills         hostCommand = true;
2923d22c8396SJason M. Bills     }
2924d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2925d22c8396SJason M. Bills     {
292686a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
292786a0851aSJason M. Bills         hostCommand = true;
2928cc340dd9SEd Tanous     }
2929bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2930bfd5b826SLakshminarayana R. Kammath     {
2931bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2932bfd5b826SLakshminarayana R. Kammath         return;
2933bfd5b826SLakshminarayana R. Kammath     }
2934cc340dd9SEd Tanous     else
2935cc340dd9SEd Tanous     {
2936c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2937cc340dd9SEd Tanous         return;
2938cc340dd9SEd Tanous     }
2939d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
2940cc340dd9SEd Tanous 
2941d22c8396SJason M. Bills     if (hostCommand)
2942d22c8396SJason M. Bills     {
2943e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
2944d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
2945e93abac6SGinu George                         "RequestedHostTransition", command);
2946cc340dd9SEd Tanous     }
2947d22c8396SJason M. Bills     else
2948d22c8396SJason M. Bills     {
2949e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
2950d02aad39SEd Tanous                         statePath / "chassis0",
2951d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2952e93abac6SGinu George                         "RequestedPowerTransition", command);
2953d22c8396SJason M. Bills     }
2954d22c8396SJason M. Bills }
2955cc340dd9SEd Tanous 
2956c1e219d5SEd Tanous inline void handleComputerSystemHead(
2957dd60b9edSEd Tanous     App& app, const crow::Request& req,
29587f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29597f3e84a1SEd Tanous     const std::string& /*systemName*/)
2960dd60b9edSEd Tanous {
2961dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2962dd60b9edSEd Tanous     {
2963dd60b9edSEd Tanous         return;
2964dd60b9edSEd Tanous     }
2965dd60b9edSEd Tanous 
2966dd60b9edSEd Tanous     asyncResp->res.addHeader(
2967dd60b9edSEd Tanous         boost::beast::http::field::link,
2968dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2969dd60b9edSEd Tanous }
2970dd60b9edSEd Tanous 
29715c3e9272SAbhishek Patel inline void afterPortRequest(
29725c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29735c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29745c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29755c3e9272SAbhishek Patel {
29765c3e9272SAbhishek Patel     if (ec)
29775c3e9272SAbhishek Patel     {
2978b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29795c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29805c3e9272SAbhishek Patel         return;
29815c3e9272SAbhishek Patel     }
29825c3e9272SAbhishek Patel     for (const auto& data : socketData)
29835c3e9272SAbhishek Patel     {
29845c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29855c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29865c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29875c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29885c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29895c3e9272SAbhishek Patel         // need to retrieve port number for
29905c3e9272SAbhishek Patel         // obmc-console-ssh service
29915c3e9272SAbhishek Patel         if (protocolName == "SSH")
29925c3e9272SAbhishek Patel         {
29935c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
299481c4e330SEd Tanous                                           const boost::system::error_code& ec1,
29955c3e9272SAbhishek Patel                                           int portNumber) {
29965c3e9272SAbhishek Patel                 if (ec1)
29975c3e9272SAbhishek Patel                 {
2998b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
29995c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30005c3e9272SAbhishek Patel                     return;
30015c3e9272SAbhishek Patel                 }
30025c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30035c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30045c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30055c3e9272SAbhishek Patel             });
30065c3e9272SAbhishek Patel         }
30075c3e9272SAbhishek Patel     }
30085c3e9272SAbhishek Patel }
3009c1e219d5SEd Tanous 
3010c1e219d5SEd Tanous inline void
3011c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
301222d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3013c1e219d5SEd Tanous                             const std::string& systemName)
3014c1e219d5SEd Tanous {
30153ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
301645ca1b86SEd Tanous     {
301745ca1b86SEd Tanous         return;
301845ca1b86SEd Tanous     }
3019746b56f3SAsmitha Karunanithi 
302025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30217f3e84a1SEd Tanous     {
30227f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30237f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
30247f3e84a1SEd Tanous                                    systemName);
30257f3e84a1SEd Tanous         return;
30267f3e84a1SEd Tanous     }
30277f3e84a1SEd Tanous 
302868896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
302968896206SGunnar Mills     {
3030746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3031746b56f3SAsmitha Karunanithi         {
3032746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3033746b56f3SAsmitha Karunanithi             return;
3034746b56f3SAsmitha Karunanithi         }
303568896206SGunnar Mills     }
3036746b56f3SAsmitha Karunanithi 
3037253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
303822d268cbSEd Tanous     {
303922d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
304022d268cbSEd Tanous                                    systemName);
304122d268cbSEd Tanous         return;
304222d268cbSEd Tanous     }
3043dd60b9edSEd Tanous     asyncResp->res.addHeader(
3044dd60b9edSEd Tanous         boost::beast::http::field::link,
3045dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30468d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3047b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
3048253f11b8SEd Tanous     asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3049253f11b8SEd Tanous     asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3050539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3051539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30528d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30538d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3054cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3055dfb2b408SPriyanga Ramasamy         double(0);
3056253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3057253f11b8SEd Tanous         "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
305804a258f4SEd Tanous 
3059253f11b8SEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3060253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3061253f11b8SEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3062253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3063253f11b8SEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3064253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
30653179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3066253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3067253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3068029573d4SEd Tanous 
3069002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3070253f11b8SEd Tanous         boost::urls::format(
3071253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3072253f11b8SEd Tanous             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3073c1e219d5SEd Tanous     asyncResp->res
3074c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3075253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3076253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3077c5b2abe0SLewanczyk, Dawid 
3078253f11b8SEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3079253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3080253f11b8SEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3081253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3082c4bf6374SJason M. Bills 
30831476687dSEd Tanous     nlohmann::json::array_t managedBy;
30841476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3085253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3086253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3087002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3088539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3089539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
30900e8ac5e7SGunnar Mills 
30910e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3092002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3093c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
30941476687dSEd Tanous 
3095c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
30961476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3097c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30981476687dSEd Tanous         "Press ~. to exit console";
30995c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31005c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31010e8ac5e7SGunnar Mills 
310225b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
310325b54dbaSEd Tanous     {
31040e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3105002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
310625b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
310725b54dbaSEd Tanous             4;
3108613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3109613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
311025b54dbaSEd Tanous     }
311113451e39SWilly Tu 
3112bd79bce8SPatrick Williams     getMainChassisId(
3113bd79bce8SPatrick Williams         asyncResp, [](const std::string& chassisId,
31148d1b46d7Szhanghch05                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3115b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3116b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3117bd79bce8SPatrick Williams             chassis["@odata.id"] =
3118bd79bce8SPatrick Williams                 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3119002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3120c5d03ff4SJennifer Lee         });
3121a3002228SAppaRao Puli 
312259a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
31239f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3124a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
312551bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
31266c34de48SEd Tanous     getHostState(asyncResp);
3127491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3128978b8803SAndrew Geissler     getBootProgress(asyncResp);
3129b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
313070c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
313170c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
313251709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3133c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
31349dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3135797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3136c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
313725b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
313825b54dbaSEd Tanous     {
3139a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
314025b54dbaSEd Tanous     }
31411981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
31423a2d0424SChris Cain     getPowerMode(asyncResp);
314337bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3144c1e219d5SEd Tanous }
3145550a6bf8SJiaqing Zhao 
3146c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3147c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
314822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3149c1e219d5SEd Tanous     const std::string& systemName)
3150c1e219d5SEd Tanous {
31513ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
315245ca1b86SEd Tanous     {
315345ca1b86SEd Tanous         return;
315445ca1b86SEd Tanous     }
315525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31567f3e84a1SEd Tanous     {
31577f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31587f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31597f3e84a1SEd Tanous                                    systemName);
31607f3e84a1SEd Tanous         return;
31617f3e84a1SEd Tanous     }
3162253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
316322d268cbSEd Tanous     {
316422d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
316522d268cbSEd Tanous                                    systemName);
316622d268cbSEd Tanous         return;
316722d268cbSEd Tanous     }
316822d268cbSEd Tanous 
3169dd60b9edSEd Tanous     asyncResp->res.addHeader(
3170dd60b9edSEd Tanous         boost::beast::http::field::link,
3171dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3172dd60b9edSEd Tanous 
31739f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3174cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
317598e386ecSGunnar Mills     std::optional<std::string> assetTag;
3176c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
31773a2d0424SChris Cain     std::optional<std::string> powerMode;
3178550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3179550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3180550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3181550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3182550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3183550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3184797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3185550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
31869dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3187550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3188550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3189550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3190550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3191550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3192550a6bf8SJiaqing Zhao 
3193afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
3194afc474aeSMyung Bae             req, asyncResp->res, //
3195afc474aeSMyung Bae             "AssetTag", assetTag, //
3196afc474aeSMyung Bae             "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3197afc474aeSMyung Bae             "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3198afc474aeSMyung Bae             "Boot/BootSourceOverrideEnabled", bootEnable, //
3199afc474aeSMyung Bae             "Boot/BootSourceOverrideMode", bootType, //
3200afc474aeSMyung Bae             "Boot/BootSourceOverrideTarget", bootSource, //
3201afc474aeSMyung Bae             "Boot/StopBootOnFault", stopBootOnFault, //
3202afc474aeSMyung Bae             "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3203afc474aeSMyung Bae             "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3204afc474aeSMyung Bae             "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3205afc474aeSMyung Bae             "IdlePowerSaver/Enabled", ipsEnable, //
3206afc474aeSMyung Bae             "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3207afc474aeSMyung Bae             "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3208afc474aeSMyung Bae             "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3209afc474aeSMyung Bae             "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3210afc474aeSMyung Bae             "IndicatorLED", indicatorLed, //
3211afc474aeSMyung Bae             "LocationIndicatorActive", locationIndicatorActive, //
3212afc474aeSMyung Bae             "PowerMode", powerMode, //
3213afc474aeSMyung Bae             "PowerRestorePolicy", powerRestorePolicy //
3214afc474aeSMyung Bae             ))
32156617338dSEd Tanous     {
32166617338dSEd Tanous         return;
32176617338dSEd Tanous     }
3218491d8ee7SSantosh Puranik 
32198d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3220c45f0082SYong Li 
322198e386ecSGunnar Mills     if (assetTag)
322298e386ecSGunnar Mills     {
322398e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
322498e386ecSGunnar Mills     }
322598e386ecSGunnar Mills 
3226550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3227c45f0082SYong Li     {
3228f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3229c45f0082SYong Li     }
3230c45f0082SYong Li 
3231cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
323269f35306SGunnar Mills     {
3233002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3234491d8ee7SSantosh Puranik     }
3235550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
323669f35306SGunnar Mills     {
3237550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
323869f35306SGunnar Mills     }
3239ac7e1e0bSAli Ahmed 
3240797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3241797d5daeSCorey Hardesty     {
3242797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3243797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3244797d5daeSCorey Hardesty     }
3245797d5daeSCorey Hardesty 
3246550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3247ac7e1e0bSAli Ahmed     {
3248c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
324969f35306SGunnar Mills     }
3250265c1602SJohnathan Mantey 
32519dcfe8c1SAlbert Zhang     if (stopBootOnFault)
32529dcfe8c1SAlbert Zhang     {
32539dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
32549dcfe8c1SAlbert Zhang     }
32559dcfe8c1SAlbert Zhang 
32569f8bfa7cSGunnar Mills     if (locationIndicatorActive)
32579f8bfa7cSGunnar Mills     {
325859a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32599f8bfa7cSGunnar Mills     }
32609f8bfa7cSGunnar Mills 
32617e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
32627e860f15SJohn Edward Broadbent     // passed
32639712f8acSEd Tanous     if (indicatorLed)
32646617338dSEd Tanous     {
3265f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3266002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3267d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3268d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
32696617338dSEd Tanous     }
3270c6a620f2SGeorge Liu 
3271c6a620f2SGeorge Liu     if (powerRestorePolicy)
3272c6a620f2SGeorge Liu     {
32734e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3274c6a620f2SGeorge Liu     }
32753a2d0424SChris Cain 
32763a2d0424SChris Cain     if (powerMode)
32773a2d0424SChris Cain     {
32783a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
32793a2d0424SChris Cain     }
328037bbf98cSChris Cain 
3281c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
328237bbf98cSChris Cain     {
3283002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3284002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
328537bbf98cSChris Cain     }
3286c1e219d5SEd Tanous }
32871cb1a9e6SAppaRao Puli 
328838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3289dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
32907f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3291c1e219d5SEd Tanous     const std::string& /*systemName*/)
3292dd60b9edSEd Tanous {
3293dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3294dd60b9edSEd Tanous     {
3295dd60b9edSEd Tanous         return;
3296dd60b9edSEd Tanous     }
3297dd60b9edSEd Tanous     asyncResp->res.addHeader(
3298dd60b9edSEd Tanous         boost::beast::http::field::link,
3299dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3300dd60b9edSEd Tanous }
330133e1f122SAndrew Geissler 
330233e1f122SAndrew Geissler /**
330333e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
330433e1f122SAndrew Geissler  *
330533e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
330633e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
330733e1f122SAndrew Geissler  *
3308efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
330933e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
331033e1f122SAndrew Geissler  * allowableValues.
331133e1f122SAndrew Geissler  */
331233e1f122SAndrew Geissler inline void
331333e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
331433e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
331533e1f122SAndrew Geissler {
331633e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
331733e1f122SAndrew Geissler     {
331833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
331933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
332033e1f122SAndrew Geissler     }
332133e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
332233e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
332333e1f122SAndrew Geissler     {
332433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
332533e1f122SAndrew Geissler     }
332633e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
332733e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
332833e1f122SAndrew Geissler     {
332933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
333033e1f122SAndrew Geissler     }
333133e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
333233e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
333333e1f122SAndrew Geissler     {
333433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
333533e1f122SAndrew Geissler     }
333633e1f122SAndrew Geissler     else
333733e1f122SAndrew Geissler     {
333833e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
333933e1f122SAndrew Geissler     }
334033e1f122SAndrew Geissler }
334133e1f122SAndrew Geissler 
334233e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
334333e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
334433e1f122SAndrew Geissler     const boost::system::error_code& ec,
334533e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
334633e1f122SAndrew Geissler {
334733e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
334833e1f122SAndrew Geissler 
334933e1f122SAndrew Geissler     // Supported on all systems currently
335033e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
335133e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
335233e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
335333e1f122SAndrew Geissler 
335433e1f122SAndrew Geissler     if (ec)
335533e1f122SAndrew Geissler     {
3356e715d14bSEd Tanous         if ((ec.value() ==
3357e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3358e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
335933e1f122SAndrew Geissler         {
336033e1f122SAndrew Geissler             // Property not implemented so just return defaults
336133e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
336233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
336333e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
336433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
336533e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
336633e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
336733e1f122SAndrew Geissler         }
336833e1f122SAndrew Geissler         else
336933e1f122SAndrew Geissler         {
337033e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
337133e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
337233e1f122SAndrew Geissler             return;
337333e1f122SAndrew Geissler         }
337433e1f122SAndrew Geissler     }
337533e1f122SAndrew Geissler     else
337633e1f122SAndrew Geissler     {
337733e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
337833e1f122SAndrew Geissler         {
337933e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
338033e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
338133e1f122SAndrew Geissler         }
338233e1f122SAndrew Geissler     }
338333e1f122SAndrew Geissler 
338433e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
338533e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
338633e1f122SAndrew Geissler     parameter["Required"] = true;
3387539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
338833e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
338933e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
339033e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
339133e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
339233e1f122SAndrew Geissler }
339333e1f122SAndrew Geissler 
3394c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3395c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
339622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3397c1e219d5SEd Tanous     const std::string& systemName)
3398c1e219d5SEd Tanous {
33993ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
340045ca1b86SEd Tanous     {
340145ca1b86SEd Tanous         return;
340245ca1b86SEd Tanous     }
340325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
34047f3e84a1SEd Tanous     {
34057f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34067f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34077f3e84a1SEd Tanous                                    systemName);
34087f3e84a1SEd Tanous         return;
34097f3e84a1SEd Tanous     }
3410746b56f3SAsmitha Karunanithi 
341168896206SGunnar Mills     if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
341268896206SGunnar Mills     {
3413746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3414746b56f3SAsmitha Karunanithi         {
3415746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3416746b56f3SAsmitha Karunanithi             return;
3417746b56f3SAsmitha Karunanithi         }
341868896206SGunnar Mills     }
3419746b56f3SAsmitha Karunanithi 
3420253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
342122d268cbSEd Tanous     {
342222d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
342322d268cbSEd Tanous                                    systemName);
342422d268cbSEd Tanous         return;
342522d268cbSEd Tanous     }
342622d268cbSEd Tanous 
3427dd60b9edSEd Tanous     asyncResp->res.addHeader(
3428dd60b9edSEd Tanous         boost::beast::http::field::link,
3429dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34301476687dSEd Tanous 
34311476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
3432253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3433253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3434c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34351476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34361476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34373215e700SNan Zhou 
343833e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
3439*deae6a78SEd Tanous     dbus::utility::getProperty<std::vector<std::string>>(
3440*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
3441*deae6a78SEd Tanous         "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
344233e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
344333e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
3444bd79bce8SPatrick Williams             afterGetAllowedHostTransitions(asyncResp, ec,
3445bd79bce8SPatrick Williams                                            allowedHostTransitions);
344633e1f122SAndrew Geissler         });
3447c1e219d5SEd Tanous }
3448c1e219d5SEd Tanous /**
3449c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3450c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3451c1e219d5SEd Tanous  */
3452100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3453c1e219d5SEd Tanous {
3454100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3455100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3456100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3457100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3458100afe56SEd Tanous 
3459100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3460100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3461100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3462100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3463100afe56SEd Tanous 
3464100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3465100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3466100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3467100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3468100afe56SEd Tanous 
3469100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3470100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3471100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3472100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3473100afe56SEd Tanous 
3474100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3475100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3476100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3477100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3478100afe56SEd Tanous 
3479100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3480100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3481100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3482100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3483100afe56SEd Tanous 
3484c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3485c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3486c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3487c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3488c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3489c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3490c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3491c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
34921cb1a9e6SAppaRao Puli }
3493c5b2abe0SLewanczyk, Dawid } // namespace redfish
3494