xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision c1e219d5ca712e6179c2c0b2d1bab7fc026019aa)
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"
23b49ac873SJames Feist #include "health.hpp"
24746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
251c8fba97SJames Feist #include "led.hpp"
26f4c99e70SEd Tanous #include "query.hpp"
27c5d03ff4SJennifer Lee #include "redfish_util.hpp"
283ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
293ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
303ccb3adbSEd Tanous #include "utils/json_utils.hpp"
31472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
323ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
332b82937eSEd Tanous #include "utils/time_utils.hpp"
34c5d03ff4SJennifer Lee 
35fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
369712f8acSEd Tanous #include <boost/container/flat_map.hpp>
37e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
38ef4c65b7SEd Tanous #include <boost/url/format.hpp>
391e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
40fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
41bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
421214b7e7SGunnar Mills 
437a1dbc48SGeorge Liu #include <array>
447a1dbc48SGeorge Liu #include <string_view>
45abf2add6SEd Tanous #include <variant>
46c5b2abe0SLewanczyk, Dawid 
471abe55efSEd Tanous namespace redfish
481abe55efSEd Tanous {
49c5b2abe0SLewanczyk, Dawid 
505c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
515c3e9272SAbhishek Patel     protocolToDBusForSystems{
525c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
535c3e9272SAbhishek Patel 
549d3ae10eSAlpana Kumari /**
559d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
569d3ae10eSAlpana Kumari  *
57ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
589d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
599d3ae10eSAlpana Kumari  *
609d3ae10eSAlpana Kumari  * @return None.
619d3ae10eSAlpana Kumari  */
628d1b46d7Szhanghch05 inline void
63ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
641e1e598dSJonathan Doman                          bool isDimmFunctional)
659d3ae10eSAlpana Kumari {
661e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
679d3ae10eSAlpana Kumari 
689d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
699d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
709d3ae10eSAlpana Kumari     // ENABLED.
7102cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
72ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
739d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
749d3ae10eSAlpana Kumari     {
75e05aec50SEd Tanous         if (isDimmFunctional)
769d3ae10eSAlpana Kumari         {
77ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
789d3ae10eSAlpana Kumari                 "Enabled";
799d3ae10eSAlpana Kumari         }
809d3ae10eSAlpana Kumari     }
819d3ae10eSAlpana Kumari }
829d3ae10eSAlpana Kumari 
8357e8c9beSAlpana Kumari /*
8457e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8557e8c9beSAlpana Kumari  *        CPU Functional State
8657e8c9beSAlpana Kumari  *
87ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
8857e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
8957e8c9beSAlpana Kumari  *
9057e8c9beSAlpana Kumari  * @return None.
9157e8c9beSAlpana Kumari  */
92ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
93ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9457e8c9beSAlpana Kumari {
951e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
9657e8c9beSAlpana Kumari 
9702cad96eSEd Tanous     const nlohmann::json& prevProcState =
98ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
9957e8c9beSAlpana Kumari 
10057e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10157e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10257e8c9beSAlpana Kumari     // Functional.
10357e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10457e8c9beSAlpana Kumari     {
105e05aec50SEd Tanous         if (isCpuFunctional)
10657e8c9beSAlpana Kumari         {
107ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10857e8c9beSAlpana Kumari                 "Enabled";
10957e8c9beSAlpana Kumari         }
11057e8c9beSAlpana Kumari     }
11157e8c9beSAlpana Kumari }
11257e8c9beSAlpana Kumari 
113cf0e004cSNinad Palsule /*
114cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
115cf0e004cSNinad Palsule  *
116ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
117cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
118cf0e004cSNinad Palsule  *
119cf0e004cSNinad Palsule  * @return None.
120cf0e004cSNinad Palsule  */
121cf0e004cSNinad Palsule inline void
122ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
123cf0e004cSNinad Palsule                            bool isCpuPresent)
124cf0e004cSNinad Palsule {
125cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
126cf0e004cSNinad Palsule 
127cf0e004cSNinad Palsule     if (isCpuPresent)
128cf0e004cSNinad Palsule     {
129cf0e004cSNinad Palsule         nlohmann::json& procCount =
130ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
131cf0e004cSNinad Palsule         auto* procCountPtr =
132cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
133cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
134cf0e004cSNinad Palsule         {
135cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
136cf0e004cSNinad Palsule             *procCountPtr += 1;
137cf0e004cSNinad Palsule         }
138cf0e004cSNinad Palsule     }
139cf0e004cSNinad Palsule }
140cf0e004cSNinad Palsule 
141382d6475SAli Ahmed inline void getProcessorProperties(
142ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
143382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
144382d6475SAli Ahmed         properties)
14503fbed92SAli Ahmed {
14603fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14703fbed92SAli Ahmed 
14803fbed92SAli Ahmed     // TODO: Get Model
14903fbed92SAli Ahmed 
150bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15103fbed92SAli Ahmed 
152bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
153bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15403fbed92SAli Ahmed 
155bc1d29deSKrzysztof Grobelny     if (!success)
15603fbed92SAli Ahmed     {
157ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15803fbed92SAli Ahmed         return;
15903fbed92SAli Ahmed     }
16003fbed92SAli Ahmed 
161bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16203fbed92SAli Ahmed     {
163bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
164ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
165bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
166bc1d29deSKrzysztof Grobelny 
167bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
168bc1d29deSKrzysztof Grobelny         {
169bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17003fbed92SAli Ahmed         }
17103fbed92SAli Ahmed         else
17203fbed92SAli Ahmed         {
173bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17403fbed92SAli Ahmed         }
17503fbed92SAli Ahmed     }
17603fbed92SAli Ahmed }
17703fbed92SAli Ahmed 
17803fbed92SAli Ahmed /*
17903fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18003fbed92SAli Ahmed  *
181ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18203fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18303fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18403fbed92SAli Ahmed  *
18503fbed92SAli Ahmed  * @return None.
18603fbed92SAli Ahmed  */
187ac106bf6SEd Tanous inline void
188ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
189ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19003fbed92SAli Ahmed {
191ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
192382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
193382d6475SAli Ahmed         if (ec3)
194382d6475SAli Ahmed         {
195382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
196382d6475SAli Ahmed             return;
197382d6475SAli Ahmed         }
198ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
199382d6475SAli Ahmed     };
200382d6475SAli Ahmed 
201cf0e004cSNinad Palsule     // Get the Presence of CPU
202cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
203cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
204cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
205cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
206cf0e004cSNinad Palsule 
2075fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2085fd0aafbSNinad Palsule     {
2095fd0aafbSNinad Palsule         auto getCpuFunctionalState =
210ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
211382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
212382d6475SAli Ahmed             if (ec3)
213382d6475SAli Ahmed             {
214382d6475SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
215382d6475SAli Ahmed                 return;
216382d6475SAli Ahmed             }
217ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
218382d6475SAli Ahmed         };
219382d6475SAli Ahmed 
220382d6475SAli Ahmed         // Get the Functional State
221382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
222382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2235fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2245fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2255fd0aafbSNinad Palsule     }
226382d6475SAli Ahmed 
227bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
228bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
229bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
230ac106bf6SEd Tanous         [asyncResp, service,
2315e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
232b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23303fbed92SAli Ahmed         if (ec2)
23403fbed92SAli Ahmed         {
23503fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
236ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23703fbed92SAli Ahmed             return;
23803fbed92SAli Ahmed         }
239ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
240bc1d29deSKrzysztof Grobelny         });
24103fbed92SAli Ahmed }
24203fbed92SAli Ahmed 
24357e8c9beSAlpana Kumari /*
244cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
245cf0e004cSNinad Palsule  *
246ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
247cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
248cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
249cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
250cf0e004cSNinad Palsule  *
251cf0e004cSNinad Palsule  * @return None.
252cf0e004cSNinad Palsule  */
253cf0e004cSNinad Palsule inline void
254ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2555fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2565fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
257cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
258cf0e004cSNinad Palsule {
259cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
260cf0e004cSNinad Palsule 
261cf0e004cSNinad Palsule     if (properties.empty())
262cf0e004cSNinad Palsule     {
2635fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2645fd0aafbSNinad Palsule         {
265cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
266cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
267cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
268cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
269cf0e004cSNinad Palsule                 "Functional",
270ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
271ac106bf6SEd Tanous                             bool dimmState) {
272cf0e004cSNinad Palsule                 if (ec3)
273cf0e004cSNinad Palsule                 {
274cf0e004cSNinad Palsule                     BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
275cf0e004cSNinad Palsule                     return;
276cf0e004cSNinad Palsule                 }
277ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
278cf0e004cSNinad Palsule                 });
2795fd0aafbSNinad Palsule         }
280cf0e004cSNinad Palsule         return;
281cf0e004cSNinad Palsule     }
282cf0e004cSNinad Palsule 
283cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
284cf0e004cSNinad Palsule 
285cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
286cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
287cf0e004cSNinad Palsule         memorySizeInKB);
288cf0e004cSNinad Palsule 
289cf0e004cSNinad Palsule     if (!success)
290cf0e004cSNinad Palsule     {
291ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
292cf0e004cSNinad Palsule         return;
293cf0e004cSNinad Palsule     }
294cf0e004cSNinad Palsule 
295cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
296cf0e004cSNinad Palsule     {
297cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
298ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
299cf0e004cSNinad Palsule         const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
300cf0e004cSNinad Palsule         if (preValue == nullptr)
301cf0e004cSNinad Palsule         {
302ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
303cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
304cf0e004cSNinad Palsule         }
305cf0e004cSNinad Palsule         else
306cf0e004cSNinad Palsule         {
307ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
308cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
309cf0e004cSNinad Palsule         }
3105fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3115fd0aafbSNinad Palsule         {
312ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3135fd0aafbSNinad Palsule                 "Enabled";
3145fd0aafbSNinad Palsule         }
315cf0e004cSNinad Palsule     }
316cf0e004cSNinad Palsule }
317cf0e004cSNinad Palsule 
318cf0e004cSNinad Palsule /*
319cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
320cf0e004cSNinad Palsule  *
321ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
322cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
323cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
324cf0e004cSNinad Palsule  *
325cf0e004cSNinad Palsule  * @return None.
326cf0e004cSNinad Palsule  */
327ac106bf6SEd Tanous inline void
328ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
329ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
330cf0e004cSNinad Palsule {
331cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
332cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
333cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
334ac106bf6SEd Tanous         [asyncResp, service,
335cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
336cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
337cf0e004cSNinad Palsule         if (ec2)
338cf0e004cSNinad Palsule         {
339cf0e004cSNinad Palsule             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
340ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
341cf0e004cSNinad Palsule             return;
342cf0e004cSNinad Palsule         }
343ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
344cf0e004cSNinad Palsule         });
345cf0e004cSNinad Palsule }
346cf0e004cSNinad Palsule 
347cf0e004cSNinad Palsule /*
348c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
349c5b2abe0SLewanczyk, Dawid  *
350ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
3518f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
352c5b2abe0SLewanczyk, Dawid  *
353c5b2abe0SLewanczyk, Dawid  * @return None.
354c5b2abe0SLewanczyk, Dawid  */
355b5a76932SEd Tanous inline void
356ac106bf6SEd Tanous     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
357b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
3581abe55efSEd Tanous {
35955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
360e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
361e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
362e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
363e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
364e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
365e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
366e99073f5SGeorge Liu     };
367e99073f5SGeorge Liu     dbus::utility::getSubTree(
368e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
369ac106bf6SEd Tanous         [asyncResp,
370e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
371b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
3721abe55efSEd Tanous         if (ec)
3731abe55efSEd Tanous         {
37455c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
375ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
376c5b2abe0SLewanczyk, Dawid             return;
377c5b2abe0SLewanczyk, Dawid         }
378c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
379002d39b4SEd Tanous         for (const std::pair<
380002d39b4SEd Tanous                  std::string,
381002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
3821214b7e7SGunnar Mills                  object : subtree)
3831abe55efSEd Tanous         {
384c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
38555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
386002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
3871214b7e7SGunnar Mills                 connectionNames = object.second;
38826f6976fSEd Tanous             if (connectionNames.empty())
3891abe55efSEd Tanous             {
390c5b2abe0SLewanczyk, Dawid                 continue;
391c5b2abe0SLewanczyk, Dawid             }
392029573d4SEd Tanous 
3935fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
3945fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
3955bc2dc8eSJames Feist 
3965fd0aafbSNinad Palsule             if constexpr (bmcwebEnableProcMemStatus)
3975fd0aafbSNinad Palsule             {
3985fd0aafbSNinad Palsule                 memoryHealth = std::make_shared<HealthPopulate>(
399ac106bf6SEd Tanous                     asyncResp, "/MemorySummary/Status"_json_pointer);
4005fd0aafbSNinad Palsule                 systemHealth->children.emplace_back(memoryHealth);
4015bc2dc8eSJames Feist 
40213451e39SWilly Tu                 if constexpr (bmcwebEnableHealthPopulate)
40313451e39SWilly Tu                 {
4045fd0aafbSNinad Palsule                     cpuHealth = std::make_shared<HealthPopulate>(
405ac106bf6SEd Tanous                         asyncResp, "/ProcessorSummary/Status"_json_pointer);
4065fd0aafbSNinad Palsule 
4075bc2dc8eSJames Feist                     systemHealth->children.emplace_back(cpuHealth);
40813451e39SWilly Tu                 }
4095fd0aafbSNinad Palsule             }
4105bc2dc8eSJames Feist 
4116c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
4126c34de48SEd Tanous             // BiosVer
41304a258f4SEd Tanous             for (const auto& connection : connectionNames)
4141abe55efSEd Tanous             {
41504a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
4161abe55efSEd Tanous                 {
41704a258f4SEd Tanous                     if (interfaceName ==
41804a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
4191abe55efSEd Tanous                     {
4201abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
42104a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
4229d3ae10eSAlpana Kumari 
423ac106bf6SEd Tanous                         getMemorySummary(asyncResp, connection.first, path);
4245bc2dc8eSJames Feist 
4255fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4265fd0aafbSNinad Palsule                         {
4275bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4281abe55efSEd Tanous                         }
4295fd0aafbSNinad Palsule                     }
43004a258f4SEd Tanous                     else if (interfaceName ==
43104a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
4321abe55efSEd Tanous                     {
4331abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
43404a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
43557e8c9beSAlpana Kumari 
436ac106bf6SEd Tanous                         getProcessorSummary(asyncResp, connection.first, path);
4375bc2dc8eSJames Feist 
4385fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4395fd0aafbSNinad Palsule                         {
4405bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4411abe55efSEd Tanous                         }
4425fd0aafbSNinad Palsule                     }
443002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4441abe55efSEd Tanous                     {
4451abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
44604a258f4SEd Tanous                             << "Found UUID, now get its properties.";
447bc1d29deSKrzysztof Grobelny 
448bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
449bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
450bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
451ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec3,
452b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
4531214b7e7SGunnar Mills                                             properties) {
454cb13a392SEd Tanous                             if (ec3)
4551abe55efSEd Tanous                             {
456002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
457002d39b4SEd Tanous                                                  << ec3;
458ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
459c5b2abe0SLewanczyk, Dawid                                 return;
460c5b2abe0SLewanczyk, Dawid                             }
461002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
462c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
46304a258f4SEd Tanous 
464bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
465bc1d29deSKrzysztof Grobelny 
466bc1d29deSKrzysztof Grobelny                             const bool success =
467bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
468bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
469bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
470bc1d29deSKrzysztof Grobelny 
471bc1d29deSKrzysztof Grobelny                             if (!success)
4721abe55efSEd Tanous                             {
473ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
474bc1d29deSKrzysztof Grobelny                                 return;
475bc1d29deSKrzysztof Grobelny                             }
476bc1d29deSKrzysztof Grobelny 
477bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
478bc1d29deSKrzysztof Grobelny                             {
479bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
48004a258f4SEd Tanous                                 if (valueStr.size() == 32)
4811abe55efSEd Tanous                                 {
482029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
483029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
484029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
485029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
48604a258f4SEd Tanous                                 }
487bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
488ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["UUID"] = valueStr;
489c5b2abe0SLewanczyk, Dawid                             }
490bc1d29deSKrzysztof Grobelny                             });
491c5b2abe0SLewanczyk, Dawid                     }
492029573d4SEd Tanous                     else if (interfaceName ==
493029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4941abe55efSEd Tanous                     {
495bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
496bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
497bc1d29deSKrzysztof Grobelny                             path,
498bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
499ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
500b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
5011214b7e7SGunnar Mills                                             propertiesList) {
502cb13a392SEd Tanous                             if (ec2)
503029573d4SEd Tanous                             {
504e4a4b9a9SJames Feist                                 // doesn't have to include this
505e4a4b9a9SJames Feist                                 // interface
506029573d4SEd Tanous                                 return;
507029573d4SEd Tanous                             }
508002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
509029573d4SEd Tanous                                              << " properties for system";
510bc1d29deSKrzysztof Grobelny 
511bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
512bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
513bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
514bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
515bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
516bc1d29deSKrzysztof Grobelny 
517bc1d29deSKrzysztof Grobelny                             const bool success =
518bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
519bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
520bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
521bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
522bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
523bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
524bc1d29deSKrzysztof Grobelny 
525bc1d29deSKrzysztof Grobelny                             if (!success)
526029573d4SEd Tanous                             {
527ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
528bc1d29deSKrzysztof Grobelny                                 return;
529029573d4SEd Tanous                             }
530bc1d29deSKrzysztof Grobelny 
531bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
532bc1d29deSKrzysztof Grobelny                             {
533ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["PartNumber"] =
534bc1d29deSKrzysztof Grobelny                                     *partNumber;
535029573d4SEd Tanous                             }
536bc1d29deSKrzysztof Grobelny 
537bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
538bc1d29deSKrzysztof Grobelny                             {
539ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SerialNumber"] =
540bc1d29deSKrzysztof Grobelny                                     *serialNumber;
541bc1d29deSKrzysztof Grobelny                             }
542bc1d29deSKrzysztof Grobelny 
543bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
544bc1d29deSKrzysztof Grobelny                             {
545ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Manufacturer"] =
546bc1d29deSKrzysztof Grobelny                                     *manufacturer;
547bc1d29deSKrzysztof Grobelny                             }
548bc1d29deSKrzysztof Grobelny 
549bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
550bc1d29deSKrzysztof Grobelny                             {
551ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Model"] = *model;
552bc1d29deSKrzysztof Grobelny                             }
553bc1d29deSKrzysztof Grobelny 
554bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
555bc1d29deSKrzysztof Grobelny                             {
556ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SubModel"] =
557ac106bf6SEd Tanous                                     *subModel;
558fc5afcf9Sbeccabroek                             }
559c1e236a6SGunnar Mills 
560cb7e1e7bSAndrew Geissler                             // Grab the bios version
561eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
562ac106bf6SEd Tanous                                 asyncResp, sw_util::biosPurpose, "BiosVersion",
563002d39b4SEd Tanous                                 false);
564bc1d29deSKrzysztof Grobelny                             });
565e4a4b9a9SJames Feist 
5661e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5671e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5681e1e598dSJonathan Doman                             path,
5691e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5701e1e598dSJonathan Doman                             "AssetTag",
5711e1e598dSJonathan Doman                             "AssetTag",
572ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
5731e1e598dSJonathan Doman                                         const std::string& value) {
574cb13a392SEd Tanous                             if (ec2)
575e4a4b9a9SJames Feist                             {
576e4a4b9a9SJames Feist                                 // doesn't have to include this
577e4a4b9a9SJames Feist                                 // interface
578e4a4b9a9SJames Feist                                 return;
579e4a4b9a9SJames Feist                             }
580e4a4b9a9SJames Feist 
581ac106bf6SEd Tanous                             asyncResp->res.jsonValue["AssetTag"] = value;
5821e1e598dSJonathan Doman                             });
583029573d4SEd Tanous                     }
584029573d4SEd Tanous                 }
585029573d4SEd Tanous             }
586c5b2abe0SLewanczyk, Dawid         }
5876617338dSEd Tanous         });
588c5b2abe0SLewanczyk, Dawid }
589c5b2abe0SLewanczyk, Dawid 
590c5b2abe0SLewanczyk, Dawid /**
591c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
592c5b2abe0SLewanczyk, Dawid  *
593ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
594c5b2abe0SLewanczyk, Dawid  *
595c5b2abe0SLewanczyk, Dawid  * @return None.
596c5b2abe0SLewanczyk, Dawid  */
597ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5981abe55efSEd Tanous {
59955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
6001e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6011e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6021e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6031e1e598dSJonathan Doman         "CurrentHostState",
604ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6051e1e598dSJonathan Doman                     const std::string& hostState) {
6061abe55efSEd Tanous         if (ec)
6071abe55efSEd Tanous         {
60822228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
60922228c28SAndrew Geissler             {
61022228c28SAndrew Geissler                 // Service not available, no error, just don't return
61122228c28SAndrew Geissler                 // host state info
61222228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
61322228c28SAndrew Geissler                 return;
61422228c28SAndrew Geissler             }
61522228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
616ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
617c5b2abe0SLewanczyk, Dawid             return;
618c5b2abe0SLewanczyk, Dawid         }
6196617338dSEd Tanous 
6201e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
621c5b2abe0SLewanczyk, Dawid         // Verify Host State
6221e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6231abe55efSEd Tanous         {
624ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
625ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6261abe55efSEd Tanous         }
6271e1e598dSJonathan Doman         else if (hostState ==
6280fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6298c888608SGunnar Mills         {
630ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
631ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6328c888608SGunnar Mills         }
6331e1e598dSJonathan Doman         else if (hostState ==
6340fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
63583935af9SAndrew Geissler         {
636ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
637ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
63883935af9SAndrew Geissler         }
6390fda0f12SGeorge Liu         else if (
6401e1e598dSJonathan Doman             hostState ==
6410fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6421a2a1437SAndrew Geissler         {
643ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
644ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6451a2a1437SAndrew Geissler         }
646002d39b4SEd Tanous         else if (hostState ==
6470fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6481a2a1437SAndrew Geissler         {
649ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
650ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6511a2a1437SAndrew Geissler         }
6521abe55efSEd Tanous         else
6531abe55efSEd Tanous         {
654ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
655ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
656c5b2abe0SLewanczyk, Dawid         }
6571e1e598dSJonathan Doman         });
658c5b2abe0SLewanczyk, Dawid }
659c5b2abe0SLewanczyk, Dawid 
660c5b2abe0SLewanczyk, Dawid /**
661786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
662491d8ee7SSantosh Puranik  *
663491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
664491d8ee7SSantosh Puranik  *
665491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
666491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
667491d8ee7SSantosh Puranik  */
66823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
669491d8ee7SSantosh Puranik {
670491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
671491d8ee7SSantosh Puranik     {
672491d8ee7SSantosh Puranik         return "None";
673491d8ee7SSantosh Puranik     }
6743174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
675491d8ee7SSantosh Puranik     {
676491d8ee7SSantosh Puranik         return "Hdd";
677491d8ee7SSantosh Puranik     }
6783174e4dfSEd Tanous     if (dbusSource ==
679a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
680491d8ee7SSantosh Puranik     {
681491d8ee7SSantosh Puranik         return "Cd";
682491d8ee7SSantosh Puranik     }
6833174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
684491d8ee7SSantosh Puranik     {
685491d8ee7SSantosh Puranik         return "Pxe";
686491d8ee7SSantosh Puranik     }
6873174e4dfSEd Tanous     if (dbusSource ==
688944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6899f16b2c1SJennifer Lee     {
6909f16b2c1SJennifer Lee         return "Usb";
6919f16b2c1SJennifer Lee     }
692491d8ee7SSantosh Puranik     return "";
693491d8ee7SSantosh Puranik }
694491d8ee7SSantosh Puranik 
695491d8ee7SSantosh Puranik /**
696cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
697cd9a4666SKonstantin Aladyshev  *
698cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
699cd9a4666SKonstantin Aladyshev  *
700cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
701cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
702cd9a4666SKonstantin Aladyshev  */
703cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
704cd9a4666SKonstantin Aladyshev {
705cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
706cd9a4666SKonstantin Aladyshev     {
707cd9a4666SKonstantin Aladyshev         return "Legacy";
708cd9a4666SKonstantin Aladyshev     }
709cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
710cd9a4666SKonstantin Aladyshev     {
711cd9a4666SKonstantin Aladyshev         return "UEFI";
712cd9a4666SKonstantin Aladyshev     }
713cd9a4666SKonstantin Aladyshev     return "";
714cd9a4666SKonstantin Aladyshev }
715cd9a4666SKonstantin Aladyshev 
716cd9a4666SKonstantin Aladyshev /**
717786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
718491d8ee7SSantosh Puranik  *
719491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
720491d8ee7SSantosh Puranik  *
721491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
722491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
723491d8ee7SSantosh Puranik  */
72423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
725491d8ee7SSantosh Puranik {
726491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
727491d8ee7SSantosh Puranik     {
728491d8ee7SSantosh Puranik         return "None";
729491d8ee7SSantosh Puranik     }
7303174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
731491d8ee7SSantosh Puranik     {
732491d8ee7SSantosh Puranik         return "Diags";
733491d8ee7SSantosh Puranik     }
7343174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
735491d8ee7SSantosh Puranik     {
736491d8ee7SSantosh Puranik         return "BiosSetup";
737491d8ee7SSantosh Puranik     }
738491d8ee7SSantosh Puranik     return "";
739491d8ee7SSantosh Puranik }
740491d8ee7SSantosh Puranik 
741491d8ee7SSantosh Puranik /**
742e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
743e43914b3SAndrew Geissler  *
744e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
745e43914b3SAndrew Geissler  *
746e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
747e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
748e43914b3SAndrew Geissler  */
749e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
750e43914b3SAndrew Geissler {
751e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
752e43914b3SAndrew Geissler     // enum
753e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
754e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
755e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
756e43914b3SAndrew Geissler     {
757e43914b3SAndrew Geissler         rfBpLastState = "None";
758e43914b3SAndrew Geissler     }
759e43914b3SAndrew Geissler     else if (dbusBootProgress ==
760e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
761e43914b3SAndrew Geissler              "PrimaryProcInit")
762e43914b3SAndrew Geissler     {
763e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
764e43914b3SAndrew Geissler     }
765e43914b3SAndrew Geissler     else if (dbusBootProgress ==
766e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
767e43914b3SAndrew Geissler              "BusInit")
768e43914b3SAndrew Geissler     {
769e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
770e43914b3SAndrew Geissler     }
771e43914b3SAndrew Geissler     else if (dbusBootProgress ==
772e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
773e43914b3SAndrew Geissler              "MemoryInit")
774e43914b3SAndrew Geissler     {
775e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
776e43914b3SAndrew Geissler     }
777e43914b3SAndrew Geissler     else if (dbusBootProgress ==
778e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
779e43914b3SAndrew Geissler              "SecondaryProcInit")
780e43914b3SAndrew Geissler     {
781e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
782e43914b3SAndrew Geissler     }
783e43914b3SAndrew Geissler     else if (dbusBootProgress ==
784e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
785e43914b3SAndrew Geissler              "PCIInit")
786e43914b3SAndrew Geissler     {
787e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
788e43914b3SAndrew Geissler     }
789e43914b3SAndrew Geissler     else if (dbusBootProgress ==
790e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
791e43914b3SAndrew Geissler              "SystemSetup")
792e43914b3SAndrew Geissler     {
793e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
794e43914b3SAndrew Geissler     }
795e43914b3SAndrew Geissler     else if (dbusBootProgress ==
796e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
797e43914b3SAndrew Geissler              "SystemInitComplete")
798e43914b3SAndrew Geissler     {
799e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
800e43914b3SAndrew Geissler     }
801e43914b3SAndrew Geissler     else if (dbusBootProgress ==
802e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
803e43914b3SAndrew Geissler              "OSStart")
804e43914b3SAndrew Geissler     {
805e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
806e43914b3SAndrew Geissler     }
807e43914b3SAndrew Geissler     else if (dbusBootProgress ==
808e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
809e43914b3SAndrew Geissler              "OSRunning")
810e43914b3SAndrew Geissler     {
811e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
812e43914b3SAndrew Geissler     }
813e43914b3SAndrew Geissler     else
814e43914b3SAndrew Geissler     {
815e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
816e43914b3SAndrew Geissler                          << dbusBootProgress;
817e43914b3SAndrew Geissler         // Just return the default
818e43914b3SAndrew Geissler     }
819e43914b3SAndrew Geissler     return rfBpLastState;
820e43914b3SAndrew Geissler }
821e43914b3SAndrew Geissler 
822e43914b3SAndrew Geissler /**
823786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
824491d8ee7SSantosh Puranik  *
825491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
826944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
827944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
828491d8ee7SSantosh Puranik  *
829944ffaf9SJohnathan Mantey  * @return Integer error code.
830491d8ee7SSantosh Puranik  */
831ac106bf6SEd Tanous inline int
832ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
833ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
834ac106bf6SEd Tanous                          std::string& bootMode)
835491d8ee7SSantosh Puranik {
836c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
837c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
838944ffaf9SJohnathan Mantey 
839491d8ee7SSantosh Puranik     if (rfSource == "None")
840491d8ee7SSantosh Puranik     {
841944ffaf9SJohnathan Mantey         return 0;
842491d8ee7SSantosh Puranik     }
8433174e4dfSEd Tanous     if (rfSource == "Pxe")
844491d8ee7SSantosh Puranik     {
845944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
846944ffaf9SJohnathan Mantey     }
847944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
848944ffaf9SJohnathan Mantey     {
849944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
850944ffaf9SJohnathan Mantey     }
851944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
852944ffaf9SJohnathan Mantey     {
853944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
854944ffaf9SJohnathan Mantey     }
855944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
856944ffaf9SJohnathan Mantey     {
857944ffaf9SJohnathan Mantey         bootSource =
858944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
859944ffaf9SJohnathan Mantey     }
860944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
861944ffaf9SJohnathan Mantey     {
862944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
863491d8ee7SSantosh Puranik     }
8649f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8659f16b2c1SJennifer Lee     {
866944ffaf9SJohnathan Mantey         bootSource =
867944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8689f16b2c1SJennifer Lee     }
869491d8ee7SSantosh Puranik     else
870491d8ee7SSantosh Puranik     {
8710fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8720fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
873944ffaf9SJohnathan Mantey             << bootSource;
874ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
875944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
876944ffaf9SJohnathan Mantey         return -1;
877491d8ee7SSantosh Puranik     }
878944ffaf9SJohnathan Mantey     return 0;
879491d8ee7SSantosh Puranik }
8801981771bSAli Ahmed 
881978b8803SAndrew Geissler /**
882978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
883978b8803SAndrew Geissler  *
884ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
885978b8803SAndrew Geissler  *
886978b8803SAndrew Geissler  * @return None.
887978b8803SAndrew Geissler  */
888ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
889978b8803SAndrew Geissler {
8901e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8911e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8921e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8931e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
894ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8951e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
896978b8803SAndrew Geissler         if (ec)
897978b8803SAndrew Geissler         {
898978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
899978b8803SAndrew Geissler             // not found
900978b8803SAndrew Geissler             return;
901978b8803SAndrew Geissler         }
902978b8803SAndrew Geissler 
9031e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
904978b8803SAndrew Geissler 
905ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
906e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9071e1e598dSJonathan Doman         });
908978b8803SAndrew Geissler }
909491d8ee7SSantosh Puranik 
910491d8ee7SSantosh Puranik /**
911b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
912b6d5d45cSHieu Huynh  *
913ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
914b6d5d45cSHieu Huynh  *
915b6d5d45cSHieu Huynh  * @return None.
916b6d5d45cSHieu Huynh  */
917b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
918ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
919b6d5d45cSHieu Huynh {
920b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
921b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
922b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
923b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
924ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
925b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
926b6d5d45cSHieu Huynh         if (ec)
927b6d5d45cSHieu Huynh         {
928b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
929b6d5d45cSHieu Huynh             return;
930b6d5d45cSHieu Huynh         }
931b6d5d45cSHieu Huynh 
932b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
933b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
934b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
935b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
936b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
937b6d5d45cSHieu Huynh 
938b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
939ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
940b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
941b6d5d45cSHieu Huynh         });
942b6d5d45cSHieu Huynh }
943b6d5d45cSHieu Huynh 
944b6d5d45cSHieu Huynh /**
945c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
946cd9a4666SKonstantin Aladyshev  *
947ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
948cd9a4666SKonstantin Aladyshev  *
949cd9a4666SKonstantin Aladyshev  * @return None.
950cd9a4666SKonstantin Aladyshev  */
951cd9a4666SKonstantin Aladyshev 
952ac106bf6SEd Tanous inline void
953ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
954cd9a4666SKonstantin Aladyshev {
9551e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9561e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9571e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9581e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
959ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9601e1e598dSJonathan Doman                     const std::string& bootType) {
961cd9a4666SKonstantin Aladyshev         if (ec)
962cd9a4666SKonstantin Aladyshev         {
963cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
964cd9a4666SKonstantin Aladyshev             return;
965cd9a4666SKonstantin Aladyshev         }
966cd9a4666SKonstantin Aladyshev 
9671e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
968cd9a4666SKonstantin Aladyshev 
969ac106bf6SEd Tanous         asyncResp->res
970ac106bf6SEd Tanous             .jsonValue["Boot"]
971002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
972613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
973cd9a4666SKonstantin Aladyshev 
9741e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
975cd9a4666SKonstantin Aladyshev         if (rfType.empty())
976cd9a4666SKonstantin Aladyshev         {
977ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
978cd9a4666SKonstantin Aladyshev             return;
979cd9a4666SKonstantin Aladyshev         }
980cd9a4666SKonstantin Aladyshev 
981ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9821e1e598dSJonathan Doman         });
983cd9a4666SKonstantin Aladyshev }
984cd9a4666SKonstantin Aladyshev 
985cd9a4666SKonstantin Aladyshev /**
986c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
987491d8ee7SSantosh Puranik  *
988ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
989491d8ee7SSantosh Puranik  *
990491d8ee7SSantosh Puranik  * @return None.
991491d8ee7SSantosh Puranik  */
992c21865c4SKonstantin Aladyshev 
993ac106bf6SEd Tanous inline void
994ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
995491d8ee7SSantosh Puranik {
9961e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9971e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9981e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9991e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1000ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10011e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1002491d8ee7SSantosh Puranik         if (ec)
1003491d8ee7SSantosh Puranik         {
1004491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1005ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1006491d8ee7SSantosh Puranik             return;
1007491d8ee7SSantosh Puranik         }
1008491d8ee7SSantosh Puranik 
10091e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1010491d8ee7SSantosh Puranik 
1011ac106bf6SEd Tanous         asyncResp->res
10120fda0f12SGeorge Liu             .jsonValue["Boot"]
1013002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1014002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1015491d8ee7SSantosh Puranik 
10161e1e598dSJonathan Doman         if (bootModeStr !=
1017491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1018491d8ee7SSantosh Puranik         {
10191e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1020491d8ee7SSantosh Puranik             if (!rfMode.empty())
1021491d8ee7SSantosh Puranik             {
1022ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1023491d8ee7SSantosh Puranik                     rfMode;
1024491d8ee7SSantosh Puranik             }
1025491d8ee7SSantosh Puranik         }
10261e1e598dSJonathan Doman         });
1027491d8ee7SSantosh Puranik }
1028491d8ee7SSantosh Puranik 
1029491d8ee7SSantosh Puranik /**
1030c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1031491d8ee7SSantosh Puranik  *
1032ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1033491d8ee7SSantosh Puranik  *
1034491d8ee7SSantosh Puranik  * @return None.
1035491d8ee7SSantosh Puranik  */
1036c21865c4SKonstantin Aladyshev 
1037c21865c4SKonstantin Aladyshev inline void
1038ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1039491d8ee7SSantosh Puranik {
10401e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10411e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10421e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10431e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1044ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10451e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1046491d8ee7SSantosh Puranik         if (ec)
1047491d8ee7SSantosh Puranik         {
1048491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10495ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10505ef735c8SNan Zhou             {
10515ef735c8SNan Zhou                 return;
10525ef735c8SNan Zhou             }
1053ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1054491d8ee7SSantosh Puranik             return;
1055491d8ee7SSantosh Puranik         }
1056491d8ee7SSantosh Puranik 
10571e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1058491d8ee7SSantosh Puranik 
10591e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1060491d8ee7SSantosh Puranik         if (!rfSource.empty())
1061491d8ee7SSantosh Puranik         {
1062ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1063ac106bf6SEd Tanous                 rfSource;
1064491d8ee7SSantosh Puranik         }
1065cd9a4666SKonstantin Aladyshev 
1066cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1067cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1068ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10691e1e598dSJonathan Doman         });
1070491d8ee7SSantosh Puranik }
1071491d8ee7SSantosh Puranik 
1072491d8ee7SSantosh Puranik /**
1073c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1074c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1075c21865c4SKonstantin Aladyshev  * state
1076491d8ee7SSantosh Puranik  *
1077ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1078491d8ee7SSantosh Puranik  *
1079491d8ee7SSantosh Puranik  * @return None.
1080491d8ee7SSantosh Puranik  */
1081491d8ee7SSantosh Puranik 
1082ac106bf6SEd Tanous inline void processBootOverrideEnable(
1083ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1084c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1085c21865c4SKonstantin Aladyshev {
1086c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1087c21865c4SKonstantin Aladyshev     {
1088ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1089ac106bf6SEd Tanous             "Disabled";
1090c21865c4SKonstantin Aladyshev         return;
1091c21865c4SKonstantin Aladyshev     }
1092c21865c4SKonstantin Aladyshev 
1093c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1094c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10951e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10961e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10971e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10981e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1099ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1100491d8ee7SSantosh Puranik         if (ec)
1101491d8ee7SSantosh Puranik         {
1102491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1103ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1104491d8ee7SSantosh Puranik             return;
1105491d8ee7SSantosh Puranik         }
1106491d8ee7SSantosh Puranik 
1107c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1108c21865c4SKonstantin Aladyshev         {
1109ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1110ac106bf6SEd Tanous                 "Once";
1111c21865c4SKonstantin Aladyshev         }
1112c21865c4SKonstantin Aladyshev         else
1113c21865c4SKonstantin Aladyshev         {
1114ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1115c21865c4SKonstantin Aladyshev                 "Continuous";
1116c21865c4SKonstantin Aladyshev         }
11171e1e598dSJonathan Doman         });
1118491d8ee7SSantosh Puranik }
1119491d8ee7SSantosh Puranik 
1120491d8ee7SSantosh Puranik /**
1121c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1122c21865c4SKonstantin Aladyshev  *
1123ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1124c21865c4SKonstantin Aladyshev  *
1125c21865c4SKonstantin Aladyshev  * @return None.
1126c21865c4SKonstantin Aladyshev  */
1127c21865c4SKonstantin Aladyshev 
1128c21865c4SKonstantin Aladyshev inline void
1129ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1130c21865c4SKonstantin Aladyshev {
11311e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11321e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11331e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11341e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1135ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11361e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1137c21865c4SKonstantin Aladyshev         if (ec)
1138c21865c4SKonstantin Aladyshev         {
1139c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
11405ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11415ef735c8SNan Zhou             {
11425ef735c8SNan Zhou                 return;
11435ef735c8SNan Zhou             }
1144ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1145c21865c4SKonstantin Aladyshev             return;
1146c21865c4SKonstantin Aladyshev         }
1147c21865c4SKonstantin Aladyshev 
1148ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11491e1e598dSJonathan Doman         });
1150c21865c4SKonstantin Aladyshev }
1151c21865c4SKonstantin Aladyshev 
1152c21865c4SKonstantin Aladyshev /**
1153c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1154c21865c4SKonstantin Aladyshev  *
1155ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1156c21865c4SKonstantin Aladyshev  *
1157c21865c4SKonstantin Aladyshev  * @return None.
1158c21865c4SKonstantin Aladyshev  */
1159ac106bf6SEd Tanous inline void
1160ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1161c21865c4SKonstantin Aladyshev {
1162c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1163c21865c4SKonstantin Aladyshev 
1164ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1165ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1166ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1167c21865c4SKonstantin Aladyshev }
1168c21865c4SKonstantin Aladyshev 
1169c21865c4SKonstantin Aladyshev /**
1170c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1171c0557e1aSGunnar Mills  *
1172c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1173c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1174c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1175c0557e1aSGunnar Mills  * last power operation time.
1176c0557e1aSGunnar Mills  *
1177ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1178c0557e1aSGunnar Mills  *
1179c0557e1aSGunnar Mills  * @return None.
1180c0557e1aSGunnar Mills  */
1181ac106bf6SEd Tanous inline void
1182ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1183c0557e1aSGunnar Mills {
1184c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1185c0557e1aSGunnar Mills 
11861e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11871e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11881e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11891e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1190ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1191ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1192c0557e1aSGunnar Mills         if (ec)
1193c0557e1aSGunnar Mills         {
1194c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1195c0557e1aSGunnar Mills             return;
1196c0557e1aSGunnar Mills         }
1197c0557e1aSGunnar Mills 
1198c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1199c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12001e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1201c0557e1aSGunnar Mills 
1202c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1203ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12042b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12051e1e598dSJonathan Doman         });
1206c0557e1aSGunnar Mills }
1207c0557e1aSGunnar Mills 
1208c0557e1aSGunnar Mills /**
1209797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1210797d5daeSCorey Hardesty  *
1211797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1212797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1213797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1214797d5daeSCorey Hardesty  * dbus.
1215797d5daeSCorey Hardesty  *
1216ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1217797d5daeSCorey Hardesty  *
1218797d5daeSCorey Hardesty  * @return None.
1219797d5daeSCorey Hardesty  */
1220ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1221ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1222797d5daeSCorey Hardesty {
1223797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1224797d5daeSCorey Hardesty 
1225797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1226797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1227797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1228797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1229ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1230ac106bf6SEd Tanous             const boost::system::error_code& ec,
1231797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1232797d5daeSCorey Hardesty         if (ec)
1233797d5daeSCorey Hardesty         {
1234797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1235797d5daeSCorey Hardesty             {
1236797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1237ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1238797d5daeSCorey Hardesty             }
1239797d5daeSCorey Hardesty             return;
1240797d5daeSCorey Hardesty         }
1241797d5daeSCorey Hardesty 
1242797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1243797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1244797d5daeSCorey Hardesty 
1245797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1246797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1247797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1248797d5daeSCorey Hardesty 
1249797d5daeSCorey Hardesty         if (!success)
1250797d5daeSCorey Hardesty         {
1251ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1252797d5daeSCorey Hardesty             return;
1253797d5daeSCorey Hardesty         }
1254797d5daeSCorey Hardesty 
1255797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1256797d5daeSCorey Hardesty         {
1257ac106bf6SEd Tanous             asyncResp->res
1258ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1259797d5daeSCorey Hardesty                 *attemptsLeft;
1260797d5daeSCorey Hardesty         }
1261797d5daeSCorey Hardesty 
1262797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1263797d5daeSCorey Hardesty         {
1264ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1265797d5daeSCorey Hardesty                 *retryAttempts;
1266797d5daeSCorey Hardesty         }
1267797d5daeSCorey Hardesty         });
1268797d5daeSCorey Hardesty }
1269797d5daeSCorey Hardesty 
1270797d5daeSCorey Hardesty /**
12716bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12726bd5a8d2SGunnar Mills  *
1273ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12746bd5a8d2SGunnar Mills  *
12756bd5a8d2SGunnar Mills  * @return None.
12766bd5a8d2SGunnar Mills  */
1277797d5daeSCorey Hardesty inline void
1278ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12796bd5a8d2SGunnar Mills {
12806bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12816bd5a8d2SGunnar Mills 
12821e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12831e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12841e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12851e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1286ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1287ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12886bd5a8d2SGunnar Mills         if (ec)
12896bd5a8d2SGunnar Mills         {
1290797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1291797d5daeSCorey Hardesty             {
1292797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1293ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1294797d5daeSCorey Hardesty             }
12956bd5a8d2SGunnar Mills             return;
12966bd5a8d2SGunnar Mills         }
12976bd5a8d2SGunnar Mills 
12981e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1299e05aec50SEd Tanous         if (autoRebootEnabled)
13006bd5a8d2SGunnar Mills         {
1301ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13026bd5a8d2SGunnar Mills                 "RetryAttempts";
13036bd5a8d2SGunnar Mills         }
13046bd5a8d2SGunnar Mills         else
13056bd5a8d2SGunnar Mills         {
1306ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1307ac106bf6SEd Tanous                 "Disabled";
13086bd5a8d2SGunnar Mills         }
1309ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
131069f35306SGunnar Mills 
131169f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
131269f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
131369f35306SGunnar Mills         // RetryAttempts.
1314ac106bf6SEd Tanous         asyncResp->res
1315ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1316ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13171e1e598dSJonathan Doman         });
13186bd5a8d2SGunnar Mills }
13196bd5a8d2SGunnar Mills 
13206bd5a8d2SGunnar Mills /**
1321797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1322797d5daeSCorey Hardesty  *
1323ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1324797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1325797d5daeSCorey Hardesty  *
1326797d5daeSCorey Hardesty  *@return None.
1327797d5daeSCorey Hardesty  */
1328797d5daeSCorey Hardesty 
1329ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1330ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1331797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1332797d5daeSCorey Hardesty {
1333797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1334797d5daeSCorey Hardesty     crow::connections::systemBus->async_method_call(
1335ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1336797d5daeSCorey Hardesty         if (ec)
1337797d5daeSCorey Hardesty         {
1338797d5daeSCorey Hardesty             BMCWEB_LOG_ERROR
1339797d5daeSCorey Hardesty                 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
1340ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1341797d5daeSCorey Hardesty             return;
1342797d5daeSCorey Hardesty         }
1343797d5daeSCorey Hardesty         },
1344797d5daeSCorey Hardesty         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1345797d5daeSCorey Hardesty         "org.freedesktop.DBus.Properties", "Set",
1346797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1347797d5daeSCorey Hardesty         std::variant<uint32_t>(retryAttempts));
1348797d5daeSCorey Hardesty }
1349797d5daeSCorey Hardesty 
1350797d5daeSCorey Hardesty /**
1351c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1352c6a620f2SGeorge Liu  *
1353ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1354c6a620f2SGeorge Liu  *
1355c6a620f2SGeorge Liu  * @return None.
1356c6a620f2SGeorge Liu  */
13578d1b46d7Szhanghch05 inline void
1358ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1359c6a620f2SGeorge Liu {
1360c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1361c6a620f2SGeorge Liu 
13621e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13631e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13641e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13651e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1366ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13675e7e2dc5SEd Tanous                     const std::string& policy) {
1368c6a620f2SGeorge Liu         if (ec)
1369c6a620f2SGeorge Liu         {
1370c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1371c6a620f2SGeorge Liu             return;
1372c6a620f2SGeorge Liu         }
1373c6a620f2SGeorge Liu 
13740fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
13750fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1376c6a620f2SGeorge Liu              "AlwaysOn"},
13770fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1378c6a620f2SGeorge Liu              "AlwaysOff"},
13790fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
13804ed47cb8SMatthew Barth              "LastState"},
13814ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
13824ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
13834ed47cb8SMatthew Barth              "AlwaysOff"}};
1384c6a620f2SGeorge Liu 
13851e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1386c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1387c6a620f2SGeorge Liu         {
1388ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1389c6a620f2SGeorge Liu             return;
1390c6a620f2SGeorge Liu         }
1391c6a620f2SGeorge Liu 
1392ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
13931e1e598dSJonathan Doman         });
1394c6a620f2SGeorge Liu }
1395c6a620f2SGeorge Liu 
1396c6a620f2SGeorge Liu /**
13971981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13981981771bSAli Ahmed  * TPM is required for booting the host.
13991981771bSAli Ahmed  *
1400ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14011981771bSAli Ahmed  *
14021981771bSAli Ahmed  * @return None.
14031981771bSAli Ahmed  */
14041981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1405ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14061981771bSAli Ahmed {
14071981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1408e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1409e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1410e99073f5SGeorge Liu     dbus::utility::getSubTree(
1411e99073f5SGeorge Liu         "/", 0, interfaces,
1412ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1413b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14141981771bSAli Ahmed         if (ec)
14151981771bSAli Ahmed         {
1416002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1417002d39b4SEd Tanous                              << ec;
14181981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14191981771bSAli Ahmed             // error occurs
14201981771bSAli Ahmed             return;
14211981771bSAli Ahmed         }
142226f6976fSEd Tanous         if (subtree.empty())
14231981771bSAli Ahmed         {
14241981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14251981771bSAli Ahmed             // if there is no instance found
14261981771bSAli Ahmed             return;
14271981771bSAli Ahmed         }
14281981771bSAli Ahmed 
14291981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14301981771bSAli Ahmed         if (subtree.size() > 1)
14311981771bSAli Ahmed         {
14321981771bSAli Ahmed             BMCWEB_LOG_DEBUG
14331981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14341981771bSAli Ahmed                 << subtree.size();
14351981771bSAli Ahmed             // Throw an internal Error and return
1436ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14371981771bSAli Ahmed             return;
14381981771bSAli Ahmed         }
14391981771bSAli Ahmed 
14401981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14411981771bSAli Ahmed         // field
14421981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14431981771bSAli Ahmed         {
14441981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1445ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14461981771bSAli Ahmed             return;
14471981771bSAli Ahmed         }
14481981771bSAli Ahmed 
14491981771bSAli Ahmed         const std::string& path = subtree[0].first;
14501981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14511981771bSAli Ahmed 
14521981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14531e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14541e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14551e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1456ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1457ac106bf6SEd Tanous                         bool tpmRequired) {
14588a592810SEd Tanous             if (ec2)
14591981771bSAli Ahmed             {
1460002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
14618a592810SEd Tanous                                  << ec2;
1462ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14631981771bSAli Ahmed                 return;
14641981771bSAli Ahmed             }
14651981771bSAli Ahmed 
14661e1e598dSJonathan Doman             if (tpmRequired)
14671981771bSAli Ahmed             {
1468ac106bf6SEd Tanous                 asyncResp->res
1469ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14701981771bSAli Ahmed                     "Required";
14711981771bSAli Ahmed             }
14721981771bSAli Ahmed             else
14731981771bSAli Ahmed             {
1474ac106bf6SEd Tanous                 asyncResp->res
1475ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14761981771bSAli Ahmed                     "Disabled";
14771981771bSAli Ahmed             }
14781e1e598dSJonathan Doman             });
1479e99073f5SGeorge Liu         });
14801981771bSAli Ahmed }
14811981771bSAli Ahmed 
14821981771bSAli Ahmed /**
14831c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14841c05dae3SAli Ahmed  * TPM is required for booting the host.
14851c05dae3SAli Ahmed  *
1486ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14871c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14881c05dae3SAli Ahmed  *
14891c05dae3SAli Ahmed  * @return None.
14901c05dae3SAli Ahmed  */
14911c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1492ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14931c05dae3SAli Ahmed {
14941c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1495e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1496e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1497e99073f5SGeorge Liu     dbus::utility::getSubTree(
1498e99073f5SGeorge Liu         "/", 0, interfaces,
1499ac106bf6SEd Tanous         [asyncResp,
1500e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1501e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15021c05dae3SAli Ahmed         if (ec)
15031c05dae3SAli Ahmed         {
1504002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1505002d39b4SEd Tanous                              << ec;
1506ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15071c05dae3SAli Ahmed             return;
15081c05dae3SAli Ahmed         }
150926f6976fSEd Tanous         if (subtree.empty())
15101c05dae3SAli Ahmed         {
1511ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15121c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15131c05dae3SAli Ahmed             return;
15141c05dae3SAli Ahmed         }
15151c05dae3SAli Ahmed 
15161c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15171c05dae3SAli Ahmed         if (subtree.size() > 1)
15181c05dae3SAli Ahmed         {
15191c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
15201c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
15211c05dae3SAli Ahmed                 << subtree.size();
15221c05dae3SAli Ahmed             // Throw an internal Error and return
1523ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15241c05dae3SAli Ahmed             return;
15251c05dae3SAli Ahmed         }
15261c05dae3SAli Ahmed 
15271c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15281c05dae3SAli Ahmed         // field
15291c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15301c05dae3SAli Ahmed         {
15311c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1532ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15331c05dae3SAli Ahmed             return;
15341c05dae3SAli Ahmed         }
15351c05dae3SAli Ahmed 
15361c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15371c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15381c05dae3SAli Ahmed 
15391c05dae3SAli Ahmed         if (serv.empty())
15401c05dae3SAli Ahmed         {
15411c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1542ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15431c05dae3SAli Ahmed             return;
15441c05dae3SAli Ahmed         }
15451c05dae3SAli Ahmed 
15461c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15471c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
1548ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
15498a592810SEd Tanous             if (ec2)
15501c05dae3SAli Ahmed             {
15510fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
15520fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
15538a592810SEd Tanous                     << ec2;
1554ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15551c05dae3SAli Ahmed                 return;
15561c05dae3SAli Ahmed             }
15571c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15581c05dae3SAli Ahmed             },
15591c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
15601c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1561168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1562e99073f5SGeorge Liu         });
15631c05dae3SAli Ahmed }
15641c05dae3SAli Ahmed 
15651c05dae3SAli Ahmed /**
1566491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1567491d8ee7SSantosh Puranik  *
1568ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1569cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1570cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1571cd9a4666SKonstantin Aladyshev  */
1572ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1573cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1574cd9a4666SKonstantin Aladyshev {
1575c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1576cd9a4666SKonstantin Aladyshev 
1577c21865c4SKonstantin Aladyshev     if (!bootType)
1578cd9a4666SKonstantin Aladyshev     {
1579c21865c4SKonstantin Aladyshev         return;
1580c21865c4SKonstantin Aladyshev     }
1581c21865c4SKonstantin Aladyshev 
1582cd9a4666SKonstantin Aladyshev     // Source target specified
1583cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1584cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1585cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1586cd9a4666SKonstantin Aladyshev     {
1587cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1588cd9a4666SKonstantin Aladyshev     }
1589cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1590cd9a4666SKonstantin Aladyshev     {
1591cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1592cd9a4666SKonstantin Aladyshev     }
1593cd9a4666SKonstantin Aladyshev     else
1594cd9a4666SKonstantin Aladyshev     {
1595cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1596cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1597cd9a4666SKonstantin Aladyshev                          << *bootType;
1598ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1599cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1600cd9a4666SKonstantin Aladyshev         return;
1601cd9a4666SKonstantin Aladyshev     }
1602cd9a4666SKonstantin Aladyshev 
1603cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1604cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1605cd9a4666SKonstantin Aladyshev 
1606cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1607ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1608cd9a4666SKonstantin Aladyshev         if (ec)
1609cd9a4666SKonstantin Aladyshev         {
1610cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1611cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1612cd9a4666SKonstantin Aladyshev             {
1613ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1614cd9a4666SKonstantin Aladyshev                 return;
1615cd9a4666SKonstantin Aladyshev             }
1616ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1617cd9a4666SKonstantin Aladyshev             return;
1618cd9a4666SKonstantin Aladyshev         }
1619cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1620cd9a4666SKonstantin Aladyshev         },
1621c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1622c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1623cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1624cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1625168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1626cd9a4666SKonstantin Aladyshev }
1627cd9a4666SKonstantin Aladyshev 
1628cd9a4666SKonstantin Aladyshev /**
1629cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1630cd9a4666SKonstantin Aladyshev  *
1631ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1632ac106bf6SEd Tanous  * message.
1633c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1634c21865c4SKonstantin Aladyshev  * @return Integer error code.
1635c21865c4SKonstantin Aladyshev  */
1636ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1637c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1638c21865c4SKonstantin Aladyshev {
1639c21865c4SKonstantin Aladyshev     if (!bootEnable)
1640c21865c4SKonstantin Aladyshev     {
1641c21865c4SKonstantin Aladyshev         return;
1642c21865c4SKonstantin Aladyshev     }
1643c21865c4SKonstantin Aladyshev     // Source target specified
1644c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1645c21865c4SKonstantin Aladyshev 
1646c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1647c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1648c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1649c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1650c21865c4SKonstantin Aladyshev     {
1651c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1652c21865c4SKonstantin Aladyshev     }
1653c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1654c21865c4SKonstantin Aladyshev     {
1655c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1656c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1657c21865c4SKonstantin Aladyshev     }
1658c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1659c21865c4SKonstantin Aladyshev     {
1660c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1661c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1662c21865c4SKonstantin Aladyshev     }
1663c21865c4SKonstantin Aladyshev     else
1664c21865c4SKonstantin Aladyshev     {
16650fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16660fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1667c21865c4SKonstantin Aladyshev             << *bootEnable;
1668ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1669c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1670c21865c4SKonstantin Aladyshev         return;
1671c21865c4SKonstantin Aladyshev     }
1672c21865c4SKonstantin Aladyshev 
1673c21865c4SKonstantin Aladyshev     // Act on validated parameters
1674c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1675c21865c4SKonstantin Aladyshev 
1676c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1677ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
16788a592810SEd Tanous         if (ec2)
1679c21865c4SKonstantin Aladyshev         {
16808a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1681ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1682c21865c4SKonstantin Aladyshev             return;
1683c21865c4SKonstantin Aladyshev         }
1684c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1685c21865c4SKonstantin Aladyshev         },
1686c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1687c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1688c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1689c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1690168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1691c21865c4SKonstantin Aladyshev 
1692c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1693c21865c4SKonstantin Aladyshev     {
1694c21865c4SKonstantin Aladyshev         return;
1695c21865c4SKonstantin Aladyshev     }
1696c21865c4SKonstantin Aladyshev 
1697c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1698c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1699c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1700c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1701c21865c4SKonstantin Aladyshev 
1702c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1703ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1704c21865c4SKonstantin Aladyshev         if (ec)
1705c21865c4SKonstantin Aladyshev         {
1706c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1707ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1708c21865c4SKonstantin Aladyshev             return;
1709c21865c4SKonstantin Aladyshev         }
1710c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1711c21865c4SKonstantin Aladyshev         },
1712c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1713c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1714c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1715c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1716168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1717c21865c4SKonstantin Aladyshev }
1718c21865c4SKonstantin Aladyshev 
1719c21865c4SKonstantin Aladyshev /**
1720c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1721c21865c4SKonstantin Aladyshev  *
1722ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1723491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1724491d8ee7SSantosh Puranik  *
1725265c1602SJohnathan Mantey  * @return Integer error code.
1726491d8ee7SSantosh Puranik  */
1727ac106bf6SEd Tanous inline void
1728ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1729cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1730491d8ee7SSantosh Puranik {
1731c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1732c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1733944ffaf9SJohnathan Mantey 
1734c21865c4SKonstantin Aladyshev     if (!bootSource)
1735491d8ee7SSantosh Puranik     {
1736c21865c4SKonstantin Aladyshev         return;
1737c21865c4SKonstantin Aladyshev     }
1738c21865c4SKonstantin Aladyshev 
1739491d8ee7SSantosh Puranik     // Source target specified
1740491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1741491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1742ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1743ac106bf6SEd Tanous                              bootModeStr) != 0)
1744491d8ee7SSantosh Puranik     {
1745944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1746944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1747491d8ee7SSantosh Puranik             << *bootSource;
1748ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1749491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1750491d8ee7SSantosh Puranik         return;
1751491d8ee7SSantosh Puranik     }
1752491d8ee7SSantosh Puranik 
1753944ffaf9SJohnathan Mantey     // Act on validated parameters
1754944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1755944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1756944ffaf9SJohnathan Mantey 
1757491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1758ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1759491d8ee7SSantosh Puranik         if (ec)
1760491d8ee7SSantosh Puranik         {
1761491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1762ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1763491d8ee7SSantosh Puranik             return;
1764491d8ee7SSantosh Puranik         }
1765491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1766491d8ee7SSantosh Puranik         },
1767c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1768c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1769491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1770491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1771168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1772944ffaf9SJohnathan Mantey 
1773491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1774ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1775491d8ee7SSantosh Puranik         if (ec)
1776491d8ee7SSantosh Puranik         {
1777491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1778ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1779491d8ee7SSantosh Puranik             return;
1780491d8ee7SSantosh Puranik         }
1781491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1782491d8ee7SSantosh Puranik         },
1783c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1784c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1785491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1786491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1787168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1788cd9a4666SKonstantin Aladyshev }
1789944ffaf9SJohnathan Mantey 
1790cd9a4666SKonstantin Aladyshev /**
1791c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1792491d8ee7SSantosh Puranik  *
1793ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1794491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1795cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1796491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1797491d8ee7SSantosh Puranik  *
1798265c1602SJohnathan Mantey  * @return Integer error code.
1799491d8ee7SSantosh Puranik  */
1800c21865c4SKonstantin Aladyshev 
1801ac106bf6SEd Tanous inline void
1802ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1803c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1804c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1805c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1806491d8ee7SSantosh Puranik {
1807491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1808491d8ee7SSantosh Puranik 
1809ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1810ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1811ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1812491d8ee7SSantosh Puranik }
1813491d8ee7SSantosh Puranik 
1814c6a620f2SGeorge Liu /**
181598e386ecSGunnar Mills  * @brief Sets AssetTag
181698e386ecSGunnar Mills  *
1817ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
181898e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
181998e386ecSGunnar Mills  *
182098e386ecSGunnar Mills  * @return None.
182198e386ecSGunnar Mills  */
1822ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
182398e386ecSGunnar Mills                         const std::string& assetTag)
182498e386ecSGunnar Mills {
1825e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1826e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1827e99073f5SGeorge Liu     dbus::utility::getSubTree(
1828e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1829ac106bf6SEd Tanous         [asyncResp,
1830e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1831b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
183298e386ecSGunnar Mills         if (ec)
183398e386ecSGunnar Mills         {
183498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1835ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
183698e386ecSGunnar Mills             return;
183798e386ecSGunnar Mills         }
183826f6976fSEd Tanous         if (subtree.empty())
183998e386ecSGunnar Mills         {
184098e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1841ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
184298e386ecSGunnar Mills             return;
184398e386ecSGunnar Mills         }
184498e386ecSGunnar Mills         // Assume only 1 system D-Bus object
184598e386ecSGunnar Mills         // Throw an error if there is more than 1
184698e386ecSGunnar Mills         if (subtree.size() > 1)
184798e386ecSGunnar Mills         {
184898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1849ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
185098e386ecSGunnar Mills             return;
185198e386ecSGunnar Mills         }
185298e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
185398e386ecSGunnar Mills         {
185498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1855ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
185698e386ecSGunnar Mills             return;
185798e386ecSGunnar Mills         }
185898e386ecSGunnar Mills 
185998e386ecSGunnar Mills         const std::string& path = subtree[0].first;
186098e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
186198e386ecSGunnar Mills 
186298e386ecSGunnar Mills         if (service.empty())
186398e386ecSGunnar Mills         {
186498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1865ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
186698e386ecSGunnar Mills             return;
186798e386ecSGunnar Mills         }
186898e386ecSGunnar Mills 
186998e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
1870ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
187198e386ecSGunnar Mills             if (ec2)
187298e386ecSGunnar Mills             {
1873002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1874002d39b4SEd Tanous                                  << ec2;
1875ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
187698e386ecSGunnar Mills                 return;
187798e386ecSGunnar Mills             }
187898e386ecSGunnar Mills             },
187998e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
188098e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1881168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1882e99073f5SGeorge Liu         });
188398e386ecSGunnar Mills }
188498e386ecSGunnar Mills 
188598e386ecSGunnar Mills /**
188669f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
188769f35306SGunnar Mills  *
1888ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
188969f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
189069f35306SGunnar Mills  *
189169f35306SGunnar Mills  * @return None.
189269f35306SGunnar Mills  */
1893ac106bf6SEd Tanous inline void
1894ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1895f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
189669f35306SGunnar Mills {
189769f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
189869f35306SGunnar Mills 
189969f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1900543f4400SEd Tanous     bool autoRebootEnabled = false;
190169f35306SGunnar Mills 
190269f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
190369f35306SGunnar Mills     {
190469f35306SGunnar Mills         autoRebootEnabled = false;
190569f35306SGunnar Mills     }
190669f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
190769f35306SGunnar Mills     {
190869f35306SGunnar Mills         autoRebootEnabled = true;
190969f35306SGunnar Mills     }
191069f35306SGunnar Mills     else
191169f35306SGunnar Mills     {
19120fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
191369f35306SGunnar Mills                          << automaticRetryConfig;
1914ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
191569f35306SGunnar Mills                                          "AutomaticRetryConfig");
191669f35306SGunnar Mills         return;
191769f35306SGunnar Mills     }
191869f35306SGunnar Mills 
191969f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
1920ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
192169f35306SGunnar Mills         if (ec)
192269f35306SGunnar Mills         {
1923ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
192469f35306SGunnar Mills             return;
192569f35306SGunnar Mills         }
192669f35306SGunnar Mills         },
192769f35306SGunnar Mills         "xyz.openbmc_project.Settings",
192869f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
192969f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
193069f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1931168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
193269f35306SGunnar Mills }
193369f35306SGunnar Mills 
193469f35306SGunnar Mills /**
1935c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1936c6a620f2SGeorge Liu  *
1937ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1938c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1939c6a620f2SGeorge Liu  *
1940c6a620f2SGeorge Liu  * @return None.
1941c6a620f2SGeorge Liu  */
19428d1b46d7Szhanghch05 inline void
1943ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19444e69c904SGunnar Mills                           const std::string& policy)
1945c6a620f2SGeorge Liu {
1946c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1947c6a620f2SGeorge Liu 
1948c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
19490fda0f12SGeorge Liu         {"AlwaysOn",
19500fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
19510fda0f12SGeorge Liu         {"AlwaysOff",
19520fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
19530fda0f12SGeorge Liu         {"LastState",
19540fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1955c6a620f2SGeorge Liu 
1956c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1957c6a620f2SGeorge Liu 
19584e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1959c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1960c6a620f2SGeorge Liu     {
1961ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19624e69c904SGunnar Mills                                          "PowerRestorePolicy");
1963c6a620f2SGeorge Liu         return;
1964c6a620f2SGeorge Liu     }
1965c6a620f2SGeorge Liu 
1966c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1967c6a620f2SGeorge Liu 
1968c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1969ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1970c6a620f2SGeorge Liu         if (ec)
1971c6a620f2SGeorge Liu         {
1972ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1973c6a620f2SGeorge Liu             return;
1974c6a620f2SGeorge Liu         }
1975c6a620f2SGeorge Liu         },
1976c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1977c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1978c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1979c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1980168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1981c6a620f2SGeorge Liu }
1982c6a620f2SGeorge Liu 
1983a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1984a6349918SAppaRao Puli /**
1985a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1986a6349918SAppaRao Puli  *
1987ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
1988a6349918SAppaRao Puli  *
1989a6349918SAppaRao Puli  * @return None.
1990a6349918SAppaRao Puli  */
1991ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
1992a6349918SAppaRao Puli {
1993a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1994bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1995bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1996bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1997ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1998b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1999b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2000ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2001ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
200250626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
200350626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
200450626f4fSJames Feist 
2005a6349918SAppaRao Puli         if (ec)
2006a6349918SAppaRao Puli         {
2007a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2008b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2009b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2010a6349918SAppaRao Puli             return;
2011a6349918SAppaRao Puli         }
2012a6349918SAppaRao Puli 
2013a6349918SAppaRao Puli         const bool* provState = nullptr;
2014a6349918SAppaRao Puli         const bool* lockState = nullptr;
2015bc1d29deSKrzysztof Grobelny 
2016bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
20170d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
20180d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2019bc1d29deSKrzysztof Grobelny 
2020bc1d29deSKrzysztof Grobelny         if (!success)
2021a6349918SAppaRao Puli         {
2022ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2023bc1d29deSKrzysztof Grobelny             return;
2024a6349918SAppaRao Puli         }
2025a6349918SAppaRao Puli 
2026a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2027a6349918SAppaRao Puli         {
2028a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
2029ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2030a6349918SAppaRao Puli             return;
2031a6349918SAppaRao Puli         }
2032a6349918SAppaRao Puli 
2033a6349918SAppaRao Puli         if (*provState == true)
2034a6349918SAppaRao Puli         {
2035a6349918SAppaRao Puli             if (*lockState == true)
2036a6349918SAppaRao Puli             {
2037a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2038a6349918SAppaRao Puli             }
2039a6349918SAppaRao Puli             else
2040a6349918SAppaRao Puli             {
2041a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2042a6349918SAppaRao Puli             }
2043a6349918SAppaRao Puli         }
2044a6349918SAppaRao Puli         else
2045a6349918SAppaRao Puli         {
2046a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2047a6349918SAppaRao Puli         }
2048bc1d29deSKrzysztof Grobelny         });
2049a6349918SAppaRao Puli }
2050a6349918SAppaRao Puli #endif
2051a6349918SAppaRao Puli 
2052491d8ee7SSantosh Puranik /**
20533a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20543a2d0424SChris Cain  *
2055ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
20563a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20573a2d0424SChris Cain  *
20583a2d0424SChris Cain  * @return None.
20593a2d0424SChris Cain  */
2060ac106bf6SEd Tanous inline void
2061ac106bf6SEd Tanous     translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20623a2d0424SChris Cain                        const std::string& modeValue)
20633a2d0424SChris Cain {
20640fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20653a2d0424SChris Cain     {
2066ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "Static";
20673a2d0424SChris Cain     }
20680fda0f12SGeorge Liu     else if (
20690fda0f12SGeorge Liu         modeValue ==
20700fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20713a2d0424SChris Cain     {
2072ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20733a2d0424SChris Cain     }
20740fda0f12SGeorge Liu     else if (modeValue ==
20750fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20763a2d0424SChris Cain     {
2077ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
20783a2d0424SChris Cain     }
20790fda0f12SGeorge Liu     else if (modeValue ==
20800fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20813a2d0424SChris Cain     {
2082ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "OEM";
20833a2d0424SChris Cain     }
20843a2d0424SChris Cain     else
20853a2d0424SChris Cain     {
20863a2d0424SChris Cain         // Any other values would be invalid
20873a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
2088ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
20893a2d0424SChris Cain     }
20903a2d0424SChris Cain }
20913a2d0424SChris Cain 
20923a2d0424SChris Cain /**
20933a2d0424SChris Cain  * @brief Retrieves system power mode
20943a2d0424SChris Cain  *
2095ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
20963a2d0424SChris Cain  *
20973a2d0424SChris Cain  * @return None.
20983a2d0424SChris Cain  */
2099ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21003a2d0424SChris Cain {
21013a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
21023a2d0424SChris Cain 
21033a2d0424SChris Cain     // Get Power Mode object path:
2104e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2105e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2106e99073f5SGeorge Liu     dbus::utility::getSubTree(
2107e99073f5SGeorge Liu         "/", 0, interfaces,
2108ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2109b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21103a2d0424SChris Cain         if (ec)
21113a2d0424SChris Cain         {
2112002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2113002d39b4SEd Tanous                              << ec;
21143a2d0424SChris Cain             // This is an optional D-Bus object so just return if
21153a2d0424SChris Cain             // error occurs
21163a2d0424SChris Cain             return;
21173a2d0424SChris Cain         }
21183a2d0424SChris Cain         if (subtree.empty())
21193a2d0424SChris Cain         {
21203a2d0424SChris Cain             // As noted above, this is an optional interface so just return
21213a2d0424SChris Cain             // if there is no instance found
21223a2d0424SChris Cain             return;
21233a2d0424SChris Cain         }
21243a2d0424SChris Cain         if (subtree.size() > 1)
21253a2d0424SChris Cain         {
21263a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21273a2d0424SChris Cain             // error
21283a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21293a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21303a2d0424SChris Cain                 << subtree.size();
2131ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21323a2d0424SChris Cain             return;
21333a2d0424SChris Cain         }
21343a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21353a2d0424SChris Cain         {
21363a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2137ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21383a2d0424SChris Cain             return;
21393a2d0424SChris Cain         }
21403a2d0424SChris Cain         const std::string& path = subtree[0].first;
21413a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21423a2d0424SChris Cain         if (service.empty())
21433a2d0424SChris Cain         {
21443a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2145ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21463a2d0424SChris Cain             return;
21473a2d0424SChris Cain         }
21483a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
21491e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
21501e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
21511e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2152ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
21531e1e598dSJonathan Doman                         const std::string& pmode) {
21548a592810SEd Tanous             if (ec2)
21553a2d0424SChris Cain             {
2156002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
21578a592810SEd Tanous                                  << ec2;
2158ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21593a2d0424SChris Cain                 return;
21603a2d0424SChris Cain             }
21613a2d0424SChris Cain 
2162ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2163002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
21643a2d0424SChris Cain 
21651e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2166ac106bf6SEd Tanous             translatePowerMode(asyncResp, pmode);
21671e1e598dSJonathan Doman             });
2168e99073f5SGeorge Liu         });
21693a2d0424SChris Cain }
21703a2d0424SChris Cain 
21713a2d0424SChris Cain /**
21723a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21733a2d0424SChris Cain  * name associated with that string
21743a2d0424SChris Cain  *
2175ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
21763a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21773a2d0424SChris Cain  *
21783a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21793a2d0424SChris Cain  */
21803a2d0424SChris Cain inline std::string
2181ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21823a2d0424SChris Cain                       const std::string& modeString)
21833a2d0424SChris Cain {
21843a2d0424SChris Cain     std::string mode;
21853a2d0424SChris Cain 
21863a2d0424SChris Cain     if (modeString == "Static")
21873a2d0424SChris Cain     {
21883a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21893a2d0424SChris Cain     }
21903a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21913a2d0424SChris Cain     {
21920fda0f12SGeorge Liu         mode =
21930fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21943a2d0424SChris Cain     }
21953a2d0424SChris Cain     else if (modeString == "PowerSaving")
21963a2d0424SChris Cain     {
21973a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21983a2d0424SChris Cain     }
21993a2d0424SChris Cain     else
22003a2d0424SChris Cain     {
2201ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, modeString,
2202ac106bf6SEd Tanous                                          "PowerMode");
22033a2d0424SChris Cain     }
22043a2d0424SChris Cain     return mode;
22053a2d0424SChris Cain }
22063a2d0424SChris Cain 
22073a2d0424SChris Cain /**
22083a2d0424SChris Cain  * @brief Sets system power mode.
22093a2d0424SChris Cain  *
2210ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22113a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22123a2d0424SChris Cain  *
22133a2d0424SChris Cain  * @return None.
22143a2d0424SChris Cain  */
2215ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22163a2d0424SChris Cain                          const std::string& pmode)
22173a2d0424SChris Cain {
22183a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
22193a2d0424SChris Cain 
2220ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22213a2d0424SChris Cain     if (powerMode.empty())
22223a2d0424SChris Cain     {
22233a2d0424SChris Cain         return;
22243a2d0424SChris Cain     }
22253a2d0424SChris Cain 
22263a2d0424SChris Cain     // Get Power Mode object path:
2227e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2228e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2229e99073f5SGeorge Liu     dbus::utility::getSubTree(
2230e99073f5SGeorge Liu         "/", 0, interfaces,
2231ac106bf6SEd Tanous         [asyncResp,
2232e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2233b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22343a2d0424SChris Cain         if (ec)
22353a2d0424SChris Cain         {
2236002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2237002d39b4SEd Tanous                              << ec;
22383a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2239ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22403a2d0424SChris Cain             return;
22413a2d0424SChris Cain         }
22423a2d0424SChris Cain         if (subtree.empty())
22433a2d0424SChris Cain         {
22443a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2245ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22463a2d0424SChris Cain                                        "PowerMode");
22473a2d0424SChris Cain             return;
22483a2d0424SChris Cain         }
22493a2d0424SChris Cain         if (subtree.size() > 1)
22503a2d0424SChris Cain         {
22513a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22523a2d0424SChris Cain             // error
22533a2d0424SChris Cain             BMCWEB_LOG_DEBUG
22543a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
22553a2d0424SChris Cain                 << subtree.size();
2256ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22573a2d0424SChris Cain             return;
22583a2d0424SChris Cain         }
22593a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22603a2d0424SChris Cain         {
22613a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2262ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22633a2d0424SChris Cain             return;
22643a2d0424SChris Cain         }
22653a2d0424SChris Cain         const std::string& path = subtree[0].first;
22663a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22673a2d0424SChris Cain         if (service.empty())
22683a2d0424SChris Cain         {
22693a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2270ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22713a2d0424SChris Cain             return;
22723a2d0424SChris Cain         }
22733a2d0424SChris Cain 
22743a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22753a2d0424SChris Cain                          << path;
22763a2d0424SChris Cain 
22773a2d0424SChris Cain         // Set the Power Mode property
22783a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
2279ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
22808a592810SEd Tanous             if (ec2)
22813a2d0424SChris Cain             {
2282ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22833a2d0424SChris Cain                 return;
22843a2d0424SChris Cain             }
22853a2d0424SChris Cain             },
22863a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
22873a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2288168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2289e99073f5SGeorge Liu         });
22903a2d0424SChris Cain }
22913a2d0424SChris Cain 
22923a2d0424SChris Cain /**
229351709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
229451709ffdSYong Li  *
229551709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
229651709ffdSYong Li  *
229751709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
229851709ffdSYong Li  * translation cannot be done, returns an empty string.
229951709ffdSYong Li  */
230023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
230151709ffdSYong Li {
230251709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
230351709ffdSYong Li     {
230451709ffdSYong Li         return "None";
230551709ffdSYong Li     }
23063174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
230751709ffdSYong Li     {
230851709ffdSYong Li         return "ResetSystem";
230951709ffdSYong Li     }
23103174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
231151709ffdSYong Li     {
231251709ffdSYong Li         return "PowerDown";
231351709ffdSYong Li     }
23143174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
231551709ffdSYong Li     {
231651709ffdSYong Li         return "PowerCycle";
231751709ffdSYong Li     }
231851709ffdSYong Li 
231951709ffdSYong Li     return "";
232051709ffdSYong Li }
232151709ffdSYong Li 
232251709ffdSYong Li /**
2323c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2324c45f0082SYong Li  *
2325c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2326c45f0082SYong Li  *
2327c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2328c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2329c45f0082SYong Li  */
2330c45f0082SYong Li 
233123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2332c45f0082SYong Li {
2333c45f0082SYong Li     if (rfAction == "None")
2334c45f0082SYong Li     {
2335c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2336c45f0082SYong Li     }
23373174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2338c45f0082SYong Li     {
2339c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2340c45f0082SYong Li     }
23413174e4dfSEd Tanous     if (rfAction == "PowerDown")
2342c45f0082SYong Li     {
2343c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2344c45f0082SYong Li     }
23453174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2346c45f0082SYong Li     {
2347c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2348c45f0082SYong Li     }
2349c45f0082SYong Li 
2350c45f0082SYong Li     return "";
2351c45f0082SYong Li }
2352c45f0082SYong Li 
2353c45f0082SYong Li /**
235451709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
235551709ffdSYong Li  *
2356ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
235751709ffdSYong Li  *
235851709ffdSYong Li  * @return None.
235951709ffdSYong Li  */
23608d1b46d7Szhanghch05 inline void
2361ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
236251709ffdSYong Li {
236351709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2364bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2365bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2366bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2367bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2368ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2369b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
237051709ffdSYong Li         if (ec)
237151709ffdSYong Li         {
237251709ffdSYong Li             // watchdog service is stopped
237351709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
237451709ffdSYong Li             return;
237551709ffdSYong Li         }
237651709ffdSYong Li 
237751709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
237851709ffdSYong Li 
237951709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2380ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
238151709ffdSYong Li 
238251709ffdSYong Li         // watchdog service is running/enabled
238351709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
238451709ffdSYong Li 
2385bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2386bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
238751709ffdSYong Li 
2388bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2389bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2390bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2391bc1d29deSKrzysztof Grobelny 
2392bc1d29deSKrzysztof Grobelny         if (!success)
239351709ffdSYong Li         {
2394ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2395601af5edSChicago Duan             return;
239651709ffdSYong Li         }
239751709ffdSYong Li 
2398bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
239951709ffdSYong Li         {
2400bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
240151709ffdSYong Li         }
240251709ffdSYong Li 
2403bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2404bc1d29deSKrzysztof Grobelny         {
2405bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
240651709ffdSYong Li             if (action.empty())
240751709ffdSYong Li             {
2408ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2409601af5edSChicago Duan                 return;
241051709ffdSYong Li             }
241151709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
241251709ffdSYong Li         }
2413bc1d29deSKrzysztof Grobelny         });
241451709ffdSYong Li }
241551709ffdSYong Li 
241651709ffdSYong Li /**
2417c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2418c45f0082SYong Li  *
2419ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2420c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2421c45f0082SYong Li  *                       RF request.
2422c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2423c45f0082SYong Li  *
2424c45f0082SYong Li  * @return None.
2425c45f0082SYong Li  */
2426ac106bf6SEd Tanous inline void
2427ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2428c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2429c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2430c45f0082SYong Li {
2431c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2432c45f0082SYong Li 
2433c45f0082SYong Li     if (wdtTimeOutAction)
2434c45f0082SYong Li     {
2435c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2436c45f0082SYong Li         // check if TimeOut Action is Valid
2437c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2438c45f0082SYong Li         {
2439c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2440c45f0082SYong Li                              << *wdtTimeOutAction;
2441ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2442c45f0082SYong Li                                              "TimeoutAction");
2443c45f0082SYong Li             return;
2444c45f0082SYong Li         }
2445c45f0082SYong Li 
2446c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2447ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2448c45f0082SYong Li             if (ec)
2449c45f0082SYong Li             {
2450c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2451ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2452c45f0082SYong Li                 return;
2453c45f0082SYong Li             }
2454c45f0082SYong Li             },
2455c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2456c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2457c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2458c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2459168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2460c45f0082SYong Li     }
2461c45f0082SYong Li 
2462c45f0082SYong Li     if (wdtEnable)
2463c45f0082SYong Li     {
2464c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2465ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2466c45f0082SYong Li             if (ec)
2467c45f0082SYong Li             {
2468c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2469ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2470c45f0082SYong Li                 return;
2471c45f0082SYong Li             }
2472c45f0082SYong Li             },
2473c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2474c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2475c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2476c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2477168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2478c45f0082SYong Li     }
2479c45f0082SYong Li }
2480c45f0082SYong Li 
248137bbf98cSChris Cain /**
248237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
248337bbf98cSChris Cain  *
2484ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
248537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
248637bbf98cSChris Cain  *
248737bbf98cSChris Cain  * @return true if successful
248837bbf98cSChris Cain  */
24891e5b7c88SJiaqing Zhao inline bool
2490ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24911e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
249237bbf98cSChris Cain {
2493bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2494bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2495bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2496bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2497bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2498bc1d29deSKrzysztof Grobelny 
2499bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2500bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
25012661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
25022661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
25032661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2504bc1d29deSKrzysztof Grobelny 
2505bc1d29deSKrzysztof Grobelny     if (!success)
250637bbf98cSChris Cain     {
250737bbf98cSChris Cain         return false;
250837bbf98cSChris Cain     }
2509bc1d29deSKrzysztof Grobelny 
2510bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
251137bbf98cSChris Cain     {
2512ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
251337bbf98cSChris Cain     }
2514bc1d29deSKrzysztof Grobelny 
2515bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
251637bbf98cSChris Cain     {
2517ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2518bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
251937bbf98cSChris Cain     }
2520bc1d29deSKrzysztof Grobelny 
2521bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2522bc1d29deSKrzysztof Grobelny     {
2523bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2524ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
252537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
252637bbf98cSChris Cain                 .count();
252737bbf98cSChris Cain     }
2528bc1d29deSKrzysztof Grobelny 
2529bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
253037bbf98cSChris Cain     {
2531ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2532bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
253337bbf98cSChris Cain     }
2534bc1d29deSKrzysztof Grobelny 
2535bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
253637bbf98cSChris Cain     {
2537bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2538ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
253937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
254037bbf98cSChris Cain                 .count();
254137bbf98cSChris Cain     }
254237bbf98cSChris Cain 
254337bbf98cSChris Cain     return true;
254437bbf98cSChris Cain }
254537bbf98cSChris Cain 
254637bbf98cSChris Cain /**
254737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
254837bbf98cSChris Cain  *
2549ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
255037bbf98cSChris Cain  *
255137bbf98cSChris Cain  * @return None.
255237bbf98cSChris Cain  */
2553ac106bf6SEd Tanous inline void
2554ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
255537bbf98cSChris Cain {
255637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
255737bbf98cSChris Cain 
255837bbf98cSChris Cain     // Get IdlePowerSaver object path:
2559e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2560e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2561e99073f5SGeorge Liu     dbus::utility::getSubTree(
2562e99073f5SGeorge Liu         "/", 0, interfaces,
2563ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2564b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
256537bbf98cSChris Cain         if (ec)
256637bbf98cSChris Cain         {
256737bbf98cSChris Cain             BMCWEB_LOG_DEBUG
256837bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
256937bbf98cSChris Cain                 << ec;
2570ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
257137bbf98cSChris Cain             return;
257237bbf98cSChris Cain         }
257337bbf98cSChris Cain         if (subtree.empty())
257437bbf98cSChris Cain         {
257537bbf98cSChris Cain             // This is an optional interface so just return
257637bbf98cSChris Cain             // if there is no instance found
257737bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
257837bbf98cSChris Cain             return;
257937bbf98cSChris Cain         }
258037bbf98cSChris Cain         if (subtree.size() > 1)
258137bbf98cSChris Cain         {
258237bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
258337bbf98cSChris Cain             // is an error
258437bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
258537bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
258637bbf98cSChris Cain                              << subtree.size();
2587ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
258837bbf98cSChris Cain             return;
258937bbf98cSChris Cain         }
259037bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
259137bbf98cSChris Cain         {
259237bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2593ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
259437bbf98cSChris Cain             return;
259537bbf98cSChris Cain         }
259637bbf98cSChris Cain         const std::string& path = subtree[0].first;
259737bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
259837bbf98cSChris Cain         if (service.empty())
259937bbf98cSChris Cain         {
2600002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2601ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
260237bbf98cSChris Cain             return;
260337bbf98cSChris Cain         }
260437bbf98cSChris Cain 
260537bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2606bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2607bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2608bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2609ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
26101e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
26118a592810SEd Tanous             if (ec2)
261237bbf98cSChris Cain             {
261337bbf98cSChris Cain                 BMCWEB_LOG_ERROR
26148a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
2615ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261637bbf98cSChris Cain                 return;
261737bbf98cSChris Cain             }
261837bbf98cSChris Cain 
2619ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
262037bbf98cSChris Cain             {
2621ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
262237bbf98cSChris Cain                 return;
262337bbf98cSChris Cain             }
2624bc1d29deSKrzysztof Grobelny             });
2625e99073f5SGeorge Liu         });
262637bbf98cSChris Cain 
262737bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
262837bbf98cSChris Cain }
262937bbf98cSChris Cain 
263037bbf98cSChris Cain /**
263137bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
263237bbf98cSChris Cain  *
2633ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
263437bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
263537bbf98cSChris Cain  *                       RF request.
263637bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
263737bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
263837bbf98cSChris Cain  * before entering idle state.
263937bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
264037bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
264137bbf98cSChris Cain  * before exiting idle state
264237bbf98cSChris Cain  *
264337bbf98cSChris Cain  * @return None.
264437bbf98cSChris Cain  */
2645ac106bf6SEd Tanous inline void
2646ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
264737bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
264837bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
264937bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
265037bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
265137bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
265237bbf98cSChris Cain {
265337bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
265437bbf98cSChris Cain 
265537bbf98cSChris Cain     // Get IdlePowerSaver object path:
2656e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2657e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2658e99073f5SGeorge Liu     dbus::utility::getSubTree(
2659e99073f5SGeorge Liu         "/", 0, interfaces,
2660ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2661e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2662b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
266337bbf98cSChris Cain         if (ec)
266437bbf98cSChris Cain         {
266537bbf98cSChris Cain             BMCWEB_LOG_DEBUG
266637bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
266737bbf98cSChris Cain                 << ec;
2668ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
266937bbf98cSChris Cain             return;
267037bbf98cSChris Cain         }
267137bbf98cSChris Cain         if (subtree.empty())
267237bbf98cSChris Cain         {
267337bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2674ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
267537bbf98cSChris Cain                                        "IdlePowerSaver");
267637bbf98cSChris Cain             return;
267737bbf98cSChris Cain         }
267837bbf98cSChris Cain         if (subtree.size() > 1)
267937bbf98cSChris Cain         {
268037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
268137bbf98cSChris Cain             // is an error
26820fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
26830fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
268437bbf98cSChris Cain                 << subtree.size();
2685ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
268637bbf98cSChris Cain             return;
268737bbf98cSChris Cain         }
268837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
268937bbf98cSChris Cain         {
269037bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2691ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269237bbf98cSChris Cain             return;
269337bbf98cSChris Cain         }
269437bbf98cSChris Cain         const std::string& path = subtree[0].first;
269537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
269637bbf98cSChris Cain         if (service.empty())
269737bbf98cSChris Cain         {
2698002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2699ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
270037bbf98cSChris Cain             return;
270137bbf98cSChris Cain         }
270237bbf98cSChris Cain 
270337bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
270437bbf98cSChris Cain         // need to be updated
270537bbf98cSChris Cain 
270637bbf98cSChris Cain         if (ipsEnable)
270737bbf98cSChris Cain         {
270837bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2709ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
27108a592810SEd Tanous                 if (ec2)
271137bbf98cSChris Cain                 {
27128a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2713ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
271437bbf98cSChris Cain                     return;
271537bbf98cSChris Cain                 }
271637bbf98cSChris Cain                 },
271737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2718002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2719002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
272037bbf98cSChris Cain         }
272137bbf98cSChris Cain         if (ipsEnterUtil)
272237bbf98cSChris Cain         {
272337bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2724ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
27258a592810SEd Tanous                 if (ec2)
272637bbf98cSChris Cain                 {
27278a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2728ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
272937bbf98cSChris Cain                     return;
273037bbf98cSChris Cain                 }
273137bbf98cSChris Cain                 },
273237bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
273337bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
273437bbf98cSChris Cain                 "EnterUtilizationPercent",
2735168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
273637bbf98cSChris Cain         }
273737bbf98cSChris Cain         if (ipsEnterTime)
273837bbf98cSChris Cain         {
273937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
274037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
274137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2742ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
27438a592810SEd Tanous                 if (ec2)
274437bbf98cSChris Cain                 {
27458a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2746ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
274737bbf98cSChris Cain                     return;
274837bbf98cSChris Cain                 }
274937bbf98cSChris Cain                 },
275037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
275137bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2752168e20c1SEd Tanous                 "EnterDwellTime",
2753168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
275437bbf98cSChris Cain         }
275537bbf98cSChris Cain         if (ipsExitUtil)
275637bbf98cSChris Cain         {
275737bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2758ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
27598a592810SEd Tanous                 if (ec2)
276037bbf98cSChris Cain                 {
27618a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2762ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
276337bbf98cSChris Cain                     return;
276437bbf98cSChris Cain                 }
276537bbf98cSChris Cain                 },
276637bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
276737bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
276837bbf98cSChris Cain                 "ExitUtilizationPercent",
2769168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
277037bbf98cSChris Cain         }
277137bbf98cSChris Cain         if (ipsExitTime)
277237bbf98cSChris Cain         {
277337bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
277437bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
277537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
2776ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
27778a592810SEd Tanous                 if (ec2)
277837bbf98cSChris Cain                 {
27798a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2780ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
278137bbf98cSChris Cain                     return;
278237bbf98cSChris Cain                 }
278337bbf98cSChris Cain                 },
278437bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
278537bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2786168e20c1SEd Tanous                 "ExitDwellTime",
2787168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
278837bbf98cSChris Cain         }
2789e99073f5SGeorge Liu         });
279037bbf98cSChris Cain 
279137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
279237bbf98cSChris Cain }
279337bbf98cSChris Cain 
2794*c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2795dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2796dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2797dd60b9edSEd Tanous {
2798dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2799dd60b9edSEd Tanous     {
2800dd60b9edSEd Tanous         return;
2801dd60b9edSEd Tanous     }
2802dd60b9edSEd Tanous     asyncResp->res.addHeader(
2803dd60b9edSEd Tanous         boost::beast::http::field::link,
2804dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2805dd60b9edSEd Tanous }
2806dd60b9edSEd Tanous 
2807*c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2808*c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2809*c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28101abe55efSEd Tanous {
28113ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2812f4c99e70SEd Tanous     {
2813f4c99e70SEd Tanous         return;
2814f4c99e70SEd Tanous     }
2815dd60b9edSEd Tanous 
2816dd60b9edSEd Tanous     asyncResp->res.addHeader(
2817dd60b9edSEd Tanous         boost::beast::http::field::link,
2818dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28198d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
28200f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
28218d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28228d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2823462023adSSunitha Harish 
28247f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
28257f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
28267f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
28277f3e84a1SEd Tanous     {
28287f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
28297f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28307f3e84a1SEd Tanous         return;
28317f3e84a1SEd Tanous     }
28327f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
28337f3e84a1SEd Tanous     nlohmann::json::object_t system;
28347f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
28357f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
28361e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2837002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
28381e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2839002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
28405e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
28411e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
28427f3e84a1SEd Tanous         if (ec2)
2843462023adSSunitha Harish         {
28447f3e84a1SEd Tanous             return;
28457f3e84a1SEd Tanous         }
28467f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
28477f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
28487f3e84a1SEd Tanous         {
28497f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
28507f3e84a1SEd Tanous             return;
28517f3e84a1SEd Tanous         }
28527f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
28537f3e84a1SEd Tanous         if (count == nullptr)
28547f3e84a1SEd Tanous         {
28557f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
28567f3e84a1SEd Tanous             return;
28577f3e84a1SEd Tanous         }
28587f3e84a1SEd Tanous         *count = *count + 1;
2859462023adSSunitha Harish         BMCWEB_LOG_DEBUG << "Hypervisor is available";
28607f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
28611476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2862002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
28637f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
28641e1e598dSJonathan Doman         });
2865*c1e219d5SEd Tanous }
2866*c1e219d5SEd Tanous 
2867*c1e219d5SEd Tanous /**
2868*c1e219d5SEd Tanous  * SystemsCollection derived class for delivering ComputerSystems Collection
2869*c1e219d5SEd Tanous  * Schema
2870*c1e219d5SEd Tanous  */
2871*c1e219d5SEd Tanous inline void requestRoutesSystemsCollection(App& app)
2872*c1e219d5SEd Tanous {
2873*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2874*c1e219d5SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2875*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(
2876*c1e219d5SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
2877*c1e219d5SEd Tanous 
2878*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2879*c1e219d5SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
2880*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(
2881*c1e219d5SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
2882c5b2abe0SLewanczyk, Dawid }
28837e860f15SJohn Edward Broadbent 
28847e860f15SJohn Edward Broadbent /**
28857e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28867e860f15SJohn Edward Broadbent  */
28874f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28887e860f15SJohn Edward Broadbent {
288989492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
289089492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
289189492a15SPatrick Williams     constexpr const char* interfaceName =
28927e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
289389492a15SPatrick Williams     constexpr const char* method = "NMI";
28947e860f15SJohn Edward Broadbent 
28957e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28965e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28977e860f15SJohn Edward Broadbent         if (ec)
28987e860f15SJohn Edward Broadbent         {
28997e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
29007e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
29017e860f15SJohn Edward Broadbent             return;
29027e860f15SJohn Edward Broadbent         }
29037e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
29047e860f15SJohn Edward Broadbent         },
29057e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29067e860f15SJohn Edward Broadbent }
2907c5b2abe0SLewanczyk, Dawid 
2908c5b2abe0SLewanczyk, Dawid /**
2909fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
2910fc903b3dSAndrew Geissler  */
2911fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
2912fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
2913fc903b3dSAndrew Geissler                                          std::string_view resetType,
2914fc903b3dSAndrew Geissler                                          crow::Response& res)
2915fc903b3dSAndrew Geissler {
2916fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
2917fc903b3dSAndrew Geissler     {
2918fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
2919fc903b3dSAndrew Geissler         return;
2920fc903b3dSAndrew Geissler     }
2921fc903b3dSAndrew Geissler 
2922fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
2923fc903b3dSAndrew Geissler     {
2924fc903b3dSAndrew Geissler         BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2925fc903b3dSAndrew Geissler         messages::internalError(res);
2926fc903b3dSAndrew Geissler         return;
2927fc903b3dSAndrew Geissler     }
2928fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
2929fc903b3dSAndrew Geissler 
2930fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
2931fc903b3dSAndrew Geissler     // user to retry in a bit
2932fc903b3dSAndrew Geissler     if ((errorMessage ==
2933fc903b3dSAndrew Geissler          std::string_view(
2934fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2935fc903b3dSAndrew Geissler         (errorMessage ==
2936fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2937fc903b3dSAndrew Geissler     {
2938fc903b3dSAndrew Geissler         BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2939fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
2940fc903b3dSAndrew Geissler         return;
2941fc903b3dSAndrew Geissler     }
2942fc903b3dSAndrew Geissler 
2943fc903b3dSAndrew Geissler     BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2944fc903b3dSAndrew Geissler                      << " sdbusplus:" << errorMessage;
2945fc903b3dSAndrew Geissler     messages::internalError(res);
2946fc903b3dSAndrew Geissler }
2947fc903b3dSAndrew Geissler 
2948*c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2949*c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
29507f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2951*c1e219d5SEd Tanous     const std::string& systemName)
2952*c1e219d5SEd Tanous {
29533ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
295445ca1b86SEd Tanous     {
295545ca1b86SEd Tanous         return;
295645ca1b86SEd Tanous     }
2957*c1e219d5SEd Tanous     if (systemName != "system")
2958*c1e219d5SEd Tanous     {
2959*c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2960*c1e219d5SEd Tanous                                    systemName);
2961*c1e219d5SEd Tanous         return;
2962*c1e219d5SEd Tanous     }
29637f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29647f3e84a1SEd Tanous     {
29657f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29667f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2967*c1e219d5SEd Tanous                                    systemName);
29687f3e84a1SEd Tanous         return;
29697f3e84a1SEd Tanous     }
29709712f8acSEd Tanous     std::string resetType;
2971*c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2972cc340dd9SEd Tanous     {
2973cc340dd9SEd Tanous         return;
2974cc340dd9SEd Tanous     }
2975cc340dd9SEd Tanous 
2976d22c8396SJason M. Bills     // Get the command and host vs. chassis
2977cc340dd9SEd Tanous     std::string command;
2978543f4400SEd Tanous     bool hostCommand = true;
2979d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2980cc340dd9SEd Tanous     {
2981cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2982d22c8396SJason M. Bills         hostCommand = true;
2983d22c8396SJason M. Bills     }
2984d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2985d22c8396SJason M. Bills     {
2986d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2987d22c8396SJason M. Bills         hostCommand = false;
2988d22c8396SJason M. Bills     }
2989d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2990d22c8396SJason M. Bills     {
2991*c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
299286a0851aSJason M. Bills         hostCommand = true;
2993cc340dd9SEd Tanous     }
29949712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2995cc340dd9SEd Tanous     {
2996cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2997d22c8396SJason M. Bills         hostCommand = true;
2998cc340dd9SEd Tanous     }
29999712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3000cc340dd9SEd Tanous     {
30010fda0f12SGeorge Liu         command =
30020fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3003d22c8396SJason M. Bills         hostCommand = true;
3004d22c8396SJason M. Bills     }
3005d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3006d22c8396SJason M. Bills     {
300786a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
300886a0851aSJason M. Bills         hostCommand = true;
3009cc340dd9SEd Tanous     }
3010bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3011bfd5b826SLakshminarayana R. Kammath     {
3012bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3013bfd5b826SLakshminarayana R. Kammath         return;
3014bfd5b826SLakshminarayana R. Kammath     }
3015cc340dd9SEd Tanous     else
3016cc340dd9SEd Tanous     {
3017*c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3018cc340dd9SEd Tanous         return;
3019cc340dd9SEd Tanous     }
3020cc340dd9SEd Tanous 
3021d22c8396SJason M. Bills     if (hostCommand)
3022d22c8396SJason M. Bills     {
3023cc340dd9SEd Tanous         crow::connections::systemBus->async_method_call(
3024fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3025fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3026cc340dd9SEd Tanous             if (ec)
3027cc340dd9SEd Tanous             {
3028fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3029fc903b3dSAndrew Geissler                                              asyncResp->res);
3030fc903b3dSAndrew Geissler 
3031cc340dd9SEd Tanous                 return;
3032cc340dd9SEd Tanous             }
3033f12894f8SJason M. Bills             messages::success(asyncResp->res);
3034cc340dd9SEd Tanous             },
3035cc340dd9SEd Tanous             "xyz.openbmc_project.State.Host",
3036cc340dd9SEd Tanous             "/xyz/openbmc_project/state/host0",
3037cc340dd9SEd Tanous             "org.freedesktop.DBus.Properties", "Set",
30389712f8acSEd Tanous             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3039168e20c1SEd Tanous             dbus::utility::DbusVariantType{command});
3040cc340dd9SEd Tanous     }
3041d22c8396SJason M. Bills     else
3042d22c8396SJason M. Bills     {
3043d22c8396SJason M. Bills         crow::connections::systemBus->async_method_call(
3044fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3045fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3046d22c8396SJason M. Bills             if (ec)
3047d22c8396SJason M. Bills             {
3048fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3049fc903b3dSAndrew Geissler                                              asyncResp->res);
3050d22c8396SJason M. Bills                 return;
3051d22c8396SJason M. Bills             }
3052d22c8396SJason M. Bills             messages::success(asyncResp->res);
3053d22c8396SJason M. Bills             },
3054d22c8396SJason M. Bills             "xyz.openbmc_project.State.Chassis",
3055d22c8396SJason M. Bills             "/xyz/openbmc_project/state/chassis0",
3056d22c8396SJason M. Bills             "org.freedesktop.DBus.Properties", "Set",
3057002d39b4SEd Tanous             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3058168e20c1SEd Tanous             dbus::utility::DbusVariantType{command});
3059d22c8396SJason M. Bills     }
3060d22c8396SJason M. Bills }
3061cc340dd9SEd Tanous 
3062*c1e219d5SEd Tanous /**
3063*c1e219d5SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
3064*c1e219d5SEd Tanous  * The class retrieves and sends data directly to D-Bus.
3065*c1e219d5SEd Tanous  */
3066*c1e219d5SEd Tanous inline void requestRoutesSystemActionsReset(App& app)
3067*c1e219d5SEd Tanous {
3068*c1e219d5SEd Tanous     /**
3069*c1e219d5SEd Tanous      * Function handles POST method request.
3070*c1e219d5SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
3071*c1e219d5SEd Tanous      */
3072*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3073*c1e219d5SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3074*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3075*c1e219d5SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3076*c1e219d5SEd Tanous }
3077*c1e219d5SEd Tanous 
3078*c1e219d5SEd Tanous inline void handleComputerSystemHead(
3079dd60b9edSEd Tanous     App& app, const crow::Request& req,
30807f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30817f3e84a1SEd Tanous     const std::string& /*systemName*/)
3082dd60b9edSEd Tanous {
3083dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3084dd60b9edSEd Tanous     {
3085dd60b9edSEd Tanous         return;
3086dd60b9edSEd Tanous     }
3087dd60b9edSEd Tanous 
3088dd60b9edSEd Tanous     asyncResp->res.addHeader(
3089dd60b9edSEd Tanous         boost::beast::http::field::link,
3090dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3091dd60b9edSEd Tanous }
3092dd60b9edSEd Tanous 
30935c3e9272SAbhishek Patel inline void afterPortRequest(
30945c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30955c3e9272SAbhishek Patel     const boost::system::error_code& ec,
30965c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
30975c3e9272SAbhishek Patel {
30985c3e9272SAbhishek Patel     if (ec)
30995c3e9272SAbhishek Patel     {
31005c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
31015c3e9272SAbhishek Patel         return;
31025c3e9272SAbhishek Patel     }
31035c3e9272SAbhishek Patel     for (const auto& data : socketData)
31045c3e9272SAbhishek Patel     {
31055c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
31065c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
31075c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
31085c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
31095c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
31105c3e9272SAbhishek Patel         // need to retrieve port number for
31115c3e9272SAbhishek Patel         // obmc-console-ssh service
31125c3e9272SAbhishek Patel         if (protocolName == "SSH")
31135c3e9272SAbhishek Patel         {
31145c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
311581c4e330SEd Tanous                                           const boost::system::error_code& ec1,
31165c3e9272SAbhishek Patel                                           int portNumber) {
31175c3e9272SAbhishek Patel                 if (ec1)
31185c3e9272SAbhishek Patel                 {
31195c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
31205c3e9272SAbhishek Patel                     return;
31215c3e9272SAbhishek Patel                 }
31225c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
31235c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
31245c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
31255c3e9272SAbhishek Patel             });
31265c3e9272SAbhishek Patel         }
31275c3e9272SAbhishek Patel     }
31285c3e9272SAbhishek Patel }
3129*c1e219d5SEd Tanous 
3130*c1e219d5SEd Tanous inline void
3131*c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
313222d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3133*c1e219d5SEd Tanous                             const std::string& systemName)
3134*c1e219d5SEd Tanous {
31353ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
313645ca1b86SEd Tanous     {
313745ca1b86SEd Tanous         return;
313845ca1b86SEd Tanous     }
3139746b56f3SAsmitha Karunanithi 
31407f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
31417f3e84a1SEd Tanous     {
31427f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31437f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31447f3e84a1SEd Tanous                                    systemName);
31457f3e84a1SEd Tanous         return;
31467f3e84a1SEd Tanous     }
31477f3e84a1SEd Tanous 
3148746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3149746b56f3SAsmitha Karunanithi     {
3150746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3151746b56f3SAsmitha Karunanithi         return;
3152746b56f3SAsmitha Karunanithi     }
3153746b56f3SAsmitha Karunanithi 
315422d268cbSEd Tanous     if (systemName != "system")
315522d268cbSEd Tanous     {
315622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
315722d268cbSEd Tanous                                    systemName);
315822d268cbSEd Tanous         return;
315922d268cbSEd Tanous     }
3160dd60b9edSEd Tanous     asyncResp->res.addHeader(
3161dd60b9edSEd Tanous         boost::beast::http::field::link,
3162dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
31638d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
316437bbf98cSChris Cain         "#ComputerSystem.v1_16_0.ComputerSystem";
31658d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
31668d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
31678d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
31688d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
31698d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
31705fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
31715fd0aafbSNinad Palsule     {
31728d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
31738d1b46d7Szhanghch05             "Disabled";
31748d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
31758d1b46d7Szhanghch05             "Disabled";
31765fd0aafbSNinad Palsule     }
3177cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3178cf0e004cSNinad Palsule         uint64_t(0);
3179002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
318004a258f4SEd Tanous 
31811476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
31821476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
31831476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
31841476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
31851476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
31861476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
31873179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
31883179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3189029573d4SEd Tanous 
3190002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
31911476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3192*c1e219d5SEd Tanous     asyncResp->res
3193*c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
31941476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3195c5b2abe0SLewanczyk, Dawid 
31961476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
31971476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
31981476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
31991476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3200c4bf6374SJason M. Bills 
32011476687dSEd Tanous     nlohmann::json::array_t managedBy;
32021476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
32031476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3204002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
32051476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
32061476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
32070e8ac5e7SGunnar Mills 
32080e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3209002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3210*c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
32111476687dSEd Tanous 
3212*c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
32131476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3214*c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
32151476687dSEd Tanous         "Press ~. to exit console";
32165c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
32175c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
32180e8ac5e7SGunnar Mills 
32190e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
32200e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3221002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3222*c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3223613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3224613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
32251476687dSEd Tanous 
32260e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
322713451e39SWilly Tu 
322813451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
322913451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
323013451e39SWilly Tu     {
32317a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3232b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
32332ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3234e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3235e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3236b49ac873SJames Feist 
32377a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
32387a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
32397a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3240914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3241b49ac873SJames Feist             if (ec)
3242b49ac873SJames Feist             {
3243b49ac873SJames Feist                 // no inventory
3244b49ac873SJames Feist                 return;
3245b49ac873SJames Feist             }
3246b49ac873SJames Feist 
3247914e2d5dSEd Tanous             health->inventory = resp;
32487a1dbc48SGeorge Liu             });
3249b49ac873SJames Feist         health->populate();
325013451e39SWilly Tu     }
3251b49ac873SJames Feist 
3252002d39b4SEd Tanous     getMainChassisId(asyncResp,
3253002d39b4SEd Tanous                      [](const std::string& chassisId,
32548d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3255b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3256b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3257ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3258ef4c65b7SEd Tanous                                                    chassisId);
3259002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3260c5d03ff4SJennifer Lee     });
3261a3002228SAppaRao Puli 
32629f8bfa7cSGunnar Mills     getLocationIndicatorActive(asyncResp);
32639f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3264a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
32655bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
32666c34de48SEd Tanous     getHostState(asyncResp);
3267491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3268978b8803SAndrew Geissler     getBootProgress(asyncResp);
3269b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
3270472bd202SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
327151709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3272c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
3273797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3274c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3275a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3276a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3277a6349918SAppaRao Puli #endif
32781981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
32793a2d0424SChris Cain     getPowerMode(asyncResp);
328037bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3281*c1e219d5SEd Tanous }
3282550a6bf8SJiaqing Zhao 
3283*c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3284*c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
328522d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3286*c1e219d5SEd Tanous     const std::string& systemName)
3287*c1e219d5SEd Tanous {
32883ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
328945ca1b86SEd Tanous     {
329045ca1b86SEd Tanous         return;
329145ca1b86SEd Tanous     }
32927f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32937f3e84a1SEd Tanous     {
32947f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32957f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32967f3e84a1SEd Tanous                                    systemName);
32977f3e84a1SEd Tanous         return;
32987f3e84a1SEd Tanous     }
329922d268cbSEd Tanous     if (systemName != "system")
330022d268cbSEd Tanous     {
330122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
330222d268cbSEd Tanous                                    systemName);
330322d268cbSEd Tanous         return;
330422d268cbSEd Tanous     }
330522d268cbSEd Tanous 
3306dd60b9edSEd Tanous     asyncResp->res.addHeader(
3307dd60b9edSEd Tanous         boost::beast::http::field::link,
3308dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3309dd60b9edSEd Tanous 
33109f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3311cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
331298e386ecSGunnar Mills     std::optional<std::string> assetTag;
3313c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
33143a2d0424SChris Cain     std::optional<std::string> powerMode;
3315550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3316550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3317550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3318550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3319550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3320550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3321797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3322550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
3323550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3324550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3325550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3326550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3327550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3328550a6bf8SJiaqing Zhao 
3329550a6bf8SJiaqing Zhao     // clang-format off
333015ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3331550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3332550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
33337e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3334550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3335550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3336550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3337550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3338550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3339550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3340550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3341550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3342550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3343797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3344550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3345550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3346550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3347550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3348550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3349550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
33506617338dSEd Tanous                 {
33516617338dSEd Tanous                     return;
33526617338dSEd Tanous                 }
3353550a6bf8SJiaqing Zhao     // clang-format on
3354491d8ee7SSantosh Puranik 
33558d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3356c45f0082SYong Li 
335798e386ecSGunnar Mills     if (assetTag)
335898e386ecSGunnar Mills     {
335998e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
336098e386ecSGunnar Mills     }
336198e386ecSGunnar Mills 
3362550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3363c45f0082SYong Li     {
3364f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3365c45f0082SYong Li     }
3366c45f0082SYong Li 
3367cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
336869f35306SGunnar Mills     {
3369002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3370491d8ee7SSantosh Puranik     }
3371550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
337269f35306SGunnar Mills     {
3373550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
337469f35306SGunnar Mills     }
3375ac7e1e0bSAli Ahmed 
3376797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3377797d5daeSCorey Hardesty     {
3378797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3379797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3380797d5daeSCorey Hardesty     }
3381797d5daeSCorey Hardesty 
3382550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3383ac7e1e0bSAli Ahmed     {
3384*c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
338569f35306SGunnar Mills     }
3386265c1602SJohnathan Mantey 
33879f8bfa7cSGunnar Mills     if (locationIndicatorActive)
33889f8bfa7cSGunnar Mills     {
3389002d39b4SEd Tanous         setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
33909f8bfa7cSGunnar Mills     }
33919f8bfa7cSGunnar Mills 
33927e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
33937e860f15SJohn Edward Broadbent     // passed
33949712f8acSEd Tanous     if (indicatorLed)
33956617338dSEd Tanous     {
3396f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3397002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3398d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3399d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
34006617338dSEd Tanous     }
3401c6a620f2SGeorge Liu 
3402c6a620f2SGeorge Liu     if (powerRestorePolicy)
3403c6a620f2SGeorge Liu     {
34044e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3405c6a620f2SGeorge Liu     }
34063a2d0424SChris Cain 
34073a2d0424SChris Cain     if (powerMode)
34083a2d0424SChris Cain     {
34093a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
34103a2d0424SChris Cain     }
341137bbf98cSChris Cain 
3412*c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
341337bbf98cSChris Cain     {
3414002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3415002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
341637bbf98cSChris Cain     }
3417*c1e219d5SEd Tanous }
3418*c1e219d5SEd Tanous /**
3419*c1e219d5SEd Tanous  * Systems derived class for delivering Computer Systems Schema.
3420*c1e219d5SEd Tanous  */
3421*c1e219d5SEd Tanous inline void requestRoutesSystems(App& app)
3422*c1e219d5SEd Tanous {
3423*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3424*c1e219d5SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3425*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(
3426*c1e219d5SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3427*c1e219d5SEd Tanous     /**
3428*c1e219d5SEd Tanous      * Functions triggers appropriate requests on DBus
3429*c1e219d5SEd Tanous      */
3430*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3431*c1e219d5SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3432*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(
3433*c1e219d5SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3434*c1e219d5SEd Tanous 
3435*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3436*c1e219d5SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3437*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::patch)(
3438*c1e219d5SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3439c5b2abe0SLewanczyk, Dawid }
34401cb1a9e6SAppaRao Puli 
344138c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3442dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34437f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3444*c1e219d5SEd Tanous     const std::string& /*systemName*/)
3445dd60b9edSEd Tanous {
3446dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3447dd60b9edSEd Tanous     {
3448dd60b9edSEd Tanous         return;
3449dd60b9edSEd Tanous     }
3450dd60b9edSEd Tanous     asyncResp->res.addHeader(
3451dd60b9edSEd Tanous         boost::beast::http::field::link,
3452dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3453dd60b9edSEd Tanous }
3454*c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3455*c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
345622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3457*c1e219d5SEd Tanous     const std::string& systemName)
3458*c1e219d5SEd Tanous {
34593ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
346045ca1b86SEd Tanous     {
346145ca1b86SEd Tanous         return;
346245ca1b86SEd Tanous     }
34637f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
34647f3e84a1SEd Tanous     {
34657f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34667f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34677f3e84a1SEd Tanous                                    systemName);
34687f3e84a1SEd Tanous         return;
34697f3e84a1SEd Tanous     }
3470746b56f3SAsmitha Karunanithi 
3471746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3472746b56f3SAsmitha Karunanithi     {
3473746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3474746b56f3SAsmitha Karunanithi         return;
3475746b56f3SAsmitha Karunanithi     }
3476746b56f3SAsmitha Karunanithi 
347722d268cbSEd Tanous     if (systemName != "system")
347822d268cbSEd Tanous     {
347922d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
348022d268cbSEd Tanous                                    systemName);
348122d268cbSEd Tanous         return;
348222d268cbSEd Tanous     }
348322d268cbSEd Tanous 
3484dd60b9edSEd Tanous     asyncResp->res.addHeader(
3485dd60b9edSEd Tanous         boost::beast::http::field::link,
3486dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34871476687dSEd Tanous 
34881476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
34891476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3490*c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34911476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34921476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34933215e700SNan Zhou 
34943215e700SNan Zhou     nlohmann::json::array_t parameters;
34953215e700SNan Zhou     nlohmann::json::object_t parameter;
34963215e700SNan Zhou 
34973215e700SNan Zhou     parameter["Name"] = "ResetType";
34983215e700SNan Zhou     parameter["Required"] = true;
34993215e700SNan Zhou     parameter["DataType"] = "String";
35003215e700SNan Zhou     nlohmann::json::array_t allowableValues;
35013215e700SNan Zhou     allowableValues.emplace_back("On");
35023215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
35033215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
35043215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
35053215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
35063215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
35073215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
35083215e700SNan Zhou     allowableValues.emplace_back("Nmi");
35093215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
35103215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
35113215e700SNan Zhou 
35123215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3513*c1e219d5SEd Tanous }
3514*c1e219d5SEd Tanous /**
3515*c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3516*c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3517*c1e219d5SEd Tanous  */
3518*c1e219d5SEd Tanous inline void requestRoutesSystemResetActionInfo(App& app)
3519*c1e219d5SEd Tanous {
3520*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3521*c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3522*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3523*c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3524*c1e219d5SEd Tanous     /**
3525*c1e219d5SEd Tanous      * Functions triggers appropriate requests on DBus
3526*c1e219d5SEd Tanous      */
3527*c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3528*c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3529*c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3530*c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
35311cb1a9e6SAppaRao Puli }
3532c5b2abe0SLewanczyk, Dawid } // namespace redfish
3533