xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 9dcfe8c1ca70f8ff260aa5613f787d5fa3e7c45d)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
1813451e39SWilly Tu #include "bmcweb_config.h"
1913451e39SWilly Tu 
203ccb3adbSEd Tanous #include "app.hpp"
211e1e598dSJonathan Doman #include "dbus_singleton.hpp"
227a1dbc48SGeorge Liu #include "dbus_utility.hpp"
238d69c668SEd Tanous #include "generated/enums/computer_system.hpp"
24b49ac873SJames Feist #include "health.hpp"
25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
261c8fba97SJames Feist #include "led.hpp"
27f4c99e70SEd Tanous #include "query.hpp"
28c5d03ff4SJennifer Lee #include "redfish_util.hpp"
293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
313ccb3adbSEd Tanous #include "utils/json_utils.hpp"
32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
333ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
342b82937eSEd Tanous #include "utils/time_utils.hpp"
35c5d03ff4SJennifer Lee 
36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
379712f8acSEd Tanous #include <boost/container/flat_map.hpp>
38e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
39ef4c65b7SEd Tanous #include <boost/url/format.hpp>
401e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
41fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
42bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
431214b7e7SGunnar Mills 
447a1dbc48SGeorge Liu #include <array>
457a1dbc48SGeorge Liu #include <string_view>
46abf2add6SEd Tanous #include <variant>
47c5b2abe0SLewanczyk, Dawid 
481abe55efSEd Tanous namespace redfish
491abe55efSEd Tanous {
50c5b2abe0SLewanczyk, Dawid 
515c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
525c3e9272SAbhishek Patel     protocolToDBusForSystems{
535c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
545c3e9272SAbhishek Patel 
559d3ae10eSAlpana Kumari /**
569d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
579d3ae10eSAlpana Kumari  *
58ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
599d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
609d3ae10eSAlpana Kumari  *
619d3ae10eSAlpana Kumari  * @return None.
629d3ae10eSAlpana Kumari  */
638d1b46d7Szhanghch05 inline void
64ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
651e1e598dSJonathan Doman                          bool isDimmFunctional)
669d3ae10eSAlpana Kumari {
671e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
689d3ae10eSAlpana Kumari 
699d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
709d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
719d3ae10eSAlpana Kumari     // ENABLED.
7202cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
73ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
749d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
759d3ae10eSAlpana Kumari     {
76e05aec50SEd Tanous         if (isDimmFunctional)
779d3ae10eSAlpana Kumari         {
78ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
799d3ae10eSAlpana Kumari                 "Enabled";
809d3ae10eSAlpana Kumari         }
819d3ae10eSAlpana Kumari     }
829d3ae10eSAlpana Kumari }
839d3ae10eSAlpana Kumari 
8457e8c9beSAlpana Kumari /*
8557e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8657e8c9beSAlpana Kumari  *        CPU Functional State
8757e8c9beSAlpana Kumari  *
88ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
8957e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9057e8c9beSAlpana Kumari  *
9157e8c9beSAlpana Kumari  * @return None.
9257e8c9beSAlpana Kumari  */
93ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
94ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9557e8c9beSAlpana Kumari {
961e1e598dSJonathan Doman     BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
9757e8c9beSAlpana Kumari 
9802cad96eSEd Tanous     const nlohmann::json& prevProcState =
99ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10057e8c9beSAlpana Kumari 
10157e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10257e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10357e8c9beSAlpana Kumari     // Functional.
10457e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10557e8c9beSAlpana Kumari     {
106e05aec50SEd Tanous         if (isCpuFunctional)
10757e8c9beSAlpana Kumari         {
108ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
10957e8c9beSAlpana Kumari                 "Enabled";
11057e8c9beSAlpana Kumari         }
11157e8c9beSAlpana Kumari     }
11257e8c9beSAlpana Kumari }
11357e8c9beSAlpana Kumari 
114cf0e004cSNinad Palsule /*
115cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
116cf0e004cSNinad Palsule  *
117ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
118cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
119cf0e004cSNinad Palsule  *
120cf0e004cSNinad Palsule  * @return None.
121cf0e004cSNinad Palsule  */
122cf0e004cSNinad Palsule inline void
123ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
124cf0e004cSNinad Palsule                            bool isCpuPresent)
125cf0e004cSNinad Palsule {
126cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
127cf0e004cSNinad Palsule 
128cf0e004cSNinad Palsule     if (isCpuPresent)
129cf0e004cSNinad Palsule     {
130cf0e004cSNinad Palsule         nlohmann::json& procCount =
131ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
132cf0e004cSNinad Palsule         auto* procCountPtr =
133cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
134cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
135cf0e004cSNinad Palsule         {
136cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
137cf0e004cSNinad Palsule             *procCountPtr += 1;
138cf0e004cSNinad Palsule         }
139cf0e004cSNinad Palsule     }
140cf0e004cSNinad Palsule }
141cf0e004cSNinad Palsule 
142382d6475SAli Ahmed inline void getProcessorProperties(
143ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
144382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
145382d6475SAli Ahmed         properties)
14603fbed92SAli Ahmed {
14703fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
14803fbed92SAli Ahmed 
14903fbed92SAli Ahmed     // TODO: Get Model
15003fbed92SAli Ahmed 
151bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15203fbed92SAli Ahmed 
153bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
154bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     if (!success)
15703fbed92SAli Ahmed     {
158ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
15903fbed92SAli Ahmed         return;
16003fbed92SAli Ahmed     }
16103fbed92SAli Ahmed 
162bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16303fbed92SAli Ahmed     {
164bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
165ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
166bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
167bc1d29deSKrzysztof Grobelny 
168bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
169bc1d29deSKrzysztof Grobelny         {
170bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17103fbed92SAli Ahmed         }
17203fbed92SAli Ahmed         else
17303fbed92SAli Ahmed         {
174bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17503fbed92SAli Ahmed         }
17603fbed92SAli Ahmed     }
17703fbed92SAli Ahmed }
17803fbed92SAli Ahmed 
17903fbed92SAli Ahmed /*
18003fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18103fbed92SAli Ahmed  *
182ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18303fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18403fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18503fbed92SAli Ahmed  *
18603fbed92SAli Ahmed  * @return None.
18703fbed92SAli Ahmed  */
188ac106bf6SEd Tanous inline void
189ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
190ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19103fbed92SAli Ahmed {
192ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
193382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
194382d6475SAli Ahmed         if (ec3)
195382d6475SAli Ahmed         {
196382d6475SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
197382d6475SAli Ahmed             return;
198382d6475SAli Ahmed         }
199ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
200382d6475SAli Ahmed     };
201382d6475SAli Ahmed 
202cf0e004cSNinad Palsule     // Get the Presence of CPU
203cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
204cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
205cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
206cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
207cf0e004cSNinad Palsule 
2085fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2095fd0aafbSNinad Palsule     {
2105fd0aafbSNinad Palsule         auto getCpuFunctionalState =
211ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
212382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
213382d6475SAli Ahmed             if (ec3)
214382d6475SAli Ahmed             {
215382d6475SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
216382d6475SAli Ahmed                 return;
217382d6475SAli Ahmed             }
218ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
219382d6475SAli Ahmed         };
220382d6475SAli Ahmed 
221382d6475SAli Ahmed         // Get the Functional State
222382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
223382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2245fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2255fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2265fd0aafbSNinad Palsule     }
227382d6475SAli Ahmed 
228bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
229bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
230bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
231ac106bf6SEd Tanous         [asyncResp, service,
2325e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
233b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23403fbed92SAli Ahmed         if (ec2)
23503fbed92SAli Ahmed         {
23603fbed92SAli Ahmed             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
237ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23803fbed92SAli Ahmed             return;
23903fbed92SAli Ahmed         }
240ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
241bc1d29deSKrzysztof Grobelny         });
24203fbed92SAli Ahmed }
24303fbed92SAli Ahmed 
24457e8c9beSAlpana Kumari /*
245cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
246cf0e004cSNinad Palsule  *
247ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
248cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
249cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
250cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
251cf0e004cSNinad Palsule  *
252cf0e004cSNinad Palsule  * @return None.
253cf0e004cSNinad Palsule  */
254cf0e004cSNinad Palsule inline void
255ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2565fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2575fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
258cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
259cf0e004cSNinad Palsule {
260cf0e004cSNinad Palsule     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
261cf0e004cSNinad Palsule 
262cf0e004cSNinad Palsule     if (properties.empty())
263cf0e004cSNinad Palsule     {
2645fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2655fd0aafbSNinad Palsule         {
266cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
267cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
268cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
269cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
270cf0e004cSNinad Palsule                 "Functional",
271ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
272ac106bf6SEd Tanous                             bool dimmState) {
273cf0e004cSNinad Palsule                 if (ec3)
274cf0e004cSNinad Palsule                 {
275cf0e004cSNinad Palsule                     BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
276cf0e004cSNinad Palsule                     return;
277cf0e004cSNinad Palsule                 }
278ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
279cf0e004cSNinad Palsule                 });
2805fd0aafbSNinad Palsule         }
281cf0e004cSNinad Palsule         return;
282cf0e004cSNinad Palsule     }
283cf0e004cSNinad Palsule 
284cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
285cf0e004cSNinad Palsule 
286cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
287cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
288cf0e004cSNinad Palsule         memorySizeInKB);
289cf0e004cSNinad Palsule 
290cf0e004cSNinad Palsule     if (!success)
291cf0e004cSNinad Palsule     {
292ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
293cf0e004cSNinad Palsule         return;
294cf0e004cSNinad Palsule     }
295cf0e004cSNinad Palsule 
296cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
297cf0e004cSNinad Palsule     {
298cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
299ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
300cf0e004cSNinad Palsule         const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
301cf0e004cSNinad Palsule         if (preValue == nullptr)
302cf0e004cSNinad Palsule         {
303ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
304cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
305cf0e004cSNinad Palsule         }
306cf0e004cSNinad Palsule         else
307cf0e004cSNinad Palsule         {
308ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
309cf0e004cSNinad Palsule                 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
310cf0e004cSNinad Palsule         }
3115fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3125fd0aafbSNinad Palsule         {
313ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3145fd0aafbSNinad Palsule                 "Enabled";
3155fd0aafbSNinad Palsule         }
316cf0e004cSNinad Palsule     }
317cf0e004cSNinad Palsule }
318cf0e004cSNinad Palsule 
319cf0e004cSNinad Palsule /*
320cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
321cf0e004cSNinad Palsule  *
322ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
323cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
324cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
325cf0e004cSNinad Palsule  *
326cf0e004cSNinad Palsule  * @return None.
327cf0e004cSNinad Palsule  */
328ac106bf6SEd Tanous inline void
329ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
330ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
331cf0e004cSNinad Palsule {
332cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
333cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
334cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
335ac106bf6SEd Tanous         [asyncResp, service,
336cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
337cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
338cf0e004cSNinad Palsule         if (ec2)
339cf0e004cSNinad Palsule         {
340cf0e004cSNinad Palsule             BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
341ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
342cf0e004cSNinad Palsule             return;
343cf0e004cSNinad Palsule         }
344ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
345cf0e004cSNinad Palsule         });
346cf0e004cSNinad Palsule }
347cf0e004cSNinad Palsule 
348cf0e004cSNinad Palsule /*
349c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
350c5b2abe0SLewanczyk, Dawid  *
351ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
3528f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
353c5b2abe0SLewanczyk, Dawid  *
354c5b2abe0SLewanczyk, Dawid  * @return None.
355c5b2abe0SLewanczyk, Dawid  */
356b5a76932SEd Tanous inline void
357ac106bf6SEd Tanous     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
358b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
3591abe55efSEd Tanous {
36055c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
361e99073f5SGeorge Liu     constexpr std::array<std::string_view, 5> interfaces = {
362e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Decorator.Asset",
363e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Cpu",
364e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
365e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System",
366e99073f5SGeorge Liu         "xyz.openbmc_project.Common.UUID",
367e99073f5SGeorge Liu     };
368e99073f5SGeorge Liu     dbus::utility::getSubTree(
369e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
370ac106bf6SEd Tanous         [asyncResp,
371e99073f5SGeorge Liu          systemHealth](const boost::system::error_code& ec,
372b9d36b47SEd Tanous                        const dbus::utility::MapperGetSubTreeResponse& subtree) {
3731abe55efSEd Tanous         if (ec)
3741abe55efSEd Tanous         {
37555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error";
376ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
377c5b2abe0SLewanczyk, Dawid             return;
378c5b2abe0SLewanczyk, Dawid         }
379c5b2abe0SLewanczyk, Dawid         // Iterate over all retrieved ObjectPaths.
380002d39b4SEd Tanous         for (const std::pair<
381002d39b4SEd Tanous                  std::string,
382002d39b4SEd Tanous                  std::vector<std::pair<std::string, std::vector<std::string>>>>&
3831214b7e7SGunnar Mills                  object : subtree)
3841abe55efSEd Tanous         {
385c5b2abe0SLewanczyk, Dawid             const std::string& path = object.first;
38655c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got path: " << path;
387002d39b4SEd Tanous             const std::vector<std::pair<std::string, std::vector<std::string>>>&
3881214b7e7SGunnar Mills                 connectionNames = object.second;
38926f6976fSEd Tanous             if (connectionNames.empty())
3901abe55efSEd Tanous             {
391c5b2abe0SLewanczyk, Dawid                 continue;
392c5b2abe0SLewanczyk, Dawid             }
393029573d4SEd Tanous 
3945fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
3955fd0aafbSNinad Palsule             std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
3965bc2dc8eSJames Feist 
3975fd0aafbSNinad Palsule             if constexpr (bmcwebEnableProcMemStatus)
3985fd0aafbSNinad Palsule             {
3995fd0aafbSNinad Palsule                 memoryHealth = std::make_shared<HealthPopulate>(
400ac106bf6SEd Tanous                     asyncResp, "/MemorySummary/Status"_json_pointer);
4015fd0aafbSNinad Palsule                 systemHealth->children.emplace_back(memoryHealth);
4025bc2dc8eSJames Feist 
40313451e39SWilly Tu                 if constexpr (bmcwebEnableHealthPopulate)
40413451e39SWilly Tu                 {
4055fd0aafbSNinad Palsule                     cpuHealth = std::make_shared<HealthPopulate>(
406ac106bf6SEd Tanous                         asyncResp, "/ProcessorSummary/Status"_json_pointer);
4075fd0aafbSNinad Palsule 
4085bc2dc8eSJames Feist                     systemHealth->children.emplace_back(cpuHealth);
40913451e39SWilly Tu                 }
4105fd0aafbSNinad Palsule             }
4115bc2dc8eSJames Feist 
4126c34de48SEd Tanous             // This is not system, so check if it's cpu, dimm, UUID or
4136c34de48SEd Tanous             // BiosVer
41404a258f4SEd Tanous             for (const auto& connection : connectionNames)
4151abe55efSEd Tanous             {
41604a258f4SEd Tanous                 for (const auto& interfaceName : connection.second)
4171abe55efSEd Tanous                 {
41804a258f4SEd Tanous                     if (interfaceName ==
41904a258f4SEd Tanous                         "xyz.openbmc_project.Inventory.Item.Dimm")
4201abe55efSEd Tanous                     {
4211abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
42204a258f4SEd Tanous                             << "Found Dimm, now get its properties.";
4239d3ae10eSAlpana Kumari 
424ac106bf6SEd Tanous                         getMemorySummary(asyncResp, connection.first, path);
4255bc2dc8eSJames Feist 
4265fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4275fd0aafbSNinad Palsule                         {
4285bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4291abe55efSEd Tanous                         }
4305fd0aafbSNinad Palsule                     }
43104a258f4SEd Tanous                     else if (interfaceName ==
43204a258f4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.Cpu")
4331abe55efSEd Tanous                     {
4341abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
43504a258f4SEd Tanous                             << "Found Cpu, now get its properties.";
43657e8c9beSAlpana Kumari 
437ac106bf6SEd Tanous                         getProcessorSummary(asyncResp, connection.first, path);
4385bc2dc8eSJames Feist 
4395fd0aafbSNinad Palsule                         if constexpr (bmcwebEnableProcMemStatus)
4405fd0aafbSNinad Palsule                         {
4415bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4421abe55efSEd Tanous                         }
4435fd0aafbSNinad Palsule                     }
444002d39b4SEd Tanous                     else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4451abe55efSEd Tanous                     {
4461abe55efSEd Tanous                         BMCWEB_LOG_DEBUG
44704a258f4SEd Tanous                             << "Found UUID, now get its properties.";
448bc1d29deSKrzysztof Grobelny 
449bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
450bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
451bc1d29deSKrzysztof Grobelny                             path, "xyz.openbmc_project.Common.UUID",
452ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec3,
453b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
4541214b7e7SGunnar Mills                                             properties) {
455cb13a392SEd Tanous                             if (ec3)
4561abe55efSEd Tanous                             {
457002d39b4SEd Tanous                                 BMCWEB_LOG_DEBUG << "DBUS response error "
458002d39b4SEd Tanous                                                  << ec3;
459ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
460c5b2abe0SLewanczyk, Dawid                                 return;
461c5b2abe0SLewanczyk, Dawid                             }
462002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << properties.size()
463c5b2abe0SLewanczyk, Dawid                                              << " UUID properties.";
46404a258f4SEd Tanous 
465bc1d29deSKrzysztof Grobelny                             const std::string* uUID = nullptr;
466bc1d29deSKrzysztof Grobelny 
467bc1d29deSKrzysztof Grobelny                             const bool success =
468bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
469bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
470bc1d29deSKrzysztof Grobelny                                     properties, "UUID", uUID);
471bc1d29deSKrzysztof Grobelny 
472bc1d29deSKrzysztof Grobelny                             if (!success)
4731abe55efSEd Tanous                             {
474ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
475bc1d29deSKrzysztof Grobelny                                 return;
476bc1d29deSKrzysztof Grobelny                             }
477bc1d29deSKrzysztof Grobelny 
478bc1d29deSKrzysztof Grobelny                             if (uUID != nullptr)
479bc1d29deSKrzysztof Grobelny                             {
480bc1d29deSKrzysztof Grobelny                                 std::string valueStr = *uUID;
48104a258f4SEd Tanous                                 if (valueStr.size() == 32)
4821abe55efSEd Tanous                                 {
483029573d4SEd Tanous                                     valueStr.insert(8, 1, '-');
484029573d4SEd Tanous                                     valueStr.insert(13, 1, '-');
485029573d4SEd Tanous                                     valueStr.insert(18, 1, '-');
486029573d4SEd Tanous                                     valueStr.insert(23, 1, '-');
48704a258f4SEd Tanous                                 }
488bc1d29deSKrzysztof Grobelny                                 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
489ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["UUID"] = valueStr;
490c5b2abe0SLewanczyk, Dawid                             }
491bc1d29deSKrzysztof Grobelny                             });
492c5b2abe0SLewanczyk, Dawid                     }
493029573d4SEd Tanous                     else if (interfaceName ==
494029573d4SEd Tanous                              "xyz.openbmc_project.Inventory.Item.System")
4951abe55efSEd Tanous                     {
496bc1d29deSKrzysztof Grobelny                         sdbusplus::asio::getAllProperties(
497bc1d29deSKrzysztof Grobelny                             *crow::connections::systemBus, connection.first,
498bc1d29deSKrzysztof Grobelny                             path,
499bc1d29deSKrzysztof Grobelny                             "xyz.openbmc_project.Inventory.Decorator.Asset",
500ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
501b9d36b47SEd Tanous                                         const dbus::utility::DBusPropertiesMap&
5021214b7e7SGunnar Mills                                             propertiesList) {
503cb13a392SEd Tanous                             if (ec2)
504029573d4SEd Tanous                             {
505e4a4b9a9SJames Feist                                 // doesn't have to include this
506e4a4b9a9SJames Feist                                 // interface
507029573d4SEd Tanous                                 return;
508029573d4SEd Tanous                             }
509002d39b4SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
510029573d4SEd Tanous                                              << " properties for system";
511bc1d29deSKrzysztof Grobelny 
512bc1d29deSKrzysztof Grobelny                             const std::string* partNumber = nullptr;
513bc1d29deSKrzysztof Grobelny                             const std::string* serialNumber = nullptr;
514bc1d29deSKrzysztof Grobelny                             const std::string* manufacturer = nullptr;
515bc1d29deSKrzysztof Grobelny                             const std::string* model = nullptr;
516bc1d29deSKrzysztof Grobelny                             const std::string* subModel = nullptr;
517bc1d29deSKrzysztof Grobelny 
518bc1d29deSKrzysztof Grobelny                             const bool success =
519bc1d29deSKrzysztof Grobelny                                 sdbusplus::unpackPropertiesNoThrow(
520bc1d29deSKrzysztof Grobelny                                     dbus_utils::UnpackErrorPrinter(),
521bc1d29deSKrzysztof Grobelny                                     propertiesList, "PartNumber", partNumber,
522bc1d29deSKrzysztof Grobelny                                     "SerialNumber", serialNumber,
523bc1d29deSKrzysztof Grobelny                                     "Manufacturer", manufacturer, "Model",
524bc1d29deSKrzysztof Grobelny                                     model, "SubModel", subModel);
525bc1d29deSKrzysztof Grobelny 
526bc1d29deSKrzysztof Grobelny                             if (!success)
527029573d4SEd Tanous                             {
528ac106bf6SEd Tanous                                 messages::internalError(asyncResp->res);
529bc1d29deSKrzysztof Grobelny                                 return;
530029573d4SEd Tanous                             }
531bc1d29deSKrzysztof Grobelny 
532bc1d29deSKrzysztof Grobelny                             if (partNumber != nullptr)
533bc1d29deSKrzysztof Grobelny                             {
534ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["PartNumber"] =
535bc1d29deSKrzysztof Grobelny                                     *partNumber;
536029573d4SEd Tanous                             }
537bc1d29deSKrzysztof Grobelny 
538bc1d29deSKrzysztof Grobelny                             if (serialNumber != nullptr)
539bc1d29deSKrzysztof Grobelny                             {
540ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SerialNumber"] =
541bc1d29deSKrzysztof Grobelny                                     *serialNumber;
542bc1d29deSKrzysztof Grobelny                             }
543bc1d29deSKrzysztof Grobelny 
544bc1d29deSKrzysztof Grobelny                             if (manufacturer != nullptr)
545bc1d29deSKrzysztof Grobelny                             {
546ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Manufacturer"] =
547bc1d29deSKrzysztof Grobelny                                     *manufacturer;
548bc1d29deSKrzysztof Grobelny                             }
549bc1d29deSKrzysztof Grobelny 
550bc1d29deSKrzysztof Grobelny                             if (model != nullptr)
551bc1d29deSKrzysztof Grobelny                             {
552ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["Model"] = *model;
553bc1d29deSKrzysztof Grobelny                             }
554bc1d29deSKrzysztof Grobelny 
555bc1d29deSKrzysztof Grobelny                             if (subModel != nullptr)
556bc1d29deSKrzysztof Grobelny                             {
557ac106bf6SEd Tanous                                 asyncResp->res.jsonValue["SubModel"] =
558ac106bf6SEd Tanous                                     *subModel;
559fc5afcf9Sbeccabroek                             }
560c1e236a6SGunnar Mills 
561cb7e1e7bSAndrew Geissler                             // Grab the bios version
562eee0013eSWilly Tu                             sw_util::populateSoftwareInformation(
563ac106bf6SEd Tanous                                 asyncResp, sw_util::biosPurpose, "BiosVersion",
564002d39b4SEd Tanous                                 false);
565bc1d29deSKrzysztof Grobelny                             });
566e4a4b9a9SJames Feist 
5671e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<std::string>(
5681e1e598dSJonathan Doman                             *crow::connections::systemBus, connection.first,
5691e1e598dSJonathan Doman                             path,
5701e1e598dSJonathan Doman                             "xyz.openbmc_project.Inventory.Decorator."
5711e1e598dSJonathan Doman                             "AssetTag",
5721e1e598dSJonathan Doman                             "AssetTag",
573ac106bf6SEd Tanous                             [asyncResp](const boost::system::error_code& ec2,
5741e1e598dSJonathan Doman                                         const std::string& value) {
575cb13a392SEd Tanous                             if (ec2)
576e4a4b9a9SJames Feist                             {
577e4a4b9a9SJames Feist                                 // doesn't have to include this
578e4a4b9a9SJames Feist                                 // interface
579e4a4b9a9SJames Feist                                 return;
580e4a4b9a9SJames Feist                             }
581e4a4b9a9SJames Feist 
582ac106bf6SEd Tanous                             asyncResp->res.jsonValue["AssetTag"] = value;
5831e1e598dSJonathan Doman                             });
584029573d4SEd Tanous                     }
585029573d4SEd Tanous                 }
586029573d4SEd Tanous             }
587c5b2abe0SLewanczyk, Dawid         }
5886617338dSEd Tanous         });
589c5b2abe0SLewanczyk, Dawid }
590c5b2abe0SLewanczyk, Dawid 
591c5b2abe0SLewanczyk, Dawid /**
592c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
593c5b2abe0SLewanczyk, Dawid  *
594ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
595c5b2abe0SLewanczyk, Dawid  *
596c5b2abe0SLewanczyk, Dawid  * @return None.
597c5b2abe0SLewanczyk, Dawid  */
598ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5991abe55efSEd Tanous {
60055c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
6011e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6021e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6031e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6041e1e598dSJonathan Doman         "CurrentHostState",
605ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6061e1e598dSJonathan Doman                     const std::string& hostState) {
6071abe55efSEd Tanous         if (ec)
6081abe55efSEd Tanous         {
60922228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
61022228c28SAndrew Geissler             {
61122228c28SAndrew Geissler                 // Service not available, no error, just don't return
61222228c28SAndrew Geissler                 // host state info
61322228c28SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Service not available " << ec;
61422228c28SAndrew Geissler                 return;
61522228c28SAndrew Geissler             }
61622228c28SAndrew Geissler             BMCWEB_LOG_ERROR << "DBUS response error " << ec;
617ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
618c5b2abe0SLewanczyk, Dawid             return;
619c5b2abe0SLewanczyk, Dawid         }
6206617338dSEd Tanous 
6211e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Host state: " << hostState;
622c5b2abe0SLewanczyk, Dawid         // Verify Host State
6231e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6241abe55efSEd Tanous         {
625ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
626ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6271abe55efSEd Tanous         }
6281e1e598dSJonathan Doman         else if (hostState ==
6290fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6308c888608SGunnar Mills         {
631ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
632ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6338c888608SGunnar Mills         }
6341e1e598dSJonathan Doman         else if (hostState ==
6350fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
63683935af9SAndrew Geissler         {
637ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
638ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
63983935af9SAndrew Geissler         }
6400fda0f12SGeorge Liu         else if (
6411e1e598dSJonathan Doman             hostState ==
6420fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6431a2a1437SAndrew Geissler         {
644ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
645ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6461a2a1437SAndrew Geissler         }
647002d39b4SEd Tanous         else if (hostState ==
6480fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6491a2a1437SAndrew Geissler         {
650ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
651ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6521a2a1437SAndrew Geissler         }
6531abe55efSEd Tanous         else
6541abe55efSEd Tanous         {
655ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
656ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
657c5b2abe0SLewanczyk, Dawid         }
6581e1e598dSJonathan Doman         });
659c5b2abe0SLewanczyk, Dawid }
660c5b2abe0SLewanczyk, Dawid 
661c5b2abe0SLewanczyk, Dawid /**
662786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
663491d8ee7SSantosh Puranik  *
664491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
665491d8ee7SSantosh Puranik  *
666491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
667491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
668491d8ee7SSantosh Puranik  */
66923a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
670491d8ee7SSantosh Puranik {
671491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
672491d8ee7SSantosh Puranik     {
673491d8ee7SSantosh Puranik         return "None";
674491d8ee7SSantosh Puranik     }
6753174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
676491d8ee7SSantosh Puranik     {
677491d8ee7SSantosh Puranik         return "Hdd";
678491d8ee7SSantosh Puranik     }
6793174e4dfSEd Tanous     if (dbusSource ==
680a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
681491d8ee7SSantosh Puranik     {
682491d8ee7SSantosh Puranik         return "Cd";
683491d8ee7SSantosh Puranik     }
6843174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
685491d8ee7SSantosh Puranik     {
686491d8ee7SSantosh Puranik         return "Pxe";
687491d8ee7SSantosh Puranik     }
6883174e4dfSEd Tanous     if (dbusSource ==
689944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6909f16b2c1SJennifer Lee     {
6919f16b2c1SJennifer Lee         return "Usb";
6929f16b2c1SJennifer Lee     }
693491d8ee7SSantosh Puranik     return "";
694491d8ee7SSantosh Puranik }
695491d8ee7SSantosh Puranik 
696491d8ee7SSantosh Puranik /**
697cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
698cd9a4666SKonstantin Aladyshev  *
699cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
700cd9a4666SKonstantin Aladyshev  *
701cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
702cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
703cd9a4666SKonstantin Aladyshev  */
704cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
705cd9a4666SKonstantin Aladyshev {
706cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
707cd9a4666SKonstantin Aladyshev     {
708cd9a4666SKonstantin Aladyshev         return "Legacy";
709cd9a4666SKonstantin Aladyshev     }
710cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
711cd9a4666SKonstantin Aladyshev     {
712cd9a4666SKonstantin Aladyshev         return "UEFI";
713cd9a4666SKonstantin Aladyshev     }
714cd9a4666SKonstantin Aladyshev     return "";
715cd9a4666SKonstantin Aladyshev }
716cd9a4666SKonstantin Aladyshev 
717cd9a4666SKonstantin Aladyshev /**
718786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
719491d8ee7SSantosh Puranik  *
720491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
721491d8ee7SSantosh Puranik  *
722491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
723491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
724491d8ee7SSantosh Puranik  */
72523a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
726491d8ee7SSantosh Puranik {
727491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
728491d8ee7SSantosh Puranik     {
729491d8ee7SSantosh Puranik         return "None";
730491d8ee7SSantosh Puranik     }
7313174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
732491d8ee7SSantosh Puranik     {
733491d8ee7SSantosh Puranik         return "Diags";
734491d8ee7SSantosh Puranik     }
7353174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
736491d8ee7SSantosh Puranik     {
737491d8ee7SSantosh Puranik         return "BiosSetup";
738491d8ee7SSantosh Puranik     }
739491d8ee7SSantosh Puranik     return "";
740491d8ee7SSantosh Puranik }
741491d8ee7SSantosh Puranik 
742491d8ee7SSantosh Puranik /**
743e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
744e43914b3SAndrew Geissler  *
745e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
746e43914b3SAndrew Geissler  *
747e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
748e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
749e43914b3SAndrew Geissler  */
750e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
751e43914b3SAndrew Geissler {
752e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
753e43914b3SAndrew Geissler     // enum
754e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
755e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
756e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
757e43914b3SAndrew Geissler     {
758e43914b3SAndrew Geissler         rfBpLastState = "None";
759e43914b3SAndrew Geissler     }
760e43914b3SAndrew Geissler     else if (dbusBootProgress ==
761e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
762e43914b3SAndrew Geissler              "PrimaryProcInit")
763e43914b3SAndrew Geissler     {
764e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
765e43914b3SAndrew Geissler     }
766e43914b3SAndrew Geissler     else if (dbusBootProgress ==
767e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
768e43914b3SAndrew Geissler              "BusInit")
769e43914b3SAndrew Geissler     {
770e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
771e43914b3SAndrew Geissler     }
772e43914b3SAndrew Geissler     else if (dbusBootProgress ==
773e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
774e43914b3SAndrew Geissler              "MemoryInit")
775e43914b3SAndrew Geissler     {
776e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
777e43914b3SAndrew Geissler     }
778e43914b3SAndrew Geissler     else if (dbusBootProgress ==
779e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
780e43914b3SAndrew Geissler              "SecondaryProcInit")
781e43914b3SAndrew Geissler     {
782e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
783e43914b3SAndrew Geissler     }
784e43914b3SAndrew Geissler     else if (dbusBootProgress ==
785e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
786e43914b3SAndrew Geissler              "PCIInit")
787e43914b3SAndrew Geissler     {
788e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
789e43914b3SAndrew Geissler     }
790e43914b3SAndrew Geissler     else if (dbusBootProgress ==
791e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
792e43914b3SAndrew Geissler              "SystemSetup")
793e43914b3SAndrew Geissler     {
794e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
795e43914b3SAndrew Geissler     }
796e43914b3SAndrew Geissler     else if (dbusBootProgress ==
797e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
798e43914b3SAndrew Geissler              "SystemInitComplete")
799e43914b3SAndrew Geissler     {
800e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
801e43914b3SAndrew Geissler     }
802e43914b3SAndrew Geissler     else if (dbusBootProgress ==
803e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
804e43914b3SAndrew Geissler              "OSStart")
805e43914b3SAndrew Geissler     {
806e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
807e43914b3SAndrew Geissler     }
808e43914b3SAndrew Geissler     else if (dbusBootProgress ==
809e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
810e43914b3SAndrew Geissler              "OSRunning")
811e43914b3SAndrew Geissler     {
812e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
813e43914b3SAndrew Geissler     }
814e43914b3SAndrew Geissler     else
815e43914b3SAndrew Geissler     {
816e43914b3SAndrew Geissler         BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
817e43914b3SAndrew Geissler                          << dbusBootProgress;
818e43914b3SAndrew Geissler         // Just return the default
819e43914b3SAndrew Geissler     }
820e43914b3SAndrew Geissler     return rfBpLastState;
821e43914b3SAndrew Geissler }
822e43914b3SAndrew Geissler 
823e43914b3SAndrew Geissler /**
824786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
825491d8ee7SSantosh Puranik  *
826491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
827944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
828944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
829491d8ee7SSantosh Puranik  *
830944ffaf9SJohnathan Mantey  * @return Integer error code.
831491d8ee7SSantosh Puranik  */
832ac106bf6SEd Tanous inline int
833ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
834ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
835ac106bf6SEd Tanous                          std::string& bootMode)
836491d8ee7SSantosh Puranik {
837c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
838c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
839944ffaf9SJohnathan Mantey 
840491d8ee7SSantosh Puranik     if (rfSource == "None")
841491d8ee7SSantosh Puranik     {
842944ffaf9SJohnathan Mantey         return 0;
843491d8ee7SSantosh Puranik     }
8443174e4dfSEd Tanous     if (rfSource == "Pxe")
845491d8ee7SSantosh Puranik     {
846944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
847944ffaf9SJohnathan Mantey     }
848944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
849944ffaf9SJohnathan Mantey     {
850944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
851944ffaf9SJohnathan Mantey     }
852944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
853944ffaf9SJohnathan Mantey     {
854944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
855944ffaf9SJohnathan Mantey     }
856944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
857944ffaf9SJohnathan Mantey     {
858944ffaf9SJohnathan Mantey         bootSource =
859944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
860944ffaf9SJohnathan Mantey     }
861944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
862944ffaf9SJohnathan Mantey     {
863944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
864491d8ee7SSantosh Puranik     }
8659f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8669f16b2c1SJennifer Lee     {
867944ffaf9SJohnathan Mantey         bootSource =
868944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8699f16b2c1SJennifer Lee     }
870491d8ee7SSantosh Puranik     else
871491d8ee7SSantosh Puranik     {
8720fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
8730fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
874944ffaf9SJohnathan Mantey             << bootSource;
875ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
876944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
877944ffaf9SJohnathan Mantey         return -1;
878491d8ee7SSantosh Puranik     }
879944ffaf9SJohnathan Mantey     return 0;
880491d8ee7SSantosh Puranik }
8811981771bSAli Ahmed 
882978b8803SAndrew Geissler /**
883978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
884978b8803SAndrew Geissler  *
885ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
886978b8803SAndrew Geissler  *
887978b8803SAndrew Geissler  * @return None.
888978b8803SAndrew Geissler  */
889ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
890978b8803SAndrew Geissler {
8911e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8921e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8931e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8941e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
895ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8961e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
897978b8803SAndrew Geissler         if (ec)
898978b8803SAndrew Geissler         {
899978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
900978b8803SAndrew Geissler             // not found
901978b8803SAndrew Geissler             return;
902978b8803SAndrew Geissler         }
903978b8803SAndrew Geissler 
9041e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
905978b8803SAndrew Geissler 
906ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
907e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9081e1e598dSJonathan Doman         });
909978b8803SAndrew Geissler }
910491d8ee7SSantosh Puranik 
911491d8ee7SSantosh Puranik /**
912b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
913b6d5d45cSHieu Huynh  *
914ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
915b6d5d45cSHieu Huynh  *
916b6d5d45cSHieu Huynh  * @return None.
917b6d5d45cSHieu Huynh  */
918b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
919ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
920b6d5d45cSHieu Huynh {
921b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
922b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
923b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
924b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
925ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
926b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
927b6d5d45cSHieu Huynh         if (ec)
928b6d5d45cSHieu Huynh         {
929b6d5d45cSHieu Huynh             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
930b6d5d45cSHieu Huynh             return;
931b6d5d45cSHieu Huynh         }
932b6d5d45cSHieu Huynh 
933b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
934b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
935b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
936b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
937b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
938b6d5d45cSHieu Huynh 
939b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
940ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
941b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
942b6d5d45cSHieu Huynh         });
943b6d5d45cSHieu Huynh }
944b6d5d45cSHieu Huynh 
945b6d5d45cSHieu Huynh /**
946c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
947cd9a4666SKonstantin Aladyshev  *
948ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
949cd9a4666SKonstantin Aladyshev  *
950cd9a4666SKonstantin Aladyshev  * @return None.
951cd9a4666SKonstantin Aladyshev  */
952cd9a4666SKonstantin Aladyshev 
953ac106bf6SEd Tanous inline void
954ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
955cd9a4666SKonstantin Aladyshev {
9561e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9571e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9581e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9591e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
960ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9611e1e598dSJonathan Doman                     const std::string& bootType) {
962cd9a4666SKonstantin Aladyshev         if (ec)
963cd9a4666SKonstantin Aladyshev         {
964cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
965cd9a4666SKonstantin Aladyshev             return;
966cd9a4666SKonstantin Aladyshev         }
967cd9a4666SKonstantin Aladyshev 
9681e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
969cd9a4666SKonstantin Aladyshev 
970ac106bf6SEd Tanous         asyncResp->res
971ac106bf6SEd Tanous             .jsonValue["Boot"]
972002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
973613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
974cd9a4666SKonstantin Aladyshev 
9751e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
976cd9a4666SKonstantin Aladyshev         if (rfType.empty())
977cd9a4666SKonstantin Aladyshev         {
978ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
979cd9a4666SKonstantin Aladyshev             return;
980cd9a4666SKonstantin Aladyshev         }
981cd9a4666SKonstantin Aladyshev 
982ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9831e1e598dSJonathan Doman         });
984cd9a4666SKonstantin Aladyshev }
985cd9a4666SKonstantin Aladyshev 
986cd9a4666SKonstantin Aladyshev /**
987c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
988491d8ee7SSantosh Puranik  *
989ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
990491d8ee7SSantosh Puranik  *
991491d8ee7SSantosh Puranik  * @return None.
992491d8ee7SSantosh Puranik  */
993c21865c4SKonstantin Aladyshev 
994ac106bf6SEd Tanous inline void
995ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
996491d8ee7SSantosh Puranik {
9971e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9981e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9991e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10001e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1001ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10021e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1003491d8ee7SSantosh Puranik         if (ec)
1004491d8ee7SSantosh Puranik         {
1005491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1006ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1007491d8ee7SSantosh Puranik             return;
1008491d8ee7SSantosh Puranik         }
1009491d8ee7SSantosh Puranik 
10101e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1011491d8ee7SSantosh Puranik 
1012ac106bf6SEd Tanous         asyncResp->res
10130fda0f12SGeorge Liu             .jsonValue["Boot"]
1014002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1015002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1016491d8ee7SSantosh Puranik 
10171e1e598dSJonathan Doman         if (bootModeStr !=
1018491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1019491d8ee7SSantosh Puranik         {
10201e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1021491d8ee7SSantosh Puranik             if (!rfMode.empty())
1022491d8ee7SSantosh Puranik             {
1023ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1024491d8ee7SSantosh Puranik                     rfMode;
1025491d8ee7SSantosh Puranik             }
1026491d8ee7SSantosh Puranik         }
10271e1e598dSJonathan Doman         });
1028491d8ee7SSantosh Puranik }
1029491d8ee7SSantosh Puranik 
1030491d8ee7SSantosh Puranik /**
1031c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1032491d8ee7SSantosh Puranik  *
1033ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1034491d8ee7SSantosh Puranik  *
1035491d8ee7SSantosh Puranik  * @return None.
1036491d8ee7SSantosh Puranik  */
1037c21865c4SKonstantin Aladyshev 
1038c21865c4SKonstantin Aladyshev inline void
1039ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1040491d8ee7SSantosh Puranik {
10411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10431e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10441e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1045ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10461e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1047491d8ee7SSantosh Puranik         if (ec)
1048491d8ee7SSantosh Puranik         {
1049491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
10505ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10515ef735c8SNan Zhou             {
10525ef735c8SNan Zhou                 return;
10535ef735c8SNan Zhou             }
1054ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1055491d8ee7SSantosh Puranik             return;
1056491d8ee7SSantosh Puranik         }
1057491d8ee7SSantosh Puranik 
10581e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
1059491d8ee7SSantosh Puranik 
10601e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1061491d8ee7SSantosh Puranik         if (!rfSource.empty())
1062491d8ee7SSantosh Puranik         {
1063ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1064ac106bf6SEd Tanous                 rfSource;
1065491d8ee7SSantosh Puranik         }
1066cd9a4666SKonstantin Aladyshev 
1067cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1068cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1069ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10701e1e598dSJonathan Doman         });
1071491d8ee7SSantosh Puranik }
1072491d8ee7SSantosh Puranik 
1073491d8ee7SSantosh Puranik /**
1074c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1075c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1076c21865c4SKonstantin Aladyshev  * state
1077491d8ee7SSantosh Puranik  *
1078ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1079491d8ee7SSantosh Puranik  *
1080491d8ee7SSantosh Puranik  * @return None.
1081491d8ee7SSantosh Puranik  */
1082491d8ee7SSantosh Puranik 
1083ac106bf6SEd Tanous inline void processBootOverrideEnable(
1084ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1085c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1086c21865c4SKonstantin Aladyshev {
1087c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1088c21865c4SKonstantin Aladyshev     {
1089ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1090ac106bf6SEd Tanous             "Disabled";
1091c21865c4SKonstantin Aladyshev         return;
1092c21865c4SKonstantin Aladyshev     }
1093c21865c4SKonstantin Aladyshev 
1094c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1095c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10961e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10971e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10981e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10991e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1100ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1101491d8ee7SSantosh Puranik         if (ec)
1102491d8ee7SSantosh Puranik         {
1103491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1104ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1105491d8ee7SSantosh Puranik             return;
1106491d8ee7SSantosh Puranik         }
1107491d8ee7SSantosh Puranik 
1108c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1109c21865c4SKonstantin Aladyshev         {
1110ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1111ac106bf6SEd Tanous                 "Once";
1112c21865c4SKonstantin Aladyshev         }
1113c21865c4SKonstantin Aladyshev         else
1114c21865c4SKonstantin Aladyshev         {
1115ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1116c21865c4SKonstantin Aladyshev                 "Continuous";
1117c21865c4SKonstantin Aladyshev         }
11181e1e598dSJonathan Doman         });
1119491d8ee7SSantosh Puranik }
1120491d8ee7SSantosh Puranik 
1121491d8ee7SSantosh Puranik /**
1122c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1123c21865c4SKonstantin Aladyshev  *
1124ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1125c21865c4SKonstantin Aladyshev  *
1126c21865c4SKonstantin Aladyshev  * @return None.
1127c21865c4SKonstantin Aladyshev  */
1128c21865c4SKonstantin Aladyshev 
1129c21865c4SKonstantin Aladyshev inline void
1130ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1131c21865c4SKonstantin Aladyshev {
11321e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11331e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11341e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11351e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1136ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11371e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1138c21865c4SKonstantin Aladyshev         if (ec)
1139c21865c4SKonstantin Aladyshev         {
1140c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
11415ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11425ef735c8SNan Zhou             {
11435ef735c8SNan Zhou                 return;
11445ef735c8SNan Zhou             }
1145ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1146c21865c4SKonstantin Aladyshev             return;
1147c21865c4SKonstantin Aladyshev         }
1148c21865c4SKonstantin Aladyshev 
1149ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11501e1e598dSJonathan Doman         });
1151c21865c4SKonstantin Aladyshev }
1152c21865c4SKonstantin Aladyshev 
1153c21865c4SKonstantin Aladyshev /**
1154c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1155c21865c4SKonstantin Aladyshev  *
1156ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1157c21865c4SKonstantin Aladyshev  *
1158c21865c4SKonstantin Aladyshev  * @return None.
1159c21865c4SKonstantin Aladyshev  */
1160ac106bf6SEd Tanous inline void
1161ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1162c21865c4SKonstantin Aladyshev {
1163c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1164c21865c4SKonstantin Aladyshev 
1165ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1166ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1167ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1168c21865c4SKonstantin Aladyshev }
1169c21865c4SKonstantin Aladyshev 
1170c21865c4SKonstantin Aladyshev /**
1171c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1172c0557e1aSGunnar Mills  *
1173c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1174c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1175c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1176c0557e1aSGunnar Mills  * last power operation time.
1177c0557e1aSGunnar Mills  *
1178ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1179c0557e1aSGunnar Mills  *
1180c0557e1aSGunnar Mills  * @return None.
1181c0557e1aSGunnar Mills  */
1182ac106bf6SEd Tanous inline void
1183ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1184c0557e1aSGunnar Mills {
1185c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1186c0557e1aSGunnar Mills 
11871e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11881e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11891e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11901e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1191ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1192ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1193c0557e1aSGunnar Mills         if (ec)
1194c0557e1aSGunnar Mills         {
1195c0557e1aSGunnar Mills             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1196c0557e1aSGunnar Mills             return;
1197c0557e1aSGunnar Mills         }
1198c0557e1aSGunnar Mills 
1199c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1200c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12011e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1202c0557e1aSGunnar Mills 
1203c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1204ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12052b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12061e1e598dSJonathan Doman         });
1207c0557e1aSGunnar Mills }
1208c0557e1aSGunnar Mills 
1209c0557e1aSGunnar Mills /**
1210797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1211797d5daeSCorey Hardesty  *
1212797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1213797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1214797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1215797d5daeSCorey Hardesty  * dbus.
1216797d5daeSCorey Hardesty  *
1217ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1218797d5daeSCorey Hardesty  *
1219797d5daeSCorey Hardesty  * @return None.
1220797d5daeSCorey Hardesty  */
1221ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1222ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1223797d5daeSCorey Hardesty {
1224797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1225797d5daeSCorey Hardesty 
1226797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1227797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1228797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1229797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1230ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1231ac106bf6SEd Tanous             const boost::system::error_code& ec,
1232797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1233797d5daeSCorey Hardesty         if (ec)
1234797d5daeSCorey Hardesty         {
1235797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1236797d5daeSCorey Hardesty             {
1237797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1238ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1239797d5daeSCorey Hardesty             }
1240797d5daeSCorey Hardesty             return;
1241797d5daeSCorey Hardesty         }
1242797d5daeSCorey Hardesty 
1243797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1244797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1245797d5daeSCorey Hardesty 
1246797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1247797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1248797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1249797d5daeSCorey Hardesty 
1250797d5daeSCorey Hardesty         if (!success)
1251797d5daeSCorey Hardesty         {
1252ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1253797d5daeSCorey Hardesty             return;
1254797d5daeSCorey Hardesty         }
1255797d5daeSCorey Hardesty 
1256797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1257797d5daeSCorey Hardesty         {
1258ac106bf6SEd Tanous             asyncResp->res
1259ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1260797d5daeSCorey Hardesty                 *attemptsLeft;
1261797d5daeSCorey Hardesty         }
1262797d5daeSCorey Hardesty 
1263797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1264797d5daeSCorey Hardesty         {
1265ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1266797d5daeSCorey Hardesty                 *retryAttempts;
1267797d5daeSCorey Hardesty         }
1268797d5daeSCorey Hardesty         });
1269797d5daeSCorey Hardesty }
1270797d5daeSCorey Hardesty 
1271797d5daeSCorey Hardesty /**
12726bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12736bd5a8d2SGunnar Mills  *
1274ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12756bd5a8d2SGunnar Mills  *
12766bd5a8d2SGunnar Mills  * @return None.
12776bd5a8d2SGunnar Mills  */
1278797d5daeSCorey Hardesty inline void
1279ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12806bd5a8d2SGunnar Mills {
12816bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12826bd5a8d2SGunnar Mills 
12831e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12841e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12851e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12861e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1287ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1288ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12896bd5a8d2SGunnar Mills         if (ec)
12906bd5a8d2SGunnar Mills         {
1291797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1292797d5daeSCorey Hardesty             {
1293797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1294ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1295797d5daeSCorey Hardesty             }
12966bd5a8d2SGunnar Mills             return;
12976bd5a8d2SGunnar Mills         }
12986bd5a8d2SGunnar Mills 
12991e1e598dSJonathan Doman         BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1300e05aec50SEd Tanous         if (autoRebootEnabled)
13016bd5a8d2SGunnar Mills         {
1302ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13036bd5a8d2SGunnar Mills                 "RetryAttempts";
13046bd5a8d2SGunnar Mills         }
13056bd5a8d2SGunnar Mills         else
13066bd5a8d2SGunnar Mills         {
1307ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1308ac106bf6SEd Tanous                 "Disabled";
13096bd5a8d2SGunnar Mills         }
1310ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
131169f35306SGunnar Mills 
131269f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
131369f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
131469f35306SGunnar Mills         // RetryAttempts.
1315ac106bf6SEd Tanous         asyncResp->res
1316ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1317ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13181e1e598dSJonathan Doman         });
13196bd5a8d2SGunnar Mills }
13206bd5a8d2SGunnar Mills 
13216bd5a8d2SGunnar Mills /**
1322797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1323797d5daeSCorey Hardesty  *
1324ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1325797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1326797d5daeSCorey Hardesty  *
1327797d5daeSCorey Hardesty  *@return None.
1328797d5daeSCorey Hardesty  */
1329797d5daeSCorey Hardesty 
1330ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1331ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1332797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1333797d5daeSCorey Hardesty {
1334797d5daeSCorey Hardesty     BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
13359ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13369ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13379ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13389ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13399ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1340797d5daeSCorey Hardesty             if (ec)
1341797d5daeSCorey Hardesty             {
1342797d5daeSCorey Hardesty                 BMCWEB_LOG_ERROR
13439ae226faSGeorge Liu                     << "DBUS response error: Set setAutomaticRetryAttempts"
13449ae226faSGeorge Liu                     << ec;
1345ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1346797d5daeSCorey Hardesty                 return;
1347797d5daeSCorey Hardesty             }
13489ae226faSGeorge Liu         });
1349797d5daeSCorey Hardesty }
1350797d5daeSCorey Hardesty 
13518d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13528d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13538d69c668SEd Tanous {
13548d69c668SEd Tanous     if (value ==
13558d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13568d69c668SEd Tanous     {
13578d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13588d69c668SEd Tanous     }
13598d69c668SEd Tanous     if (value ==
13608d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13618d69c668SEd Tanous     {
13628d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13638d69c668SEd Tanous     }
13648d69c668SEd Tanous     if (value ==
13658d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
13668d69c668SEd Tanous     {
13678d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13688d69c668SEd Tanous     }
13698d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13708d69c668SEd Tanous     {
13718d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13728d69c668SEd Tanous     }
13738d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13748d69c668SEd Tanous }
1375797d5daeSCorey Hardesty /**
1376c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1377c6a620f2SGeorge Liu  *
1378ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1379c6a620f2SGeorge Liu  *
1380c6a620f2SGeorge Liu  * @return None.
1381c6a620f2SGeorge Liu  */
13828d1b46d7Szhanghch05 inline void
1383ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1384c6a620f2SGeorge Liu {
1385c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1386c6a620f2SGeorge Liu 
13871e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13881e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13891e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13901e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1391ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13925e7e2dc5SEd Tanous                     const std::string& policy) {
1393c6a620f2SGeorge Liu         if (ec)
1394c6a620f2SGeorge Liu         {
1395c6a620f2SGeorge Liu             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1396c6a620f2SGeorge Liu             return;
1397c6a620f2SGeorge Liu         }
13988d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
13998d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14008d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1401c6a620f2SGeorge Liu         {
1402ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1403c6a620f2SGeorge Liu             return;
1404c6a620f2SGeorge Liu         }
1405c6a620f2SGeorge Liu 
14068d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14071e1e598dSJonathan Doman         });
1408c6a620f2SGeorge Liu }
1409c6a620f2SGeorge Liu 
1410c6a620f2SGeorge Liu /**
1411*9dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
1412*9dcfe8c1SAlbert Zhang  *
1413*9dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
1414*9dcfe8c1SAlbert Zhang  *
1415*9dcfe8c1SAlbert Zhang  * @return None.
1416*9dcfe8c1SAlbert Zhang  */
1417*9dcfe8c1SAlbert Zhang inline void
1418*9dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1419*9dcfe8c1SAlbert Zhang {
1420*9dcfe8c1SAlbert Zhang     BMCWEB_LOG_DEBUG << "Get Stop Boot On Fault";
1421*9dcfe8c1SAlbert Zhang 
1422*9dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
1423*9dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1424*9dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1425*9dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1426*9dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
1427*9dcfe8c1SAlbert Zhang         if (ec)
1428*9dcfe8c1SAlbert Zhang         {
1429*9dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
1430*9dcfe8c1SAlbert Zhang             {
1431*9dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
1432*9dcfe8c1SAlbert Zhang             }
1433*9dcfe8c1SAlbert Zhang             return;
1434*9dcfe8c1SAlbert Zhang         }
1435*9dcfe8c1SAlbert Zhang 
1436*9dcfe8c1SAlbert Zhang         if (value)
1437*9dcfe8c1SAlbert Zhang         {
1438*9dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1439*9dcfe8c1SAlbert Zhang         }
1440*9dcfe8c1SAlbert Zhang         else
1441*9dcfe8c1SAlbert Zhang         {
1442*9dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1443*9dcfe8c1SAlbert Zhang         }
1444*9dcfe8c1SAlbert Zhang         });
1445*9dcfe8c1SAlbert Zhang }
1446*9dcfe8c1SAlbert Zhang 
1447*9dcfe8c1SAlbert Zhang /**
14481981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14491981771bSAli Ahmed  * TPM is required for booting the host.
14501981771bSAli Ahmed  *
1451ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14521981771bSAli Ahmed  *
14531981771bSAli Ahmed  * @return None.
14541981771bSAli Ahmed  */
14551981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1456ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14571981771bSAli Ahmed {
14581981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1459e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1460e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1461e99073f5SGeorge Liu     dbus::utility::getSubTree(
1462e99073f5SGeorge Liu         "/", 0, interfaces,
1463ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1464b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14651981771bSAli Ahmed         if (ec)
14661981771bSAli Ahmed         {
1467002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1468002d39b4SEd Tanous                              << ec;
14691981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14701981771bSAli Ahmed             // error occurs
14711981771bSAli Ahmed             return;
14721981771bSAli Ahmed         }
147326f6976fSEd Tanous         if (subtree.empty())
14741981771bSAli Ahmed         {
14751981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14761981771bSAli Ahmed             // if there is no instance found
14771981771bSAli Ahmed             return;
14781981771bSAli Ahmed         }
14791981771bSAli Ahmed 
14801981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14811981771bSAli Ahmed         if (subtree.size() > 1)
14821981771bSAli Ahmed         {
14831981771bSAli Ahmed             BMCWEB_LOG_DEBUG
14841981771bSAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
14851981771bSAli Ahmed                 << subtree.size();
14861981771bSAli Ahmed             // Throw an internal Error and return
1487ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14881981771bSAli Ahmed             return;
14891981771bSAli Ahmed         }
14901981771bSAli Ahmed 
14911981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14921981771bSAli Ahmed         // field
14931981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14941981771bSAli Ahmed         {
14951981771bSAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1496ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14971981771bSAli Ahmed             return;
14981981771bSAli Ahmed         }
14991981771bSAli Ahmed 
15001981771bSAli Ahmed         const std::string& path = subtree[0].first;
15011981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15021981771bSAli Ahmed 
15031981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15041e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15051e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15061e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1507ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1508ac106bf6SEd Tanous                         bool tpmRequired) {
15098a592810SEd Tanous             if (ec2)
15101981771bSAli Ahmed             {
1511002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
15128a592810SEd Tanous                                  << ec2;
1513ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15141981771bSAli Ahmed                 return;
15151981771bSAli Ahmed             }
15161981771bSAli Ahmed 
15171e1e598dSJonathan Doman             if (tpmRequired)
15181981771bSAli Ahmed             {
1519ac106bf6SEd Tanous                 asyncResp->res
1520ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15211981771bSAli Ahmed                     "Required";
15221981771bSAli Ahmed             }
15231981771bSAli Ahmed             else
15241981771bSAli Ahmed             {
1525ac106bf6SEd Tanous                 asyncResp->res
1526ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15271981771bSAli Ahmed                     "Disabled";
15281981771bSAli Ahmed             }
15291e1e598dSJonathan Doman             });
1530e99073f5SGeorge Liu         });
15311981771bSAli Ahmed }
15321981771bSAli Ahmed 
15331981771bSAli Ahmed /**
15341c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15351c05dae3SAli Ahmed  * TPM is required for booting the host.
15361c05dae3SAli Ahmed  *
1537ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15381c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15391c05dae3SAli Ahmed  *
15401c05dae3SAli Ahmed  * @return None.
15411c05dae3SAli Ahmed  */
15421c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1543ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15441c05dae3SAli Ahmed {
15451c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1546e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1547e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1548e99073f5SGeorge Liu     dbus::utility::getSubTree(
1549e99073f5SGeorge Liu         "/", 0, interfaces,
1550ac106bf6SEd Tanous         [asyncResp,
1551e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1552e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15531c05dae3SAli Ahmed         if (ec)
15541c05dae3SAli Ahmed         {
1555002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1556002d39b4SEd Tanous                              << ec;
1557ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15581c05dae3SAli Ahmed             return;
15591c05dae3SAli Ahmed         }
156026f6976fSEd Tanous         if (subtree.empty())
15611c05dae3SAli Ahmed         {
1562ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15631c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15641c05dae3SAli Ahmed             return;
15651c05dae3SAli Ahmed         }
15661c05dae3SAli Ahmed 
15671c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15681c05dae3SAli Ahmed         if (subtree.size() > 1)
15691c05dae3SAli Ahmed         {
15701c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG
15711c05dae3SAli Ahmed                 << "DBUS response has more than 1 TPM Enable object:"
15721c05dae3SAli Ahmed                 << subtree.size();
15731c05dae3SAli Ahmed             // Throw an internal Error and return
1574ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15751c05dae3SAli Ahmed             return;
15761c05dae3SAli Ahmed         }
15771c05dae3SAli Ahmed 
15781c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15791c05dae3SAli Ahmed         // field
15801c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15811c05dae3SAli Ahmed         {
15821c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1583ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15841c05dae3SAli Ahmed             return;
15851c05dae3SAli Ahmed         }
15861c05dae3SAli Ahmed 
15871c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15881c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15891c05dae3SAli Ahmed 
15901c05dae3SAli Ahmed         if (serv.empty())
15911c05dae3SAli Ahmed         {
15921c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1593ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15941c05dae3SAli Ahmed             return;
15951c05dae3SAli Ahmed         }
15961c05dae3SAli Ahmed 
15971c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15989ae226faSGeorge Liu         sdbusplus::asio::setProperty(
15999ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16009ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1601ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16028a592810SEd Tanous             if (ec2)
16031c05dae3SAli Ahmed             {
16040fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
16050fda0f12SGeorge Liu                     << "DBUS response error: Set TrustedModuleRequiredToBoot"
16068a592810SEd Tanous                     << ec2;
1607ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16081c05dae3SAli Ahmed                 return;
16091c05dae3SAli Ahmed             }
16101c05dae3SAli Ahmed             BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
16119ae226faSGeorge Liu             });
1612e99073f5SGeorge Liu         });
16131c05dae3SAli Ahmed }
16141c05dae3SAli Ahmed 
16151c05dae3SAli Ahmed /**
1616491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1617491d8ee7SSantosh Puranik  *
1618ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1619cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1620cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1621cd9a4666SKonstantin Aladyshev  */
1622ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1623cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1624cd9a4666SKonstantin Aladyshev {
1625c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1626cd9a4666SKonstantin Aladyshev 
1627c21865c4SKonstantin Aladyshev     if (!bootType)
1628cd9a4666SKonstantin Aladyshev     {
1629c21865c4SKonstantin Aladyshev         return;
1630c21865c4SKonstantin Aladyshev     }
1631c21865c4SKonstantin Aladyshev 
1632cd9a4666SKonstantin Aladyshev     // Source target specified
1633cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1634cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1635cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1636cd9a4666SKonstantin Aladyshev     {
1637cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1638cd9a4666SKonstantin Aladyshev     }
1639cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1640cd9a4666SKonstantin Aladyshev     {
1641cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1642cd9a4666SKonstantin Aladyshev     }
1643cd9a4666SKonstantin Aladyshev     else
1644cd9a4666SKonstantin Aladyshev     {
1645cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1646cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1647cd9a4666SKonstantin Aladyshev                          << *bootType;
1648ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1649cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1650cd9a4666SKonstantin Aladyshev         return;
1651cd9a4666SKonstantin Aladyshev     }
1652cd9a4666SKonstantin Aladyshev 
1653cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1654cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1655cd9a4666SKonstantin Aladyshev 
16569ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16579ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16589ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16599ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1660ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1661cd9a4666SKonstantin Aladyshev         if (ec)
1662cd9a4666SKonstantin Aladyshev         {
1663cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1664cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1665cd9a4666SKonstantin Aladyshev             {
1666ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1667cd9a4666SKonstantin Aladyshev                 return;
1668cd9a4666SKonstantin Aladyshev             }
1669ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1670cd9a4666SKonstantin Aladyshev             return;
1671cd9a4666SKonstantin Aladyshev         }
1672cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot type update done.";
16739ae226faSGeorge Liu         });
1674cd9a4666SKonstantin Aladyshev }
1675cd9a4666SKonstantin Aladyshev 
1676cd9a4666SKonstantin Aladyshev /**
1677cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1678cd9a4666SKonstantin Aladyshev  *
1679ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1680ac106bf6SEd Tanous  * message.
1681c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1682c21865c4SKonstantin Aladyshev  * @return Integer error code.
1683c21865c4SKonstantin Aladyshev  */
1684ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1685c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1686c21865c4SKonstantin Aladyshev {
1687c21865c4SKonstantin Aladyshev     if (!bootEnable)
1688c21865c4SKonstantin Aladyshev     {
1689c21865c4SKonstantin Aladyshev         return;
1690c21865c4SKonstantin Aladyshev     }
1691c21865c4SKonstantin Aladyshev     // Source target specified
1692c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1693c21865c4SKonstantin Aladyshev 
1694c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1695c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1696c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1697c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1698c21865c4SKonstantin Aladyshev     {
1699c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1700c21865c4SKonstantin Aladyshev     }
1701c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1702c21865c4SKonstantin Aladyshev     {
1703c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1704c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1705c21865c4SKonstantin Aladyshev     }
1706c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1707c21865c4SKonstantin Aladyshev     {
1708c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1709c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1710c21865c4SKonstantin Aladyshev     }
1711c21865c4SKonstantin Aladyshev     else
1712c21865c4SKonstantin Aladyshev     {
17130fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
17140fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1715c21865c4SKonstantin Aladyshev             << *bootEnable;
1716ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1717c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1718c21865c4SKonstantin Aladyshev         return;
1719c21865c4SKonstantin Aladyshev     }
1720c21865c4SKonstantin Aladyshev 
1721c21865c4SKonstantin Aladyshev     // Act on validated parameters
1722c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1723c21865c4SKonstantin Aladyshev 
17249ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17259ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17269ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17279ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1728ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17298a592810SEd Tanous         if (ec2)
1730c21865c4SKonstantin Aladyshev         {
17318a592810SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
1732ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1733c21865c4SKonstantin Aladyshev             return;
1734c21865c4SKonstantin Aladyshev         }
1735c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot override enable update done.";
17369ae226faSGeorge Liu         });
1737c21865c4SKonstantin Aladyshev 
1738c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1739c21865c4SKonstantin Aladyshev     {
1740c21865c4SKonstantin Aladyshev         return;
1741c21865c4SKonstantin Aladyshev     }
1742c21865c4SKonstantin Aladyshev 
1743c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1744c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1745c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1746c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1747c21865c4SKonstantin Aladyshev 
17489ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17499ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17509ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17519ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1752ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1753c21865c4SKonstantin Aladyshev         if (ec)
1754c21865c4SKonstantin Aladyshev         {
1755c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1756ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1757c21865c4SKonstantin Aladyshev             return;
1758c21865c4SKonstantin Aladyshev         }
1759c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Boot one_time update done.";
17609ae226faSGeorge Liu         });
1761c21865c4SKonstantin Aladyshev }
1762c21865c4SKonstantin Aladyshev 
1763c21865c4SKonstantin Aladyshev /**
1764c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1765c21865c4SKonstantin Aladyshev  *
1766ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1767491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1768491d8ee7SSantosh Puranik  *
1769265c1602SJohnathan Mantey  * @return Integer error code.
1770491d8ee7SSantosh Puranik  */
1771ac106bf6SEd Tanous inline void
1772ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1773cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1774491d8ee7SSantosh Puranik {
1775c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1776c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1777944ffaf9SJohnathan Mantey 
1778c21865c4SKonstantin Aladyshev     if (!bootSource)
1779491d8ee7SSantosh Puranik     {
1780c21865c4SKonstantin Aladyshev         return;
1781c21865c4SKonstantin Aladyshev     }
1782c21865c4SKonstantin Aladyshev 
1783491d8ee7SSantosh Puranik     // Source target specified
1784491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1785491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1786ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1787ac106bf6SEd Tanous                              bootModeStr) != 0)
1788491d8ee7SSantosh Puranik     {
1789944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1790944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1791491d8ee7SSantosh Puranik             << *bootSource;
1792ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1793491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1794491d8ee7SSantosh Puranik         return;
1795491d8ee7SSantosh Puranik     }
1796491d8ee7SSantosh Puranik 
1797944ffaf9SJohnathan Mantey     // Act on validated parameters
1798944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1799944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1800944ffaf9SJohnathan Mantey 
18019ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18029ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18039ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18049ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1805ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1806491d8ee7SSantosh Puranik         if (ec)
1807491d8ee7SSantosh Puranik         {
1808491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1809ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1810491d8ee7SSantosh Puranik             return;
1811491d8ee7SSantosh Puranik         }
1812491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot source update done.";
18139ae226faSGeorge Liu         });
1814944ffaf9SJohnathan Mantey 
18159ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18169ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18179ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18189ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1819ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1820491d8ee7SSantosh Puranik         if (ec)
1821491d8ee7SSantosh Puranik         {
1822491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1823ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1824491d8ee7SSantosh Puranik             return;
1825491d8ee7SSantosh Puranik         }
1826491d8ee7SSantosh Puranik         BMCWEB_LOG_DEBUG << "Boot mode update done.";
18279ae226faSGeorge Liu         });
1828cd9a4666SKonstantin Aladyshev }
1829944ffaf9SJohnathan Mantey 
1830cd9a4666SKonstantin Aladyshev /**
1831c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1832491d8ee7SSantosh Puranik  *
1833ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1834491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1835cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1836491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1837491d8ee7SSantosh Puranik  *
1838265c1602SJohnathan Mantey  * @return Integer error code.
1839491d8ee7SSantosh Puranik  */
1840c21865c4SKonstantin Aladyshev 
1841ac106bf6SEd Tanous inline void
1842ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1843c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1844c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1845c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1846491d8ee7SSantosh Puranik {
1847491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1848491d8ee7SSantosh Puranik 
1849ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1850ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1851ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1852491d8ee7SSantosh Puranik }
1853491d8ee7SSantosh Puranik 
1854c6a620f2SGeorge Liu /**
185598e386ecSGunnar Mills  * @brief Sets AssetTag
185698e386ecSGunnar Mills  *
1857ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
185898e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
185998e386ecSGunnar Mills  *
186098e386ecSGunnar Mills  * @return None.
186198e386ecSGunnar Mills  */
1862ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
186398e386ecSGunnar Mills                         const std::string& assetTag)
186498e386ecSGunnar Mills {
1865e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1866e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1867e99073f5SGeorge Liu     dbus::utility::getSubTree(
1868e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1869ac106bf6SEd Tanous         [asyncResp,
1870e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1871b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
187298e386ecSGunnar Mills         if (ec)
187398e386ecSGunnar Mills         {
187498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1875ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
187698e386ecSGunnar Mills             return;
187798e386ecSGunnar Mills         }
187826f6976fSEd Tanous         if (subtree.empty())
187998e386ecSGunnar Mills         {
188098e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1881ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188298e386ecSGunnar Mills             return;
188398e386ecSGunnar Mills         }
188498e386ecSGunnar Mills         // Assume only 1 system D-Bus object
188598e386ecSGunnar Mills         // Throw an error if there is more than 1
188698e386ecSGunnar Mills         if (subtree.size() > 1)
188798e386ecSGunnar Mills         {
188898e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1889ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189098e386ecSGunnar Mills             return;
189198e386ecSGunnar Mills         }
189298e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
189398e386ecSGunnar Mills         {
189498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1895ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189698e386ecSGunnar Mills             return;
189798e386ecSGunnar Mills         }
189898e386ecSGunnar Mills 
189998e386ecSGunnar Mills         const std::string& path = subtree[0].first;
190098e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
190198e386ecSGunnar Mills 
190298e386ecSGunnar Mills         if (service.empty())
190398e386ecSGunnar Mills         {
190498e386ecSGunnar Mills             BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1905ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190698e386ecSGunnar Mills             return;
190798e386ecSGunnar Mills         }
190898e386ecSGunnar Mills 
19099ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19109ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19119ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19129ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
191398e386ecSGunnar Mills                 if (ec2)
191498e386ecSGunnar Mills                 {
1915002d39b4SEd Tanous                     BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1916002d39b4SEd Tanous                                      << ec2;
1917ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
191898e386ecSGunnar Mills                     return;
191998e386ecSGunnar Mills                 }
19209ae226faSGeorge Liu             });
1921e99073f5SGeorge Liu         });
192298e386ecSGunnar Mills }
192398e386ecSGunnar Mills 
192498e386ecSGunnar Mills /**
1925*9dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
1926*9dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
1927*9dcfe8c1SAlbert Zhang  *
1928*9dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
1929*9dcfe8c1SAlbert Zhang  * stopBootOnFault
1930*9dcfe8c1SAlbert Zhang  *
1931*9dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
1932*9dcfe8c1SAlbert Zhang  */
1933*9dcfe8c1SAlbert Zhang inline std::optional<bool>
1934*9dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
1935*9dcfe8c1SAlbert Zhang {
1936*9dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
1937*9dcfe8c1SAlbert Zhang     {
1938*9dcfe8c1SAlbert Zhang         return true;
1939*9dcfe8c1SAlbert Zhang     }
1940*9dcfe8c1SAlbert Zhang 
1941*9dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
1942*9dcfe8c1SAlbert Zhang     {
1943*9dcfe8c1SAlbert Zhang         return false;
1944*9dcfe8c1SAlbert Zhang     }
1945*9dcfe8c1SAlbert Zhang 
1946*9dcfe8c1SAlbert Zhang     return std::nullopt;
1947*9dcfe8c1SAlbert Zhang }
1948*9dcfe8c1SAlbert Zhang 
1949*9dcfe8c1SAlbert Zhang /**
1950*9dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
1951*9dcfe8c1SAlbert Zhang  *
1952*9dcfe8c1SAlbert Zhang  * @param[in] aResp   Shared pointer for generating response message.
1953*9dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
1954*9dcfe8c1SAlbert Zhang  *
1955*9dcfe8c1SAlbert Zhang  * @return None.
1956*9dcfe8c1SAlbert Zhang  */
1957*9dcfe8c1SAlbert Zhang inline void setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1958*9dcfe8c1SAlbert Zhang                                const std::string& stopBootOnFault)
1959*9dcfe8c1SAlbert Zhang {
1960*9dcfe8c1SAlbert Zhang     BMCWEB_LOG_DEBUG << "Set Stop Boot On Fault.";
1961*9dcfe8c1SAlbert Zhang 
1962*9dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1963*9dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
1964*9dcfe8c1SAlbert Zhang     {
1965*9dcfe8c1SAlbert Zhang         BMCWEB_LOG_DEBUG << "Invalid property value for StopBootOnFault: "
1966*9dcfe8c1SAlbert Zhang                          << stopBootOnFault;
1967*9dcfe8c1SAlbert Zhang         messages::propertyValueNotInList(aResp->res, stopBootOnFault,
1968*9dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
1969*9dcfe8c1SAlbert Zhang         return;
1970*9dcfe8c1SAlbert Zhang     }
1971*9dcfe8c1SAlbert Zhang 
1972*9dcfe8c1SAlbert Zhang     sdbusplus::asio::setProperty(*crow::connections::systemBus,
1973*9dcfe8c1SAlbert Zhang                                  "xyz.openbmc_project.Settings",
1974*9dcfe8c1SAlbert Zhang                                  "/xyz/openbmc_project/logging/settings",
1975*9dcfe8c1SAlbert Zhang                                  "xyz.openbmc_project.Logging.Settings",
1976*9dcfe8c1SAlbert Zhang                                  "QuiesceOnHwError", *stopBootEnabled,
1977*9dcfe8c1SAlbert Zhang                                  [aResp](const boost::system::error_code& ec) {
1978*9dcfe8c1SAlbert Zhang         if (ec)
1979*9dcfe8c1SAlbert Zhang         {
1980*9dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
1981*9dcfe8c1SAlbert Zhang             {
1982*9dcfe8c1SAlbert Zhang                 messages::internalError(aResp->res);
1983*9dcfe8c1SAlbert Zhang             }
1984*9dcfe8c1SAlbert Zhang             return;
1985*9dcfe8c1SAlbert Zhang         }
1986*9dcfe8c1SAlbert Zhang     });
1987*9dcfe8c1SAlbert Zhang }
1988*9dcfe8c1SAlbert Zhang 
1989*9dcfe8c1SAlbert Zhang /**
199069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
199169f35306SGunnar Mills  *
1992ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
199369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
199469f35306SGunnar Mills  *
199569f35306SGunnar Mills  * @return None.
199669f35306SGunnar Mills  */
1997ac106bf6SEd Tanous inline void
1998ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1999f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
200069f35306SGunnar Mills {
200169f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
200269f35306SGunnar Mills 
200369f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2004543f4400SEd Tanous     bool autoRebootEnabled = false;
200569f35306SGunnar Mills 
200669f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
200769f35306SGunnar Mills     {
200869f35306SGunnar Mills         autoRebootEnabled = false;
200969f35306SGunnar Mills     }
201069f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
201169f35306SGunnar Mills     {
201269f35306SGunnar Mills         autoRebootEnabled = true;
201369f35306SGunnar Mills     }
201469f35306SGunnar Mills     else
201569f35306SGunnar Mills     {
20160fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
201769f35306SGunnar Mills                          << automaticRetryConfig;
2018ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
201969f35306SGunnar Mills                                          "AutomaticRetryConfig");
202069f35306SGunnar Mills         return;
202169f35306SGunnar Mills     }
202269f35306SGunnar Mills 
20239ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20249ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20259ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20269ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20279ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
202869f35306SGunnar Mills             if (ec)
202969f35306SGunnar Mills             {
2030ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
203169f35306SGunnar Mills                 return;
203269f35306SGunnar Mills             }
20339ae226faSGeorge Liu         });
203469f35306SGunnar Mills }
203569f35306SGunnar Mills 
20368d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20378d69c668SEd Tanous {
20388d69c668SEd Tanous     if (policy == "AlwaysOn")
20398d69c668SEd Tanous     {
20408d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20418d69c668SEd Tanous     }
20428d69c668SEd Tanous     if (policy == "AlwaysOff")
20438d69c668SEd Tanous     {
20448d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20458d69c668SEd Tanous     }
20468d69c668SEd Tanous     if (policy == "LastState")
20478d69c668SEd Tanous     {
20488d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20498d69c668SEd Tanous     }
20508d69c668SEd Tanous     return "";
20518d69c668SEd Tanous }
20528d69c668SEd Tanous 
205369f35306SGunnar Mills /**
2054c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2055c6a620f2SGeorge Liu  *
2056ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2057c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2058c6a620f2SGeorge Liu  *
2059c6a620f2SGeorge Liu  * @return None.
2060c6a620f2SGeorge Liu  */
20618d1b46d7Szhanghch05 inline void
2062ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20638d69c668SEd Tanous                           std::string_view policy)
2064c6a620f2SGeorge Liu {
2065c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
2066c6a620f2SGeorge Liu 
20678d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2068c6a620f2SGeorge Liu 
20698d69c668SEd Tanous     if (powerRestorePolicy.empty())
2070c6a620f2SGeorge Liu     {
2071ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20724e69c904SGunnar Mills                                          "PowerRestorePolicy");
2073c6a620f2SGeorge Liu         return;
2074c6a620f2SGeorge Liu     }
2075c6a620f2SGeorge Liu 
20769ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20779ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20789ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20799ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20809ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2081c6a620f2SGeorge Liu             if (ec)
2082c6a620f2SGeorge Liu             {
2083ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2084c6a620f2SGeorge Liu                 return;
2085c6a620f2SGeorge Liu             }
20869ae226faSGeorge Liu         });
2087c6a620f2SGeorge Liu }
2088c6a620f2SGeorge Liu 
2089a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2090a6349918SAppaRao Puli /**
2091a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2092a6349918SAppaRao Puli  *
2093ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2094a6349918SAppaRao Puli  *
2095a6349918SAppaRao Puli  * @return None.
2096a6349918SAppaRao Puli  */
2097ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2098a6349918SAppaRao Puli {
2099a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
2100bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2101bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2102bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2103ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2104b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2105b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2106ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2107ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
210850626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
210950626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
211050626f4fSJames Feist 
2111a6349918SAppaRao Puli         if (ec)
2112a6349918SAppaRao Puli         {
2113a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2114b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2115b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2116a6349918SAppaRao Puli             return;
2117a6349918SAppaRao Puli         }
2118a6349918SAppaRao Puli 
2119a6349918SAppaRao Puli         const bool* provState = nullptr;
2120a6349918SAppaRao Puli         const bool* lockState = nullptr;
2121bc1d29deSKrzysztof Grobelny 
2122bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21230d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21240d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2125bc1d29deSKrzysztof Grobelny 
2126bc1d29deSKrzysztof Grobelny         if (!success)
2127a6349918SAppaRao Puli         {
2128ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2129bc1d29deSKrzysztof Grobelny             return;
2130a6349918SAppaRao Puli         }
2131a6349918SAppaRao Puli 
2132a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2133a6349918SAppaRao Puli         {
2134a6349918SAppaRao Puli             BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
2135ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2136a6349918SAppaRao Puli             return;
2137a6349918SAppaRao Puli         }
2138a6349918SAppaRao Puli 
2139a6349918SAppaRao Puli         if (*provState == true)
2140a6349918SAppaRao Puli         {
2141a6349918SAppaRao Puli             if (*lockState == true)
2142a6349918SAppaRao Puli             {
2143a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2144a6349918SAppaRao Puli             }
2145a6349918SAppaRao Puli             else
2146a6349918SAppaRao Puli             {
2147a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2148a6349918SAppaRao Puli             }
2149a6349918SAppaRao Puli         }
2150a6349918SAppaRao Puli         else
2151a6349918SAppaRao Puli         {
2152a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2153a6349918SAppaRao Puli         }
2154bc1d29deSKrzysztof Grobelny         });
2155a6349918SAppaRao Puli }
2156a6349918SAppaRao Puli #endif
2157a6349918SAppaRao Puli 
2158491d8ee7SSantosh Puranik /**
21593a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
21603a2d0424SChris Cain  *
2161ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21623a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
21633a2d0424SChris Cain  *
21643a2d0424SChris Cain  * @return None.
21653a2d0424SChris Cain  */
2166ac106bf6SEd Tanous inline void
2167ac106bf6SEd Tanous     translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21683a2d0424SChris Cain                        const std::string& modeValue)
21693a2d0424SChris Cain {
21700fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21713a2d0424SChris Cain     {
2172ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "Static";
21733a2d0424SChris Cain     }
21740fda0f12SGeorge Liu     else if (
21750fda0f12SGeorge Liu         modeValue ==
21760fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21773a2d0424SChris Cain     {
2178ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
21793a2d0424SChris Cain     }
21800fda0f12SGeorge Liu     else if (modeValue ==
21810fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21823a2d0424SChris Cain     {
2183ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
21843a2d0424SChris Cain     }
21850fda0f12SGeorge Liu     else if (modeValue ==
21860fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21873a2d0424SChris Cain     {
2188ac106bf6SEd Tanous         asyncResp->res.jsonValue["PowerMode"] = "OEM";
21893a2d0424SChris Cain     }
21903a2d0424SChris Cain     else
21913a2d0424SChris Cain     {
21923a2d0424SChris Cain         // Any other values would be invalid
21933a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
2194ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
21953a2d0424SChris Cain     }
21963a2d0424SChris Cain }
21973a2d0424SChris Cain 
21983a2d0424SChris Cain /**
21993a2d0424SChris Cain  * @brief Retrieves system power mode
22003a2d0424SChris Cain  *
2201ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22023a2d0424SChris Cain  *
22033a2d0424SChris Cain  * @return None.
22043a2d0424SChris Cain  */
2205ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22063a2d0424SChris Cain {
22073a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
22083a2d0424SChris Cain 
22093a2d0424SChris Cain     // Get Power Mode object path:
2210e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2211e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2212e99073f5SGeorge Liu     dbus::utility::getSubTree(
2213e99073f5SGeorge Liu         "/", 0, interfaces,
2214ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2215b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22163a2d0424SChris Cain         if (ec)
22173a2d0424SChris Cain         {
2218002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2219002d39b4SEd Tanous                              << ec;
22203a2d0424SChris Cain             // This is an optional D-Bus object so just return if
22213a2d0424SChris Cain             // error occurs
22223a2d0424SChris Cain             return;
22233a2d0424SChris Cain         }
22243a2d0424SChris Cain         if (subtree.empty())
22253a2d0424SChris Cain         {
22263a2d0424SChris Cain             // As noted above, this is an optional interface so just return
22273a2d0424SChris Cain             // if there is no instance found
22283a2d0424SChris Cain             return;
22293a2d0424SChris Cain         }
22303a2d0424SChris Cain         if (subtree.size() > 1)
22313a2d0424SChris Cain         {
22323a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22333a2d0424SChris Cain             // error
22343a2d0424SChris Cain             BMCWEB_LOG_DEBUG
22353a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
22363a2d0424SChris Cain                 << subtree.size();
2237ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22383a2d0424SChris Cain             return;
22393a2d0424SChris Cain         }
22403a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22413a2d0424SChris Cain         {
22423a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2243ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22443a2d0424SChris Cain             return;
22453a2d0424SChris Cain         }
22463a2d0424SChris Cain         const std::string& path = subtree[0].first;
22473a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22483a2d0424SChris Cain         if (service.empty())
22493a2d0424SChris Cain         {
22503a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2251ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22523a2d0424SChris Cain             return;
22533a2d0424SChris Cain         }
22543a2d0424SChris Cain         // Valid Power Mode object found, now read the current value
22551e1e598dSJonathan Doman         sdbusplus::asio::getProperty<std::string>(
22561e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22571e1e598dSJonathan Doman             "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2258ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22591e1e598dSJonathan Doman                         const std::string& pmode) {
22608a592810SEd Tanous             if (ec2)
22613a2d0424SChris Cain             {
2262002d39b4SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
22638a592810SEd Tanous                                  << ec2;
2264ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22653a2d0424SChris Cain                 return;
22663a2d0424SChris Cain             }
22673a2d0424SChris Cain 
2268ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2269002d39b4SEd Tanous                 "Static", "MaximumPerformance", "PowerSaving"};
22703a2d0424SChris Cain 
22711e1e598dSJonathan Doman             BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2272ac106bf6SEd Tanous             translatePowerMode(asyncResp, pmode);
22731e1e598dSJonathan Doman             });
2274e99073f5SGeorge Liu         });
22753a2d0424SChris Cain }
22763a2d0424SChris Cain 
22773a2d0424SChris Cain /**
22783a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22793a2d0424SChris Cain  * name associated with that string
22803a2d0424SChris Cain  *
2281ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22823a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
22833a2d0424SChris Cain  *
22843a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22853a2d0424SChris Cain  */
22863a2d0424SChris Cain inline std::string
2287ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22883a2d0424SChris Cain                       const std::string& modeString)
22893a2d0424SChris Cain {
22903a2d0424SChris Cain     std::string mode;
22913a2d0424SChris Cain 
22923a2d0424SChris Cain     if (modeString == "Static")
22933a2d0424SChris Cain     {
22943a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22953a2d0424SChris Cain     }
22963a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
22973a2d0424SChris Cain     {
22980fda0f12SGeorge Liu         mode =
22990fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23003a2d0424SChris Cain     }
23013a2d0424SChris Cain     else if (modeString == "PowerSaving")
23023a2d0424SChris Cain     {
23033a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23043a2d0424SChris Cain     }
23053a2d0424SChris Cain     else
23063a2d0424SChris Cain     {
2307ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, modeString,
2308ac106bf6SEd Tanous                                          "PowerMode");
23093a2d0424SChris Cain     }
23103a2d0424SChris Cain     return mode;
23113a2d0424SChris Cain }
23123a2d0424SChris Cain 
23133a2d0424SChris Cain /**
23143a2d0424SChris Cain  * @brief Sets system power mode.
23153a2d0424SChris Cain  *
2316ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23173a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23183a2d0424SChris Cain  *
23193a2d0424SChris Cain  * @return None.
23203a2d0424SChris Cain  */
2321ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23223a2d0424SChris Cain                          const std::string& pmode)
23233a2d0424SChris Cain {
23243a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
23253a2d0424SChris Cain 
2326ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23273a2d0424SChris Cain     if (powerMode.empty())
23283a2d0424SChris Cain     {
23293a2d0424SChris Cain         return;
23303a2d0424SChris Cain     }
23313a2d0424SChris Cain 
23323a2d0424SChris Cain     // Get Power Mode object path:
2333e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2334e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2335e99073f5SGeorge Liu     dbus::utility::getSubTree(
2336e99073f5SGeorge Liu         "/", 0, interfaces,
2337ac106bf6SEd Tanous         [asyncResp,
2338e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2339b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23403a2d0424SChris Cain         if (ec)
23413a2d0424SChris Cain         {
2342002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2343002d39b4SEd Tanous                              << ec;
23443a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2345ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23463a2d0424SChris Cain             return;
23473a2d0424SChris Cain         }
23483a2d0424SChris Cain         if (subtree.empty())
23493a2d0424SChris Cain         {
23503a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2351ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23523a2d0424SChris Cain                                        "PowerMode");
23533a2d0424SChris Cain             return;
23543a2d0424SChris Cain         }
23553a2d0424SChris Cain         if (subtree.size() > 1)
23563a2d0424SChris Cain         {
23573a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23583a2d0424SChris Cain             // error
23593a2d0424SChris Cain             BMCWEB_LOG_DEBUG
23603a2d0424SChris Cain                 << "Found more than 1 system D-Bus Power.Mode objects: "
23613a2d0424SChris Cain                 << subtree.size();
2362ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23633a2d0424SChris Cain             return;
23643a2d0424SChris Cain         }
23653a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23663a2d0424SChris Cain         {
23673a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2368ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23693a2d0424SChris Cain             return;
23703a2d0424SChris Cain         }
23713a2d0424SChris Cain         const std::string& path = subtree[0].first;
23723a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23733a2d0424SChris Cain         if (service.empty())
23743a2d0424SChris Cain         {
23753a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2376ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23773a2d0424SChris Cain             return;
23783a2d0424SChris Cain         }
23793a2d0424SChris Cain 
23803a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
23813a2d0424SChris Cain                          << path;
23823a2d0424SChris Cain 
23833a2d0424SChris Cain         // Set the Power Mode property
23849ae226faSGeorge Liu         sdbusplus::asio::setProperty(
23859ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
23869ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2387ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
23888a592810SEd Tanous             if (ec2)
23893a2d0424SChris Cain             {
2390ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
23913a2d0424SChris Cain                 return;
23923a2d0424SChris Cain             }
23939ae226faSGeorge Liu             });
2394e99073f5SGeorge Liu         });
23953a2d0424SChris Cain }
23963a2d0424SChris Cain 
23973a2d0424SChris Cain /**
239851709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
239951709ffdSYong Li  *
240051709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
240151709ffdSYong Li  *
240251709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
240351709ffdSYong Li  * translation cannot be done, returns an empty string.
240451709ffdSYong Li  */
240523a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
240651709ffdSYong Li {
240751709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
240851709ffdSYong Li     {
240951709ffdSYong Li         return "None";
241051709ffdSYong Li     }
24113174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
241251709ffdSYong Li     {
241351709ffdSYong Li         return "ResetSystem";
241451709ffdSYong Li     }
24153174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
241651709ffdSYong Li     {
241751709ffdSYong Li         return "PowerDown";
241851709ffdSYong Li     }
24193174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
242051709ffdSYong Li     {
242151709ffdSYong Li         return "PowerCycle";
242251709ffdSYong Li     }
242351709ffdSYong Li 
242451709ffdSYong Li     return "";
242551709ffdSYong Li }
242651709ffdSYong Li 
242751709ffdSYong Li /**
2428c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2429c45f0082SYong Li  *
2430c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2431c45f0082SYong Li  *
2432c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2433c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2434c45f0082SYong Li  */
2435c45f0082SYong Li 
243623a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2437c45f0082SYong Li {
2438c45f0082SYong Li     if (rfAction == "None")
2439c45f0082SYong Li     {
2440c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2441c45f0082SYong Li     }
24423174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2443c45f0082SYong Li     {
2444c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2445c45f0082SYong Li     }
24463174e4dfSEd Tanous     if (rfAction == "PowerDown")
2447c45f0082SYong Li     {
2448c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2449c45f0082SYong Li     }
24503174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2451c45f0082SYong Li     {
2452c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2453c45f0082SYong Li     }
2454c45f0082SYong Li 
2455c45f0082SYong Li     return "";
2456c45f0082SYong Li }
2457c45f0082SYong Li 
2458c45f0082SYong Li /**
245951709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
246051709ffdSYong Li  *
2461ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
246251709ffdSYong Li  *
246351709ffdSYong Li  * @return None.
246451709ffdSYong Li  */
24658d1b46d7Szhanghch05 inline void
2466ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
246751709ffdSYong Li {
246851709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
2469bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2470bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2471bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2472bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2473ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2474b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
247551709ffdSYong Li         if (ec)
247651709ffdSYong Li         {
247751709ffdSYong Li             // watchdog service is stopped
247851709ffdSYong Li             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
247951709ffdSYong Li             return;
248051709ffdSYong Li         }
248151709ffdSYong Li 
248251709ffdSYong Li         BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
248351709ffdSYong Li 
248451709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2485ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
248651709ffdSYong Li 
248751709ffdSYong Li         // watchdog service is running/enabled
248851709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
248951709ffdSYong Li 
2490bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2491bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
249251709ffdSYong Li 
2493bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2494bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2495bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2496bc1d29deSKrzysztof Grobelny 
2497bc1d29deSKrzysztof Grobelny         if (!success)
249851709ffdSYong Li         {
2499ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2500601af5edSChicago Duan             return;
250151709ffdSYong Li         }
250251709ffdSYong Li 
2503bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
250451709ffdSYong Li         {
2505bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
250651709ffdSYong Li         }
250751709ffdSYong Li 
2508bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2509bc1d29deSKrzysztof Grobelny         {
2510bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
251151709ffdSYong Li             if (action.empty())
251251709ffdSYong Li             {
2513ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2514601af5edSChicago Duan                 return;
251551709ffdSYong Li             }
251651709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
251751709ffdSYong Li         }
2518bc1d29deSKrzysztof Grobelny         });
251951709ffdSYong Li }
252051709ffdSYong Li 
252151709ffdSYong Li /**
2522c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2523c45f0082SYong Li  *
2524ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2525c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2526c45f0082SYong Li  *                       RF request.
2527c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2528c45f0082SYong Li  *
2529c45f0082SYong Li  * @return None.
2530c45f0082SYong Li  */
2531ac106bf6SEd Tanous inline void
2532ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2533c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2534c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2535c45f0082SYong Li {
2536c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2537c45f0082SYong Li 
2538c45f0082SYong Li     if (wdtTimeOutAction)
2539c45f0082SYong Li     {
2540c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2541c45f0082SYong Li         // check if TimeOut Action is Valid
2542c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2543c45f0082SYong Li         {
2544c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2545c45f0082SYong Li                              << *wdtTimeOutAction;
2546ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2547c45f0082SYong Li                                              "TimeoutAction");
2548c45f0082SYong Li             return;
2549c45f0082SYong Li         }
2550c45f0082SYong Li 
25519ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25529ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25539ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25549ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
25559ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2556c45f0082SYong Li                 if (ec)
2557c45f0082SYong Li                 {
2558c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2559ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
2560c45f0082SYong Li                     return;
2561c45f0082SYong Li                 }
25629ae226faSGeorge Liu             });
2563c45f0082SYong Li     }
2564c45f0082SYong Li 
2565c45f0082SYong Li     if (wdtEnable)
2566c45f0082SYong Li     {
25679ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25689ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25699ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25709ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2571ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2572c45f0082SYong Li             if (ec)
2573c45f0082SYong Li             {
2574c45f0082SYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2575ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2576c45f0082SYong Li                 return;
2577c45f0082SYong Li             }
25789ae226faSGeorge Liu             });
2579c45f0082SYong Li     }
2580c45f0082SYong Li }
2581c45f0082SYong Li 
258237bbf98cSChris Cain /**
258337bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
258437bbf98cSChris Cain  *
2585ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
258637bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
258737bbf98cSChris Cain  *
258837bbf98cSChris Cain  * @return true if successful
258937bbf98cSChris Cain  */
25901e5b7c88SJiaqing Zhao inline bool
2591ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25921e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
259337bbf98cSChris Cain {
2594bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2595bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2596bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2597bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2598bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2599bc1d29deSKrzysztof Grobelny 
2600bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2601bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26022661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26032661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26042661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2605bc1d29deSKrzysztof Grobelny 
2606bc1d29deSKrzysztof Grobelny     if (!success)
260737bbf98cSChris Cain     {
260837bbf98cSChris Cain         return false;
260937bbf98cSChris Cain     }
2610bc1d29deSKrzysztof Grobelny 
2611bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
261237bbf98cSChris Cain     {
2613ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
261437bbf98cSChris Cain     }
2615bc1d29deSKrzysztof Grobelny 
2616bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
261737bbf98cSChris Cain     {
2618ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2619bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
262037bbf98cSChris Cain     }
2621bc1d29deSKrzysztof Grobelny 
2622bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2623bc1d29deSKrzysztof Grobelny     {
2624bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2625ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
262637bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
262737bbf98cSChris Cain                 .count();
262837bbf98cSChris Cain     }
2629bc1d29deSKrzysztof Grobelny 
2630bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
263137bbf98cSChris Cain     {
2632ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2633bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
263437bbf98cSChris Cain     }
2635bc1d29deSKrzysztof Grobelny 
2636bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
263737bbf98cSChris Cain     {
2638bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2639ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
264037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
264137bbf98cSChris Cain                 .count();
264237bbf98cSChris Cain     }
264337bbf98cSChris Cain 
264437bbf98cSChris Cain     return true;
264537bbf98cSChris Cain }
264637bbf98cSChris Cain 
264737bbf98cSChris Cain /**
264837bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
264937bbf98cSChris Cain  *
2650ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
265137bbf98cSChris Cain  *
265237bbf98cSChris Cain  * @return None.
265337bbf98cSChris Cain  */
2654ac106bf6SEd Tanous inline void
2655ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
265637bbf98cSChris Cain {
265737bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
265837bbf98cSChris Cain 
265937bbf98cSChris Cain     // Get IdlePowerSaver object path:
2660e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2661e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2662e99073f5SGeorge Liu     dbus::utility::getSubTree(
2663e99073f5SGeorge Liu         "/", 0, interfaces,
2664ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2665b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
266637bbf98cSChris Cain         if (ec)
266737bbf98cSChris Cain         {
266837bbf98cSChris Cain             BMCWEB_LOG_DEBUG
266937bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
267037bbf98cSChris Cain                 << ec;
2671ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
267237bbf98cSChris Cain             return;
267337bbf98cSChris Cain         }
267437bbf98cSChris Cain         if (subtree.empty())
267537bbf98cSChris Cain         {
267637bbf98cSChris Cain             // This is an optional interface so just return
267737bbf98cSChris Cain             // if there is no instance found
267837bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "No instances found";
267937bbf98cSChris Cain             return;
268037bbf98cSChris Cain         }
268137bbf98cSChris Cain         if (subtree.size() > 1)
268237bbf98cSChris Cain         {
268337bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
268437bbf98cSChris Cain             // is an error
268537bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
268637bbf98cSChris Cain                                 "Power.IdlePowerSaver objects: "
268737bbf98cSChris Cain                              << subtree.size();
2688ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
268937bbf98cSChris Cain             return;
269037bbf98cSChris Cain         }
269137bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
269237bbf98cSChris Cain         {
269337bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2694ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269537bbf98cSChris Cain             return;
269637bbf98cSChris Cain         }
269737bbf98cSChris Cain         const std::string& path = subtree[0].first;
269837bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
269937bbf98cSChris Cain         if (service.empty())
270037bbf98cSChris Cain         {
2701002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2702ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
270337bbf98cSChris Cain             return;
270437bbf98cSChris Cain         }
270537bbf98cSChris Cain 
270637bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2707bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2708bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2709bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2710ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27111e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27128a592810SEd Tanous             if (ec2)
271337bbf98cSChris Cain             {
271437bbf98cSChris Cain                 BMCWEB_LOG_ERROR
27158a592810SEd Tanous                     << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
2716ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
271737bbf98cSChris Cain                 return;
271837bbf98cSChris Cain             }
271937bbf98cSChris Cain 
2720ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
272137bbf98cSChris Cain             {
2722ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272337bbf98cSChris Cain                 return;
272437bbf98cSChris Cain             }
2725bc1d29deSKrzysztof Grobelny             });
2726e99073f5SGeorge Liu         });
272737bbf98cSChris Cain 
272837bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
272937bbf98cSChris Cain }
273037bbf98cSChris Cain 
273137bbf98cSChris Cain /**
273237bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
273337bbf98cSChris Cain  *
2734ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
273537bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
273637bbf98cSChris Cain  *                       RF request.
273737bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
273837bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
273937bbf98cSChris Cain  * before entering idle state.
274037bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
274137bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
274237bbf98cSChris Cain  * before exiting idle state
274337bbf98cSChris Cain  *
274437bbf98cSChris Cain  * @return None.
274537bbf98cSChris Cain  */
2746ac106bf6SEd Tanous inline void
2747ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
274837bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
274937bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
275037bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
275137bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
275237bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
275337bbf98cSChris Cain {
275437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
275537bbf98cSChris Cain 
275637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2757e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2758e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2759e99073f5SGeorge Liu     dbus::utility::getSubTree(
2760e99073f5SGeorge Liu         "/", 0, interfaces,
2761ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2762e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2763b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
276437bbf98cSChris Cain         if (ec)
276537bbf98cSChris Cain         {
276637bbf98cSChris Cain             BMCWEB_LOG_DEBUG
276737bbf98cSChris Cain                 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
276837bbf98cSChris Cain                 << ec;
2769ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277037bbf98cSChris Cain             return;
277137bbf98cSChris Cain         }
277237bbf98cSChris Cain         if (subtree.empty())
277337bbf98cSChris Cain         {
277437bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2775ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
277637bbf98cSChris Cain                                        "IdlePowerSaver");
277737bbf98cSChris Cain             return;
277837bbf98cSChris Cain         }
277937bbf98cSChris Cain         if (subtree.size() > 1)
278037bbf98cSChris Cain         {
278137bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
278237bbf98cSChris Cain             // is an error
27830fda0f12SGeorge Liu             BMCWEB_LOG_DEBUG
27840fda0f12SGeorge Liu                 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
278537bbf98cSChris Cain                 << subtree.size();
2786ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
278737bbf98cSChris Cain             return;
278837bbf98cSChris Cain         }
278937bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
279037bbf98cSChris Cain         {
279137bbf98cSChris Cain             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2792ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
279337bbf98cSChris Cain             return;
279437bbf98cSChris Cain         }
279537bbf98cSChris Cain         const std::string& path = subtree[0].first;
279637bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
279737bbf98cSChris Cain         if (service.empty())
279837bbf98cSChris Cain         {
2799002d39b4SEd Tanous             BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2800ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
280137bbf98cSChris Cain             return;
280237bbf98cSChris Cain         }
280337bbf98cSChris Cain 
280437bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
280537bbf98cSChris Cain         // need to be updated
280637bbf98cSChris Cain 
280737bbf98cSChris Cain         if (ipsEnable)
280837bbf98cSChris Cain         {
28099ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28109ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28119ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28129ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28138a592810SEd Tanous                     if (ec2)
281437bbf98cSChris Cain                     {
28158a592810SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2816ac106bf6SEd Tanous                         messages::internalError(asyncResp->res);
281737bbf98cSChris Cain                         return;
281837bbf98cSChris Cain                     }
28199ae226faSGeorge Liu                 });
282037bbf98cSChris Cain         }
282137bbf98cSChris Cain         if (ipsEnterUtil)
282237bbf98cSChris Cain         {
28239ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28249ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28259ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28269ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2827ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28288a592810SEd Tanous                 if (ec2)
282937bbf98cSChris Cain                 {
28308a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2831ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
283237bbf98cSChris Cain                     return;
283337bbf98cSChris Cain                 }
28349ae226faSGeorge Liu                 });
283537bbf98cSChris Cain         }
283637bbf98cSChris Cain         if (ipsEnterTime)
283737bbf98cSChris Cain         {
283837bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
283937bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
28409ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28419ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28429ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28439ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2844ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28458a592810SEd Tanous                 if (ec2)
284637bbf98cSChris Cain                 {
28478a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2848ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
284937bbf98cSChris Cain                     return;
285037bbf98cSChris Cain                 }
28519ae226faSGeorge Liu                 });
285237bbf98cSChris Cain         }
285337bbf98cSChris Cain         if (ipsExitUtil)
285437bbf98cSChris Cain         {
28559ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28569ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28579ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28589ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2859ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28608a592810SEd Tanous                 if (ec2)
286137bbf98cSChris Cain                 {
28628a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2863ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
286437bbf98cSChris Cain                     return;
286537bbf98cSChris Cain                 }
28669ae226faSGeorge Liu                 });
286737bbf98cSChris Cain         }
286837bbf98cSChris Cain         if (ipsExitTime)
286937bbf98cSChris Cain         {
287037bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
287137bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
28729ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28739ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28749ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28759ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2876ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28778a592810SEd Tanous                 if (ec2)
287837bbf98cSChris Cain                 {
28798a592810SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2880ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
288137bbf98cSChris Cain                     return;
288237bbf98cSChris Cain                 }
28839ae226faSGeorge Liu                 });
288437bbf98cSChris Cain         }
2885e99073f5SGeorge Liu         });
288637bbf98cSChris Cain 
288737bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
288837bbf98cSChris Cain }
288937bbf98cSChris Cain 
2890c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2891dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2892dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2893dd60b9edSEd Tanous {
2894dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2895dd60b9edSEd Tanous     {
2896dd60b9edSEd Tanous         return;
2897dd60b9edSEd Tanous     }
2898dd60b9edSEd Tanous     asyncResp->res.addHeader(
2899dd60b9edSEd Tanous         boost::beast::http::field::link,
2900dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2901dd60b9edSEd Tanous }
2902dd60b9edSEd Tanous 
2903c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2904c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2905c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29061abe55efSEd Tanous {
29073ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2908f4c99e70SEd Tanous     {
2909f4c99e70SEd Tanous         return;
2910f4c99e70SEd Tanous     }
2911dd60b9edSEd Tanous 
2912dd60b9edSEd Tanous     asyncResp->res.addHeader(
2913dd60b9edSEd Tanous         boost::beast::http::field::link,
2914dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29158d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29160f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29178d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29188d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2919462023adSSunitha Harish 
29207f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
29217f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
29227f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29237f3e84a1SEd Tanous     {
29247f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
29257f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29267f3e84a1SEd Tanous         return;
29277f3e84a1SEd Tanous     }
29287f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
29297f3e84a1SEd Tanous     nlohmann::json::object_t system;
29307f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
29317f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
29321e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2933002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
29341e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2935002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
29365e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
29371e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
29387f3e84a1SEd Tanous         if (ec2)
2939462023adSSunitha Harish         {
29407f3e84a1SEd Tanous             return;
29417f3e84a1SEd Tanous         }
29427f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
29437f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
29447f3e84a1SEd Tanous         {
29457f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
29467f3e84a1SEd Tanous             return;
29477f3e84a1SEd Tanous         }
29487f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
29497f3e84a1SEd Tanous         if (count == nullptr)
29507f3e84a1SEd Tanous         {
29517f3e84a1SEd Tanous             BMCWEB_LOG_CRITICAL << "Count wasn't found??";
29527f3e84a1SEd Tanous             return;
29537f3e84a1SEd Tanous         }
29547f3e84a1SEd Tanous         *count = *count + 1;
2955462023adSSunitha Harish         BMCWEB_LOG_DEBUG << "Hypervisor is available";
29567f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
29571476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2958002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
29597f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
29601e1e598dSJonathan Doman         });
2961c1e219d5SEd Tanous }
2962c1e219d5SEd Tanous 
2963c1e219d5SEd Tanous /**
29647e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
29657e860f15SJohn Edward Broadbent  */
29664f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29677e860f15SJohn Edward Broadbent {
296889492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
296989492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
297089492a15SPatrick Williams     constexpr const char* interfaceName =
29717e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
297289492a15SPatrick Williams     constexpr const char* method = "NMI";
29737e860f15SJohn Edward Broadbent 
29747e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
29755e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
29767e860f15SJohn Edward Broadbent         if (ec)
29777e860f15SJohn Edward Broadbent         {
29787e860f15SJohn Edward Broadbent             BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
29797e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
29807e860f15SJohn Edward Broadbent             return;
29817e860f15SJohn Edward Broadbent         }
29827e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
29837e860f15SJohn Edward Broadbent         },
29847e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29857e860f15SJohn Edward Broadbent }
2986c5b2abe0SLewanczyk, Dawid 
2987c5b2abe0SLewanczyk, Dawid /**
2988fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
2989fc903b3dSAndrew Geissler  */
2990fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
2991fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
2992fc903b3dSAndrew Geissler                                          std::string_view resetType,
2993fc903b3dSAndrew Geissler                                          crow::Response& res)
2994fc903b3dSAndrew Geissler {
2995fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
2996fc903b3dSAndrew Geissler     {
2997fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
2998fc903b3dSAndrew Geissler         return;
2999fc903b3dSAndrew Geissler     }
3000fc903b3dSAndrew Geissler 
3001fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3002fc903b3dSAndrew Geissler     {
3003fc903b3dSAndrew Geissler         BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
3004fc903b3dSAndrew Geissler         messages::internalError(res);
3005fc903b3dSAndrew Geissler         return;
3006fc903b3dSAndrew Geissler     }
3007fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3008fc903b3dSAndrew Geissler 
3009fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3010fc903b3dSAndrew Geissler     // user to retry in a bit
3011fc903b3dSAndrew Geissler     if ((errorMessage ==
3012fc903b3dSAndrew Geissler          std::string_view(
3013fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3014fc903b3dSAndrew Geissler         (errorMessage ==
3015fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3016fc903b3dSAndrew Geissler     {
3017fc903b3dSAndrew Geissler         BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
3018fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3019fc903b3dSAndrew Geissler         return;
3020fc903b3dSAndrew Geissler     }
3021fc903b3dSAndrew Geissler 
3022fc903b3dSAndrew Geissler     BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
3023fc903b3dSAndrew Geissler                      << " sdbusplus:" << errorMessage;
3024fc903b3dSAndrew Geissler     messages::internalError(res);
3025fc903b3dSAndrew Geissler }
3026fc903b3dSAndrew Geissler 
3027c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3028c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
30297f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3030c1e219d5SEd Tanous     const std::string& systemName)
3031c1e219d5SEd Tanous {
30323ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
303345ca1b86SEd Tanous     {
303445ca1b86SEd Tanous         return;
303545ca1b86SEd Tanous     }
3036c1e219d5SEd Tanous     if (systemName != "system")
3037c1e219d5SEd Tanous     {
3038c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3039c1e219d5SEd Tanous                                    systemName);
3040c1e219d5SEd Tanous         return;
3041c1e219d5SEd Tanous     }
30427f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30437f3e84a1SEd Tanous     {
30447f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30457f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3046c1e219d5SEd Tanous                                    systemName);
30477f3e84a1SEd Tanous         return;
30487f3e84a1SEd Tanous     }
30499712f8acSEd Tanous     std::string resetType;
3050c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3051cc340dd9SEd Tanous     {
3052cc340dd9SEd Tanous         return;
3053cc340dd9SEd Tanous     }
3054cc340dd9SEd Tanous 
3055d22c8396SJason M. Bills     // Get the command and host vs. chassis
3056cc340dd9SEd Tanous     std::string command;
3057543f4400SEd Tanous     bool hostCommand = true;
3058d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3059cc340dd9SEd Tanous     {
3060cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3061d22c8396SJason M. Bills         hostCommand = true;
3062d22c8396SJason M. Bills     }
3063d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3064d22c8396SJason M. Bills     {
3065d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3066d22c8396SJason M. Bills         hostCommand = false;
3067d22c8396SJason M. Bills     }
3068d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3069d22c8396SJason M. Bills     {
3070c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
307186a0851aSJason M. Bills         hostCommand = true;
3072cc340dd9SEd Tanous     }
30739712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3074cc340dd9SEd Tanous     {
3075cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3076d22c8396SJason M. Bills         hostCommand = true;
3077cc340dd9SEd Tanous     }
30789712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3079cc340dd9SEd Tanous     {
30800fda0f12SGeorge Liu         command =
30810fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3082d22c8396SJason M. Bills         hostCommand = true;
3083d22c8396SJason M. Bills     }
3084d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3085d22c8396SJason M. Bills     {
308686a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
308786a0851aSJason M. Bills         hostCommand = true;
3088cc340dd9SEd Tanous     }
3089bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3090bfd5b826SLakshminarayana R. Kammath     {
3091bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3092bfd5b826SLakshminarayana R. Kammath         return;
3093bfd5b826SLakshminarayana R. Kammath     }
3094cc340dd9SEd Tanous     else
3095cc340dd9SEd Tanous     {
3096c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3097cc340dd9SEd Tanous         return;
3098cc340dd9SEd Tanous     }
3099cc340dd9SEd Tanous 
3100d22c8396SJason M. Bills     if (hostCommand)
3101d22c8396SJason M. Bills     {
31029ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31039ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31049ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31059ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31069ae226faSGeorge Liu             command,
3107fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3108fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3109cc340dd9SEd Tanous             if (ec)
3110cc340dd9SEd Tanous             {
3111fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3112fc903b3dSAndrew Geissler                                              asyncResp->res);
3113fc903b3dSAndrew Geissler 
3114cc340dd9SEd Tanous                 return;
3115cc340dd9SEd Tanous             }
3116f12894f8SJason M. Bills             messages::success(asyncResp->res);
31179ae226faSGeorge Liu             });
3118cc340dd9SEd Tanous     }
3119d22c8396SJason M. Bills     else
3120d22c8396SJason M. Bills     {
31219ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31229ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
31239ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
31249ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
31259ae226faSGeorge Liu             command,
3126fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3127fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3128d22c8396SJason M. Bills             if (ec)
3129d22c8396SJason M. Bills             {
3130fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3131fc903b3dSAndrew Geissler                                              asyncResp->res);
3132d22c8396SJason M. Bills                 return;
3133d22c8396SJason M. Bills             }
3134d22c8396SJason M. Bills             messages::success(asyncResp->res);
31359ae226faSGeorge Liu             });
3136d22c8396SJason M. Bills     }
3137d22c8396SJason M. Bills }
3138cc340dd9SEd Tanous 
3139c1e219d5SEd Tanous inline void handleComputerSystemHead(
3140dd60b9edSEd Tanous     App& app, const crow::Request& req,
31417f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31427f3e84a1SEd Tanous     const std::string& /*systemName*/)
3143dd60b9edSEd Tanous {
3144dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3145dd60b9edSEd Tanous     {
3146dd60b9edSEd Tanous         return;
3147dd60b9edSEd Tanous     }
3148dd60b9edSEd Tanous 
3149dd60b9edSEd Tanous     asyncResp->res.addHeader(
3150dd60b9edSEd Tanous         boost::beast::http::field::link,
3151dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3152dd60b9edSEd Tanous }
3153dd60b9edSEd Tanous 
31545c3e9272SAbhishek Patel inline void afterPortRequest(
31555c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31565c3e9272SAbhishek Patel     const boost::system::error_code& ec,
31575c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
31585c3e9272SAbhishek Patel {
31595c3e9272SAbhishek Patel     if (ec)
31605c3e9272SAbhishek Patel     {
31615c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
31625c3e9272SAbhishek Patel         return;
31635c3e9272SAbhishek Patel     }
31645c3e9272SAbhishek Patel     for (const auto& data : socketData)
31655c3e9272SAbhishek Patel     {
31665c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
31675c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
31685c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
31695c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
31705c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
31715c3e9272SAbhishek Patel         // need to retrieve port number for
31725c3e9272SAbhishek Patel         // obmc-console-ssh service
31735c3e9272SAbhishek Patel         if (protocolName == "SSH")
31745c3e9272SAbhishek Patel         {
31755c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
317681c4e330SEd Tanous                                           const boost::system::error_code& ec1,
31775c3e9272SAbhishek Patel                                           int portNumber) {
31785c3e9272SAbhishek Patel                 if (ec1)
31795c3e9272SAbhishek Patel                 {
31805c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
31815c3e9272SAbhishek Patel                     return;
31825c3e9272SAbhishek Patel                 }
31835c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
31845c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
31855c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
31865c3e9272SAbhishek Patel             });
31875c3e9272SAbhishek Patel         }
31885c3e9272SAbhishek Patel     }
31895c3e9272SAbhishek Patel }
3190c1e219d5SEd Tanous 
3191c1e219d5SEd Tanous inline void
3192c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
319322d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3194c1e219d5SEd Tanous                             const std::string& systemName)
3195c1e219d5SEd Tanous {
31963ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
319745ca1b86SEd Tanous     {
319845ca1b86SEd Tanous         return;
319945ca1b86SEd Tanous     }
3200746b56f3SAsmitha Karunanithi 
32017f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32027f3e84a1SEd Tanous     {
32037f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32047f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32057f3e84a1SEd Tanous                                    systemName);
32067f3e84a1SEd Tanous         return;
32077f3e84a1SEd Tanous     }
32087f3e84a1SEd Tanous 
3209746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3210746b56f3SAsmitha Karunanithi     {
3211746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3212746b56f3SAsmitha Karunanithi         return;
3213746b56f3SAsmitha Karunanithi     }
3214746b56f3SAsmitha Karunanithi 
321522d268cbSEd Tanous     if (systemName != "system")
321622d268cbSEd Tanous     {
321722d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
321822d268cbSEd Tanous                                    systemName);
321922d268cbSEd Tanous         return;
322022d268cbSEd Tanous     }
3221dd60b9edSEd Tanous     asyncResp->res.addHeader(
3222dd60b9edSEd Tanous         boost::beast::http::field::link,
3223dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
32248d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
322537bbf98cSChris Cain         "#ComputerSystem.v1_16_0.ComputerSystem";
32268d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
32278d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
32288d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
32298d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
32308d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
32315fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
32325fd0aafbSNinad Palsule     {
32338d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
32348d1b46d7Szhanghch05             "Disabled";
32358d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
32368d1b46d7Szhanghch05             "Disabled";
32375fd0aafbSNinad Palsule     }
3238cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3239cf0e004cSNinad Palsule         uint64_t(0);
3240002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
324104a258f4SEd Tanous 
32421476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
32431476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
32441476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
32451476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
32461476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
32471476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
32483179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
32493179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3250029573d4SEd Tanous 
3251002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
32521476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3253c1e219d5SEd Tanous     asyncResp->res
3254c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
32551476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3256c5b2abe0SLewanczyk, Dawid 
32571476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
32581476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
32591476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
32601476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3261c4bf6374SJason M. Bills 
32621476687dSEd Tanous     nlohmann::json::array_t managedBy;
32631476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
32641476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3265002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
32661476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
32671476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
32680e8ac5e7SGunnar Mills 
32690e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3270002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3271c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
32721476687dSEd Tanous 
3273c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
32741476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3275c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
32761476687dSEd Tanous         "Press ~. to exit console";
32775c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
32785c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
32790e8ac5e7SGunnar Mills 
32800e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
32810e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3282002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3283c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3284613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3285613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
32861476687dSEd Tanous 
32870e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
328813451e39SWilly Tu 
328913451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
329013451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
329113451e39SWilly Tu     {
32927a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3293b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
32942ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3295e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3296e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3297b49ac873SJames Feist 
32987a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
32997a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33007a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3301914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3302b49ac873SJames Feist             if (ec)
3303b49ac873SJames Feist             {
3304b49ac873SJames Feist                 // no inventory
3305b49ac873SJames Feist                 return;
3306b49ac873SJames Feist             }
3307b49ac873SJames Feist 
3308914e2d5dSEd Tanous             health->inventory = resp;
33097a1dbc48SGeorge Liu             });
3310b49ac873SJames Feist         health->populate();
331113451e39SWilly Tu     }
3312b49ac873SJames Feist 
3313002d39b4SEd Tanous     getMainChassisId(asyncResp,
3314002d39b4SEd Tanous                      [](const std::string& chassisId,
33158d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3316b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3317b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3318ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3319ef4c65b7SEd Tanous                                                    chassisId);
3320002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3321c5d03ff4SJennifer Lee     });
3322a3002228SAppaRao Puli 
33239f8bfa7cSGunnar Mills     getLocationIndicatorActive(asyncResp);
33249f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3325a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
33265bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
33276c34de48SEd Tanous     getHostState(asyncResp);
3328491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3329978b8803SAndrew Geissler     getBootProgress(asyncResp);
3330b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
3331472bd202SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
333251709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3333c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
3334*9dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3335797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3336c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3337a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3338a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3339a6349918SAppaRao Puli #endif
33401981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
33413a2d0424SChris Cain     getPowerMode(asyncResp);
334237bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3343c1e219d5SEd Tanous }
3344550a6bf8SJiaqing Zhao 
3345c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3346c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
334722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3348c1e219d5SEd Tanous     const std::string& systemName)
3349c1e219d5SEd Tanous {
33503ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
335145ca1b86SEd Tanous     {
335245ca1b86SEd Tanous         return;
335345ca1b86SEd Tanous     }
33547f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
33557f3e84a1SEd Tanous     {
33567f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
33577f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33587f3e84a1SEd Tanous                                    systemName);
33597f3e84a1SEd Tanous         return;
33607f3e84a1SEd Tanous     }
336122d268cbSEd Tanous     if (systemName != "system")
336222d268cbSEd Tanous     {
336322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
336422d268cbSEd Tanous                                    systemName);
336522d268cbSEd Tanous         return;
336622d268cbSEd Tanous     }
336722d268cbSEd Tanous 
3368dd60b9edSEd Tanous     asyncResp->res.addHeader(
3369dd60b9edSEd Tanous         boost::beast::http::field::link,
3370dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3371dd60b9edSEd Tanous 
33729f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3373cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
337498e386ecSGunnar Mills     std::optional<std::string> assetTag;
3375c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
33763a2d0424SChris Cain     std::optional<std::string> powerMode;
3377550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3378550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3379550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3380550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3381550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3382550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3383797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3384550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
3385*9dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3386550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3387550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3388550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3389550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3390550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3391550a6bf8SJiaqing Zhao 
3392550a6bf8SJiaqing Zhao     // clang-format off
339315ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3394550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3395550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
33967e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3397550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3398550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3399550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3400550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3401550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3402550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3403550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3404550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3405550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3406797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3407550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3408*9dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3409550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3410550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3411550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3412550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3413550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
34146617338dSEd Tanous                 {
34156617338dSEd Tanous                     return;
34166617338dSEd Tanous                 }
3417550a6bf8SJiaqing Zhao     // clang-format on
3418491d8ee7SSantosh Puranik 
34198d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3420c45f0082SYong Li 
342198e386ecSGunnar Mills     if (assetTag)
342298e386ecSGunnar Mills     {
342398e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
342498e386ecSGunnar Mills     }
342598e386ecSGunnar Mills 
3426550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3427c45f0082SYong Li     {
3428f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3429c45f0082SYong Li     }
3430c45f0082SYong Li 
3431cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
343269f35306SGunnar Mills     {
3433002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3434491d8ee7SSantosh Puranik     }
3435550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
343669f35306SGunnar Mills     {
3437550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
343869f35306SGunnar Mills     }
3439ac7e1e0bSAli Ahmed 
3440797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3441797d5daeSCorey Hardesty     {
3442797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3443797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3444797d5daeSCorey Hardesty     }
3445797d5daeSCorey Hardesty 
3446550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3447ac7e1e0bSAli Ahmed     {
3448c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
344969f35306SGunnar Mills     }
3450265c1602SJohnathan Mantey 
3451*9dcfe8c1SAlbert Zhang     if (stopBootOnFault)
3452*9dcfe8c1SAlbert Zhang     {
3453*9dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
3454*9dcfe8c1SAlbert Zhang     }
3455*9dcfe8c1SAlbert Zhang 
34569f8bfa7cSGunnar Mills     if (locationIndicatorActive)
34579f8bfa7cSGunnar Mills     {
3458002d39b4SEd Tanous         setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
34599f8bfa7cSGunnar Mills     }
34609f8bfa7cSGunnar Mills 
34617e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
34627e860f15SJohn Edward Broadbent     // passed
34639712f8acSEd Tanous     if (indicatorLed)
34646617338dSEd Tanous     {
3465f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3466002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3467d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3468d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
34696617338dSEd Tanous     }
3470c6a620f2SGeorge Liu 
3471c6a620f2SGeorge Liu     if (powerRestorePolicy)
3472c6a620f2SGeorge Liu     {
34734e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3474c6a620f2SGeorge Liu     }
34753a2d0424SChris Cain 
34763a2d0424SChris Cain     if (powerMode)
34773a2d0424SChris Cain     {
34783a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
34793a2d0424SChris Cain     }
348037bbf98cSChris Cain 
3481c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
348237bbf98cSChris Cain     {
3483002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3484002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
348537bbf98cSChris Cain     }
3486c1e219d5SEd Tanous }
34871cb1a9e6SAppaRao Puli 
348838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3489dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34907f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3491c1e219d5SEd Tanous     const std::string& /*systemName*/)
3492dd60b9edSEd Tanous {
3493dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3494dd60b9edSEd Tanous     {
3495dd60b9edSEd Tanous         return;
3496dd60b9edSEd Tanous     }
3497dd60b9edSEd Tanous     asyncResp->res.addHeader(
3498dd60b9edSEd Tanous         boost::beast::http::field::link,
3499dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3500dd60b9edSEd Tanous }
3501c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3502c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
350322d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3504c1e219d5SEd Tanous     const std::string& systemName)
3505c1e219d5SEd Tanous {
35063ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
350745ca1b86SEd Tanous     {
350845ca1b86SEd Tanous         return;
350945ca1b86SEd Tanous     }
35107f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35117f3e84a1SEd Tanous     {
35127f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
35137f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
35147f3e84a1SEd Tanous                                    systemName);
35157f3e84a1SEd Tanous         return;
35167f3e84a1SEd Tanous     }
3517746b56f3SAsmitha Karunanithi 
3518746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3519746b56f3SAsmitha Karunanithi     {
3520746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3521746b56f3SAsmitha Karunanithi         return;
3522746b56f3SAsmitha Karunanithi     }
3523746b56f3SAsmitha Karunanithi 
352422d268cbSEd Tanous     if (systemName != "system")
352522d268cbSEd Tanous     {
352622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
352722d268cbSEd Tanous                                    systemName);
352822d268cbSEd Tanous         return;
352922d268cbSEd Tanous     }
353022d268cbSEd Tanous 
3531dd60b9edSEd Tanous     asyncResp->res.addHeader(
3532dd60b9edSEd Tanous         boost::beast::http::field::link,
3533dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35341476687dSEd Tanous 
35351476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
35361476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3537c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35381476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35391476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35403215e700SNan Zhou 
35413215e700SNan Zhou     nlohmann::json::array_t parameters;
35423215e700SNan Zhou     nlohmann::json::object_t parameter;
35433215e700SNan Zhou 
35443215e700SNan Zhou     parameter["Name"] = "ResetType";
35453215e700SNan Zhou     parameter["Required"] = true;
35463215e700SNan Zhou     parameter["DataType"] = "String";
35473215e700SNan Zhou     nlohmann::json::array_t allowableValues;
35483215e700SNan Zhou     allowableValues.emplace_back("On");
35493215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
35503215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
35513215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
35523215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
35533215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
35543215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
35553215e700SNan Zhou     allowableValues.emplace_back("Nmi");
35563215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
35573215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
35583215e700SNan Zhou 
35593215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3560c1e219d5SEd Tanous }
3561c1e219d5SEd Tanous /**
3562c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3563c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3564c1e219d5SEd Tanous  */
3565100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3566c1e219d5SEd Tanous {
3567100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3568100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3569100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3570100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3571100afe56SEd Tanous 
3572100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3573100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3574100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3575100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3576100afe56SEd Tanous 
3577100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3578100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3579100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3580100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3581100afe56SEd Tanous 
3582100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3583100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3584100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3585100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3586100afe56SEd Tanous 
3587100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3588100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3589100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3590100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3591100afe56SEd Tanous 
3592100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3593100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3594100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3595100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3596100afe56SEd Tanous 
3597c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3598c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3599c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3600c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3601c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3602c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3603c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3604c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36051cb1a9e6SAppaRao Puli }
3606c5b2abe0SLewanczyk, Dawid } // namespace redfish
3607