xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 539d8c6bc399e516d39bcaa18262cf206f4c1035)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // 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"
23*539d8c6bSEd Tanous #include "generated/enums/action_info.hpp"
248d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
25*539d8c6bSEd 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  */
708d1b46d7Szhanghch05 inline void
71ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
721e1e598dSJonathan Doman                          bool isDimmFunctional)
739d3ae10eSAlpana Kumari {
7462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
759d3ae10eSAlpana Kumari 
769d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
779d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
789d3ae10eSAlpana Kumari     // ENABLED.
7902cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
80ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
819d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
829d3ae10eSAlpana Kumari     {
83e05aec50SEd Tanous         if (isDimmFunctional)
849d3ae10eSAlpana Kumari         {
85ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
869d3ae10eSAlpana Kumari                 "Enabled";
879d3ae10eSAlpana Kumari         }
889d3ae10eSAlpana Kumari     }
899d3ae10eSAlpana Kumari }
909d3ae10eSAlpana Kumari 
9157e8c9beSAlpana Kumari /*
9257e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9357e8c9beSAlpana Kumari  *        CPU Functional State
9457e8c9beSAlpana Kumari  *
95ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9657e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9757e8c9beSAlpana Kumari  *
9857e8c9beSAlpana Kumari  * @return None.
9957e8c9beSAlpana Kumari  */
100ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
101ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10257e8c9beSAlpana Kumari {
10362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10457e8c9beSAlpana Kumari 
10502cad96eSEd Tanous     const nlohmann::json& prevProcState =
106ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10757e8c9beSAlpana Kumari 
10857e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10957e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
11057e8c9beSAlpana Kumari     // Functional.
11157e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11257e8c9beSAlpana Kumari     {
113e05aec50SEd Tanous         if (isCpuFunctional)
11457e8c9beSAlpana Kumari         {
115ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11657e8c9beSAlpana Kumari                 "Enabled";
11757e8c9beSAlpana Kumari         }
11857e8c9beSAlpana Kumari     }
11957e8c9beSAlpana Kumari }
12057e8c9beSAlpana Kumari 
121cf0e004cSNinad Palsule /*
122cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
123cf0e004cSNinad Palsule  *
124ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
125cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
126cf0e004cSNinad Palsule  *
127cf0e004cSNinad Palsule  * @return None.
128cf0e004cSNinad Palsule  */
129cf0e004cSNinad Palsule inline void
130ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
131cf0e004cSNinad Palsule                            bool isCpuPresent)
132cf0e004cSNinad Palsule {
13362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
134cf0e004cSNinad Palsule 
135cf0e004cSNinad Palsule     if (isCpuPresent)
136cf0e004cSNinad Palsule     {
137cf0e004cSNinad Palsule         nlohmann::json& procCount =
138ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
139cf0e004cSNinad Palsule         auto* procCountPtr =
140cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
141cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
142cf0e004cSNinad Palsule         {
143cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
144cf0e004cSNinad Palsule             *procCountPtr += 1;
145cf0e004cSNinad Palsule         }
146cf0e004cSNinad Palsule     }
147cf0e004cSNinad Palsule }
148cf0e004cSNinad Palsule 
149382d6475SAli Ahmed inline void getProcessorProperties(
150ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
151382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
152382d6475SAli Ahmed         properties)
15303fbed92SAli Ahmed {
15462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15503fbed92SAli Ahmed 
15603fbed92SAli Ahmed     // TODO: Get Model
15703fbed92SAli Ahmed 
158bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15903fbed92SAli Ahmed 
160bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
161bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16203fbed92SAli Ahmed 
163bc1d29deSKrzysztof Grobelny     if (!success)
16403fbed92SAli Ahmed     {
165ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16603fbed92SAli Ahmed         return;
16703fbed92SAli Ahmed     }
16803fbed92SAli Ahmed 
169bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
17003fbed92SAli Ahmed     {
171bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
172ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
173bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
174bc1d29deSKrzysztof Grobelny 
175bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
176bc1d29deSKrzysztof Grobelny         {
177bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17803fbed92SAli Ahmed         }
17903fbed92SAli Ahmed         else
18003fbed92SAli Ahmed         {
181bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18203fbed92SAli Ahmed         }
18303fbed92SAli Ahmed     }
18403fbed92SAli Ahmed }
18503fbed92SAli Ahmed 
18603fbed92SAli Ahmed /*
18703fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18803fbed92SAli Ahmed  *
189ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
19003fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
19103fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19203fbed92SAli Ahmed  *
19303fbed92SAli Ahmed  * @return None.
19403fbed92SAli Ahmed  */
195ac106bf6SEd Tanous inline void
196ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
197ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19803fbed92SAli Ahmed {
199ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
200382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
201382d6475SAli Ahmed         if (ec3)
202382d6475SAli Ahmed         {
20362598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
204382d6475SAli Ahmed             return;
205382d6475SAli Ahmed         }
206ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
207382d6475SAli Ahmed     };
208382d6475SAli Ahmed 
209cf0e004cSNinad Palsule     // Get the Presence of CPU
210cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
211cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
212cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
213cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
214cf0e004cSNinad Palsule 
215bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
216bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
217bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
218ac106bf6SEd Tanous         [asyncResp, service,
2195e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
220b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22103fbed92SAli Ahmed         if (ec2)
22203fbed92SAli Ahmed         {
22362598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
224ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22503fbed92SAli Ahmed             return;
22603fbed92SAli Ahmed         }
227ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
228bc1d29deSKrzysztof Grobelny     });
22903fbed92SAli Ahmed }
23003fbed92SAli Ahmed 
23157e8c9beSAlpana Kumari /*
232cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
233cf0e004cSNinad Palsule  *
234ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
235cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
236cf0e004cSNinad Palsule  *
237cf0e004cSNinad Palsule  * @return None.
238cf0e004cSNinad Palsule  */
239cf0e004cSNinad Palsule inline void
240ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
241cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
242cf0e004cSNinad Palsule {
24362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
244cf0e004cSNinad Palsule 
245cf0e004cSNinad Palsule     if (properties.empty())
246cf0e004cSNinad Palsule     {
247cf0e004cSNinad Palsule         return;
248cf0e004cSNinad Palsule     }
249cf0e004cSNinad Palsule 
250cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
251cf0e004cSNinad Palsule 
252cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
253cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
254cf0e004cSNinad Palsule         memorySizeInKB);
255cf0e004cSNinad Palsule 
256cf0e004cSNinad Palsule     if (!success)
257cf0e004cSNinad Palsule     {
258ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
259cf0e004cSNinad Palsule         return;
260cf0e004cSNinad Palsule     }
261cf0e004cSNinad Palsule 
262cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
263cf0e004cSNinad Palsule     {
264cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
265ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
266dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
267cf0e004cSNinad Palsule         if (preValue == nullptr)
268cf0e004cSNinad Palsule         {
269ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
270dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
271cf0e004cSNinad Palsule         }
272cf0e004cSNinad Palsule         else
273cf0e004cSNinad Palsule         {
274ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
275dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
276dfb2b408SPriyanga Ramasamy                 *preValue;
277cf0e004cSNinad Palsule         }
278cf0e004cSNinad Palsule     }
279cf0e004cSNinad Palsule }
280cf0e004cSNinad Palsule 
281cf0e004cSNinad Palsule /*
282cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
283cf0e004cSNinad Palsule  *
284ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
285cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
286cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
287cf0e004cSNinad Palsule  *
288cf0e004cSNinad Palsule  * @return None.
289cf0e004cSNinad Palsule  */
290ac106bf6SEd Tanous inline void
291ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
292ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
293cf0e004cSNinad Palsule {
294cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
295cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
296cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
297ac106bf6SEd Tanous         [asyncResp, service,
298cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
299cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
300cf0e004cSNinad Palsule         if (ec2)
301cf0e004cSNinad Palsule         {
30262598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
303ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
304cf0e004cSNinad Palsule             return;
305cf0e004cSNinad Palsule         }
30651bd2d8aSGunnar Mills         processMemoryProperties(asyncResp, properties);
307cf0e004cSNinad Palsule     });
308cf0e004cSNinad Palsule }
309cf0e004cSNinad Palsule 
310a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
311a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
312a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3131abe55efSEd Tanous {
314a974c132SLakshmi Yadlapati     if (ec)
315a974c132SLakshmi Yadlapati     {
316a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
317a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
318a974c132SLakshmi Yadlapati         return;
319a974c132SLakshmi Yadlapati     }
320a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
321a974c132SLakshmi Yadlapati 
322a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
323a974c132SLakshmi Yadlapati 
324a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
325a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
326a974c132SLakshmi Yadlapati 
327a974c132SLakshmi Yadlapati     if (!success)
328a974c132SLakshmi Yadlapati     {
329a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
330a974c132SLakshmi Yadlapati         return;
331a974c132SLakshmi Yadlapati     }
332a974c132SLakshmi Yadlapati 
333a974c132SLakshmi Yadlapati     if (uUID != nullptr)
334a974c132SLakshmi Yadlapati     {
335a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
336a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
337a974c132SLakshmi Yadlapati         {
338a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
339a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
340a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
341a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
342a974c132SLakshmi Yadlapati         }
343a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
344a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
345a974c132SLakshmi Yadlapati     }
346a974c132SLakshmi Yadlapati }
347a974c132SLakshmi Yadlapati 
348a974c132SLakshmi Yadlapati inline void
349a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
350a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
351a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
352a974c132SLakshmi Yadlapati {
353a974c132SLakshmi Yadlapati     if (ec)
354a974c132SLakshmi Yadlapati     {
355a974c132SLakshmi Yadlapati         // doesn't have to include this
356a974c132SLakshmi Yadlapati         // interface
357a974c132SLakshmi Yadlapati         return;
358a974c132SLakshmi Yadlapati     }
359a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
360a974c132SLakshmi Yadlapati 
361a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
362a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
363a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
364a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
365a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
366a974c132SLakshmi Yadlapati 
367a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
368a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
369a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
370a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
371a974c132SLakshmi Yadlapati 
372a974c132SLakshmi Yadlapati     if (!success)
373a974c132SLakshmi Yadlapati     {
374a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
375a974c132SLakshmi Yadlapati         return;
376a974c132SLakshmi Yadlapati     }
377a974c132SLakshmi Yadlapati 
378a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
379a974c132SLakshmi Yadlapati     {
380a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
381a974c132SLakshmi Yadlapati     }
382a974c132SLakshmi Yadlapati 
383a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
384a974c132SLakshmi Yadlapati     {
385a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
386a974c132SLakshmi Yadlapati     }
387a974c132SLakshmi Yadlapati 
388a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
389a974c132SLakshmi Yadlapati     {
390a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
391a974c132SLakshmi Yadlapati     }
392a974c132SLakshmi Yadlapati 
393a974c132SLakshmi Yadlapati     if (model != nullptr)
394a974c132SLakshmi Yadlapati     {
395a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
396a974c132SLakshmi Yadlapati     }
397a974c132SLakshmi Yadlapati 
398a974c132SLakshmi Yadlapati     if (subModel != nullptr)
399a974c132SLakshmi Yadlapati     {
400a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
401a974c132SLakshmi Yadlapati     }
402a974c132SLakshmi Yadlapati 
403a974c132SLakshmi Yadlapati     // Grab the bios version
404a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
405a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
406a974c132SLakshmi Yadlapati }
407a974c132SLakshmi Yadlapati 
408a974c132SLakshmi Yadlapati inline void
409a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
410a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
411a974c132SLakshmi Yadlapati                      const std::string& value)
412a974c132SLakshmi Yadlapati {
413a974c132SLakshmi Yadlapati     if (ec)
414a974c132SLakshmi Yadlapati     {
415a974c132SLakshmi Yadlapati         // doesn't have to include this
416a974c132SLakshmi Yadlapati         // interface
417a974c132SLakshmi Yadlapati         return;
418a974c132SLakshmi Yadlapati     }
419a974c132SLakshmi Yadlapati 
420a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
421a974c132SLakshmi Yadlapati }
422a974c132SLakshmi Yadlapati 
423a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
424a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
425a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
426a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
427a974c132SLakshmi Yadlapati {
4281abe55efSEd Tanous     if (ec)
4291abe55efSEd Tanous     {
430b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
431ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
432c5b2abe0SLewanczyk, Dawid         return;
433c5b2abe0SLewanczyk, Dawid     }
434c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
435002d39b4SEd Tanous     for (const std::pair<
436002d39b4SEd Tanous              std::string,
437002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4381214b7e7SGunnar Mills              object : subtree)
4391abe55efSEd Tanous     {
440c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
44162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
442002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4431214b7e7SGunnar Mills             connectionNames = object.second;
44426f6976fSEd Tanous         if (connectionNames.empty())
4451abe55efSEd Tanous         {
446c5b2abe0SLewanczyk, Dawid             continue;
447c5b2abe0SLewanczyk, Dawid         }
448029573d4SEd Tanous 
4496c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4506c34de48SEd Tanous         // BiosVer
45104a258f4SEd Tanous         for (const auto& connection : connectionNames)
4521abe55efSEd Tanous         {
45304a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4541abe55efSEd Tanous             {
455a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4561abe55efSEd Tanous                 {
45762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4589d3ae10eSAlpana Kumari 
459ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4605fd0aafbSNinad Palsule                 }
46104a258f4SEd Tanous                 else if (interfaceName ==
46204a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4631abe55efSEd Tanous                 {
46462598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
46557e8c9beSAlpana Kumari 
466ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4675fd0aafbSNinad Palsule                 }
468002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4691abe55efSEd Tanous                 {
47062598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
471bc1d29deSKrzysztof Grobelny 
472bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
473a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
474a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
475ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
476b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4771214b7e7SGunnar Mills                                         properties) {
478a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
479bc1d29deSKrzysztof Grobelny                     });
480c5b2abe0SLewanczyk, Dawid                 }
481029573d4SEd Tanous                 else if (interfaceName ==
482029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4831abe55efSEd Tanous                 {
484bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
485a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
486bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
487a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
488b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
489a974c132SLakshmi Yadlapati                                         properties) {
490a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
491bc1d29deSKrzysztof Grobelny                     });
492e4a4b9a9SJames Feist 
4931e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
494a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
4951e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4961e1e598dSJonathan Doman                         "AssetTag",
4971e1e598dSJonathan Doman                         "AssetTag",
498a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
499a974c132SLakshmi Yadlapati                 }
500a974c132SLakshmi Yadlapati             }
501a974c132SLakshmi Yadlapati         }
502a974c132SLakshmi Yadlapati     }
503a974c132SLakshmi Yadlapati }
504a974c132SLakshmi Yadlapati 
505a974c132SLakshmi Yadlapati /*
506a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
507a974c132SLakshmi Yadlapati  *
508a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
509a974c132SLakshmi Yadlapati  *
510a974c132SLakshmi Yadlapati  * @return None.
511a974c132SLakshmi Yadlapati  */
512a974c132SLakshmi Yadlapati inline void
51351bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
514e4a4b9a9SJames Feist {
515a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
516a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
517a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
518a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
519a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
520a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
521a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
522a974c132SLakshmi Yadlapati     };
523a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
524a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
52551bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
526c5b2abe0SLewanczyk, Dawid }
527c5b2abe0SLewanczyk, Dawid 
528c5b2abe0SLewanczyk, Dawid /**
529c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
530c5b2abe0SLewanczyk, Dawid  *
531ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
532c5b2abe0SLewanczyk, Dawid  *
533c5b2abe0SLewanczyk, Dawid  * @return None.
534c5b2abe0SLewanczyk, Dawid  */
535ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5361abe55efSEd Tanous {
53762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
5381e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5391e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5401e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5411e1e598dSJonathan Doman         "CurrentHostState",
542ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5431e1e598dSJonathan Doman                     const std::string& hostState) {
5441abe55efSEd Tanous         if (ec)
5451abe55efSEd Tanous         {
54622228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
54722228c28SAndrew Geissler             {
54822228c28SAndrew Geissler                 // Service not available, no error, just don't return
54922228c28SAndrew Geissler                 // host state info
55062598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
55122228c28SAndrew Geissler                 return;
55222228c28SAndrew Geissler             }
55362598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
554ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
555c5b2abe0SLewanczyk, Dawid             return;
556c5b2abe0SLewanczyk, Dawid         }
5576617338dSEd Tanous 
55862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
559c5b2abe0SLewanczyk, Dawid         // Verify Host State
5601e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5611abe55efSEd Tanous         {
562*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
563*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
564*539d8c6bSEd Tanous                 resource::State::Enabled;
5651abe55efSEd Tanous         }
5661e1e598dSJonathan Doman         else if (hostState ==
5670fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5688c888608SGunnar Mills         {
569*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
570*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
571*539d8c6bSEd Tanous                 resource::State::Quiesced;
5728c888608SGunnar Mills         }
5731e1e598dSJonathan Doman         else if (hostState ==
5740fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57583935af9SAndrew Geissler         {
576*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
577*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
578*539d8c6bSEd Tanous                 resource::State::InTest;
57983935af9SAndrew Geissler         }
5800fda0f12SGeorge Liu         else if (
5811e1e598dSJonathan Doman             hostState ==
5820fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5831a2a1437SAndrew Geissler         {
584*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] =
585*539d8c6bSEd Tanous                 resource::PowerState::PoweringOn;
586*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
587*539d8c6bSEd Tanous                 resource::State::Starting;
5881a2a1437SAndrew Geissler         }
589002d39b4SEd Tanous         else if (hostState ==
5900fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5911a2a1437SAndrew Geissler         {
592*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] =
593*539d8c6bSEd Tanous                 resource::PowerState::PoweringOff;
594*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
595*539d8c6bSEd Tanous                 resource::State::Disabled;
5961a2a1437SAndrew Geissler         }
5971abe55efSEd Tanous         else
5981abe55efSEd Tanous         {
599*539d8c6bSEd Tanous             asyncResp->res.jsonValue["PowerState"] = resource::PowerState::Off;
600*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
601*539d8c6bSEd Tanous                 resource::State::Disabled;
602c5b2abe0SLewanczyk, Dawid         }
6031e1e598dSJonathan Doman     });
604c5b2abe0SLewanczyk, Dawid }
605c5b2abe0SLewanczyk, Dawid 
606c5b2abe0SLewanczyk, Dawid /**
607786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
608491d8ee7SSantosh Puranik  *
609491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
610491d8ee7SSantosh Puranik  *
611491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
612491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
613491d8ee7SSantosh Puranik  */
61423a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
615491d8ee7SSantosh Puranik {
616491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
617491d8ee7SSantosh Puranik     {
618491d8ee7SSantosh Puranik         return "None";
619491d8ee7SSantosh Puranik     }
6203174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
621491d8ee7SSantosh Puranik     {
622491d8ee7SSantosh Puranik         return "Hdd";
623491d8ee7SSantosh Puranik     }
6243174e4dfSEd Tanous     if (dbusSource ==
625a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
626491d8ee7SSantosh Puranik     {
627491d8ee7SSantosh Puranik         return "Cd";
628491d8ee7SSantosh Puranik     }
6293174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
630491d8ee7SSantosh Puranik     {
631491d8ee7SSantosh Puranik         return "Pxe";
632491d8ee7SSantosh Puranik     }
6333174e4dfSEd Tanous     if (dbusSource ==
634944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6359f16b2c1SJennifer Lee     {
6369f16b2c1SJennifer Lee         return "Usb";
6379f16b2c1SJennifer Lee     }
638491d8ee7SSantosh Puranik     return "";
639491d8ee7SSantosh Puranik }
640491d8ee7SSantosh Puranik 
641491d8ee7SSantosh Puranik /**
642cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
643cd9a4666SKonstantin Aladyshev  *
644cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
645cd9a4666SKonstantin Aladyshev  *
646cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
647cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
648cd9a4666SKonstantin Aladyshev  */
649cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
650cd9a4666SKonstantin Aladyshev {
651cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
652cd9a4666SKonstantin Aladyshev     {
653cd9a4666SKonstantin Aladyshev         return "Legacy";
654cd9a4666SKonstantin Aladyshev     }
655cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
656cd9a4666SKonstantin Aladyshev     {
657cd9a4666SKonstantin Aladyshev         return "UEFI";
658cd9a4666SKonstantin Aladyshev     }
659cd9a4666SKonstantin Aladyshev     return "";
660cd9a4666SKonstantin Aladyshev }
661cd9a4666SKonstantin Aladyshev 
662cd9a4666SKonstantin Aladyshev /**
663786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
664491d8ee7SSantosh Puranik  *
665491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
666491d8ee7SSantosh Puranik  *
667491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
668491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
669491d8ee7SSantosh Puranik  */
67023a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
671491d8ee7SSantosh Puranik {
672491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
673491d8ee7SSantosh Puranik     {
674491d8ee7SSantosh Puranik         return "None";
675491d8ee7SSantosh Puranik     }
6763174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
677491d8ee7SSantosh Puranik     {
678491d8ee7SSantosh Puranik         return "Diags";
679491d8ee7SSantosh Puranik     }
6803174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
681491d8ee7SSantosh Puranik     {
682491d8ee7SSantosh Puranik         return "BiosSetup";
683491d8ee7SSantosh Puranik     }
684491d8ee7SSantosh Puranik     return "";
685491d8ee7SSantosh Puranik }
686491d8ee7SSantosh Puranik 
687491d8ee7SSantosh Puranik /**
688e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
689e43914b3SAndrew Geissler  *
690e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
691e43914b3SAndrew Geissler  *
692e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
693e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
694e43914b3SAndrew Geissler  */
695e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
696e43914b3SAndrew Geissler {
697e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
698e43914b3SAndrew Geissler     // enum
699e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
700e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
701e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
702e43914b3SAndrew Geissler     {
703e43914b3SAndrew Geissler         rfBpLastState = "None";
704e43914b3SAndrew Geissler     }
705e43914b3SAndrew Geissler     else if (dbusBootProgress ==
706e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
707e43914b3SAndrew Geissler              "PrimaryProcInit")
708e43914b3SAndrew Geissler     {
709e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
710e43914b3SAndrew Geissler     }
711e43914b3SAndrew Geissler     else if (dbusBootProgress ==
712e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
713e43914b3SAndrew Geissler              "BusInit")
714e43914b3SAndrew Geissler     {
715e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
716e43914b3SAndrew Geissler     }
717e43914b3SAndrew Geissler     else if (dbusBootProgress ==
718e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
719e43914b3SAndrew Geissler              "MemoryInit")
720e43914b3SAndrew Geissler     {
721e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
722e43914b3SAndrew Geissler     }
723e43914b3SAndrew Geissler     else if (dbusBootProgress ==
724e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
725e43914b3SAndrew Geissler              "SecondaryProcInit")
726e43914b3SAndrew Geissler     {
727e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
728e43914b3SAndrew Geissler     }
729e43914b3SAndrew Geissler     else if (dbusBootProgress ==
730e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
731e43914b3SAndrew Geissler              "PCIInit")
732e43914b3SAndrew Geissler     {
733e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
734e43914b3SAndrew Geissler     }
735e43914b3SAndrew Geissler     else if (dbusBootProgress ==
736e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
737e43914b3SAndrew Geissler              "SystemSetup")
738e43914b3SAndrew Geissler     {
739e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
740e43914b3SAndrew Geissler     }
741e43914b3SAndrew Geissler     else if (dbusBootProgress ==
742e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
743e43914b3SAndrew Geissler              "SystemInitComplete")
744e43914b3SAndrew Geissler     {
745e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
746e43914b3SAndrew Geissler     }
747e43914b3SAndrew Geissler     else if (dbusBootProgress ==
748e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
749e43914b3SAndrew Geissler              "OSStart")
750e43914b3SAndrew Geissler     {
751e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
752e43914b3SAndrew Geissler     }
753e43914b3SAndrew Geissler     else if (dbusBootProgress ==
754e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
755e43914b3SAndrew Geissler              "OSRunning")
756e43914b3SAndrew Geissler     {
757e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
758e43914b3SAndrew Geissler     }
759e43914b3SAndrew Geissler     else
760e43914b3SAndrew Geissler     {
76162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
762e43914b3SAndrew Geissler         // Just return the default
763e43914b3SAndrew Geissler     }
764e43914b3SAndrew Geissler     return rfBpLastState;
765e43914b3SAndrew Geissler }
766e43914b3SAndrew Geissler 
767e43914b3SAndrew Geissler /**
768786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
769491d8ee7SSantosh Puranik  *
770491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
771944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
772944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
773491d8ee7SSantosh Puranik  *
774944ffaf9SJohnathan Mantey  * @return Integer error code.
775491d8ee7SSantosh Puranik  */
776ac106bf6SEd Tanous inline int
777ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
778ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
779ac106bf6SEd Tanous                          std::string& bootMode)
780491d8ee7SSantosh Puranik {
781c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
782c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
783944ffaf9SJohnathan Mantey 
784491d8ee7SSantosh Puranik     if (rfSource == "None")
785491d8ee7SSantosh Puranik     {
786944ffaf9SJohnathan Mantey         return 0;
787491d8ee7SSantosh Puranik     }
7883174e4dfSEd Tanous     if (rfSource == "Pxe")
789491d8ee7SSantosh Puranik     {
790944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
791944ffaf9SJohnathan Mantey     }
792944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
793944ffaf9SJohnathan Mantey     {
794944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
795944ffaf9SJohnathan Mantey     }
796944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
797944ffaf9SJohnathan Mantey     {
798944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
799944ffaf9SJohnathan Mantey     }
800944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
801944ffaf9SJohnathan Mantey     {
802944ffaf9SJohnathan Mantey         bootSource =
803944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
804944ffaf9SJohnathan Mantey     }
805944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
806944ffaf9SJohnathan Mantey     {
807944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
808491d8ee7SSantosh Puranik     }
8099f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8109f16b2c1SJennifer Lee     {
811944ffaf9SJohnathan Mantey         bootSource =
812944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8139f16b2c1SJennifer Lee     }
814491d8ee7SSantosh Puranik     else
815491d8ee7SSantosh Puranik     {
81662598e31SEd Tanous         BMCWEB_LOG_DEBUG(
81762598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
81862598e31SEd Tanous             bootSource);
819ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
820944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
821944ffaf9SJohnathan Mantey         return -1;
822491d8ee7SSantosh Puranik     }
823944ffaf9SJohnathan Mantey     return 0;
824491d8ee7SSantosh Puranik }
8251981771bSAli Ahmed 
826978b8803SAndrew Geissler /**
827978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
828978b8803SAndrew Geissler  *
829ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
830978b8803SAndrew Geissler  *
831978b8803SAndrew Geissler  * @return None.
832978b8803SAndrew Geissler  */
833ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
834978b8803SAndrew Geissler {
8351e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8361e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8371e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8381e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
839ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8401e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
841978b8803SAndrew Geissler         if (ec)
842978b8803SAndrew Geissler         {
843978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
844978b8803SAndrew Geissler             // not found
845978b8803SAndrew Geissler             return;
846978b8803SAndrew Geissler         }
847978b8803SAndrew Geissler 
84862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
849978b8803SAndrew Geissler 
850ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
851e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8521e1e598dSJonathan Doman     });
853978b8803SAndrew Geissler }
854491d8ee7SSantosh Puranik 
855491d8ee7SSantosh Puranik /**
856b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
857b6d5d45cSHieu Huynh  *
858ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
859b6d5d45cSHieu Huynh  *
860b6d5d45cSHieu Huynh  * @return None.
861b6d5d45cSHieu Huynh  */
862b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
863ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
864b6d5d45cSHieu Huynh {
865b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
866b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
867b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
868b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
869ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
870b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
871b6d5d45cSHieu Huynh         if (ec)
872b6d5d45cSHieu Huynh         {
87362598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
874b6d5d45cSHieu Huynh             return;
875b6d5d45cSHieu Huynh         }
876b6d5d45cSHieu Huynh 
877b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
878b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
879b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
880b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
881b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
882b6d5d45cSHieu Huynh 
883b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
884ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
885b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
886b6d5d45cSHieu Huynh     });
887b6d5d45cSHieu Huynh }
888b6d5d45cSHieu Huynh 
889b6d5d45cSHieu Huynh /**
890c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
891cd9a4666SKonstantin Aladyshev  *
892ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
893cd9a4666SKonstantin Aladyshev  *
894cd9a4666SKonstantin Aladyshev  * @return None.
895cd9a4666SKonstantin Aladyshev  */
896cd9a4666SKonstantin Aladyshev 
897ac106bf6SEd Tanous inline void
898ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
899cd9a4666SKonstantin Aladyshev {
9001e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9011e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9021e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9031e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
904ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9051e1e598dSJonathan Doman                     const std::string& bootType) {
906cd9a4666SKonstantin Aladyshev         if (ec)
907cd9a4666SKonstantin Aladyshev         {
908cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
909cd9a4666SKonstantin Aladyshev             return;
910cd9a4666SKonstantin Aladyshev         }
911cd9a4666SKonstantin Aladyshev 
91262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
913cd9a4666SKonstantin Aladyshev 
914ac106bf6SEd Tanous         asyncResp->res
915ac106bf6SEd Tanous             .jsonValue["Boot"]
916002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
917613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
918cd9a4666SKonstantin Aladyshev 
9191e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
920cd9a4666SKonstantin Aladyshev         if (rfType.empty())
921cd9a4666SKonstantin Aladyshev         {
922ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
923cd9a4666SKonstantin Aladyshev             return;
924cd9a4666SKonstantin Aladyshev         }
925cd9a4666SKonstantin Aladyshev 
926ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9271e1e598dSJonathan Doman     });
928cd9a4666SKonstantin Aladyshev }
929cd9a4666SKonstantin Aladyshev 
930cd9a4666SKonstantin Aladyshev /**
931c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
932491d8ee7SSantosh Puranik  *
933ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
934491d8ee7SSantosh Puranik  *
935491d8ee7SSantosh Puranik  * @return None.
936491d8ee7SSantosh Puranik  */
937c21865c4SKonstantin Aladyshev 
938ac106bf6SEd Tanous inline void
939ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
940491d8ee7SSantosh Puranik {
9411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9431e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9441e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
945ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9461e1e598dSJonathan Doman                     const std::string& bootModeStr) {
947491d8ee7SSantosh Puranik         if (ec)
948491d8ee7SSantosh Puranik         {
949b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
950ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
951491d8ee7SSantosh Puranik             return;
952491d8ee7SSantosh Puranik         }
953491d8ee7SSantosh Puranik 
95462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
955491d8ee7SSantosh Puranik 
95620fa6a2cSEd Tanous         nlohmann::json::array_t allowed;
95720fa6a2cSEd Tanous         allowed.emplace_back("None");
95820fa6a2cSEd Tanous         allowed.emplace_back("Pxe");
95920fa6a2cSEd Tanous         allowed.emplace_back("Hdd");
96020fa6a2cSEd Tanous         allowed.emplace_back("Cd");
96120fa6a2cSEd Tanous         allowed.emplace_back("Diags");
96220fa6a2cSEd Tanous         allowed.emplace_back("BiosSetup");
96320fa6a2cSEd Tanous         allowed.emplace_back("Usb");
96420fa6a2cSEd Tanous 
965ac106bf6SEd Tanous         asyncResp->res
9660fda0f12SGeorge Liu             .jsonValue["Boot"]
96720fa6a2cSEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
96820fa6a2cSEd Tanous             std::move(allowed);
9691e1e598dSJonathan Doman         if (bootModeStr !=
970491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
971491d8ee7SSantosh Puranik         {
9721e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
973491d8ee7SSantosh Puranik             if (!rfMode.empty())
974491d8ee7SSantosh Puranik             {
975ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
976491d8ee7SSantosh Puranik                     rfMode;
977491d8ee7SSantosh Puranik             }
978491d8ee7SSantosh Puranik         }
9791e1e598dSJonathan Doman     });
980491d8ee7SSantosh Puranik }
981491d8ee7SSantosh Puranik 
982491d8ee7SSantosh Puranik /**
983c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
984491d8ee7SSantosh Puranik  *
985ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
986491d8ee7SSantosh Puranik  *
987491d8ee7SSantosh Puranik  * @return None.
988491d8ee7SSantosh Puranik  */
989c21865c4SKonstantin Aladyshev 
990c21865c4SKonstantin Aladyshev inline void
991ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
992491d8ee7SSantosh Puranik {
9931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9951e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9961e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
997ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9981e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
999491d8ee7SSantosh Puranik         if (ec)
1000491d8ee7SSantosh Puranik         {
10015ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10025ef735c8SNan Zhou             {
10035ef735c8SNan Zhou                 return;
10045ef735c8SNan Zhou             }
1005b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1006ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1007491d8ee7SSantosh Puranik             return;
1008491d8ee7SSantosh Puranik         }
1009491d8ee7SSantosh Puranik 
101062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1011491d8ee7SSantosh Puranik 
10121e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1013491d8ee7SSantosh Puranik         if (!rfSource.empty())
1014491d8ee7SSantosh Puranik         {
1015ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1016ac106bf6SEd Tanous                 rfSource;
1017491d8ee7SSantosh Puranik         }
1018cd9a4666SKonstantin Aladyshev 
1019cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1020cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1021ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10221e1e598dSJonathan Doman     });
1023491d8ee7SSantosh Puranik }
1024491d8ee7SSantosh Puranik 
1025491d8ee7SSantosh Puranik /**
1026c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1027c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1028c21865c4SKonstantin Aladyshev  * state
1029491d8ee7SSantosh Puranik  *
1030ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1031491d8ee7SSantosh Puranik  *
1032491d8ee7SSantosh Puranik  * @return None.
1033491d8ee7SSantosh Puranik  */
1034491d8ee7SSantosh Puranik 
1035ac106bf6SEd Tanous inline void processBootOverrideEnable(
1036ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1037c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1038c21865c4SKonstantin Aladyshev {
1039c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1040c21865c4SKonstantin Aladyshev     {
1041ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1042ac106bf6SEd Tanous             "Disabled";
1043c21865c4SKonstantin Aladyshev         return;
1044c21865c4SKonstantin Aladyshev     }
1045c21865c4SKonstantin Aladyshev 
1046c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1047c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10481e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10491e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10501e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10511e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1052ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1053491d8ee7SSantosh Puranik         if (ec)
1054491d8ee7SSantosh Puranik         {
1055b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1056ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1057491d8ee7SSantosh Puranik             return;
1058491d8ee7SSantosh Puranik         }
1059491d8ee7SSantosh Puranik 
1060c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1061c21865c4SKonstantin Aladyshev         {
1062ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1063ac106bf6SEd Tanous                 "Once";
1064c21865c4SKonstantin Aladyshev         }
1065c21865c4SKonstantin Aladyshev         else
1066c21865c4SKonstantin Aladyshev         {
1067ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1068c21865c4SKonstantin Aladyshev                 "Continuous";
1069c21865c4SKonstantin Aladyshev         }
10701e1e598dSJonathan Doman     });
1071491d8ee7SSantosh Puranik }
1072491d8ee7SSantosh Puranik 
1073491d8ee7SSantosh Puranik /**
1074c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1075c21865c4SKonstantin Aladyshev  *
1076ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1077c21865c4SKonstantin Aladyshev  *
1078c21865c4SKonstantin Aladyshev  * @return None.
1079c21865c4SKonstantin Aladyshev  */
1080c21865c4SKonstantin Aladyshev 
1081c21865c4SKonstantin Aladyshev inline void
1082ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1083c21865c4SKonstantin Aladyshev {
10841e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10851e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10861e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10871e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1088ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10891e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1090c21865c4SKonstantin Aladyshev         if (ec)
1091c21865c4SKonstantin Aladyshev         {
10925ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10935ef735c8SNan Zhou             {
10945ef735c8SNan Zhou                 return;
10955ef735c8SNan Zhou             }
1096b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1097ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1098c21865c4SKonstantin Aladyshev             return;
1099c21865c4SKonstantin Aladyshev         }
1100c21865c4SKonstantin Aladyshev 
1101ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11021e1e598dSJonathan Doman     });
1103c21865c4SKonstantin Aladyshev }
1104c21865c4SKonstantin Aladyshev 
1105c21865c4SKonstantin Aladyshev /**
1106c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1107c21865c4SKonstantin Aladyshev  *
1108ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1109c21865c4SKonstantin Aladyshev  *
1110c21865c4SKonstantin Aladyshev  * @return None.
1111c21865c4SKonstantin Aladyshev  */
1112ac106bf6SEd Tanous inline void
1113ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1114c21865c4SKonstantin Aladyshev {
111562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1116c21865c4SKonstantin Aladyshev 
1117ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1118ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1119ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1120c21865c4SKonstantin Aladyshev }
1121c21865c4SKonstantin Aladyshev 
1122c21865c4SKonstantin Aladyshev /**
1123c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1124c0557e1aSGunnar Mills  *
1125c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1126c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1127c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1128c0557e1aSGunnar Mills  * last power operation time.
1129c0557e1aSGunnar Mills  *
1130ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1131c0557e1aSGunnar Mills  *
1132c0557e1aSGunnar Mills  * @return None.
1133c0557e1aSGunnar Mills  */
1134ac106bf6SEd Tanous inline void
1135ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1136c0557e1aSGunnar Mills {
113762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1138c0557e1aSGunnar Mills 
11391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11411e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11421e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1143ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1144ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1145c0557e1aSGunnar Mills         if (ec)
1146c0557e1aSGunnar Mills         {
114762598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1148c0557e1aSGunnar Mills             return;
1149c0557e1aSGunnar Mills         }
1150c0557e1aSGunnar Mills 
1151c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1152c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11531e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1154c0557e1aSGunnar Mills 
1155c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1156ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
11572b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11581e1e598dSJonathan Doman     });
1159c0557e1aSGunnar Mills }
1160c0557e1aSGunnar Mills 
1161c0557e1aSGunnar Mills /**
1162797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1163797d5daeSCorey Hardesty  *
1164797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1165797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1166797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1167797d5daeSCorey Hardesty  * dbus.
1168797d5daeSCorey Hardesty  *
1169ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1170797d5daeSCorey Hardesty  *
1171797d5daeSCorey Hardesty  * @return None.
1172797d5daeSCorey Hardesty  */
1173ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1174ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1175797d5daeSCorey Hardesty {
117662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1177797d5daeSCorey Hardesty 
1178797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1179797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1180797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1181797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1182ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1183ac106bf6SEd Tanous             const boost::system::error_code& ec,
1184797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1185797d5daeSCorey Hardesty         if (ec)
1186797d5daeSCorey Hardesty         {
1187797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1188797d5daeSCorey Hardesty             {
118962598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1190ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1191797d5daeSCorey Hardesty             }
1192797d5daeSCorey Hardesty             return;
1193797d5daeSCorey Hardesty         }
1194797d5daeSCorey Hardesty 
1195797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1196797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1197797d5daeSCorey Hardesty 
1198797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1199797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1200797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1201797d5daeSCorey Hardesty 
1202797d5daeSCorey Hardesty         if (!success)
1203797d5daeSCorey Hardesty         {
1204ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1205797d5daeSCorey Hardesty             return;
1206797d5daeSCorey Hardesty         }
1207797d5daeSCorey Hardesty 
1208797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1209797d5daeSCorey Hardesty         {
1210ac106bf6SEd Tanous             asyncResp->res
1211ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1212797d5daeSCorey Hardesty                 *attemptsLeft;
1213797d5daeSCorey Hardesty         }
1214797d5daeSCorey Hardesty 
1215797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1216797d5daeSCorey Hardesty         {
1217ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1218797d5daeSCorey Hardesty                 *retryAttempts;
1219797d5daeSCorey Hardesty         }
1220797d5daeSCorey Hardesty     });
1221797d5daeSCorey Hardesty }
1222797d5daeSCorey Hardesty 
1223797d5daeSCorey Hardesty /**
12246bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12256bd5a8d2SGunnar Mills  *
1226ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12276bd5a8d2SGunnar Mills  *
12286bd5a8d2SGunnar Mills  * @return None.
12296bd5a8d2SGunnar Mills  */
1230797d5daeSCorey Hardesty inline void
1231ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12326bd5a8d2SGunnar Mills {
123362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12346bd5a8d2SGunnar Mills 
12351e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12361e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12371e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12381e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1239ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1240ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12416bd5a8d2SGunnar Mills         if (ec)
12426bd5a8d2SGunnar Mills         {
1243797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1244797d5daeSCorey Hardesty             {
124562598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1246ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1247797d5daeSCorey Hardesty             }
12486bd5a8d2SGunnar Mills             return;
12496bd5a8d2SGunnar Mills         }
12506bd5a8d2SGunnar Mills 
125162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1252e05aec50SEd Tanous         if (autoRebootEnabled)
12536bd5a8d2SGunnar Mills         {
1254ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12556bd5a8d2SGunnar Mills                 "RetryAttempts";
12566bd5a8d2SGunnar Mills         }
12576bd5a8d2SGunnar Mills         else
12586bd5a8d2SGunnar Mills         {
1259ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1260ac106bf6SEd Tanous                 "Disabled";
12616bd5a8d2SGunnar Mills         }
1262ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
126369f35306SGunnar Mills 
126469f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
126569f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
126669f35306SGunnar Mills         // RetryAttempts.
126720fa6a2cSEd Tanous         nlohmann::json::array_t allowed;
126820fa6a2cSEd Tanous         allowed.emplace_back("Disabled");
126920fa6a2cSEd Tanous         allowed.emplace_back("RetryAttempts");
1270ac106bf6SEd Tanous         asyncResp->res
1271ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
127220fa6a2cSEd Tanous             std::move(allowed);
12731e1e598dSJonathan Doman     });
12746bd5a8d2SGunnar Mills }
12756bd5a8d2SGunnar Mills 
12766bd5a8d2SGunnar Mills /**
1277797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1278797d5daeSCorey Hardesty  *
1279ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1280797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1281797d5daeSCorey Hardesty  *
1282797d5daeSCorey Hardesty  *@return None.
1283797d5daeSCorey Hardesty  */
1284797d5daeSCorey Hardesty 
1285ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1286ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1287797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1288797d5daeSCorey Hardesty {
128962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
129087c44966SAsmitha Karunanithi     setDbusProperty(
1291e93abac6SGinu George         asyncResp, "Boot/AutomaticRetryAttempts",
1292e93abac6SGinu George         "xyz.openbmc_project.State.Host",
129387c44966SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
12949ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1295e93abac6SGinu George         retryAttempts);
1296797d5daeSCorey Hardesty }
1297797d5daeSCorey Hardesty 
12988d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12998d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13008d69c668SEd Tanous {
13018d69c668SEd Tanous     if (value ==
13028d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13038d69c668SEd Tanous     {
13048d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13058d69c668SEd Tanous     }
13068d69c668SEd Tanous     if (value ==
13078d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13088d69c668SEd Tanous     {
13098d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13108d69c668SEd Tanous     }
13118d69c668SEd Tanous     if (value ==
13123a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13138d69c668SEd Tanous     {
13148d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13158d69c668SEd Tanous     }
13168d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13178d69c668SEd Tanous     {
13188d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13198d69c668SEd Tanous     }
13208d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13218d69c668SEd Tanous }
1322797d5daeSCorey Hardesty /**
1323c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1324c6a620f2SGeorge Liu  *
1325ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1326c6a620f2SGeorge Liu  *
1327c6a620f2SGeorge Liu  * @return None.
1328c6a620f2SGeorge Liu  */
13298d1b46d7Szhanghch05 inline void
1330ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1331c6a620f2SGeorge Liu {
133262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1333c6a620f2SGeorge Liu 
13341e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13351e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13361e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13371e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1338ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13395e7e2dc5SEd Tanous                     const std::string& policy) {
1340c6a620f2SGeorge Liu         if (ec)
1341c6a620f2SGeorge Liu         {
134262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1343c6a620f2SGeorge Liu             return;
1344c6a620f2SGeorge Liu         }
13458d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
13468d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
13478d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1348c6a620f2SGeorge Liu         {
1349ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1350c6a620f2SGeorge Liu             return;
1351c6a620f2SGeorge Liu         }
1352c6a620f2SGeorge Liu 
13538d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13541e1e598dSJonathan Doman     });
1355c6a620f2SGeorge Liu }
1356c6a620f2SGeorge Liu 
1357c6a620f2SGeorge Liu /**
13589dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13599dcfe8c1SAlbert Zhang  *
13609dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13619dcfe8c1SAlbert Zhang  *
13629dcfe8c1SAlbert Zhang  * @return None.
13639dcfe8c1SAlbert Zhang  */
13649dcfe8c1SAlbert Zhang inline void
13659dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13669dcfe8c1SAlbert Zhang {
136762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13689dcfe8c1SAlbert Zhang 
13699dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
13709dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13719dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
13729dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13739dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13749dcfe8c1SAlbert Zhang         if (ec)
13759dcfe8c1SAlbert Zhang         {
13769dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
13779dcfe8c1SAlbert Zhang             {
1378b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13799dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
13809dcfe8c1SAlbert Zhang             }
13819dcfe8c1SAlbert Zhang             return;
13829dcfe8c1SAlbert Zhang         }
13839dcfe8c1SAlbert Zhang 
13849dcfe8c1SAlbert Zhang         if (value)
13859dcfe8c1SAlbert Zhang         {
1386*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1387*539d8c6bSEd Tanous                 computer_system::StopBootOnFault::AnyFault;
13889dcfe8c1SAlbert Zhang         }
13899dcfe8c1SAlbert Zhang         else
13909dcfe8c1SAlbert Zhang         {
1391*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1392*539d8c6bSEd Tanous                 computer_system::StopBootOnFault::Never;
13939dcfe8c1SAlbert Zhang         }
13949dcfe8c1SAlbert Zhang     });
13959dcfe8c1SAlbert Zhang }
13969dcfe8c1SAlbert Zhang 
13979dcfe8c1SAlbert Zhang /**
13981981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13991981771bSAli Ahmed  * TPM is required for booting the host.
14001981771bSAli Ahmed  *
1401ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14021981771bSAli Ahmed  *
14031981771bSAli Ahmed  * @return None.
14041981771bSAli Ahmed  */
14051981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1406ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14071981771bSAli Ahmed {
140862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1409e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1410e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1411e99073f5SGeorge Liu     dbus::utility::getSubTree(
1412e99073f5SGeorge Liu         "/", 0, interfaces,
1413ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1414b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14151981771bSAli Ahmed         if (ec)
14161981771bSAli Ahmed         {
141762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
141862598e31SEd Tanous                              ec);
14191981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14201981771bSAli Ahmed             // error occurs
14211981771bSAli Ahmed             return;
14221981771bSAli Ahmed         }
142326f6976fSEd Tanous         if (subtree.empty())
14241981771bSAli Ahmed         {
14251981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14261981771bSAli Ahmed             // if there is no instance found
14271981771bSAli Ahmed             return;
14281981771bSAli Ahmed         }
14291981771bSAli Ahmed 
14301981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14311981771bSAli Ahmed         if (subtree.size() > 1)
14321981771bSAli Ahmed         {
143362598e31SEd Tanous             BMCWEB_LOG_DEBUG(
143462598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
143562598e31SEd Tanous                 subtree.size());
14361981771bSAli Ahmed             // Throw an internal Error and return
1437ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14381981771bSAli Ahmed             return;
14391981771bSAli Ahmed         }
14401981771bSAli Ahmed 
14411981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14421981771bSAli Ahmed         // field
14431981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14441981771bSAli Ahmed         {
144562598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1446ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14471981771bSAli Ahmed             return;
14481981771bSAli Ahmed         }
14491981771bSAli Ahmed 
14501981771bSAli Ahmed         const std::string& path = subtree[0].first;
14511981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14521981771bSAli Ahmed 
14531981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14541e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14551e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14561e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1457ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1458ac106bf6SEd Tanous                         bool tpmRequired) {
14598a592810SEd Tanous             if (ec2)
14601981771bSAli Ahmed             {
1461b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
146262598e31SEd Tanous                                  ec2);
1463ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14641981771bSAli Ahmed                 return;
14651981771bSAli Ahmed             }
14661981771bSAli Ahmed 
14671e1e598dSJonathan Doman             if (tpmRequired)
14681981771bSAli Ahmed             {
1469ac106bf6SEd Tanous                 asyncResp->res
1470ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14711981771bSAli Ahmed                     "Required";
14721981771bSAli Ahmed             }
14731981771bSAli Ahmed             else
14741981771bSAli Ahmed             {
1475ac106bf6SEd Tanous                 asyncResp->res
1476ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14771981771bSAli Ahmed                     "Disabled";
14781981771bSAli Ahmed             }
14791e1e598dSJonathan Doman         });
1480e99073f5SGeorge Liu     });
14811981771bSAli Ahmed }
14821981771bSAli Ahmed 
14831981771bSAli Ahmed /**
14841c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14851c05dae3SAli Ahmed  * TPM is required for booting the host.
14861c05dae3SAli Ahmed  *
1487ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14881c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14891c05dae3SAli Ahmed  *
14901c05dae3SAli Ahmed  * @return None.
14911c05dae3SAli Ahmed  */
14921c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1493ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14941c05dae3SAli Ahmed {
149562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1496e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1497e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1498e99073f5SGeorge Liu     dbus::utility::getSubTree(
1499e99073f5SGeorge Liu         "/", 0, interfaces,
1500ac106bf6SEd Tanous         [asyncResp,
1501e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1502e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15031c05dae3SAli Ahmed         if (ec)
15041c05dae3SAli Ahmed         {
1505b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
150662598e31SEd Tanous                              ec);
1507ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15081c05dae3SAli Ahmed             return;
15091c05dae3SAli Ahmed         }
151026f6976fSEd Tanous         if (subtree.empty())
15111c05dae3SAli Ahmed         {
1512ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15131c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15141c05dae3SAli Ahmed             return;
15151c05dae3SAli Ahmed         }
15161c05dae3SAli Ahmed 
15171c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15181c05dae3SAli Ahmed         if (subtree.size() > 1)
15191c05dae3SAli Ahmed         {
152062598e31SEd Tanous             BMCWEB_LOG_DEBUG(
152162598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
152262598e31SEd Tanous                 subtree.size());
15231c05dae3SAli Ahmed             // Throw an internal Error and return
1524ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15251c05dae3SAli Ahmed             return;
15261c05dae3SAli Ahmed         }
15271c05dae3SAli Ahmed 
15281c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15291c05dae3SAli Ahmed         // field
15301c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15311c05dae3SAli Ahmed         {
153262598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1533ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15341c05dae3SAli Ahmed             return;
15351c05dae3SAli Ahmed         }
15361c05dae3SAli Ahmed 
15371c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15381c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15391c05dae3SAli Ahmed 
15401c05dae3SAli Ahmed         if (serv.empty())
15411c05dae3SAli Ahmed         {
154262598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1543ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15441c05dae3SAli Ahmed             return;
15451c05dae3SAli Ahmed         }
15461c05dae3SAli Ahmed 
15471c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
1548e93abac6SGinu George         setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1549e93abac6SGinu George                         path, "xyz.openbmc_project.Control.TPM.Policy",
1550e93abac6SGinu George                         "TPMEnable", tpmRequired);
1551e99073f5SGeorge Liu     });
15521c05dae3SAli Ahmed }
15531c05dae3SAli Ahmed 
15541c05dae3SAli Ahmed /**
1555491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1556491d8ee7SSantosh Puranik  *
1557ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1558cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1559cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1560cd9a4666SKonstantin Aladyshev  */
1561ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1562cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1563cd9a4666SKonstantin Aladyshev {
1564c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1565cd9a4666SKonstantin Aladyshev 
1566c21865c4SKonstantin Aladyshev     if (!bootType)
1567cd9a4666SKonstantin Aladyshev     {
1568c21865c4SKonstantin Aladyshev         return;
1569c21865c4SKonstantin Aladyshev     }
1570c21865c4SKonstantin Aladyshev 
1571cd9a4666SKonstantin Aladyshev     // Source target specified
157262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1573cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1574cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1575cd9a4666SKonstantin Aladyshev     {
1576cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1577cd9a4666SKonstantin Aladyshev     }
1578cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1579cd9a4666SKonstantin Aladyshev     {
1580cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1581cd9a4666SKonstantin Aladyshev     }
1582cd9a4666SKonstantin Aladyshev     else
1583cd9a4666SKonstantin Aladyshev     {
158462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
158562598e31SEd Tanous                          "BootSourceOverrideMode: {}",
158662598e31SEd Tanous                          *bootType);
1587ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1588cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1589cd9a4666SKonstantin Aladyshev         return;
1590cd9a4666SKonstantin Aladyshev     }
1591cd9a4666SKonstantin Aladyshev 
1592cd9a4666SKonstantin Aladyshev     // Act on validated parameters
159362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1594cd9a4666SKonstantin Aladyshev 
1595e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1596e93abac6SGinu George                     "xyz.openbmc_project.Settings",
159787c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
159887c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
159987c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
1600e93abac6SGinu George                     bootTypeStr);
1601cd9a4666SKonstantin Aladyshev }
1602cd9a4666SKonstantin Aladyshev 
1603cd9a4666SKonstantin Aladyshev /**
1604cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1605cd9a4666SKonstantin Aladyshev  *
1606ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1607ac106bf6SEd Tanous  * message.
1608c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1609c21865c4SKonstantin Aladyshev  * @return Integer error code.
1610c21865c4SKonstantin Aladyshev  */
1611ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1612c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1613c21865c4SKonstantin Aladyshev {
1614c21865c4SKonstantin Aladyshev     if (!bootEnable)
1615c21865c4SKonstantin Aladyshev     {
1616c21865c4SKonstantin Aladyshev         return;
1617c21865c4SKonstantin Aladyshev     }
1618c21865c4SKonstantin Aladyshev     // Source target specified
161962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1620c21865c4SKonstantin Aladyshev 
1621c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1622c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1623c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1624c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1625c21865c4SKonstantin Aladyshev     {
1626c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1627c21865c4SKonstantin Aladyshev     }
1628c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1629c21865c4SKonstantin Aladyshev     {
1630c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1631c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1632c21865c4SKonstantin Aladyshev     }
1633c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1634c21865c4SKonstantin Aladyshev     {
1635c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1636c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1637c21865c4SKonstantin Aladyshev     }
1638c21865c4SKonstantin Aladyshev     else
1639c21865c4SKonstantin Aladyshev     {
164062598e31SEd Tanous         BMCWEB_LOG_DEBUG(
164162598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
164262598e31SEd Tanous             *bootEnable);
1643ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1644c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1645c21865c4SKonstantin Aladyshev         return;
1646c21865c4SKonstantin Aladyshev     }
1647c21865c4SKonstantin Aladyshev 
1648c21865c4SKonstantin Aladyshev     // Act on validated parameters
164962598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1650c21865c4SKonstantin Aladyshev 
1651e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1652e93abac6SGinu George                     "xyz.openbmc_project.Settings",
165387c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
165487c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
165587c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1656e93abac6SGinu George                     bootOverrideEnable);
1657c21865c4SKonstantin Aladyshev 
1658c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1659c21865c4SKonstantin Aladyshev     {
1660c21865c4SKonstantin Aladyshev         return;
1661c21865c4SKonstantin Aladyshev     }
1662c21865c4SKonstantin Aladyshev 
1663c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1664c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
166562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
166662598e31SEd Tanous                      bootOverridePersistent);
1667c21865c4SKonstantin Aladyshev 
1668e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1669e93abac6SGinu George                     "xyz.openbmc_project.Settings",
167087c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
167187c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot/one_time"),
167287c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
1673e93abac6SGinu George                     !bootOverridePersistent);
1674c21865c4SKonstantin Aladyshev }
1675c21865c4SKonstantin Aladyshev 
1676c21865c4SKonstantin Aladyshev /**
1677c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1678c21865c4SKonstantin Aladyshev  *
1679ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1680491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1681491d8ee7SSantosh Puranik  *
1682265c1602SJohnathan Mantey  * @return Integer error code.
1683491d8ee7SSantosh Puranik  */
1684ac106bf6SEd Tanous inline void
1685ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1686cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1687491d8ee7SSantosh Puranik {
1688c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1689c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1690944ffaf9SJohnathan Mantey 
1691c21865c4SKonstantin Aladyshev     if (!bootSource)
1692491d8ee7SSantosh Puranik     {
1693c21865c4SKonstantin Aladyshev         return;
1694c21865c4SKonstantin Aladyshev     }
1695c21865c4SKonstantin Aladyshev 
1696491d8ee7SSantosh Puranik     // Source target specified
169762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1698491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1699ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1700ac106bf6SEd Tanous                              bootModeStr) != 0)
1701491d8ee7SSantosh Puranik     {
170262598e31SEd Tanous         BMCWEB_LOG_DEBUG(
170362598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
170462598e31SEd Tanous             *bootSource);
1705ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1706491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1707491d8ee7SSantosh Puranik         return;
1708491d8ee7SSantosh Puranik     }
1709491d8ee7SSantosh Puranik 
1710944ffaf9SJohnathan Mantey     // Act on validated parameters
171162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
171262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1713944ffaf9SJohnathan Mantey 
1714e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1715e93abac6SGinu George                     "xyz.openbmc_project.Settings",
171687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
171787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
171887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1719e93abac6SGinu George                     bootSourceStr);
1720e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1721e93abac6SGinu George                     "xyz.openbmc_project.Settings",
172287c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
172387c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
172487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1725e93abac6SGinu George                     bootModeStr);
1726cd9a4666SKonstantin Aladyshev }
1727944ffaf9SJohnathan Mantey 
1728cd9a4666SKonstantin Aladyshev /**
1729c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1730491d8ee7SSantosh Puranik  *
1731ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1732491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1733cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1734491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1735491d8ee7SSantosh Puranik  *
1736265c1602SJohnathan Mantey  * @return Integer error code.
1737491d8ee7SSantosh Puranik  */
1738c21865c4SKonstantin Aladyshev 
1739ac106bf6SEd Tanous inline void
1740ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1741c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1742c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1743c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1744491d8ee7SSantosh Puranik {
174562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1746491d8ee7SSantosh Puranik 
1747ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1748ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1749ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1750491d8ee7SSantosh Puranik }
1751491d8ee7SSantosh Puranik 
1752c6a620f2SGeorge Liu /**
175398e386ecSGunnar Mills  * @brief Sets AssetTag
175498e386ecSGunnar Mills  *
1755ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
175698e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
175798e386ecSGunnar Mills  *
175898e386ecSGunnar Mills  * @return None.
175998e386ecSGunnar Mills  */
1760ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
176198e386ecSGunnar Mills                         const std::string& assetTag)
176298e386ecSGunnar Mills {
1763e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1764e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1765e99073f5SGeorge Liu     dbus::utility::getSubTree(
1766e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1767ac106bf6SEd Tanous         [asyncResp,
1768e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1769b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
177098e386ecSGunnar Mills         if (ec)
177198e386ecSGunnar Mills         {
177262598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1773ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
177498e386ecSGunnar Mills             return;
177598e386ecSGunnar Mills         }
177626f6976fSEd Tanous         if (subtree.empty())
177798e386ecSGunnar Mills         {
177862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1779ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
178098e386ecSGunnar Mills             return;
178198e386ecSGunnar Mills         }
178298e386ecSGunnar Mills         // Assume only 1 system D-Bus object
178398e386ecSGunnar Mills         // Throw an error if there is more than 1
178498e386ecSGunnar Mills         if (subtree.size() > 1)
178598e386ecSGunnar Mills         {
178662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1787ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
178898e386ecSGunnar Mills             return;
178998e386ecSGunnar Mills         }
179098e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
179198e386ecSGunnar Mills         {
179262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1793ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
179498e386ecSGunnar Mills             return;
179598e386ecSGunnar Mills         }
179698e386ecSGunnar Mills 
179798e386ecSGunnar Mills         const std::string& path = subtree[0].first;
179898e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
179998e386ecSGunnar Mills 
180098e386ecSGunnar Mills         if (service.empty())
180198e386ecSGunnar Mills         {
180262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1803ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
180498e386ecSGunnar Mills             return;
180598e386ecSGunnar Mills         }
180698e386ecSGunnar Mills 
1807e93abac6SGinu George         setDbusProperty(asyncResp, "AssetTag", service, path,
180887c44966SAsmitha Karunanithi                         "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1809e93abac6SGinu George                         "AssetTag", assetTag);
1810e99073f5SGeorge Liu     });
181198e386ecSGunnar Mills }
181298e386ecSGunnar Mills 
181398e386ecSGunnar Mills /**
18149dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18159dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18169dcfe8c1SAlbert Zhang  *
18179dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18189dcfe8c1SAlbert Zhang  * stopBootOnFault
18199dcfe8c1SAlbert Zhang  *
18209dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18219dcfe8c1SAlbert Zhang  */
18229dcfe8c1SAlbert Zhang inline std::optional<bool>
18239dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
18249dcfe8c1SAlbert Zhang {
18259dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18269dcfe8c1SAlbert Zhang     {
18279dcfe8c1SAlbert Zhang         return true;
18289dcfe8c1SAlbert Zhang     }
18299dcfe8c1SAlbert Zhang 
18309dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18319dcfe8c1SAlbert Zhang     {
18329dcfe8c1SAlbert Zhang         return false;
18339dcfe8c1SAlbert Zhang     }
18349dcfe8c1SAlbert Zhang 
18359dcfe8c1SAlbert Zhang     return std::nullopt;
18369dcfe8c1SAlbert Zhang }
18379dcfe8c1SAlbert Zhang 
18389dcfe8c1SAlbert Zhang /**
18399dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18409dcfe8c1SAlbert Zhang  *
1841fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18429dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18439dcfe8c1SAlbert Zhang  *
18449dcfe8c1SAlbert Zhang  * @return None.
18459dcfe8c1SAlbert Zhang  */
1846fc3edfddSEd Tanous inline void
1847fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18489dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18499dcfe8c1SAlbert Zhang {
185062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18519dcfe8c1SAlbert Zhang 
18529dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18539dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18549dcfe8c1SAlbert Zhang     {
185562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
185662598e31SEd Tanous                          stopBootOnFault);
1857fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18589dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18599dcfe8c1SAlbert Zhang         return;
18609dcfe8c1SAlbert Zhang     }
18619dcfe8c1SAlbert Zhang 
1862e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1863e93abac6SGinu George                     "xyz.openbmc_project.Settings",
186487c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
186587c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1866fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1867e93abac6SGinu George                     *stopBootEnabled);
18689dcfe8c1SAlbert Zhang }
18699dcfe8c1SAlbert Zhang 
18709dcfe8c1SAlbert Zhang /**
187169f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
187269f35306SGunnar Mills  *
1873ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
187469f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
187569f35306SGunnar Mills  *
187669f35306SGunnar Mills  * @return None.
187769f35306SGunnar Mills  */
1878ac106bf6SEd Tanous inline void
1879ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1880f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
188169f35306SGunnar Mills {
188262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
188369f35306SGunnar Mills 
188469f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1885543f4400SEd Tanous     bool autoRebootEnabled = false;
188669f35306SGunnar Mills 
188769f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
188869f35306SGunnar Mills     {
188969f35306SGunnar Mills         autoRebootEnabled = false;
189069f35306SGunnar Mills     }
189169f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
189269f35306SGunnar Mills     {
189369f35306SGunnar Mills         autoRebootEnabled = true;
189469f35306SGunnar Mills     }
189569f35306SGunnar Mills     else
189669f35306SGunnar Mills     {
189762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
189862598e31SEd Tanous                          automaticRetryConfig);
1899ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
190069f35306SGunnar Mills                                          "AutomaticRetryConfig");
190169f35306SGunnar Mills         return;
190269f35306SGunnar Mills     }
190369f35306SGunnar Mills 
1904e93abac6SGinu George     setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1905e93abac6SGinu George                     "xyz.openbmc_project.Settings",
190687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
190787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/auto_reboot"),
190887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
1909e93abac6SGinu George                     "AutoReboot", autoRebootEnabled);
191069f35306SGunnar Mills }
191169f35306SGunnar Mills 
19128d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19138d69c668SEd Tanous {
19148d69c668SEd Tanous     if (policy == "AlwaysOn")
19158d69c668SEd Tanous     {
19168d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19178d69c668SEd Tanous     }
19188d69c668SEd Tanous     if (policy == "AlwaysOff")
19198d69c668SEd Tanous     {
19208d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19218d69c668SEd Tanous     }
19228d69c668SEd Tanous     if (policy == "LastState")
19238d69c668SEd Tanous     {
19248d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19258d69c668SEd Tanous     }
19268d69c668SEd Tanous     return "";
19278d69c668SEd Tanous }
19288d69c668SEd Tanous 
192969f35306SGunnar Mills /**
1930c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1931c6a620f2SGeorge Liu  *
1932ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1933c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1934c6a620f2SGeorge Liu  *
1935c6a620f2SGeorge Liu  * @return None.
1936c6a620f2SGeorge Liu  */
19378d1b46d7Szhanghch05 inline void
1938ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19398d69c668SEd Tanous                           std::string_view policy)
1940c6a620f2SGeorge Liu {
194162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1942c6a620f2SGeorge Liu 
19438d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1944c6a620f2SGeorge Liu 
19458d69c668SEd Tanous     if (powerRestorePolicy.empty())
1946c6a620f2SGeorge Liu     {
1947ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19484e69c904SGunnar Mills                                          "PowerRestorePolicy");
1949c6a620f2SGeorge Liu         return;
1950c6a620f2SGeorge Liu     }
1951c6a620f2SGeorge Liu 
195287c44966SAsmitha Karunanithi     setDbusProperty(
1953e93abac6SGinu George         asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
195487c44966SAsmitha Karunanithi         sdbusplus::message::object_path(
195587c44966SAsmitha Karunanithi             "/xyz/openbmc_project/control/host0/power_restore_policy"),
19569ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1957e93abac6SGinu George         powerRestorePolicy);
1958c6a620f2SGeorge Liu }
1959c6a620f2SGeorge Liu 
1960a6349918SAppaRao Puli /**
1961a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1962a6349918SAppaRao Puli  *
196325b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
196425b54dbaSEd Tanous  * calls.
1965a6349918SAppaRao Puli  *
1966a6349918SAppaRao Puli  * @return None.
1967a6349918SAppaRao Puli  */
196825b54dbaSEd Tanous inline void
196925b54dbaSEd Tanous     getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1970a6349918SAppaRao Puli {
197162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1972bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1973bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1974bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1975ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1976b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1977b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1978ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1979ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
19801d834d49SEd Tanous             "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
19811d834d49SEd Tanous         oemPFR["@odata.type"] = "#OpenBMCComputerSystem.FirmwareProvisioning";
198250626f4fSJames Feist 
1983a6349918SAppaRao Puli         if (ec)
1984a6349918SAppaRao Puli         {
198562598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1986b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1987*539d8c6bSEd Tanous             oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
1988*539d8c6bSEd Tanous                 FirmwareProvisioningStatus::NotProvisioned;
1989a6349918SAppaRao Puli             return;
1990a6349918SAppaRao Puli         }
1991a6349918SAppaRao Puli 
1992a6349918SAppaRao Puli         const bool* provState = nullptr;
1993a6349918SAppaRao Puli         const bool* lockState = nullptr;
1994bc1d29deSKrzysztof Grobelny 
1995bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19960d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19970d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1998bc1d29deSKrzysztof Grobelny 
1999bc1d29deSKrzysztof Grobelny         if (!success)
2000a6349918SAppaRao Puli         {
2001ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2002bc1d29deSKrzysztof Grobelny             return;
2003a6349918SAppaRao Puli         }
2004a6349918SAppaRao Puli 
2005a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2006a6349918SAppaRao Puli         {
200762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2008ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2009a6349918SAppaRao Puli             return;
2010a6349918SAppaRao Puli         }
2011a6349918SAppaRao Puli 
201225b54dbaSEd Tanous         if (*provState)
2013a6349918SAppaRao Puli         {
201425b54dbaSEd Tanous             if (*lockState)
2015a6349918SAppaRao Puli             {
2016*539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2017*539d8c6bSEd Tanous                     FirmwareProvisioningStatus::ProvisionedAndLocked;
2018a6349918SAppaRao Puli             }
2019a6349918SAppaRao Puli             else
2020a6349918SAppaRao Puli             {
2021*539d8c6bSEd Tanous                 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2022*539d8c6bSEd Tanous                     FirmwareProvisioningStatus::ProvisionedButNotLocked;
2023a6349918SAppaRao Puli             }
2024a6349918SAppaRao Puli         }
2025a6349918SAppaRao Puli         else
2026a6349918SAppaRao Puli         {
2027*539d8c6bSEd Tanous             oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2028*539d8c6bSEd Tanous                 FirmwareProvisioningStatus::NotProvisioned;
2029a6349918SAppaRao Puli         }
2030bc1d29deSKrzysztof Grobelny     });
2031a6349918SAppaRao Puli }
2032a6349918SAppaRao Puli 
2033491d8ee7SSantosh Puranik /**
20346b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20353a2d0424SChris Cain  *
20366b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20373a2d0424SChris Cain  *
20386b9ac4f2SChris Cain  * @return PowerMode enum
20393a2d0424SChris Cain  */
20406b9ac4f2SChris Cain inline computer_system::PowerMode
20416b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
20423a2d0424SChris Cain {
2043b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2044b6655101SChris Cain 
20456b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20463a2d0424SChris Cain     {
20476b9ac4f2SChris Cain         return PowerMode::Static;
20483a2d0424SChris Cain     }
20496b9ac4f2SChris Cain     if (modeString ==
20500fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20513a2d0424SChris Cain     {
20526b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20533a2d0424SChris Cain     }
20546b9ac4f2SChris Cain     if (modeString ==
20550fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20563a2d0424SChris Cain     {
20576b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2058b6655101SChris Cain     }
20596b9ac4f2SChris Cain     if (modeString ==
2060b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2061b6655101SChris Cain     {
20626b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2063b6655101SChris Cain     }
20646b9ac4f2SChris Cain     if (modeString ==
2065b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2066b6655101SChris Cain     {
20676b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2068b6655101SChris Cain     }
20696b9ac4f2SChris Cain     if (modeString ==
2070b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2071b6655101SChris Cain     {
20726b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20733a2d0424SChris Cain     }
20746b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20753a2d0424SChris Cain     {
20766b9ac4f2SChris Cain         return PowerMode::OEM;
20776b9ac4f2SChris Cain     }
20786b9ac4f2SChris Cain     // Any other values would be invalid
20796b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20806b9ac4f2SChris Cain     return PowerMode::Invalid;
20816b9ac4f2SChris Cain }
20826b9ac4f2SChris Cain 
20836b9ac4f2SChris Cain inline void
20846b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20856b9ac4f2SChris Cain                       const boost::system::error_code& ec,
20866b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
20876b9ac4f2SChris Cain {
20886b9ac4f2SChris Cain     if (ec)
20896b9ac4f2SChris Cain     {
20906b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
20916b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20926b9ac4f2SChris Cain         return;
20936b9ac4f2SChris Cain     }
20946b9ac4f2SChris Cain 
20956b9ac4f2SChris Cain     std::string powerMode;
20966b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
20976b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
20986b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
20996b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21006b9ac4f2SChris Cain 
21016b9ac4f2SChris Cain     if (!success)
21026b9ac4f2SChris Cain     {
21036b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21046b9ac4f2SChris Cain         return;
21056b9ac4f2SChris Cain     }
21066b9ac4f2SChris Cain 
21076b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21086b9ac4f2SChris Cain     if (allowedModes == nullptr)
21096b9ac4f2SChris Cain     {
21106b9ac4f2SChris Cain         modeList.emplace_back("Static");
21116b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21126b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21133a2d0424SChris Cain     }
21143a2d0424SChris Cain     else
21153a2d0424SChris Cain     {
21166b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21176b9ac4f2SChris Cain         {
21186b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21196b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21206b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21216b9ac4f2SChris Cain             {
2122ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21236b9ac4f2SChris Cain                 continue;
21246b9ac4f2SChris Cain             }
21256b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21263a2d0424SChris Cain         }
21273a2d0424SChris Cain     }
21286b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21293a2d0424SChris Cain 
21306b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21316b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21326b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21336b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21346b9ac4f2SChris Cain     {
21356b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21366b9ac4f2SChris Cain         return;
21376b9ac4f2SChris Cain     }
21386b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21396b9ac4f2SChris Cain }
21403a2d0424SChris Cain /**
21413a2d0424SChris Cain  * @brief Retrieves system power mode
21423a2d0424SChris Cain  *
2143ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21443a2d0424SChris Cain  *
21453a2d0424SChris Cain  * @return None.
21463a2d0424SChris Cain  */
2147ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21483a2d0424SChris Cain {
214962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21503a2d0424SChris Cain 
21513a2d0424SChris Cain     // Get Power Mode object path:
2152e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2153e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2154e99073f5SGeorge Liu     dbus::utility::getSubTree(
2155e99073f5SGeorge Liu         "/", 0, interfaces,
2156ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2157b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21583a2d0424SChris Cain         if (ec)
21593a2d0424SChris Cain         {
216062598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
216162598e31SEd Tanous                              ec);
21623a2d0424SChris Cain             // This is an optional D-Bus object so just return if
21633a2d0424SChris Cain             // error occurs
21643a2d0424SChris Cain             return;
21653a2d0424SChris Cain         }
21663a2d0424SChris Cain         if (subtree.empty())
21673a2d0424SChris Cain         {
21683a2d0424SChris Cain             // As noted above, this is an optional interface so just return
21693a2d0424SChris Cain             // if there is no instance found
21703a2d0424SChris Cain             return;
21713a2d0424SChris Cain         }
21723a2d0424SChris Cain         if (subtree.size() > 1)
21733a2d0424SChris Cain         {
21743a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21753a2d0424SChris Cain             // error
217662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
217762598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
217862598e31SEd Tanous                 subtree.size());
2179ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21803a2d0424SChris Cain             return;
21813a2d0424SChris Cain         }
21823a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21833a2d0424SChris Cain         {
218462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2185ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21863a2d0424SChris Cain             return;
21873a2d0424SChris Cain         }
21883a2d0424SChris Cain         const std::string& path = subtree[0].first;
21893a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21903a2d0424SChris Cain         if (service.empty())
21913a2d0424SChris Cain         {
219262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2193ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21943a2d0424SChris Cain             return;
21953a2d0424SChris Cain         }
21966b9ac4f2SChris Cain 
21976b9ac4f2SChris Cain         // Valid Power Mode object found, now read the mode properties
21986b9ac4f2SChris Cain         sdbusplus::asio::getAllProperties(
21991e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22006b9ac4f2SChris Cain             "xyz.openbmc_project.Control.Power.Mode",
2201ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22026b9ac4f2SChris Cain                         const dbus::utility::DBusPropertiesMap& properties) {
22036b9ac4f2SChris Cain             afterGetPowerMode(asyncResp, ec2, properties);
22041e1e598dSJonathan Doman         });
2205e99073f5SGeorge Liu     });
22063a2d0424SChris Cain }
22073a2d0424SChris Cain 
22083a2d0424SChris Cain /**
22093a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22103a2d0424SChris Cain  * name associated with that string
22113a2d0424SChris Cain  *
2212ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2213b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22143a2d0424SChris Cain  *
22153a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22163a2d0424SChris Cain  */
22173a2d0424SChris Cain inline std::string
2218ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2219b6655101SChris Cain                       const nlohmann::json& modeValue)
22203a2d0424SChris Cain {
2221b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22223a2d0424SChris Cain     std::string mode;
22233a2d0424SChris Cain 
2224b6655101SChris Cain     if (modeValue == PowerMode::Static)
22253a2d0424SChris Cain     {
22263a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22273a2d0424SChris Cain     }
2228b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22293a2d0424SChris Cain     {
22300fda0f12SGeorge Liu         mode =
22310fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22323a2d0424SChris Cain     }
2233b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22343a2d0424SChris Cain     {
22353a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22363a2d0424SChris Cain     }
2237b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2238b6655101SChris Cain     {
2239b6655101SChris Cain         mode =
2240b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2241b6655101SChris Cain     }
2242b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2243b6655101SChris Cain     {
2244b6655101SChris Cain         mode =
2245b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2246b6655101SChris Cain     }
2247b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2248b6655101SChris Cain     {
2249b6655101SChris Cain         mode =
2250b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2251b6655101SChris Cain     }
22523a2d0424SChris Cain     else
22533a2d0424SChris Cain     {
2254b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2255ac106bf6SEd Tanous                                          "PowerMode");
22563a2d0424SChris Cain     }
22573a2d0424SChris Cain     return mode;
22583a2d0424SChris Cain }
22593a2d0424SChris Cain 
22603a2d0424SChris Cain /**
22613a2d0424SChris Cain  * @brief Sets system power mode.
22623a2d0424SChris Cain  *
2263ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22643a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22653a2d0424SChris Cain  *
22663a2d0424SChris Cain  * @return None.
22673a2d0424SChris Cain  */
2268ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22693a2d0424SChris Cain                          const std::string& pmode)
22703a2d0424SChris Cain {
227162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22723a2d0424SChris Cain 
2273ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22743a2d0424SChris Cain     if (powerMode.empty())
22753a2d0424SChris Cain     {
22763a2d0424SChris Cain         return;
22773a2d0424SChris Cain     }
22783a2d0424SChris Cain 
22793a2d0424SChris Cain     // Get Power Mode object path:
2280e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2281e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2282e99073f5SGeorge Liu     dbus::utility::getSubTree(
2283e99073f5SGeorge Liu         "/", 0, interfaces,
2284ac106bf6SEd Tanous         [asyncResp,
2285e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2286b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22873a2d0424SChris Cain         if (ec)
22883a2d0424SChris Cain         {
2289b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
229062598e31SEd Tanous                              ec);
22913a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2292ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22933a2d0424SChris Cain             return;
22943a2d0424SChris Cain         }
22953a2d0424SChris Cain         if (subtree.empty())
22963a2d0424SChris Cain         {
22973a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2298ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22993a2d0424SChris Cain                                        "PowerMode");
23003a2d0424SChris Cain             return;
23013a2d0424SChris Cain         }
23023a2d0424SChris Cain         if (subtree.size() > 1)
23033a2d0424SChris Cain         {
23043a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23053a2d0424SChris Cain             // error
230662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
230762598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
230862598e31SEd Tanous                 subtree.size());
2309ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23103a2d0424SChris Cain             return;
23113a2d0424SChris Cain         }
23123a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23133a2d0424SChris Cain         {
231462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2315ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23163a2d0424SChris Cain             return;
23173a2d0424SChris Cain         }
23183a2d0424SChris Cain         const std::string& path = subtree[0].first;
23193a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23203a2d0424SChris Cain         if (service.empty())
23213a2d0424SChris Cain         {
232262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2323ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23243a2d0424SChris Cain             return;
23253a2d0424SChris Cain         }
23263a2d0424SChris Cain 
232762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23283a2d0424SChris Cain 
23293a2d0424SChris Cain         // Set the Power Mode property
2330e93abac6SGinu George         setDbusProperty(asyncResp, "PowerMode", service, path,
233187c44966SAsmitha Karunanithi                         "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2332e93abac6SGinu George                         powerMode);
2333e99073f5SGeorge Liu     });
23343a2d0424SChris Cain }
23353a2d0424SChris Cain 
23363a2d0424SChris Cain /**
233751709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
233851709ffdSYong Li  *
233951709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
234051709ffdSYong Li  *
234151709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
234251709ffdSYong Li  * translation cannot be done, returns an empty string.
234351709ffdSYong Li  */
234423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
234551709ffdSYong Li {
234651709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
234751709ffdSYong Li     {
234851709ffdSYong Li         return "None";
234951709ffdSYong Li     }
23503174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
235151709ffdSYong Li     {
235251709ffdSYong Li         return "ResetSystem";
235351709ffdSYong Li     }
23543174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
235551709ffdSYong Li     {
235651709ffdSYong Li         return "PowerDown";
235751709ffdSYong Li     }
23583174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
235951709ffdSYong Li     {
236051709ffdSYong Li         return "PowerCycle";
236151709ffdSYong Li     }
236251709ffdSYong Li 
236351709ffdSYong Li     return "";
236451709ffdSYong Li }
236551709ffdSYong Li 
236651709ffdSYong Li /**
2367c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2368c45f0082SYong Li  *
2369c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2370c45f0082SYong Li  *
2371c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2372c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2373c45f0082SYong Li  */
2374c45f0082SYong Li 
237523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2376c45f0082SYong Li {
2377c45f0082SYong Li     if (rfAction == "None")
2378c45f0082SYong Li     {
2379c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2380c45f0082SYong Li     }
23813174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2382c45f0082SYong Li     {
2383c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2384c45f0082SYong Li     }
23853174e4dfSEd Tanous     if (rfAction == "PowerDown")
2386c45f0082SYong Li     {
2387c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2388c45f0082SYong Li     }
23893174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2390c45f0082SYong Li     {
2391c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2392c45f0082SYong Li     }
2393c45f0082SYong Li 
2394c45f0082SYong Li     return "";
2395c45f0082SYong Li }
2396c45f0082SYong Li 
2397c45f0082SYong Li /**
239851709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
239951709ffdSYong Li  *
2400ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
240151709ffdSYong Li  *
240251709ffdSYong Li  * @return None.
240351709ffdSYong Li  */
24048d1b46d7Szhanghch05 inline void
2405ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
240651709ffdSYong Li {
240762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2408bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2409bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2410bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2411bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2412ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2413b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
241451709ffdSYong Li         if (ec)
241551709ffdSYong Li         {
241651709ffdSYong Li             // watchdog service is stopped
241762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
241851709ffdSYong Li             return;
241951709ffdSYong Li         }
242051709ffdSYong Li 
242162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
242251709ffdSYong Li 
242351709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2424ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
242551709ffdSYong Li 
242651709ffdSYong Li         // watchdog service is running/enabled
2427*539d8c6bSEd Tanous         hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
242851709ffdSYong Li 
2429bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2430bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
243151709ffdSYong Li 
2432bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2433bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2434bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2435bc1d29deSKrzysztof Grobelny 
2436bc1d29deSKrzysztof Grobelny         if (!success)
243751709ffdSYong Li         {
2438ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2439601af5edSChicago Duan             return;
244051709ffdSYong Li         }
244151709ffdSYong Li 
2442bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
244351709ffdSYong Li         {
2444bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
244551709ffdSYong Li         }
244651709ffdSYong Li 
2447bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2448bc1d29deSKrzysztof Grobelny         {
2449bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
245051709ffdSYong Li             if (action.empty())
245151709ffdSYong Li             {
2452ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2453601af5edSChicago Duan                 return;
245451709ffdSYong Li             }
245551709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
245651709ffdSYong Li         }
2457bc1d29deSKrzysztof Grobelny     });
245851709ffdSYong Li }
245951709ffdSYong Li 
246051709ffdSYong Li /**
2461c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2462c45f0082SYong Li  *
2463ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2464c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2465c45f0082SYong Li  *                       RF request.
2466c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2467c45f0082SYong Li  *
2468c45f0082SYong Li  * @return None.
2469c45f0082SYong Li  */
2470ac106bf6SEd Tanous inline void
2471ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2472c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2473c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2474c45f0082SYong Li {
247562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2476c45f0082SYong Li 
2477c45f0082SYong Li     if (wdtTimeOutAction)
2478c45f0082SYong Li     {
2479c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2480c45f0082SYong Li         // check if TimeOut Action is Valid
2481c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2482c45f0082SYong Li         {
248362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
248462598e31SEd Tanous                              *wdtTimeOutAction);
2485ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2486c45f0082SYong Li                                              "TimeoutAction");
2487c45f0082SYong Li             return;
2488c45f0082SYong Li         }
2489c45f0082SYong Li 
2490e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2491e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
249287c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
249387c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
24949ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2495e93abac6SGinu George                         wdtTimeOutActStr);
2496c45f0082SYong Li     }
2497c45f0082SYong Li 
2498c45f0082SYong Li     if (wdtEnable)
2499c45f0082SYong Li     {
2500e93abac6SGinu George         setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2501e93abac6SGinu George                         "xyz.openbmc_project.Watchdog",
250287c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
250387c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
250487c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
2505e93abac6SGinu George                         *wdtEnable);
2506c45f0082SYong Li     }
2507c45f0082SYong Li }
2508c45f0082SYong Li 
250937bbf98cSChris Cain /**
251037bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
251137bbf98cSChris Cain  *
2512ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
251337bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
251437bbf98cSChris Cain  *
251537bbf98cSChris Cain  * @return true if successful
251637bbf98cSChris Cain  */
25171e5b7c88SJiaqing Zhao inline bool
2518ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25191e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
252037bbf98cSChris Cain {
2521bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2522bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2523bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2524bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2525bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2526bc1d29deSKrzysztof Grobelny 
2527bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2528bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25292661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25302661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25312661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2532bc1d29deSKrzysztof Grobelny 
2533bc1d29deSKrzysztof Grobelny     if (!success)
253437bbf98cSChris Cain     {
253537bbf98cSChris Cain         return false;
253637bbf98cSChris Cain     }
2537bc1d29deSKrzysztof Grobelny 
2538bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
253937bbf98cSChris Cain     {
2540ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
254137bbf98cSChris Cain     }
2542bc1d29deSKrzysztof Grobelny 
2543bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
254437bbf98cSChris Cain     {
2545ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2546bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
254737bbf98cSChris Cain     }
2548bc1d29deSKrzysztof Grobelny 
2549bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2550bc1d29deSKrzysztof Grobelny     {
2551bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2552ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
255337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
255437bbf98cSChris Cain                 .count();
255537bbf98cSChris Cain     }
2556bc1d29deSKrzysztof Grobelny 
2557bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
255837bbf98cSChris Cain     {
2559ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2560bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
256137bbf98cSChris Cain     }
2562bc1d29deSKrzysztof Grobelny 
2563bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
256437bbf98cSChris Cain     {
2565bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2566ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
256737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
256837bbf98cSChris Cain                 .count();
256937bbf98cSChris Cain     }
257037bbf98cSChris Cain 
257137bbf98cSChris Cain     return true;
257237bbf98cSChris Cain }
257337bbf98cSChris Cain 
257437bbf98cSChris Cain /**
257537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
257637bbf98cSChris Cain  *
2577ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
257837bbf98cSChris Cain  *
257937bbf98cSChris Cain  * @return None.
258037bbf98cSChris Cain  */
2581ac106bf6SEd Tanous inline void
2582ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
258337bbf98cSChris Cain {
258462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
258537bbf98cSChris Cain 
258637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2587e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2588e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2589e99073f5SGeorge Liu     dbus::utility::getSubTree(
2590e99073f5SGeorge Liu         "/", 0, interfaces,
2591ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2592b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
259337bbf98cSChris Cain         if (ec)
259437bbf98cSChris Cain         {
2595b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
259662598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
259762598e31SEd Tanous                 ec);
2598ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
259937bbf98cSChris Cain             return;
260037bbf98cSChris Cain         }
260137bbf98cSChris Cain         if (subtree.empty())
260237bbf98cSChris Cain         {
260337bbf98cSChris Cain             // This is an optional interface so just return
260437bbf98cSChris Cain             // if there is no instance found
260562598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
260637bbf98cSChris Cain             return;
260737bbf98cSChris Cain         }
260837bbf98cSChris Cain         if (subtree.size() > 1)
260937bbf98cSChris Cain         {
261037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
261137bbf98cSChris Cain             // is an error
261262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
261362598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
261462598e31SEd Tanous                              subtree.size());
2615ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
261637bbf98cSChris Cain             return;
261737bbf98cSChris Cain         }
261837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
261937bbf98cSChris Cain         {
262062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2621ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
262237bbf98cSChris Cain             return;
262337bbf98cSChris Cain         }
262437bbf98cSChris Cain         const std::string& path = subtree[0].first;
262537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
262637bbf98cSChris Cain         if (service.empty())
262737bbf98cSChris Cain         {
262862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2629ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
263037bbf98cSChris Cain             return;
263137bbf98cSChris Cain         }
263237bbf98cSChris Cain 
263337bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2634bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2635bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2636bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2637ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
26381e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
26398a592810SEd Tanous             if (ec2)
264037bbf98cSChris Cain             {
264162598e31SEd Tanous                 BMCWEB_LOG_ERROR(
264262598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2643ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
264437bbf98cSChris Cain                 return;
264537bbf98cSChris Cain             }
264637bbf98cSChris Cain 
2647ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
264837bbf98cSChris Cain             {
2649ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
265037bbf98cSChris Cain                 return;
265137bbf98cSChris Cain             }
2652bc1d29deSKrzysztof Grobelny         });
2653e99073f5SGeorge Liu     });
265437bbf98cSChris Cain 
265562598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
265637bbf98cSChris Cain }
265737bbf98cSChris Cain 
265837bbf98cSChris Cain /**
265937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
266037bbf98cSChris Cain  *
2661ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
266237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
266337bbf98cSChris Cain  *                       RF request.
266437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
266537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
266637bbf98cSChris Cain  * before entering idle state.
266737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
266837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
266937bbf98cSChris Cain  * before exiting idle state
267037bbf98cSChris Cain  *
267137bbf98cSChris Cain  * @return None.
267237bbf98cSChris Cain  */
2673ac106bf6SEd Tanous inline void
2674ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
267537bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
267637bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
267737bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
267837bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
267937bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
268037bbf98cSChris Cain {
268162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
268237bbf98cSChris Cain 
268337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2684e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2685e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2686e99073f5SGeorge Liu     dbus::utility::getSubTree(
2687e99073f5SGeorge Liu         "/", 0, interfaces,
2688ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2689e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2690b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
269137bbf98cSChris Cain         if (ec)
269237bbf98cSChris Cain         {
2693b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
269462598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
269562598e31SEd Tanous                 ec);
2696ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269737bbf98cSChris Cain             return;
269837bbf98cSChris Cain         }
269937bbf98cSChris Cain         if (subtree.empty())
270037bbf98cSChris Cain         {
270137bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2702ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
270337bbf98cSChris Cain                                        "IdlePowerSaver");
270437bbf98cSChris Cain             return;
270537bbf98cSChris Cain         }
270637bbf98cSChris Cain         if (subtree.size() > 1)
270737bbf98cSChris Cain         {
270837bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
270937bbf98cSChris Cain             // is an error
271062598e31SEd Tanous             BMCWEB_LOG_DEBUG(
271162598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
271262598e31SEd Tanous                 subtree.size());
2713ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
271437bbf98cSChris Cain             return;
271537bbf98cSChris Cain         }
271637bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
271737bbf98cSChris Cain         {
271862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2719ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
272037bbf98cSChris Cain             return;
272137bbf98cSChris Cain         }
272237bbf98cSChris Cain         const std::string& path = subtree[0].first;
272337bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
272437bbf98cSChris Cain         if (service.empty())
272537bbf98cSChris Cain         {
272662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2727ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
272837bbf98cSChris Cain             return;
272937bbf98cSChris Cain         }
273037bbf98cSChris Cain 
273137bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
273237bbf98cSChris Cain         // need to be updated
273337bbf98cSChris Cain 
273437bbf98cSChris Cain         if (ipsEnable)
273537bbf98cSChris Cain         {
2736e93abac6SGinu George             setDbusProperty(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         {
2742e93abac6SGinu George             setDbusProperty(asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2743e93abac6SGinu George                             service, path,
27449ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2745e93abac6SGinu George                             "EnterUtilizationPercent", *ipsEnterUtil);
274637bbf98cSChris Cain         }
274737bbf98cSChris Cain         if (ipsEnterTime)
274837bbf98cSChris Cain         {
274937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
275037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2751e93abac6SGinu George             setDbusProperty(asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds",
2752e93abac6SGinu George                             service, path,
27539ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2754e93abac6SGinu George                             "EnterDwellTime", timeMilliseconds);
275537bbf98cSChris Cain         }
275637bbf98cSChris Cain         if (ipsExitUtil)
275737bbf98cSChris Cain         {
2758e93abac6SGinu George             setDbusProperty(asyncResp, "IdlePowerSaver/ExitUtilizationPercent",
2759e93abac6SGinu George                             service, path,
27609ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2761e93abac6SGinu George                             "ExitUtilizationPercent", *ipsExitUtil);
276237bbf98cSChris Cain         }
276337bbf98cSChris Cain         if (ipsExitTime)
276437bbf98cSChris Cain         {
276537bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
276637bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2767e93abac6SGinu George             setDbusProperty(asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds",
2768e93abac6SGinu George                             service, path,
27699ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2770e93abac6SGinu George                             "ExitDwellTime", timeMilliseconds);
277137bbf98cSChris Cain         }
2772e99073f5SGeorge Liu     });
277337bbf98cSChris Cain 
277462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
277537bbf98cSChris Cain }
277637bbf98cSChris Cain 
2777c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2778dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2779dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2780dd60b9edSEd Tanous {
2781dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2782dd60b9edSEd Tanous     {
2783dd60b9edSEd Tanous         return;
2784dd60b9edSEd Tanous     }
2785dd60b9edSEd Tanous     asyncResp->res.addHeader(
2786dd60b9edSEd Tanous         boost::beast::http::field::link,
2787dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2788dd60b9edSEd Tanous }
2789dd60b9edSEd Tanous 
2790c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2791c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2792c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27931abe55efSEd Tanous {
27943ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2795f4c99e70SEd Tanous     {
2796f4c99e70SEd Tanous         return;
2797f4c99e70SEd Tanous     }
2798dd60b9edSEd Tanous 
2799dd60b9edSEd Tanous     asyncResp->res.addHeader(
2800dd60b9edSEd Tanous         boost::beast::http::field::link,
2801dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28028d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28030f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28048d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28058d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2806462023adSSunitha Harish 
28077f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
28087f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
280925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28107f3e84a1SEd Tanous     {
28117f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
28127f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28137f3e84a1SEd Tanous         return;
28147f3e84a1SEd Tanous     }
28157f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
28167f3e84a1SEd Tanous     nlohmann::json::object_t system;
2817253f11b8SEd Tanous     system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2818253f11b8SEd Tanous                                               BMCWEB_REDFISH_SYSTEM_URI_NAME);
28197f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
28201e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2821002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
28221e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2823002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
28245e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
28251e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
28267f3e84a1SEd Tanous         if (ec2)
2827462023adSSunitha Harish         {
28287f3e84a1SEd Tanous             return;
28297f3e84a1SEd Tanous         }
28307f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
28317f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
28327f3e84a1SEd Tanous         {
283362598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
28347f3e84a1SEd Tanous             return;
28357f3e84a1SEd Tanous         }
283667b15903SAsmitha Karunanithi         int64_t* count = val->get_ptr<int64_t*>();
28377f3e84a1SEd Tanous         if (count == nullptr)
28387f3e84a1SEd Tanous         {
283962598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
28407f3e84a1SEd Tanous             return;
28417f3e84a1SEd Tanous         }
28427f3e84a1SEd Tanous         *count = *count + 1;
284362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
28447f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
28451476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2846002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
28477f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
28481e1e598dSJonathan Doman     });
2849c1e219d5SEd Tanous }
2850c1e219d5SEd Tanous 
2851c1e219d5SEd Tanous /**
28527e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28537e860f15SJohn Edward Broadbent  */
28544f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28557e860f15SJohn Edward Broadbent {
285689492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
285789492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
285889492a15SPatrick Williams     constexpr const char* interfaceName =
28597e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
286089492a15SPatrick Williams     constexpr const char* method = "NMI";
28617e860f15SJohn Edward Broadbent 
28627e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28635e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28647e860f15SJohn Edward Broadbent         if (ec)
28657e860f15SJohn Edward Broadbent         {
286662598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28677e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28687e860f15SJohn Edward Broadbent             return;
28697e860f15SJohn Edward Broadbent         }
28707e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28717e860f15SJohn Edward Broadbent     },
28727e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28737e860f15SJohn Edward Broadbent }
2874c5b2abe0SLewanczyk, Dawid 
2875c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2876c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
28777f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2878c1e219d5SEd Tanous     const std::string& systemName)
2879c1e219d5SEd Tanous {
28803ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
288145ca1b86SEd Tanous     {
288245ca1b86SEd Tanous         return;
288345ca1b86SEd Tanous     }
2884253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2885c1e219d5SEd Tanous     {
2886c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2887c1e219d5SEd Tanous                                    systemName);
2888c1e219d5SEd Tanous         return;
2889c1e219d5SEd Tanous     }
289025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28917f3e84a1SEd Tanous     {
28927f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28937f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2894c1e219d5SEd Tanous                                    systemName);
28957f3e84a1SEd Tanous         return;
28967f3e84a1SEd Tanous     }
28979712f8acSEd Tanous     std::string resetType;
2898c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2899cc340dd9SEd Tanous     {
2900cc340dd9SEd Tanous         return;
2901cc340dd9SEd Tanous     }
2902cc340dd9SEd Tanous 
2903d22c8396SJason M. Bills     // Get the command and host vs. chassis
2904cc340dd9SEd Tanous     std::string command;
2905543f4400SEd Tanous     bool hostCommand = true;
2906d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2907cc340dd9SEd Tanous     {
2908cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2909d22c8396SJason M. Bills         hostCommand = true;
2910d22c8396SJason M. Bills     }
2911d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2912d22c8396SJason M. Bills     {
2913d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2914d22c8396SJason M. Bills         hostCommand = false;
2915d22c8396SJason M. Bills     }
2916d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2917d22c8396SJason M. Bills     {
2918c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
291986a0851aSJason M. Bills         hostCommand = true;
2920cc340dd9SEd Tanous     }
29219712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2922cc340dd9SEd Tanous     {
2923cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2924d22c8396SJason M. Bills         hostCommand = true;
2925cc340dd9SEd Tanous     }
29269712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2927cc340dd9SEd Tanous     {
29280fda0f12SGeorge Liu         command =
29290fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2930d22c8396SJason M. Bills         hostCommand = true;
2931d22c8396SJason M. Bills     }
2932d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2933d22c8396SJason M. Bills     {
293486a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
293586a0851aSJason M. Bills         hostCommand = true;
2936cc340dd9SEd Tanous     }
2937bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2938bfd5b826SLakshminarayana R. Kammath     {
2939bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2940bfd5b826SLakshminarayana R. Kammath         return;
2941bfd5b826SLakshminarayana R. Kammath     }
2942cc340dd9SEd Tanous     else
2943cc340dd9SEd Tanous     {
2944c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2945cc340dd9SEd Tanous         return;
2946cc340dd9SEd Tanous     }
2947d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
2948cc340dd9SEd Tanous 
2949d22c8396SJason M. Bills     if (hostCommand)
2950d22c8396SJason M. Bills     {
2951e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
2952d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
2953e93abac6SGinu George                         "RequestedHostTransition", command);
2954cc340dd9SEd Tanous     }
2955d22c8396SJason M. Bills     else
2956d22c8396SJason M. Bills     {
2957e93abac6SGinu George         setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
2958d02aad39SEd Tanous                         statePath / "chassis0",
2959d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2960e93abac6SGinu George                         "RequestedPowerTransition", command);
2961d22c8396SJason M. Bills     }
2962d22c8396SJason M. Bills }
2963cc340dd9SEd Tanous 
2964c1e219d5SEd Tanous inline void handleComputerSystemHead(
2965dd60b9edSEd Tanous     App& app, const crow::Request& req,
29667f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29677f3e84a1SEd Tanous     const std::string& /*systemName*/)
2968dd60b9edSEd Tanous {
2969dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2970dd60b9edSEd Tanous     {
2971dd60b9edSEd Tanous         return;
2972dd60b9edSEd Tanous     }
2973dd60b9edSEd Tanous 
2974dd60b9edSEd Tanous     asyncResp->res.addHeader(
2975dd60b9edSEd Tanous         boost::beast::http::field::link,
2976dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2977dd60b9edSEd Tanous }
2978dd60b9edSEd Tanous 
29795c3e9272SAbhishek Patel inline void afterPortRequest(
29805c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29815c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29825c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29835c3e9272SAbhishek Patel {
29845c3e9272SAbhishek Patel     if (ec)
29855c3e9272SAbhishek Patel     {
2986b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29875c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29885c3e9272SAbhishek Patel         return;
29895c3e9272SAbhishek Patel     }
29905c3e9272SAbhishek Patel     for (const auto& data : socketData)
29915c3e9272SAbhishek Patel     {
29925c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29935c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29945c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29955c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29965c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29975c3e9272SAbhishek Patel         // need to retrieve port number for
29985c3e9272SAbhishek Patel         // obmc-console-ssh service
29995c3e9272SAbhishek Patel         if (protocolName == "SSH")
30005c3e9272SAbhishek Patel         {
30015c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
300281c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30035c3e9272SAbhishek Patel                                           int portNumber) {
30045c3e9272SAbhishek Patel                 if (ec1)
30055c3e9272SAbhishek Patel                 {
3006b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
30075c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30085c3e9272SAbhishek Patel                     return;
30095c3e9272SAbhishek Patel                 }
30105c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30115c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30125c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30135c3e9272SAbhishek Patel             });
30145c3e9272SAbhishek Patel         }
30155c3e9272SAbhishek Patel     }
30165c3e9272SAbhishek Patel }
3017c1e219d5SEd Tanous 
3018c1e219d5SEd Tanous inline void
3019c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
302022d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3021c1e219d5SEd Tanous                             const std::string& systemName)
3022c1e219d5SEd Tanous {
30233ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
302445ca1b86SEd Tanous     {
302545ca1b86SEd Tanous         return;
302645ca1b86SEd Tanous     }
3027746b56f3SAsmitha Karunanithi 
302825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
30297f3e84a1SEd Tanous     {
30307f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30317f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
30327f3e84a1SEd Tanous                                    systemName);
30337f3e84a1SEd Tanous         return;
30347f3e84a1SEd Tanous     }
30357f3e84a1SEd Tanous 
3036746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3037746b56f3SAsmitha Karunanithi     {
3038746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3039746b56f3SAsmitha Karunanithi         return;
3040746b56f3SAsmitha Karunanithi     }
3041746b56f3SAsmitha Karunanithi 
3042253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
304322d268cbSEd Tanous     {
304422d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
304522d268cbSEd Tanous                                    systemName);
304622d268cbSEd Tanous         return;
304722d268cbSEd Tanous     }
3048dd60b9edSEd Tanous     asyncResp->res.addHeader(
3049dd60b9edSEd Tanous         boost::beast::http::field::link,
3050dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30518d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3052b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
3053253f11b8SEd Tanous     asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3054253f11b8SEd Tanous     asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3055*539d8c6bSEd Tanous     asyncResp->res.jsonValue["SystemType"] =
3056*539d8c6bSEd Tanous         computer_system::SystemType::Physical;
30578d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30588d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3059cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3060dfb2b408SPriyanga Ramasamy         double(0);
3061253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3062253f11b8SEd Tanous         "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
306304a258f4SEd Tanous 
3064253f11b8SEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3065253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3066253f11b8SEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3067253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3068253f11b8SEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3069253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
30703179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3071253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3072253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3073029573d4SEd Tanous 
3074002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3075253f11b8SEd Tanous         boost::urls::format(
3076253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3077253f11b8SEd Tanous             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3078c1e219d5SEd Tanous     asyncResp->res
3079c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3080253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3081253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3082c5b2abe0SLewanczyk, Dawid 
3083253f11b8SEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3084253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3085253f11b8SEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3086253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3087c4bf6374SJason M. Bills 
30881476687dSEd Tanous     nlohmann::json::array_t managedBy;
30891476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3090253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3091253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3092002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3093*539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3094*539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
30950e8ac5e7SGunnar Mills 
30960e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3097002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3098c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
30991476687dSEd Tanous 
3100c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
31011476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3102c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31031476687dSEd Tanous         "Press ~. to exit console";
31045c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
31055c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
31060e8ac5e7SGunnar Mills 
310725b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
310825b54dbaSEd Tanous     {
31090e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3110002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
311125b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
311225b54dbaSEd Tanous             4;
3113613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3114613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
311525b54dbaSEd Tanous     }
311613451e39SWilly Tu 
3117002d39b4SEd Tanous     getMainChassisId(asyncResp,
3118002d39b4SEd Tanous                      [](const std::string& chassisId,
31198d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3120b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3121b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3122ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3123ef4c65b7SEd Tanous                                                    chassisId);
3124002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3125c5d03ff4SJennifer Lee     });
3126a3002228SAppaRao Puli 
312759a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
31289f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3129a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
313051bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
31316c34de48SEd Tanous     getHostState(asyncResp);
3132491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3133978b8803SAndrew Geissler     getBootProgress(asyncResp);
3134b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
313570c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
313670c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
313751709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3138c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
31399dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3140797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3141c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
314225b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
314325b54dbaSEd Tanous     {
3144a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
314525b54dbaSEd Tanous     }
31461981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
31473a2d0424SChris Cain     getPowerMode(asyncResp);
314837bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3149c1e219d5SEd Tanous }
3150550a6bf8SJiaqing Zhao 
3151c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3152c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
315322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3154c1e219d5SEd Tanous     const std::string& systemName)
3155c1e219d5SEd Tanous {
31563ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
315745ca1b86SEd Tanous     {
315845ca1b86SEd Tanous         return;
315945ca1b86SEd Tanous     }
316025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31617f3e84a1SEd Tanous     {
31627f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31637f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31647f3e84a1SEd Tanous                                    systemName);
31657f3e84a1SEd Tanous         return;
31667f3e84a1SEd Tanous     }
3167253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
316822d268cbSEd Tanous     {
316922d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
317022d268cbSEd Tanous                                    systemName);
317122d268cbSEd Tanous         return;
317222d268cbSEd Tanous     }
317322d268cbSEd Tanous 
3174dd60b9edSEd Tanous     asyncResp->res.addHeader(
3175dd60b9edSEd Tanous         boost::beast::http::field::link,
3176dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3177dd60b9edSEd Tanous 
31789f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3179cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
318098e386ecSGunnar Mills     std::optional<std::string> assetTag;
3181c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
31823a2d0424SChris Cain     std::optional<std::string> powerMode;
3183550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3184550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3185550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3186550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3187550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3188550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3189797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3190550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
31919dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3192550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3193550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3194550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3195550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3196550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3197550a6bf8SJiaqing Zhao 
3198550a6bf8SJiaqing Zhao     // clang-format off
319915ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3200550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3201550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
32027e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3203550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3204550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3205550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3206550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3207550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3208550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3209550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3210550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3211550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3212797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3213550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
32149dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3215550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3216550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3217550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3218550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3219550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
32206617338dSEd Tanous                 {
32216617338dSEd Tanous                     return;
32226617338dSEd Tanous                 }
3223550a6bf8SJiaqing Zhao     // clang-format on
3224491d8ee7SSantosh Puranik 
32258d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3226c45f0082SYong Li 
322798e386ecSGunnar Mills     if (assetTag)
322898e386ecSGunnar Mills     {
322998e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
323098e386ecSGunnar Mills     }
323198e386ecSGunnar Mills 
3232550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3233c45f0082SYong Li     {
3234f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3235c45f0082SYong Li     }
3236c45f0082SYong Li 
3237cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
323869f35306SGunnar Mills     {
3239002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3240491d8ee7SSantosh Puranik     }
3241550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
324269f35306SGunnar Mills     {
3243550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
324469f35306SGunnar Mills     }
3245ac7e1e0bSAli Ahmed 
3246797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3247797d5daeSCorey Hardesty     {
3248797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3249797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3250797d5daeSCorey Hardesty     }
3251797d5daeSCorey Hardesty 
3252550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3253ac7e1e0bSAli Ahmed     {
3254c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
325569f35306SGunnar Mills     }
3256265c1602SJohnathan Mantey 
32579dcfe8c1SAlbert Zhang     if (stopBootOnFault)
32589dcfe8c1SAlbert Zhang     {
32599dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
32609dcfe8c1SAlbert Zhang     }
32619dcfe8c1SAlbert Zhang 
32629f8bfa7cSGunnar Mills     if (locationIndicatorActive)
32639f8bfa7cSGunnar Mills     {
326459a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32659f8bfa7cSGunnar Mills     }
32669f8bfa7cSGunnar Mills 
32677e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
32687e860f15SJohn Edward Broadbent     // passed
32699712f8acSEd Tanous     if (indicatorLed)
32706617338dSEd Tanous     {
3271f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3272002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3273d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3274d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
32756617338dSEd Tanous     }
3276c6a620f2SGeorge Liu 
3277c6a620f2SGeorge Liu     if (powerRestorePolicy)
3278c6a620f2SGeorge Liu     {
32794e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3280c6a620f2SGeorge Liu     }
32813a2d0424SChris Cain 
32823a2d0424SChris Cain     if (powerMode)
32833a2d0424SChris Cain     {
32843a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
32853a2d0424SChris Cain     }
328637bbf98cSChris Cain 
3287c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
328837bbf98cSChris Cain     {
3289002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3290002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
329137bbf98cSChris Cain     }
3292c1e219d5SEd Tanous }
32931cb1a9e6SAppaRao Puli 
329438c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3295dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
32967f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3297c1e219d5SEd Tanous     const std::string& /*systemName*/)
3298dd60b9edSEd Tanous {
3299dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3300dd60b9edSEd Tanous     {
3301dd60b9edSEd Tanous         return;
3302dd60b9edSEd Tanous     }
3303dd60b9edSEd Tanous     asyncResp->res.addHeader(
3304dd60b9edSEd Tanous         boost::beast::http::field::link,
3305dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3306dd60b9edSEd Tanous }
330733e1f122SAndrew Geissler 
330833e1f122SAndrew Geissler /**
330933e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
331033e1f122SAndrew Geissler  *
331133e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
331233e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
331333e1f122SAndrew Geissler  *
3314efff2b5dSManojkiran Eda  * @return Emplaces corresponding Redfish translated value(s) in
331533e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
331633e1f122SAndrew Geissler  * allowableValues.
331733e1f122SAndrew Geissler  */
331833e1f122SAndrew Geissler inline void
331933e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
332033e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
332133e1f122SAndrew Geissler {
332233e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
332333e1f122SAndrew Geissler     {
332433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
332533e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
332633e1f122SAndrew Geissler     }
332733e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
332833e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
332933e1f122SAndrew Geissler     {
333033e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
333133e1f122SAndrew Geissler     }
333233e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
333333e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
333433e1f122SAndrew Geissler     {
333533e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
333633e1f122SAndrew Geissler     }
333733e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
333833e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
333933e1f122SAndrew Geissler     {
334033e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
334133e1f122SAndrew Geissler     }
334233e1f122SAndrew Geissler     else
334333e1f122SAndrew Geissler     {
334433e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
334533e1f122SAndrew Geissler     }
334633e1f122SAndrew Geissler }
334733e1f122SAndrew Geissler 
334833e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
334933e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
335033e1f122SAndrew Geissler     const boost::system::error_code& ec,
335133e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
335233e1f122SAndrew Geissler {
335333e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
335433e1f122SAndrew Geissler 
335533e1f122SAndrew Geissler     // Supported on all systems currently
335633e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
335733e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
335833e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
335933e1f122SAndrew Geissler 
336033e1f122SAndrew Geissler     if (ec)
336133e1f122SAndrew Geissler     {
3362e715d14bSEd Tanous         if ((ec.value() ==
3363e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3364e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
336533e1f122SAndrew Geissler         {
336633e1f122SAndrew Geissler             // Property not implemented so just return defaults
336733e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
336833e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
336933e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
337033e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
337133e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
337233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
337333e1f122SAndrew Geissler         }
337433e1f122SAndrew Geissler         else
337533e1f122SAndrew Geissler         {
337633e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
337733e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
337833e1f122SAndrew Geissler             return;
337933e1f122SAndrew Geissler         }
338033e1f122SAndrew Geissler     }
338133e1f122SAndrew Geissler     else
338233e1f122SAndrew Geissler     {
338333e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
338433e1f122SAndrew Geissler         {
338533e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
338633e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
338733e1f122SAndrew Geissler         }
338833e1f122SAndrew Geissler     }
338933e1f122SAndrew Geissler 
339033e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
339133e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
339233e1f122SAndrew Geissler     parameter["Required"] = true;
3393*539d8c6bSEd Tanous     parameter["DataType"] = action_info::ParameterTypes::String;
339433e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
339533e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
339633e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
339733e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
339833e1f122SAndrew Geissler }
339933e1f122SAndrew Geissler 
3400c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3401c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
340222d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3403c1e219d5SEd Tanous     const std::string& systemName)
3404c1e219d5SEd Tanous {
34053ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
340645ca1b86SEd Tanous     {
340745ca1b86SEd Tanous         return;
340845ca1b86SEd Tanous     }
340925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
34107f3e84a1SEd Tanous     {
34117f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34127f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34137f3e84a1SEd Tanous                                    systemName);
34147f3e84a1SEd Tanous         return;
34157f3e84a1SEd Tanous     }
3416746b56f3SAsmitha Karunanithi 
3417746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3418746b56f3SAsmitha Karunanithi     {
3419746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3420746b56f3SAsmitha Karunanithi         return;
3421746b56f3SAsmitha Karunanithi     }
3422746b56f3SAsmitha Karunanithi 
3423253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
342422d268cbSEd Tanous     {
342522d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
342622d268cbSEd Tanous                                    systemName);
342722d268cbSEd Tanous         return;
342822d268cbSEd Tanous     }
342922d268cbSEd Tanous 
3430dd60b9edSEd Tanous     asyncResp->res.addHeader(
3431dd60b9edSEd Tanous         boost::beast::http::field::link,
3432dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34331476687dSEd Tanous 
34341476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
3435253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3436253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3437c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34381476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34391476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34403215e700SNan Zhou 
344133e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
344233e1f122SAndrew Geissler     sdbusplus::asio::getProperty<std::vector<std::string>>(
344333e1f122SAndrew Geissler         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
344433e1f122SAndrew Geissler         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
344533e1f122SAndrew Geissler         "AllowedHostTransitions",
344633e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
344733e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
344833e1f122SAndrew Geissler         afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
344933e1f122SAndrew Geissler     });
3450c1e219d5SEd Tanous }
3451c1e219d5SEd Tanous /**
3452c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3453c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3454c1e219d5SEd Tanous  */
3455100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3456c1e219d5SEd Tanous {
3457100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3458100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3459100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3460100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3461100afe56SEd Tanous 
3462100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3463100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3464100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3465100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3466100afe56SEd Tanous 
3467100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3468100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3469100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3470100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3471100afe56SEd Tanous 
3472100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3473100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3474100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3475100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3476100afe56SEd Tanous 
3477100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3478100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3479100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3480100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3481100afe56SEd Tanous 
3482100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3483100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3484100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3485100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3486100afe56SEd Tanous 
3487c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3488c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3489c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3490c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3491c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3492c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3493c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3494c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
34951cb1a9e6SAppaRao Puli }
3496c5b2abe0SLewanczyk, Dawid } // namespace redfish
3497