xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision b66551019cf3c31186877c30a91ff8622454f342)
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"
238d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
24b49ac873SJames Feist #include "health.hpp"
25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
261c8fba97SJames Feist #include "led.hpp"
27f4c99e70SEd Tanous #include "query.hpp"
28c5d03ff4SJennifer Lee #include "redfish_util.hpp"
293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
313ccb3adbSEd Tanous #include "utils/json_utils.hpp"
32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
333ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
342b82937eSEd Tanous #include "utils/time_utils.hpp"
35c5d03ff4SJennifer Lee 
36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
379712f8acSEd Tanous #include <boost/container/flat_map.hpp>
38e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
39ef4c65b7SEd Tanous #include <boost/url/format.hpp>
40*b6655101SChris Cain #include <generated/enums/computer_system.hpp>
411e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
42fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
43bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
441214b7e7SGunnar Mills 
457a1dbc48SGeorge Liu #include <array>
467a1dbc48SGeorge Liu #include <string_view>
47abf2add6SEd Tanous #include <variant>
48c5b2abe0SLewanczyk, Dawid 
491abe55efSEd Tanous namespace redfish
501abe55efSEd Tanous {
51c5b2abe0SLewanczyk, Dawid 
525c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
535c3e9272SAbhishek Patel     protocolToDBusForSystems{
545c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
555c3e9272SAbhishek Patel 
569d3ae10eSAlpana Kumari /**
579d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
589d3ae10eSAlpana Kumari  *
59ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
609d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
619d3ae10eSAlpana Kumari  *
629d3ae10eSAlpana Kumari  * @return None.
639d3ae10eSAlpana Kumari  */
648d1b46d7Szhanghch05 inline void
65ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
661e1e598dSJonathan Doman                          bool isDimmFunctional)
679d3ae10eSAlpana Kumari {
6862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
699d3ae10eSAlpana Kumari 
709d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
719d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
729d3ae10eSAlpana Kumari     // ENABLED.
7302cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
74ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
759d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
769d3ae10eSAlpana Kumari     {
77e05aec50SEd Tanous         if (isDimmFunctional)
789d3ae10eSAlpana Kumari         {
79ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
809d3ae10eSAlpana Kumari                 "Enabled";
819d3ae10eSAlpana Kumari         }
829d3ae10eSAlpana Kumari     }
839d3ae10eSAlpana Kumari }
849d3ae10eSAlpana Kumari 
8557e8c9beSAlpana Kumari /*
8657e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8757e8c9beSAlpana Kumari  *        CPU Functional State
8857e8c9beSAlpana Kumari  *
89ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9057e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9157e8c9beSAlpana Kumari  *
9257e8c9beSAlpana Kumari  * @return None.
9357e8c9beSAlpana Kumari  */
94ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
95ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9657e8c9beSAlpana Kumari {
9762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
9857e8c9beSAlpana Kumari 
9902cad96eSEd Tanous     const nlohmann::json& prevProcState =
100ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10157e8c9beSAlpana Kumari 
10257e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10357e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10457e8c9beSAlpana Kumari     // Functional.
10557e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10657e8c9beSAlpana Kumari     {
107e05aec50SEd Tanous         if (isCpuFunctional)
10857e8c9beSAlpana Kumari         {
109ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11057e8c9beSAlpana Kumari                 "Enabled";
11157e8c9beSAlpana Kumari         }
11257e8c9beSAlpana Kumari     }
11357e8c9beSAlpana Kumari }
11457e8c9beSAlpana Kumari 
115cf0e004cSNinad Palsule /*
116cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
117cf0e004cSNinad Palsule  *
118ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
119cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
120cf0e004cSNinad Palsule  *
121cf0e004cSNinad Palsule  * @return None.
122cf0e004cSNinad Palsule  */
123cf0e004cSNinad Palsule inline void
124ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
125cf0e004cSNinad Palsule                            bool isCpuPresent)
126cf0e004cSNinad Palsule {
12762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
128cf0e004cSNinad Palsule 
129cf0e004cSNinad Palsule     if (isCpuPresent)
130cf0e004cSNinad Palsule     {
131cf0e004cSNinad Palsule         nlohmann::json& procCount =
132ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
133cf0e004cSNinad Palsule         auto* procCountPtr =
134cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
135cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
136cf0e004cSNinad Palsule         {
137cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
138cf0e004cSNinad Palsule             *procCountPtr += 1;
139cf0e004cSNinad Palsule         }
140cf0e004cSNinad Palsule     }
141cf0e004cSNinad Palsule }
142cf0e004cSNinad Palsule 
143382d6475SAli Ahmed inline void getProcessorProperties(
144ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
145382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
146382d6475SAli Ahmed         properties)
14703fbed92SAli Ahmed {
14862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
14903fbed92SAli Ahmed 
15003fbed92SAli Ahmed     // TODO: Get Model
15103fbed92SAli Ahmed 
152bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15303fbed92SAli Ahmed 
154bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
155bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15603fbed92SAli Ahmed 
157bc1d29deSKrzysztof Grobelny     if (!success)
15803fbed92SAli Ahmed     {
159ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16003fbed92SAli Ahmed         return;
16103fbed92SAli Ahmed     }
16203fbed92SAli Ahmed 
163bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16403fbed92SAli Ahmed     {
165bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
166ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
167bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
168bc1d29deSKrzysztof Grobelny 
169bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
170bc1d29deSKrzysztof Grobelny         {
171bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17203fbed92SAli Ahmed         }
17303fbed92SAli Ahmed         else
17403fbed92SAli Ahmed         {
175bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17603fbed92SAli Ahmed         }
17703fbed92SAli Ahmed     }
17803fbed92SAli Ahmed }
17903fbed92SAli Ahmed 
18003fbed92SAli Ahmed /*
18103fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18203fbed92SAli Ahmed  *
183ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18403fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18503fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18603fbed92SAli Ahmed  *
18703fbed92SAli Ahmed  * @return None.
18803fbed92SAli Ahmed  */
189ac106bf6SEd Tanous inline void
190ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
191ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19203fbed92SAli Ahmed {
193ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
194382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
195382d6475SAli Ahmed         if (ec3)
196382d6475SAli Ahmed         {
19762598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
198382d6475SAli Ahmed             return;
199382d6475SAli Ahmed         }
200ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
201382d6475SAli Ahmed     };
202382d6475SAli Ahmed 
203cf0e004cSNinad Palsule     // Get the Presence of CPU
204cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
205cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
206cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
207cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
208cf0e004cSNinad Palsule 
2095fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2105fd0aafbSNinad Palsule     {
2115fd0aafbSNinad Palsule         auto getCpuFunctionalState =
212ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
213382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
214382d6475SAli Ahmed             if (ec3)
215382d6475SAli Ahmed             {
21662598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
217382d6475SAli Ahmed                 return;
218382d6475SAli Ahmed             }
219ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
220382d6475SAli Ahmed         };
221382d6475SAli Ahmed 
222382d6475SAli Ahmed         // Get the Functional State
223382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
224382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2255fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2265fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2275fd0aafbSNinad Palsule     }
228382d6475SAli Ahmed 
229bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
230bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
231bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
232ac106bf6SEd Tanous         [asyncResp, service,
2335e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
234b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23503fbed92SAli Ahmed         if (ec2)
23603fbed92SAli Ahmed         {
23762598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
238ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23903fbed92SAli Ahmed             return;
24003fbed92SAli Ahmed         }
241ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
242bc1d29deSKrzysztof Grobelny     });
24303fbed92SAli Ahmed }
24403fbed92SAli Ahmed 
24557e8c9beSAlpana Kumari /*
246cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
247cf0e004cSNinad Palsule  *
248ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
249cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
250cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
251cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
252cf0e004cSNinad Palsule  *
253cf0e004cSNinad Palsule  * @return None.
254cf0e004cSNinad Palsule  */
255cf0e004cSNinad Palsule inline void
256ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2575fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2585fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
259cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
260cf0e004cSNinad Palsule {
26162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
262cf0e004cSNinad Palsule 
263cf0e004cSNinad Palsule     if (properties.empty())
264cf0e004cSNinad Palsule     {
2655fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2665fd0aafbSNinad Palsule         {
267cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
268cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
269cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
270cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
271cf0e004cSNinad Palsule                 "Functional",
272ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
273ac106bf6SEd Tanous                             bool dimmState) {
274cf0e004cSNinad Palsule                 if (ec3)
275cf0e004cSNinad Palsule                 {
27662598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
277cf0e004cSNinad Palsule                     return;
278cf0e004cSNinad Palsule                 }
279ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
280cf0e004cSNinad Palsule             });
2815fd0aafbSNinad Palsule         }
282cf0e004cSNinad Palsule         return;
283cf0e004cSNinad Palsule     }
284cf0e004cSNinad Palsule 
285cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
286cf0e004cSNinad Palsule 
287cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
288cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
289cf0e004cSNinad Palsule         memorySizeInKB);
290cf0e004cSNinad Palsule 
291cf0e004cSNinad Palsule     if (!success)
292cf0e004cSNinad Palsule     {
293ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
294cf0e004cSNinad Palsule         return;
295cf0e004cSNinad Palsule     }
296cf0e004cSNinad Palsule 
297cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
298cf0e004cSNinad Palsule     {
299cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
300ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
301dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
302cf0e004cSNinad Palsule         if (preValue == nullptr)
303cf0e004cSNinad Palsule         {
304ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
305dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
306cf0e004cSNinad Palsule         }
307cf0e004cSNinad Palsule         else
308cf0e004cSNinad Palsule         {
309ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
310dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
311dfb2b408SPriyanga Ramasamy                 *preValue;
312cf0e004cSNinad Palsule         }
3135fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3145fd0aafbSNinad Palsule         {
315ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3165fd0aafbSNinad Palsule                 "Enabled";
3175fd0aafbSNinad Palsule         }
318cf0e004cSNinad Palsule     }
319cf0e004cSNinad Palsule }
320cf0e004cSNinad Palsule 
321cf0e004cSNinad Palsule /*
322cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
323cf0e004cSNinad Palsule  *
324ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
325cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
326cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
327cf0e004cSNinad Palsule  *
328cf0e004cSNinad Palsule  * @return None.
329cf0e004cSNinad Palsule  */
330ac106bf6SEd Tanous inline void
331ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
332ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
333cf0e004cSNinad Palsule {
334cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
335cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
336cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
337ac106bf6SEd Tanous         [asyncResp, service,
338cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
339cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
340cf0e004cSNinad Palsule         if (ec2)
341cf0e004cSNinad Palsule         {
34262598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
343ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
344cf0e004cSNinad Palsule             return;
345cf0e004cSNinad Palsule         }
346ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
347cf0e004cSNinad Palsule     });
348cf0e004cSNinad Palsule }
349cf0e004cSNinad Palsule 
350a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
351a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
352a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3531abe55efSEd Tanous {
354a974c132SLakshmi Yadlapati     if (ec)
355a974c132SLakshmi Yadlapati     {
356a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
357a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
358a974c132SLakshmi Yadlapati         return;
359a974c132SLakshmi Yadlapati     }
360a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
361a974c132SLakshmi Yadlapati 
362a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
363a974c132SLakshmi Yadlapati 
364a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
365a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
366a974c132SLakshmi Yadlapati 
367a974c132SLakshmi Yadlapati     if (!success)
368a974c132SLakshmi Yadlapati     {
369a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
370a974c132SLakshmi Yadlapati         return;
371a974c132SLakshmi Yadlapati     }
372a974c132SLakshmi Yadlapati 
373a974c132SLakshmi Yadlapati     if (uUID != nullptr)
374a974c132SLakshmi Yadlapati     {
375a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
376a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
377a974c132SLakshmi Yadlapati         {
378a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
379a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
380a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
381a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
382a974c132SLakshmi Yadlapati         }
383a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
384a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
385a974c132SLakshmi Yadlapati     }
386a974c132SLakshmi Yadlapati }
387a974c132SLakshmi Yadlapati 
388a974c132SLakshmi Yadlapati inline void
389a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
390a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
391a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
392a974c132SLakshmi Yadlapati {
393a974c132SLakshmi Yadlapati     if (ec)
394a974c132SLakshmi Yadlapati     {
395a974c132SLakshmi Yadlapati         // doesn't have to include this
396a974c132SLakshmi Yadlapati         // interface
397a974c132SLakshmi Yadlapati         return;
398a974c132SLakshmi Yadlapati     }
399a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
400a974c132SLakshmi Yadlapati 
401a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
402a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
403a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
404a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
405a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
406a974c132SLakshmi Yadlapati 
407a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
408a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
409a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
410a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
411a974c132SLakshmi Yadlapati 
412a974c132SLakshmi Yadlapati     if (!success)
413a974c132SLakshmi Yadlapati     {
414a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
415a974c132SLakshmi Yadlapati         return;
416a974c132SLakshmi Yadlapati     }
417a974c132SLakshmi Yadlapati 
418a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
419a974c132SLakshmi Yadlapati     {
420a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
421a974c132SLakshmi Yadlapati     }
422a974c132SLakshmi Yadlapati 
423a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
424a974c132SLakshmi Yadlapati     {
425a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
426a974c132SLakshmi Yadlapati     }
427a974c132SLakshmi Yadlapati 
428a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
429a974c132SLakshmi Yadlapati     {
430a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
431a974c132SLakshmi Yadlapati     }
432a974c132SLakshmi Yadlapati 
433a974c132SLakshmi Yadlapati     if (model != nullptr)
434a974c132SLakshmi Yadlapati     {
435a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
436a974c132SLakshmi Yadlapati     }
437a974c132SLakshmi Yadlapati 
438a974c132SLakshmi Yadlapati     if (subModel != nullptr)
439a974c132SLakshmi Yadlapati     {
440a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
441a974c132SLakshmi Yadlapati     }
442a974c132SLakshmi Yadlapati 
443a974c132SLakshmi Yadlapati     // Grab the bios version
444a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
445a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
446a974c132SLakshmi Yadlapati }
447a974c132SLakshmi Yadlapati 
448a974c132SLakshmi Yadlapati inline void
449a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
450a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
451a974c132SLakshmi Yadlapati                      const std::string& value)
452a974c132SLakshmi Yadlapati {
453a974c132SLakshmi Yadlapati     if (ec)
454a974c132SLakshmi Yadlapati     {
455a974c132SLakshmi Yadlapati         // doesn't have to include this
456a974c132SLakshmi Yadlapati         // interface
457a974c132SLakshmi Yadlapati         return;
458a974c132SLakshmi Yadlapati     }
459a974c132SLakshmi Yadlapati 
460a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
461a974c132SLakshmi Yadlapati }
462a974c132SLakshmi Yadlapati 
463a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
464a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
465a974c132SLakshmi Yadlapati     const std::shared_ptr<HealthPopulate>& systemHealth,
466a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
467a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
468a974c132SLakshmi Yadlapati {
4691abe55efSEd Tanous     if (ec)
4701abe55efSEd Tanous     {
471b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
472ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
473c5b2abe0SLewanczyk, Dawid         return;
474c5b2abe0SLewanczyk, Dawid     }
475c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
476002d39b4SEd Tanous     for (const std::pair<
477002d39b4SEd Tanous              std::string,
478002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4791214b7e7SGunnar Mills              object : subtree)
4801abe55efSEd Tanous     {
481c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
48262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
483002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4841214b7e7SGunnar Mills             connectionNames = object.second;
48526f6976fSEd Tanous         if (connectionNames.empty())
4861abe55efSEd Tanous         {
487c5b2abe0SLewanczyk, Dawid             continue;
488c5b2abe0SLewanczyk, Dawid         }
489029573d4SEd Tanous 
4905fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
4915fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
4925bc2dc8eSJames Feist 
4935fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
4945fd0aafbSNinad Palsule         {
4955fd0aafbSNinad Palsule             memoryHealth = std::make_shared<HealthPopulate>(
496ac106bf6SEd Tanous                 asyncResp, "/MemorySummary/Status"_json_pointer);
4975fd0aafbSNinad Palsule             systemHealth->children.emplace_back(memoryHealth);
4985bc2dc8eSJames Feist 
49913451e39SWilly Tu             if constexpr (bmcwebEnableHealthPopulate)
50013451e39SWilly Tu             {
5015fd0aafbSNinad Palsule                 cpuHealth = std::make_shared<HealthPopulate>(
502ac106bf6SEd Tanous                     asyncResp, "/ProcessorSummary/Status"_json_pointer);
5035fd0aafbSNinad Palsule 
5045bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
50513451e39SWilly Tu             }
5065fd0aafbSNinad Palsule         }
5075bc2dc8eSJames Feist 
5086c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
5096c34de48SEd Tanous         // BiosVer
51004a258f4SEd Tanous         for (const auto& connection : connectionNames)
5111abe55efSEd Tanous         {
51204a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
5131abe55efSEd Tanous             {
514a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
5151abe55efSEd Tanous                 {
51662598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
5179d3ae10eSAlpana Kumari 
518ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
5195bc2dc8eSJames Feist 
5205fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5215fd0aafbSNinad Palsule                     {
5225bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
5231abe55efSEd Tanous                     }
5245fd0aafbSNinad Palsule                 }
52504a258f4SEd Tanous                 else if (interfaceName ==
52604a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
5271abe55efSEd Tanous                 {
52862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
52957e8c9beSAlpana Kumari 
530ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
5315bc2dc8eSJames Feist 
5325fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5335fd0aafbSNinad Palsule                     {
5345bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
5351abe55efSEd Tanous                     }
5365fd0aafbSNinad Palsule                 }
537002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
5381abe55efSEd Tanous                 {
53962598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
540bc1d29deSKrzysztof Grobelny 
541bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
542a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
543a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
544ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
545b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
5461214b7e7SGunnar Mills                                         properties) {
547a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
548bc1d29deSKrzysztof Grobelny                     });
549c5b2abe0SLewanczyk, Dawid                 }
550029573d4SEd Tanous                 else if (interfaceName ==
551029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
5521abe55efSEd Tanous                 {
553bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
554a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
555bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
556a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
557b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
558a974c132SLakshmi Yadlapati                                         properties) {
559a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
560bc1d29deSKrzysztof Grobelny                     });
561e4a4b9a9SJames Feist 
5621e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
563a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
5641e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
5651e1e598dSJonathan Doman                         "AssetTag",
5661e1e598dSJonathan Doman                         "AssetTag",
567a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
568a974c132SLakshmi Yadlapati                 }
569a974c132SLakshmi Yadlapati             }
570a974c132SLakshmi Yadlapati         }
571a974c132SLakshmi Yadlapati     }
572a974c132SLakshmi Yadlapati }
573a974c132SLakshmi Yadlapati 
574a974c132SLakshmi Yadlapati /*
575a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
576a974c132SLakshmi Yadlapati  *
577a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
578a974c132SLakshmi Yadlapati  * @param[in] systemHealth  Shared HealthPopulate pointer
579a974c132SLakshmi Yadlapati  *
580a974c132SLakshmi Yadlapati  * @return None.
581a974c132SLakshmi Yadlapati  */
582a974c132SLakshmi Yadlapati inline void
583a974c132SLakshmi Yadlapati     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
584a974c132SLakshmi Yadlapati                       const std::shared_ptr<HealthPopulate>& systemHealth)
585e4a4b9a9SJames Feist {
586a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
587a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
588a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
589a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
590a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
591a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
592a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
593a974c132SLakshmi Yadlapati     };
594a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
595a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
596a974c132SLakshmi Yadlapati         std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
597c5b2abe0SLewanczyk, Dawid }
598c5b2abe0SLewanczyk, Dawid 
599c5b2abe0SLewanczyk, Dawid /**
600c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
601c5b2abe0SLewanczyk, Dawid  *
602ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
603c5b2abe0SLewanczyk, Dawid  *
604c5b2abe0SLewanczyk, Dawid  * @return None.
605c5b2abe0SLewanczyk, Dawid  */
606ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
6071abe55efSEd Tanous {
60862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
6091e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6101e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6111e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6121e1e598dSJonathan Doman         "CurrentHostState",
613ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6141e1e598dSJonathan Doman                     const std::string& hostState) {
6151abe55efSEd Tanous         if (ec)
6161abe55efSEd Tanous         {
61722228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
61822228c28SAndrew Geissler             {
61922228c28SAndrew Geissler                 // Service not available, no error, just don't return
62022228c28SAndrew Geissler                 // host state info
62162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
62222228c28SAndrew Geissler                 return;
62322228c28SAndrew Geissler             }
62462598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
625ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
626c5b2abe0SLewanczyk, Dawid             return;
627c5b2abe0SLewanczyk, Dawid         }
6286617338dSEd Tanous 
62962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
630c5b2abe0SLewanczyk, Dawid         // Verify Host State
6311e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6321abe55efSEd Tanous         {
633ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
634ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6351abe55efSEd Tanous         }
6361e1e598dSJonathan Doman         else if (hostState ==
6370fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6388c888608SGunnar Mills         {
639ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
640ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6418c888608SGunnar Mills         }
6421e1e598dSJonathan Doman         else if (hostState ==
6430fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
64483935af9SAndrew Geissler         {
645ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
646ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
64783935af9SAndrew Geissler         }
6480fda0f12SGeorge Liu         else if (
6491e1e598dSJonathan Doman             hostState ==
6500fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6511a2a1437SAndrew Geissler         {
652ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
653ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6541a2a1437SAndrew Geissler         }
655002d39b4SEd Tanous         else if (hostState ==
6560fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6571a2a1437SAndrew Geissler         {
658ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
659ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6601a2a1437SAndrew Geissler         }
6611abe55efSEd Tanous         else
6621abe55efSEd Tanous         {
663ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
664ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
665c5b2abe0SLewanczyk, Dawid         }
6661e1e598dSJonathan Doman     });
667c5b2abe0SLewanczyk, Dawid }
668c5b2abe0SLewanczyk, Dawid 
669c5b2abe0SLewanczyk, Dawid /**
670786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
671491d8ee7SSantosh Puranik  *
672491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
673491d8ee7SSantosh Puranik  *
674491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
675491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
676491d8ee7SSantosh Puranik  */
67723a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
678491d8ee7SSantosh Puranik {
679491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
680491d8ee7SSantosh Puranik     {
681491d8ee7SSantosh Puranik         return "None";
682491d8ee7SSantosh Puranik     }
6833174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
684491d8ee7SSantosh Puranik     {
685491d8ee7SSantosh Puranik         return "Hdd";
686491d8ee7SSantosh Puranik     }
6873174e4dfSEd Tanous     if (dbusSource ==
688a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
689491d8ee7SSantosh Puranik     {
690491d8ee7SSantosh Puranik         return "Cd";
691491d8ee7SSantosh Puranik     }
6923174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
693491d8ee7SSantosh Puranik     {
694491d8ee7SSantosh Puranik         return "Pxe";
695491d8ee7SSantosh Puranik     }
6963174e4dfSEd Tanous     if (dbusSource ==
697944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6989f16b2c1SJennifer Lee     {
6999f16b2c1SJennifer Lee         return "Usb";
7009f16b2c1SJennifer Lee     }
701491d8ee7SSantosh Puranik     return "";
702491d8ee7SSantosh Puranik }
703491d8ee7SSantosh Puranik 
704491d8ee7SSantosh Puranik /**
705cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
706cd9a4666SKonstantin Aladyshev  *
707cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
708cd9a4666SKonstantin Aladyshev  *
709cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
710cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
711cd9a4666SKonstantin Aladyshev  */
712cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
713cd9a4666SKonstantin Aladyshev {
714cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
715cd9a4666SKonstantin Aladyshev     {
716cd9a4666SKonstantin Aladyshev         return "Legacy";
717cd9a4666SKonstantin Aladyshev     }
718cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
719cd9a4666SKonstantin Aladyshev     {
720cd9a4666SKonstantin Aladyshev         return "UEFI";
721cd9a4666SKonstantin Aladyshev     }
722cd9a4666SKonstantin Aladyshev     return "";
723cd9a4666SKonstantin Aladyshev }
724cd9a4666SKonstantin Aladyshev 
725cd9a4666SKonstantin Aladyshev /**
726786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
727491d8ee7SSantosh Puranik  *
728491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
729491d8ee7SSantosh Puranik  *
730491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
731491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
732491d8ee7SSantosh Puranik  */
73323a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
734491d8ee7SSantosh Puranik {
735491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
736491d8ee7SSantosh Puranik     {
737491d8ee7SSantosh Puranik         return "None";
738491d8ee7SSantosh Puranik     }
7393174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
740491d8ee7SSantosh Puranik     {
741491d8ee7SSantosh Puranik         return "Diags";
742491d8ee7SSantosh Puranik     }
7433174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
744491d8ee7SSantosh Puranik     {
745491d8ee7SSantosh Puranik         return "BiosSetup";
746491d8ee7SSantosh Puranik     }
747491d8ee7SSantosh Puranik     return "";
748491d8ee7SSantosh Puranik }
749491d8ee7SSantosh Puranik 
750491d8ee7SSantosh Puranik /**
751e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
752e43914b3SAndrew Geissler  *
753e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
754e43914b3SAndrew Geissler  *
755e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
756e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
757e43914b3SAndrew Geissler  */
758e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
759e43914b3SAndrew Geissler {
760e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
761e43914b3SAndrew Geissler     // enum
762e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
763e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
764e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
765e43914b3SAndrew Geissler     {
766e43914b3SAndrew Geissler         rfBpLastState = "None";
767e43914b3SAndrew Geissler     }
768e43914b3SAndrew Geissler     else if (dbusBootProgress ==
769e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
770e43914b3SAndrew Geissler              "PrimaryProcInit")
771e43914b3SAndrew Geissler     {
772e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
773e43914b3SAndrew Geissler     }
774e43914b3SAndrew Geissler     else if (dbusBootProgress ==
775e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
776e43914b3SAndrew Geissler              "BusInit")
777e43914b3SAndrew Geissler     {
778e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
779e43914b3SAndrew Geissler     }
780e43914b3SAndrew Geissler     else if (dbusBootProgress ==
781e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
782e43914b3SAndrew Geissler              "MemoryInit")
783e43914b3SAndrew Geissler     {
784e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
785e43914b3SAndrew Geissler     }
786e43914b3SAndrew Geissler     else if (dbusBootProgress ==
787e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
788e43914b3SAndrew Geissler              "SecondaryProcInit")
789e43914b3SAndrew Geissler     {
790e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
791e43914b3SAndrew Geissler     }
792e43914b3SAndrew Geissler     else if (dbusBootProgress ==
793e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
794e43914b3SAndrew Geissler              "PCIInit")
795e43914b3SAndrew Geissler     {
796e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
797e43914b3SAndrew Geissler     }
798e43914b3SAndrew Geissler     else if (dbusBootProgress ==
799e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
800e43914b3SAndrew Geissler              "SystemSetup")
801e43914b3SAndrew Geissler     {
802e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
803e43914b3SAndrew Geissler     }
804e43914b3SAndrew Geissler     else if (dbusBootProgress ==
805e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
806e43914b3SAndrew Geissler              "SystemInitComplete")
807e43914b3SAndrew Geissler     {
808e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
809e43914b3SAndrew Geissler     }
810e43914b3SAndrew Geissler     else if (dbusBootProgress ==
811e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
812e43914b3SAndrew Geissler              "OSStart")
813e43914b3SAndrew Geissler     {
814e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
815e43914b3SAndrew Geissler     }
816e43914b3SAndrew Geissler     else if (dbusBootProgress ==
817e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
818e43914b3SAndrew Geissler              "OSRunning")
819e43914b3SAndrew Geissler     {
820e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
821e43914b3SAndrew Geissler     }
822e43914b3SAndrew Geissler     else
823e43914b3SAndrew Geissler     {
82462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
825e43914b3SAndrew Geissler         // Just return the default
826e43914b3SAndrew Geissler     }
827e43914b3SAndrew Geissler     return rfBpLastState;
828e43914b3SAndrew Geissler }
829e43914b3SAndrew Geissler 
830e43914b3SAndrew Geissler /**
831786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
832491d8ee7SSantosh Puranik  *
833491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
834944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
835944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
836491d8ee7SSantosh Puranik  *
837944ffaf9SJohnathan Mantey  * @return Integer error code.
838491d8ee7SSantosh Puranik  */
839ac106bf6SEd Tanous inline int
840ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
841ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
842ac106bf6SEd Tanous                          std::string& bootMode)
843491d8ee7SSantosh Puranik {
844c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
845c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
846944ffaf9SJohnathan Mantey 
847491d8ee7SSantosh Puranik     if (rfSource == "None")
848491d8ee7SSantosh Puranik     {
849944ffaf9SJohnathan Mantey         return 0;
850491d8ee7SSantosh Puranik     }
8513174e4dfSEd Tanous     if (rfSource == "Pxe")
852491d8ee7SSantosh Puranik     {
853944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
854944ffaf9SJohnathan Mantey     }
855944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
856944ffaf9SJohnathan Mantey     {
857944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
858944ffaf9SJohnathan Mantey     }
859944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
860944ffaf9SJohnathan Mantey     {
861944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
862944ffaf9SJohnathan Mantey     }
863944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
864944ffaf9SJohnathan Mantey     {
865944ffaf9SJohnathan Mantey         bootSource =
866944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
867944ffaf9SJohnathan Mantey     }
868944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
869944ffaf9SJohnathan Mantey     {
870944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
871491d8ee7SSantosh Puranik     }
8729f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8739f16b2c1SJennifer Lee     {
874944ffaf9SJohnathan Mantey         bootSource =
875944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8769f16b2c1SJennifer Lee     }
877491d8ee7SSantosh Puranik     else
878491d8ee7SSantosh Puranik     {
87962598e31SEd Tanous         BMCWEB_LOG_DEBUG(
88062598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
88162598e31SEd Tanous             bootSource);
882ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
883944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
884944ffaf9SJohnathan Mantey         return -1;
885491d8ee7SSantosh Puranik     }
886944ffaf9SJohnathan Mantey     return 0;
887491d8ee7SSantosh Puranik }
8881981771bSAli Ahmed 
889978b8803SAndrew Geissler /**
890978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
891978b8803SAndrew Geissler  *
892ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
893978b8803SAndrew Geissler  *
894978b8803SAndrew Geissler  * @return None.
895978b8803SAndrew Geissler  */
896ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
897978b8803SAndrew Geissler {
8981e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8991e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
9001e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
9011e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
902ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9031e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
904978b8803SAndrew Geissler         if (ec)
905978b8803SAndrew Geissler         {
906978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
907978b8803SAndrew Geissler             // not found
908978b8803SAndrew Geissler             return;
909978b8803SAndrew Geissler         }
910978b8803SAndrew Geissler 
91162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
912978b8803SAndrew Geissler 
913ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
914e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9151e1e598dSJonathan Doman     });
916978b8803SAndrew Geissler }
917491d8ee7SSantosh Puranik 
918491d8ee7SSantosh Puranik /**
919b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
920b6d5d45cSHieu Huynh  *
921ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
922b6d5d45cSHieu Huynh  *
923b6d5d45cSHieu Huynh  * @return None.
924b6d5d45cSHieu Huynh  */
925b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
926ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
927b6d5d45cSHieu Huynh {
928b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
929b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
930b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
931b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
932ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
933b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
934b6d5d45cSHieu Huynh         if (ec)
935b6d5d45cSHieu Huynh         {
93662598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
937b6d5d45cSHieu Huynh             return;
938b6d5d45cSHieu Huynh         }
939b6d5d45cSHieu Huynh 
940b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
941b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
942b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
943b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
944b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
945b6d5d45cSHieu Huynh 
946b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
947ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
948b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
949b6d5d45cSHieu Huynh     });
950b6d5d45cSHieu Huynh }
951b6d5d45cSHieu Huynh 
952b6d5d45cSHieu Huynh /**
953c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
954cd9a4666SKonstantin Aladyshev  *
955ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
956cd9a4666SKonstantin Aladyshev  *
957cd9a4666SKonstantin Aladyshev  * @return None.
958cd9a4666SKonstantin Aladyshev  */
959cd9a4666SKonstantin Aladyshev 
960ac106bf6SEd Tanous inline void
961ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
962cd9a4666SKonstantin Aladyshev {
9631e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9641e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9651e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9661e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
967ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9681e1e598dSJonathan Doman                     const std::string& bootType) {
969cd9a4666SKonstantin Aladyshev         if (ec)
970cd9a4666SKonstantin Aladyshev         {
971cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
972cd9a4666SKonstantin Aladyshev             return;
973cd9a4666SKonstantin Aladyshev         }
974cd9a4666SKonstantin Aladyshev 
97562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
976cd9a4666SKonstantin Aladyshev 
977ac106bf6SEd Tanous         asyncResp->res
978ac106bf6SEd Tanous             .jsonValue["Boot"]
979002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
980613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
981cd9a4666SKonstantin Aladyshev 
9821e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
983cd9a4666SKonstantin Aladyshev         if (rfType.empty())
984cd9a4666SKonstantin Aladyshev         {
985ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
986cd9a4666SKonstantin Aladyshev             return;
987cd9a4666SKonstantin Aladyshev         }
988cd9a4666SKonstantin Aladyshev 
989ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9901e1e598dSJonathan Doman     });
991cd9a4666SKonstantin Aladyshev }
992cd9a4666SKonstantin Aladyshev 
993cd9a4666SKonstantin Aladyshev /**
994c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
995491d8ee7SSantosh Puranik  *
996ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
997491d8ee7SSantosh Puranik  *
998491d8ee7SSantosh Puranik  * @return None.
999491d8ee7SSantosh Puranik  */
1000c21865c4SKonstantin Aladyshev 
1001ac106bf6SEd Tanous inline void
1002ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1003491d8ee7SSantosh Puranik {
10041e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10051e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10061e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10071e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1008ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10091e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1010491d8ee7SSantosh Puranik         if (ec)
1011491d8ee7SSantosh Puranik         {
1012b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1013ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1014491d8ee7SSantosh Puranik             return;
1015491d8ee7SSantosh Puranik         }
1016491d8ee7SSantosh Puranik 
101762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
1018491d8ee7SSantosh Puranik 
1019ac106bf6SEd Tanous         asyncResp->res
10200fda0f12SGeorge Liu             .jsonValue["Boot"]
1021002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1022002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1023491d8ee7SSantosh Puranik 
10241e1e598dSJonathan Doman         if (bootModeStr !=
1025491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1026491d8ee7SSantosh Puranik         {
10271e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1028491d8ee7SSantosh Puranik             if (!rfMode.empty())
1029491d8ee7SSantosh Puranik             {
1030ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1031491d8ee7SSantosh Puranik                     rfMode;
1032491d8ee7SSantosh Puranik             }
1033491d8ee7SSantosh Puranik         }
10341e1e598dSJonathan Doman     });
1035491d8ee7SSantosh Puranik }
1036491d8ee7SSantosh Puranik 
1037491d8ee7SSantosh Puranik /**
1038c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1039491d8ee7SSantosh Puranik  *
1040ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1041491d8ee7SSantosh Puranik  *
1042491d8ee7SSantosh Puranik  * @return None.
1043491d8ee7SSantosh Puranik  */
1044c21865c4SKonstantin Aladyshev 
1045c21865c4SKonstantin Aladyshev inline void
1046ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1047491d8ee7SSantosh Puranik {
10481e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10491e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10501e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10511e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1052ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10531e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1054491d8ee7SSantosh Puranik         if (ec)
1055491d8ee7SSantosh Puranik         {
10565ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10575ef735c8SNan Zhou             {
10585ef735c8SNan Zhou                 return;
10595ef735c8SNan Zhou             }
1060b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1061ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1062491d8ee7SSantosh Puranik             return;
1063491d8ee7SSantosh Puranik         }
1064491d8ee7SSantosh Puranik 
106562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1066491d8ee7SSantosh Puranik 
10671e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1068491d8ee7SSantosh Puranik         if (!rfSource.empty())
1069491d8ee7SSantosh Puranik         {
1070ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1071ac106bf6SEd Tanous                 rfSource;
1072491d8ee7SSantosh Puranik         }
1073cd9a4666SKonstantin Aladyshev 
1074cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1075cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1076ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10771e1e598dSJonathan Doman     });
1078491d8ee7SSantosh Puranik }
1079491d8ee7SSantosh Puranik 
1080491d8ee7SSantosh Puranik /**
1081c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1082c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1083c21865c4SKonstantin Aladyshev  * state
1084491d8ee7SSantosh Puranik  *
1085ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1086491d8ee7SSantosh Puranik  *
1087491d8ee7SSantosh Puranik  * @return None.
1088491d8ee7SSantosh Puranik  */
1089491d8ee7SSantosh Puranik 
1090ac106bf6SEd Tanous inline void processBootOverrideEnable(
1091ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1092c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1093c21865c4SKonstantin Aladyshev {
1094c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1095c21865c4SKonstantin Aladyshev     {
1096ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1097ac106bf6SEd Tanous             "Disabled";
1098c21865c4SKonstantin Aladyshev         return;
1099c21865c4SKonstantin Aladyshev     }
1100c21865c4SKonstantin Aladyshev 
1101c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1102c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
11031e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11041e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11051e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
11061e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1107ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1108491d8ee7SSantosh Puranik         if (ec)
1109491d8ee7SSantosh Puranik         {
1110b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1111ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1112491d8ee7SSantosh Puranik             return;
1113491d8ee7SSantosh Puranik         }
1114491d8ee7SSantosh Puranik 
1115c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1116c21865c4SKonstantin Aladyshev         {
1117ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1118ac106bf6SEd Tanous                 "Once";
1119c21865c4SKonstantin Aladyshev         }
1120c21865c4SKonstantin Aladyshev         else
1121c21865c4SKonstantin Aladyshev         {
1122ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1123c21865c4SKonstantin Aladyshev                 "Continuous";
1124c21865c4SKonstantin Aladyshev         }
11251e1e598dSJonathan Doman     });
1126491d8ee7SSantosh Puranik }
1127491d8ee7SSantosh Puranik 
1128491d8ee7SSantosh Puranik /**
1129c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1130c21865c4SKonstantin Aladyshev  *
1131ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1132c21865c4SKonstantin Aladyshev  *
1133c21865c4SKonstantin Aladyshev  * @return None.
1134c21865c4SKonstantin Aladyshev  */
1135c21865c4SKonstantin Aladyshev 
1136c21865c4SKonstantin Aladyshev inline void
1137ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1138c21865c4SKonstantin Aladyshev {
11391e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11401e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11411e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11421e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1143ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11441e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1145c21865c4SKonstantin Aladyshev         if (ec)
1146c21865c4SKonstantin Aladyshev         {
11475ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11485ef735c8SNan Zhou             {
11495ef735c8SNan Zhou                 return;
11505ef735c8SNan Zhou             }
1151b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1152ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1153c21865c4SKonstantin Aladyshev             return;
1154c21865c4SKonstantin Aladyshev         }
1155c21865c4SKonstantin Aladyshev 
1156ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11571e1e598dSJonathan Doman     });
1158c21865c4SKonstantin Aladyshev }
1159c21865c4SKonstantin Aladyshev 
1160c21865c4SKonstantin Aladyshev /**
1161c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1162c21865c4SKonstantin Aladyshev  *
1163ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1164c21865c4SKonstantin Aladyshev  *
1165c21865c4SKonstantin Aladyshev  * @return None.
1166c21865c4SKonstantin Aladyshev  */
1167ac106bf6SEd Tanous inline void
1168ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1169c21865c4SKonstantin Aladyshev {
117062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1171c21865c4SKonstantin Aladyshev 
1172ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1173ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1174ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1175c21865c4SKonstantin Aladyshev }
1176c21865c4SKonstantin Aladyshev 
1177c21865c4SKonstantin Aladyshev /**
1178c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1179c0557e1aSGunnar Mills  *
1180c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1181c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1182c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1183c0557e1aSGunnar Mills  * last power operation time.
1184c0557e1aSGunnar Mills  *
1185ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1186c0557e1aSGunnar Mills  *
1187c0557e1aSGunnar Mills  * @return None.
1188c0557e1aSGunnar Mills  */
1189ac106bf6SEd Tanous inline void
1190ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1191c0557e1aSGunnar Mills {
119262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1193c0557e1aSGunnar Mills 
11941e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11951e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11961e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11971e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1198ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1199ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1200c0557e1aSGunnar Mills         if (ec)
1201c0557e1aSGunnar Mills         {
120262598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1203c0557e1aSGunnar Mills             return;
1204c0557e1aSGunnar Mills         }
1205c0557e1aSGunnar Mills 
1206c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1207c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12081e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1209c0557e1aSGunnar Mills 
1210c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1211ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12122b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12131e1e598dSJonathan Doman     });
1214c0557e1aSGunnar Mills }
1215c0557e1aSGunnar Mills 
1216c0557e1aSGunnar Mills /**
1217797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1218797d5daeSCorey Hardesty  *
1219797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1220797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1221797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1222797d5daeSCorey Hardesty  * dbus.
1223797d5daeSCorey Hardesty  *
1224ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1225797d5daeSCorey Hardesty  *
1226797d5daeSCorey Hardesty  * @return None.
1227797d5daeSCorey Hardesty  */
1228ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1229ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1230797d5daeSCorey Hardesty {
123162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1232797d5daeSCorey Hardesty 
1233797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1234797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1235797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1236797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1237ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1238ac106bf6SEd Tanous             const boost::system::error_code& ec,
1239797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1240797d5daeSCorey Hardesty         if (ec)
1241797d5daeSCorey Hardesty         {
1242797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1243797d5daeSCorey Hardesty             {
124462598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1245ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1246797d5daeSCorey Hardesty             }
1247797d5daeSCorey Hardesty             return;
1248797d5daeSCorey Hardesty         }
1249797d5daeSCorey Hardesty 
1250797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1251797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1252797d5daeSCorey Hardesty 
1253797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1254797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1255797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1256797d5daeSCorey Hardesty 
1257797d5daeSCorey Hardesty         if (!success)
1258797d5daeSCorey Hardesty         {
1259ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1260797d5daeSCorey Hardesty             return;
1261797d5daeSCorey Hardesty         }
1262797d5daeSCorey Hardesty 
1263797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1264797d5daeSCorey Hardesty         {
1265ac106bf6SEd Tanous             asyncResp->res
1266ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1267797d5daeSCorey Hardesty                 *attemptsLeft;
1268797d5daeSCorey Hardesty         }
1269797d5daeSCorey Hardesty 
1270797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1271797d5daeSCorey Hardesty         {
1272ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1273797d5daeSCorey Hardesty                 *retryAttempts;
1274797d5daeSCorey Hardesty         }
1275797d5daeSCorey Hardesty     });
1276797d5daeSCorey Hardesty }
1277797d5daeSCorey Hardesty 
1278797d5daeSCorey Hardesty /**
12796bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12806bd5a8d2SGunnar Mills  *
1281ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12826bd5a8d2SGunnar Mills  *
12836bd5a8d2SGunnar Mills  * @return None.
12846bd5a8d2SGunnar Mills  */
1285797d5daeSCorey Hardesty inline void
1286ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12876bd5a8d2SGunnar Mills {
128862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12896bd5a8d2SGunnar Mills 
12901e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12911e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12921e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12931e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1294ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1295ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12966bd5a8d2SGunnar Mills         if (ec)
12976bd5a8d2SGunnar Mills         {
1298797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1299797d5daeSCorey Hardesty             {
130062598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1301ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1302797d5daeSCorey Hardesty             }
13036bd5a8d2SGunnar Mills             return;
13046bd5a8d2SGunnar Mills         }
13056bd5a8d2SGunnar Mills 
130662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1307e05aec50SEd Tanous         if (autoRebootEnabled)
13086bd5a8d2SGunnar Mills         {
1309ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13106bd5a8d2SGunnar Mills                 "RetryAttempts";
13116bd5a8d2SGunnar Mills         }
13126bd5a8d2SGunnar Mills         else
13136bd5a8d2SGunnar Mills         {
1314ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1315ac106bf6SEd Tanous                 "Disabled";
13166bd5a8d2SGunnar Mills         }
1317ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
131869f35306SGunnar Mills 
131969f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
132069f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
132169f35306SGunnar Mills         // RetryAttempts.
1322ac106bf6SEd Tanous         asyncResp->res
1323ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1324ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13251e1e598dSJonathan Doman     });
13266bd5a8d2SGunnar Mills }
13276bd5a8d2SGunnar Mills 
13286bd5a8d2SGunnar Mills /**
1329797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1330797d5daeSCorey Hardesty  *
1331ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1332797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1333797d5daeSCorey Hardesty  *
1334797d5daeSCorey Hardesty  *@return None.
1335797d5daeSCorey Hardesty  */
1336797d5daeSCorey Hardesty 
1337ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1338ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1339797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1340797d5daeSCorey Hardesty {
134162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
13429ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13439ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13449ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13459ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13469ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1347797d5daeSCorey Hardesty         if (ec)
1348797d5daeSCorey Hardesty         {
134962598e31SEd Tanous             BMCWEB_LOG_ERROR(
135062598e31SEd Tanous                 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1351ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1352797d5daeSCorey Hardesty             return;
1353797d5daeSCorey Hardesty         }
13549ae226faSGeorge Liu     });
1355797d5daeSCorey Hardesty }
1356797d5daeSCorey Hardesty 
13578d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13588d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13598d69c668SEd Tanous {
13608d69c668SEd Tanous     if (value ==
13618d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13628d69c668SEd Tanous     {
13638d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13648d69c668SEd Tanous     }
13658d69c668SEd Tanous     if (value ==
13668d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13678d69c668SEd Tanous     {
13688d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13698d69c668SEd Tanous     }
13708d69c668SEd Tanous     if (value ==
13713a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13728d69c668SEd Tanous     {
13738d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13748d69c668SEd Tanous     }
13758d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13768d69c668SEd Tanous     {
13778d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13788d69c668SEd Tanous     }
13798d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13808d69c668SEd Tanous }
1381797d5daeSCorey Hardesty /**
1382c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1383c6a620f2SGeorge Liu  *
1384ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1385c6a620f2SGeorge Liu  *
1386c6a620f2SGeorge Liu  * @return None.
1387c6a620f2SGeorge Liu  */
13888d1b46d7Szhanghch05 inline void
1389ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1390c6a620f2SGeorge Liu {
139162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1392c6a620f2SGeorge Liu 
13931e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13941e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13951e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13961e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1397ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13985e7e2dc5SEd Tanous                     const std::string& policy) {
1399c6a620f2SGeorge Liu         if (ec)
1400c6a620f2SGeorge Liu         {
140162598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1402c6a620f2SGeorge Liu             return;
1403c6a620f2SGeorge Liu         }
14048d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
14058d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14068d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1407c6a620f2SGeorge Liu         {
1408ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1409c6a620f2SGeorge Liu             return;
1410c6a620f2SGeorge Liu         }
1411c6a620f2SGeorge Liu 
14128d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14131e1e598dSJonathan Doman     });
1414c6a620f2SGeorge Liu }
1415c6a620f2SGeorge Liu 
1416c6a620f2SGeorge Liu /**
14179dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14189dcfe8c1SAlbert Zhang  *
14199dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14209dcfe8c1SAlbert Zhang  *
14219dcfe8c1SAlbert Zhang  * @return None.
14229dcfe8c1SAlbert Zhang  */
14239dcfe8c1SAlbert Zhang inline void
14249dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14259dcfe8c1SAlbert Zhang {
142662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
14279dcfe8c1SAlbert Zhang 
14289dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
14299dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14309dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
14319dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14329dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14339dcfe8c1SAlbert Zhang         if (ec)
14349dcfe8c1SAlbert Zhang         {
14359dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
14369dcfe8c1SAlbert Zhang             {
1437b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
14389dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
14399dcfe8c1SAlbert Zhang             }
14409dcfe8c1SAlbert Zhang             return;
14419dcfe8c1SAlbert Zhang         }
14429dcfe8c1SAlbert Zhang 
14439dcfe8c1SAlbert Zhang         if (value)
14449dcfe8c1SAlbert Zhang         {
14459dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
14469dcfe8c1SAlbert Zhang         }
14479dcfe8c1SAlbert Zhang         else
14489dcfe8c1SAlbert Zhang         {
14499dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
14509dcfe8c1SAlbert Zhang         }
14519dcfe8c1SAlbert Zhang     });
14529dcfe8c1SAlbert Zhang }
14539dcfe8c1SAlbert Zhang 
14549dcfe8c1SAlbert Zhang /**
14551981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14561981771bSAli Ahmed  * TPM is required for booting the host.
14571981771bSAli Ahmed  *
1458ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14591981771bSAli Ahmed  *
14601981771bSAli Ahmed  * @return None.
14611981771bSAli Ahmed  */
14621981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1463ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14641981771bSAli Ahmed {
146562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1466e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1467e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1468e99073f5SGeorge Liu     dbus::utility::getSubTree(
1469e99073f5SGeorge Liu         "/", 0, interfaces,
1470ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1471b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14721981771bSAli Ahmed         if (ec)
14731981771bSAli Ahmed         {
147462598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
147562598e31SEd Tanous                              ec);
14761981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14771981771bSAli Ahmed             // error occurs
14781981771bSAli Ahmed             return;
14791981771bSAli Ahmed         }
148026f6976fSEd Tanous         if (subtree.empty())
14811981771bSAli Ahmed         {
14821981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14831981771bSAli Ahmed             // if there is no instance found
14841981771bSAli Ahmed             return;
14851981771bSAli Ahmed         }
14861981771bSAli Ahmed 
14871981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14881981771bSAli Ahmed         if (subtree.size() > 1)
14891981771bSAli Ahmed         {
149062598e31SEd Tanous             BMCWEB_LOG_DEBUG(
149162598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
149262598e31SEd Tanous                 subtree.size());
14931981771bSAli Ahmed             // Throw an internal Error and return
1494ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14951981771bSAli Ahmed             return;
14961981771bSAli Ahmed         }
14971981771bSAli Ahmed 
14981981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14991981771bSAli Ahmed         // field
15001981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15011981771bSAli Ahmed         {
150262598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1503ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15041981771bSAli Ahmed             return;
15051981771bSAli Ahmed         }
15061981771bSAli Ahmed 
15071981771bSAli Ahmed         const std::string& path = subtree[0].first;
15081981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15091981771bSAli Ahmed 
15101981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15111e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15121e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15131e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1514ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1515ac106bf6SEd Tanous                         bool tpmRequired) {
15168a592810SEd Tanous             if (ec2)
15171981771bSAli Ahmed             {
1518b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
151962598e31SEd Tanous                                  ec2);
1520ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15211981771bSAli Ahmed                 return;
15221981771bSAli Ahmed             }
15231981771bSAli Ahmed 
15241e1e598dSJonathan Doman             if (tpmRequired)
15251981771bSAli Ahmed             {
1526ac106bf6SEd Tanous                 asyncResp->res
1527ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15281981771bSAli Ahmed                     "Required";
15291981771bSAli Ahmed             }
15301981771bSAli Ahmed             else
15311981771bSAli Ahmed             {
1532ac106bf6SEd Tanous                 asyncResp->res
1533ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15341981771bSAli Ahmed                     "Disabled";
15351981771bSAli Ahmed             }
15361e1e598dSJonathan Doman         });
1537e99073f5SGeorge Liu     });
15381981771bSAli Ahmed }
15391981771bSAli Ahmed 
15401981771bSAli Ahmed /**
15411c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15421c05dae3SAli Ahmed  * TPM is required for booting the host.
15431c05dae3SAli Ahmed  *
1544ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15451c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15461c05dae3SAli Ahmed  *
15471c05dae3SAli Ahmed  * @return None.
15481c05dae3SAli Ahmed  */
15491c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1550ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15511c05dae3SAli Ahmed {
155262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1553e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1554e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1555e99073f5SGeorge Liu     dbus::utility::getSubTree(
1556e99073f5SGeorge Liu         "/", 0, interfaces,
1557ac106bf6SEd Tanous         [asyncResp,
1558e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1559e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15601c05dae3SAli Ahmed         if (ec)
15611c05dae3SAli Ahmed         {
1562b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
156362598e31SEd Tanous                              ec);
1564ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15651c05dae3SAli Ahmed             return;
15661c05dae3SAli Ahmed         }
156726f6976fSEd Tanous         if (subtree.empty())
15681c05dae3SAli Ahmed         {
1569ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15701c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15711c05dae3SAli Ahmed             return;
15721c05dae3SAli Ahmed         }
15731c05dae3SAli Ahmed 
15741c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15751c05dae3SAli Ahmed         if (subtree.size() > 1)
15761c05dae3SAli Ahmed         {
157762598e31SEd Tanous             BMCWEB_LOG_DEBUG(
157862598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
157962598e31SEd Tanous                 subtree.size());
15801c05dae3SAli Ahmed             // Throw an internal Error and return
1581ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15821c05dae3SAli Ahmed             return;
15831c05dae3SAli Ahmed         }
15841c05dae3SAli Ahmed 
15851c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15861c05dae3SAli Ahmed         // field
15871c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15881c05dae3SAli Ahmed         {
158962598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1590ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15911c05dae3SAli Ahmed             return;
15921c05dae3SAli Ahmed         }
15931c05dae3SAli Ahmed 
15941c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15951c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15961c05dae3SAli Ahmed 
15971c05dae3SAli Ahmed         if (serv.empty())
15981c05dae3SAli Ahmed         {
159962598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1600ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
16011c05dae3SAli Ahmed             return;
16021c05dae3SAli Ahmed         }
16031c05dae3SAli Ahmed 
16041c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
16059ae226faSGeorge Liu         sdbusplus::asio::setProperty(
16069ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16079ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1608ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16098a592810SEd Tanous             if (ec2)
16101c05dae3SAli Ahmed             {
1611b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
161262598e31SEd Tanous                     "DBUS response error: Set TrustedModuleRequiredToBoot{}",
161362598e31SEd Tanous                     ec2);
1614ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16151c05dae3SAli Ahmed                 return;
16161c05dae3SAli Ahmed             }
161762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
16189ae226faSGeorge Liu         });
1619e99073f5SGeorge Liu     });
16201c05dae3SAli Ahmed }
16211c05dae3SAli Ahmed 
16221c05dae3SAli Ahmed /**
1623491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1624491d8ee7SSantosh Puranik  *
1625ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1626cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1627cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1628cd9a4666SKonstantin Aladyshev  */
1629ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1630cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1631cd9a4666SKonstantin Aladyshev {
1632c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1633cd9a4666SKonstantin Aladyshev 
1634c21865c4SKonstantin Aladyshev     if (!bootType)
1635cd9a4666SKonstantin Aladyshev     {
1636c21865c4SKonstantin Aladyshev         return;
1637c21865c4SKonstantin Aladyshev     }
1638c21865c4SKonstantin Aladyshev 
1639cd9a4666SKonstantin Aladyshev     // Source target specified
164062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1641cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1642cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1643cd9a4666SKonstantin Aladyshev     {
1644cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1645cd9a4666SKonstantin Aladyshev     }
1646cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1647cd9a4666SKonstantin Aladyshev     {
1648cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1649cd9a4666SKonstantin Aladyshev     }
1650cd9a4666SKonstantin Aladyshev     else
1651cd9a4666SKonstantin Aladyshev     {
165262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
165362598e31SEd Tanous                          "BootSourceOverrideMode: {}",
165462598e31SEd Tanous                          *bootType);
1655ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1656cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1657cd9a4666SKonstantin Aladyshev         return;
1658cd9a4666SKonstantin Aladyshev     }
1659cd9a4666SKonstantin Aladyshev 
1660cd9a4666SKonstantin Aladyshev     // Act on validated parameters
166162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1662cd9a4666SKonstantin Aladyshev 
16639ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16649ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16659ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16669ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1667ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1668cd9a4666SKonstantin Aladyshev         if (ec)
1669cd9a4666SKonstantin Aladyshev         {
1670cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1671cd9a4666SKonstantin Aladyshev             {
1672ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1673cd9a4666SKonstantin Aladyshev                 return;
1674cd9a4666SKonstantin Aladyshev             }
1675b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1676ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1677cd9a4666SKonstantin Aladyshev             return;
1678cd9a4666SKonstantin Aladyshev         }
167962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type update done.");
16809ae226faSGeorge Liu     });
1681cd9a4666SKonstantin Aladyshev }
1682cd9a4666SKonstantin Aladyshev 
1683cd9a4666SKonstantin Aladyshev /**
1684cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1685cd9a4666SKonstantin Aladyshev  *
1686ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1687ac106bf6SEd Tanous  * message.
1688c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1689c21865c4SKonstantin Aladyshev  * @return Integer error code.
1690c21865c4SKonstantin Aladyshev  */
1691ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1692c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1693c21865c4SKonstantin Aladyshev {
1694c21865c4SKonstantin Aladyshev     if (!bootEnable)
1695c21865c4SKonstantin Aladyshev     {
1696c21865c4SKonstantin Aladyshev         return;
1697c21865c4SKonstantin Aladyshev     }
1698c21865c4SKonstantin Aladyshev     // Source target specified
169962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1700c21865c4SKonstantin Aladyshev 
1701c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1702c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1703c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1704c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1705c21865c4SKonstantin Aladyshev     {
1706c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1707c21865c4SKonstantin Aladyshev     }
1708c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1709c21865c4SKonstantin Aladyshev     {
1710c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1711c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1712c21865c4SKonstantin Aladyshev     }
1713c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1714c21865c4SKonstantin Aladyshev     {
1715c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1716c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1717c21865c4SKonstantin Aladyshev     }
1718c21865c4SKonstantin Aladyshev     else
1719c21865c4SKonstantin Aladyshev     {
172062598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172162598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
172262598e31SEd Tanous             *bootEnable);
1723ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1724c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1725c21865c4SKonstantin Aladyshev         return;
1726c21865c4SKonstantin Aladyshev     }
1727c21865c4SKonstantin Aladyshev 
1728c21865c4SKonstantin Aladyshev     // Act on validated parameters
172962598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1730c21865c4SKonstantin Aladyshev 
17319ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17329ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17339ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17349ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1735ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17368a592810SEd Tanous         if (ec2)
1737c21865c4SKonstantin Aladyshev         {
1738b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
1739ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1740c21865c4SKonstantin Aladyshev             return;
1741c21865c4SKonstantin Aladyshev         }
174262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot override enable update done.");
17439ae226faSGeorge Liu     });
1744c21865c4SKonstantin Aladyshev 
1745c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1746c21865c4SKonstantin Aladyshev     {
1747c21865c4SKonstantin Aladyshev         return;
1748c21865c4SKonstantin Aladyshev     }
1749c21865c4SKonstantin Aladyshev 
1750c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1751c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
175262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
175362598e31SEd Tanous                      bootOverridePersistent);
1754c21865c4SKonstantin Aladyshev 
17559ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17569ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17579ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17589ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1759ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1760c21865c4SKonstantin Aladyshev         if (ec)
1761c21865c4SKonstantin Aladyshev         {
1762b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1763ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1764c21865c4SKonstantin Aladyshev             return;
1765c21865c4SKonstantin Aladyshev         }
176662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot one_time update done.");
17679ae226faSGeorge Liu     });
1768c21865c4SKonstantin Aladyshev }
1769c21865c4SKonstantin Aladyshev 
1770c21865c4SKonstantin Aladyshev /**
1771c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1772c21865c4SKonstantin Aladyshev  *
1773ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1774491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1775491d8ee7SSantosh Puranik  *
1776265c1602SJohnathan Mantey  * @return Integer error code.
1777491d8ee7SSantosh Puranik  */
1778ac106bf6SEd Tanous inline void
1779ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1780cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1781491d8ee7SSantosh Puranik {
1782c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1783c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1784944ffaf9SJohnathan Mantey 
1785c21865c4SKonstantin Aladyshev     if (!bootSource)
1786491d8ee7SSantosh Puranik     {
1787c21865c4SKonstantin Aladyshev         return;
1788c21865c4SKonstantin Aladyshev     }
1789c21865c4SKonstantin Aladyshev 
1790491d8ee7SSantosh Puranik     // Source target specified
179162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1792491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1793ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1794ac106bf6SEd Tanous                              bootModeStr) != 0)
1795491d8ee7SSantosh Puranik     {
179662598e31SEd Tanous         BMCWEB_LOG_DEBUG(
179762598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
179862598e31SEd Tanous             *bootSource);
1799ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1800491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1801491d8ee7SSantosh Puranik         return;
1802491d8ee7SSantosh Puranik     }
1803491d8ee7SSantosh Puranik 
1804944ffaf9SJohnathan Mantey     // Act on validated parameters
180562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
180662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1807944ffaf9SJohnathan Mantey 
18089ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18099ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18109ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18119ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1812ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1813491d8ee7SSantosh Puranik         if (ec)
1814491d8ee7SSantosh Puranik         {
1815b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1816ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1817491d8ee7SSantosh Puranik             return;
1818491d8ee7SSantosh Puranik         }
181962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source update done.");
18209ae226faSGeorge Liu     });
1821944ffaf9SJohnathan Mantey 
18229ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18239ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18249ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18259ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1826ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1827491d8ee7SSantosh Puranik         if (ec)
1828491d8ee7SSantosh Puranik         {
1829b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1830ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1831491d8ee7SSantosh Puranik             return;
1832491d8ee7SSantosh Puranik         }
183362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode update done.");
18349ae226faSGeorge Liu     });
1835cd9a4666SKonstantin Aladyshev }
1836944ffaf9SJohnathan Mantey 
1837cd9a4666SKonstantin Aladyshev /**
1838c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1839491d8ee7SSantosh Puranik  *
1840ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1841491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1842cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1843491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1844491d8ee7SSantosh Puranik  *
1845265c1602SJohnathan Mantey  * @return Integer error code.
1846491d8ee7SSantosh Puranik  */
1847c21865c4SKonstantin Aladyshev 
1848ac106bf6SEd Tanous inline void
1849ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1850c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1851c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1852c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1853491d8ee7SSantosh Puranik {
185462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1855491d8ee7SSantosh Puranik 
1856ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1857ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1858ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1859491d8ee7SSantosh Puranik }
1860491d8ee7SSantosh Puranik 
1861c6a620f2SGeorge Liu /**
186298e386ecSGunnar Mills  * @brief Sets AssetTag
186398e386ecSGunnar Mills  *
1864ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
186598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
186698e386ecSGunnar Mills  *
186798e386ecSGunnar Mills  * @return None.
186898e386ecSGunnar Mills  */
1869ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
187098e386ecSGunnar Mills                         const std::string& assetTag)
187198e386ecSGunnar Mills {
1872e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1873e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1874e99073f5SGeorge Liu     dbus::utility::getSubTree(
1875e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1876ac106bf6SEd Tanous         [asyncResp,
1877e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1878b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
187998e386ecSGunnar Mills         if (ec)
188098e386ecSGunnar Mills         {
188162598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1882ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188398e386ecSGunnar Mills             return;
188498e386ecSGunnar Mills         }
188526f6976fSEd Tanous         if (subtree.empty())
188698e386ecSGunnar Mills         {
188762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1888ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188998e386ecSGunnar Mills             return;
189098e386ecSGunnar Mills         }
189198e386ecSGunnar Mills         // Assume only 1 system D-Bus object
189298e386ecSGunnar Mills         // Throw an error if there is more than 1
189398e386ecSGunnar Mills         if (subtree.size() > 1)
189498e386ecSGunnar Mills         {
189562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1896ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189798e386ecSGunnar Mills             return;
189898e386ecSGunnar Mills         }
189998e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
190098e386ecSGunnar Mills         {
190162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1902ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190398e386ecSGunnar Mills             return;
190498e386ecSGunnar Mills         }
190598e386ecSGunnar Mills 
190698e386ecSGunnar Mills         const std::string& path = subtree[0].first;
190798e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
190898e386ecSGunnar Mills 
190998e386ecSGunnar Mills         if (service.empty())
191098e386ecSGunnar Mills         {
191162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1912ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
191398e386ecSGunnar Mills             return;
191498e386ecSGunnar Mills         }
191598e386ecSGunnar Mills 
19169ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19179ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19189ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19199ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
192098e386ecSGunnar Mills             if (ec2)
192198e386ecSGunnar Mills             {
1922b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
192362598e31SEd Tanous                                  ec2);
1924ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
192598e386ecSGunnar Mills                 return;
192698e386ecSGunnar Mills             }
19279ae226faSGeorge Liu         });
1928e99073f5SGeorge Liu     });
192998e386ecSGunnar Mills }
193098e386ecSGunnar Mills 
193198e386ecSGunnar Mills /**
19329dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19339dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19349dcfe8c1SAlbert Zhang  *
19359dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19369dcfe8c1SAlbert Zhang  * stopBootOnFault
19379dcfe8c1SAlbert Zhang  *
19389dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19399dcfe8c1SAlbert Zhang  */
19409dcfe8c1SAlbert Zhang inline std::optional<bool>
19419dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
19429dcfe8c1SAlbert Zhang {
19439dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19449dcfe8c1SAlbert Zhang     {
19459dcfe8c1SAlbert Zhang         return true;
19469dcfe8c1SAlbert Zhang     }
19479dcfe8c1SAlbert Zhang 
19489dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19499dcfe8c1SAlbert Zhang     {
19509dcfe8c1SAlbert Zhang         return false;
19519dcfe8c1SAlbert Zhang     }
19529dcfe8c1SAlbert Zhang 
19539dcfe8c1SAlbert Zhang     return std::nullopt;
19549dcfe8c1SAlbert Zhang }
19559dcfe8c1SAlbert Zhang 
19569dcfe8c1SAlbert Zhang /**
19579dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19589dcfe8c1SAlbert Zhang  *
1959fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
19609dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19619dcfe8c1SAlbert Zhang  *
19629dcfe8c1SAlbert Zhang  * @return None.
19639dcfe8c1SAlbert Zhang  */
1964fc3edfddSEd Tanous inline void
1965fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19669dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
19679dcfe8c1SAlbert Zhang {
196862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
19699dcfe8c1SAlbert Zhang 
19709dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19719dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19729dcfe8c1SAlbert Zhang     {
197362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
197462598e31SEd Tanous                          stopBootOnFault);
1975fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19769dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19779dcfe8c1SAlbert Zhang         return;
19789dcfe8c1SAlbert Zhang     }
19799dcfe8c1SAlbert Zhang 
1980fc3edfddSEd Tanous     sdbusplus::asio::setProperty(
1981fc3edfddSEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19829dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1983fc3edfddSEd Tanous         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1984fc3edfddSEd Tanous         *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
19859dcfe8c1SAlbert Zhang         if (ec)
19869dcfe8c1SAlbert Zhang         {
19879dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19889dcfe8c1SAlbert Zhang             {
1989b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1990fc3edfddSEd Tanous                 messages::internalError(asyncResp->res);
19919dcfe8c1SAlbert Zhang             }
19929dcfe8c1SAlbert Zhang             return;
19939dcfe8c1SAlbert Zhang         }
19949dcfe8c1SAlbert Zhang     });
19959dcfe8c1SAlbert Zhang }
19969dcfe8c1SAlbert Zhang 
19979dcfe8c1SAlbert Zhang /**
199869f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
199969f35306SGunnar Mills  *
2000ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
200169f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
200269f35306SGunnar Mills  *
200369f35306SGunnar Mills  * @return None.
200469f35306SGunnar Mills  */
2005ac106bf6SEd Tanous inline void
2006ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2007f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
200869f35306SGunnar Mills {
200962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
201069f35306SGunnar Mills 
201169f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2012543f4400SEd Tanous     bool autoRebootEnabled = false;
201369f35306SGunnar Mills 
201469f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
201569f35306SGunnar Mills     {
201669f35306SGunnar Mills         autoRebootEnabled = false;
201769f35306SGunnar Mills     }
201869f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
201969f35306SGunnar Mills     {
202069f35306SGunnar Mills         autoRebootEnabled = true;
202169f35306SGunnar Mills     }
202269f35306SGunnar Mills     else
202369f35306SGunnar Mills     {
202462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
202562598e31SEd Tanous                          automaticRetryConfig);
2026ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
202769f35306SGunnar Mills                                          "AutomaticRetryConfig");
202869f35306SGunnar Mills         return;
202969f35306SGunnar Mills     }
203069f35306SGunnar Mills 
20319ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20329ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20339ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20349ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20359ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
203669f35306SGunnar Mills         if (ec)
203769f35306SGunnar Mills         {
2038b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2039ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
204069f35306SGunnar Mills             return;
204169f35306SGunnar Mills         }
20429ae226faSGeorge Liu     });
204369f35306SGunnar Mills }
204469f35306SGunnar Mills 
20458d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20468d69c668SEd Tanous {
20478d69c668SEd Tanous     if (policy == "AlwaysOn")
20488d69c668SEd Tanous     {
20498d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20508d69c668SEd Tanous     }
20518d69c668SEd Tanous     if (policy == "AlwaysOff")
20528d69c668SEd Tanous     {
20538d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20548d69c668SEd Tanous     }
20558d69c668SEd Tanous     if (policy == "LastState")
20568d69c668SEd Tanous     {
20578d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20588d69c668SEd Tanous     }
20598d69c668SEd Tanous     return "";
20608d69c668SEd Tanous }
20618d69c668SEd Tanous 
206269f35306SGunnar Mills /**
2063c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2064c6a620f2SGeorge Liu  *
2065ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2066c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2067c6a620f2SGeorge Liu  *
2068c6a620f2SGeorge Liu  * @return None.
2069c6a620f2SGeorge Liu  */
20708d1b46d7Szhanghch05 inline void
2071ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20728d69c668SEd Tanous                           std::string_view policy)
2073c6a620f2SGeorge Liu {
207462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2075c6a620f2SGeorge Liu 
20768d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2077c6a620f2SGeorge Liu 
20788d69c668SEd Tanous     if (powerRestorePolicy.empty())
2079c6a620f2SGeorge Liu     {
2080ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20814e69c904SGunnar Mills                                          "PowerRestorePolicy");
2082c6a620f2SGeorge Liu         return;
2083c6a620f2SGeorge Liu     }
2084c6a620f2SGeorge Liu 
20859ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20869ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20879ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20889ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20899ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2090c6a620f2SGeorge Liu         if (ec)
2091c6a620f2SGeorge Liu         {
2092b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2093ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2094c6a620f2SGeorge Liu             return;
2095c6a620f2SGeorge Liu         }
20969ae226faSGeorge Liu     });
2097c6a620f2SGeorge Liu }
2098c6a620f2SGeorge Liu 
2099a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2100a6349918SAppaRao Puli /**
2101a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2102a6349918SAppaRao Puli  *
2103ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2104a6349918SAppaRao Puli  *
2105a6349918SAppaRao Puli  * @return None.
2106a6349918SAppaRao Puli  */
2107ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2108a6349918SAppaRao Puli {
210962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2110bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2111bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2112bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2113ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2114b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2115b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2116ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2117ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
211850626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
211950626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
212050626f4fSJames Feist 
2121a6349918SAppaRao Puli         if (ec)
2122a6349918SAppaRao Puli         {
212362598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2124b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2125b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2126a6349918SAppaRao Puli             return;
2127a6349918SAppaRao Puli         }
2128a6349918SAppaRao Puli 
2129a6349918SAppaRao Puli         const bool* provState = nullptr;
2130a6349918SAppaRao Puli         const bool* lockState = nullptr;
2131bc1d29deSKrzysztof Grobelny 
2132bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21330d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21340d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2135bc1d29deSKrzysztof Grobelny 
2136bc1d29deSKrzysztof Grobelny         if (!success)
2137a6349918SAppaRao Puli         {
2138ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2139bc1d29deSKrzysztof Grobelny             return;
2140a6349918SAppaRao Puli         }
2141a6349918SAppaRao Puli 
2142a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2143a6349918SAppaRao Puli         {
214462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2145ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2146a6349918SAppaRao Puli             return;
2147a6349918SAppaRao Puli         }
2148a6349918SAppaRao Puli 
2149a6349918SAppaRao Puli         if (*provState == true)
2150a6349918SAppaRao Puli         {
2151a6349918SAppaRao Puli             if (*lockState == true)
2152a6349918SAppaRao Puli             {
2153a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2154a6349918SAppaRao Puli             }
2155a6349918SAppaRao Puli             else
2156a6349918SAppaRao Puli             {
2157a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2158a6349918SAppaRao Puli             }
2159a6349918SAppaRao Puli         }
2160a6349918SAppaRao Puli         else
2161a6349918SAppaRao Puli         {
2162a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2163a6349918SAppaRao Puli         }
2164bc1d29deSKrzysztof Grobelny     });
2165a6349918SAppaRao Puli }
2166a6349918SAppaRao Puli #endif
2167a6349918SAppaRao Puli 
2168491d8ee7SSantosh Puranik /**
21693a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
21703a2d0424SChris Cain  *
2171ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21723a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
21733a2d0424SChris Cain  *
21743a2d0424SChris Cain  * @return None.
21753a2d0424SChris Cain  */
2176ac106bf6SEd Tanous inline void
2177ac106bf6SEd Tanous     translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21783a2d0424SChris Cain                        const std::string& modeValue)
21793a2d0424SChris Cain {
2180*b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2181*b6655101SChris Cain 
21820fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21833a2d0424SChris Cain     {
2184*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::Static;
21853a2d0424SChris Cain     }
21860fda0f12SGeorge Liu     else if (
21870fda0f12SGeorge Liu         modeValue ==
21880fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21893a2d0424SChris Cain     {
2190*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::MaximumPerformance;
21913a2d0424SChris Cain     }
21920fda0f12SGeorge Liu     else if (modeValue ==
21930fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21943a2d0424SChris Cain     {
2195*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::PowerSaving;
2196*b6655101SChris Cain     }
2197*b6655101SChris Cain     else if (
2198*b6655101SChris Cain         modeValue ==
2199*b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2200*b6655101SChris Cain     {
2201*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::BalancedPerformance;
2202*b6655101SChris Cain     }
2203*b6655101SChris Cain     else if (
2204*b6655101SChris Cain         modeValue ==
2205*b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2206*b6655101SChris Cain     {
2207*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] =
2208*b6655101SChris Cain             PowerMode::EfficiencyFavorPerformance;
2209*b6655101SChris Cain     }
2210*b6655101SChris Cain     else if (
2211*b6655101SChris Cain         modeValue ==
2212*b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2213*b6655101SChris Cain     {
2214*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::EfficiencyFavorPower;
22153a2d0424SChris Cain     }
22160fda0f12SGeorge Liu     else if (modeValue ==
22170fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
22183a2d0424SChris Cain     {
2219*b6655101SChris Cain         asyncResp->res.jsonValue["PowerMode"] = PowerMode::OEM;
22203a2d0424SChris Cain     }
22213a2d0424SChris Cain     else
22223a2d0424SChris Cain     {
22233a2d0424SChris Cain         // Any other values would be invalid
222462598e31SEd Tanous         BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
2225ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
22263a2d0424SChris Cain     }
22273a2d0424SChris Cain }
22283a2d0424SChris Cain 
22293a2d0424SChris Cain /**
22303a2d0424SChris Cain  * @brief Retrieves system power mode
22313a2d0424SChris Cain  *
2232ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22333a2d0424SChris Cain  *
22343a2d0424SChris Cain  * @return None.
22353a2d0424SChris Cain  */
2236ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22373a2d0424SChris Cain {
223862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22393a2d0424SChris Cain 
22403a2d0424SChris Cain     // Get Power Mode object path:
2241e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2242e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2243e99073f5SGeorge Liu     dbus::utility::getSubTree(
2244e99073f5SGeorge Liu         "/", 0, interfaces,
2245ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2246b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22473a2d0424SChris Cain         if (ec)
22483a2d0424SChris Cain         {
224962598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
225062598e31SEd Tanous                              ec);
22513a2d0424SChris Cain             // This is an optional D-Bus object so just return if
22523a2d0424SChris Cain             // error occurs
22533a2d0424SChris Cain             return;
22543a2d0424SChris Cain         }
22553a2d0424SChris Cain         if (subtree.empty())
22563a2d0424SChris Cain         {
22573a2d0424SChris Cain             // As noted above, this is an optional interface so just return
22583a2d0424SChris Cain             // if there is no instance found
22593a2d0424SChris Cain             return;
22603a2d0424SChris Cain         }
22613a2d0424SChris Cain         if (subtree.size() > 1)
22623a2d0424SChris Cain         {
22633a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22643a2d0424SChris Cain             // error
226562598e31SEd Tanous             BMCWEB_LOG_DEBUG(
226662598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
226762598e31SEd Tanous                 subtree.size());
2268ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22693a2d0424SChris Cain             return;
22703a2d0424SChris Cain         }
22713a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22723a2d0424SChris Cain         {
227362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2274ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22753a2d0424SChris Cain             return;
22763a2d0424SChris Cain         }
22773a2d0424SChris Cain         const std::string& path = subtree[0].first;
22783a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22793a2d0424SChris Cain         if (service.empty())
22803a2d0424SChris Cain         {
228162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2282ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22833a2d0424SChris Cain             return;
22843a2d0424SChris Cain         }
22853a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
22861e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
22871e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22881e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2289ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22901e1e598dSJonathan Doman                         const std::string& pmode) {
22918a592810SEd Tanous             if (ec2)
22923a2d0424SChris Cain             {
2293b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}",
229462598e31SEd Tanous                                  ec2);
2295ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22963a2d0424SChris Cain                 return;
22973a2d0424SChris Cain             }
22983a2d0424SChris Cain 
2299ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2300002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
23013a2d0424SChris Cain 
230262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
2303ac106bf6SEd Tanous             translatePowerMode(asyncResp, pmode);
23041e1e598dSJonathan Doman         });
2305e99073f5SGeorge Liu     });
23063a2d0424SChris Cain }
23073a2d0424SChris Cain 
23083a2d0424SChris Cain /**
23093a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
23103a2d0424SChris Cain  * name associated with that string
23113a2d0424SChris Cain  *
2312ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2313*b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
23143a2d0424SChris Cain  *
23153a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
23163a2d0424SChris Cain  */
23173a2d0424SChris Cain inline std::string
2318ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2319*b6655101SChris Cain                       const nlohmann::json& modeValue)
23203a2d0424SChris Cain {
2321*b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
23223a2d0424SChris Cain     std::string mode;
23233a2d0424SChris Cain 
2324*b6655101SChris Cain     if (modeValue == PowerMode::Static)
23253a2d0424SChris Cain     {
23263a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
23273a2d0424SChris Cain     }
2328*b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
23293a2d0424SChris Cain     {
23300fda0f12SGeorge Liu         mode =
23310fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23323a2d0424SChris Cain     }
2333*b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
23343a2d0424SChris Cain     {
23353a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23363a2d0424SChris Cain     }
2337*b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2338*b6655101SChris Cain     {
2339*b6655101SChris Cain         mode =
2340*b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2341*b6655101SChris Cain     }
2342*b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2343*b6655101SChris Cain     {
2344*b6655101SChris Cain         mode =
2345*b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2346*b6655101SChris Cain     }
2347*b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2348*b6655101SChris Cain     {
2349*b6655101SChris Cain         mode =
2350*b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2351*b6655101SChris Cain     }
23523a2d0424SChris Cain     else
23533a2d0424SChris Cain     {
2354*b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2355ac106bf6SEd Tanous                                          "PowerMode");
23563a2d0424SChris Cain     }
23573a2d0424SChris Cain     return mode;
23583a2d0424SChris Cain }
23593a2d0424SChris Cain 
23603a2d0424SChris Cain /**
23613a2d0424SChris Cain  * @brief Sets system power mode.
23623a2d0424SChris Cain  *
2363ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23643a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23653a2d0424SChris Cain  *
23663a2d0424SChris Cain  * @return None.
23673a2d0424SChris Cain  */
2368ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23693a2d0424SChris Cain                          const std::string& pmode)
23703a2d0424SChris Cain {
237162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
23723a2d0424SChris Cain 
2373ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23743a2d0424SChris Cain     if (powerMode.empty())
23753a2d0424SChris Cain     {
23763a2d0424SChris Cain         return;
23773a2d0424SChris Cain     }
23783a2d0424SChris Cain 
23793a2d0424SChris Cain     // Get Power Mode object path:
2380e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2381e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2382e99073f5SGeorge Liu     dbus::utility::getSubTree(
2383e99073f5SGeorge Liu         "/", 0, interfaces,
2384ac106bf6SEd Tanous         [asyncResp,
2385e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2386b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23873a2d0424SChris Cain         if (ec)
23883a2d0424SChris Cain         {
2389b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
239062598e31SEd Tanous                              ec);
23913a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2392ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23933a2d0424SChris Cain             return;
23943a2d0424SChris Cain         }
23953a2d0424SChris Cain         if (subtree.empty())
23963a2d0424SChris Cain         {
23973a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2398ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23993a2d0424SChris Cain                                        "PowerMode");
24003a2d0424SChris Cain             return;
24013a2d0424SChris Cain         }
24023a2d0424SChris Cain         if (subtree.size() > 1)
24033a2d0424SChris Cain         {
24043a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
24053a2d0424SChris Cain             // error
240662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
240762598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
240862598e31SEd Tanous                 subtree.size());
2409ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24103a2d0424SChris Cain             return;
24113a2d0424SChris Cain         }
24123a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
24133a2d0424SChris Cain         {
241462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2415ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24163a2d0424SChris Cain             return;
24173a2d0424SChris Cain         }
24183a2d0424SChris Cain         const std::string& path = subtree[0].first;
24193a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
24203a2d0424SChris Cain         if (service.empty())
24213a2d0424SChris Cain         {
242262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2423ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24243a2d0424SChris Cain             return;
24253a2d0424SChris Cain         }
24263a2d0424SChris Cain 
242762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
24283a2d0424SChris Cain 
24293a2d0424SChris Cain         // Set the Power Mode property
24309ae226faSGeorge Liu         sdbusplus::asio::setProperty(
24319ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
24329ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2433ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
24348a592810SEd Tanous             if (ec2)
24353a2d0424SChris Cain             {
2436b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2437ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24383a2d0424SChris Cain                 return;
24393a2d0424SChris Cain             }
24409ae226faSGeorge Liu         });
2441e99073f5SGeorge Liu     });
24423a2d0424SChris Cain }
24433a2d0424SChris Cain 
24443a2d0424SChris Cain /**
244551709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
244651709ffdSYong Li  *
244751709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
244851709ffdSYong Li  *
244951709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
245051709ffdSYong Li  * translation cannot be done, returns an empty string.
245151709ffdSYong Li  */
245223a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
245351709ffdSYong Li {
245451709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
245551709ffdSYong Li     {
245651709ffdSYong Li         return "None";
245751709ffdSYong Li     }
24583174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
245951709ffdSYong Li     {
246051709ffdSYong Li         return "ResetSystem";
246151709ffdSYong Li     }
24623174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
246351709ffdSYong Li     {
246451709ffdSYong Li         return "PowerDown";
246551709ffdSYong Li     }
24663174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
246751709ffdSYong Li     {
246851709ffdSYong Li         return "PowerCycle";
246951709ffdSYong Li     }
247051709ffdSYong Li 
247151709ffdSYong Li     return "";
247251709ffdSYong Li }
247351709ffdSYong Li 
247451709ffdSYong Li /**
2475c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2476c45f0082SYong Li  *
2477c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2478c45f0082SYong Li  *
2479c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2480c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2481c45f0082SYong Li  */
2482c45f0082SYong Li 
248323a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2484c45f0082SYong Li {
2485c45f0082SYong Li     if (rfAction == "None")
2486c45f0082SYong Li     {
2487c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2488c45f0082SYong Li     }
24893174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2490c45f0082SYong Li     {
2491c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2492c45f0082SYong Li     }
24933174e4dfSEd Tanous     if (rfAction == "PowerDown")
2494c45f0082SYong Li     {
2495c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2496c45f0082SYong Li     }
24973174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2498c45f0082SYong Li     {
2499c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2500c45f0082SYong Li     }
2501c45f0082SYong Li 
2502c45f0082SYong Li     return "";
2503c45f0082SYong Li }
2504c45f0082SYong Li 
2505c45f0082SYong Li /**
250651709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
250751709ffdSYong Li  *
2508ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
250951709ffdSYong Li  *
251051709ffdSYong Li  * @return None.
251151709ffdSYong Li  */
25128d1b46d7Szhanghch05 inline void
2513ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
251451709ffdSYong Li {
251562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2516bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2517bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2518bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2519bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2520ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2521b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
252251709ffdSYong Li         if (ec)
252351709ffdSYong Li         {
252451709ffdSYong Li             // watchdog service is stopped
252562598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
252651709ffdSYong Li             return;
252751709ffdSYong Li         }
252851709ffdSYong Li 
252962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
253051709ffdSYong Li 
253151709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2532ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
253351709ffdSYong Li 
253451709ffdSYong Li         // watchdog service is running/enabled
253551709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
253651709ffdSYong Li 
2537bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2538bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
253951709ffdSYong Li 
2540bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2541bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2542bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2543bc1d29deSKrzysztof Grobelny 
2544bc1d29deSKrzysztof Grobelny         if (!success)
254551709ffdSYong Li         {
2546ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2547601af5edSChicago Duan             return;
254851709ffdSYong Li         }
254951709ffdSYong Li 
2550bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
255151709ffdSYong Li         {
2552bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
255351709ffdSYong Li         }
255451709ffdSYong Li 
2555bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2556bc1d29deSKrzysztof Grobelny         {
2557bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
255851709ffdSYong Li             if (action.empty())
255951709ffdSYong Li             {
2560ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2561601af5edSChicago Duan                 return;
256251709ffdSYong Li             }
256351709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
256451709ffdSYong Li         }
2565bc1d29deSKrzysztof Grobelny     });
256651709ffdSYong Li }
256751709ffdSYong Li 
256851709ffdSYong Li /**
2569c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2570c45f0082SYong Li  *
2571ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2572c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2573c45f0082SYong Li  *                       RF request.
2574c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2575c45f0082SYong Li  *
2576c45f0082SYong Li  * @return None.
2577c45f0082SYong Li  */
2578ac106bf6SEd Tanous inline void
2579ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2580c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2581c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2582c45f0082SYong Li {
258362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2584c45f0082SYong Li 
2585c45f0082SYong Li     if (wdtTimeOutAction)
2586c45f0082SYong Li     {
2587c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2588c45f0082SYong Li         // check if TimeOut Action is Valid
2589c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2590c45f0082SYong Li         {
259162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
259262598e31SEd Tanous                              *wdtTimeOutAction);
2593ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2594c45f0082SYong Li                                              "TimeoutAction");
2595c45f0082SYong Li             return;
2596c45f0082SYong Li         }
2597c45f0082SYong Li 
25989ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25999ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26009ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26019ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
26029ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2603c45f0082SYong Li             if (ec)
2604c45f0082SYong Li             {
2605b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2606ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2607c45f0082SYong Li                 return;
2608c45f0082SYong Li             }
26099ae226faSGeorge Liu         });
2610c45f0082SYong Li     }
2611c45f0082SYong Li 
2612c45f0082SYong Li     if (wdtEnable)
2613c45f0082SYong Li     {
26149ae226faSGeorge Liu         sdbusplus::asio::setProperty(
26159ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26169ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26179ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2618ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2619c45f0082SYong Li             if (ec)
2620c45f0082SYong Li             {
2621b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2622ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2623c45f0082SYong Li                 return;
2624c45f0082SYong Li             }
26259ae226faSGeorge Liu         });
2626c45f0082SYong Li     }
2627c45f0082SYong Li }
2628c45f0082SYong Li 
262937bbf98cSChris Cain /**
263037bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
263137bbf98cSChris Cain  *
2632ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
263337bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
263437bbf98cSChris Cain  *
263537bbf98cSChris Cain  * @return true if successful
263637bbf98cSChris Cain  */
26371e5b7c88SJiaqing Zhao inline bool
2638ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26391e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
264037bbf98cSChris Cain {
2641bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2642bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2643bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2644bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2645bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2646bc1d29deSKrzysztof Grobelny 
2647bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2648bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26492661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26502661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26512661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2652bc1d29deSKrzysztof Grobelny 
2653bc1d29deSKrzysztof Grobelny     if (!success)
265437bbf98cSChris Cain     {
265537bbf98cSChris Cain         return false;
265637bbf98cSChris Cain     }
2657bc1d29deSKrzysztof Grobelny 
2658bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
265937bbf98cSChris Cain     {
2660ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
266137bbf98cSChris Cain     }
2662bc1d29deSKrzysztof Grobelny 
2663bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
266437bbf98cSChris Cain     {
2665ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2666bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
266737bbf98cSChris Cain     }
2668bc1d29deSKrzysztof Grobelny 
2669bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2670bc1d29deSKrzysztof Grobelny     {
2671bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2672ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
267337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
267437bbf98cSChris Cain                 .count();
267537bbf98cSChris Cain     }
2676bc1d29deSKrzysztof Grobelny 
2677bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
267837bbf98cSChris Cain     {
2679ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2680bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
268137bbf98cSChris Cain     }
2682bc1d29deSKrzysztof Grobelny 
2683bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
268437bbf98cSChris Cain     {
2685bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2686ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
268737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
268837bbf98cSChris Cain                 .count();
268937bbf98cSChris Cain     }
269037bbf98cSChris Cain 
269137bbf98cSChris Cain     return true;
269237bbf98cSChris Cain }
269337bbf98cSChris Cain 
269437bbf98cSChris Cain /**
269537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
269637bbf98cSChris Cain  *
2697ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
269837bbf98cSChris Cain  *
269937bbf98cSChris Cain  * @return None.
270037bbf98cSChris Cain  */
2701ac106bf6SEd Tanous inline void
2702ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
270337bbf98cSChris Cain {
270462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
270537bbf98cSChris Cain 
270637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2707e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2708e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2709e99073f5SGeorge Liu     dbus::utility::getSubTree(
2710e99073f5SGeorge Liu         "/", 0, interfaces,
2711ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2712b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
271337bbf98cSChris Cain         if (ec)
271437bbf98cSChris Cain         {
2715b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
271662598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
271762598e31SEd Tanous                 ec);
2718ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
271937bbf98cSChris Cain             return;
272037bbf98cSChris Cain         }
272137bbf98cSChris Cain         if (subtree.empty())
272237bbf98cSChris Cain         {
272337bbf98cSChris Cain             // This is an optional interface so just return
272437bbf98cSChris Cain             // if there is no instance found
272562598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
272637bbf98cSChris Cain             return;
272737bbf98cSChris Cain         }
272837bbf98cSChris Cain         if (subtree.size() > 1)
272937bbf98cSChris Cain         {
273037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
273137bbf98cSChris Cain             // is an error
273262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
273362598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
273462598e31SEd Tanous                              subtree.size());
2735ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
273637bbf98cSChris Cain             return;
273737bbf98cSChris Cain         }
273837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
273937bbf98cSChris Cain         {
274062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2741ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
274237bbf98cSChris Cain             return;
274337bbf98cSChris Cain         }
274437bbf98cSChris Cain         const std::string& path = subtree[0].first;
274537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
274637bbf98cSChris Cain         if (service.empty())
274737bbf98cSChris Cain         {
274862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2749ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
275037bbf98cSChris Cain             return;
275137bbf98cSChris Cain         }
275237bbf98cSChris Cain 
275337bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2754bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2755bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2756bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2757ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27581e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27598a592810SEd Tanous             if (ec2)
276037bbf98cSChris Cain             {
276162598e31SEd Tanous                 BMCWEB_LOG_ERROR(
276262598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2763ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
276437bbf98cSChris Cain                 return;
276537bbf98cSChris Cain             }
276637bbf98cSChris Cain 
2767ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
276837bbf98cSChris Cain             {
2769ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
277037bbf98cSChris Cain                 return;
277137bbf98cSChris Cain             }
2772bc1d29deSKrzysztof Grobelny         });
2773e99073f5SGeorge Liu     });
277437bbf98cSChris Cain 
277562598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
277637bbf98cSChris Cain }
277737bbf98cSChris Cain 
277837bbf98cSChris Cain /**
277937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
278037bbf98cSChris Cain  *
2781ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
278237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
278337bbf98cSChris Cain  *                       RF request.
278437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
278537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
278637bbf98cSChris Cain  * before entering idle state.
278737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
278837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
278937bbf98cSChris Cain  * before exiting idle state
279037bbf98cSChris Cain  *
279137bbf98cSChris Cain  * @return None.
279237bbf98cSChris Cain  */
2793ac106bf6SEd Tanous inline void
2794ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
279537bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
279637bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
279737bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
279837bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
279937bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
280037bbf98cSChris Cain {
280162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
280237bbf98cSChris Cain 
280337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2804e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2805e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2806e99073f5SGeorge Liu     dbus::utility::getSubTree(
2807e99073f5SGeorge Liu         "/", 0, interfaces,
2808ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2809e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2810b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
281137bbf98cSChris Cain         if (ec)
281237bbf98cSChris Cain         {
2813b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
281462598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
281562598e31SEd Tanous                 ec);
2816ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
281737bbf98cSChris Cain             return;
281837bbf98cSChris Cain         }
281937bbf98cSChris Cain         if (subtree.empty())
282037bbf98cSChris Cain         {
282137bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2822ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
282337bbf98cSChris Cain                                        "IdlePowerSaver");
282437bbf98cSChris Cain             return;
282537bbf98cSChris Cain         }
282637bbf98cSChris Cain         if (subtree.size() > 1)
282737bbf98cSChris Cain         {
282837bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
282937bbf98cSChris Cain             // is an error
283062598e31SEd Tanous             BMCWEB_LOG_DEBUG(
283162598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
283262598e31SEd Tanous                 subtree.size());
2833ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
283437bbf98cSChris Cain             return;
283537bbf98cSChris Cain         }
283637bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
283737bbf98cSChris Cain         {
283862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2839ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
284037bbf98cSChris Cain             return;
284137bbf98cSChris Cain         }
284237bbf98cSChris Cain         const std::string& path = subtree[0].first;
284337bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
284437bbf98cSChris Cain         if (service.empty())
284537bbf98cSChris Cain         {
284662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2847ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
284837bbf98cSChris Cain             return;
284937bbf98cSChris Cain         }
285037bbf98cSChris Cain 
285137bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
285237bbf98cSChris Cain         // need to be updated
285337bbf98cSChris Cain 
285437bbf98cSChris Cain         if (ipsEnable)
285537bbf98cSChris Cain         {
28569ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28579ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28589ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28599ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28608a592810SEd Tanous                 if (ec2)
286137bbf98cSChris Cain                 {
2862b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2863ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
286437bbf98cSChris Cain                     return;
286537bbf98cSChris Cain                 }
28669ae226faSGeorge Liu             });
286737bbf98cSChris Cain         }
286837bbf98cSChris Cain         if (ipsEnterUtil)
286937bbf98cSChris Cain         {
28709ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28719ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28729ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28739ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2874ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28758a592810SEd Tanous                 if (ec2)
287637bbf98cSChris Cain                 {
2877b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2878ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
287937bbf98cSChris Cain                     return;
288037bbf98cSChris Cain                 }
28819ae226faSGeorge Liu             });
288237bbf98cSChris Cain         }
288337bbf98cSChris Cain         if (ipsEnterTime)
288437bbf98cSChris Cain         {
288537bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
288637bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
28879ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28889ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28899ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28909ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2891ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28928a592810SEd Tanous                 if (ec2)
289337bbf98cSChris Cain                 {
2894b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2895ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
289637bbf98cSChris Cain                     return;
289737bbf98cSChris Cain                 }
28989ae226faSGeorge Liu             });
289937bbf98cSChris Cain         }
290037bbf98cSChris Cain         if (ipsExitUtil)
290137bbf98cSChris Cain         {
29029ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29039ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29049ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29059ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2906ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29078a592810SEd Tanous                 if (ec2)
290837bbf98cSChris Cain                 {
2909b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2910ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
291137bbf98cSChris Cain                     return;
291237bbf98cSChris Cain                 }
29139ae226faSGeorge Liu             });
291437bbf98cSChris Cain         }
291537bbf98cSChris Cain         if (ipsExitTime)
291637bbf98cSChris Cain         {
291737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
291837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
29199ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29209ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29219ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29229ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2923ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29248a592810SEd Tanous                 if (ec2)
292537bbf98cSChris Cain                 {
2926b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2927ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
292837bbf98cSChris Cain                     return;
292937bbf98cSChris Cain                 }
29309ae226faSGeorge Liu             });
293137bbf98cSChris Cain         }
2932e99073f5SGeorge Liu     });
293337bbf98cSChris Cain 
293462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
293537bbf98cSChris Cain }
293637bbf98cSChris Cain 
2937c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2938dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2939dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2940dd60b9edSEd Tanous {
2941dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2942dd60b9edSEd Tanous     {
2943dd60b9edSEd Tanous         return;
2944dd60b9edSEd Tanous     }
2945dd60b9edSEd Tanous     asyncResp->res.addHeader(
2946dd60b9edSEd Tanous         boost::beast::http::field::link,
2947dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2948dd60b9edSEd Tanous }
2949dd60b9edSEd Tanous 
2950c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2951c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2952c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29531abe55efSEd Tanous {
29543ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2955f4c99e70SEd Tanous     {
2956f4c99e70SEd Tanous         return;
2957f4c99e70SEd Tanous     }
2958dd60b9edSEd Tanous 
2959dd60b9edSEd Tanous     asyncResp->res.addHeader(
2960dd60b9edSEd Tanous         boost::beast::http::field::link,
2961dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29628d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29630f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29648d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29658d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2966462023adSSunitha Harish 
29677f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
29687f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
29697f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29707f3e84a1SEd Tanous     {
29717f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
29727f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29737f3e84a1SEd Tanous         return;
29747f3e84a1SEd Tanous     }
29757f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
29767f3e84a1SEd Tanous     nlohmann::json::object_t system;
29777f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
29787f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
29791e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2980002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
29811e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2982002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
29835e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
29841e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
29857f3e84a1SEd Tanous         if (ec2)
2986462023adSSunitha Harish         {
29877f3e84a1SEd Tanous             return;
29887f3e84a1SEd Tanous         }
29897f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
29907f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
29917f3e84a1SEd Tanous         {
299262598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29937f3e84a1SEd Tanous             return;
29947f3e84a1SEd Tanous         }
29957f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
29967f3e84a1SEd Tanous         if (count == nullptr)
29977f3e84a1SEd Tanous         {
299862598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29997f3e84a1SEd Tanous             return;
30007f3e84a1SEd Tanous         }
30017f3e84a1SEd Tanous         *count = *count + 1;
300262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
30037f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
30041476687dSEd Tanous         nlohmann::json::object_t hypervisor;
3005002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
30067f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
30071e1e598dSJonathan Doman     });
3008c1e219d5SEd Tanous }
3009c1e219d5SEd Tanous 
3010c1e219d5SEd Tanous /**
30117e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
30127e860f15SJohn Edward Broadbent  */
30134f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
30147e860f15SJohn Edward Broadbent {
301589492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
301689492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
301789492a15SPatrick Williams     constexpr const char* interfaceName =
30187e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
301989492a15SPatrick Williams     constexpr const char* method = "NMI";
30207e860f15SJohn Edward Broadbent 
30217e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
30225e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
30237e860f15SJohn Edward Broadbent         if (ec)
30247e860f15SJohn Edward Broadbent         {
302562598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
30267e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
30277e860f15SJohn Edward Broadbent             return;
30287e860f15SJohn Edward Broadbent         }
30297e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
30307e860f15SJohn Edward Broadbent     },
30317e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
30327e860f15SJohn Edward Broadbent }
3033c5b2abe0SLewanczyk, Dawid 
3034c5b2abe0SLewanczyk, Dawid /**
3035fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
3036fc903b3dSAndrew Geissler  */
3037fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
3038fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
3039fc903b3dSAndrew Geissler                                          std::string_view resetType,
3040fc903b3dSAndrew Geissler                                          crow::Response& res)
3041fc903b3dSAndrew Geissler {
3042fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
3043fc903b3dSAndrew Geissler     {
3044fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
3045fc903b3dSAndrew Geissler         return;
3046fc903b3dSAndrew Geissler     }
3047fc903b3dSAndrew Geissler 
3048fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3049fc903b3dSAndrew Geissler     {
305062598e31SEd Tanous         BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
3051fc903b3dSAndrew Geissler         messages::internalError(res);
3052fc903b3dSAndrew Geissler         return;
3053fc903b3dSAndrew Geissler     }
3054fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3055fc903b3dSAndrew Geissler 
3056fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3057fc903b3dSAndrew Geissler     // user to retry in a bit
3058fc903b3dSAndrew Geissler     if ((errorMessage ==
3059fc903b3dSAndrew Geissler          std::string_view(
3060fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3061fc903b3dSAndrew Geissler         (errorMessage ==
3062fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3063fc903b3dSAndrew Geissler     {
306462598e31SEd Tanous         BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
3065fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3066fc903b3dSAndrew Geissler         return;
3067fc903b3dSAndrew Geissler     }
3068fc903b3dSAndrew Geissler 
306962598e31SEd Tanous     BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
307062598e31SEd Tanous                      errorMessage);
3071fc903b3dSAndrew Geissler     messages::internalError(res);
3072fc903b3dSAndrew Geissler }
3073fc903b3dSAndrew Geissler 
3074c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3075c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
30767f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3077c1e219d5SEd Tanous     const std::string& systemName)
3078c1e219d5SEd Tanous {
30793ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
308045ca1b86SEd Tanous     {
308145ca1b86SEd Tanous         return;
308245ca1b86SEd Tanous     }
3083c1e219d5SEd Tanous     if (systemName != "system")
3084c1e219d5SEd Tanous     {
3085c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3086c1e219d5SEd Tanous                                    systemName);
3087c1e219d5SEd Tanous         return;
3088c1e219d5SEd Tanous     }
30897f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30907f3e84a1SEd Tanous     {
30917f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30927f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3093c1e219d5SEd Tanous                                    systemName);
30947f3e84a1SEd Tanous         return;
30957f3e84a1SEd Tanous     }
30969712f8acSEd Tanous     std::string resetType;
3097c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3098cc340dd9SEd Tanous     {
3099cc340dd9SEd Tanous         return;
3100cc340dd9SEd Tanous     }
3101cc340dd9SEd Tanous 
3102d22c8396SJason M. Bills     // Get the command and host vs. chassis
3103cc340dd9SEd Tanous     std::string command;
3104543f4400SEd Tanous     bool hostCommand = true;
3105d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3106cc340dd9SEd Tanous     {
3107cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3108d22c8396SJason M. Bills         hostCommand = true;
3109d22c8396SJason M. Bills     }
3110d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3111d22c8396SJason M. Bills     {
3112d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3113d22c8396SJason M. Bills         hostCommand = false;
3114d22c8396SJason M. Bills     }
3115d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3116d22c8396SJason M. Bills     {
3117c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
311886a0851aSJason M. Bills         hostCommand = true;
3119cc340dd9SEd Tanous     }
31209712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3121cc340dd9SEd Tanous     {
3122cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3123d22c8396SJason M. Bills         hostCommand = true;
3124cc340dd9SEd Tanous     }
31259712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3126cc340dd9SEd Tanous     {
31270fda0f12SGeorge Liu         command =
31280fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3129d22c8396SJason M. Bills         hostCommand = true;
3130d22c8396SJason M. Bills     }
3131d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3132d22c8396SJason M. Bills     {
313386a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
313486a0851aSJason M. Bills         hostCommand = true;
3135cc340dd9SEd Tanous     }
3136bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3137bfd5b826SLakshminarayana R. Kammath     {
3138bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3139bfd5b826SLakshminarayana R. Kammath         return;
3140bfd5b826SLakshminarayana R. Kammath     }
3141cc340dd9SEd Tanous     else
3142cc340dd9SEd Tanous     {
3143c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3144cc340dd9SEd Tanous         return;
3145cc340dd9SEd Tanous     }
3146cc340dd9SEd Tanous 
3147d22c8396SJason M. Bills     if (hostCommand)
3148d22c8396SJason M. Bills     {
31499ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31509ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31519ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31529ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31539ae226faSGeorge Liu             command,
3154fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3155fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3156cc340dd9SEd Tanous             if (ec)
3157cc340dd9SEd Tanous             {
3158fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3159fc903b3dSAndrew Geissler                                              asyncResp->res);
3160fc903b3dSAndrew Geissler 
3161cc340dd9SEd Tanous                 return;
3162cc340dd9SEd Tanous             }
3163f12894f8SJason M. Bills             messages::success(asyncResp->res);
31649ae226faSGeorge Liu         });
3165cc340dd9SEd Tanous     }
3166d22c8396SJason M. Bills     else
3167d22c8396SJason M. Bills     {
31689ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31699ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
31709ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
31719ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
31729ae226faSGeorge Liu             command,
3173fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3174fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3175d22c8396SJason M. Bills             if (ec)
3176d22c8396SJason M. Bills             {
3177fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3178fc903b3dSAndrew Geissler                                              asyncResp->res);
3179d22c8396SJason M. Bills                 return;
3180d22c8396SJason M. Bills             }
3181d22c8396SJason M. Bills             messages::success(asyncResp->res);
31829ae226faSGeorge Liu         });
3183d22c8396SJason M. Bills     }
3184d22c8396SJason M. Bills }
3185cc340dd9SEd Tanous 
3186c1e219d5SEd Tanous inline void handleComputerSystemHead(
3187dd60b9edSEd Tanous     App& app, const crow::Request& req,
31887f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31897f3e84a1SEd Tanous     const std::string& /*systemName*/)
3190dd60b9edSEd Tanous {
3191dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3192dd60b9edSEd Tanous     {
3193dd60b9edSEd Tanous         return;
3194dd60b9edSEd Tanous     }
3195dd60b9edSEd Tanous 
3196dd60b9edSEd Tanous     asyncResp->res.addHeader(
3197dd60b9edSEd Tanous         boost::beast::http::field::link,
3198dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3199dd60b9edSEd Tanous }
3200dd60b9edSEd Tanous 
32015c3e9272SAbhishek Patel inline void afterPortRequest(
32025c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32035c3e9272SAbhishek Patel     const boost::system::error_code& ec,
32045c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
32055c3e9272SAbhishek Patel {
32065c3e9272SAbhishek Patel     if (ec)
32075c3e9272SAbhishek Patel     {
3208b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
32095c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
32105c3e9272SAbhishek Patel         return;
32115c3e9272SAbhishek Patel     }
32125c3e9272SAbhishek Patel     for (const auto& data : socketData)
32135c3e9272SAbhishek Patel     {
32145c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
32155c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
32165c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
32175c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
32185c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
32195c3e9272SAbhishek Patel         // need to retrieve port number for
32205c3e9272SAbhishek Patel         // obmc-console-ssh service
32215c3e9272SAbhishek Patel         if (protocolName == "SSH")
32225c3e9272SAbhishek Patel         {
32235c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
322481c4e330SEd Tanous                                           const boost::system::error_code& ec1,
32255c3e9272SAbhishek Patel                                           int portNumber) {
32265c3e9272SAbhishek Patel                 if (ec1)
32275c3e9272SAbhishek Patel                 {
3228b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
32295c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
32305c3e9272SAbhishek Patel                     return;
32315c3e9272SAbhishek Patel                 }
32325c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
32335c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
32345c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
32355c3e9272SAbhishek Patel             });
32365c3e9272SAbhishek Patel         }
32375c3e9272SAbhishek Patel     }
32385c3e9272SAbhishek Patel }
3239c1e219d5SEd Tanous 
3240c1e219d5SEd Tanous inline void
3241c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
324222d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3243c1e219d5SEd Tanous                             const std::string& systemName)
3244c1e219d5SEd Tanous {
32453ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
324645ca1b86SEd Tanous     {
324745ca1b86SEd Tanous         return;
324845ca1b86SEd Tanous     }
3249746b56f3SAsmitha Karunanithi 
32507f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32517f3e84a1SEd Tanous     {
32527f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32537f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32547f3e84a1SEd Tanous                                    systemName);
32557f3e84a1SEd Tanous         return;
32567f3e84a1SEd Tanous     }
32577f3e84a1SEd Tanous 
3258746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3259746b56f3SAsmitha Karunanithi     {
3260746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3261746b56f3SAsmitha Karunanithi         return;
3262746b56f3SAsmitha Karunanithi     }
3263746b56f3SAsmitha Karunanithi 
326422d268cbSEd Tanous     if (systemName != "system")
326522d268cbSEd Tanous     {
326622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
326722d268cbSEd Tanous                                    systemName);
326822d268cbSEd Tanous         return;
326922d268cbSEd Tanous     }
3270dd60b9edSEd Tanous     asyncResp->res.addHeader(
3271dd60b9edSEd Tanous         boost::beast::http::field::link,
3272dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
32738d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3274*b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
32758d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
32768d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
32778d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
32788d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
32798d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
32805fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
32815fd0aafbSNinad Palsule     {
32828d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
32838d1b46d7Szhanghch05             "Disabled";
32848d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
32858d1b46d7Szhanghch05             "Disabled";
32865fd0aafbSNinad Palsule     }
3287cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3288dfb2b408SPriyanga Ramasamy         double(0);
3289002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
329004a258f4SEd Tanous 
32911476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
32921476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
32931476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
32941476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
32951476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
32961476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
32973179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
32983179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3299029573d4SEd Tanous 
3300002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
33011476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3302c1e219d5SEd Tanous     asyncResp->res
3303c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
33041476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3305c5b2abe0SLewanczyk, Dawid 
33061476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
33071476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
33081476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
33091476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3310c4bf6374SJason M. Bills 
33111476687dSEd Tanous     nlohmann::json::array_t managedBy;
33121476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
33131476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3314002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
33151476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
33161476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
33170e8ac5e7SGunnar Mills 
33180e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3319002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3320c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
33211476687dSEd Tanous 
3322c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
33231476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3324c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
33251476687dSEd Tanous         "Press ~. to exit console";
33265c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
33275c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
33280e8ac5e7SGunnar Mills 
33290e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
33300e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3331002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3332c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3333613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3334613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
33351476687dSEd Tanous 
33360e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
333713451e39SWilly Tu 
333813451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
333913451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
334013451e39SWilly Tu     {
33417a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3342b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
33432ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3344e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3345e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3346b49ac873SJames Feist 
33477a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
33487a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33497a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3350914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3351b49ac873SJames Feist             if (ec)
3352b49ac873SJames Feist             {
3353b49ac873SJames Feist                 // no inventory
3354b49ac873SJames Feist                 return;
3355b49ac873SJames Feist             }
3356b49ac873SJames Feist 
3357914e2d5dSEd Tanous             health->inventory = resp;
33587a1dbc48SGeorge Liu         });
3359b49ac873SJames Feist         health->populate();
336013451e39SWilly Tu     }
3361b49ac873SJames Feist 
3362002d39b4SEd Tanous     getMainChassisId(asyncResp,
3363002d39b4SEd Tanous                      [](const std::string& chassisId,
33648d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3365b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3366b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3367ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3368ef4c65b7SEd Tanous                                                    chassisId);
3369002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3370c5d03ff4SJennifer Lee     });
3371a3002228SAppaRao Puli 
337259a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
33739f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3374a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
33755bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
33766c34de48SEd Tanous     getHostState(asyncResp);
3377491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3378978b8803SAndrew Geissler     getBootProgress(asyncResp);
3379b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
338070c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
338170c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
338251709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3383c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
33849dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3385797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3386c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3387a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3388a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3389a6349918SAppaRao Puli #endif
33901981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
33913a2d0424SChris Cain     getPowerMode(asyncResp);
339237bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3393c1e219d5SEd Tanous }
3394550a6bf8SJiaqing Zhao 
3395c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3396c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
339722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3398c1e219d5SEd Tanous     const std::string& systemName)
3399c1e219d5SEd Tanous {
34003ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
340145ca1b86SEd Tanous     {
340245ca1b86SEd Tanous         return;
340345ca1b86SEd Tanous     }
34047f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
34057f3e84a1SEd Tanous     {
34067f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34077f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34087f3e84a1SEd Tanous                                    systemName);
34097f3e84a1SEd Tanous         return;
34107f3e84a1SEd Tanous     }
341122d268cbSEd Tanous     if (systemName != "system")
341222d268cbSEd Tanous     {
341322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
341422d268cbSEd Tanous                                    systemName);
341522d268cbSEd Tanous         return;
341622d268cbSEd Tanous     }
341722d268cbSEd Tanous 
3418dd60b9edSEd Tanous     asyncResp->res.addHeader(
3419dd60b9edSEd Tanous         boost::beast::http::field::link,
3420dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3421dd60b9edSEd Tanous 
34229f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3423cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
342498e386ecSGunnar Mills     std::optional<std::string> assetTag;
3425c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
34263a2d0424SChris Cain     std::optional<std::string> powerMode;
3427550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3428550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3429550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3430550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3431550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3432550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3433797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3434550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
34359dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3436550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3437550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3438550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3439550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3440550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3441550a6bf8SJiaqing Zhao 
3442550a6bf8SJiaqing Zhao     // clang-format off
344315ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3444550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3445550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
34467e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3447550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3448550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3449550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3450550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3451550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3452550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3453550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3454550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3455550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3456797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3457550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
34589dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3459550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3460550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3461550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3462550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3463550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
34646617338dSEd Tanous                 {
34656617338dSEd Tanous                     return;
34666617338dSEd Tanous                 }
3467550a6bf8SJiaqing Zhao     // clang-format on
3468491d8ee7SSantosh Puranik 
34698d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3470c45f0082SYong Li 
347198e386ecSGunnar Mills     if (assetTag)
347298e386ecSGunnar Mills     {
347398e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
347498e386ecSGunnar Mills     }
347598e386ecSGunnar Mills 
3476550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3477c45f0082SYong Li     {
3478f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3479c45f0082SYong Li     }
3480c45f0082SYong Li 
3481cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
348269f35306SGunnar Mills     {
3483002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3484491d8ee7SSantosh Puranik     }
3485550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
348669f35306SGunnar Mills     {
3487550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
348869f35306SGunnar Mills     }
3489ac7e1e0bSAli Ahmed 
3490797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3491797d5daeSCorey Hardesty     {
3492797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3493797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3494797d5daeSCorey Hardesty     }
3495797d5daeSCorey Hardesty 
3496550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3497ac7e1e0bSAli Ahmed     {
3498c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
349969f35306SGunnar Mills     }
3500265c1602SJohnathan Mantey 
35019dcfe8c1SAlbert Zhang     if (stopBootOnFault)
35029dcfe8c1SAlbert Zhang     {
35039dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
35049dcfe8c1SAlbert Zhang     }
35059dcfe8c1SAlbert Zhang 
35069f8bfa7cSGunnar Mills     if (locationIndicatorActive)
35079f8bfa7cSGunnar Mills     {
350859a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
35099f8bfa7cSGunnar Mills     }
35109f8bfa7cSGunnar Mills 
35117e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
35127e860f15SJohn Edward Broadbent     // passed
35139712f8acSEd Tanous     if (indicatorLed)
35146617338dSEd Tanous     {
3515f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3516002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3517d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3518d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
35196617338dSEd Tanous     }
3520c6a620f2SGeorge Liu 
3521c6a620f2SGeorge Liu     if (powerRestorePolicy)
3522c6a620f2SGeorge Liu     {
35234e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3524c6a620f2SGeorge Liu     }
35253a2d0424SChris Cain 
35263a2d0424SChris Cain     if (powerMode)
35273a2d0424SChris Cain     {
35283a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
35293a2d0424SChris Cain     }
353037bbf98cSChris Cain 
3531c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
353237bbf98cSChris Cain     {
3533002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3534002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
353537bbf98cSChris Cain     }
3536c1e219d5SEd Tanous }
35371cb1a9e6SAppaRao Puli 
353838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3539dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
35407f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3541c1e219d5SEd Tanous     const std::string& /*systemName*/)
3542dd60b9edSEd Tanous {
3543dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3544dd60b9edSEd Tanous     {
3545dd60b9edSEd Tanous         return;
3546dd60b9edSEd Tanous     }
3547dd60b9edSEd Tanous     asyncResp->res.addHeader(
3548dd60b9edSEd Tanous         boost::beast::http::field::link,
3549dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3550dd60b9edSEd Tanous }
3551c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3552c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
355322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3554c1e219d5SEd Tanous     const std::string& systemName)
3555c1e219d5SEd Tanous {
35563ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
355745ca1b86SEd Tanous     {
355845ca1b86SEd Tanous         return;
355945ca1b86SEd Tanous     }
35607f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35617f3e84a1SEd Tanous     {
35627f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
35637f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
35647f3e84a1SEd Tanous                                    systemName);
35657f3e84a1SEd Tanous         return;
35667f3e84a1SEd Tanous     }
3567746b56f3SAsmitha Karunanithi 
3568746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3569746b56f3SAsmitha Karunanithi     {
3570746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3571746b56f3SAsmitha Karunanithi         return;
3572746b56f3SAsmitha Karunanithi     }
3573746b56f3SAsmitha Karunanithi 
357422d268cbSEd Tanous     if (systemName != "system")
357522d268cbSEd Tanous     {
357622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
357722d268cbSEd Tanous                                    systemName);
357822d268cbSEd Tanous         return;
357922d268cbSEd Tanous     }
358022d268cbSEd Tanous 
3581dd60b9edSEd Tanous     asyncResp->res.addHeader(
3582dd60b9edSEd Tanous         boost::beast::http::field::link,
3583dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35841476687dSEd Tanous 
35851476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
35861476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3587c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35881476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35891476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35903215e700SNan Zhou 
35913215e700SNan Zhou     nlohmann::json::array_t parameters;
35923215e700SNan Zhou     nlohmann::json::object_t parameter;
35933215e700SNan Zhou 
35943215e700SNan Zhou     parameter["Name"] = "ResetType";
35953215e700SNan Zhou     parameter["Required"] = true;
35963215e700SNan Zhou     parameter["DataType"] = "String";
35973215e700SNan Zhou     nlohmann::json::array_t allowableValues;
35983215e700SNan Zhou     allowableValues.emplace_back("On");
35993215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
36003215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
36013215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
36023215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
36033215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
36043215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
36053215e700SNan Zhou     allowableValues.emplace_back("Nmi");
36063215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
36073215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
36083215e700SNan Zhou 
36093215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3610c1e219d5SEd Tanous }
3611c1e219d5SEd Tanous /**
3612c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3613c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3614c1e219d5SEd Tanous  */
3615100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3616c1e219d5SEd Tanous {
3617100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3618100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3619100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3620100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3621100afe56SEd Tanous 
3622100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3623100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3624100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3625100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3626100afe56SEd Tanous 
3627100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3628100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3629100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3630100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3631100afe56SEd Tanous 
3632100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3633100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3634100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3635100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3636100afe56SEd Tanous 
3637100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3638100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3639100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3640100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3641100afe56SEd Tanous 
3642100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3643100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3644100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3645100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3646100afe56SEd Tanous 
3647c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3648c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3649c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3650c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3651c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3652c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3653c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3654c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36551cb1a9e6SAppaRao Puli }
3656c5b2abe0SLewanczyk, Dawid } // namespace redfish
3657