xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision fc903b3d9b6b61a6b215aabf4ae68408c04787ef)
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 
35*fc903b3dSAndrew 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>
40*fc903b3dSAndrew 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  *
579d3ae10eSAlpana Kumari  * @param[in] aResp 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
638d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
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 =
729d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
739d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
749d3ae10eSAlpana Kumari     {
75e05aec50SEd Tanous         if (isDimmFunctional)
769d3ae10eSAlpana Kumari         {
779d3ae10eSAlpana Kumari             aResp->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  *
8757e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
8857e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
8957e8c9beSAlpana Kumari  *
9057e8c9beSAlpana Kumari  * @return None.
9157e8c9beSAlpana Kumari  */
921e1e598dSJonathan Doman inline void
931e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
941e1e598dSJonathan Doman                              bool isCpuFunctional)
9557e8c9beSAlpana Kumari {
961e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
9757e8c9beSAlpana Kumari 
9802cad96eSEd Tanous     const nlohmann::json& prevProcState =
9957e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10057e8c9beSAlpana Kumari 
10157e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10257e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10357e8c9beSAlpana Kumari     // Functional.
10457e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10557e8c9beSAlpana Kumari     {
106e05aec50SEd Tanous         if (isCpuFunctional)
10757e8c9beSAlpana Kumari         {
10857e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10957e8c9beSAlpana Kumari                 "Enabled";
11057e8c9beSAlpana Kumari         }
11157e8c9beSAlpana Kumari     }
11257e8c9beSAlpana Kumari }
11357e8c9beSAlpana Kumari 
114cf0e004cSNinad Palsule /*
115cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
116cf0e004cSNinad Palsule  *
117cf0e004cSNinad Palsule  * @param[in] aResp Shared pointer for completing asynchronous calls
118cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
119cf0e004cSNinad Palsule  *
120cf0e004cSNinad Palsule  * @return None.
121cf0e004cSNinad Palsule  */
122cf0e004cSNinad Palsule inline void
123cf0e004cSNinad Palsule     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
124cf0e004cSNinad Palsule                            bool isCpuPresent)
125cf0e004cSNinad Palsule {
126cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
127cf0e004cSNinad Palsule 
128cf0e004cSNinad Palsule     if (isCpuPresent)
129cf0e004cSNinad Palsule     {
130cf0e004cSNinad Palsule         nlohmann::json& procCount =
131cf0e004cSNinad Palsule             aResp->res.jsonValue["ProcessorSummary"]["Count"];
132cf0e004cSNinad Palsule         auto* procCountPtr =
133cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
134cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
135cf0e004cSNinad Palsule         {
136cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
137cf0e004cSNinad Palsule             *procCountPtr += 1;
138cf0e004cSNinad Palsule         }
139cf0e004cSNinad Palsule     }
140cf0e004cSNinad Palsule }
141cf0e004cSNinad Palsule 
142382d6475SAli Ahmed inline void getProcessorProperties(
143382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
144382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
145382d6475SAli Ahmed         properties)
14603fbed92SAli Ahmed {
14703fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14803fbed92SAli Ahmed 
14903fbed92SAli Ahmed     // TODO: Get Model
15003fbed92SAli Ahmed 
151bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15203fbed92SAli Ahmed 
153bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
154bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     if (!success)
15703fbed92SAli Ahmed     {
15803fbed92SAli Ahmed         messages::internalError(aResp->res);
15903fbed92SAli Ahmed         return;
16003fbed92SAli Ahmed     }
16103fbed92SAli Ahmed 
162bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16303fbed92SAli Ahmed     {
164bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
165bc1d29deSKrzysztof Grobelny             aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
166bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
167bc1d29deSKrzysztof Grobelny 
168bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
169bc1d29deSKrzysztof Grobelny         {
170bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17103fbed92SAli Ahmed         }
17203fbed92SAli Ahmed         else
17303fbed92SAli Ahmed         {
174bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17503fbed92SAli Ahmed         }
17603fbed92SAli Ahmed     }
17703fbed92SAli Ahmed }
17803fbed92SAli Ahmed 
17903fbed92SAli Ahmed /*
18003fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18103fbed92SAli Ahmed  *
18203fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
18303fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18403fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18503fbed92SAli Ahmed  *
18603fbed92SAli Ahmed  * @return None.
18703fbed92SAli Ahmed  */
18803fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18903fbed92SAli Ahmed                                 const std::string& service,
19003fbed92SAli Ahmed                                 const std::string& path)
19103fbed92SAli Ahmed {
1925e7e2dc5SEd Tanous     auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
193382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
194382d6475SAli Ahmed         if (ec3)
195382d6475SAli Ahmed         {
196382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
197382d6475SAli Ahmed             return;
198382d6475SAli Ahmed         }
199382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
200382d6475SAli Ahmed     };
201382d6475SAli Ahmed 
202cf0e004cSNinad Palsule     // Get the Presence of CPU
203cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
204cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
205cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
206cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
207cf0e004cSNinad Palsule 
2085fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2095fd0aafbSNinad Palsule     {
2105fd0aafbSNinad Palsule         auto getCpuFunctionalState =
2115fd0aafbSNinad Palsule             [aResp](const boost::system::error_code& ec3,
212382d6475SAli Ahmed                     const bool cpuFunctionalCheck) {
213382d6475SAli Ahmed             if (ec3)
214382d6475SAli Ahmed             {
215382d6475SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
216382d6475SAli Ahmed                 return;
217382d6475SAli Ahmed             }
218382d6475SAli Ahmed             modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
219382d6475SAli Ahmed         };
220382d6475SAli Ahmed 
221382d6475SAli Ahmed         // Get the Functional State
222382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
223382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2245fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2255fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2265fd0aafbSNinad Palsule     }
227382d6475SAli Ahmed 
228bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
229bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
230bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
23103fbed92SAli Ahmed         [aResp, service,
2325e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
233b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23403fbed92SAli Ahmed         if (ec2)
23503fbed92SAli Ahmed         {
23603fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
23703fbed92SAli Ahmed             messages::internalError(aResp->res);
23803fbed92SAli Ahmed             return;
23903fbed92SAli Ahmed         }
240382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
241bc1d29deSKrzysztof Grobelny         });
24203fbed92SAli Ahmed }
24303fbed92SAli Ahmed 
24457e8c9beSAlpana Kumari /*
245cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
246cf0e004cSNinad Palsule  *
247cf0e004cSNinad Palsule  * @param[in] aResp Shared pointer for completing asynchronous calls
248cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
249cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
250cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
251cf0e004cSNinad Palsule  *
252cf0e004cSNinad Palsule  * @return None.
253cf0e004cSNinad Palsule  */
254cf0e004cSNinad Palsule inline void
255cf0e004cSNinad Palsule     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2565fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2575fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
258cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
259cf0e004cSNinad Palsule {
260cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
261cf0e004cSNinad Palsule 
262cf0e004cSNinad Palsule     if (properties.empty())
263cf0e004cSNinad Palsule     {
2645fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2655fd0aafbSNinad Palsule         {
266cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
267cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
268cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
269cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
270cf0e004cSNinad Palsule                 "Functional",
271cf0e004cSNinad Palsule                 [aResp](const boost::system::error_code& ec3, bool dimmState) {
272cf0e004cSNinad Palsule                 if (ec3)
273cf0e004cSNinad Palsule                 {
274cf0e004cSNinad Palsule                     BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
275cf0e004cSNinad Palsule                     return;
276cf0e004cSNinad Palsule                 }
277cf0e004cSNinad Palsule                 updateDimmProperties(aResp, 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     {
291cf0e004cSNinad Palsule         messages::internalError(aResp->res);
292cf0e004cSNinad Palsule         return;
293cf0e004cSNinad Palsule     }
294cf0e004cSNinad Palsule 
295cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
296cf0e004cSNinad Palsule     {
297cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
298cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
299cf0e004cSNinad Palsule         const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
300cf0e004cSNinad Palsule         if (preValue == nullptr)
301cf0e004cSNinad Palsule         {
302cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
303cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
304cf0e004cSNinad Palsule         }
305cf0e004cSNinad Palsule         else
306cf0e004cSNinad Palsule         {
307cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
308cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
309cf0e004cSNinad Palsule         }
3105fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3115fd0aafbSNinad Palsule         {
3125fd0aafbSNinad Palsule             aResp->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  *
321cf0e004cSNinad Palsule  * @param[in] aResp 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  */
327cf0e004cSNinad Palsule inline void getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
328cf0e004cSNinad Palsule                              const std::string& service,
329cf0e004cSNinad Palsule                              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",
334cf0e004cSNinad Palsule         [aResp, 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;
340cf0e004cSNinad Palsule             messages::internalError(aResp->res);
341cf0e004cSNinad Palsule             return;
342cf0e004cSNinad Palsule         }
343cf0e004cSNinad Palsule         processMemoryProperties(aResp, service, path, properties);
344cf0e004cSNinad Palsule         });
345cf0e004cSNinad Palsule }
346cf0e004cSNinad Palsule 
347cf0e004cSNinad Palsule /*
348c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
349c5b2abe0SLewanczyk, Dawid  *
350c5b2abe0SLewanczyk, Dawid  * @param[in] aResp 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
3568d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
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,
369b9d36b47SEd Tanous         [aResp,
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";
375f12894f8SJason M. Bills             messages::internalError(aResp->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>(
3995fd0aafbSNinad Palsule                     aResp, "/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>(
4055fd0aafbSNinad Palsule                         aResp, "/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 
423cf0e004cSNinad Palsule                         getMemorySummary(aResp, 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 
43603fbed92SAli Ahmed                         getProcessorSummary(aResp, 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",
4515e7e2dc5SEd Tanous                             [aResp](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;
458f12894f8SJason M. Bills                                 messages::internalError(aResp->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                             {
473bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->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;
488002d39b4SEd Tanous                                 aResp->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",
4995e7e2dc5SEd Tanous                             [aResp](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                             {
527bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
528bc1d29deSKrzysztof Grobelny                                 return;
529029573d4SEd Tanous                             }
530bc1d29deSKrzysztof Grobelny 
531bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
532bc1d29deSKrzysztof Grobelny                             {
533bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
534bc1d29deSKrzysztof Grobelny                                     *partNumber;
535029573d4SEd Tanous                             }
536bc1d29deSKrzysztof Grobelny 
537bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
538bc1d29deSKrzysztof Grobelny                             {
539bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
540bc1d29deSKrzysztof Grobelny                                     *serialNumber;
541bc1d29deSKrzysztof Grobelny                             }
542bc1d29deSKrzysztof Grobelny 
543bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
544bc1d29deSKrzysztof Grobelny                             {
545bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
546bc1d29deSKrzysztof Grobelny                                     *manufacturer;
547bc1d29deSKrzysztof Grobelny                             }
548bc1d29deSKrzysztof Grobelny 
549bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
550bc1d29deSKrzysztof Grobelny                             {
551bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
552bc1d29deSKrzysztof Grobelny                             }
553bc1d29deSKrzysztof Grobelny 
554bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
555bc1d29deSKrzysztof Grobelny                             {
556bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
557fc5afcf9Sbeccabroek                             }
558c1e236a6SGunnar Mills 
559cb7e1e7bSAndrew Geissler                             // Grab the bios version
560eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
561eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
562002d39b4SEd Tanous                                 false);
563bc1d29deSKrzysztof Grobelny                             });
564e4a4b9a9SJames Feist 
5651e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5661e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5671e1e598dSJonathan Doman                             path,
5681e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5691e1e598dSJonathan Doman                             "AssetTag",
5701e1e598dSJonathan Doman                             "AssetTag",
5715e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
5721e1e598dSJonathan Doman                                     const std::string& value) {
573cb13a392SEd Tanous                             if (ec2)
574e4a4b9a9SJames Feist                             {
575e4a4b9a9SJames Feist                                 // doesn't have to include this
576e4a4b9a9SJames Feist                                 // interface
577e4a4b9a9SJames Feist                                 return;
578e4a4b9a9SJames Feist                             }
579e4a4b9a9SJames Feist 
5801e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5811e1e598dSJonathan Doman                             });
582029573d4SEd Tanous                     }
583029573d4SEd Tanous                 }
584029573d4SEd Tanous             }
585c5b2abe0SLewanczyk, Dawid         }
5866617338dSEd Tanous         });
587c5b2abe0SLewanczyk, Dawid }
588c5b2abe0SLewanczyk, Dawid 
589c5b2abe0SLewanczyk, Dawid /**
590c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
591c5b2abe0SLewanczyk, Dawid  *
592c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
593c5b2abe0SLewanczyk, Dawid  *
594c5b2abe0SLewanczyk, Dawid  * @return None.
595c5b2abe0SLewanczyk, Dawid  */
5968d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5971abe55efSEd Tanous {
59855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5991e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6001e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6011e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6021e1e598dSJonathan Doman         "CurrentHostState",
6035e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
6041e1e598dSJonathan Doman                 const std::string& hostState) {
6051abe55efSEd Tanous         if (ec)
6061abe55efSEd Tanous         {
60722228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
60822228c28SAndrew Geissler             {
60922228c28SAndrew Geissler                 // Service not available, no error, just don't return
61022228c28SAndrew Geissler                 // host state info
61122228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
61222228c28SAndrew Geissler                 return;
61322228c28SAndrew Geissler             }
61422228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
615f12894f8SJason M. Bills             messages::internalError(aResp->res);
616c5b2abe0SLewanczyk, Dawid             return;
617c5b2abe0SLewanczyk, Dawid         }
6186617338dSEd Tanous 
6191e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
620c5b2abe0SLewanczyk, Dawid         // Verify Host State
6211e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6221abe55efSEd Tanous         {
62355c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
6246617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
6251abe55efSEd Tanous         }
6261e1e598dSJonathan Doman         else if (hostState ==
6270fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6288c888608SGunnar Mills         {
6298c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
6308c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6318c888608SGunnar Mills         }
6321e1e598dSJonathan Doman         else if (hostState ==
6330fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
63483935af9SAndrew Geissler         {
63583935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
63683935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
63783935af9SAndrew Geissler         }
6380fda0f12SGeorge Liu         else if (
6391e1e598dSJonathan Doman             hostState ==
6400fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6411a2a1437SAndrew Geissler         {
6421a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
64315c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
6441a2a1437SAndrew Geissler         }
645002d39b4SEd Tanous         else if (hostState ==
6460fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6471a2a1437SAndrew Geissler         {
6481a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
6491a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
6501a2a1437SAndrew Geissler         }
6511abe55efSEd Tanous         else
6521abe55efSEd Tanous         {
65355c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
6546617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
655c5b2abe0SLewanczyk, Dawid         }
6561e1e598dSJonathan Doman         });
657c5b2abe0SLewanczyk, Dawid }
658c5b2abe0SLewanczyk, Dawid 
659c5b2abe0SLewanczyk, Dawid /**
660786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
661491d8ee7SSantosh Puranik  *
662491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
663491d8ee7SSantosh Puranik  *
664491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
665491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
666491d8ee7SSantosh Puranik  */
66723a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
668491d8ee7SSantosh Puranik {
669491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
670491d8ee7SSantosh Puranik     {
671491d8ee7SSantosh Puranik         return "None";
672491d8ee7SSantosh Puranik     }
6733174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
674491d8ee7SSantosh Puranik     {
675491d8ee7SSantosh Puranik         return "Hdd";
676491d8ee7SSantosh Puranik     }
6773174e4dfSEd Tanous     if (dbusSource ==
678a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
679491d8ee7SSantosh Puranik     {
680491d8ee7SSantosh Puranik         return "Cd";
681491d8ee7SSantosh Puranik     }
6823174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
683491d8ee7SSantosh Puranik     {
684491d8ee7SSantosh Puranik         return "Pxe";
685491d8ee7SSantosh Puranik     }
6863174e4dfSEd Tanous     if (dbusSource ==
687944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6889f16b2c1SJennifer Lee     {
6899f16b2c1SJennifer Lee         return "Usb";
6909f16b2c1SJennifer Lee     }
691491d8ee7SSantosh Puranik     return "";
692491d8ee7SSantosh Puranik }
693491d8ee7SSantosh Puranik 
694491d8ee7SSantosh Puranik /**
695cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
696cd9a4666SKonstantin Aladyshev  *
697cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
698cd9a4666SKonstantin Aladyshev  *
699cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
700cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
701cd9a4666SKonstantin Aladyshev  */
702cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
703cd9a4666SKonstantin Aladyshev {
704cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
705cd9a4666SKonstantin Aladyshev     {
706cd9a4666SKonstantin Aladyshev         return "Legacy";
707cd9a4666SKonstantin Aladyshev     }
708cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
709cd9a4666SKonstantin Aladyshev     {
710cd9a4666SKonstantin Aladyshev         return "UEFI";
711cd9a4666SKonstantin Aladyshev     }
712cd9a4666SKonstantin Aladyshev     return "";
713cd9a4666SKonstantin Aladyshev }
714cd9a4666SKonstantin Aladyshev 
715cd9a4666SKonstantin Aladyshev /**
716786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
717491d8ee7SSantosh Puranik  *
718491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
719491d8ee7SSantosh Puranik  *
720491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
721491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
722491d8ee7SSantosh Puranik  */
72323a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
724491d8ee7SSantosh Puranik {
725491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
726491d8ee7SSantosh Puranik     {
727491d8ee7SSantosh Puranik         return "None";
728491d8ee7SSantosh Puranik     }
7293174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
730491d8ee7SSantosh Puranik     {
731491d8ee7SSantosh Puranik         return "Diags";
732491d8ee7SSantosh Puranik     }
7333174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
734491d8ee7SSantosh Puranik     {
735491d8ee7SSantosh Puranik         return "BiosSetup";
736491d8ee7SSantosh Puranik     }
737491d8ee7SSantosh Puranik     return "";
738491d8ee7SSantosh Puranik }
739491d8ee7SSantosh Puranik 
740491d8ee7SSantosh Puranik /**
741e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
742e43914b3SAndrew Geissler  *
743e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
744e43914b3SAndrew Geissler  *
745e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
746e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
747e43914b3SAndrew Geissler  */
748e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
749e43914b3SAndrew Geissler {
750e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
751e43914b3SAndrew Geissler     // enum
752e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
753e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
754e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
755e43914b3SAndrew Geissler     {
756e43914b3SAndrew Geissler         rfBpLastState = "None";
757e43914b3SAndrew Geissler     }
758e43914b3SAndrew Geissler     else if (dbusBootProgress ==
759e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
760e43914b3SAndrew Geissler              "PrimaryProcInit")
761e43914b3SAndrew Geissler     {
762e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
763e43914b3SAndrew Geissler     }
764e43914b3SAndrew Geissler     else if (dbusBootProgress ==
765e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
766e43914b3SAndrew Geissler              "BusInit")
767e43914b3SAndrew Geissler     {
768e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
769e43914b3SAndrew Geissler     }
770e43914b3SAndrew Geissler     else if (dbusBootProgress ==
771e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
772e43914b3SAndrew Geissler              "MemoryInit")
773e43914b3SAndrew Geissler     {
774e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
775e43914b3SAndrew Geissler     }
776e43914b3SAndrew Geissler     else if (dbusBootProgress ==
777e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
778e43914b3SAndrew Geissler              "SecondaryProcInit")
779e43914b3SAndrew Geissler     {
780e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
781e43914b3SAndrew Geissler     }
782e43914b3SAndrew Geissler     else if (dbusBootProgress ==
783e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
784e43914b3SAndrew Geissler              "PCIInit")
785e43914b3SAndrew Geissler     {
786e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
787e43914b3SAndrew Geissler     }
788e43914b3SAndrew Geissler     else if (dbusBootProgress ==
789e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
790e43914b3SAndrew Geissler              "SystemSetup")
791e43914b3SAndrew Geissler     {
792e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
793e43914b3SAndrew Geissler     }
794e43914b3SAndrew Geissler     else if (dbusBootProgress ==
795e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
796e43914b3SAndrew Geissler              "SystemInitComplete")
797e43914b3SAndrew Geissler     {
798e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
799e43914b3SAndrew Geissler     }
800e43914b3SAndrew Geissler     else if (dbusBootProgress ==
801e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
802e43914b3SAndrew Geissler              "OSStart")
803e43914b3SAndrew Geissler     {
804e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
805e43914b3SAndrew Geissler     }
806e43914b3SAndrew Geissler     else if (dbusBootProgress ==
807e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
808e43914b3SAndrew Geissler              "OSRunning")
809e43914b3SAndrew Geissler     {
810e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
811e43914b3SAndrew Geissler     }
812e43914b3SAndrew Geissler     else
813e43914b3SAndrew Geissler     {
814e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
815e43914b3SAndrew Geissler                          << dbusBootProgress;
816e43914b3SAndrew Geissler         // Just return the default
817e43914b3SAndrew Geissler     }
818e43914b3SAndrew Geissler     return rfBpLastState;
819e43914b3SAndrew Geissler }
820e43914b3SAndrew Geissler 
821e43914b3SAndrew Geissler /**
822786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
823491d8ee7SSantosh Puranik  *
824491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
825944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
826944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
827491d8ee7SSantosh Puranik  *
828944ffaf9SJohnathan Mantey  * @return Integer error code.
829491d8ee7SSantosh Puranik  */
8308d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
831944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
832944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
833491d8ee7SSantosh Puranik {
834c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
835c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
836944ffaf9SJohnathan Mantey 
837491d8ee7SSantosh Puranik     if (rfSource == "None")
838491d8ee7SSantosh Puranik     {
839944ffaf9SJohnathan Mantey         return 0;
840491d8ee7SSantosh Puranik     }
8413174e4dfSEd Tanous     if (rfSource == "Pxe")
842491d8ee7SSantosh Puranik     {
843944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
844944ffaf9SJohnathan Mantey     }
845944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
846944ffaf9SJohnathan Mantey     {
847944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
848944ffaf9SJohnathan Mantey     }
849944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
850944ffaf9SJohnathan Mantey     {
851944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
852944ffaf9SJohnathan Mantey     }
853944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
854944ffaf9SJohnathan Mantey     {
855944ffaf9SJohnathan Mantey         bootSource =
856944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
857944ffaf9SJohnathan Mantey     }
858944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
859944ffaf9SJohnathan Mantey     {
860944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
861491d8ee7SSantosh Puranik     }
8629f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8639f16b2c1SJennifer Lee     {
864944ffaf9SJohnathan Mantey         bootSource =
865944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8669f16b2c1SJennifer Lee     }
867491d8ee7SSantosh Puranik     else
868491d8ee7SSantosh Puranik     {
8690fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8700fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
871944ffaf9SJohnathan Mantey             << bootSource;
872944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
873944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
874944ffaf9SJohnathan Mantey         return -1;
875491d8ee7SSantosh Puranik     }
876944ffaf9SJohnathan Mantey     return 0;
877491d8ee7SSantosh Puranik }
8781981771bSAli Ahmed 
879978b8803SAndrew Geissler /**
880978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
881978b8803SAndrew Geissler  *
882978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
883978b8803SAndrew Geissler  *
884978b8803SAndrew Geissler  * @return None.
885978b8803SAndrew Geissler  */
8868d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
887978b8803SAndrew Geissler {
8881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8901e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8911e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
8925e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
8931e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
894978b8803SAndrew Geissler         if (ec)
895978b8803SAndrew Geissler         {
896978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
897978b8803SAndrew Geissler             // not found
898978b8803SAndrew Geissler             return;
899978b8803SAndrew Geissler         }
900978b8803SAndrew Geissler 
9011e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
902978b8803SAndrew Geissler 
903e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
904e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9051e1e598dSJonathan Doman         });
906978b8803SAndrew Geissler }
907491d8ee7SSantosh Puranik 
908491d8ee7SSantosh Puranik /**
909b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
910b6d5d45cSHieu Huynh  *
911b6d5d45cSHieu Huynh  * @param[in] aResp  Shared pointer for generating response message.
912b6d5d45cSHieu Huynh  *
913b6d5d45cSHieu Huynh  * @return None.
914b6d5d45cSHieu Huynh  */
915b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
916b6d5d45cSHieu Huynh     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
917b6d5d45cSHieu Huynh {
918b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
919b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
920b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
921b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
9225e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
923b6d5d45cSHieu Huynh                 const uint64_t lastStateTime) {
924b6d5d45cSHieu Huynh         if (ec)
925b6d5d45cSHieu Huynh         {
926b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
927b6d5d45cSHieu Huynh             return;
928b6d5d45cSHieu Huynh         }
929b6d5d45cSHieu Huynh 
930b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
931b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
932b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
933b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
934b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
935b6d5d45cSHieu Huynh 
936b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
937b6d5d45cSHieu Huynh         aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
938b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
939b6d5d45cSHieu Huynh         });
940b6d5d45cSHieu Huynh }
941b6d5d45cSHieu Huynh 
942b6d5d45cSHieu Huynh /**
943c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
944cd9a4666SKonstantin Aladyshev  *
945cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
946cd9a4666SKonstantin Aladyshev  *
947cd9a4666SKonstantin Aladyshev  * @return None.
948cd9a4666SKonstantin Aladyshev  */
949cd9a4666SKonstantin Aladyshev 
950c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
951cd9a4666SKonstantin Aladyshev {
9521e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9531e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9541e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9551e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
9565e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9571e1e598dSJonathan Doman                 const std::string& bootType) {
958cd9a4666SKonstantin Aladyshev         if (ec)
959cd9a4666SKonstantin Aladyshev         {
960cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
961cd9a4666SKonstantin Aladyshev             return;
962cd9a4666SKonstantin Aladyshev         }
963cd9a4666SKonstantin Aladyshev 
9641e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
965cd9a4666SKonstantin Aladyshev 
966002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
967002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
968613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
969cd9a4666SKonstantin Aladyshev 
9701e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
971cd9a4666SKonstantin Aladyshev         if (rfType.empty())
972cd9a4666SKonstantin Aladyshev         {
973cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
974cd9a4666SKonstantin Aladyshev             return;
975cd9a4666SKonstantin Aladyshev         }
976cd9a4666SKonstantin Aladyshev 
977cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9781e1e598dSJonathan Doman         });
979cd9a4666SKonstantin Aladyshev }
980cd9a4666SKonstantin Aladyshev 
981cd9a4666SKonstantin Aladyshev /**
982c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
983491d8ee7SSantosh Puranik  *
984491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
985491d8ee7SSantosh Puranik  *
986491d8ee7SSantosh Puranik  * @return None.
987491d8ee7SSantosh Puranik  */
988c21865c4SKonstantin Aladyshev 
989c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
990491d8ee7SSantosh Puranik {
9911e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9921e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9931e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9941e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
9955e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9961e1e598dSJonathan Doman                 const std::string& bootModeStr) {
997491d8ee7SSantosh Puranik         if (ec)
998491d8ee7SSantosh Puranik         {
999491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1000491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1001491d8ee7SSantosh Puranik             return;
1002491d8ee7SSantosh Puranik         }
1003491d8ee7SSantosh Puranik 
10041e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1005491d8ee7SSantosh Puranik 
10060fda0f12SGeorge Liu         aResp->res
10070fda0f12SGeorge Liu             .jsonValue["Boot"]
1008002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1009002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1010491d8ee7SSantosh Puranik 
10111e1e598dSJonathan Doman         if (bootModeStr !=
1012491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1013491d8ee7SSantosh Puranik         {
10141e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1015491d8ee7SSantosh Puranik             if (!rfMode.empty())
1016491d8ee7SSantosh Puranik             {
1017491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1018491d8ee7SSantosh Puranik                     rfMode;
1019491d8ee7SSantosh Puranik             }
1020491d8ee7SSantosh Puranik         }
10211e1e598dSJonathan Doman         });
1022491d8ee7SSantosh Puranik }
1023491d8ee7SSantosh Puranik 
1024491d8ee7SSantosh Puranik /**
1025c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1026491d8ee7SSantosh Puranik  *
1027491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
1028491d8ee7SSantosh Puranik  *
1029491d8ee7SSantosh Puranik  * @return None.
1030491d8ee7SSantosh Puranik  */
1031c21865c4SKonstantin Aladyshev 
1032c21865c4SKonstantin Aladyshev inline void
1033c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1034491d8ee7SSantosh Puranik {
10351e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10361e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10371e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10381e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
10395e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
10401e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
1041491d8ee7SSantosh Puranik         if (ec)
1042491d8ee7SSantosh Puranik         {
1043491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10445ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10455ef735c8SNan Zhou             {
10465ef735c8SNan Zhou                 return;
10475ef735c8SNan Zhou             }
1048491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1049491d8ee7SSantosh Puranik             return;
1050491d8ee7SSantosh Puranik         }
1051491d8ee7SSantosh Puranik 
10521e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1053491d8ee7SSantosh Puranik 
10541e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1055491d8ee7SSantosh Puranik         if (!rfSource.empty())
1056491d8ee7SSantosh Puranik         {
1057002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1058491d8ee7SSantosh Puranik         }
1059cd9a4666SKonstantin Aladyshev 
1060cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1061cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1062c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
10631e1e598dSJonathan Doman         });
1064491d8ee7SSantosh Puranik }
1065491d8ee7SSantosh Puranik 
1066491d8ee7SSantosh Puranik /**
1067c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1068c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1069c21865c4SKonstantin Aladyshev  * state
1070491d8ee7SSantosh Puranik  *
1071491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1072491d8ee7SSantosh Puranik  *
1073491d8ee7SSantosh Puranik  * @return None.
1074491d8ee7SSantosh Puranik  */
1075491d8ee7SSantosh Puranik 
1076c21865c4SKonstantin Aladyshev inline void
1077c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1078c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1079c21865c4SKonstantin Aladyshev {
1080c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1081c21865c4SKonstantin Aladyshev     {
1082c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1083c21865c4SKonstantin Aladyshev         return;
1084c21865c4SKonstantin Aladyshev     }
1085c21865c4SKonstantin Aladyshev 
1086c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1087c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10881e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10891e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10901e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10911e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10925e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1093491d8ee7SSantosh Puranik         if (ec)
1094491d8ee7SSantosh Puranik         {
1095491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1096c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1097491d8ee7SSantosh Puranik             return;
1098491d8ee7SSantosh Puranik         }
1099491d8ee7SSantosh Puranik 
1100c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1101c21865c4SKonstantin Aladyshev         {
1102002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1103c21865c4SKonstantin Aladyshev         }
1104c21865c4SKonstantin Aladyshev         else
1105c21865c4SKonstantin Aladyshev         {
1106c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1107c21865c4SKonstantin Aladyshev                 "Continuous";
1108c21865c4SKonstantin Aladyshev         }
11091e1e598dSJonathan Doman         });
1110491d8ee7SSantosh Puranik }
1111491d8ee7SSantosh Puranik 
1112491d8ee7SSantosh Puranik /**
1113c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1114c21865c4SKonstantin Aladyshev  *
1115c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1116c21865c4SKonstantin Aladyshev  *
1117c21865c4SKonstantin Aladyshev  * @return None.
1118c21865c4SKonstantin Aladyshev  */
1119c21865c4SKonstantin Aladyshev 
1120c21865c4SKonstantin Aladyshev inline void
1121c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1122c21865c4SKonstantin Aladyshev {
11231e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11241e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11251e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11261e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
11275e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
11281e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1129c21865c4SKonstantin Aladyshev         if (ec)
1130c21865c4SKonstantin Aladyshev         {
1131c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
11325ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11335ef735c8SNan Zhou             {
11345ef735c8SNan Zhou                 return;
11355ef735c8SNan Zhou             }
1136c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1137c21865c4SKonstantin Aladyshev             return;
1138c21865c4SKonstantin Aladyshev         }
1139c21865c4SKonstantin Aladyshev 
11401e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
11411e1e598dSJonathan Doman         });
1142c21865c4SKonstantin Aladyshev }
1143c21865c4SKonstantin Aladyshev 
1144c21865c4SKonstantin Aladyshev /**
1145c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1146c21865c4SKonstantin Aladyshev  *
1147c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1148c21865c4SKonstantin Aladyshev  *
1149c21865c4SKonstantin Aladyshev  * @return None.
1150c21865c4SKonstantin Aladyshev  */
1151c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1152c21865c4SKonstantin Aladyshev {
1153c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1154c21865c4SKonstantin Aladyshev 
1155c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1156c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1157c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1158c21865c4SKonstantin Aladyshev }
1159c21865c4SKonstantin Aladyshev 
1160c21865c4SKonstantin Aladyshev /**
1161c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1162c0557e1aSGunnar Mills  *
1163c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1164c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1165c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1166c0557e1aSGunnar Mills  * last power operation time.
1167c0557e1aSGunnar Mills  *
1168c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1169c0557e1aSGunnar Mills  *
1170c0557e1aSGunnar Mills  * @return None.
1171c0557e1aSGunnar Mills  */
11728d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1173c0557e1aSGunnar Mills {
1174c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1175c0557e1aSGunnar Mills 
11761e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11771e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11781e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11791e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
11805e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
1181c0557e1aSGunnar Mills         if (ec)
1182c0557e1aSGunnar Mills         {
1183c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1184c0557e1aSGunnar Mills             return;
1185c0557e1aSGunnar Mills         }
1186c0557e1aSGunnar Mills 
1187c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1188c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11891e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1190c0557e1aSGunnar Mills 
1191c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1192c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11932b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11941e1e598dSJonathan Doman         });
1195c0557e1aSGunnar Mills }
1196c0557e1aSGunnar Mills 
1197c0557e1aSGunnar Mills /**
1198797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1199797d5daeSCorey Hardesty  *
1200797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1201797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1202797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1203797d5daeSCorey Hardesty  * dbus.
1204797d5daeSCorey Hardesty  *
1205797d5daeSCorey Hardesty  * @param[in] aResp     Shared pointer for generating response message.
1206797d5daeSCorey Hardesty  *
1207797d5daeSCorey Hardesty  * @return None.
1208797d5daeSCorey Hardesty  */
1209797d5daeSCorey Hardesty inline void
1210797d5daeSCorey Hardesty     getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1211797d5daeSCorey Hardesty {
1212797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1213797d5daeSCorey Hardesty 
1214797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1215797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1216797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1217797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1218797d5daeSCorey Hardesty         [aResp{aResp}](const boost::system::error_code& ec,
1219797d5daeSCorey Hardesty                        const dbus::utility::DBusPropertiesMap& propertiesList) {
1220797d5daeSCorey Hardesty         if (ec)
1221797d5daeSCorey Hardesty         {
1222797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1223797d5daeSCorey Hardesty             {
1224797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1225797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1226797d5daeSCorey Hardesty             }
1227797d5daeSCorey Hardesty             return;
1228797d5daeSCorey Hardesty         }
1229797d5daeSCorey Hardesty 
1230797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1231797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1232797d5daeSCorey Hardesty 
1233797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1234797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1235797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1236797d5daeSCorey Hardesty 
1237797d5daeSCorey Hardesty         if (!success)
1238797d5daeSCorey Hardesty         {
1239797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1240797d5daeSCorey Hardesty             return;
1241797d5daeSCorey Hardesty         }
1242797d5daeSCorey Hardesty 
1243797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1244797d5daeSCorey Hardesty         {
1245797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1246797d5daeSCorey Hardesty                 *attemptsLeft;
1247797d5daeSCorey Hardesty         }
1248797d5daeSCorey Hardesty 
1249797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1250797d5daeSCorey Hardesty         {
1251797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1252797d5daeSCorey Hardesty                 *retryAttempts;
1253797d5daeSCorey Hardesty         }
1254797d5daeSCorey Hardesty         });
1255797d5daeSCorey Hardesty }
1256797d5daeSCorey Hardesty 
1257797d5daeSCorey Hardesty /**
12586bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12596bd5a8d2SGunnar Mills  *
12606bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
12616bd5a8d2SGunnar Mills  *
12626bd5a8d2SGunnar Mills  * @return None.
12636bd5a8d2SGunnar Mills  */
1264797d5daeSCorey Hardesty inline void
1265797d5daeSCorey Hardesty     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12666bd5a8d2SGunnar Mills {
12676bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12686bd5a8d2SGunnar Mills 
12691e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12701e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12711e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12721e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12735e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
12746bd5a8d2SGunnar Mills         if (ec)
12756bd5a8d2SGunnar Mills         {
1276797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1277797d5daeSCorey Hardesty             {
1278797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1279797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1280797d5daeSCorey Hardesty             }
12816bd5a8d2SGunnar Mills             return;
12826bd5a8d2SGunnar Mills         }
12836bd5a8d2SGunnar Mills 
12841e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1285e05aec50SEd Tanous         if (autoRebootEnabled)
12866bd5a8d2SGunnar Mills         {
12876bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12886bd5a8d2SGunnar Mills                 "RetryAttempts";
12896bd5a8d2SGunnar Mills         }
12906bd5a8d2SGunnar Mills         else
12916bd5a8d2SGunnar Mills         {
1292002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12936bd5a8d2SGunnar Mills         }
1294797d5daeSCorey Hardesty         getAutomaticRebootAttempts(aResp);
129569f35306SGunnar Mills 
129669f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
129769f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
129869f35306SGunnar Mills         // RetryAttempts.
1299002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
13000fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
13010fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
13021e1e598dSJonathan Doman         });
13036bd5a8d2SGunnar Mills }
13046bd5a8d2SGunnar Mills 
13056bd5a8d2SGunnar Mills /**
1306797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1307797d5daeSCorey Hardesty  *
1308797d5daeSCorey Hardesty  * @param[in] aResp   Shared pointer for generating response message.
1309797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1310797d5daeSCorey Hardesty  *
1311797d5daeSCorey Hardesty  *@return None.
1312797d5daeSCorey Hardesty  */
1313797d5daeSCorey Hardesty 
1314797d5daeSCorey Hardesty inline void
1315797d5daeSCorey Hardesty     setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1316797d5daeSCorey Hardesty                               const uint32_t retryAttempts)
1317797d5daeSCorey Hardesty {
1318797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1319797d5daeSCorey Hardesty     crow::connections::systemBus->async_method_call(
1320797d5daeSCorey Hardesty         [aResp](const boost::system::error_code& ec) {
1321797d5daeSCorey Hardesty         if (ec)
1322797d5daeSCorey Hardesty         {
1323797d5daeSCorey Hardesty             BMCWEB_LOG_ERROR
1324797d5daeSCorey Hardesty                 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
1325797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1326797d5daeSCorey Hardesty             return;
1327797d5daeSCorey Hardesty         }
1328797d5daeSCorey Hardesty         },
1329797d5daeSCorey Hardesty         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1330797d5daeSCorey Hardesty         "org.freedesktop.DBus.Properties", "Set",
1331797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1332797d5daeSCorey Hardesty         std::variant<uint32_t>(retryAttempts));
1333797d5daeSCorey Hardesty }
1334797d5daeSCorey Hardesty 
1335797d5daeSCorey Hardesty /**
1336c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1337c6a620f2SGeorge Liu  *
1338c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1339c6a620f2SGeorge Liu  *
1340c6a620f2SGeorge Liu  * @return None.
1341c6a620f2SGeorge Liu  */
13428d1b46d7Szhanghch05 inline void
13438d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1344c6a620f2SGeorge Liu {
1345c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1346c6a620f2SGeorge Liu 
13471e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13481e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13491e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13501e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
13515e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
13525e7e2dc5SEd Tanous                 const std::string& policy) {
1353c6a620f2SGeorge Liu         if (ec)
1354c6a620f2SGeorge Liu         {
1355c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1356c6a620f2SGeorge Liu             return;
1357c6a620f2SGeorge Liu         }
1358c6a620f2SGeorge Liu 
13590fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
13600fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1361c6a620f2SGeorge Liu              "AlwaysOn"},
13620fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1363c6a620f2SGeorge Liu              "AlwaysOff"},
13640fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
13654ed47cb8SMatthew Barth              "LastState"},
13664ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
13674ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
13684ed47cb8SMatthew Barth              "AlwaysOff"}};
1369c6a620f2SGeorge Liu 
13701e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1371c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1372c6a620f2SGeorge Liu         {
1373c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1374c6a620f2SGeorge Liu             return;
1375c6a620f2SGeorge Liu         }
1376c6a620f2SGeorge Liu 
1377c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
13781e1e598dSJonathan Doman         });
1379c6a620f2SGeorge Liu }
1380c6a620f2SGeorge Liu 
1381c6a620f2SGeorge Liu /**
13821981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13831981771bSAli Ahmed  * TPM is required for booting the host.
13841981771bSAli Ahmed  *
13851981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13861981771bSAli Ahmed  *
13871981771bSAli Ahmed  * @return None.
13881981771bSAli Ahmed  */
13891981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13901981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13911981771bSAli Ahmed {
13921981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1393e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1394e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1395e99073f5SGeorge Liu     dbus::utility::getSubTree(
1396e99073f5SGeorge Liu         "/", 0, interfaces,
1397e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1398b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
13991981771bSAli Ahmed         if (ec)
14001981771bSAli Ahmed         {
1401002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1402002d39b4SEd Tanous                              << ec;
14031981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14041981771bSAli Ahmed             // error occurs
14051981771bSAli Ahmed             return;
14061981771bSAli Ahmed         }
140726f6976fSEd Tanous         if (subtree.empty())
14081981771bSAli Ahmed         {
14091981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14101981771bSAli Ahmed             // if there is no instance found
14111981771bSAli Ahmed             return;
14121981771bSAli Ahmed         }
14131981771bSAli Ahmed 
14141981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14151981771bSAli Ahmed         if (subtree.size() > 1)
14161981771bSAli Ahmed         {
14171981771bSAli Ahmed             BMCWEB_LOG_DEBUG
14181981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14191981771bSAli Ahmed                 << subtree.size();
14201981771bSAli Ahmed             // Throw an internal Error and return
14211981771bSAli Ahmed             messages::internalError(aResp->res);
14221981771bSAli Ahmed             return;
14231981771bSAli Ahmed         }
14241981771bSAli Ahmed 
14251981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14261981771bSAli Ahmed         // field
14271981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14281981771bSAli Ahmed         {
14291981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14301981771bSAli Ahmed             messages::internalError(aResp->res);
14311981771bSAli Ahmed             return;
14321981771bSAli Ahmed         }
14331981771bSAli Ahmed 
14341981771bSAli Ahmed         const std::string& path = subtree[0].first;
14351981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14361981771bSAli Ahmed 
14371981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14381e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14391e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14401e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
14415e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
14428a592810SEd Tanous             if (ec2)
14431981771bSAli Ahmed             {
1444002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
14458a592810SEd Tanous                                  << ec2;
14461981771bSAli Ahmed                 messages::internalError(aResp->res);
14471981771bSAli Ahmed                 return;
14481981771bSAli Ahmed             }
14491981771bSAli Ahmed 
14501e1e598dSJonathan Doman             if (tpmRequired)
14511981771bSAli Ahmed             {
1452002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14531981771bSAli Ahmed                     "Required";
14541981771bSAli Ahmed             }
14551981771bSAli Ahmed             else
14561981771bSAli Ahmed             {
1457002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14581981771bSAli Ahmed                     "Disabled";
14591981771bSAli Ahmed             }
14601e1e598dSJonathan Doman             });
1461e99073f5SGeorge Liu         });
14621981771bSAli Ahmed }
14631981771bSAli Ahmed 
14641981771bSAli Ahmed /**
14651c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14661c05dae3SAli Ahmed  * TPM is required for booting the host.
14671c05dae3SAli Ahmed  *
14681c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14691c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14701c05dae3SAli Ahmed  *
14711c05dae3SAli Ahmed  * @return None.
14721c05dae3SAli Ahmed  */
14731c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14741c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14751c05dae3SAli Ahmed {
14761c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1477e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1478e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1479e99073f5SGeorge Liu     dbus::utility::getSubTree(
1480e99073f5SGeorge Liu         "/", 0, interfaces,
1481e99073f5SGeorge Liu         [aResp,
1482e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1483e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14841c05dae3SAli Ahmed         if (ec)
14851c05dae3SAli Ahmed         {
1486002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1487002d39b4SEd Tanous                              << ec;
14881c05dae3SAli Ahmed             messages::internalError(aResp->res);
14891c05dae3SAli Ahmed             return;
14901c05dae3SAli Ahmed         }
149126f6976fSEd Tanous         if (subtree.empty())
14921c05dae3SAli Ahmed         {
14931c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14941c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14951c05dae3SAli Ahmed             return;
14961c05dae3SAli Ahmed         }
14971c05dae3SAli Ahmed 
14981c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
14991c05dae3SAli Ahmed         if (subtree.size() > 1)
15001c05dae3SAli Ahmed         {
15011c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
15021c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
15031c05dae3SAli Ahmed                 << subtree.size();
15041c05dae3SAli Ahmed             // Throw an internal Error and return
15051c05dae3SAli Ahmed             messages::internalError(aResp->res);
15061c05dae3SAli Ahmed             return;
15071c05dae3SAli Ahmed         }
15081c05dae3SAli Ahmed 
15091c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15101c05dae3SAli Ahmed         // field
15111c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15121c05dae3SAli Ahmed         {
15131c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
15141c05dae3SAli Ahmed             messages::internalError(aResp->res);
15151c05dae3SAli Ahmed             return;
15161c05dae3SAli Ahmed         }
15171c05dae3SAli Ahmed 
15181c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15191c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15201c05dae3SAli Ahmed 
15211c05dae3SAli Ahmed         if (serv.empty())
15221c05dae3SAli Ahmed         {
15231c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
15241c05dae3SAli Ahmed             messages::internalError(aResp->res);
15251c05dae3SAli Ahmed             return;
15261c05dae3SAli Ahmed         }
15271c05dae3SAli Ahmed 
15281c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15291c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
15305e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
15318a592810SEd Tanous             if (ec2)
15321c05dae3SAli Ahmed             {
15330fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
15340fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
15358a592810SEd Tanous                     << ec2;
15361c05dae3SAli Ahmed                 messages::internalError(aResp->res);
15371c05dae3SAli Ahmed                 return;
15381c05dae3SAli Ahmed             }
15391c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15401c05dae3SAli Ahmed             },
15411c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
15421c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1543168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1544e99073f5SGeorge Liu         });
15451c05dae3SAli Ahmed }
15461c05dae3SAli Ahmed 
15471c05dae3SAli Ahmed /**
1548491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1549491d8ee7SSantosh Puranik  *
1550491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1551cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1552cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1553cd9a4666SKonstantin Aladyshev  */
1554cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1555cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1556cd9a4666SKonstantin Aladyshev {
1557c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1558cd9a4666SKonstantin Aladyshev 
1559c21865c4SKonstantin Aladyshev     if (!bootType)
1560cd9a4666SKonstantin Aladyshev     {
1561c21865c4SKonstantin Aladyshev         return;
1562c21865c4SKonstantin Aladyshev     }
1563c21865c4SKonstantin Aladyshev 
1564cd9a4666SKonstantin Aladyshev     // Source target specified
1565cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1566cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1567cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1568cd9a4666SKonstantin Aladyshev     {
1569cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1570cd9a4666SKonstantin Aladyshev     }
1571cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1572cd9a4666SKonstantin Aladyshev     {
1573cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1574cd9a4666SKonstantin Aladyshev     }
1575cd9a4666SKonstantin Aladyshev     else
1576cd9a4666SKonstantin Aladyshev     {
1577cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1578cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1579cd9a4666SKonstantin Aladyshev                          << *bootType;
1580cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1581cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1582cd9a4666SKonstantin Aladyshev         return;
1583cd9a4666SKonstantin Aladyshev     }
1584cd9a4666SKonstantin Aladyshev 
1585cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1586cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1587cd9a4666SKonstantin Aladyshev 
1588cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15895e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1590cd9a4666SKonstantin Aladyshev         if (ec)
1591cd9a4666SKonstantin Aladyshev         {
1592cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1593cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1594cd9a4666SKonstantin Aladyshev             {
1595cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1596cd9a4666SKonstantin Aladyshev                 return;
1597cd9a4666SKonstantin Aladyshev             }
1598cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1599cd9a4666SKonstantin Aladyshev             return;
1600cd9a4666SKonstantin Aladyshev         }
1601cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1602cd9a4666SKonstantin Aladyshev         },
1603c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1604c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1605cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1606cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1607168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1608cd9a4666SKonstantin Aladyshev }
1609cd9a4666SKonstantin Aladyshev 
1610cd9a4666SKonstantin Aladyshev /**
1611cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1612cd9a4666SKonstantin Aladyshev  *
1613cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1614c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1615c21865c4SKonstantin Aladyshev  * @return Integer error code.
1616c21865c4SKonstantin Aladyshev  */
1617c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1618c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1619c21865c4SKonstantin Aladyshev {
1620c21865c4SKonstantin Aladyshev     if (!bootEnable)
1621c21865c4SKonstantin Aladyshev     {
1622c21865c4SKonstantin Aladyshev         return;
1623c21865c4SKonstantin Aladyshev     }
1624c21865c4SKonstantin Aladyshev     // Source target specified
1625c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1626c21865c4SKonstantin Aladyshev 
1627c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1628c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1629c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1630c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1631c21865c4SKonstantin Aladyshev     {
1632c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1633c21865c4SKonstantin Aladyshev     }
1634c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1635c21865c4SKonstantin Aladyshev     {
1636c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1637c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1638c21865c4SKonstantin Aladyshev     }
1639c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1640c21865c4SKonstantin Aladyshev     {
1641c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1642c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1643c21865c4SKonstantin Aladyshev     }
1644c21865c4SKonstantin Aladyshev     else
1645c21865c4SKonstantin Aladyshev     {
16460fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16470fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1648c21865c4SKonstantin Aladyshev             << *bootEnable;
1649c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1650c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1651c21865c4SKonstantin Aladyshev         return;
1652c21865c4SKonstantin Aladyshev     }
1653c21865c4SKonstantin Aladyshev 
1654c21865c4SKonstantin Aladyshev     // Act on validated parameters
1655c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1656c21865c4SKonstantin Aladyshev 
1657c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16585e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
16598a592810SEd Tanous         if (ec2)
1660c21865c4SKonstantin Aladyshev         {
16618a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1662c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1663c21865c4SKonstantin Aladyshev             return;
1664c21865c4SKonstantin Aladyshev         }
1665c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1666c21865c4SKonstantin Aladyshev         },
1667c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1668c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1669c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1670c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1671168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1672c21865c4SKonstantin Aladyshev 
1673c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1674c21865c4SKonstantin Aladyshev     {
1675c21865c4SKonstantin Aladyshev         return;
1676c21865c4SKonstantin Aladyshev     }
1677c21865c4SKonstantin Aladyshev 
1678c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1679c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1680c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1681c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1682c21865c4SKonstantin Aladyshev 
1683c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16845e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1685c21865c4SKonstantin Aladyshev         if (ec)
1686c21865c4SKonstantin Aladyshev         {
1687c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1688c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1689c21865c4SKonstantin Aladyshev             return;
1690c21865c4SKonstantin Aladyshev         }
1691c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1692c21865c4SKonstantin Aladyshev         },
1693c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1694c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1695c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1696c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1697168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1698c21865c4SKonstantin Aladyshev }
1699c21865c4SKonstantin Aladyshev 
1700c21865c4SKonstantin Aladyshev /**
1701c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1702c21865c4SKonstantin Aladyshev  *
1703c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1704491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1705491d8ee7SSantosh Puranik  *
1706265c1602SJohnathan Mantey  * @return Integer error code.
1707491d8ee7SSantosh Puranik  */
1708cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1709cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1710491d8ee7SSantosh Puranik {
1711c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1712c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1713944ffaf9SJohnathan Mantey 
1714c21865c4SKonstantin Aladyshev     if (!bootSource)
1715491d8ee7SSantosh Puranik     {
1716c21865c4SKonstantin Aladyshev         return;
1717c21865c4SKonstantin Aladyshev     }
1718c21865c4SKonstantin Aladyshev 
1719491d8ee7SSantosh Puranik     // Source target specified
1720491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1721491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1722e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1723e662eae8SEd Tanous         0)
1724491d8ee7SSantosh Puranik     {
1725944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1726944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1727491d8ee7SSantosh Puranik             << *bootSource;
1728491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1729491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1730491d8ee7SSantosh Puranik         return;
1731491d8ee7SSantosh Puranik     }
1732491d8ee7SSantosh Puranik 
1733944ffaf9SJohnathan Mantey     // Act on validated parameters
1734944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1735944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1736944ffaf9SJohnathan Mantey 
1737491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17385e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1739491d8ee7SSantosh Puranik         if (ec)
1740491d8ee7SSantosh Puranik         {
1741491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1742491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1743491d8ee7SSantosh Puranik             return;
1744491d8ee7SSantosh Puranik         }
1745491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1746491d8ee7SSantosh Puranik         },
1747c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1748c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1749491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1750491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1751168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1752944ffaf9SJohnathan Mantey 
1753491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17545e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1755491d8ee7SSantosh Puranik         if (ec)
1756491d8ee7SSantosh Puranik         {
1757491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1758491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1759491d8ee7SSantosh Puranik             return;
1760491d8ee7SSantosh Puranik         }
1761491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1762491d8ee7SSantosh Puranik         },
1763c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1764c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1765491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1766491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1767168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1768cd9a4666SKonstantin Aladyshev }
1769944ffaf9SJohnathan Mantey 
1770cd9a4666SKonstantin Aladyshev /**
1771c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1772491d8ee7SSantosh Puranik  *
1773491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1774491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1775cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1776491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1777491d8ee7SSantosh Puranik  *
1778265c1602SJohnathan Mantey  * @return Integer error code.
1779491d8ee7SSantosh Puranik  */
1780c21865c4SKonstantin Aladyshev 
1781c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1782c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1783c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1784c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1785491d8ee7SSantosh Puranik {
1786491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1787491d8ee7SSantosh Puranik 
1788c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1789c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1790c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1791491d8ee7SSantosh Puranik }
1792491d8ee7SSantosh Puranik 
1793c6a620f2SGeorge Liu /**
179498e386ecSGunnar Mills  * @brief Sets AssetTag
179598e386ecSGunnar Mills  *
179698e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
179798e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
179898e386ecSGunnar Mills  *
179998e386ecSGunnar Mills  * @return None.
180098e386ecSGunnar Mills  */
18018d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
180298e386ecSGunnar Mills                         const std::string& assetTag)
180398e386ecSGunnar Mills {
1804e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1805e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1806e99073f5SGeorge Liu     dbus::utility::getSubTree(
1807e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1808b9d36b47SEd Tanous         [aResp,
1809e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1810b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
181198e386ecSGunnar Mills         if (ec)
181298e386ecSGunnar Mills         {
181398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
181498e386ecSGunnar Mills             messages::internalError(aResp->res);
181598e386ecSGunnar Mills             return;
181698e386ecSGunnar Mills         }
181726f6976fSEd Tanous         if (subtree.empty())
181898e386ecSGunnar Mills         {
181998e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
182098e386ecSGunnar Mills             messages::internalError(aResp->res);
182198e386ecSGunnar Mills             return;
182298e386ecSGunnar Mills         }
182398e386ecSGunnar Mills         // Assume only 1 system D-Bus object
182498e386ecSGunnar Mills         // Throw an error if there is more than 1
182598e386ecSGunnar Mills         if (subtree.size() > 1)
182698e386ecSGunnar Mills         {
182798e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
182898e386ecSGunnar Mills             messages::internalError(aResp->res);
182998e386ecSGunnar Mills             return;
183098e386ecSGunnar Mills         }
183198e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
183298e386ecSGunnar Mills         {
183398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
183498e386ecSGunnar Mills             messages::internalError(aResp->res);
183598e386ecSGunnar Mills             return;
183698e386ecSGunnar Mills         }
183798e386ecSGunnar Mills 
183898e386ecSGunnar Mills         const std::string& path = subtree[0].first;
183998e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
184098e386ecSGunnar Mills 
184198e386ecSGunnar Mills         if (service.empty())
184298e386ecSGunnar Mills         {
184398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
184498e386ecSGunnar Mills             messages::internalError(aResp->res);
184598e386ecSGunnar Mills             return;
184698e386ecSGunnar Mills         }
184798e386ecSGunnar Mills 
184898e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
18495e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
185098e386ecSGunnar Mills             if (ec2)
185198e386ecSGunnar Mills             {
1852002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1853002d39b4SEd Tanous                                  << ec2;
185498e386ecSGunnar Mills                 messages::internalError(aResp->res);
185598e386ecSGunnar Mills                 return;
185698e386ecSGunnar Mills             }
185798e386ecSGunnar Mills             },
185898e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
185998e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1860168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1861e99073f5SGeorge Liu         });
186298e386ecSGunnar Mills }
186398e386ecSGunnar Mills 
186498e386ecSGunnar Mills /**
186569f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
186669f35306SGunnar Mills  *
186769f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
186869f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
186969f35306SGunnar Mills  *
187069f35306SGunnar Mills  * @return None.
187169f35306SGunnar Mills  */
18728d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1873f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
187469f35306SGunnar Mills {
187569f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
187669f35306SGunnar Mills 
187769f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1878543f4400SEd Tanous     bool autoRebootEnabled = false;
187969f35306SGunnar Mills 
188069f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
188169f35306SGunnar Mills     {
188269f35306SGunnar Mills         autoRebootEnabled = false;
188369f35306SGunnar Mills     }
188469f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
188569f35306SGunnar Mills     {
188669f35306SGunnar Mills         autoRebootEnabled = true;
188769f35306SGunnar Mills     }
188869f35306SGunnar Mills     else
188969f35306SGunnar Mills     {
18900fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
189169f35306SGunnar Mills                          << automaticRetryConfig;
189269f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
189369f35306SGunnar Mills                                          "AutomaticRetryConfig");
189469f35306SGunnar Mills         return;
189569f35306SGunnar Mills     }
189669f35306SGunnar Mills 
189769f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
18985e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
189969f35306SGunnar Mills         if (ec)
190069f35306SGunnar Mills         {
190169f35306SGunnar Mills             messages::internalError(aResp->res);
190269f35306SGunnar Mills             return;
190369f35306SGunnar Mills         }
190469f35306SGunnar Mills         },
190569f35306SGunnar Mills         "xyz.openbmc_project.Settings",
190669f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
190769f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
190869f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1909168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
191069f35306SGunnar Mills }
191169f35306SGunnar Mills 
191269f35306SGunnar Mills /**
1913c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1914c6a620f2SGeorge Liu  *
1915c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1916c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1917c6a620f2SGeorge Liu  *
1918c6a620f2SGeorge Liu  * @return None.
1919c6a620f2SGeorge Liu  */
19208d1b46d7Szhanghch05 inline void
19218d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19224e69c904SGunnar Mills                           const std::string& policy)
1923c6a620f2SGeorge Liu {
1924c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1925c6a620f2SGeorge Liu 
1926c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
19270fda0f12SGeorge Liu         {"AlwaysOn",
19280fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
19290fda0f12SGeorge Liu         {"AlwaysOff",
19300fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
19310fda0f12SGeorge Liu         {"LastState",
19320fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1933c6a620f2SGeorge Liu 
1934c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1935c6a620f2SGeorge Liu 
19364e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1937c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1938c6a620f2SGeorge Liu     {
19394e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19404e69c904SGunnar Mills                                          "PowerRestorePolicy");
1941c6a620f2SGeorge Liu         return;
1942c6a620f2SGeorge Liu     }
1943c6a620f2SGeorge Liu 
1944c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1945c6a620f2SGeorge Liu 
1946c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
19475e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1948c6a620f2SGeorge Liu         if (ec)
1949c6a620f2SGeorge Liu         {
1950c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1951c6a620f2SGeorge Liu             return;
1952c6a620f2SGeorge Liu         }
1953c6a620f2SGeorge Liu         },
1954c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1955c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1956c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1957c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1958168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1959c6a620f2SGeorge Liu }
1960c6a620f2SGeorge Liu 
1961a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1962a6349918SAppaRao Puli /**
1963a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1964a6349918SAppaRao Puli  *
1965a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1966a6349918SAppaRao Puli  *
1967a6349918SAppaRao Puli  * @return None.
1968a6349918SAppaRao Puli  */
19698d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1970a6349918SAppaRao Puli {
1971a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1972bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1973bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1974bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
19755e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1976b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1977b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1978b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
197950626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
198050626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
198150626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
198250626f4fSJames Feist 
1983a6349918SAppaRao Puli         if (ec)
1984a6349918SAppaRao Puli         {
1985a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1986b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1987b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1988a6349918SAppaRao Puli             return;
1989a6349918SAppaRao Puli         }
1990a6349918SAppaRao Puli 
1991a6349918SAppaRao Puli         const bool* provState = nullptr;
1992a6349918SAppaRao Puli         const bool* lockState = nullptr;
1993bc1d29deSKrzysztof Grobelny 
1994bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19950d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19960d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1997bc1d29deSKrzysztof Grobelny 
1998bc1d29deSKrzysztof Grobelny         if (!success)
1999a6349918SAppaRao Puli         {
2000bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
2001bc1d29deSKrzysztof Grobelny             return;
2002a6349918SAppaRao Puli         }
2003a6349918SAppaRao Puli 
2004a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2005a6349918SAppaRao Puli         {
2006a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
2007a6349918SAppaRao Puli             messages::internalError(aResp->res);
2008a6349918SAppaRao Puli             return;
2009a6349918SAppaRao Puli         }
2010a6349918SAppaRao Puli 
2011a6349918SAppaRao Puli         if (*provState == true)
2012a6349918SAppaRao Puli         {
2013a6349918SAppaRao Puli             if (*lockState == true)
2014a6349918SAppaRao Puli             {
2015a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2016a6349918SAppaRao Puli             }
2017a6349918SAppaRao Puli             else
2018a6349918SAppaRao Puli             {
2019a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2020a6349918SAppaRao Puli             }
2021a6349918SAppaRao Puli         }
2022a6349918SAppaRao Puli         else
2023a6349918SAppaRao Puli         {
2024a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2025a6349918SAppaRao Puli         }
2026bc1d29deSKrzysztof Grobelny         });
2027a6349918SAppaRao Puli }
2028a6349918SAppaRao Puli #endif
2029a6349918SAppaRao Puli 
2030491d8ee7SSantosh Puranik /**
20313a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20323a2d0424SChris Cain  *
20333a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20343a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20353a2d0424SChris Cain  *
20363a2d0424SChris Cain  * @return None.
20373a2d0424SChris Cain  */
20383a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20393a2d0424SChris Cain                                const std::string& modeValue)
20403a2d0424SChris Cain {
20410fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20423a2d0424SChris Cain     {
20433a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20443a2d0424SChris Cain     }
20450fda0f12SGeorge Liu     else if (
20460fda0f12SGeorge Liu         modeValue ==
20470fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20483a2d0424SChris Cain     {
20493a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20503a2d0424SChris Cain     }
20510fda0f12SGeorge Liu     else if (modeValue ==
20520fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20533a2d0424SChris Cain     {
20543a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20553a2d0424SChris Cain     }
20560fda0f12SGeorge Liu     else if (modeValue ==
20570fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20583a2d0424SChris Cain     {
20593a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20603a2d0424SChris Cain     }
20613a2d0424SChris Cain     else
20623a2d0424SChris Cain     {
20633a2d0424SChris Cain         // Any other values would be invalid
20643a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20653a2d0424SChris Cain         messages::internalError(aResp->res);
20663a2d0424SChris Cain     }
20673a2d0424SChris Cain }
20683a2d0424SChris Cain 
20693a2d0424SChris Cain /**
20703a2d0424SChris Cain  * @brief Retrieves system power mode
20713a2d0424SChris Cain  *
20723a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20733a2d0424SChris Cain  *
20743a2d0424SChris Cain  * @return None.
20753a2d0424SChris Cain  */
20763a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20773a2d0424SChris Cain {
20783a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20793a2d0424SChris Cain 
20803a2d0424SChris Cain     // Get Power Mode object path:
2081e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2082e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2083e99073f5SGeorge Liu     dbus::utility::getSubTree(
2084e99073f5SGeorge Liu         "/", 0, interfaces,
2085e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2086b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
20873a2d0424SChris Cain         if (ec)
20883a2d0424SChris Cain         {
2089002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2090002d39b4SEd Tanous                              << ec;
20913a2d0424SChris Cain             // This is an optional D-Bus object so just return if
20923a2d0424SChris Cain             // error occurs
20933a2d0424SChris Cain             return;
20943a2d0424SChris Cain         }
20953a2d0424SChris Cain         if (subtree.empty())
20963a2d0424SChris Cain         {
20973a2d0424SChris Cain             // As noted above, this is an optional interface so just return
20983a2d0424SChris Cain             // if there is no instance found
20993a2d0424SChris Cain             return;
21003a2d0424SChris Cain         }
21013a2d0424SChris Cain         if (subtree.size() > 1)
21023a2d0424SChris Cain         {
21033a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21043a2d0424SChris Cain             // error
21053a2d0424SChris Cain             BMCWEB_LOG_DEBUG
21063a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
21073a2d0424SChris Cain                 << subtree.size();
21083a2d0424SChris Cain             messages::internalError(aResp->res);
21093a2d0424SChris Cain             return;
21103a2d0424SChris Cain         }
21113a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21123a2d0424SChris Cain         {
21133a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21143a2d0424SChris Cain             messages::internalError(aResp->res);
21153a2d0424SChris Cain             return;
21163a2d0424SChris Cain         }
21173a2d0424SChris Cain         const std::string& path = subtree[0].first;
21183a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21193a2d0424SChris Cain         if (service.empty())
21203a2d0424SChris Cain         {
21213a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21223a2d0424SChris Cain             messages::internalError(aResp->res);
21233a2d0424SChris Cain             return;
21243a2d0424SChris Cain         }
21253a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
21261e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
21271e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
21281e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
21295e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
21301e1e598dSJonathan Doman                     const std::string& pmode) {
21318a592810SEd Tanous             if (ec2)
21323a2d0424SChris Cain             {
2133002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
21348a592810SEd Tanous                                  << ec2;
21353a2d0424SChris Cain                 messages::internalError(aResp->res);
21363a2d0424SChris Cain                 return;
21373a2d0424SChris Cain             }
21383a2d0424SChris Cain 
2139002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2140002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
21413a2d0424SChris Cain 
21421e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
21431e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
21441e1e598dSJonathan Doman             });
2145e99073f5SGeorge Liu         });
21463a2d0424SChris Cain }
21473a2d0424SChris Cain 
21483a2d0424SChris Cain /**
21493a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21503a2d0424SChris Cain  * name associated with that string
21513a2d0424SChris Cain  *
21523a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21533a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21543a2d0424SChris Cain  *
21553a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21563a2d0424SChris Cain  */
21573a2d0424SChris Cain inline std::string
21583a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21593a2d0424SChris Cain                       const std::string& modeString)
21603a2d0424SChris Cain {
21613a2d0424SChris Cain     std::string mode;
21623a2d0424SChris Cain 
21633a2d0424SChris Cain     if (modeString == "Static")
21643a2d0424SChris Cain     {
21653a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21663a2d0424SChris Cain     }
21673a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21683a2d0424SChris Cain     {
21690fda0f12SGeorge Liu         mode =
21700fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21713a2d0424SChris Cain     }
21723a2d0424SChris Cain     else if (modeString == "PowerSaving")
21733a2d0424SChris Cain     {
21743a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21753a2d0424SChris Cain     }
21763a2d0424SChris Cain     else
21773a2d0424SChris Cain     {
21783a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21793a2d0424SChris Cain     }
21803a2d0424SChris Cain     return mode;
21813a2d0424SChris Cain }
21823a2d0424SChris Cain 
21833a2d0424SChris Cain /**
21843a2d0424SChris Cain  * @brief Sets system power mode.
21853a2d0424SChris Cain  *
21863a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21873a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21883a2d0424SChris Cain  *
21893a2d0424SChris Cain  * @return None.
21903a2d0424SChris Cain  */
21913a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21923a2d0424SChris Cain                          const std::string& pmode)
21933a2d0424SChris Cain {
21943a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21953a2d0424SChris Cain 
21963a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
21973a2d0424SChris Cain     if (powerMode.empty())
21983a2d0424SChris Cain     {
21993a2d0424SChris Cain         return;
22003a2d0424SChris Cain     }
22013a2d0424SChris Cain 
22023a2d0424SChris Cain     // Get Power Mode object path:
2203e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2204e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2205e99073f5SGeorge Liu     dbus::utility::getSubTree(
2206e99073f5SGeorge Liu         "/", 0, interfaces,
2207b9d36b47SEd Tanous         [aResp,
2208e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2209b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22103a2d0424SChris Cain         if (ec)
22113a2d0424SChris Cain         {
2212002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2213002d39b4SEd Tanous                              << ec;
22143a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
22153a2d0424SChris Cain             messages::internalError(aResp->res);
22163a2d0424SChris Cain             return;
22173a2d0424SChris Cain         }
22183a2d0424SChris Cain         if (subtree.empty())
22193a2d0424SChris Cain         {
22203a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
22213a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
22223a2d0424SChris Cain                                        "PowerMode");
22233a2d0424SChris Cain             return;
22243a2d0424SChris Cain         }
22253a2d0424SChris Cain         if (subtree.size() > 1)
22263a2d0424SChris Cain         {
22273a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22283a2d0424SChris Cain             // error
22293a2d0424SChris Cain             BMCWEB_LOG_DEBUG
22303a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
22313a2d0424SChris Cain                 << subtree.size();
22323a2d0424SChris Cain             messages::internalError(aResp->res);
22333a2d0424SChris Cain             return;
22343a2d0424SChris Cain         }
22353a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22363a2d0424SChris Cain         {
22373a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22383a2d0424SChris Cain             messages::internalError(aResp->res);
22393a2d0424SChris Cain             return;
22403a2d0424SChris Cain         }
22413a2d0424SChris Cain         const std::string& path = subtree[0].first;
22423a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22433a2d0424SChris Cain         if (service.empty())
22443a2d0424SChris Cain         {
22453a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22463a2d0424SChris Cain             messages::internalError(aResp->res);
22473a2d0424SChris Cain             return;
22483a2d0424SChris Cain         }
22493a2d0424SChris Cain 
22503a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22513a2d0424SChris Cain                          << path;
22523a2d0424SChris Cain 
22533a2d0424SChris Cain         // Set the Power Mode property
22543a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
22555e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
22568a592810SEd Tanous             if (ec2)
22573a2d0424SChris Cain             {
22583a2d0424SChris Cain                 messages::internalError(aResp->res);
22593a2d0424SChris Cain                 return;
22603a2d0424SChris Cain             }
22613a2d0424SChris Cain             },
22623a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
22633a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2264168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2265e99073f5SGeorge Liu         });
22663a2d0424SChris Cain }
22673a2d0424SChris Cain 
22683a2d0424SChris Cain /**
226951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
227051709ffdSYong Li  *
227151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
227251709ffdSYong Li  *
227351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
227451709ffdSYong Li  * translation cannot be done, returns an empty string.
227551709ffdSYong Li  */
227623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
227751709ffdSYong Li {
227851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
227951709ffdSYong Li     {
228051709ffdSYong Li         return "None";
228151709ffdSYong Li     }
22823174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
228351709ffdSYong Li     {
228451709ffdSYong Li         return "ResetSystem";
228551709ffdSYong Li     }
22863174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
228751709ffdSYong Li     {
228851709ffdSYong Li         return "PowerDown";
228951709ffdSYong Li     }
22903174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
229151709ffdSYong Li     {
229251709ffdSYong Li         return "PowerCycle";
229351709ffdSYong Li     }
229451709ffdSYong Li 
229551709ffdSYong Li     return "";
229651709ffdSYong Li }
229751709ffdSYong Li 
229851709ffdSYong Li /**
2299c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2300c45f0082SYong Li  *
2301c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2302c45f0082SYong Li  *
2303c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2304c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2305c45f0082SYong Li  */
2306c45f0082SYong Li 
230723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2308c45f0082SYong Li {
2309c45f0082SYong Li     if (rfAction == "None")
2310c45f0082SYong Li     {
2311c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2312c45f0082SYong Li     }
23133174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2314c45f0082SYong Li     {
2315c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2316c45f0082SYong Li     }
23173174e4dfSEd Tanous     if (rfAction == "PowerDown")
2318c45f0082SYong Li     {
2319c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2320c45f0082SYong Li     }
23213174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2322c45f0082SYong Li     {
2323c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2324c45f0082SYong Li     }
2325c45f0082SYong Li 
2326c45f0082SYong Li     return "";
2327c45f0082SYong Li }
2328c45f0082SYong Li 
2329c45f0082SYong Li /**
233051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
233151709ffdSYong Li  *
233251709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
233351709ffdSYong Li  *
233451709ffdSYong Li  * @return None.
233551709ffdSYong Li  */
23368d1b46d7Szhanghch05 inline void
23378d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
233851709ffdSYong Li {
233951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2340bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2341bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2342bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2343bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
23445e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2345b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
234651709ffdSYong Li         if (ec)
234751709ffdSYong Li         {
234851709ffdSYong Li             // watchdog service is stopped
234951709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
235051709ffdSYong Li             return;
235151709ffdSYong Li         }
235251709ffdSYong Li 
235351709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
235451709ffdSYong Li 
235551709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
235651709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
235751709ffdSYong Li 
235851709ffdSYong Li         // watchdog service is running/enabled
235951709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
236051709ffdSYong Li 
2361bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2362bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
236351709ffdSYong Li 
2364bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2365bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2366bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2367bc1d29deSKrzysztof Grobelny 
2368bc1d29deSKrzysztof Grobelny         if (!success)
236951709ffdSYong Li         {
237051709ffdSYong Li             messages::internalError(aResp->res);
2371601af5edSChicago Duan             return;
237251709ffdSYong Li         }
237351709ffdSYong Li 
2374bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
237551709ffdSYong Li         {
2376bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
237751709ffdSYong Li         }
237851709ffdSYong Li 
2379bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2380bc1d29deSKrzysztof Grobelny         {
2381bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
238251709ffdSYong Li             if (action.empty())
238351709ffdSYong Li             {
238451709ffdSYong Li                 messages::internalError(aResp->res);
2385601af5edSChicago Duan                 return;
238651709ffdSYong Li             }
238751709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
238851709ffdSYong Li         }
2389bc1d29deSKrzysztof Grobelny         });
239051709ffdSYong Li }
239151709ffdSYong Li 
239251709ffdSYong Li /**
2393c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2394c45f0082SYong Li  *
2395c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2396c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2397c45f0082SYong Li  *                       RF request.
2398c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2399c45f0082SYong Li  *
2400c45f0082SYong Li  * @return None.
2401c45f0082SYong Li  */
24028d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2403c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2404c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2405c45f0082SYong Li {
2406c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2407c45f0082SYong Li 
2408c45f0082SYong Li     if (wdtTimeOutAction)
2409c45f0082SYong Li     {
2410c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2411c45f0082SYong Li         // check if TimeOut Action is Valid
2412c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2413c45f0082SYong Li         {
2414c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2415c45f0082SYong Li                              << *wdtTimeOutAction;
2416c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2417c45f0082SYong Li                                              "TimeoutAction");
2418c45f0082SYong Li             return;
2419c45f0082SYong Li         }
2420c45f0082SYong Li 
2421c45f0082SYong Li         crow::connections::systemBus->async_method_call(
24225e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2423c45f0082SYong Li             if (ec)
2424c45f0082SYong Li             {
2425c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2426c45f0082SYong Li                 messages::internalError(aResp->res);
2427c45f0082SYong Li                 return;
2428c45f0082SYong Li             }
2429c45f0082SYong Li             },
2430c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2431c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2432c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2433c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2434168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2435c45f0082SYong Li     }
2436c45f0082SYong Li 
2437c45f0082SYong Li     if (wdtEnable)
2438c45f0082SYong Li     {
2439c45f0082SYong Li         crow::connections::systemBus->async_method_call(
24405e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2441c45f0082SYong Li             if (ec)
2442c45f0082SYong Li             {
2443c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2444c45f0082SYong Li                 messages::internalError(aResp->res);
2445c45f0082SYong Li                 return;
2446c45f0082SYong Li             }
2447c45f0082SYong Li             },
2448c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2449c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2450c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2451c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2452168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2453c45f0082SYong Li     }
2454c45f0082SYong Li }
2455c45f0082SYong Li 
245637bbf98cSChris Cain /**
245737bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
245837bbf98cSChris Cain  *
245937bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
246037bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
246137bbf98cSChris Cain  *
246237bbf98cSChris Cain  * @return true if successful
246337bbf98cSChris Cain  */
24641e5b7c88SJiaqing Zhao inline bool
24651e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
24661e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
246737bbf98cSChris Cain {
2468bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2469bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2470bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2471bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2472bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2473bc1d29deSKrzysztof Grobelny 
2474bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2475bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
24762661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
24772661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
24782661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2479bc1d29deSKrzysztof Grobelny 
2480bc1d29deSKrzysztof Grobelny     if (!success)
248137bbf98cSChris Cain     {
248237bbf98cSChris Cain         return false;
248337bbf98cSChris Cain     }
2484bc1d29deSKrzysztof Grobelny 
2485bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
248637bbf98cSChris Cain     {
2487bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
248837bbf98cSChris Cain     }
2489bc1d29deSKrzysztof Grobelny 
2490bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
249137bbf98cSChris Cain     {
2492bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2493bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
249437bbf98cSChris Cain     }
2495bc1d29deSKrzysztof Grobelny 
2496bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2497bc1d29deSKrzysztof Grobelny     {
2498bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
249937bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
250037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
250137bbf98cSChris Cain                 .count();
250237bbf98cSChris Cain     }
2503bc1d29deSKrzysztof Grobelny 
2504bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
250537bbf98cSChris Cain     {
2506bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2507bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
250837bbf98cSChris Cain     }
2509bc1d29deSKrzysztof Grobelny 
2510bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
251137bbf98cSChris Cain     {
2512bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
251337bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
251437bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
251537bbf98cSChris Cain                 .count();
251637bbf98cSChris Cain     }
251737bbf98cSChris Cain 
251837bbf98cSChris Cain     return true;
251937bbf98cSChris Cain }
252037bbf98cSChris Cain 
252137bbf98cSChris Cain /**
252237bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
252337bbf98cSChris Cain  *
252437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
252537bbf98cSChris Cain  *
252637bbf98cSChris Cain  * @return None.
252737bbf98cSChris Cain  */
252837bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
252937bbf98cSChris Cain {
253037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
253137bbf98cSChris Cain 
253237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2533e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2534e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2535e99073f5SGeorge Liu     dbus::utility::getSubTree(
2536e99073f5SGeorge Liu         "/", 0, interfaces,
2537e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2538b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
253937bbf98cSChris Cain         if (ec)
254037bbf98cSChris Cain         {
254137bbf98cSChris Cain             BMCWEB_LOG_DEBUG
254237bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
254337bbf98cSChris Cain                 << ec;
254437bbf98cSChris Cain             messages::internalError(aResp->res);
254537bbf98cSChris Cain             return;
254637bbf98cSChris Cain         }
254737bbf98cSChris Cain         if (subtree.empty())
254837bbf98cSChris Cain         {
254937bbf98cSChris Cain             // This is an optional interface so just return
255037bbf98cSChris Cain             // if there is no instance found
255137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
255237bbf98cSChris Cain             return;
255337bbf98cSChris Cain         }
255437bbf98cSChris Cain         if (subtree.size() > 1)
255537bbf98cSChris Cain         {
255637bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
255737bbf98cSChris Cain             // is an error
255837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
255937bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
256037bbf98cSChris Cain                              << subtree.size();
256137bbf98cSChris Cain             messages::internalError(aResp->res);
256237bbf98cSChris Cain             return;
256337bbf98cSChris Cain         }
256437bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
256537bbf98cSChris Cain         {
256637bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
256737bbf98cSChris Cain             messages::internalError(aResp->res);
256837bbf98cSChris Cain             return;
256937bbf98cSChris Cain         }
257037bbf98cSChris Cain         const std::string& path = subtree[0].first;
257137bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
257237bbf98cSChris Cain         if (service.empty())
257337bbf98cSChris Cain         {
2574002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
257537bbf98cSChris Cain             messages::internalError(aResp->res);
257637bbf98cSChris Cain             return;
257737bbf98cSChris Cain         }
257837bbf98cSChris Cain 
257937bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2580bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2581bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2582bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
25835e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
25841e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
25858a592810SEd Tanous             if (ec2)
258637bbf98cSChris Cain             {
258737bbf98cSChris Cain                 BMCWEB_LOG_ERROR
25888a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
258937bbf98cSChris Cain                 messages::internalError(aResp->res);
259037bbf98cSChris Cain                 return;
259137bbf98cSChris Cain             }
259237bbf98cSChris Cain 
2593e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
259437bbf98cSChris Cain             {
259537bbf98cSChris Cain                 messages::internalError(aResp->res);
259637bbf98cSChris Cain                 return;
259737bbf98cSChris Cain             }
2598bc1d29deSKrzysztof Grobelny             });
2599e99073f5SGeorge Liu         });
260037bbf98cSChris Cain 
260137bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
260237bbf98cSChris Cain }
260337bbf98cSChris Cain 
260437bbf98cSChris Cain /**
260537bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
260637bbf98cSChris Cain  *
260737bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
260837bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
260937bbf98cSChris Cain  *                       RF request.
261037bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
261137bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
261237bbf98cSChris Cain  * before entering idle state.
261337bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
261437bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
261537bbf98cSChris Cain  * before exiting idle state
261637bbf98cSChris Cain  *
261737bbf98cSChris Cain  * @return None.
261837bbf98cSChris Cain  */
261937bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
262037bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
262137bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
262237bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
262337bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
262437bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
262537bbf98cSChris Cain {
262637bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
262737bbf98cSChris Cain 
262837bbf98cSChris Cain     // Get IdlePowerSaver object path:
2629e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2630e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2631e99073f5SGeorge Liu     dbus::utility::getSubTree(
2632e99073f5SGeorge Liu         "/", 0, interfaces,
263337bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2634e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2635b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
263637bbf98cSChris Cain         if (ec)
263737bbf98cSChris Cain         {
263837bbf98cSChris Cain             BMCWEB_LOG_DEBUG
263937bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
264037bbf98cSChris Cain                 << ec;
264137bbf98cSChris Cain             messages::internalError(aResp->res);
264237bbf98cSChris Cain             return;
264337bbf98cSChris Cain         }
264437bbf98cSChris Cain         if (subtree.empty())
264537bbf98cSChris Cain         {
264637bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
264737bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
264837bbf98cSChris Cain                                        "IdlePowerSaver");
264937bbf98cSChris Cain             return;
265037bbf98cSChris Cain         }
265137bbf98cSChris Cain         if (subtree.size() > 1)
265237bbf98cSChris Cain         {
265337bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
265437bbf98cSChris Cain             // is an error
26550fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
26560fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
265737bbf98cSChris Cain                 << subtree.size();
265837bbf98cSChris Cain             messages::internalError(aResp->res);
265937bbf98cSChris Cain             return;
266037bbf98cSChris Cain         }
266137bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
266237bbf98cSChris Cain         {
266337bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
266437bbf98cSChris Cain             messages::internalError(aResp->res);
266537bbf98cSChris Cain             return;
266637bbf98cSChris Cain         }
266737bbf98cSChris Cain         const std::string& path = subtree[0].first;
266837bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
266937bbf98cSChris Cain         if (service.empty())
267037bbf98cSChris Cain         {
2671002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
267237bbf98cSChris Cain             messages::internalError(aResp->res);
267337bbf98cSChris Cain             return;
267437bbf98cSChris Cain         }
267537bbf98cSChris Cain 
267637bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
267737bbf98cSChris Cain         // need to be updated
267837bbf98cSChris Cain 
267937bbf98cSChris Cain         if (ipsEnable)
268037bbf98cSChris Cain         {
268137bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26825e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26838a592810SEd Tanous                 if (ec2)
268437bbf98cSChris Cain                 {
26858a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
268637bbf98cSChris Cain                     messages::internalError(aResp->res);
268737bbf98cSChris Cain                     return;
268837bbf98cSChris Cain                 }
268937bbf98cSChris Cain                 },
269037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2691002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2692002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
269337bbf98cSChris Cain         }
269437bbf98cSChris Cain         if (ipsEnterUtil)
269537bbf98cSChris Cain         {
269637bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26975e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26988a592810SEd Tanous                 if (ec2)
269937bbf98cSChris Cain                 {
27008a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
270137bbf98cSChris Cain                     messages::internalError(aResp->res);
270237bbf98cSChris Cain                     return;
270337bbf98cSChris Cain                 }
270437bbf98cSChris Cain                 },
270537bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
270637bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
270737bbf98cSChris Cain                 "EnterUtilizationPercent",
2708168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
270937bbf98cSChris Cain         }
271037bbf98cSChris Cain         if (ipsEnterTime)
271137bbf98cSChris Cain         {
271237bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
271337bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
271437bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27155e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27168a592810SEd Tanous                 if (ec2)
271737bbf98cSChris Cain                 {
27188a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
271937bbf98cSChris Cain                     messages::internalError(aResp->res);
272037bbf98cSChris Cain                     return;
272137bbf98cSChris Cain                 }
272237bbf98cSChris Cain                 },
272337bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
272437bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2725168e20c1SEd Tanous                 "EnterDwellTime",
2726168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
272737bbf98cSChris Cain         }
272837bbf98cSChris Cain         if (ipsExitUtil)
272937bbf98cSChris Cain         {
273037bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27315e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27328a592810SEd Tanous                 if (ec2)
273337bbf98cSChris Cain                 {
27348a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
273537bbf98cSChris Cain                     messages::internalError(aResp->res);
273637bbf98cSChris Cain                     return;
273737bbf98cSChris Cain                 }
273837bbf98cSChris Cain                 },
273937bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
274037bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
274137bbf98cSChris Cain                 "ExitUtilizationPercent",
2742168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
274337bbf98cSChris Cain         }
274437bbf98cSChris Cain         if (ipsExitTime)
274537bbf98cSChris Cain         {
274637bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
274737bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
274837bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27495e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27508a592810SEd Tanous                 if (ec2)
275137bbf98cSChris Cain                 {
27528a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
275337bbf98cSChris Cain                     messages::internalError(aResp->res);
275437bbf98cSChris Cain                     return;
275537bbf98cSChris Cain                 }
275637bbf98cSChris Cain                 },
275737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
275837bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2759168e20c1SEd Tanous                 "ExitDwellTime",
2760168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
276137bbf98cSChris Cain         }
2762e99073f5SGeorge Liu         });
276337bbf98cSChris Cain 
276437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
276537bbf98cSChris Cain }
276637bbf98cSChris Cain 
2767dd60b9edSEd Tanous inline void handleComputerSystemHead(
2768dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2769dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2770dd60b9edSEd Tanous {
2771dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2772dd60b9edSEd Tanous     {
2773dd60b9edSEd Tanous         return;
2774dd60b9edSEd Tanous     }
2775dd60b9edSEd Tanous     asyncResp->res.addHeader(
2776dd60b9edSEd Tanous         boost::beast::http::field::link,
2777dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2778dd60b9edSEd Tanous }
2779dd60b9edSEd Tanous 
2780c45f0082SYong Li /**
2781c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2782c5b2abe0SLewanczyk, Dawid  * Schema
2783c5b2abe0SLewanczyk, Dawid  */
27847e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
27851abe55efSEd Tanous {
27867e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2787dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2788dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2789dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2790dd60b9edSEd Tanous 
2791dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2792ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
27937e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2794f4c99e70SEd Tanous             [&app](const crow::Request& req,
27957e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27963ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2797f4c99e70SEd Tanous         {
2798f4c99e70SEd Tanous             return;
2799f4c99e70SEd Tanous         }
2800dd60b9edSEd Tanous 
2801dd60b9edSEd Tanous         asyncResp->res.addHeader(
2802dd60b9edSEd Tanous             boost::beast::http::field::link,
2803dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
28048d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
28050f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
28068d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28078d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2808462023adSSunitha Harish 
28091e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2810002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
28111e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2812002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
28135e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
28141e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2815002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
28162c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2817002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
28181476687dSEd Tanous 
28191476687dSEd Tanous             nlohmann::json::object_t system;
28201476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
2821b2ba3072SPatrick Williams             ifaceArray.emplace_back(std::move(system));
282294bda602STim Lee             count = ifaceArray.size();
28238a592810SEd Tanous             if (!ec2)
2824462023adSSunitha Harish             {
2825462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
28261476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2827002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2828b2ba3072SPatrick Williams                 ifaceArray.emplace_back(std::move(hypervisor));
28292c70f800SEd Tanous                 count = ifaceArray.size();
2830cb13a392SEd Tanous             }
28311e1e598dSJonathan Doman             });
28327e860f15SJohn Edward Broadbent         });
2833c5b2abe0SLewanczyk, Dawid }
28347e860f15SJohn Edward Broadbent 
28357e860f15SJohn Edward Broadbent /**
28367e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28377e860f15SJohn Edward Broadbent  */
28384f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28397e860f15SJohn Edward Broadbent {
284089492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
284189492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
284289492a15SPatrick Williams     constexpr const char* interfaceName =
28437e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
284489492a15SPatrick Williams     constexpr const char* method = "NMI";
28457e860f15SJohn Edward Broadbent 
28467e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28475e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28487e860f15SJohn Edward Broadbent         if (ec)
28497e860f15SJohn Edward Broadbent         {
28507e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28517e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28527e860f15SJohn Edward Broadbent             return;
28537e860f15SJohn Edward Broadbent         }
28547e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28557e860f15SJohn Edward Broadbent         },
28567e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28577e860f15SJohn Edward Broadbent }
2858c5b2abe0SLewanczyk, Dawid 
2859c5b2abe0SLewanczyk, Dawid /**
2860*fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
2861*fc903b3dSAndrew Geissler  */
2862*fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
2863*fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
2864*fc903b3dSAndrew Geissler                                          std::string_view resetType,
2865*fc903b3dSAndrew Geissler                                          crow::Response& res)
2866*fc903b3dSAndrew Geissler {
2867*fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
2868*fc903b3dSAndrew Geissler     {
2869*fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
2870*fc903b3dSAndrew Geissler         return;
2871*fc903b3dSAndrew Geissler     }
2872*fc903b3dSAndrew Geissler 
2873*fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
2874*fc903b3dSAndrew Geissler     {
2875*fc903b3dSAndrew Geissler         BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2876*fc903b3dSAndrew Geissler         messages::internalError(res);
2877*fc903b3dSAndrew Geissler         return;
2878*fc903b3dSAndrew Geissler     }
2879*fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
2880*fc903b3dSAndrew Geissler 
2881*fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
2882*fc903b3dSAndrew Geissler     // user to retry in a bit
2883*fc903b3dSAndrew Geissler     if ((errorMessage ==
2884*fc903b3dSAndrew Geissler          std::string_view(
2885*fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2886*fc903b3dSAndrew Geissler         (errorMessage ==
2887*fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2888*fc903b3dSAndrew Geissler     {
2889*fc903b3dSAndrew Geissler         BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2890*fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
2891*fc903b3dSAndrew Geissler         return;
2892*fc903b3dSAndrew Geissler     }
2893*fc903b3dSAndrew Geissler 
2894*fc903b3dSAndrew Geissler     BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2895*fc903b3dSAndrew Geissler                      << " sdbusplus:" << errorMessage;
2896*fc903b3dSAndrew Geissler     messages::internalError(res);
2897*fc903b3dSAndrew Geissler }
2898*fc903b3dSAndrew Geissler 
2899*fc903b3dSAndrew Geissler /**
2900cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2901cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2902cc340dd9SEd Tanous  */
29037e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2904cc340dd9SEd Tanous {
2905cc340dd9SEd Tanous     /**
2906cc340dd9SEd Tanous      * Function handles POST method request.
2907cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2908cc340dd9SEd Tanous      */
29097e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
29107e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2911ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2912002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2913002d39b4SEd Tanous             [&app](const crow::Request& req,
29147e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
29153ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
291645ca1b86SEd Tanous         {
291745ca1b86SEd Tanous             return;
291845ca1b86SEd Tanous         }
29199712f8acSEd Tanous         std::string resetType;
292015ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
29217e860f15SJohn Edward Broadbent                                        resetType))
2922cc340dd9SEd Tanous         {
2923cc340dd9SEd Tanous             return;
2924cc340dd9SEd Tanous         }
2925cc340dd9SEd Tanous 
2926d22c8396SJason M. Bills         // Get the command and host vs. chassis
2927cc340dd9SEd Tanous         std::string command;
2928543f4400SEd Tanous         bool hostCommand = true;
2929d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2930cc340dd9SEd Tanous         {
2931cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2932d22c8396SJason M. Bills             hostCommand = true;
2933d22c8396SJason M. Bills         }
2934d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2935d22c8396SJason M. Bills         {
2936d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2937d22c8396SJason M. Bills             hostCommand = false;
2938d22c8396SJason M. Bills         }
2939d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2940d22c8396SJason M. Bills         {
294186a0851aSJason M. Bills             command =
294286a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
294386a0851aSJason M. Bills             hostCommand = true;
2944cc340dd9SEd Tanous         }
29459712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2946cc340dd9SEd Tanous         {
2947cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2948d22c8396SJason M. Bills             hostCommand = true;
2949cc340dd9SEd Tanous         }
29509712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2951cc340dd9SEd Tanous         {
29520fda0f12SGeorge Liu             command =
29530fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2954d22c8396SJason M. Bills             hostCommand = true;
2955d22c8396SJason M. Bills         }
2956d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2957d22c8396SJason M. Bills         {
295886a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
295986a0851aSJason M. Bills             hostCommand = true;
2960cc340dd9SEd Tanous         }
2961bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2962bfd5b826SLakshminarayana R. Kammath         {
2963bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2964bfd5b826SLakshminarayana R. Kammath             return;
2965bfd5b826SLakshminarayana R. Kammath         }
2966cc340dd9SEd Tanous         else
2967cc340dd9SEd Tanous         {
29688d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
29698d1b46d7Szhanghch05                                              resetType);
2970cc340dd9SEd Tanous             return;
2971cc340dd9SEd Tanous         }
2972cc340dd9SEd Tanous 
2973d22c8396SJason M. Bills         if (hostCommand)
2974d22c8396SJason M. Bills         {
2975cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
2976*fc903b3dSAndrew Geissler                 [asyncResp, resetType](const boost::system::error_code& ec,
2977*fc903b3dSAndrew Geissler                                        sdbusplus::message_t& sdbusErrMsg) {
2978cc340dd9SEd Tanous                 if (ec)
2979cc340dd9SEd Tanous                 {
2980*fc903b3dSAndrew Geissler                     handleSystemActionResetError(ec, sdbusErrMsg, resetType,
2981*fc903b3dSAndrew Geissler                                                  asyncResp->res);
2982*fc903b3dSAndrew Geissler 
2983cc340dd9SEd Tanous                     return;
2984cc340dd9SEd Tanous                 }
2985f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2986cc340dd9SEd Tanous                 },
2987cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2988cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2989cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
29909712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2991168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2992cc340dd9SEd Tanous         }
2993d22c8396SJason M. Bills         else
2994d22c8396SJason M. Bills         {
2995d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
2996*fc903b3dSAndrew Geissler                 [asyncResp, resetType](const boost::system::error_code& ec,
2997*fc903b3dSAndrew Geissler                                        sdbusplus::message_t& sdbusErrMsg) {
2998d22c8396SJason M. Bills                 if (ec)
2999d22c8396SJason M. Bills                 {
3000*fc903b3dSAndrew Geissler                     handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3001*fc903b3dSAndrew Geissler                                                  asyncResp->res);
3002d22c8396SJason M. Bills                     return;
3003d22c8396SJason M. Bills                 }
3004d22c8396SJason M. Bills                 messages::success(asyncResp->res);
3005d22c8396SJason M. Bills                 },
3006d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
3007d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
3008d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
3009002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3010168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
3011d22c8396SJason M. Bills         }
30127e860f15SJohn Edward Broadbent         });
3013d22c8396SJason M. Bills }
3014cc340dd9SEd Tanous 
301538c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
3016dd60b9edSEd Tanous     App& app, const crow::Request& req,
3017dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3018dd60b9edSEd Tanous {
3019dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3020dd60b9edSEd Tanous     {
3021dd60b9edSEd Tanous         return;
3022dd60b9edSEd Tanous     }
3023dd60b9edSEd Tanous 
3024dd60b9edSEd Tanous     asyncResp->res.addHeader(
3025dd60b9edSEd Tanous         boost::beast::http::field::link,
3026dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3027dd60b9edSEd Tanous }
3028dd60b9edSEd Tanous 
30295c3e9272SAbhishek Patel inline void afterPortRequest(
30305c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30315c3e9272SAbhishek Patel     const boost::system::error_code& ec,
30325c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
30335c3e9272SAbhishek Patel {
30345c3e9272SAbhishek Patel     if (ec)
30355c3e9272SAbhishek Patel     {
30365c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
30375c3e9272SAbhishek Patel         return;
30385c3e9272SAbhishek Patel     }
30395c3e9272SAbhishek Patel     for (const auto& data : socketData)
30405c3e9272SAbhishek Patel     {
30415c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
30425c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
30435c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
30445c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
30455c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
30465c3e9272SAbhishek Patel         // need to retrieve port number for
30475c3e9272SAbhishek Patel         // obmc-console-ssh service
30485c3e9272SAbhishek Patel         if (protocolName == "SSH")
30495c3e9272SAbhishek Patel         {
30505c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
305181c4e330SEd Tanous                                           const boost::system::error_code& ec1,
30525c3e9272SAbhishek Patel                                           int portNumber) {
30535c3e9272SAbhishek Patel                 if (ec1)
30545c3e9272SAbhishek Patel                 {
30555c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30565c3e9272SAbhishek Patel                     return;
30575c3e9272SAbhishek Patel                 }
30585c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30595c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30605c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30615c3e9272SAbhishek Patel             });
30625c3e9272SAbhishek Patel         }
30635c3e9272SAbhishek Patel     }
30645c3e9272SAbhishek Patel }
3065cc340dd9SEd Tanous /**
30666617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
3067c5b2abe0SLewanczyk, Dawid  */
30687e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
30691abe55efSEd Tanous {
3070dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3071dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3072dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
3073dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3074c5b2abe0SLewanczyk, Dawid     /**
3075c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3076c5b2abe0SLewanczyk, Dawid      */
307722d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3078ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3079002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
3080002d39b4SEd Tanous             [&app](const crow::Request& req,
308122d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
308222d268cbSEd Tanous                    const std::string& systemName) {
30833ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
308445ca1b86SEd Tanous         {
308545ca1b86SEd Tanous             return;
308645ca1b86SEd Tanous         }
3087746b56f3SAsmitha Karunanithi 
3088746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3089746b56f3SAsmitha Karunanithi         {
3090746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3091746b56f3SAsmitha Karunanithi             return;
3092746b56f3SAsmitha Karunanithi         }
3093746b56f3SAsmitha Karunanithi 
309422d268cbSEd Tanous         if (systemName != "system")
309522d268cbSEd Tanous         {
309622d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
309722d268cbSEd Tanous                                        systemName);
309822d268cbSEd Tanous             return;
309922d268cbSEd Tanous         }
3100dd60b9edSEd Tanous         asyncResp->res.addHeader(
3101dd60b9edSEd Tanous             boost::beast::http::field::link,
3102dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
31038d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
310437bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
31058d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
31068d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
31078d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
31088d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
31098d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
31105fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
31115fd0aafbSNinad Palsule         {
31128d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
31138d1b46d7Szhanghch05                 "Disabled";
31148d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
31158d1b46d7Szhanghch05                 "Disabled";
31165fd0aafbSNinad Palsule         }
3117cf0e004cSNinad Palsule         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3118cf0e004cSNinad Palsule             uint64_t(0);
3119002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
312004a258f4SEd Tanous 
31211476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
31221476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
31231476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
31241476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
31251476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
31261476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
31273179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
31283179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
3129029573d4SEd Tanous 
3130002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
31311476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
31321476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
31331476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
31341476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
3135c5b2abe0SLewanczyk, Dawid 
31361476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
31371476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
31381476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
31391476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
3140c4bf6374SJason M. Bills 
31411476687dSEd Tanous         nlohmann::json::array_t managedBy;
31421476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
31431476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3144002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
31451476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
31461476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
31470e8ac5e7SGunnar Mills 
31480e8ac5e7SGunnar Mills         // Fill in SerialConsole info
3149002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3150002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3151002d39b4SEd Tanous             true;
31521476687dSEd Tanous 
31531476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
31541476687dSEd Tanous             true;
31551476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
31561476687dSEd Tanous         asyncResp->res
31571476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31581476687dSEd Tanous             "Press ~. to exit console";
31595c3e9272SAbhishek Patel         getPortStatusAndPath(std::span{protocolToDBusForSystems},
31605c3e9272SAbhishek Patel                              std::bind_front(afterPortRequest, asyncResp));
31610e8ac5e7SGunnar Mills 
31620e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
31630e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3164002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3165002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3166002d39b4SEd Tanous             4;
3167613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3168613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
31691476687dSEd Tanous 
31700e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
317113451e39SWilly Tu 
317213451e39SWilly Tu         auto health = std::make_shared<HealthPopulate>(asyncResp);
317313451e39SWilly Tu         if constexpr (bmcwebEnableHealthPopulate)
317413451e39SWilly Tu         {
31757a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 4> inventoryForSystems{
3176b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
31772ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
3178e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
3179e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
3180b49ac873SJames Feist 
31817a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
31827a1dbc48SGeorge Liu                 "/", 0, inventoryForSystems,
31837a1dbc48SGeorge Liu                 [health](const boost::system::error_code& ec,
3184914e2d5dSEd Tanous                          const std::vector<std::string>& resp) {
3185b49ac873SJames Feist                 if (ec)
3186b49ac873SJames Feist                 {
3187b49ac873SJames Feist                     // no inventory
3188b49ac873SJames Feist                     return;
3189b49ac873SJames Feist                 }
3190b49ac873SJames Feist 
3191914e2d5dSEd Tanous                 health->inventory = resp;
31927a1dbc48SGeorge Liu                 });
3193b49ac873SJames Feist             health->populate();
319413451e39SWilly Tu         }
3195b49ac873SJames Feist 
3196002d39b4SEd Tanous         getMainChassisId(asyncResp,
3197002d39b4SEd Tanous                          [](const std::string& chassisId,
31988d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3199b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3200b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3201ef4c65b7SEd Tanous             chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3202ef4c65b7SEd Tanous                                                        chassisId);
3203002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3204c5d03ff4SJennifer Lee         });
3205a3002228SAppaRao Puli 
32069f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
32079f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3208a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
32095bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
32106c34de48SEd Tanous         getHostState(asyncResp);
3211491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3212978b8803SAndrew Geissler         getBootProgress(asyncResp);
3213b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3214472bd202SLakshmi Yadlapati         pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
321551709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3216c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
3217797d5daeSCorey Hardesty         getAutomaticRetryPolicy(asyncResp);
3218c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3219a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3220a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3221a6349918SAppaRao Puli #endif
32221981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
32233a2d0424SChris Cain         getPowerMode(asyncResp);
322437bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
32257e860f15SJohn Edward Broadbent         });
3226550a6bf8SJiaqing Zhao 
322722d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3228ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
32297e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
323045ca1b86SEd Tanous             [&app](const crow::Request& req,
323122d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
323222d268cbSEd Tanous                    const std::string& systemName) {
32333ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
323445ca1b86SEd Tanous         {
323545ca1b86SEd Tanous             return;
323645ca1b86SEd Tanous         }
323722d268cbSEd Tanous         if (systemName != "system")
323822d268cbSEd Tanous         {
323922d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
324022d268cbSEd Tanous                                        systemName);
324122d268cbSEd Tanous             return;
324222d268cbSEd Tanous         }
324322d268cbSEd Tanous 
3244dd60b9edSEd Tanous         asyncResp->res.addHeader(
3245dd60b9edSEd Tanous             boost::beast::http::field::link,
3246dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3247dd60b9edSEd Tanous 
32489f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3249cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
325098e386ecSGunnar Mills         std::optional<std::string> assetTag;
3251c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
32523a2d0424SChris Cain         std::optional<std::string> powerMode;
3253550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3254550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3255550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3256550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3257550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3258550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3259797d5daeSCorey Hardesty         std::optional<uint32_t> bootAutomaticRetryAttempts;
3260550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3261550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3262550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3263550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3264550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3265550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3266550a6bf8SJiaqing Zhao 
3267550a6bf8SJiaqing Zhao         // clang-format off
326815ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3269550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3270550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
32717e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3272550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3273550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3274550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3275550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3276550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3277550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3278550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3279550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3280550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3281797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3282550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3283550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3284550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3285550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3286550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3287550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
32886617338dSEd Tanous                 {
32896617338dSEd Tanous                     return;
32906617338dSEd Tanous                 }
3291550a6bf8SJiaqing Zhao         // clang-format on
3292491d8ee7SSantosh Puranik 
32938d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3294c45f0082SYong Li 
329598e386ecSGunnar Mills         if (assetTag)
329698e386ecSGunnar Mills         {
329798e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
329898e386ecSGunnar Mills         }
329998e386ecSGunnar Mills 
3300550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3301c45f0082SYong Li         {
3302f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3303c45f0082SYong Li         }
3304c45f0082SYong Li 
3305cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
330669f35306SGunnar Mills         {
3307002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3308491d8ee7SSantosh Puranik         }
3309550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
331069f35306SGunnar Mills         {
3311550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
331269f35306SGunnar Mills         }
3313ac7e1e0bSAli Ahmed 
3314797d5daeSCorey Hardesty         if (bootAutomaticRetryAttempts)
3315797d5daeSCorey Hardesty         {
3316797d5daeSCorey Hardesty             setAutomaticRetryAttempts(asyncResp,
3317797d5daeSCorey Hardesty                                       bootAutomaticRetryAttempts.value());
3318797d5daeSCorey Hardesty         }
3319797d5daeSCorey Hardesty 
3320550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3321ac7e1e0bSAli Ahmed         {
3322550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3323550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
332469f35306SGunnar Mills         }
3325265c1602SJohnathan Mantey 
33269f8bfa7cSGunnar Mills         if (locationIndicatorActive)
33279f8bfa7cSGunnar Mills         {
3328002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
33299f8bfa7cSGunnar Mills         }
33309f8bfa7cSGunnar Mills 
33317e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
33327e860f15SJohn Edward Broadbent         // passed
33339712f8acSEd Tanous         if (indicatorLed)
33346617338dSEd Tanous         {
3335f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3336002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3337d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3338d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
33396617338dSEd Tanous         }
3340c6a620f2SGeorge Liu 
3341c6a620f2SGeorge Liu         if (powerRestorePolicy)
3342c6a620f2SGeorge Liu         {
33434e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3344c6a620f2SGeorge Liu         }
33453a2d0424SChris Cain 
33463a2d0424SChris Cain         if (powerMode)
33473a2d0424SChris Cain         {
33483a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
33493a2d0424SChris Cain         }
335037bbf98cSChris Cain 
3351550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3352550a6bf8SJiaqing Zhao             ipsExitTime)
335337bbf98cSChris Cain         {
3354002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3355002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
335637bbf98cSChris Cain         }
33577e860f15SJohn Edward Broadbent         });
3358c5b2abe0SLewanczyk, Dawid }
33591cb1a9e6SAppaRao Puli 
336038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3361dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3362dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3363dd60b9edSEd Tanous {
3364dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3365dd60b9edSEd Tanous     {
3366dd60b9edSEd Tanous         return;
3367dd60b9edSEd Tanous     }
3368dd60b9edSEd Tanous     asyncResp->res.addHeader(
3369dd60b9edSEd Tanous         boost::beast::http::field::link,
3370dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3371dd60b9edSEd Tanous }
3372dd60b9edSEd Tanous 
33731cb1a9e6SAppaRao Puli /**
33741cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
33751cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
33761cb1a9e6SAppaRao Puli  */
33777e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
33781cb1a9e6SAppaRao Puli {
3379dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3380dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3381dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3382dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
33831cb1a9e6SAppaRao Puli     /**
33841cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
33851cb1a9e6SAppaRao Puli      */
338622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3387ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
33887e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
338945ca1b86SEd Tanous             [&app](const crow::Request& req,
339022d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
339122d268cbSEd Tanous                    const std::string& systemName) {
33923ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
339345ca1b86SEd Tanous         {
339445ca1b86SEd Tanous             return;
339545ca1b86SEd Tanous         }
3396746b56f3SAsmitha Karunanithi 
3397746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3398746b56f3SAsmitha Karunanithi         {
3399746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3400746b56f3SAsmitha Karunanithi             return;
3401746b56f3SAsmitha Karunanithi         }
3402746b56f3SAsmitha Karunanithi 
340322d268cbSEd Tanous         if (systemName != "system")
340422d268cbSEd Tanous         {
340522d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
340622d268cbSEd Tanous                                        systemName);
340722d268cbSEd Tanous             return;
340822d268cbSEd Tanous         }
340922d268cbSEd Tanous 
3410dd60b9edSEd Tanous         asyncResp->res.addHeader(
3411dd60b9edSEd Tanous             boost::beast::http::field::link,
3412dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
34131476687dSEd Tanous 
34141476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
34151476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
34161476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
34171476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
34181476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34191476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34203215e700SNan Zhou 
34213215e700SNan Zhou         nlohmann::json::array_t parameters;
34223215e700SNan Zhou         nlohmann::json::object_t parameter;
34233215e700SNan Zhou 
34243215e700SNan Zhou         parameter["Name"] = "ResetType";
34253215e700SNan Zhou         parameter["Required"] = true;
34263215e700SNan Zhou         parameter["DataType"] = "String";
34273215e700SNan Zhou         nlohmann::json::array_t allowableValues;
34283215e700SNan Zhou         allowableValues.emplace_back("On");
34293215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
34303215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
34313215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
34323215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
34333215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
34343215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
34353215e700SNan Zhou         allowableValues.emplace_back("Nmi");
34363215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
34373215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
34383215e700SNan Zhou 
34393215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
34407e860f15SJohn Edward Broadbent         });
34411cb1a9e6SAppaRao Puli }
3442c5b2abe0SLewanczyk, Dawid } // namespace redfish
3443