xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 13451e3913c29bb380ef6778f11749d337ddd442)
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 
18*13451e39SWilly Tu #include "bmcweb_config.h"
19*13451e39SWilly 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"
26f5c9f8bdSJason M. Bills #include "pcie.hpp"
27f4c99e70SEd Tanous #include "query.hpp"
28c5d03ff4SJennifer Lee #include "redfish_util.hpp"
293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
313ccb3adbSEd Tanous #include "utils/json_utils.hpp"
323ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
332b82937eSEd Tanous #include "utils/time_utils.hpp"
34c5d03ff4SJennifer Lee 
359712f8acSEd Tanous #include <boost/container/flat_map.hpp>
36e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
37ef4c65b7SEd Tanous #include <boost/url/format.hpp>
381e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
39bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
401214b7e7SGunnar Mills 
417a1dbc48SGeorge Liu #include <array>
427a1dbc48SGeorge Liu #include <string_view>
43abf2add6SEd Tanous #include <variant>
44c5b2abe0SLewanczyk, Dawid 
451abe55efSEd Tanous namespace redfish
461abe55efSEd Tanous {
47c5b2abe0SLewanczyk, Dawid 
485c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
495c3e9272SAbhishek Patel     protocolToDBusForSystems{
505c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
515c3e9272SAbhishek Patel 
529d3ae10eSAlpana Kumari /**
539d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
549d3ae10eSAlpana Kumari  *
559d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
569d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
579d3ae10eSAlpana Kumari  *
589d3ae10eSAlpana Kumari  * @return None.
599d3ae10eSAlpana Kumari  */
608d1b46d7Szhanghch05 inline void
618d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
621e1e598dSJonathan Doman                          bool isDimmFunctional)
639d3ae10eSAlpana Kumari {
641e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
659d3ae10eSAlpana Kumari 
669d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
679d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
689d3ae10eSAlpana Kumari     // ENABLED.
6902cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
709d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
719d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
729d3ae10eSAlpana Kumari     {
73e05aec50SEd Tanous         if (isDimmFunctional)
749d3ae10eSAlpana Kumari         {
759d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
769d3ae10eSAlpana Kumari                 "Enabled";
779d3ae10eSAlpana Kumari         }
789d3ae10eSAlpana Kumari     }
799d3ae10eSAlpana Kumari }
809d3ae10eSAlpana Kumari 
8157e8c9beSAlpana Kumari /*
8257e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8357e8c9beSAlpana Kumari  *        CPU Functional State
8457e8c9beSAlpana Kumari  *
8557e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
8657e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
8757e8c9beSAlpana Kumari  *
8857e8c9beSAlpana Kumari  * @return None.
8957e8c9beSAlpana Kumari  */
901e1e598dSJonathan Doman inline void
911e1e598dSJonathan Doman     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
921e1e598dSJonathan Doman                              bool isCpuFunctional)
9357e8c9beSAlpana Kumari {
941e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
9557e8c9beSAlpana Kumari 
9602cad96eSEd Tanous     const nlohmann::json& prevProcState =
9757e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
9857e8c9beSAlpana Kumari 
9957e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10057e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10157e8c9beSAlpana Kumari     // Functional.
10257e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10357e8c9beSAlpana Kumari     {
104e05aec50SEd Tanous         if (isCpuFunctional)
10557e8c9beSAlpana Kumari         {
10657e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10757e8c9beSAlpana Kumari                 "Enabled";
10857e8c9beSAlpana Kumari         }
10957e8c9beSAlpana Kumari     }
11057e8c9beSAlpana Kumari }
11157e8c9beSAlpana Kumari 
112cf0e004cSNinad Palsule /*
113cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
114cf0e004cSNinad Palsule  *
115cf0e004cSNinad Palsule  * @param[in] aResp Shared pointer for completing asynchronous calls
116cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
117cf0e004cSNinad Palsule  *
118cf0e004cSNinad Palsule  * @return None.
119cf0e004cSNinad Palsule  */
120cf0e004cSNinad Palsule inline void
121cf0e004cSNinad Palsule     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
122cf0e004cSNinad Palsule                            bool isCpuPresent)
123cf0e004cSNinad Palsule {
124cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
125cf0e004cSNinad Palsule 
126cf0e004cSNinad Palsule     if (isCpuPresent)
127cf0e004cSNinad Palsule     {
128cf0e004cSNinad Palsule         nlohmann::json& procCount =
129cf0e004cSNinad Palsule             aResp->res.jsonValue["ProcessorSummary"]["Count"];
130cf0e004cSNinad Palsule         auto* procCountPtr =
131cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
132cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
133cf0e004cSNinad Palsule         {
134cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
135cf0e004cSNinad Palsule             *procCountPtr += 1;
136cf0e004cSNinad Palsule         }
137cf0e004cSNinad Palsule     }
138cf0e004cSNinad Palsule }
139cf0e004cSNinad Palsule 
140382d6475SAli Ahmed inline void getProcessorProperties(
141382d6475SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
142382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
143382d6475SAli Ahmed         properties)
14403fbed92SAli Ahmed {
14503fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14603fbed92SAli Ahmed 
14703fbed92SAli Ahmed     // TODO: Get Model
14803fbed92SAli Ahmed 
149bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15003fbed92SAli Ahmed 
151bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
152bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15303fbed92SAli Ahmed 
154bc1d29deSKrzysztof Grobelny     if (!success)
15503fbed92SAli Ahmed     {
15603fbed92SAli Ahmed         messages::internalError(aResp->res);
15703fbed92SAli Ahmed         return;
15803fbed92SAli Ahmed     }
15903fbed92SAli Ahmed 
160bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16103fbed92SAli Ahmed     {
162bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
163bc1d29deSKrzysztof Grobelny             aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
164bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
165bc1d29deSKrzysztof Grobelny 
166bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
167bc1d29deSKrzysztof Grobelny         {
168bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
16903fbed92SAli Ahmed         }
17003fbed92SAli Ahmed         else
17103fbed92SAli Ahmed         {
172bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17303fbed92SAli Ahmed         }
17403fbed92SAli Ahmed     }
17503fbed92SAli Ahmed }
17603fbed92SAli Ahmed 
17703fbed92SAli Ahmed /*
17803fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
17903fbed92SAli Ahmed  *
18003fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
18103fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18203fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18303fbed92SAli Ahmed  *
18403fbed92SAli Ahmed  * @return None.
18503fbed92SAli Ahmed  */
18603fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18703fbed92SAli Ahmed                                 const std::string& service,
18803fbed92SAli Ahmed                                 const std::string& path)
18903fbed92SAli Ahmed {
1905e7e2dc5SEd Tanous     auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
191382d6475SAli Ahmed                                        const bool cpuPresenceCheck) {
192382d6475SAli Ahmed         if (ec3)
193382d6475SAli Ahmed         {
194382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
195382d6475SAli Ahmed             return;
196382d6475SAli Ahmed         }
197382d6475SAli Ahmed         modifyCpuPresenceState(aResp, cpuPresenceCheck);
198382d6475SAli Ahmed     };
199382d6475SAli Ahmed 
200cf0e004cSNinad Palsule     // Get the Presence of CPU
201cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
202cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
203cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
204cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
205cf0e004cSNinad Palsule 
2065e7e2dc5SEd Tanous     auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
207382d6475SAli Ahmed                                          const bool cpuFunctionalCheck) {
208382d6475SAli Ahmed         if (ec3)
209382d6475SAli Ahmed         {
210382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
211382d6475SAli Ahmed             return;
212382d6475SAli Ahmed         }
213382d6475SAli Ahmed         modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
214382d6475SAli Ahmed     };
215382d6475SAli Ahmed 
216382d6475SAli Ahmed     // Get the Functional State
217382d6475SAli Ahmed     sdbusplus::asio::getProperty<bool>(
218382d6475SAli Ahmed         *crow::connections::systemBus, service, path,
219382d6475SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
220382d6475SAli Ahmed         std::move(getCpuFunctionalState));
221382d6475SAli Ahmed 
222bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
223bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
224bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
22503fbed92SAli Ahmed         [aResp, service,
2265e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
227b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
22803fbed92SAli Ahmed         if (ec2)
22903fbed92SAli Ahmed         {
23003fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
23103fbed92SAli Ahmed             messages::internalError(aResp->res);
23203fbed92SAli Ahmed             return;
23303fbed92SAli Ahmed         }
234382d6475SAli Ahmed         getProcessorProperties(aResp, properties);
235bc1d29deSKrzysztof Grobelny         });
23603fbed92SAli Ahmed }
23703fbed92SAli Ahmed 
23857e8c9beSAlpana Kumari /*
239cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
240cf0e004cSNinad Palsule  *
241cf0e004cSNinad Palsule  * @param[in] aResp Shared pointer for completing asynchronous calls
242cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
243cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
244cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
245cf0e004cSNinad Palsule  *
246cf0e004cSNinad Palsule  * @return None.
247cf0e004cSNinad Palsule  */
248cf0e004cSNinad Palsule inline void
249cf0e004cSNinad Palsule     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
250cf0e004cSNinad Palsule                             const std::string& service, const std::string& path,
251cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
252cf0e004cSNinad Palsule {
253cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
254cf0e004cSNinad Palsule 
255cf0e004cSNinad Palsule     if (properties.empty())
256cf0e004cSNinad Palsule     {
257cf0e004cSNinad Palsule         sdbusplus::asio::getProperty<bool>(
258cf0e004cSNinad Palsule             *crow::connections::systemBus, service, path,
259cf0e004cSNinad Palsule             "xyz.openbmc_project.State."
260cf0e004cSNinad Palsule             "Decorator.OperationalStatus",
261cf0e004cSNinad Palsule             "Functional",
262cf0e004cSNinad Palsule             [aResp](const boost::system::error_code& ec3, bool dimmState) {
263cf0e004cSNinad Palsule             if (ec3)
264cf0e004cSNinad Palsule             {
265cf0e004cSNinad Palsule                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
266cf0e004cSNinad Palsule                 return;
267cf0e004cSNinad Palsule             }
268cf0e004cSNinad Palsule             updateDimmProperties(aResp, dimmState);
269cf0e004cSNinad Palsule             });
270cf0e004cSNinad Palsule         return;
271cf0e004cSNinad Palsule     }
272cf0e004cSNinad Palsule 
273cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
274cf0e004cSNinad Palsule 
275cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
276cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
277cf0e004cSNinad Palsule         memorySizeInKB);
278cf0e004cSNinad Palsule 
279cf0e004cSNinad Palsule     if (!success)
280cf0e004cSNinad Palsule     {
281cf0e004cSNinad Palsule         messages::internalError(aResp->res);
282cf0e004cSNinad Palsule         return;
283cf0e004cSNinad Palsule     }
284cf0e004cSNinad Palsule 
285cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
286cf0e004cSNinad Palsule     {
287cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
288cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
289cf0e004cSNinad Palsule         const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
290cf0e004cSNinad Palsule         if (preValue == nullptr)
291cf0e004cSNinad Palsule         {
292cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
293cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
294cf0e004cSNinad Palsule         }
295cf0e004cSNinad Palsule         else
296cf0e004cSNinad Palsule         {
297cf0e004cSNinad Palsule             aResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
298cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
299cf0e004cSNinad Palsule         }
300cf0e004cSNinad Palsule         aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = "Enabled";
301cf0e004cSNinad Palsule     }
302cf0e004cSNinad Palsule }
303cf0e004cSNinad Palsule 
304cf0e004cSNinad Palsule /*
305cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
306cf0e004cSNinad Palsule  *
307cf0e004cSNinad Palsule  * @param[in] aResp Shared pointer for completing asynchronous calls
308cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
309cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
310cf0e004cSNinad Palsule  *
311cf0e004cSNinad Palsule  * @return None.
312cf0e004cSNinad Palsule  */
313cf0e004cSNinad Palsule inline void getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
314cf0e004cSNinad Palsule                              const std::string& service,
315cf0e004cSNinad Palsule                              const std::string& path)
316cf0e004cSNinad Palsule {
317cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
318cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
319cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
320cf0e004cSNinad Palsule         [aResp, service,
321cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
322cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
323cf0e004cSNinad Palsule         if (ec2)
324cf0e004cSNinad Palsule         {
325cf0e004cSNinad Palsule             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
326cf0e004cSNinad Palsule             messages::internalError(aResp->res);
327cf0e004cSNinad Palsule             return;
328cf0e004cSNinad Palsule         }
329cf0e004cSNinad Palsule         processMemoryProperties(aResp, service, path, properties);
330cf0e004cSNinad Palsule         });
331cf0e004cSNinad Palsule }
332cf0e004cSNinad Palsule 
333cf0e004cSNinad Palsule /*
334c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
335c5b2abe0SLewanczyk, Dawid  *
336c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
3378f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
338c5b2abe0SLewanczyk, Dawid  *
339c5b2abe0SLewanczyk, Dawid  * @return None.
340c5b2abe0SLewanczyk, Dawid  */
341b5a76932SEd Tanous inline void
3428d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
343b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
3441abe55efSEd Tanous {
34555c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
346e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
347e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
348e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
349e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
350e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
351e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
352e99073f5SGeorge Liu     };
353e99073f5SGeorge Liu     dbus::utility::getSubTree(
354e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
355b9d36b47SEd Tanous         [aResp,
356e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
357b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
3581abe55efSEd Tanous         if (ec)
3591abe55efSEd Tanous         {
36055c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
361f12894f8SJason M. Bills             messages::internalError(aResp->res);
362c5b2abe0SLewanczyk, Dawid             return;
363c5b2abe0SLewanczyk, Dawid         }
364c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
365002d39b4SEd Tanous         for (const std::pair<
366002d39b4SEd Tanous                  std::string,
367002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
3681214b7e7SGunnar Mills                  object : subtree)
3691abe55efSEd Tanous         {
370c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
37155c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
372002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
3731214b7e7SGunnar Mills                 connectionNames = object.second;
37426f6976fSEd Tanous             if (connectionNames.empty())
3751abe55efSEd Tanous             {
376c5b2abe0SLewanczyk, Dawid                 continue;
377c5b2abe0SLewanczyk, Dawid             }
378029573d4SEd Tanous 
3795bc2dc8eSJames Feist             auto memoryHealth = std::make_shared<HealthPopulate>(
380dfababfcSNan Zhou                 aResp, "/MemorySummary/Status"_json_pointer);
3815bc2dc8eSJames Feist 
3825bc2dc8eSJames Feist             auto cpuHealth = std::make_shared<HealthPopulate>(
383dfababfcSNan Zhou                 aResp, "/ProcessorSummary/Status"_json_pointer);
3845bc2dc8eSJames Feist 
385*13451e39SWilly Tu             if constexpr (bmcwebEnableHealthPopulate)
386*13451e39SWilly Tu             {
3875bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
3885bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
389*13451e39SWilly Tu             }
3905bc2dc8eSJames Feist 
3916c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
3926c34de48SEd Tanous             // BiosVer
39304a258f4SEd Tanous             for (const auto& connection : connectionNames)
3941abe55efSEd Tanous             {
39504a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
3961abe55efSEd Tanous                 {
39704a258f4SEd Tanous                     if (interfaceName ==
39804a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
3991abe55efSEd Tanous                     {
4001abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
40104a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
4029d3ae10eSAlpana Kumari 
403cf0e004cSNinad Palsule                         getMemorySummary(aResp, connection.first, path);
4045bc2dc8eSJames Feist 
4055bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
4061abe55efSEd Tanous                     }
40704a258f4SEd Tanous                     else if (interfaceName ==
40804a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
4091abe55efSEd Tanous                     {
4101abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
41104a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
41257e8c9beSAlpana Kumari 
41303fbed92SAli Ahmed                         getProcessorSummary(aResp, connection.first, path);
4145bc2dc8eSJames Feist 
4155bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
4161abe55efSEd Tanous                     }
417002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4181abe55efSEd Tanous                     {
4191abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
42004a258f4SEd Tanous                             << "Found UUID, now get its properties.";
421bc1d29deSKrzysztof Grobelny 
422bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
423bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
424bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
4255e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec3,
426b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4271214b7e7SGunnar Mills                                         properties) {
428cb13a392SEd Tanous                             if (ec3)
4291abe55efSEd Tanous                             {
430002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
431002d39b4SEd Tanous                                                  << ec3;
432f12894f8SJason M. Bills                                 messages::internalError(aResp->res);
433c5b2abe0SLewanczyk, Dawid                                 return;
434c5b2abe0SLewanczyk, Dawid                             }
435002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
436c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
43704a258f4SEd Tanous 
438bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
439bc1d29deSKrzysztof Grobelny 
440bc1d29deSKrzysztof Grobelny                             const bool success =
441bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
442bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
443bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
444bc1d29deSKrzysztof Grobelny 
445bc1d29deSKrzysztof Grobelny                             if (!success)
4461abe55efSEd Tanous                             {
447bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
448bc1d29deSKrzysztof Grobelny                                 return;
449bc1d29deSKrzysztof Grobelny                             }
450bc1d29deSKrzysztof Grobelny 
451bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
452bc1d29deSKrzysztof Grobelny                             {
453bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
45404a258f4SEd Tanous                                 if (valueStr.size() == 32)
4551abe55efSEd Tanous                                 {
456029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
457029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
458029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
459029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
46004a258f4SEd Tanous                                 }
461bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
462002d39b4SEd Tanous                                 aResp->res.jsonValue["UUID"] = valueStr;
463c5b2abe0SLewanczyk, Dawid                             }
464bc1d29deSKrzysztof Grobelny                             });
465c5b2abe0SLewanczyk, Dawid                     }
466029573d4SEd Tanous                     else if (interfaceName ==
467029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4681abe55efSEd Tanous                     {
469bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
470bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
471bc1d29deSKrzysztof Grobelny                             path,
472bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
4735e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
474b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4751214b7e7SGunnar Mills                                         propertiesList) {
476cb13a392SEd Tanous                             if (ec2)
477029573d4SEd Tanous                             {
478e4a4b9a9SJames Feist                                 // doesn't have to include this
479e4a4b9a9SJames Feist                                 // interface
480029573d4SEd Tanous                                 return;
481029573d4SEd Tanous                             }
482002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
483029573d4SEd Tanous                                              << " properties for system";
484bc1d29deSKrzysztof Grobelny 
485bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
486bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
487bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
488bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
489bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
490bc1d29deSKrzysztof Grobelny 
491bc1d29deSKrzysztof Grobelny                             const bool success =
492bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
493bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
494bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
495bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
496bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
497bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
498bc1d29deSKrzysztof Grobelny 
499bc1d29deSKrzysztof Grobelny                             if (!success)
500029573d4SEd Tanous                             {
501bc1d29deSKrzysztof Grobelny                                 messages::internalError(aResp->res);
502bc1d29deSKrzysztof Grobelny                                 return;
503029573d4SEd Tanous                             }
504bc1d29deSKrzysztof Grobelny 
505bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
506bc1d29deSKrzysztof Grobelny                             {
507bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["PartNumber"] =
508bc1d29deSKrzysztof Grobelny                                     *partNumber;
509029573d4SEd Tanous                             }
510bc1d29deSKrzysztof Grobelny 
511bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
512bc1d29deSKrzysztof Grobelny                             {
513bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SerialNumber"] =
514bc1d29deSKrzysztof Grobelny                                     *serialNumber;
515bc1d29deSKrzysztof Grobelny                             }
516bc1d29deSKrzysztof Grobelny 
517bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
518bc1d29deSKrzysztof Grobelny                             {
519bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Manufacturer"] =
520bc1d29deSKrzysztof Grobelny                                     *manufacturer;
521bc1d29deSKrzysztof Grobelny                             }
522bc1d29deSKrzysztof Grobelny 
523bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
524bc1d29deSKrzysztof Grobelny                             {
525bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["Model"] = *model;
526bc1d29deSKrzysztof Grobelny                             }
527bc1d29deSKrzysztof Grobelny 
528bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
529bc1d29deSKrzysztof Grobelny                             {
530bc1d29deSKrzysztof Grobelny                                 aResp->res.jsonValue["SubModel"] = *subModel;
531fc5afcf9Sbeccabroek                             }
532c1e236a6SGunnar Mills 
533cb7e1e7bSAndrew Geissler                             // Grab the bios version
534eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
535eee0013eSWilly Tu                                 aResp, sw_util::biosPurpose, "BiosVersion",
536002d39b4SEd Tanous                                 false);
537bc1d29deSKrzysztof Grobelny                             });
538e4a4b9a9SJames Feist 
5391e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5401e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5411e1e598dSJonathan Doman                             path,
5421e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5431e1e598dSJonathan Doman                             "AssetTag",
5441e1e598dSJonathan Doman                             "AssetTag",
5455e7e2dc5SEd Tanous                             [aResp](const boost::system::error_code& ec2,
5461e1e598dSJonathan Doman                                     const std::string& value) {
547cb13a392SEd Tanous                             if (ec2)
548e4a4b9a9SJames Feist                             {
549e4a4b9a9SJames Feist                                 // doesn't have to include this
550e4a4b9a9SJames Feist                                 // interface
551e4a4b9a9SJames Feist                                 return;
552e4a4b9a9SJames Feist                             }
553e4a4b9a9SJames Feist 
5541e1e598dSJonathan Doman                             aResp->res.jsonValue["AssetTag"] = value;
5551e1e598dSJonathan Doman                             });
556029573d4SEd Tanous                     }
557029573d4SEd Tanous                 }
558029573d4SEd Tanous             }
559c5b2abe0SLewanczyk, Dawid         }
5606617338dSEd Tanous         });
561c5b2abe0SLewanczyk, Dawid }
562c5b2abe0SLewanczyk, Dawid 
563c5b2abe0SLewanczyk, Dawid /**
564c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
565c5b2abe0SLewanczyk, Dawid  *
566c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
567c5b2abe0SLewanczyk, Dawid  *
568c5b2abe0SLewanczyk, Dawid  * @return None.
569c5b2abe0SLewanczyk, Dawid  */
5708d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5711abe55efSEd Tanous {
57255c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
5731e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5741e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5751e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5761e1e598dSJonathan Doman         "CurrentHostState",
5775e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
5781e1e598dSJonathan Doman                 const std::string& hostState) {
5791abe55efSEd Tanous         if (ec)
5801abe55efSEd Tanous         {
58122228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
58222228c28SAndrew Geissler             {
58322228c28SAndrew Geissler                 // Service not available, no error, just don't return
58422228c28SAndrew Geissler                 // host state info
58522228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
58622228c28SAndrew Geissler                 return;
58722228c28SAndrew Geissler             }
58822228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
589f12894f8SJason M. Bills             messages::internalError(aResp->res);
590c5b2abe0SLewanczyk, Dawid             return;
591c5b2abe0SLewanczyk, Dawid         }
5926617338dSEd Tanous 
5931e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
594c5b2abe0SLewanczyk, Dawid         // Verify Host State
5951e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5961abe55efSEd Tanous         {
59755c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "On";
5986617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Enabled";
5991abe55efSEd Tanous         }
6001e1e598dSJonathan Doman         else if (hostState ==
6010fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6028c888608SGunnar Mills         {
6038c888608SGunnar Mills             aResp->res.jsonValue["PowerState"] = "On";
6048c888608SGunnar Mills             aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6058c888608SGunnar Mills         }
6061e1e598dSJonathan Doman         else if (hostState ==
6070fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
60883935af9SAndrew Geissler         {
60983935af9SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "On";
61083935af9SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "InTest";
61183935af9SAndrew Geissler         }
6120fda0f12SGeorge Liu         else if (
6131e1e598dSJonathan Doman             hostState ==
6140fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6151a2a1437SAndrew Geissler         {
6161a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOn";
61715c27bf8SNoah Brewer             aResp->res.jsonValue["Status"]["State"] = "Starting";
6181a2a1437SAndrew Geissler         }
619002d39b4SEd Tanous         else if (hostState ==
6200fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6211a2a1437SAndrew Geissler         {
6221a2a1437SAndrew Geissler             aResp->res.jsonValue["PowerState"] = "PoweringOff";
6231a2a1437SAndrew Geissler             aResp->res.jsonValue["Status"]["State"] = "Disabled";
6241a2a1437SAndrew Geissler         }
6251abe55efSEd Tanous         else
6261abe55efSEd Tanous         {
62755c7b7a2SEd Tanous             aResp->res.jsonValue["PowerState"] = "Off";
6286617338dSEd Tanous             aResp->res.jsonValue["Status"]["State"] = "Disabled";
629c5b2abe0SLewanczyk, Dawid         }
6301e1e598dSJonathan Doman         });
631c5b2abe0SLewanczyk, Dawid }
632c5b2abe0SLewanczyk, Dawid 
633c5b2abe0SLewanczyk, Dawid /**
634786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
635491d8ee7SSantosh Puranik  *
636491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
637491d8ee7SSantosh Puranik  *
638491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
639491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
640491d8ee7SSantosh Puranik  */
64123a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
642491d8ee7SSantosh Puranik {
643491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
644491d8ee7SSantosh Puranik     {
645491d8ee7SSantosh Puranik         return "None";
646491d8ee7SSantosh Puranik     }
6473174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
648491d8ee7SSantosh Puranik     {
649491d8ee7SSantosh Puranik         return "Hdd";
650491d8ee7SSantosh Puranik     }
6513174e4dfSEd Tanous     if (dbusSource ==
652a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
653491d8ee7SSantosh Puranik     {
654491d8ee7SSantosh Puranik         return "Cd";
655491d8ee7SSantosh Puranik     }
6563174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
657491d8ee7SSantosh Puranik     {
658491d8ee7SSantosh Puranik         return "Pxe";
659491d8ee7SSantosh Puranik     }
6603174e4dfSEd Tanous     if (dbusSource ==
661944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6629f16b2c1SJennifer Lee     {
6639f16b2c1SJennifer Lee         return "Usb";
6649f16b2c1SJennifer Lee     }
665491d8ee7SSantosh Puranik     return "";
666491d8ee7SSantosh Puranik }
667491d8ee7SSantosh Puranik 
668491d8ee7SSantosh Puranik /**
669cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
670cd9a4666SKonstantin Aladyshev  *
671cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
672cd9a4666SKonstantin Aladyshev  *
673cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
674cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
675cd9a4666SKonstantin Aladyshev  */
676cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
677cd9a4666SKonstantin Aladyshev {
678cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
679cd9a4666SKonstantin Aladyshev     {
680cd9a4666SKonstantin Aladyshev         return "Legacy";
681cd9a4666SKonstantin Aladyshev     }
682cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
683cd9a4666SKonstantin Aladyshev     {
684cd9a4666SKonstantin Aladyshev         return "UEFI";
685cd9a4666SKonstantin Aladyshev     }
686cd9a4666SKonstantin Aladyshev     return "";
687cd9a4666SKonstantin Aladyshev }
688cd9a4666SKonstantin Aladyshev 
689cd9a4666SKonstantin Aladyshev /**
690786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
691491d8ee7SSantosh Puranik  *
692491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
693491d8ee7SSantosh Puranik  *
694491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
695491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
696491d8ee7SSantosh Puranik  */
69723a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
698491d8ee7SSantosh Puranik {
699491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
700491d8ee7SSantosh Puranik     {
701491d8ee7SSantosh Puranik         return "None";
702491d8ee7SSantosh Puranik     }
7033174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
704491d8ee7SSantosh Puranik     {
705491d8ee7SSantosh Puranik         return "Diags";
706491d8ee7SSantosh Puranik     }
7073174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
708491d8ee7SSantosh Puranik     {
709491d8ee7SSantosh Puranik         return "BiosSetup";
710491d8ee7SSantosh Puranik     }
711491d8ee7SSantosh Puranik     return "";
712491d8ee7SSantosh Puranik }
713491d8ee7SSantosh Puranik 
714491d8ee7SSantosh Puranik /**
715e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
716e43914b3SAndrew Geissler  *
717e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
718e43914b3SAndrew Geissler  *
719e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
720e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
721e43914b3SAndrew Geissler  */
722e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
723e43914b3SAndrew Geissler {
724e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
725e43914b3SAndrew Geissler     // enum
726e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
727e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
728e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
729e43914b3SAndrew Geissler     {
730e43914b3SAndrew Geissler         rfBpLastState = "None";
731e43914b3SAndrew Geissler     }
732e43914b3SAndrew Geissler     else if (dbusBootProgress ==
733e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
734e43914b3SAndrew Geissler              "PrimaryProcInit")
735e43914b3SAndrew Geissler     {
736e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
737e43914b3SAndrew Geissler     }
738e43914b3SAndrew Geissler     else if (dbusBootProgress ==
739e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
740e43914b3SAndrew Geissler              "BusInit")
741e43914b3SAndrew Geissler     {
742e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
743e43914b3SAndrew Geissler     }
744e43914b3SAndrew Geissler     else if (dbusBootProgress ==
745e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
746e43914b3SAndrew Geissler              "MemoryInit")
747e43914b3SAndrew Geissler     {
748e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
749e43914b3SAndrew Geissler     }
750e43914b3SAndrew Geissler     else if (dbusBootProgress ==
751e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
752e43914b3SAndrew Geissler              "SecondaryProcInit")
753e43914b3SAndrew Geissler     {
754e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
755e43914b3SAndrew Geissler     }
756e43914b3SAndrew Geissler     else if (dbusBootProgress ==
757e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
758e43914b3SAndrew Geissler              "PCIInit")
759e43914b3SAndrew Geissler     {
760e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
761e43914b3SAndrew Geissler     }
762e43914b3SAndrew Geissler     else if (dbusBootProgress ==
763e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
764e43914b3SAndrew Geissler              "SystemSetup")
765e43914b3SAndrew Geissler     {
766e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
767e43914b3SAndrew Geissler     }
768e43914b3SAndrew Geissler     else if (dbusBootProgress ==
769e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
770e43914b3SAndrew Geissler              "SystemInitComplete")
771e43914b3SAndrew Geissler     {
772e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
773e43914b3SAndrew Geissler     }
774e43914b3SAndrew Geissler     else if (dbusBootProgress ==
775e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
776e43914b3SAndrew Geissler              "OSStart")
777e43914b3SAndrew Geissler     {
778e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
779e43914b3SAndrew Geissler     }
780e43914b3SAndrew Geissler     else if (dbusBootProgress ==
781e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
782e43914b3SAndrew Geissler              "OSRunning")
783e43914b3SAndrew Geissler     {
784e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
785e43914b3SAndrew Geissler     }
786e43914b3SAndrew Geissler     else
787e43914b3SAndrew Geissler     {
788e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
789e43914b3SAndrew Geissler                          << dbusBootProgress;
790e43914b3SAndrew Geissler         // Just return the default
791e43914b3SAndrew Geissler     }
792e43914b3SAndrew Geissler     return rfBpLastState;
793e43914b3SAndrew Geissler }
794e43914b3SAndrew Geissler 
795e43914b3SAndrew Geissler /**
796786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
797491d8ee7SSantosh Puranik  *
798491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
799944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
800944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
801491d8ee7SSantosh Puranik  *
802944ffaf9SJohnathan Mantey  * @return Integer error code.
803491d8ee7SSantosh Puranik  */
8048d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
805944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
806944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
807491d8ee7SSantosh Puranik {
808c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
809c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
810944ffaf9SJohnathan Mantey 
811491d8ee7SSantosh Puranik     if (rfSource == "None")
812491d8ee7SSantosh Puranik     {
813944ffaf9SJohnathan Mantey         return 0;
814491d8ee7SSantosh Puranik     }
8153174e4dfSEd Tanous     if (rfSource == "Pxe")
816491d8ee7SSantosh Puranik     {
817944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
818944ffaf9SJohnathan Mantey     }
819944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
820944ffaf9SJohnathan Mantey     {
821944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
822944ffaf9SJohnathan Mantey     }
823944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
824944ffaf9SJohnathan Mantey     {
825944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
826944ffaf9SJohnathan Mantey     }
827944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
828944ffaf9SJohnathan Mantey     {
829944ffaf9SJohnathan Mantey         bootSource =
830944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
831944ffaf9SJohnathan Mantey     }
832944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
833944ffaf9SJohnathan Mantey     {
834944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
835491d8ee7SSantosh Puranik     }
8369f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8379f16b2c1SJennifer Lee     {
838944ffaf9SJohnathan Mantey         bootSource =
839944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8409f16b2c1SJennifer Lee     }
841491d8ee7SSantosh Puranik     else
842491d8ee7SSantosh Puranik     {
8430fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8440fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
845944ffaf9SJohnathan Mantey             << bootSource;
846944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
847944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
848944ffaf9SJohnathan Mantey         return -1;
849491d8ee7SSantosh Puranik     }
850944ffaf9SJohnathan Mantey     return 0;
851491d8ee7SSantosh Puranik }
8521981771bSAli Ahmed 
853978b8803SAndrew Geissler /**
854978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
855978b8803SAndrew Geissler  *
856978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
857978b8803SAndrew Geissler  *
858978b8803SAndrew Geissler  * @return None.
859978b8803SAndrew Geissler  */
8608d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
861978b8803SAndrew Geissler {
8621e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8631e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8641e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8651e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
8665e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
8671e1e598dSJonathan Doman                 const std::string& bootProgressStr) {
868978b8803SAndrew Geissler         if (ec)
869978b8803SAndrew Geissler         {
870978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
871978b8803SAndrew Geissler             // not found
872978b8803SAndrew Geissler             return;
873978b8803SAndrew Geissler         }
874978b8803SAndrew Geissler 
8751e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
876978b8803SAndrew Geissler 
877e43914b3SAndrew Geissler         aResp->res.jsonValue["BootProgress"]["LastState"] =
878e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8791e1e598dSJonathan Doman         });
880978b8803SAndrew Geissler }
881491d8ee7SSantosh Puranik 
882491d8ee7SSantosh Puranik /**
883b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
884b6d5d45cSHieu Huynh  *
885b6d5d45cSHieu Huynh  * @param[in] aResp  Shared pointer for generating response message.
886b6d5d45cSHieu Huynh  *
887b6d5d45cSHieu Huynh  * @return None.
888b6d5d45cSHieu Huynh  */
889b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
890b6d5d45cSHieu Huynh     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
891b6d5d45cSHieu Huynh {
892b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
893b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
894b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
895b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
8965e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
897b6d5d45cSHieu Huynh                 const uint64_t lastStateTime) {
898b6d5d45cSHieu Huynh         if (ec)
899b6d5d45cSHieu Huynh         {
900b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
901b6d5d45cSHieu Huynh             return;
902b6d5d45cSHieu Huynh         }
903b6d5d45cSHieu Huynh 
904b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
905b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
906b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
907b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
908b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
909b6d5d45cSHieu Huynh 
910b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
911b6d5d45cSHieu Huynh         aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
912b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
913b6d5d45cSHieu Huynh         });
914b6d5d45cSHieu Huynh }
915b6d5d45cSHieu Huynh 
916b6d5d45cSHieu Huynh /**
917c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
918cd9a4666SKonstantin Aladyshev  *
919cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
920cd9a4666SKonstantin Aladyshev  *
921cd9a4666SKonstantin Aladyshev  * @return None.
922cd9a4666SKonstantin Aladyshev  */
923cd9a4666SKonstantin Aladyshev 
924c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
925cd9a4666SKonstantin Aladyshev {
9261e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9271e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9281e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9291e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
9305e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9311e1e598dSJonathan Doman                 const std::string& bootType) {
932cd9a4666SKonstantin Aladyshev         if (ec)
933cd9a4666SKonstantin Aladyshev         {
934cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
935cd9a4666SKonstantin Aladyshev             return;
936cd9a4666SKonstantin Aladyshev         }
937cd9a4666SKonstantin Aladyshev 
9381e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
939cd9a4666SKonstantin Aladyshev 
940002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
941002d39b4SEd Tanous                             ["BootSourceOverrideMode@Redfish.AllowableValues"] =
942613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
943cd9a4666SKonstantin Aladyshev 
9441e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
945cd9a4666SKonstantin Aladyshev         if (rfType.empty())
946cd9a4666SKonstantin Aladyshev         {
947cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
948cd9a4666SKonstantin Aladyshev             return;
949cd9a4666SKonstantin Aladyshev         }
950cd9a4666SKonstantin Aladyshev 
951cd9a4666SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9521e1e598dSJonathan Doman         });
953cd9a4666SKonstantin Aladyshev }
954cd9a4666SKonstantin Aladyshev 
955cd9a4666SKonstantin Aladyshev /**
956c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
957491d8ee7SSantosh Puranik  *
958491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
959491d8ee7SSantosh Puranik  *
960491d8ee7SSantosh Puranik  * @return None.
961491d8ee7SSantosh Puranik  */
962c21865c4SKonstantin Aladyshev 
963c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
964491d8ee7SSantosh Puranik {
9651e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9661e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9671e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9681e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
9695e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
9701e1e598dSJonathan Doman                 const std::string& bootModeStr) {
971491d8ee7SSantosh Puranik         if (ec)
972491d8ee7SSantosh Puranik         {
973491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
974491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
975491d8ee7SSantosh Puranik             return;
976491d8ee7SSantosh Puranik         }
977491d8ee7SSantosh Puranik 
9781e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
979491d8ee7SSantosh Puranik 
9800fda0f12SGeorge Liu         aResp->res
9810fda0f12SGeorge Liu             .jsonValue["Boot"]
982002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
983002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
984491d8ee7SSantosh Puranik 
9851e1e598dSJonathan Doman         if (bootModeStr !=
986491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
987491d8ee7SSantosh Puranik         {
9881e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
989491d8ee7SSantosh Puranik             if (!rfMode.empty())
990491d8ee7SSantosh Puranik             {
991491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
992491d8ee7SSantosh Puranik                     rfMode;
993491d8ee7SSantosh Puranik             }
994491d8ee7SSantosh Puranik         }
9951e1e598dSJonathan Doman         });
996491d8ee7SSantosh Puranik }
997491d8ee7SSantosh Puranik 
998491d8ee7SSantosh Puranik /**
999c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1000491d8ee7SSantosh Puranik  *
1001491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
1002491d8ee7SSantosh Puranik  *
1003491d8ee7SSantosh Puranik  * @return None.
1004491d8ee7SSantosh Puranik  */
1005c21865c4SKonstantin Aladyshev 
1006c21865c4SKonstantin Aladyshev inline void
1007c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1008491d8ee7SSantosh Puranik {
10091e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10101e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10111e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10121e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
10135e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
10141e1e598dSJonathan Doman                 const std::string& bootSourceStr) {
1015491d8ee7SSantosh Puranik         if (ec)
1016491d8ee7SSantosh Puranik         {
1017491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10185ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10195ef735c8SNan Zhou             {
10205ef735c8SNan Zhou                 return;
10215ef735c8SNan Zhou             }
1022491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1023491d8ee7SSantosh Puranik             return;
1024491d8ee7SSantosh Puranik         }
1025491d8ee7SSantosh Puranik 
10261e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1027491d8ee7SSantosh Puranik 
10281e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1029491d8ee7SSantosh Puranik         if (!rfSource.empty())
1030491d8ee7SSantosh Puranik         {
1031002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1032491d8ee7SSantosh Puranik         }
1033cd9a4666SKonstantin Aladyshev 
1034cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1035cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1036c21865c4SKonstantin Aladyshev         getBootOverrideMode(aResp);
10371e1e598dSJonathan Doman         });
1038491d8ee7SSantosh Puranik }
1039491d8ee7SSantosh Puranik 
1040491d8ee7SSantosh Puranik /**
1041c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1042c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1043c21865c4SKonstantin Aladyshev  * state
1044491d8ee7SSantosh Puranik  *
1045491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1046491d8ee7SSantosh Puranik  *
1047491d8ee7SSantosh Puranik  * @return None.
1048491d8ee7SSantosh Puranik  */
1049491d8ee7SSantosh Puranik 
1050c21865c4SKonstantin Aladyshev inline void
1051c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1052c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1053c21865c4SKonstantin Aladyshev {
1054c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1055c21865c4SKonstantin Aladyshev     {
1056c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1057c21865c4SKonstantin Aladyshev         return;
1058c21865c4SKonstantin Aladyshev     }
1059c21865c4SKonstantin Aladyshev 
1060c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1061c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10621e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10631e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10641e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10651e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
10665e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1067491d8ee7SSantosh Puranik         if (ec)
1068491d8ee7SSantosh Puranik         {
1069491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1070c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1071491d8ee7SSantosh Puranik             return;
1072491d8ee7SSantosh Puranik         }
1073491d8ee7SSantosh Puranik 
1074c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1075c21865c4SKonstantin Aladyshev         {
1076002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1077c21865c4SKonstantin Aladyshev         }
1078c21865c4SKonstantin Aladyshev         else
1079c21865c4SKonstantin Aladyshev         {
1080c21865c4SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1081c21865c4SKonstantin Aladyshev                 "Continuous";
1082c21865c4SKonstantin Aladyshev         }
10831e1e598dSJonathan Doman         });
1084491d8ee7SSantosh Puranik }
1085491d8ee7SSantosh Puranik 
1086491d8ee7SSantosh Puranik /**
1087c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1088c21865c4SKonstantin Aladyshev  *
1089c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1090c21865c4SKonstantin Aladyshev  *
1091c21865c4SKonstantin Aladyshev  * @return None.
1092c21865c4SKonstantin Aladyshev  */
1093c21865c4SKonstantin Aladyshev 
1094c21865c4SKonstantin Aladyshev inline void
1095c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1096c21865c4SKonstantin Aladyshev {
10971e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10981e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10991e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11001e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
11015e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
11021e1e598dSJonathan Doman                 const bool bootOverrideEnable) {
1103c21865c4SKonstantin Aladyshev         if (ec)
1104c21865c4SKonstantin Aladyshev         {
1105c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
11065ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11075ef735c8SNan Zhou             {
11085ef735c8SNan Zhou                 return;
11095ef735c8SNan Zhou             }
1110c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1111c21865c4SKonstantin Aladyshev             return;
1112c21865c4SKonstantin Aladyshev         }
1113c21865c4SKonstantin Aladyshev 
11141e1e598dSJonathan Doman         processBootOverrideEnable(aResp, bootOverrideEnable);
11151e1e598dSJonathan Doman         });
1116c21865c4SKonstantin Aladyshev }
1117c21865c4SKonstantin Aladyshev 
1118c21865c4SKonstantin Aladyshev /**
1119c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1120c21865c4SKonstantin Aladyshev  *
1121c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1122c21865c4SKonstantin Aladyshev  *
1123c21865c4SKonstantin Aladyshev  * @return None.
1124c21865c4SKonstantin Aladyshev  */
1125c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1126c21865c4SKonstantin Aladyshev {
1127c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1128c21865c4SKonstantin Aladyshev 
1129c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1130c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1131c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1132c21865c4SKonstantin Aladyshev }
1133c21865c4SKonstantin Aladyshev 
1134c21865c4SKonstantin Aladyshev /**
1135c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1136c0557e1aSGunnar Mills  *
1137c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1138c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1139c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1140c0557e1aSGunnar Mills  * last power operation time.
1141c0557e1aSGunnar Mills  *
1142c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1143c0557e1aSGunnar Mills  *
1144c0557e1aSGunnar Mills  * @return None.
1145c0557e1aSGunnar Mills  */
11468d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1147c0557e1aSGunnar Mills {
1148c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1149c0557e1aSGunnar Mills 
11501e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11511e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11521e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11531e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
11545e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
1155c0557e1aSGunnar Mills         if (ec)
1156c0557e1aSGunnar Mills         {
1157c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1158c0557e1aSGunnar Mills             return;
1159c0557e1aSGunnar Mills         }
1160c0557e1aSGunnar Mills 
1161c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1162c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11631e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1164c0557e1aSGunnar Mills 
1165c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1166c0557e1aSGunnar Mills         aResp->res.jsonValue["LastResetTime"] =
11672b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11681e1e598dSJonathan Doman         });
1169c0557e1aSGunnar Mills }
1170c0557e1aSGunnar Mills 
1171c0557e1aSGunnar Mills /**
1172797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1173797d5daeSCorey Hardesty  *
1174797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1175797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1176797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1177797d5daeSCorey Hardesty  * dbus.
1178797d5daeSCorey Hardesty  *
1179797d5daeSCorey Hardesty  * @param[in] aResp     Shared pointer for generating response message.
1180797d5daeSCorey Hardesty  *
1181797d5daeSCorey Hardesty  * @return None.
1182797d5daeSCorey Hardesty  */
1183797d5daeSCorey Hardesty inline void
1184797d5daeSCorey Hardesty     getAutomaticRebootAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1185797d5daeSCorey Hardesty {
1186797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1187797d5daeSCorey Hardesty 
1188797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1189797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1190797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1191797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1192797d5daeSCorey Hardesty         [aResp{aResp}](const boost::system::error_code& ec,
1193797d5daeSCorey Hardesty                        const dbus::utility::DBusPropertiesMap& propertiesList) {
1194797d5daeSCorey Hardesty         if (ec)
1195797d5daeSCorey Hardesty         {
1196797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1197797d5daeSCorey Hardesty             {
1198797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1199797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1200797d5daeSCorey Hardesty             }
1201797d5daeSCorey Hardesty             return;
1202797d5daeSCorey Hardesty         }
1203797d5daeSCorey Hardesty 
1204797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1205797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1206797d5daeSCorey Hardesty 
1207797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1208797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1209797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1210797d5daeSCorey Hardesty 
1211797d5daeSCorey Hardesty         if (!success)
1212797d5daeSCorey Hardesty         {
1213797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1214797d5daeSCorey Hardesty             return;
1215797d5daeSCorey Hardesty         }
1216797d5daeSCorey Hardesty 
1217797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1218797d5daeSCorey Hardesty         {
1219797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1220797d5daeSCorey Hardesty                 *attemptsLeft;
1221797d5daeSCorey Hardesty         }
1222797d5daeSCorey Hardesty 
1223797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1224797d5daeSCorey Hardesty         {
1225797d5daeSCorey Hardesty             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1226797d5daeSCorey Hardesty                 *retryAttempts;
1227797d5daeSCorey Hardesty         }
1228797d5daeSCorey Hardesty         });
1229797d5daeSCorey Hardesty }
1230797d5daeSCorey Hardesty 
1231797d5daeSCorey Hardesty /**
12326bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12336bd5a8d2SGunnar Mills  *
12346bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
12356bd5a8d2SGunnar Mills  *
12366bd5a8d2SGunnar Mills  * @return None.
12376bd5a8d2SGunnar Mills  */
1238797d5daeSCorey Hardesty inline void
1239797d5daeSCorey Hardesty     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12406bd5a8d2SGunnar Mills {
12416bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12426bd5a8d2SGunnar Mills 
12431e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12441e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12451e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12461e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
12475e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
12486bd5a8d2SGunnar Mills         if (ec)
12496bd5a8d2SGunnar Mills         {
1250797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1251797d5daeSCorey Hardesty             {
1252797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1253797d5daeSCorey Hardesty                 messages::internalError(aResp->res);
1254797d5daeSCorey Hardesty             }
12556bd5a8d2SGunnar Mills             return;
12566bd5a8d2SGunnar Mills         }
12576bd5a8d2SGunnar Mills 
12581e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1259e05aec50SEd Tanous         if (autoRebootEnabled)
12606bd5a8d2SGunnar Mills         {
12616bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12626bd5a8d2SGunnar Mills                 "RetryAttempts";
12636bd5a8d2SGunnar Mills         }
12646bd5a8d2SGunnar Mills         else
12656bd5a8d2SGunnar Mills         {
1266002d39b4SEd Tanous             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
12676bd5a8d2SGunnar Mills         }
1268797d5daeSCorey Hardesty         getAutomaticRebootAttempts(aResp);
126969f35306SGunnar Mills 
127069f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
127169f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
127269f35306SGunnar Mills         // RetryAttempts.
1273002d39b4SEd Tanous         aResp->res.jsonValue["Boot"]
12740fda0f12SGeorge Liu                             ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12750fda0f12SGeorge Liu             "Disabled", "RetryAttempts"};
12761e1e598dSJonathan Doman         });
12776bd5a8d2SGunnar Mills }
12786bd5a8d2SGunnar Mills 
12796bd5a8d2SGunnar Mills /**
1280797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1281797d5daeSCorey Hardesty  *
1282797d5daeSCorey Hardesty  * @param[in] aResp   Shared pointer for generating response message.
1283797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1284797d5daeSCorey Hardesty  *
1285797d5daeSCorey Hardesty  *@return None.
1286797d5daeSCorey Hardesty  */
1287797d5daeSCorey Hardesty 
1288797d5daeSCorey Hardesty inline void
1289797d5daeSCorey Hardesty     setAutomaticRetryAttempts(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1290797d5daeSCorey Hardesty                               const uint32_t retryAttempts)
1291797d5daeSCorey Hardesty {
1292797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
1293797d5daeSCorey Hardesty     crow::connections::systemBus->async_method_call(
1294797d5daeSCorey Hardesty         [aResp](const boost::system::error_code& ec) {
1295797d5daeSCorey Hardesty         if (ec)
1296797d5daeSCorey Hardesty         {
1297797d5daeSCorey Hardesty             BMCWEB_LOG_ERROR
1298797d5daeSCorey Hardesty                 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
1299797d5daeSCorey Hardesty             messages::internalError(aResp->res);
1300797d5daeSCorey Hardesty             return;
1301797d5daeSCorey Hardesty         }
1302797d5daeSCorey Hardesty         },
1303797d5daeSCorey Hardesty         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1304797d5daeSCorey Hardesty         "org.freedesktop.DBus.Properties", "Set",
1305797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1306797d5daeSCorey Hardesty         std::variant<uint32_t>(retryAttempts));
1307797d5daeSCorey Hardesty }
1308797d5daeSCorey Hardesty 
1309797d5daeSCorey Hardesty /**
1310c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1311c6a620f2SGeorge Liu  *
1312c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1313c6a620f2SGeorge Liu  *
1314c6a620f2SGeorge Liu  * @return None.
1315c6a620f2SGeorge Liu  */
13168d1b46d7Szhanghch05 inline void
13178d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1318c6a620f2SGeorge Liu {
1319c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1320c6a620f2SGeorge Liu 
13211e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13221e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13231e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13241e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
13255e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
13265e7e2dc5SEd Tanous                 const std::string& policy) {
1327c6a620f2SGeorge Liu         if (ec)
1328c6a620f2SGeorge Liu         {
1329c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1330c6a620f2SGeorge Liu             return;
1331c6a620f2SGeorge Liu         }
1332c6a620f2SGeorge Liu 
13330fda0f12SGeorge Liu         const boost::container::flat_map<std::string, std::string> policyMaps = {
13340fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1335c6a620f2SGeorge Liu              "AlwaysOn"},
13360fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1337c6a620f2SGeorge Liu              "AlwaysOff"},
13380fda0f12SGeorge Liu             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
13394ed47cb8SMatthew Barth              "LastState"},
13404ed47cb8SMatthew Barth             // Return `AlwaysOff` when power restore policy set to "None"
13414ed47cb8SMatthew Barth             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
13424ed47cb8SMatthew Barth              "AlwaysOff"}};
1343c6a620f2SGeorge Liu 
13441e1e598dSJonathan Doman         auto policyMapsIt = policyMaps.find(policy);
1345c6a620f2SGeorge Liu         if (policyMapsIt == policyMaps.end())
1346c6a620f2SGeorge Liu         {
1347c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1348c6a620f2SGeorge Liu             return;
1349c6a620f2SGeorge Liu         }
1350c6a620f2SGeorge Liu 
1351c6a620f2SGeorge Liu         aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
13521e1e598dSJonathan Doman         });
1353c6a620f2SGeorge Liu }
1354c6a620f2SGeorge Liu 
1355c6a620f2SGeorge Liu /**
13561981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13571981771bSAli Ahmed  * TPM is required for booting the host.
13581981771bSAli Ahmed  *
13591981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13601981771bSAli Ahmed  *
13611981771bSAli Ahmed  * @return None.
13621981771bSAli Ahmed  */
13631981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13641981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13651981771bSAli Ahmed {
13661981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1367e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1368e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1369e99073f5SGeorge Liu     dbus::utility::getSubTree(
1370e99073f5SGeorge Liu         "/", 0, interfaces,
1371e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
1372b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
13731981771bSAli Ahmed         if (ec)
13741981771bSAli Ahmed         {
1375002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1376002d39b4SEd Tanous                              << ec;
13771981771bSAli Ahmed             // This is an optional D-Bus object so just return if
13781981771bSAli Ahmed             // error occurs
13791981771bSAli Ahmed             return;
13801981771bSAli Ahmed         }
138126f6976fSEd Tanous         if (subtree.empty())
13821981771bSAli Ahmed         {
13831981771bSAli Ahmed             // As noted above, this is an optional interface so just return
13841981771bSAli Ahmed             // if there is no instance found
13851981771bSAli Ahmed             return;
13861981771bSAli Ahmed         }
13871981771bSAli Ahmed 
13881981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
13891981771bSAli Ahmed         if (subtree.size() > 1)
13901981771bSAli Ahmed         {
13911981771bSAli Ahmed             BMCWEB_LOG_DEBUG
13921981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
13931981771bSAli Ahmed                 << subtree.size();
13941981771bSAli Ahmed             // Throw an internal Error and return
13951981771bSAli Ahmed             messages::internalError(aResp->res);
13961981771bSAli Ahmed             return;
13971981771bSAli Ahmed         }
13981981771bSAli Ahmed 
13991981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14001981771bSAli Ahmed         // field
14011981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14021981771bSAli Ahmed         {
14031981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14041981771bSAli Ahmed             messages::internalError(aResp->res);
14051981771bSAli Ahmed             return;
14061981771bSAli Ahmed         }
14071981771bSAli Ahmed 
14081981771bSAli Ahmed         const std::string& path = subtree[0].first;
14091981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14101981771bSAli Ahmed 
14111981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14121e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14131e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14141e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
14155e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
14168a592810SEd Tanous             if (ec2)
14171981771bSAli Ahmed             {
1418002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
14198a592810SEd Tanous                                  << ec2;
14201981771bSAli Ahmed                 messages::internalError(aResp->res);
14211981771bSAli Ahmed                 return;
14221981771bSAli Ahmed             }
14231981771bSAli Ahmed 
14241e1e598dSJonathan Doman             if (tpmRequired)
14251981771bSAli Ahmed             {
1426002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14271981771bSAli Ahmed                     "Required";
14281981771bSAli Ahmed             }
14291981771bSAli Ahmed             else
14301981771bSAli Ahmed             {
1431002d39b4SEd Tanous                 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14321981771bSAli Ahmed                     "Disabled";
14331981771bSAli Ahmed             }
14341e1e598dSJonathan Doman             });
1435e99073f5SGeorge Liu         });
14361981771bSAli Ahmed }
14371981771bSAli Ahmed 
14381981771bSAli Ahmed /**
14391c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14401c05dae3SAli Ahmed  * TPM is required for booting the host.
14411c05dae3SAli Ahmed  *
14421c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14431c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14441c05dae3SAli Ahmed  *
14451c05dae3SAli Ahmed  * @return None.
14461c05dae3SAli Ahmed  */
14471c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14481c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14491c05dae3SAli Ahmed {
14501c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1451e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1452e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1453e99073f5SGeorge Liu     dbus::utility::getSubTree(
1454e99073f5SGeorge Liu         "/", 0, interfaces,
1455e99073f5SGeorge Liu         [aResp,
1456e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1457e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14581c05dae3SAli Ahmed         if (ec)
14591c05dae3SAli Ahmed         {
1460002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1461002d39b4SEd Tanous                              << ec;
14621c05dae3SAli Ahmed             messages::internalError(aResp->res);
14631c05dae3SAli Ahmed             return;
14641c05dae3SAli Ahmed         }
146526f6976fSEd Tanous         if (subtree.empty())
14661c05dae3SAli Ahmed         {
14671c05dae3SAli Ahmed             messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14681c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14691c05dae3SAli Ahmed             return;
14701c05dae3SAli Ahmed         }
14711c05dae3SAli Ahmed 
14721c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
14731c05dae3SAli Ahmed         if (subtree.size() > 1)
14741c05dae3SAli Ahmed         {
14751c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
14761c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14771c05dae3SAli Ahmed                 << subtree.size();
14781c05dae3SAli Ahmed             // Throw an internal Error and return
14791c05dae3SAli Ahmed             messages::internalError(aResp->res);
14801c05dae3SAli Ahmed             return;
14811c05dae3SAli Ahmed         }
14821c05dae3SAli Ahmed 
14831c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14841c05dae3SAli Ahmed         // field
14851c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14861c05dae3SAli Ahmed         {
14871c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14881c05dae3SAli Ahmed             messages::internalError(aResp->res);
14891c05dae3SAli Ahmed             return;
14901c05dae3SAli Ahmed         }
14911c05dae3SAli Ahmed 
14921c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
14931c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14941c05dae3SAli Ahmed 
14951c05dae3SAli Ahmed         if (serv.empty())
14961c05dae3SAli Ahmed         {
14971c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14981c05dae3SAli Ahmed             messages::internalError(aResp->res);
14991c05dae3SAli Ahmed             return;
15001c05dae3SAli Ahmed         }
15011c05dae3SAli Ahmed 
15021c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15031c05dae3SAli Ahmed         crow::connections::systemBus->async_method_call(
15045e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
15058a592810SEd Tanous             if (ec2)
15061c05dae3SAli Ahmed             {
15070fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
15080fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
15098a592810SEd Tanous                     << ec2;
15101c05dae3SAli Ahmed                 messages::internalError(aResp->res);
15111c05dae3SAli Ahmed                 return;
15121c05dae3SAli Ahmed             }
15131c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15141c05dae3SAli Ahmed             },
15151c05dae3SAli Ahmed             serv, path, "org.freedesktop.DBus.Properties", "Set",
15161c05dae3SAli Ahmed             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1517168e20c1SEd Tanous             dbus::utility::DbusVariantType(tpmRequired));
1518e99073f5SGeorge Liu         });
15191c05dae3SAli Ahmed }
15201c05dae3SAli Ahmed 
15211c05dae3SAli Ahmed /**
1522491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1523491d8ee7SSantosh Puranik  *
1524491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1525cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1526cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1527cd9a4666SKonstantin Aladyshev  */
1528cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1529cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1530cd9a4666SKonstantin Aladyshev {
1531c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1532cd9a4666SKonstantin Aladyshev 
1533c21865c4SKonstantin Aladyshev     if (!bootType)
1534cd9a4666SKonstantin Aladyshev     {
1535c21865c4SKonstantin Aladyshev         return;
1536c21865c4SKonstantin Aladyshev     }
1537c21865c4SKonstantin Aladyshev 
1538cd9a4666SKonstantin Aladyshev     // Source target specified
1539cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1540cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1541cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1542cd9a4666SKonstantin Aladyshev     {
1543cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1544cd9a4666SKonstantin Aladyshev     }
1545cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1546cd9a4666SKonstantin Aladyshev     {
1547cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1548cd9a4666SKonstantin Aladyshev     }
1549cd9a4666SKonstantin Aladyshev     else
1550cd9a4666SKonstantin Aladyshev     {
1551cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1552cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1553cd9a4666SKonstantin Aladyshev                          << *bootType;
1554cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1555cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1556cd9a4666SKonstantin Aladyshev         return;
1557cd9a4666SKonstantin Aladyshev     }
1558cd9a4666SKonstantin Aladyshev 
1559cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1560cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1561cd9a4666SKonstantin Aladyshev 
1562cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
15635e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1564cd9a4666SKonstantin Aladyshev         if (ec)
1565cd9a4666SKonstantin Aladyshev         {
1566cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1567cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1568cd9a4666SKonstantin Aladyshev             {
1569cd9a4666SKonstantin Aladyshev                 messages::resourceNotFound(aResp->res, "Set", "BootType");
1570cd9a4666SKonstantin Aladyshev                 return;
1571cd9a4666SKonstantin Aladyshev             }
1572cd9a4666SKonstantin Aladyshev             messages::internalError(aResp->res);
1573cd9a4666SKonstantin Aladyshev             return;
1574cd9a4666SKonstantin Aladyshev         }
1575cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
1576cd9a4666SKonstantin Aladyshev         },
1577c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1578c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1579cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1580cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1581168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1582cd9a4666SKonstantin Aladyshev }
1583cd9a4666SKonstantin Aladyshev 
1584cd9a4666SKonstantin Aladyshev /**
1585cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1586cd9a4666SKonstantin Aladyshev  *
1587cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1588c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1589c21865c4SKonstantin Aladyshev  * @return Integer error code.
1590c21865c4SKonstantin Aladyshev  */
1591c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1592c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1593c21865c4SKonstantin Aladyshev {
1594c21865c4SKonstantin Aladyshev     if (!bootEnable)
1595c21865c4SKonstantin Aladyshev     {
1596c21865c4SKonstantin Aladyshev         return;
1597c21865c4SKonstantin Aladyshev     }
1598c21865c4SKonstantin Aladyshev     // Source target specified
1599c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1600c21865c4SKonstantin Aladyshev 
1601c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1602c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1603c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1604c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1605c21865c4SKonstantin Aladyshev     {
1606c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1607c21865c4SKonstantin Aladyshev     }
1608c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1609c21865c4SKonstantin Aladyshev     {
1610c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1611c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1612c21865c4SKonstantin Aladyshev     }
1613c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1614c21865c4SKonstantin Aladyshev     {
1615c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1616c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1617c21865c4SKonstantin Aladyshev     }
1618c21865c4SKonstantin Aladyshev     else
1619c21865c4SKonstantin Aladyshev     {
16200fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16210fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1622c21865c4SKonstantin Aladyshev             << *bootEnable;
1623c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1624c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1625c21865c4SKonstantin Aladyshev         return;
1626c21865c4SKonstantin Aladyshev     }
1627c21865c4SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     // Act on validated parameters
1629c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1630c21865c4SKonstantin Aladyshev 
1631c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16325e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec2) {
16338a592810SEd Tanous         if (ec2)
1634c21865c4SKonstantin Aladyshev         {
16358a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1636c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1637c21865c4SKonstantin Aladyshev             return;
1638c21865c4SKonstantin Aladyshev         }
1639c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1640c21865c4SKonstantin Aladyshev         },
1641c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1642c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1643c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1644c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1645168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1646c21865c4SKonstantin Aladyshev 
1647c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1648c21865c4SKonstantin Aladyshev     {
1649c21865c4SKonstantin Aladyshev         return;
1650c21865c4SKonstantin Aladyshev     }
1651c21865c4SKonstantin Aladyshev 
1652c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1653c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1654c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1655c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1656c21865c4SKonstantin Aladyshev 
1657c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
16585e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1659c21865c4SKonstantin Aladyshev         if (ec)
1660c21865c4SKonstantin Aladyshev         {
1661c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1662c21865c4SKonstantin Aladyshev             messages::internalError(aResp->res);
1663c21865c4SKonstantin Aladyshev             return;
1664c21865c4SKonstantin Aladyshev         }
1665c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1666c21865c4SKonstantin Aladyshev         },
1667c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1668c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1669c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1670c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1671168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1672c21865c4SKonstantin Aladyshev }
1673c21865c4SKonstantin Aladyshev 
1674c21865c4SKonstantin Aladyshev /**
1675c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1676c21865c4SKonstantin Aladyshev  *
1677c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1678491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1679491d8ee7SSantosh Puranik  *
1680265c1602SJohnathan Mantey  * @return Integer error code.
1681491d8ee7SSantosh Puranik  */
1682cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1683cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1684491d8ee7SSantosh Puranik {
1685c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1686c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1687944ffaf9SJohnathan Mantey 
1688c21865c4SKonstantin Aladyshev     if (!bootSource)
1689491d8ee7SSantosh Puranik     {
1690c21865c4SKonstantin Aladyshev         return;
1691c21865c4SKonstantin Aladyshev     }
1692c21865c4SKonstantin Aladyshev 
1693491d8ee7SSantosh Puranik     // Source target specified
1694491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1695491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1696e662eae8SEd Tanous     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1697e662eae8SEd Tanous         0)
1698491d8ee7SSantosh Puranik     {
1699944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1700944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1701491d8ee7SSantosh Puranik             << *bootSource;
1702491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1703491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1704491d8ee7SSantosh Puranik         return;
1705491d8ee7SSantosh Puranik     }
1706491d8ee7SSantosh Puranik 
1707944ffaf9SJohnathan Mantey     // Act on validated parameters
1708944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1709944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1710944ffaf9SJohnathan Mantey 
1711491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17125e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1713491d8ee7SSantosh Puranik         if (ec)
1714491d8ee7SSantosh Puranik         {
1715491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1716491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1717491d8ee7SSantosh Puranik             return;
1718491d8ee7SSantosh Puranik         }
1719491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
1720491d8ee7SSantosh Puranik         },
1721c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1722c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1723491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1724491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1725168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1726944ffaf9SJohnathan Mantey 
1727491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
17285e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1729491d8ee7SSantosh Puranik         if (ec)
1730491d8ee7SSantosh Puranik         {
1731491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1732491d8ee7SSantosh Puranik             messages::internalError(aResp->res);
1733491d8ee7SSantosh Puranik             return;
1734491d8ee7SSantosh Puranik         }
1735491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
1736491d8ee7SSantosh Puranik         },
1737c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1738c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1739491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1740491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1741168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1742cd9a4666SKonstantin Aladyshev }
1743944ffaf9SJohnathan Mantey 
1744cd9a4666SKonstantin Aladyshev /**
1745c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1746491d8ee7SSantosh Puranik  *
1747491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1748491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1749cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1750491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1751491d8ee7SSantosh Puranik  *
1752265c1602SJohnathan Mantey  * @return Integer error code.
1753491d8ee7SSantosh Puranik  */
1754c21865c4SKonstantin Aladyshev 
1755c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1756c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1757c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1758c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1759491d8ee7SSantosh Puranik {
1760491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1761491d8ee7SSantosh Puranik 
1762c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1763c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1764c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1765491d8ee7SSantosh Puranik }
1766491d8ee7SSantosh Puranik 
1767c6a620f2SGeorge Liu /**
176898e386ecSGunnar Mills  * @brief Sets AssetTag
176998e386ecSGunnar Mills  *
177098e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
177198e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
177298e386ecSGunnar Mills  *
177398e386ecSGunnar Mills  * @return None.
177498e386ecSGunnar Mills  */
17758d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
177698e386ecSGunnar Mills                         const std::string& assetTag)
177798e386ecSGunnar Mills {
1778e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1779e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1780e99073f5SGeorge Liu     dbus::utility::getSubTree(
1781e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1782b9d36b47SEd Tanous         [aResp,
1783e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1784b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
178598e386ecSGunnar Mills         if (ec)
178698e386ecSGunnar Mills         {
178798e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
178898e386ecSGunnar Mills             messages::internalError(aResp->res);
178998e386ecSGunnar Mills             return;
179098e386ecSGunnar Mills         }
179126f6976fSEd Tanous         if (subtree.empty())
179298e386ecSGunnar Mills         {
179398e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
179498e386ecSGunnar Mills             messages::internalError(aResp->res);
179598e386ecSGunnar Mills             return;
179698e386ecSGunnar Mills         }
179798e386ecSGunnar Mills         // Assume only 1 system D-Bus object
179898e386ecSGunnar Mills         // Throw an error if there is more than 1
179998e386ecSGunnar Mills         if (subtree.size() > 1)
180098e386ecSGunnar Mills         {
180198e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
180298e386ecSGunnar Mills             messages::internalError(aResp->res);
180398e386ecSGunnar Mills             return;
180498e386ecSGunnar Mills         }
180598e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
180698e386ecSGunnar Mills         {
180798e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
180898e386ecSGunnar Mills             messages::internalError(aResp->res);
180998e386ecSGunnar Mills             return;
181098e386ecSGunnar Mills         }
181198e386ecSGunnar Mills 
181298e386ecSGunnar Mills         const std::string& path = subtree[0].first;
181398e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
181498e386ecSGunnar Mills 
181598e386ecSGunnar Mills         if (service.empty())
181698e386ecSGunnar Mills         {
181798e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
181898e386ecSGunnar Mills             messages::internalError(aResp->res);
181998e386ecSGunnar Mills             return;
182098e386ecSGunnar Mills         }
182198e386ecSGunnar Mills 
182298e386ecSGunnar Mills         crow::connections::systemBus->async_method_call(
18235e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
182498e386ecSGunnar Mills             if (ec2)
182598e386ecSGunnar Mills             {
1826002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1827002d39b4SEd Tanous                                  << ec2;
182898e386ecSGunnar Mills                 messages::internalError(aResp->res);
182998e386ecSGunnar Mills                 return;
183098e386ecSGunnar Mills             }
183198e386ecSGunnar Mills             },
183298e386ecSGunnar Mills             service, path, "org.freedesktop.DBus.Properties", "Set",
183398e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1834168e20c1SEd Tanous             dbus::utility::DbusVariantType(assetTag));
1835e99073f5SGeorge Liu         });
183698e386ecSGunnar Mills }
183798e386ecSGunnar Mills 
183898e386ecSGunnar Mills /**
183969f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
184069f35306SGunnar Mills  *
184169f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
184269f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
184369f35306SGunnar Mills  *
184469f35306SGunnar Mills  * @return None.
184569f35306SGunnar Mills  */
18468d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1847f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
184869f35306SGunnar Mills {
184969f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
185069f35306SGunnar Mills 
185169f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1852543f4400SEd Tanous     bool autoRebootEnabled = false;
185369f35306SGunnar Mills 
185469f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
185569f35306SGunnar Mills     {
185669f35306SGunnar Mills         autoRebootEnabled = false;
185769f35306SGunnar Mills     }
185869f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
185969f35306SGunnar Mills     {
186069f35306SGunnar Mills         autoRebootEnabled = true;
186169f35306SGunnar Mills     }
186269f35306SGunnar Mills     else
186369f35306SGunnar Mills     {
18640fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
186569f35306SGunnar Mills                          << automaticRetryConfig;
186669f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
186769f35306SGunnar Mills                                          "AutomaticRetryConfig");
186869f35306SGunnar Mills         return;
186969f35306SGunnar Mills     }
187069f35306SGunnar Mills 
187169f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
18725e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
187369f35306SGunnar Mills         if (ec)
187469f35306SGunnar Mills         {
187569f35306SGunnar Mills             messages::internalError(aResp->res);
187669f35306SGunnar Mills             return;
187769f35306SGunnar Mills         }
187869f35306SGunnar Mills         },
187969f35306SGunnar Mills         "xyz.openbmc_project.Settings",
188069f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
188169f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
188269f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1883168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
188469f35306SGunnar Mills }
188569f35306SGunnar Mills 
188669f35306SGunnar Mills /**
1887c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1888c6a620f2SGeorge Liu  *
1889c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1890c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1891c6a620f2SGeorge Liu  *
1892c6a620f2SGeorge Liu  * @return None.
1893c6a620f2SGeorge Liu  */
18948d1b46d7Szhanghch05 inline void
18958d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
18964e69c904SGunnar Mills                           const std::string& policy)
1897c6a620f2SGeorge Liu {
1898c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1899c6a620f2SGeorge Liu 
1900c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
19010fda0f12SGeorge Liu         {"AlwaysOn",
19020fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
19030fda0f12SGeorge Liu         {"AlwaysOff",
19040fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
19050fda0f12SGeorge Liu         {"LastState",
19060fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1907c6a620f2SGeorge Liu 
1908c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1909c6a620f2SGeorge Liu 
19104e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1911c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1912c6a620f2SGeorge Liu     {
19134e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19144e69c904SGunnar Mills                                          "PowerRestorePolicy");
1915c6a620f2SGeorge Liu         return;
1916c6a620f2SGeorge Liu     }
1917c6a620f2SGeorge Liu 
1918c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1919c6a620f2SGeorge Liu 
1920c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
19215e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec) {
1922c6a620f2SGeorge Liu         if (ec)
1923c6a620f2SGeorge Liu         {
1924c6a620f2SGeorge Liu             messages::internalError(aResp->res);
1925c6a620f2SGeorge Liu             return;
1926c6a620f2SGeorge Liu         }
1927c6a620f2SGeorge Liu         },
1928c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1929c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1930c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1931c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1932168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1933c6a620f2SGeorge Liu }
1934c6a620f2SGeorge Liu 
1935a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1936a6349918SAppaRao Puli /**
1937a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1938a6349918SAppaRao Puli  *
1939a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1940a6349918SAppaRao Puli  *
1941a6349918SAppaRao Puli  * @return None.
1942a6349918SAppaRao Puli  */
19438d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1944a6349918SAppaRao Puli {
1945a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1946bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1947bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1948bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
19495e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
1950b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& propertiesList) {
1951b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1952b99fb1a9SAppaRao Puli             aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
195350626f4fSJames Feist         aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
195450626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
195550626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
195650626f4fSJames Feist 
1957a6349918SAppaRao Puli         if (ec)
1958a6349918SAppaRao Puli         {
1959a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1960b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1961b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1962a6349918SAppaRao Puli             return;
1963a6349918SAppaRao Puli         }
1964a6349918SAppaRao Puli 
1965a6349918SAppaRao Puli         const bool* provState = nullptr;
1966a6349918SAppaRao Puli         const bool* lockState = nullptr;
1967bc1d29deSKrzysztof Grobelny 
1968bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19690d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19700d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1971bc1d29deSKrzysztof Grobelny 
1972bc1d29deSKrzysztof Grobelny         if (!success)
1973a6349918SAppaRao Puli         {
1974bc1d29deSKrzysztof Grobelny             messages::internalError(aResp->res);
1975bc1d29deSKrzysztof Grobelny             return;
1976a6349918SAppaRao Puli         }
1977a6349918SAppaRao Puli 
1978a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1979a6349918SAppaRao Puli         {
1980a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1981a6349918SAppaRao Puli             messages::internalError(aResp->res);
1982a6349918SAppaRao Puli             return;
1983a6349918SAppaRao Puli         }
1984a6349918SAppaRao Puli 
1985a6349918SAppaRao Puli         if (*provState == true)
1986a6349918SAppaRao Puli         {
1987a6349918SAppaRao Puli             if (*lockState == true)
1988a6349918SAppaRao Puli             {
1989a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1990a6349918SAppaRao Puli             }
1991a6349918SAppaRao Puli             else
1992a6349918SAppaRao Puli             {
1993a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1994a6349918SAppaRao Puli             }
1995a6349918SAppaRao Puli         }
1996a6349918SAppaRao Puli         else
1997a6349918SAppaRao Puli         {
1998a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1999a6349918SAppaRao Puli         }
2000bc1d29deSKrzysztof Grobelny         });
2001a6349918SAppaRao Puli }
2002a6349918SAppaRao Puli #endif
2003a6349918SAppaRao Puli 
2004491d8ee7SSantosh Puranik /**
20053a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20063a2d0424SChris Cain  *
20073a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20083a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20093a2d0424SChris Cain  *
20103a2d0424SChris Cain  * @return None.
20113a2d0424SChris Cain  */
20123a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20133a2d0424SChris Cain                                const std::string& modeValue)
20143a2d0424SChris Cain {
20150fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20163a2d0424SChris Cain     {
20173a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20183a2d0424SChris Cain     }
20190fda0f12SGeorge Liu     else if (
20200fda0f12SGeorge Liu         modeValue ==
20210fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20223a2d0424SChris Cain     {
20233a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20243a2d0424SChris Cain     }
20250fda0f12SGeorge Liu     else if (modeValue ==
20260fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20273a2d0424SChris Cain     {
20283a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20293a2d0424SChris Cain     }
20300fda0f12SGeorge Liu     else if (modeValue ==
20310fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20323a2d0424SChris Cain     {
20333a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20343a2d0424SChris Cain     }
20353a2d0424SChris Cain     else
20363a2d0424SChris Cain     {
20373a2d0424SChris Cain         // Any other values would be invalid
20383a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20393a2d0424SChris Cain         messages::internalError(aResp->res);
20403a2d0424SChris Cain     }
20413a2d0424SChris Cain }
20423a2d0424SChris Cain 
20433a2d0424SChris Cain /**
20443a2d0424SChris Cain  * @brief Retrieves system power mode
20453a2d0424SChris Cain  *
20463a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20473a2d0424SChris Cain  *
20483a2d0424SChris Cain  * @return None.
20493a2d0424SChris Cain  */
20503a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20513a2d0424SChris Cain {
20523a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20533a2d0424SChris Cain 
20543a2d0424SChris Cain     // Get Power Mode object path:
2055e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2056e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2057e99073f5SGeorge Liu     dbus::utility::getSubTree(
2058e99073f5SGeorge Liu         "/", 0, interfaces,
2059e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2060b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
20613a2d0424SChris Cain         if (ec)
20623a2d0424SChris Cain         {
2063002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2064002d39b4SEd Tanous                              << ec;
20653a2d0424SChris Cain             // This is an optional D-Bus object so just return if
20663a2d0424SChris Cain             // error occurs
20673a2d0424SChris Cain             return;
20683a2d0424SChris Cain         }
20693a2d0424SChris Cain         if (subtree.empty())
20703a2d0424SChris Cain         {
20713a2d0424SChris Cain             // As noted above, this is an optional interface so just return
20723a2d0424SChris Cain             // if there is no instance found
20733a2d0424SChris Cain             return;
20743a2d0424SChris Cain         }
20753a2d0424SChris Cain         if (subtree.size() > 1)
20763a2d0424SChris Cain         {
20773a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
20783a2d0424SChris Cain             // error
20793a2d0424SChris Cain             BMCWEB_LOG_DEBUG
20803a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
20813a2d0424SChris Cain                 << subtree.size();
20823a2d0424SChris Cain             messages::internalError(aResp->res);
20833a2d0424SChris Cain             return;
20843a2d0424SChris Cain         }
20853a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
20863a2d0424SChris Cain         {
20873a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
20883a2d0424SChris Cain             messages::internalError(aResp->res);
20893a2d0424SChris Cain             return;
20903a2d0424SChris Cain         }
20913a2d0424SChris Cain         const std::string& path = subtree[0].first;
20923a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
20933a2d0424SChris Cain         if (service.empty())
20943a2d0424SChris Cain         {
20953a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
20963a2d0424SChris Cain             messages::internalError(aResp->res);
20973a2d0424SChris Cain             return;
20983a2d0424SChris Cain         }
20993a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
21001e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
21011e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
21021e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
21035e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
21041e1e598dSJonathan Doman                     const std::string& pmode) {
21058a592810SEd Tanous             if (ec2)
21063a2d0424SChris Cain             {
2107002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
21088a592810SEd Tanous                                  << ec2;
21093a2d0424SChris Cain                 messages::internalError(aResp->res);
21103a2d0424SChris Cain                 return;
21113a2d0424SChris Cain             }
21123a2d0424SChris Cain 
2113002d39b4SEd Tanous             aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2114002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
21153a2d0424SChris Cain 
21161e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
21171e1e598dSJonathan Doman             translatePowerMode(aResp, pmode);
21181e1e598dSJonathan Doman             });
2119e99073f5SGeorge Liu         });
21203a2d0424SChris Cain }
21213a2d0424SChris Cain 
21223a2d0424SChris Cain /**
21233a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21243a2d0424SChris Cain  * name associated with that string
21253a2d0424SChris Cain  *
21263a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21273a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21283a2d0424SChris Cain  *
21293a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21303a2d0424SChris Cain  */
21313a2d0424SChris Cain inline std::string
21323a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21333a2d0424SChris Cain                       const std::string& modeString)
21343a2d0424SChris Cain {
21353a2d0424SChris Cain     std::string mode;
21363a2d0424SChris Cain 
21373a2d0424SChris Cain     if (modeString == "Static")
21383a2d0424SChris Cain     {
21393a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21403a2d0424SChris Cain     }
21413a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21423a2d0424SChris Cain     {
21430fda0f12SGeorge Liu         mode =
21440fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21453a2d0424SChris Cain     }
21463a2d0424SChris Cain     else if (modeString == "PowerSaving")
21473a2d0424SChris Cain     {
21483a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21493a2d0424SChris Cain     }
21503a2d0424SChris Cain     else
21513a2d0424SChris Cain     {
21523a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21533a2d0424SChris Cain     }
21543a2d0424SChris Cain     return mode;
21553a2d0424SChris Cain }
21563a2d0424SChris Cain 
21573a2d0424SChris Cain /**
21583a2d0424SChris Cain  * @brief Sets system power mode.
21593a2d0424SChris Cain  *
21603a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21613a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21623a2d0424SChris Cain  *
21633a2d0424SChris Cain  * @return None.
21643a2d0424SChris Cain  */
21653a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21663a2d0424SChris Cain                          const std::string& pmode)
21673a2d0424SChris Cain {
21683a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21693a2d0424SChris Cain 
21703a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
21713a2d0424SChris Cain     if (powerMode.empty())
21723a2d0424SChris Cain     {
21733a2d0424SChris Cain         return;
21743a2d0424SChris Cain     }
21753a2d0424SChris Cain 
21763a2d0424SChris Cain     // Get Power Mode object path:
2177e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2178e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2179e99073f5SGeorge Liu     dbus::utility::getSubTree(
2180e99073f5SGeorge Liu         "/", 0, interfaces,
2181b9d36b47SEd Tanous         [aResp,
2182e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2183b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21843a2d0424SChris Cain         if (ec)
21853a2d0424SChris Cain         {
2186002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2187002d39b4SEd Tanous                              << ec;
21883a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21893a2d0424SChris Cain             messages::internalError(aResp->res);
21903a2d0424SChris Cain             return;
21913a2d0424SChris Cain         }
21923a2d0424SChris Cain         if (subtree.empty())
21933a2d0424SChris Cain         {
21943a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
21953a2d0424SChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
21963a2d0424SChris Cain                                        "PowerMode");
21973a2d0424SChris Cain             return;
21983a2d0424SChris Cain         }
21993a2d0424SChris Cain         if (subtree.size() > 1)
22003a2d0424SChris Cain         {
22013a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22023a2d0424SChris Cain             // error
22033a2d0424SChris Cain             BMCWEB_LOG_DEBUG
22043a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
22053a2d0424SChris Cain                 << subtree.size();
22063a2d0424SChris Cain             messages::internalError(aResp->res);
22073a2d0424SChris Cain             return;
22083a2d0424SChris Cain         }
22093a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22103a2d0424SChris Cain         {
22113a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22123a2d0424SChris Cain             messages::internalError(aResp->res);
22133a2d0424SChris Cain             return;
22143a2d0424SChris Cain         }
22153a2d0424SChris Cain         const std::string& path = subtree[0].first;
22163a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22173a2d0424SChris Cain         if (service.empty())
22183a2d0424SChris Cain         {
22193a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22203a2d0424SChris Cain             messages::internalError(aResp->res);
22213a2d0424SChris Cain             return;
22223a2d0424SChris Cain         }
22233a2d0424SChris Cain 
22243a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22253a2d0424SChris Cain                          << path;
22263a2d0424SChris Cain 
22273a2d0424SChris Cain         // Set the Power Mode property
22283a2d0424SChris Cain         crow::connections::systemBus->async_method_call(
22295e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2) {
22308a592810SEd Tanous             if (ec2)
22313a2d0424SChris Cain             {
22323a2d0424SChris Cain                 messages::internalError(aResp->res);
22333a2d0424SChris Cain                 return;
22343a2d0424SChris Cain             }
22353a2d0424SChris Cain             },
22363a2d0424SChris Cain             service, path, "org.freedesktop.DBus.Properties", "Set",
22373a2d0424SChris Cain             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2238168e20c1SEd Tanous             dbus::utility::DbusVariantType(powerMode));
2239e99073f5SGeorge Liu         });
22403a2d0424SChris Cain }
22413a2d0424SChris Cain 
22423a2d0424SChris Cain /**
224351709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
224451709ffdSYong Li  *
224551709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
224651709ffdSYong Li  *
224751709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
224851709ffdSYong Li  * translation cannot be done, returns an empty string.
224951709ffdSYong Li  */
225023a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
225151709ffdSYong Li {
225251709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
225351709ffdSYong Li     {
225451709ffdSYong Li         return "None";
225551709ffdSYong Li     }
22563174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
225751709ffdSYong Li     {
225851709ffdSYong Li         return "ResetSystem";
225951709ffdSYong Li     }
22603174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
226151709ffdSYong Li     {
226251709ffdSYong Li         return "PowerDown";
226351709ffdSYong Li     }
22643174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
226551709ffdSYong Li     {
226651709ffdSYong Li         return "PowerCycle";
226751709ffdSYong Li     }
226851709ffdSYong Li 
226951709ffdSYong Li     return "";
227051709ffdSYong Li }
227151709ffdSYong Li 
227251709ffdSYong Li /**
2273c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2274c45f0082SYong Li  *
2275c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2276c45f0082SYong Li  *
2277c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2278c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2279c45f0082SYong Li  */
2280c45f0082SYong Li 
228123a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2282c45f0082SYong Li {
2283c45f0082SYong Li     if (rfAction == "None")
2284c45f0082SYong Li     {
2285c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2286c45f0082SYong Li     }
22873174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2288c45f0082SYong Li     {
2289c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2290c45f0082SYong Li     }
22913174e4dfSEd Tanous     if (rfAction == "PowerDown")
2292c45f0082SYong Li     {
2293c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2294c45f0082SYong Li     }
22953174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2296c45f0082SYong Li     {
2297c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2298c45f0082SYong Li     }
2299c45f0082SYong Li 
2300c45f0082SYong Li     return "";
2301c45f0082SYong Li }
2302c45f0082SYong Li 
2303c45f0082SYong Li /**
230451709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
230551709ffdSYong Li  *
230651709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
230751709ffdSYong Li  *
230851709ffdSYong Li  * @return None.
230951709ffdSYong Li  */
23108d1b46d7Szhanghch05 inline void
23118d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
231251709ffdSYong Li {
231351709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2314bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2315bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2316bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2317bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
23185e7e2dc5SEd Tanous         [aResp](const boost::system::error_code& ec,
2319b9d36b47SEd Tanous                 const dbus::utility::DBusPropertiesMap& properties) {
232051709ffdSYong Li         if (ec)
232151709ffdSYong Li         {
232251709ffdSYong Li             // watchdog service is stopped
232351709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
232451709ffdSYong Li             return;
232551709ffdSYong Li         }
232651709ffdSYong Li 
232751709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
232851709ffdSYong Li 
232951709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
233051709ffdSYong Li             aResp->res.jsonValue["HostWatchdogTimer"];
233151709ffdSYong Li 
233251709ffdSYong Li         // watchdog service is running/enabled
233351709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
233451709ffdSYong Li 
2335bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2336bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
233751709ffdSYong Li 
2338bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2339bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2340bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2341bc1d29deSKrzysztof Grobelny 
2342bc1d29deSKrzysztof Grobelny         if (!success)
234351709ffdSYong Li         {
234451709ffdSYong Li             messages::internalError(aResp->res);
2345601af5edSChicago Duan             return;
234651709ffdSYong Li         }
234751709ffdSYong Li 
2348bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
234951709ffdSYong Li         {
2350bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
235151709ffdSYong Li         }
235251709ffdSYong Li 
2353bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2354bc1d29deSKrzysztof Grobelny         {
2355bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
235651709ffdSYong Li             if (action.empty())
235751709ffdSYong Li             {
235851709ffdSYong Li                 messages::internalError(aResp->res);
2359601af5edSChicago Duan                 return;
236051709ffdSYong Li             }
236151709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
236251709ffdSYong Li         }
2363bc1d29deSKrzysztof Grobelny         });
236451709ffdSYong Li }
236551709ffdSYong Li 
236651709ffdSYong Li /**
2367c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2368c45f0082SYong Li  *
2369c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2370c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2371c45f0082SYong Li  *                       RF request.
2372c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2373c45f0082SYong Li  *
2374c45f0082SYong Li  * @return None.
2375c45f0082SYong Li  */
23768d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2377c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2378c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2379c45f0082SYong Li {
2380c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2381c45f0082SYong Li 
2382c45f0082SYong Li     if (wdtTimeOutAction)
2383c45f0082SYong Li     {
2384c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2385c45f0082SYong Li         // check if TimeOut Action is Valid
2386c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2387c45f0082SYong Li         {
2388c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2389c45f0082SYong Li                              << *wdtTimeOutAction;
2390c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2391c45f0082SYong Li                                              "TimeoutAction");
2392c45f0082SYong Li             return;
2393c45f0082SYong Li         }
2394c45f0082SYong Li 
2395c45f0082SYong Li         crow::connections::systemBus->async_method_call(
23965e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2397c45f0082SYong Li             if (ec)
2398c45f0082SYong Li             {
2399c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2400c45f0082SYong Li                 messages::internalError(aResp->res);
2401c45f0082SYong Li                 return;
2402c45f0082SYong Li             }
2403c45f0082SYong Li             },
2404c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2405c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2406c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2407c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2408168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2409c45f0082SYong Li     }
2410c45f0082SYong Li 
2411c45f0082SYong Li     if (wdtEnable)
2412c45f0082SYong Li     {
2413c45f0082SYong Li         crow::connections::systemBus->async_method_call(
24145e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec) {
2415c45f0082SYong Li             if (ec)
2416c45f0082SYong Li             {
2417c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2418c45f0082SYong Li                 messages::internalError(aResp->res);
2419c45f0082SYong Li                 return;
2420c45f0082SYong Li             }
2421c45f0082SYong Li             },
2422c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2423c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2424c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2425c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2426168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2427c45f0082SYong Li     }
2428c45f0082SYong Li }
2429c45f0082SYong Li 
243037bbf98cSChris Cain /**
243137bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
243237bbf98cSChris Cain  *
243337bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
243437bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
243537bbf98cSChris Cain  *
243637bbf98cSChris Cain  * @return true if successful
243737bbf98cSChris Cain  */
24381e5b7c88SJiaqing Zhao inline bool
24391e5b7c88SJiaqing Zhao     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
24401e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
244137bbf98cSChris Cain {
2442bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2443bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2444bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2445bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2446bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2447bc1d29deSKrzysztof Grobelny 
2448bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2449bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
24502661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
24512661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
24522661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2453bc1d29deSKrzysztof Grobelny 
2454bc1d29deSKrzysztof Grobelny     if (!success)
245537bbf98cSChris Cain     {
245637bbf98cSChris Cain         return false;
245737bbf98cSChris Cain     }
2458bc1d29deSKrzysztof Grobelny 
2459bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
246037bbf98cSChris Cain     {
2461bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
246237bbf98cSChris Cain     }
2463bc1d29deSKrzysztof Grobelny 
2464bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
246537bbf98cSChris Cain     {
2466bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2467bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
246837bbf98cSChris Cain     }
2469bc1d29deSKrzysztof Grobelny 
2470bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2471bc1d29deSKrzysztof Grobelny     {
2472bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
247337bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
247437bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
247537bbf98cSChris Cain                 .count();
247637bbf98cSChris Cain     }
2477bc1d29deSKrzysztof Grobelny 
2478bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
247937bbf98cSChris Cain     {
2480bc1d29deSKrzysztof Grobelny         aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2481bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
248237bbf98cSChris Cain     }
2483bc1d29deSKrzysztof Grobelny 
2484bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
248537bbf98cSChris Cain     {
2486bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
248737bbf98cSChris Cain         aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
248837bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
248937bbf98cSChris Cain                 .count();
249037bbf98cSChris Cain     }
249137bbf98cSChris Cain 
249237bbf98cSChris Cain     return true;
249337bbf98cSChris Cain }
249437bbf98cSChris Cain 
249537bbf98cSChris Cain /**
249637bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
249737bbf98cSChris Cain  *
249837bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
249937bbf98cSChris Cain  *
250037bbf98cSChris Cain  * @return None.
250137bbf98cSChris Cain  */
250237bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
250337bbf98cSChris Cain {
250437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
250537bbf98cSChris Cain 
250637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2507e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2508e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2509e99073f5SGeorge Liu     dbus::utility::getSubTree(
2510e99073f5SGeorge Liu         "/", 0, interfaces,
2511e99073f5SGeorge Liu         [aResp](const boost::system::error_code& ec,
2512b9d36b47SEd Tanous                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
251337bbf98cSChris Cain         if (ec)
251437bbf98cSChris Cain         {
251537bbf98cSChris Cain             BMCWEB_LOG_DEBUG
251637bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
251737bbf98cSChris Cain                 << ec;
251837bbf98cSChris Cain             messages::internalError(aResp->res);
251937bbf98cSChris Cain             return;
252037bbf98cSChris Cain         }
252137bbf98cSChris Cain         if (subtree.empty())
252237bbf98cSChris Cain         {
252337bbf98cSChris Cain             // This is an optional interface so just return
252437bbf98cSChris Cain             // if there is no instance found
252537bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
252637bbf98cSChris Cain             return;
252737bbf98cSChris Cain         }
252837bbf98cSChris Cain         if (subtree.size() > 1)
252937bbf98cSChris Cain         {
253037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
253137bbf98cSChris Cain             // is an error
253237bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
253337bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
253437bbf98cSChris Cain                              << subtree.size();
253537bbf98cSChris Cain             messages::internalError(aResp->res);
253637bbf98cSChris Cain             return;
253737bbf98cSChris Cain         }
253837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
253937bbf98cSChris Cain         {
254037bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
254137bbf98cSChris Cain             messages::internalError(aResp->res);
254237bbf98cSChris Cain             return;
254337bbf98cSChris Cain         }
254437bbf98cSChris Cain         const std::string& path = subtree[0].first;
254537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
254637bbf98cSChris Cain         if (service.empty())
254737bbf98cSChris Cain         {
2548002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
254937bbf98cSChris Cain             messages::internalError(aResp->res);
255037bbf98cSChris Cain             return;
255137bbf98cSChris Cain         }
255237bbf98cSChris Cain 
255337bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2554bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2555bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2556bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
25575e7e2dc5SEd Tanous             [aResp](const boost::system::error_code& ec2,
25581e5b7c88SJiaqing Zhao                     const dbus::utility::DBusPropertiesMap& properties) {
25598a592810SEd Tanous             if (ec2)
256037bbf98cSChris Cain             {
256137bbf98cSChris Cain                 BMCWEB_LOG_ERROR
25628a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
256337bbf98cSChris Cain                 messages::internalError(aResp->res);
256437bbf98cSChris Cain                 return;
256537bbf98cSChris Cain             }
256637bbf98cSChris Cain 
2567e05aec50SEd Tanous             if (!parseIpsProperties(aResp, properties))
256837bbf98cSChris Cain             {
256937bbf98cSChris Cain                 messages::internalError(aResp->res);
257037bbf98cSChris Cain                 return;
257137bbf98cSChris Cain             }
2572bc1d29deSKrzysztof Grobelny             });
2573e99073f5SGeorge Liu         });
257437bbf98cSChris Cain 
257537bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
257637bbf98cSChris Cain }
257737bbf98cSChris Cain 
257837bbf98cSChris Cain /**
257937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
258037bbf98cSChris Cain  *
258137bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
258237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
258337bbf98cSChris Cain  *                       RF request.
258437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
258537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
258637bbf98cSChris Cain  * before entering idle state.
258737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
258837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
258937bbf98cSChris Cain  * before exiting idle state
259037bbf98cSChris Cain  *
259137bbf98cSChris Cain  * @return None.
259237bbf98cSChris Cain  */
259337bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
259437bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
259537bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
259637bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
259737bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
259837bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
259937bbf98cSChris Cain {
260037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
260137bbf98cSChris Cain 
260237bbf98cSChris Cain     // Get IdlePowerSaver object path:
2603e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2604e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2605e99073f5SGeorge Liu     dbus::utility::getSubTree(
2606e99073f5SGeorge Liu         "/", 0, interfaces,
260737bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2608e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2609b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
261037bbf98cSChris Cain         if (ec)
261137bbf98cSChris Cain         {
261237bbf98cSChris Cain             BMCWEB_LOG_DEBUG
261337bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
261437bbf98cSChris Cain                 << ec;
261537bbf98cSChris Cain             messages::internalError(aResp->res);
261637bbf98cSChris Cain             return;
261737bbf98cSChris Cain         }
261837bbf98cSChris Cain         if (subtree.empty())
261937bbf98cSChris Cain         {
262037bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
262137bbf98cSChris Cain             messages::resourceNotFound(aResp->res, "ComputerSystem",
262237bbf98cSChris Cain                                        "IdlePowerSaver");
262337bbf98cSChris Cain             return;
262437bbf98cSChris Cain         }
262537bbf98cSChris Cain         if (subtree.size() > 1)
262637bbf98cSChris Cain         {
262737bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
262837bbf98cSChris Cain             // is an error
26290fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
26300fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
263137bbf98cSChris Cain                 << subtree.size();
263237bbf98cSChris Cain             messages::internalError(aResp->res);
263337bbf98cSChris Cain             return;
263437bbf98cSChris Cain         }
263537bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
263637bbf98cSChris Cain         {
263737bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
263837bbf98cSChris Cain             messages::internalError(aResp->res);
263937bbf98cSChris Cain             return;
264037bbf98cSChris Cain         }
264137bbf98cSChris Cain         const std::string& path = subtree[0].first;
264237bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
264337bbf98cSChris Cain         if (service.empty())
264437bbf98cSChris Cain         {
2645002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
264637bbf98cSChris Cain             messages::internalError(aResp->res);
264737bbf98cSChris Cain             return;
264837bbf98cSChris Cain         }
264937bbf98cSChris Cain 
265037bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
265137bbf98cSChris Cain         // need to be updated
265237bbf98cSChris Cain 
265337bbf98cSChris Cain         if (ipsEnable)
265437bbf98cSChris Cain         {
265537bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26565e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26578a592810SEd Tanous                 if (ec2)
265837bbf98cSChris Cain                 {
26598a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
266037bbf98cSChris Cain                     messages::internalError(aResp->res);
266137bbf98cSChris Cain                     return;
266237bbf98cSChris Cain                 }
266337bbf98cSChris Cain                 },
266437bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
2665002d39b4SEd Tanous                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2666002d39b4SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnable));
266737bbf98cSChris Cain         }
266837bbf98cSChris Cain         if (ipsEnterUtil)
266937bbf98cSChris Cain         {
267037bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26715e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26728a592810SEd Tanous                 if (ec2)
267337bbf98cSChris Cain                 {
26748a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
267537bbf98cSChris Cain                     messages::internalError(aResp->res);
267637bbf98cSChris Cain                     return;
267737bbf98cSChris Cain                 }
267837bbf98cSChris Cain                 },
267937bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
268037bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
268137bbf98cSChris Cain                 "EnterUtilizationPercent",
2682168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsEnterUtil));
268337bbf98cSChris Cain         }
268437bbf98cSChris Cain         if (ipsEnterTime)
268537bbf98cSChris Cain         {
268637bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
268737bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
268837bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
26895e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
26908a592810SEd Tanous                 if (ec2)
269137bbf98cSChris Cain                 {
26928a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
269337bbf98cSChris Cain                     messages::internalError(aResp->res);
269437bbf98cSChris Cain                     return;
269537bbf98cSChris Cain                 }
269637bbf98cSChris Cain                 },
269737bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
269837bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2699168e20c1SEd Tanous                 "EnterDwellTime",
2700168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
270137bbf98cSChris Cain         }
270237bbf98cSChris Cain         if (ipsExitUtil)
270337bbf98cSChris Cain         {
270437bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27055e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27068a592810SEd Tanous                 if (ec2)
270737bbf98cSChris Cain                 {
27088a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
270937bbf98cSChris Cain                     messages::internalError(aResp->res);
271037bbf98cSChris Cain                     return;
271137bbf98cSChris Cain                 }
271237bbf98cSChris Cain                 },
271337bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
271437bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
271537bbf98cSChris Cain                 "ExitUtilizationPercent",
2716168e20c1SEd Tanous                 dbus::utility::DbusVariantType(*ipsExitUtil));
271737bbf98cSChris Cain         }
271837bbf98cSChris Cain         if (ipsExitTime)
271937bbf98cSChris Cain         {
272037bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
272137bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
272237bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
27235e7e2dc5SEd Tanous                 [aResp](const boost::system::error_code& ec2) {
27248a592810SEd Tanous                 if (ec2)
272537bbf98cSChris Cain                 {
27268a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
272737bbf98cSChris Cain                     messages::internalError(aResp->res);
272837bbf98cSChris Cain                     return;
272937bbf98cSChris Cain                 }
273037bbf98cSChris Cain                 },
273137bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
273237bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2733168e20c1SEd Tanous                 "ExitDwellTime",
2734168e20c1SEd Tanous                 dbus::utility::DbusVariantType(timeMilliseconds));
273537bbf98cSChris Cain         }
2736e99073f5SGeorge Liu         });
273737bbf98cSChris Cain 
273837bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
273937bbf98cSChris Cain }
274037bbf98cSChris Cain 
2741dd60b9edSEd Tanous inline void handleComputerSystemHead(
2742dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2743dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2744dd60b9edSEd Tanous {
2745dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2746dd60b9edSEd Tanous     {
2747dd60b9edSEd Tanous         return;
2748dd60b9edSEd Tanous     }
2749dd60b9edSEd Tanous     asyncResp->res.addHeader(
2750dd60b9edSEd Tanous         boost::beast::http::field::link,
2751dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2752dd60b9edSEd Tanous }
2753dd60b9edSEd Tanous 
2754c45f0082SYong Li /**
2755c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2756c5b2abe0SLewanczyk, Dawid  * Schema
2757c5b2abe0SLewanczyk, Dawid  */
27587e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
27591abe55efSEd Tanous {
27607e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2761dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
2762dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
2763dd60b9edSEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
2764dd60b9edSEd Tanous 
2765dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2766ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
27677e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2768f4c99e70SEd Tanous             [&app](const crow::Request& req,
27697e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27703ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2771f4c99e70SEd Tanous         {
2772f4c99e70SEd Tanous             return;
2773f4c99e70SEd Tanous         }
2774dd60b9edSEd Tanous 
2775dd60b9edSEd Tanous         asyncResp->res.addHeader(
2776dd60b9edSEd Tanous             boost::beast::http::field::link,
2777dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
27788d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
27790f74e643SEd Tanous             "#ComputerSystemCollection.ComputerSystemCollection";
27808d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
27818d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2782462023adSSunitha Harish 
27831e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
2784002d39b4SEd Tanous             *crow::connections::systemBus, "xyz.openbmc_project.Settings",
27851e1e598dSJonathan Doman             "/xyz/openbmc_project/network/hypervisor",
2786002d39b4SEd Tanous             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
27875e7e2dc5SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27881e1e598dSJonathan Doman                         const std::string& /*hostName*/) {
2789002d39b4SEd Tanous             nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27902c70f800SEd Tanous             ifaceArray = nlohmann::json::array();
2791002d39b4SEd Tanous             auto& count = asyncResp->res.jsonValue["Members@odata.count"];
27921476687dSEd Tanous 
27931476687dSEd Tanous             nlohmann::json::object_t system;
27941476687dSEd Tanous             system["@odata.id"] = "/redfish/v1/Systems/system";
2795b2ba3072SPatrick Williams             ifaceArray.emplace_back(std::move(system));
279694bda602STim Lee             count = ifaceArray.size();
27978a592810SEd Tanous             if (!ec2)
2798462023adSSunitha Harish             {
2799462023adSSunitha Harish                 BMCWEB_LOG_DEBUG << "Hypervisor is available";
28001476687dSEd Tanous                 nlohmann::json::object_t hypervisor;
2801002d39b4SEd Tanous                 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2802b2ba3072SPatrick Williams                 ifaceArray.emplace_back(std::move(hypervisor));
28032c70f800SEd Tanous                 count = ifaceArray.size();
2804cb13a392SEd Tanous             }
28051e1e598dSJonathan Doman             });
28067e860f15SJohn Edward Broadbent         });
2807c5b2abe0SLewanczyk, Dawid }
28087e860f15SJohn Edward Broadbent 
28097e860f15SJohn Edward Broadbent /**
28107e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28117e860f15SJohn Edward Broadbent  */
28124f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28137e860f15SJohn Edward Broadbent {
281489492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
281589492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
281689492a15SPatrick Williams     constexpr const char* interfaceName =
28177e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
281889492a15SPatrick Williams     constexpr const char* method = "NMI";
28197e860f15SJohn Edward Broadbent 
28207e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28215e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28227e860f15SJohn Edward Broadbent         if (ec)
28237e860f15SJohn Edward Broadbent         {
28247e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28257e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28267e860f15SJohn Edward Broadbent             return;
28277e860f15SJohn Edward Broadbent         }
28287e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28297e860f15SJohn Edward Broadbent         },
28307e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28317e860f15SJohn Edward Broadbent }
2832c5b2abe0SLewanczyk, Dawid 
2833c5b2abe0SLewanczyk, Dawid /**
2834cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2835cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2836cc340dd9SEd Tanous  */
28377e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2838cc340dd9SEd Tanous {
2839cc340dd9SEd Tanous     /**
2840cc340dd9SEd Tanous      * Function handles POST method request.
2841cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2842cc340dd9SEd Tanous      */
28437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
28447e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2845ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
2846002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
2847002d39b4SEd Tanous             [&app](const crow::Request& req,
28487e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28493ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
285045ca1b86SEd Tanous         {
285145ca1b86SEd Tanous             return;
285245ca1b86SEd Tanous         }
28539712f8acSEd Tanous         std::string resetType;
285415ed6780SWilly Tu         if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
28557e860f15SJohn Edward Broadbent                                        resetType))
2856cc340dd9SEd Tanous         {
2857cc340dd9SEd Tanous             return;
2858cc340dd9SEd Tanous         }
2859cc340dd9SEd Tanous 
2860d22c8396SJason M. Bills         // Get the command and host vs. chassis
2861cc340dd9SEd Tanous         std::string command;
2862543f4400SEd Tanous         bool hostCommand = true;
2863d4d25793SEd Tanous         if ((resetType == "On") || (resetType == "ForceOn"))
2864cc340dd9SEd Tanous         {
2865cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
2866d22c8396SJason M. Bills             hostCommand = true;
2867d22c8396SJason M. Bills         }
2868d22c8396SJason M. Bills         else if (resetType == "ForceOff")
2869d22c8396SJason M. Bills         {
2870d22c8396SJason M. Bills             command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2871d22c8396SJason M. Bills             hostCommand = false;
2872d22c8396SJason M. Bills         }
2873d22c8396SJason M. Bills         else if (resetType == "ForceRestart")
2874d22c8396SJason M. Bills         {
287586a0851aSJason M. Bills             command =
287686a0851aSJason M. Bills                 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
287786a0851aSJason M. Bills             hostCommand = true;
2878cc340dd9SEd Tanous         }
28799712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
2880cc340dd9SEd Tanous         {
2881cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
2882d22c8396SJason M. Bills             hostCommand = true;
2883cc340dd9SEd Tanous         }
28849712f8acSEd Tanous         else if (resetType == "GracefulRestart")
2885cc340dd9SEd Tanous         {
28860fda0f12SGeorge Liu             command =
28870fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2888d22c8396SJason M. Bills             hostCommand = true;
2889d22c8396SJason M. Bills         }
2890d22c8396SJason M. Bills         else if (resetType == "PowerCycle")
2891d22c8396SJason M. Bills         {
289286a0851aSJason M. Bills             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
289386a0851aSJason M. Bills             hostCommand = true;
2894cc340dd9SEd Tanous         }
2895bfd5b826SLakshminarayana R. Kammath         else if (resetType == "Nmi")
2896bfd5b826SLakshminarayana R. Kammath         {
2897bfd5b826SLakshminarayana R. Kammath             doNMI(asyncResp);
2898bfd5b826SLakshminarayana R. Kammath             return;
2899bfd5b826SLakshminarayana R. Kammath         }
2900cc340dd9SEd Tanous         else
2901cc340dd9SEd Tanous         {
29028d1b46d7Szhanghch05             messages::actionParameterUnknown(asyncResp->res, "Reset",
29038d1b46d7Szhanghch05                                              resetType);
2904cc340dd9SEd Tanous             return;
2905cc340dd9SEd Tanous         }
2906cc340dd9SEd Tanous 
2907d22c8396SJason M. Bills         if (hostCommand)
2908d22c8396SJason M. Bills         {
2909cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
29105e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2911cc340dd9SEd Tanous                 if (ec)
2912cc340dd9SEd Tanous                 {
2913cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2914002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2915d22c8396SJason M. Bills                     {
2916d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2917d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2918d22c8396SJason M. Bills                     }
2919d22c8396SJason M. Bills                     else
2920d22c8396SJason M. Bills                     {
2921f12894f8SJason M. Bills                         messages::internalError(asyncResp->res);
2922d22c8396SJason M. Bills                     }
2923cc340dd9SEd Tanous                     return;
2924cc340dd9SEd Tanous                 }
2925f12894f8SJason M. Bills                 messages::success(asyncResp->res);
2926cc340dd9SEd Tanous                 },
2927cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Host",
2928cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/host0",
2929cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
29309712f8acSEd Tanous                 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2931168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2932cc340dd9SEd Tanous         }
2933d22c8396SJason M. Bills         else
2934d22c8396SJason M. Bills         {
2935d22c8396SJason M. Bills             crow::connections::systemBus->async_method_call(
29365e7e2dc5SEd Tanous                 [asyncResp, resetType](const boost::system::error_code& ec) {
2937d22c8396SJason M. Bills                 if (ec)
2938d22c8396SJason M. Bills                 {
2939d22c8396SJason M. Bills                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2940002d39b4SEd Tanous                     if (ec.value() == boost::asio::error::invalid_argument)
2941d22c8396SJason M. Bills                     {
2942d22c8396SJason M. Bills                         messages::actionParameterNotSupported(
2943d22c8396SJason M. Bills                             asyncResp->res, resetType, "Reset");
2944d22c8396SJason M. Bills                     }
2945d22c8396SJason M. Bills                     else
2946d22c8396SJason M. Bills                     {
2947d22c8396SJason M. Bills                         messages::internalError(asyncResp->res);
2948d22c8396SJason M. Bills                     }
2949d22c8396SJason M. Bills                     return;
2950d22c8396SJason M. Bills                 }
2951d22c8396SJason M. Bills                 messages::success(asyncResp->res);
2952d22c8396SJason M. Bills                 },
2953d22c8396SJason M. Bills                 "xyz.openbmc_project.State.Chassis",
2954d22c8396SJason M. Bills                 "/xyz/openbmc_project/state/chassis0",
2955d22c8396SJason M. Bills                 "org.freedesktop.DBus.Properties", "Set",
2956002d39b4SEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2957168e20c1SEd Tanous                 dbus::utility::DbusVariantType{command});
2958d22c8396SJason M. Bills         }
29597e860f15SJohn Edward Broadbent         });
2960d22c8396SJason M. Bills }
2961cc340dd9SEd Tanous 
296238c8a6f2SEd Tanous inline void handleComputerSystemCollectionHead(
2963dd60b9edSEd Tanous     App& app, const crow::Request& req,
2964dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2965dd60b9edSEd Tanous {
2966dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2967dd60b9edSEd Tanous     {
2968dd60b9edSEd Tanous         return;
2969dd60b9edSEd Tanous     }
2970dd60b9edSEd Tanous 
2971dd60b9edSEd Tanous     asyncResp->res.addHeader(
2972dd60b9edSEd Tanous         boost::beast::http::field::link,
2973dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2974dd60b9edSEd Tanous }
2975dd60b9edSEd Tanous 
29765c3e9272SAbhishek Patel inline void afterPortRequest(
29775c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29785c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29795c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29805c3e9272SAbhishek Patel {
29815c3e9272SAbhishek Patel     if (ec)
29825c3e9272SAbhishek Patel     {
29835c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29845c3e9272SAbhishek Patel         return;
29855c3e9272SAbhishek Patel     }
29865c3e9272SAbhishek Patel     for (const auto& data : socketData)
29875c3e9272SAbhishek Patel     {
29885c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29895c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29905c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29915c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29925c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29935c3e9272SAbhishek Patel         // need to retrieve port number for
29945c3e9272SAbhishek Patel         // obmc-console-ssh service
29955c3e9272SAbhishek Patel         if (protocolName == "SSH")
29965c3e9272SAbhishek Patel         {
29975c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
299881c4e330SEd Tanous                                           const boost::system::error_code& ec1,
29995c3e9272SAbhishek Patel                                           int portNumber) {
30005c3e9272SAbhishek Patel                 if (ec1)
30015c3e9272SAbhishek Patel                 {
30025c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
30035c3e9272SAbhishek Patel                     return;
30045c3e9272SAbhishek Patel                 }
30055c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
30065c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
30075c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
30085c3e9272SAbhishek Patel             });
30095c3e9272SAbhishek Patel         }
30105c3e9272SAbhishek Patel     }
30115c3e9272SAbhishek Patel }
3012cc340dd9SEd Tanous /**
30136617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
3014c5b2abe0SLewanczyk, Dawid  */
30157e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
30161abe55efSEd Tanous {
3017dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3018dd60b9edSEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3019dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(
3020dd60b9edSEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3021c5b2abe0SLewanczyk, Dawid     /**
3022c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3023c5b2abe0SLewanczyk, Dawid      */
302422d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3025ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3026002d39b4SEd Tanous         .methods(boost::beast::http::verb::get)(
3027002d39b4SEd Tanous             [&app](const crow::Request& req,
302822d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
302922d268cbSEd Tanous                    const std::string& systemName) {
30303ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
303145ca1b86SEd Tanous         {
303245ca1b86SEd Tanous             return;
303345ca1b86SEd Tanous         }
3034746b56f3SAsmitha Karunanithi 
3035746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3036746b56f3SAsmitha Karunanithi         {
3037746b56f3SAsmitha Karunanithi             handleHypervisorSystemGet(asyncResp);
3038746b56f3SAsmitha Karunanithi             return;
3039746b56f3SAsmitha Karunanithi         }
3040746b56f3SAsmitha Karunanithi 
304122d268cbSEd Tanous         if (systemName != "system")
304222d268cbSEd Tanous         {
304322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
304422d268cbSEd Tanous                                        systemName);
304522d268cbSEd Tanous             return;
304622d268cbSEd Tanous         }
3047dd60b9edSEd Tanous         asyncResp->res.addHeader(
3048dd60b9edSEd Tanous             boost::beast::http::field::link,
3049dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30508d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
305137bbf98cSChris Cain             "#ComputerSystem.v1_16_0.ComputerSystem";
30528d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "system";
30538d1b46d7Szhanghch05         asyncResp->res.jsonValue["Id"] = "system";
30548d1b46d7Szhanghch05         asyncResp->res.jsonValue["SystemType"] = "Physical";
30558d1b46d7Szhanghch05         asyncResp->res.jsonValue["Description"] = "Computer System";
30568d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
30578d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
30588d1b46d7Szhanghch05             "Disabled";
30598d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
30608d1b46d7Szhanghch05             "Disabled";
3061cf0e004cSNinad Palsule         asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3062cf0e004cSNinad Palsule             uint64_t(0);
3063002d39b4SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
306404a258f4SEd Tanous 
30651476687dSEd Tanous         asyncResp->res.jsonValue["Processors"]["@odata.id"] =
30661476687dSEd Tanous             "/redfish/v1/Systems/system/Processors";
30671476687dSEd Tanous         asyncResp->res.jsonValue["Memory"]["@odata.id"] =
30681476687dSEd Tanous             "/redfish/v1/Systems/system/Memory";
30691476687dSEd Tanous         asyncResp->res.jsonValue["Storage"]["@odata.id"] =
30701476687dSEd Tanous             "/redfish/v1/Systems/system/Storage";
30713179105bSSunny Srivastava         asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
30723179105bSSunny Srivastava             "/redfish/v1/Systems/system/FabricAdapters";
3073029573d4SEd Tanous 
3074002d39b4SEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
30751476687dSEd Tanous             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
30761476687dSEd Tanous         asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
30771476687dSEd Tanous                                 ["@Redfish.ActionInfo"] =
30781476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
3079c5b2abe0SLewanczyk, Dawid 
30801476687dSEd Tanous         asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
30811476687dSEd Tanous             "/redfish/v1/Systems/system/LogServices";
30821476687dSEd Tanous         asyncResp->res.jsonValue["Bios"]["@odata.id"] =
30831476687dSEd Tanous             "/redfish/v1/Systems/system/Bios";
3084c4bf6374SJason M. Bills 
30851476687dSEd Tanous         nlohmann::json::array_t managedBy;
30861476687dSEd Tanous         nlohmann::json& manager = managedBy.emplace_back();
30871476687dSEd Tanous         manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3088002d39b4SEd Tanous         asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
30891476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
30901476687dSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
30910e8ac5e7SGunnar Mills 
30920e8ac5e7SGunnar Mills         // Fill in SerialConsole info
3093002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3094002d39b4SEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3095002d39b4SEd Tanous             true;
30961476687dSEd Tanous 
30971476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
30981476687dSEd Tanous             true;
30991476687dSEd Tanous         asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
31001476687dSEd Tanous         asyncResp->res
31011476687dSEd Tanous             .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
31021476687dSEd Tanous             "Press ~. to exit console";
31035c3e9272SAbhishek Patel         getPortStatusAndPath(std::span{protocolToDBusForSystems},
31045c3e9272SAbhishek Patel                              std::bind_front(afterPortRequest, asyncResp));
31050e8ac5e7SGunnar Mills 
31060e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
31070e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3108002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3109002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3110002d39b4SEd Tanous             4;
3111613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3112613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
31131476687dSEd Tanous 
31140e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
3115*13451e39SWilly Tu 
3116*13451e39SWilly Tu         auto health = std::make_shared<HealthPopulate>(asyncResp);
3117*13451e39SWilly Tu         if constexpr (bmcwebEnableHealthPopulate)
3118*13451e39SWilly Tu         {
31197a1dbc48SGeorge Liu             constexpr std::array<std::string_view, 4> inventoryForSystems{
3120b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
31212ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
3122e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
3123e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
3124b49ac873SJames Feist 
31257a1dbc48SGeorge Liu             dbus::utility::getSubTreePaths(
31267a1dbc48SGeorge Liu                 "/", 0, inventoryForSystems,
31277a1dbc48SGeorge Liu                 [health](const boost::system::error_code& ec,
3128914e2d5dSEd Tanous                          const std::vector<std::string>& resp) {
3129b49ac873SJames Feist                 if (ec)
3130b49ac873SJames Feist                 {
3131b49ac873SJames Feist                     // no inventory
3132b49ac873SJames Feist                     return;
3133b49ac873SJames Feist                 }
3134b49ac873SJames Feist 
3135914e2d5dSEd Tanous                 health->inventory = resp;
31367a1dbc48SGeorge Liu                 });
3137b49ac873SJames Feist             health->populate();
3138*13451e39SWilly Tu         }
3139b49ac873SJames Feist 
3140002d39b4SEd Tanous         getMainChassisId(asyncResp,
3141002d39b4SEd Tanous                          [](const std::string& chassisId,
31428d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3143b2c7e208SEd Tanous             nlohmann::json::array_t chassisArray;
3144b2c7e208SEd Tanous             nlohmann::json& chassis = chassisArray.emplace_back();
3145ef4c65b7SEd Tanous             chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3146ef4c65b7SEd Tanous                                                        chassisId);
3147002d39b4SEd Tanous             aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3148c5d03ff4SJennifer Lee         });
3149a3002228SAppaRao Puli 
31509f8bfa7cSGunnar Mills         getLocationIndicatorActive(asyncResp);
31519f8bfa7cSGunnar Mills         // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3152a3002228SAppaRao Puli         getIndicatorLedState(asyncResp);
31535bc2dc8eSJames Feist         getComputerSystem(asyncResp, health);
31546c34de48SEd Tanous         getHostState(asyncResp);
3155491d8ee7SSantosh Puranik         getBootProperties(asyncResp);
3156978b8803SAndrew Geissler         getBootProgress(asyncResp);
3157b6d5d45cSHieu Huynh         getBootProgressLastStateTime(asyncResp);
3158adbe192aSJason M. Bills         getPCIeDeviceList(asyncResp, "PCIeDevices");
315951709ffdSYong Li         getHostWatchdogTimer(asyncResp);
3160c6a620f2SGeorge Liu         getPowerRestorePolicy(asyncResp);
3161797d5daeSCorey Hardesty         getAutomaticRetryPolicy(asyncResp);
3162c0557e1aSGunnar Mills         getLastResetTime(asyncResp);
3163a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3164a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
3165a6349918SAppaRao Puli #endif
31661981771bSAli Ahmed         getTrustedModuleRequiredToBoot(asyncResp);
31673a2d0424SChris Cain         getPowerMode(asyncResp);
316837bbf98cSChris Cain         getIdlePowerSaver(asyncResp);
31697e860f15SJohn Edward Broadbent         });
3170550a6bf8SJiaqing Zhao 
317122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3172ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
31737e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
317445ca1b86SEd Tanous             [&app](const crow::Request& req,
317522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
317622d268cbSEd Tanous                    const std::string& systemName) {
31773ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
317845ca1b86SEd Tanous         {
317945ca1b86SEd Tanous             return;
318045ca1b86SEd Tanous         }
318122d268cbSEd Tanous         if (systemName != "system")
318222d268cbSEd Tanous         {
318322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
318422d268cbSEd Tanous                                        systemName);
318522d268cbSEd Tanous             return;
318622d268cbSEd Tanous         }
318722d268cbSEd Tanous 
3188dd60b9edSEd Tanous         asyncResp->res.addHeader(
3189dd60b9edSEd Tanous             boost::beast::http::field::link,
3190dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3191dd60b9edSEd Tanous 
31929f8bfa7cSGunnar Mills         std::optional<bool> locationIndicatorActive;
3193cde19e5fSSantosh Puranik         std::optional<std::string> indicatorLed;
319498e386ecSGunnar Mills         std::optional<std::string> assetTag;
3195c6a620f2SGeorge Liu         std::optional<std::string> powerRestorePolicy;
31963a2d0424SChris Cain         std::optional<std::string> powerMode;
3197550a6bf8SJiaqing Zhao         std::optional<bool> wdtEnable;
3198550a6bf8SJiaqing Zhao         std::optional<std::string> wdtTimeOutAction;
3199550a6bf8SJiaqing Zhao         std::optional<std::string> bootSource;
3200550a6bf8SJiaqing Zhao         std::optional<std::string> bootType;
3201550a6bf8SJiaqing Zhao         std::optional<std::string> bootEnable;
3202550a6bf8SJiaqing Zhao         std::optional<std::string> bootAutomaticRetry;
3203797d5daeSCorey Hardesty         std::optional<uint32_t> bootAutomaticRetryAttempts;
3204550a6bf8SJiaqing Zhao         std::optional<bool> bootTrustedModuleRequired;
3205550a6bf8SJiaqing Zhao         std::optional<bool> ipsEnable;
3206550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsEnterUtil;
3207550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsEnterTime;
3208550a6bf8SJiaqing Zhao         std::optional<uint8_t> ipsExitUtil;
3209550a6bf8SJiaqing Zhao         std::optional<uint64_t> ipsExitTime;
3210550a6bf8SJiaqing Zhao 
3211550a6bf8SJiaqing Zhao         // clang-format off
321215ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3213550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3214550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
32157e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3216550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3217550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3218550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3219550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3220550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3221550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3222550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3223550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3224550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3225797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3226550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3227550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3228550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3229550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3230550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3231550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
32326617338dSEd Tanous                 {
32336617338dSEd Tanous                     return;
32346617338dSEd Tanous                 }
3235550a6bf8SJiaqing Zhao         // clang-format on
3236491d8ee7SSantosh Puranik 
32378d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
3238c45f0082SYong Li 
323998e386ecSGunnar Mills         if (assetTag)
324098e386ecSGunnar Mills         {
324198e386ecSGunnar Mills             setAssetTag(asyncResp, *assetTag);
324298e386ecSGunnar Mills         }
324398e386ecSGunnar Mills 
3244550a6bf8SJiaqing Zhao         if (wdtEnable || wdtTimeOutAction)
3245c45f0082SYong Li         {
3246f23b7296SEd Tanous             setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3247c45f0082SYong Li         }
3248c45f0082SYong Li 
3249cd9a4666SKonstantin Aladyshev         if (bootSource || bootType || bootEnable)
325069f35306SGunnar Mills         {
3251002d39b4SEd Tanous             setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3252491d8ee7SSantosh Puranik         }
3253550a6bf8SJiaqing Zhao         if (bootAutomaticRetry)
325469f35306SGunnar Mills         {
3255550a6bf8SJiaqing Zhao             setAutomaticRetry(asyncResp, *bootAutomaticRetry);
325669f35306SGunnar Mills         }
3257ac7e1e0bSAli Ahmed 
3258797d5daeSCorey Hardesty         if (bootAutomaticRetryAttempts)
3259797d5daeSCorey Hardesty         {
3260797d5daeSCorey Hardesty             setAutomaticRetryAttempts(asyncResp,
3261797d5daeSCorey Hardesty                                       bootAutomaticRetryAttempts.value());
3262797d5daeSCorey Hardesty         }
3263797d5daeSCorey Hardesty 
3264550a6bf8SJiaqing Zhao         if (bootTrustedModuleRequired)
3265ac7e1e0bSAli Ahmed         {
3266550a6bf8SJiaqing Zhao             setTrustedModuleRequiredToBoot(asyncResp,
3267550a6bf8SJiaqing Zhao                                            *bootTrustedModuleRequired);
326869f35306SGunnar Mills         }
3269265c1602SJohnathan Mantey 
32709f8bfa7cSGunnar Mills         if (locationIndicatorActive)
32719f8bfa7cSGunnar Mills         {
3272002d39b4SEd Tanous             setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32739f8bfa7cSGunnar Mills         }
32749f8bfa7cSGunnar Mills 
32757e860f15SJohn Edward Broadbent         // TODO (Gunnar): Remove IndicatorLED after enough time has
32767e860f15SJohn Edward Broadbent         // passed
32779712f8acSEd Tanous         if (indicatorLed)
32786617338dSEd Tanous         {
3279f23b7296SEd Tanous             setIndicatorLedState(asyncResp, *indicatorLed);
3280002d39b4SEd Tanous             asyncResp->res.addHeader(boost::beast::http::field::warning,
3281d6aa0093SGunnar Mills                                      "299 - \"IndicatorLED is deprecated. Use "
3282d6aa0093SGunnar Mills                                      "LocationIndicatorActive instead.\"");
32836617338dSEd Tanous         }
3284c6a620f2SGeorge Liu 
3285c6a620f2SGeorge Liu         if (powerRestorePolicy)
3286c6a620f2SGeorge Liu         {
32874e69c904SGunnar Mills             setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3288c6a620f2SGeorge Liu         }
32893a2d0424SChris Cain 
32903a2d0424SChris Cain         if (powerMode)
32913a2d0424SChris Cain         {
32923a2d0424SChris Cain             setPowerMode(asyncResp, *powerMode);
32933a2d0424SChris Cain         }
329437bbf98cSChris Cain 
3295550a6bf8SJiaqing Zhao         if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3296550a6bf8SJiaqing Zhao             ipsExitTime)
329737bbf98cSChris Cain         {
3298002d39b4SEd Tanous             setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3299002d39b4SEd Tanous                               ipsExitUtil, ipsExitTime);
330037bbf98cSChris Cain         }
33017e860f15SJohn Edward Broadbent         });
3302c5b2abe0SLewanczyk, Dawid }
33031cb1a9e6SAppaRao Puli 
330438c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3305dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
3306dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3307dd60b9edSEd Tanous {
3308dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3309dd60b9edSEd Tanous     {
3310dd60b9edSEd Tanous         return;
3311dd60b9edSEd Tanous     }
3312dd60b9edSEd Tanous     asyncResp->res.addHeader(
3313dd60b9edSEd Tanous         boost::beast::http::field::link,
3314dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3315dd60b9edSEd Tanous }
3316dd60b9edSEd Tanous 
33171cb1a9e6SAppaRao Puli /**
33181cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
33191cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
33201cb1a9e6SAppaRao Puli  */
33217e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
33221cb1a9e6SAppaRao Puli {
3323dd60b9edSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3324dd60b9edSEd Tanous         .privileges(redfish::privileges::headActionInfo)
3325dd60b9edSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3326dd60b9edSEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
33271cb1a9e6SAppaRao Puli     /**
33281cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
33291cb1a9e6SAppaRao Puli      */
333022d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3331ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
33327e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
333345ca1b86SEd Tanous             [&app](const crow::Request& req,
333422d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
333522d268cbSEd Tanous                    const std::string& systemName) {
33363ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
333745ca1b86SEd Tanous         {
333845ca1b86SEd Tanous             return;
333945ca1b86SEd Tanous         }
3340746b56f3SAsmitha Karunanithi 
3341746b56f3SAsmitha Karunanithi         if (systemName == "hypervisor")
3342746b56f3SAsmitha Karunanithi         {
3343746b56f3SAsmitha Karunanithi             handleHypervisorResetActionGet(asyncResp);
3344746b56f3SAsmitha Karunanithi             return;
3345746b56f3SAsmitha Karunanithi         }
3346746b56f3SAsmitha Karunanithi 
334722d268cbSEd Tanous         if (systemName != "system")
334822d268cbSEd Tanous         {
334922d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
335022d268cbSEd Tanous                                        systemName);
335122d268cbSEd Tanous             return;
335222d268cbSEd Tanous         }
335322d268cbSEd Tanous 
3354dd60b9edSEd Tanous         asyncResp->res.addHeader(
3355dd60b9edSEd Tanous             boost::beast::http::field::link,
3356dd60b9edSEd Tanous             "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
33571476687dSEd Tanous 
33581476687dSEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
33591476687dSEd Tanous             "/redfish/v1/Systems/system/ResetActionInfo";
33601476687dSEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
33611476687dSEd Tanous             "#ActionInfo.v1_1_2.ActionInfo";
33621476687dSEd Tanous         asyncResp->res.jsonValue["Name"] = "Reset Action Info";
33631476687dSEd Tanous         asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
33643215e700SNan Zhou 
33653215e700SNan Zhou         nlohmann::json::array_t parameters;
33663215e700SNan Zhou         nlohmann::json::object_t parameter;
33673215e700SNan Zhou 
33683215e700SNan Zhou         parameter["Name"] = "ResetType";
33693215e700SNan Zhou         parameter["Required"] = true;
33703215e700SNan Zhou         parameter["DataType"] = "String";
33713215e700SNan Zhou         nlohmann::json::array_t allowableValues;
33723215e700SNan Zhou         allowableValues.emplace_back("On");
33733215e700SNan Zhou         allowableValues.emplace_back("ForceOff");
33743215e700SNan Zhou         allowableValues.emplace_back("ForceOn");
33753215e700SNan Zhou         allowableValues.emplace_back("ForceRestart");
33763215e700SNan Zhou         allowableValues.emplace_back("GracefulRestart");
33773215e700SNan Zhou         allowableValues.emplace_back("GracefulShutdown");
33783215e700SNan Zhou         allowableValues.emplace_back("PowerCycle");
33793215e700SNan Zhou         allowableValues.emplace_back("Nmi");
33803215e700SNan Zhou         parameter["AllowableValues"] = std::move(allowableValues);
33813215e700SNan Zhou         parameters.emplace_back(std::move(parameter));
33823215e700SNan Zhou 
33833215e700SNan Zhou         asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
33847e860f15SJohn Edward Broadbent         });
33851cb1a9e6SAppaRao Puli }
3386c5b2abe0SLewanczyk, Dawid } // namespace redfish
3387