xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 6b9ac4f23ed00c3905c9b99f1d0831930acdbb1c)
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>
40b6655101SChris Cain #include <generated/enums/computer_system.hpp>
411e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
42fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
43bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
441214b7e7SGunnar Mills 
457a1dbc48SGeorge Liu #include <array>
46*6b9ac4f2SChris Cain #include <string>
477a1dbc48SGeorge Liu #include <string_view>
48abf2add6SEd Tanous #include <variant>
49*6b9ac4f2SChris Cain #include <vector>
50c5b2abe0SLewanczyk, Dawid 
511abe55efSEd Tanous namespace redfish
521abe55efSEd Tanous {
53c5b2abe0SLewanczyk, Dawid 
545c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
555c3e9272SAbhishek Patel     protocolToDBusForSystems{
565c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
575c3e9272SAbhishek Patel 
589d3ae10eSAlpana Kumari /**
599d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
609d3ae10eSAlpana Kumari  *
61ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
629d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
639d3ae10eSAlpana Kumari  *
649d3ae10eSAlpana Kumari  * @return None.
659d3ae10eSAlpana Kumari  */
668d1b46d7Szhanghch05 inline void
67ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
681e1e598dSJonathan Doman                          bool isDimmFunctional)
699d3ae10eSAlpana Kumari {
7062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
719d3ae10eSAlpana Kumari 
729d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
739d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
749d3ae10eSAlpana Kumari     // ENABLED.
7502cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
76ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
779d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
789d3ae10eSAlpana Kumari     {
79e05aec50SEd Tanous         if (isDimmFunctional)
809d3ae10eSAlpana Kumari         {
81ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
829d3ae10eSAlpana Kumari                 "Enabled";
839d3ae10eSAlpana Kumari         }
849d3ae10eSAlpana Kumari     }
859d3ae10eSAlpana Kumari }
869d3ae10eSAlpana Kumari 
8757e8c9beSAlpana Kumari /*
8857e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
8957e8c9beSAlpana Kumari  *        CPU Functional State
9057e8c9beSAlpana Kumari  *
91ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9257e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9357e8c9beSAlpana Kumari  *
9457e8c9beSAlpana Kumari  * @return None.
9557e8c9beSAlpana Kumari  */
96ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
97ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9857e8c9beSAlpana Kumari {
9962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10057e8c9beSAlpana Kumari 
10102cad96eSEd Tanous     const nlohmann::json& prevProcState =
102ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10357e8c9beSAlpana Kumari 
10457e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10557e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10657e8c9beSAlpana Kumari     // Functional.
10757e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10857e8c9beSAlpana Kumari     {
109e05aec50SEd Tanous         if (isCpuFunctional)
11057e8c9beSAlpana Kumari         {
111ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11257e8c9beSAlpana Kumari                 "Enabled";
11357e8c9beSAlpana Kumari         }
11457e8c9beSAlpana Kumari     }
11557e8c9beSAlpana Kumari }
11657e8c9beSAlpana Kumari 
117cf0e004cSNinad Palsule /*
118cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
119cf0e004cSNinad Palsule  *
120ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
121cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
122cf0e004cSNinad Palsule  *
123cf0e004cSNinad Palsule  * @return None.
124cf0e004cSNinad Palsule  */
125cf0e004cSNinad Palsule inline void
126ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
127cf0e004cSNinad Palsule                            bool isCpuPresent)
128cf0e004cSNinad Palsule {
12962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
130cf0e004cSNinad Palsule 
131cf0e004cSNinad Palsule     if (isCpuPresent)
132cf0e004cSNinad Palsule     {
133cf0e004cSNinad Palsule         nlohmann::json& procCount =
134ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
135cf0e004cSNinad Palsule         auto* procCountPtr =
136cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
137cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
138cf0e004cSNinad Palsule         {
139cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
140cf0e004cSNinad Palsule             *procCountPtr += 1;
141cf0e004cSNinad Palsule         }
142cf0e004cSNinad Palsule     }
143cf0e004cSNinad Palsule }
144cf0e004cSNinad Palsule 
145382d6475SAli Ahmed inline void getProcessorProperties(
146ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
147382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
148382d6475SAli Ahmed         properties)
14903fbed92SAli Ahmed {
15062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15103fbed92SAli Ahmed 
15203fbed92SAli Ahmed     // TODO: Get Model
15303fbed92SAli Ahmed 
154bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
157bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15803fbed92SAli Ahmed 
159bc1d29deSKrzysztof Grobelny     if (!success)
16003fbed92SAli Ahmed     {
161ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16203fbed92SAli Ahmed         return;
16303fbed92SAli Ahmed     }
16403fbed92SAli Ahmed 
165bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16603fbed92SAli Ahmed     {
167bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
168ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
169bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
170bc1d29deSKrzysztof Grobelny 
171bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
172bc1d29deSKrzysztof Grobelny         {
173bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17403fbed92SAli Ahmed         }
17503fbed92SAli Ahmed         else
17603fbed92SAli Ahmed         {
177bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17803fbed92SAli Ahmed         }
17903fbed92SAli Ahmed     }
18003fbed92SAli Ahmed }
18103fbed92SAli Ahmed 
18203fbed92SAli Ahmed /*
18303fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18403fbed92SAli Ahmed  *
185ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18603fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18703fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18803fbed92SAli Ahmed  *
18903fbed92SAli Ahmed  * @return None.
19003fbed92SAli Ahmed  */
191ac106bf6SEd Tanous inline void
192ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
193ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19403fbed92SAli Ahmed {
195ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
196382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
197382d6475SAli Ahmed         if (ec3)
198382d6475SAli Ahmed         {
19962598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
200382d6475SAli Ahmed             return;
201382d6475SAli Ahmed         }
202ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
203382d6475SAli Ahmed     };
204382d6475SAli Ahmed 
205cf0e004cSNinad Palsule     // Get the Presence of CPU
206cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
207cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
208cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
209cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
210cf0e004cSNinad Palsule 
2115fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2125fd0aafbSNinad Palsule     {
2135fd0aafbSNinad Palsule         auto getCpuFunctionalState =
214ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
215382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
216382d6475SAli Ahmed             if (ec3)
217382d6475SAli Ahmed             {
21862598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
219382d6475SAli Ahmed                 return;
220382d6475SAli Ahmed             }
221ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
222382d6475SAli Ahmed         };
223382d6475SAli Ahmed 
224382d6475SAli Ahmed         // Get the Functional State
225382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
226382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2275fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2285fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2295fd0aafbSNinad Palsule     }
230382d6475SAli Ahmed 
231bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
232bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
233bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
234ac106bf6SEd Tanous         [asyncResp, service,
2355e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
236b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
23703fbed92SAli Ahmed         if (ec2)
23803fbed92SAli Ahmed         {
23962598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
240ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24103fbed92SAli Ahmed             return;
24203fbed92SAli Ahmed         }
243ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
244bc1d29deSKrzysztof Grobelny     });
24503fbed92SAli Ahmed }
24603fbed92SAli Ahmed 
24757e8c9beSAlpana Kumari /*
248cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
249cf0e004cSNinad Palsule  *
250ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
251cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
252cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
253cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
254cf0e004cSNinad Palsule  *
255cf0e004cSNinad Palsule  * @return None.
256cf0e004cSNinad Palsule  */
257cf0e004cSNinad Palsule inline void
258ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2595fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2605fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
261cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
262cf0e004cSNinad Palsule {
26362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
264cf0e004cSNinad Palsule 
265cf0e004cSNinad Palsule     if (properties.empty())
266cf0e004cSNinad Palsule     {
2675fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2685fd0aafbSNinad Palsule         {
269cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
270cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
271cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
272cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
273cf0e004cSNinad Palsule                 "Functional",
274ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
275ac106bf6SEd Tanous                             bool dimmState) {
276cf0e004cSNinad Palsule                 if (ec3)
277cf0e004cSNinad Palsule                 {
27862598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
279cf0e004cSNinad Palsule                     return;
280cf0e004cSNinad Palsule                 }
281ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
282cf0e004cSNinad Palsule             });
2835fd0aafbSNinad Palsule         }
284cf0e004cSNinad Palsule         return;
285cf0e004cSNinad Palsule     }
286cf0e004cSNinad Palsule 
287cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
288cf0e004cSNinad Palsule 
289cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
290cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
291cf0e004cSNinad Palsule         memorySizeInKB);
292cf0e004cSNinad Palsule 
293cf0e004cSNinad Palsule     if (!success)
294cf0e004cSNinad Palsule     {
295ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
296cf0e004cSNinad Palsule         return;
297cf0e004cSNinad Palsule     }
298cf0e004cSNinad Palsule 
299cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
300cf0e004cSNinad Palsule     {
301cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
302ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
303dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
304cf0e004cSNinad Palsule         if (preValue == nullptr)
305cf0e004cSNinad Palsule         {
306ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
307dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
308cf0e004cSNinad Palsule         }
309cf0e004cSNinad Palsule         else
310cf0e004cSNinad Palsule         {
311ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
312dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
313dfb2b408SPriyanga Ramasamy                 *preValue;
314cf0e004cSNinad Palsule         }
3155fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3165fd0aafbSNinad Palsule         {
317ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3185fd0aafbSNinad Palsule                 "Enabled";
3195fd0aafbSNinad Palsule         }
320cf0e004cSNinad Palsule     }
321cf0e004cSNinad Palsule }
322cf0e004cSNinad Palsule 
323cf0e004cSNinad Palsule /*
324cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
325cf0e004cSNinad Palsule  *
326ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
327cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
328cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
329cf0e004cSNinad Palsule  *
330cf0e004cSNinad Palsule  * @return None.
331cf0e004cSNinad Palsule  */
332ac106bf6SEd Tanous inline void
333ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
334ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
335cf0e004cSNinad Palsule {
336cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
337cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
338cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
339ac106bf6SEd Tanous         [asyncResp, service,
340cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
341cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
342cf0e004cSNinad Palsule         if (ec2)
343cf0e004cSNinad Palsule         {
34462598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
345ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
346cf0e004cSNinad Palsule             return;
347cf0e004cSNinad Palsule         }
348ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
349cf0e004cSNinad Palsule     });
350cf0e004cSNinad Palsule }
351cf0e004cSNinad Palsule 
352a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
353a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
354a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3551abe55efSEd Tanous {
356a974c132SLakshmi Yadlapati     if (ec)
357a974c132SLakshmi Yadlapati     {
358a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
359a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
360a974c132SLakshmi Yadlapati         return;
361a974c132SLakshmi Yadlapati     }
362a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
363a974c132SLakshmi Yadlapati 
364a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
365a974c132SLakshmi Yadlapati 
366a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
367a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
368a974c132SLakshmi Yadlapati 
369a974c132SLakshmi Yadlapati     if (!success)
370a974c132SLakshmi Yadlapati     {
371a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
372a974c132SLakshmi Yadlapati         return;
373a974c132SLakshmi Yadlapati     }
374a974c132SLakshmi Yadlapati 
375a974c132SLakshmi Yadlapati     if (uUID != nullptr)
376a974c132SLakshmi Yadlapati     {
377a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
378a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
379a974c132SLakshmi Yadlapati         {
380a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
381a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
382a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
383a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
384a974c132SLakshmi Yadlapati         }
385a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
386a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
387a974c132SLakshmi Yadlapati     }
388a974c132SLakshmi Yadlapati }
389a974c132SLakshmi Yadlapati 
390a974c132SLakshmi Yadlapati inline void
391a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
392a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
393a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
394a974c132SLakshmi Yadlapati {
395a974c132SLakshmi Yadlapati     if (ec)
396a974c132SLakshmi Yadlapati     {
397a974c132SLakshmi Yadlapati         // doesn't have to include this
398a974c132SLakshmi Yadlapati         // interface
399a974c132SLakshmi Yadlapati         return;
400a974c132SLakshmi Yadlapati     }
401a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
402a974c132SLakshmi Yadlapati 
403a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
404a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
405a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
406a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
407a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
408a974c132SLakshmi Yadlapati 
409a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
410a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
411a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
412a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
413a974c132SLakshmi Yadlapati 
414a974c132SLakshmi Yadlapati     if (!success)
415a974c132SLakshmi Yadlapati     {
416a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
417a974c132SLakshmi Yadlapati         return;
418a974c132SLakshmi Yadlapati     }
419a974c132SLakshmi Yadlapati 
420a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
421a974c132SLakshmi Yadlapati     {
422a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
423a974c132SLakshmi Yadlapati     }
424a974c132SLakshmi Yadlapati 
425a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
426a974c132SLakshmi Yadlapati     {
427a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
428a974c132SLakshmi Yadlapati     }
429a974c132SLakshmi Yadlapati 
430a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
431a974c132SLakshmi Yadlapati     {
432a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
433a974c132SLakshmi Yadlapati     }
434a974c132SLakshmi Yadlapati 
435a974c132SLakshmi Yadlapati     if (model != nullptr)
436a974c132SLakshmi Yadlapati     {
437a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
438a974c132SLakshmi Yadlapati     }
439a974c132SLakshmi Yadlapati 
440a974c132SLakshmi Yadlapati     if (subModel != nullptr)
441a974c132SLakshmi Yadlapati     {
442a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
443a974c132SLakshmi Yadlapati     }
444a974c132SLakshmi Yadlapati 
445a974c132SLakshmi Yadlapati     // Grab the bios version
446a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
447a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
448a974c132SLakshmi Yadlapati }
449a974c132SLakshmi Yadlapati 
450a974c132SLakshmi Yadlapati inline void
451a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
452a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
453a974c132SLakshmi Yadlapati                      const std::string& value)
454a974c132SLakshmi Yadlapati {
455a974c132SLakshmi Yadlapati     if (ec)
456a974c132SLakshmi Yadlapati     {
457a974c132SLakshmi Yadlapati         // doesn't have to include this
458a974c132SLakshmi Yadlapati         // interface
459a974c132SLakshmi Yadlapati         return;
460a974c132SLakshmi Yadlapati     }
461a974c132SLakshmi Yadlapati 
462a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
463a974c132SLakshmi Yadlapati }
464a974c132SLakshmi Yadlapati 
465a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
466a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
467a974c132SLakshmi Yadlapati     const std::shared_ptr<HealthPopulate>& systemHealth,
468a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
469a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
470a974c132SLakshmi Yadlapati {
4711abe55efSEd Tanous     if (ec)
4721abe55efSEd Tanous     {
473b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
474ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
475c5b2abe0SLewanczyk, Dawid         return;
476c5b2abe0SLewanczyk, Dawid     }
477c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
478002d39b4SEd Tanous     for (const std::pair<
479002d39b4SEd Tanous              std::string,
480002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4811214b7e7SGunnar Mills              object : subtree)
4821abe55efSEd Tanous     {
483c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
48462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
485002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4861214b7e7SGunnar Mills             connectionNames = object.second;
48726f6976fSEd Tanous         if (connectionNames.empty())
4881abe55efSEd Tanous         {
489c5b2abe0SLewanczyk, Dawid             continue;
490c5b2abe0SLewanczyk, Dawid         }
491029573d4SEd Tanous 
4925fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
4935fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
4945bc2dc8eSJames Feist 
4955fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
4965fd0aafbSNinad Palsule         {
4975fd0aafbSNinad Palsule             memoryHealth = std::make_shared<HealthPopulate>(
498ac106bf6SEd Tanous                 asyncResp, "/MemorySummary/Status"_json_pointer);
4995fd0aafbSNinad Palsule             systemHealth->children.emplace_back(memoryHealth);
5005bc2dc8eSJames Feist 
50113451e39SWilly Tu             if constexpr (bmcwebEnableHealthPopulate)
50213451e39SWilly Tu             {
5035fd0aafbSNinad Palsule                 cpuHealth = std::make_shared<HealthPopulate>(
504ac106bf6SEd Tanous                     asyncResp, "/ProcessorSummary/Status"_json_pointer);
5055fd0aafbSNinad Palsule 
5065bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
50713451e39SWilly Tu             }
5085fd0aafbSNinad Palsule         }
5095bc2dc8eSJames Feist 
5106c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
5116c34de48SEd Tanous         // BiosVer
51204a258f4SEd Tanous         for (const auto& connection : connectionNames)
5131abe55efSEd Tanous         {
51404a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
5151abe55efSEd Tanous             {
516a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
5171abe55efSEd Tanous                 {
51862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
5199d3ae10eSAlpana Kumari 
520ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
5215bc2dc8eSJames Feist 
5225fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5235fd0aafbSNinad Palsule                     {
5245bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
5251abe55efSEd Tanous                     }
5265fd0aafbSNinad Palsule                 }
52704a258f4SEd Tanous                 else if (interfaceName ==
52804a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
5291abe55efSEd Tanous                 {
53062598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
53157e8c9beSAlpana Kumari 
532ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
5335bc2dc8eSJames Feist 
5345fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5355fd0aafbSNinad Palsule                     {
5365bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
5371abe55efSEd Tanous                     }
5385fd0aafbSNinad Palsule                 }
539002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
5401abe55efSEd Tanous                 {
54162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
542bc1d29deSKrzysztof Grobelny 
543bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
544a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
545a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
546ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
547b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
5481214b7e7SGunnar Mills                                         properties) {
549a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
550bc1d29deSKrzysztof Grobelny                     });
551c5b2abe0SLewanczyk, Dawid                 }
552029573d4SEd Tanous                 else if (interfaceName ==
553029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
5541abe55efSEd Tanous                 {
555bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
556a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
557bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
558a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
559b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
560a974c132SLakshmi Yadlapati                                         properties) {
561a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
562bc1d29deSKrzysztof Grobelny                     });
563e4a4b9a9SJames Feist 
5641e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
565a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
5661e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
5671e1e598dSJonathan Doman                         "AssetTag",
5681e1e598dSJonathan Doman                         "AssetTag",
569a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
570a974c132SLakshmi Yadlapati                 }
571a974c132SLakshmi Yadlapati             }
572a974c132SLakshmi Yadlapati         }
573a974c132SLakshmi Yadlapati     }
574a974c132SLakshmi Yadlapati }
575a974c132SLakshmi Yadlapati 
576a974c132SLakshmi Yadlapati /*
577a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
578a974c132SLakshmi Yadlapati  *
579a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
580a974c132SLakshmi Yadlapati  * @param[in] systemHealth  Shared HealthPopulate pointer
581a974c132SLakshmi Yadlapati  *
582a974c132SLakshmi Yadlapati  * @return None.
583a974c132SLakshmi Yadlapati  */
584a974c132SLakshmi Yadlapati inline void
585a974c132SLakshmi Yadlapati     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
586a974c132SLakshmi Yadlapati                       const std::shared_ptr<HealthPopulate>& systemHealth)
587e4a4b9a9SJames Feist {
588a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
589a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
590a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
591a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
592a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
593a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
594a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
595a974c132SLakshmi Yadlapati     };
596a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
597a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
598a974c132SLakshmi Yadlapati         std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
599c5b2abe0SLewanczyk, Dawid }
600c5b2abe0SLewanczyk, Dawid 
601c5b2abe0SLewanczyk, Dawid /**
602c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
603c5b2abe0SLewanczyk, Dawid  *
604ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
605c5b2abe0SLewanczyk, Dawid  *
606c5b2abe0SLewanczyk, Dawid  * @return None.
607c5b2abe0SLewanczyk, Dawid  */
608ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
6091abe55efSEd Tanous {
61062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
6111e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6121e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6131e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6141e1e598dSJonathan Doman         "CurrentHostState",
615ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6161e1e598dSJonathan Doman                     const std::string& hostState) {
6171abe55efSEd Tanous         if (ec)
6181abe55efSEd Tanous         {
61922228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
62022228c28SAndrew Geissler             {
62122228c28SAndrew Geissler                 // Service not available, no error, just don't return
62222228c28SAndrew Geissler                 // host state info
62362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
62422228c28SAndrew Geissler                 return;
62522228c28SAndrew Geissler             }
62662598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
627ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
628c5b2abe0SLewanczyk, Dawid             return;
629c5b2abe0SLewanczyk, Dawid         }
6306617338dSEd Tanous 
63162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
632c5b2abe0SLewanczyk, Dawid         // Verify Host State
6331e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6341abe55efSEd Tanous         {
635ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
636ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6371abe55efSEd Tanous         }
6381e1e598dSJonathan Doman         else if (hostState ==
6390fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6408c888608SGunnar Mills         {
641ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
642ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6438c888608SGunnar Mills         }
6441e1e598dSJonathan Doman         else if (hostState ==
6450fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
64683935af9SAndrew Geissler         {
647ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
648ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
64983935af9SAndrew Geissler         }
6500fda0f12SGeorge Liu         else if (
6511e1e598dSJonathan Doman             hostState ==
6520fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6531a2a1437SAndrew Geissler         {
654ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
655ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6561a2a1437SAndrew Geissler         }
657002d39b4SEd Tanous         else if (hostState ==
6580fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6591a2a1437SAndrew Geissler         {
660ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
661ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6621a2a1437SAndrew Geissler         }
6631abe55efSEd Tanous         else
6641abe55efSEd Tanous         {
665ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
666ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
667c5b2abe0SLewanczyk, Dawid         }
6681e1e598dSJonathan Doman     });
669c5b2abe0SLewanczyk, Dawid }
670c5b2abe0SLewanczyk, Dawid 
671c5b2abe0SLewanczyk, Dawid /**
672786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
673491d8ee7SSantosh Puranik  *
674491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
675491d8ee7SSantosh Puranik  *
676491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
677491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
678491d8ee7SSantosh Puranik  */
67923a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
680491d8ee7SSantosh Puranik {
681491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
682491d8ee7SSantosh Puranik     {
683491d8ee7SSantosh Puranik         return "None";
684491d8ee7SSantosh Puranik     }
6853174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
686491d8ee7SSantosh Puranik     {
687491d8ee7SSantosh Puranik         return "Hdd";
688491d8ee7SSantosh Puranik     }
6893174e4dfSEd Tanous     if (dbusSource ==
690a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
691491d8ee7SSantosh Puranik     {
692491d8ee7SSantosh Puranik         return "Cd";
693491d8ee7SSantosh Puranik     }
6943174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
695491d8ee7SSantosh Puranik     {
696491d8ee7SSantosh Puranik         return "Pxe";
697491d8ee7SSantosh Puranik     }
6983174e4dfSEd Tanous     if (dbusSource ==
699944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
7009f16b2c1SJennifer Lee     {
7019f16b2c1SJennifer Lee         return "Usb";
7029f16b2c1SJennifer Lee     }
703491d8ee7SSantosh Puranik     return "";
704491d8ee7SSantosh Puranik }
705491d8ee7SSantosh Puranik 
706491d8ee7SSantosh Puranik /**
707cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
708cd9a4666SKonstantin Aladyshev  *
709cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
710cd9a4666SKonstantin Aladyshev  *
711cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
712cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
713cd9a4666SKonstantin Aladyshev  */
714cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
715cd9a4666SKonstantin Aladyshev {
716cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
717cd9a4666SKonstantin Aladyshev     {
718cd9a4666SKonstantin Aladyshev         return "Legacy";
719cd9a4666SKonstantin Aladyshev     }
720cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
721cd9a4666SKonstantin Aladyshev     {
722cd9a4666SKonstantin Aladyshev         return "UEFI";
723cd9a4666SKonstantin Aladyshev     }
724cd9a4666SKonstantin Aladyshev     return "";
725cd9a4666SKonstantin Aladyshev }
726cd9a4666SKonstantin Aladyshev 
727cd9a4666SKonstantin Aladyshev /**
728786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
729491d8ee7SSantosh Puranik  *
730491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
731491d8ee7SSantosh Puranik  *
732491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
733491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
734491d8ee7SSantosh Puranik  */
73523a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
736491d8ee7SSantosh Puranik {
737491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
738491d8ee7SSantosh Puranik     {
739491d8ee7SSantosh Puranik         return "None";
740491d8ee7SSantosh Puranik     }
7413174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
742491d8ee7SSantosh Puranik     {
743491d8ee7SSantosh Puranik         return "Diags";
744491d8ee7SSantosh Puranik     }
7453174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
746491d8ee7SSantosh Puranik     {
747491d8ee7SSantosh Puranik         return "BiosSetup";
748491d8ee7SSantosh Puranik     }
749491d8ee7SSantosh Puranik     return "";
750491d8ee7SSantosh Puranik }
751491d8ee7SSantosh Puranik 
752491d8ee7SSantosh Puranik /**
753e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
754e43914b3SAndrew Geissler  *
755e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
756e43914b3SAndrew Geissler  *
757e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
758e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
759e43914b3SAndrew Geissler  */
760e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
761e43914b3SAndrew Geissler {
762e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
763e43914b3SAndrew Geissler     // enum
764e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
765e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
766e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
767e43914b3SAndrew Geissler     {
768e43914b3SAndrew Geissler         rfBpLastState = "None";
769e43914b3SAndrew Geissler     }
770e43914b3SAndrew Geissler     else if (dbusBootProgress ==
771e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
772e43914b3SAndrew Geissler              "PrimaryProcInit")
773e43914b3SAndrew Geissler     {
774e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
775e43914b3SAndrew Geissler     }
776e43914b3SAndrew Geissler     else if (dbusBootProgress ==
777e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
778e43914b3SAndrew Geissler              "BusInit")
779e43914b3SAndrew Geissler     {
780e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
781e43914b3SAndrew Geissler     }
782e43914b3SAndrew Geissler     else if (dbusBootProgress ==
783e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
784e43914b3SAndrew Geissler              "MemoryInit")
785e43914b3SAndrew Geissler     {
786e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
787e43914b3SAndrew Geissler     }
788e43914b3SAndrew Geissler     else if (dbusBootProgress ==
789e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
790e43914b3SAndrew Geissler              "SecondaryProcInit")
791e43914b3SAndrew Geissler     {
792e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
793e43914b3SAndrew Geissler     }
794e43914b3SAndrew Geissler     else if (dbusBootProgress ==
795e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
796e43914b3SAndrew Geissler              "PCIInit")
797e43914b3SAndrew Geissler     {
798e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
799e43914b3SAndrew Geissler     }
800e43914b3SAndrew Geissler     else if (dbusBootProgress ==
801e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
802e43914b3SAndrew Geissler              "SystemSetup")
803e43914b3SAndrew Geissler     {
804e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
805e43914b3SAndrew Geissler     }
806e43914b3SAndrew Geissler     else if (dbusBootProgress ==
807e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
808e43914b3SAndrew Geissler              "SystemInitComplete")
809e43914b3SAndrew Geissler     {
810e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
811e43914b3SAndrew Geissler     }
812e43914b3SAndrew Geissler     else if (dbusBootProgress ==
813e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
814e43914b3SAndrew Geissler              "OSStart")
815e43914b3SAndrew Geissler     {
816e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
817e43914b3SAndrew Geissler     }
818e43914b3SAndrew Geissler     else if (dbusBootProgress ==
819e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
820e43914b3SAndrew Geissler              "OSRunning")
821e43914b3SAndrew Geissler     {
822e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
823e43914b3SAndrew Geissler     }
824e43914b3SAndrew Geissler     else
825e43914b3SAndrew Geissler     {
82662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
827e43914b3SAndrew Geissler         // Just return the default
828e43914b3SAndrew Geissler     }
829e43914b3SAndrew Geissler     return rfBpLastState;
830e43914b3SAndrew Geissler }
831e43914b3SAndrew Geissler 
832e43914b3SAndrew Geissler /**
833786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
834491d8ee7SSantosh Puranik  *
835491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
836944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
837944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
838491d8ee7SSantosh Puranik  *
839944ffaf9SJohnathan Mantey  * @return Integer error code.
840491d8ee7SSantosh Puranik  */
841ac106bf6SEd Tanous inline int
842ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
843ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
844ac106bf6SEd Tanous                          std::string& bootMode)
845491d8ee7SSantosh Puranik {
846c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
847c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
848944ffaf9SJohnathan Mantey 
849491d8ee7SSantosh Puranik     if (rfSource == "None")
850491d8ee7SSantosh Puranik     {
851944ffaf9SJohnathan Mantey         return 0;
852491d8ee7SSantosh Puranik     }
8533174e4dfSEd Tanous     if (rfSource == "Pxe")
854491d8ee7SSantosh Puranik     {
855944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
856944ffaf9SJohnathan Mantey     }
857944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
858944ffaf9SJohnathan Mantey     {
859944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
860944ffaf9SJohnathan Mantey     }
861944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
862944ffaf9SJohnathan Mantey     {
863944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
864944ffaf9SJohnathan Mantey     }
865944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
866944ffaf9SJohnathan Mantey     {
867944ffaf9SJohnathan Mantey         bootSource =
868944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
869944ffaf9SJohnathan Mantey     }
870944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
871944ffaf9SJohnathan Mantey     {
872944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
873491d8ee7SSantosh Puranik     }
8749f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8759f16b2c1SJennifer Lee     {
876944ffaf9SJohnathan Mantey         bootSource =
877944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8789f16b2c1SJennifer Lee     }
879491d8ee7SSantosh Puranik     else
880491d8ee7SSantosh Puranik     {
88162598e31SEd Tanous         BMCWEB_LOG_DEBUG(
88262598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
88362598e31SEd Tanous             bootSource);
884ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
885944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
886944ffaf9SJohnathan Mantey         return -1;
887491d8ee7SSantosh Puranik     }
888944ffaf9SJohnathan Mantey     return 0;
889491d8ee7SSantosh Puranik }
8901981771bSAli Ahmed 
891978b8803SAndrew Geissler /**
892978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
893978b8803SAndrew Geissler  *
894ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
895978b8803SAndrew Geissler  *
896978b8803SAndrew Geissler  * @return None.
897978b8803SAndrew Geissler  */
898ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
899978b8803SAndrew Geissler {
9001e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9011e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
9021e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
9031e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
904ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9051e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
906978b8803SAndrew Geissler         if (ec)
907978b8803SAndrew Geissler         {
908978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
909978b8803SAndrew Geissler             // not found
910978b8803SAndrew Geissler             return;
911978b8803SAndrew Geissler         }
912978b8803SAndrew Geissler 
91362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
914978b8803SAndrew Geissler 
915ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
916e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9171e1e598dSJonathan Doman     });
918978b8803SAndrew Geissler }
919491d8ee7SSantosh Puranik 
920491d8ee7SSantosh Puranik /**
921b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
922b6d5d45cSHieu Huynh  *
923ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
924b6d5d45cSHieu Huynh  *
925b6d5d45cSHieu Huynh  * @return None.
926b6d5d45cSHieu Huynh  */
927b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
928ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
929b6d5d45cSHieu Huynh {
930b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
931b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
932b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
933b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
934ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
935b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
936b6d5d45cSHieu Huynh         if (ec)
937b6d5d45cSHieu Huynh         {
93862598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
939b6d5d45cSHieu Huynh             return;
940b6d5d45cSHieu Huynh         }
941b6d5d45cSHieu Huynh 
942b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
943b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
944b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
945b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
946b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
947b6d5d45cSHieu Huynh 
948b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
949ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
950b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
951b6d5d45cSHieu Huynh     });
952b6d5d45cSHieu Huynh }
953b6d5d45cSHieu Huynh 
954b6d5d45cSHieu Huynh /**
955c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
956cd9a4666SKonstantin Aladyshev  *
957ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
958cd9a4666SKonstantin Aladyshev  *
959cd9a4666SKonstantin Aladyshev  * @return None.
960cd9a4666SKonstantin Aladyshev  */
961cd9a4666SKonstantin Aladyshev 
962ac106bf6SEd Tanous inline void
963ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
964cd9a4666SKonstantin Aladyshev {
9651e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9661e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9671e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9681e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
969ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9701e1e598dSJonathan Doman                     const std::string& bootType) {
971cd9a4666SKonstantin Aladyshev         if (ec)
972cd9a4666SKonstantin Aladyshev         {
973cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
974cd9a4666SKonstantin Aladyshev             return;
975cd9a4666SKonstantin Aladyshev         }
976cd9a4666SKonstantin Aladyshev 
97762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
978cd9a4666SKonstantin Aladyshev 
979ac106bf6SEd Tanous         asyncResp->res
980ac106bf6SEd Tanous             .jsonValue["Boot"]
981002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
982613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
983cd9a4666SKonstantin Aladyshev 
9841e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
985cd9a4666SKonstantin Aladyshev         if (rfType.empty())
986cd9a4666SKonstantin Aladyshev         {
987ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
988cd9a4666SKonstantin Aladyshev             return;
989cd9a4666SKonstantin Aladyshev         }
990cd9a4666SKonstantin Aladyshev 
991ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9921e1e598dSJonathan Doman     });
993cd9a4666SKonstantin Aladyshev }
994cd9a4666SKonstantin Aladyshev 
995cd9a4666SKonstantin Aladyshev /**
996c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
997491d8ee7SSantosh Puranik  *
998ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
999491d8ee7SSantosh Puranik  *
1000491d8ee7SSantosh Puranik  * @return None.
1001491d8ee7SSantosh Puranik  */
1002c21865c4SKonstantin Aladyshev 
1003ac106bf6SEd Tanous inline void
1004ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1005491d8ee7SSantosh Puranik {
10061e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10071e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10081e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10091e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1010ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10111e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1012491d8ee7SSantosh Puranik         if (ec)
1013491d8ee7SSantosh Puranik         {
1014b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1015ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1016491d8ee7SSantosh Puranik             return;
1017491d8ee7SSantosh Puranik         }
1018491d8ee7SSantosh Puranik 
101962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
1020491d8ee7SSantosh Puranik 
1021ac106bf6SEd Tanous         asyncResp->res
10220fda0f12SGeorge Liu             .jsonValue["Boot"]
1023002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1024002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1025491d8ee7SSantosh Puranik 
10261e1e598dSJonathan Doman         if (bootModeStr !=
1027491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1028491d8ee7SSantosh Puranik         {
10291e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1030491d8ee7SSantosh Puranik             if (!rfMode.empty())
1031491d8ee7SSantosh Puranik             {
1032ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1033491d8ee7SSantosh Puranik                     rfMode;
1034491d8ee7SSantosh Puranik             }
1035491d8ee7SSantosh Puranik         }
10361e1e598dSJonathan Doman     });
1037491d8ee7SSantosh Puranik }
1038491d8ee7SSantosh Puranik 
1039491d8ee7SSantosh Puranik /**
1040c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1041491d8ee7SSantosh Puranik  *
1042ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1043491d8ee7SSantosh Puranik  *
1044491d8ee7SSantosh Puranik  * @return None.
1045491d8ee7SSantosh Puranik  */
1046c21865c4SKonstantin Aladyshev 
1047c21865c4SKonstantin Aladyshev inline void
1048ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1049491d8ee7SSantosh Puranik {
10501e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10511e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10521e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10531e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1054ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10551e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1056491d8ee7SSantosh Puranik         if (ec)
1057491d8ee7SSantosh Puranik         {
10585ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10595ef735c8SNan Zhou             {
10605ef735c8SNan Zhou                 return;
10615ef735c8SNan Zhou             }
1062b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1063ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1064491d8ee7SSantosh Puranik             return;
1065491d8ee7SSantosh Puranik         }
1066491d8ee7SSantosh Puranik 
106762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1068491d8ee7SSantosh Puranik 
10691e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1070491d8ee7SSantosh Puranik         if (!rfSource.empty())
1071491d8ee7SSantosh Puranik         {
1072ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1073ac106bf6SEd Tanous                 rfSource;
1074491d8ee7SSantosh Puranik         }
1075cd9a4666SKonstantin Aladyshev 
1076cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1077cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1078ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10791e1e598dSJonathan Doman     });
1080491d8ee7SSantosh Puranik }
1081491d8ee7SSantosh Puranik 
1082491d8ee7SSantosh Puranik /**
1083c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1084c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1085c21865c4SKonstantin Aladyshev  * state
1086491d8ee7SSantosh Puranik  *
1087ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1088491d8ee7SSantosh Puranik  *
1089491d8ee7SSantosh Puranik  * @return None.
1090491d8ee7SSantosh Puranik  */
1091491d8ee7SSantosh Puranik 
1092ac106bf6SEd Tanous inline void processBootOverrideEnable(
1093ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1094c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1095c21865c4SKonstantin Aladyshev {
1096c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1097c21865c4SKonstantin Aladyshev     {
1098ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1099ac106bf6SEd Tanous             "Disabled";
1100c21865c4SKonstantin Aladyshev         return;
1101c21865c4SKonstantin Aladyshev     }
1102c21865c4SKonstantin Aladyshev 
1103c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1104c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
11051e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11061e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11071e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
11081e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1109ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1110491d8ee7SSantosh Puranik         if (ec)
1111491d8ee7SSantosh Puranik         {
1112b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1113ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1114491d8ee7SSantosh Puranik             return;
1115491d8ee7SSantosh Puranik         }
1116491d8ee7SSantosh Puranik 
1117c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1118c21865c4SKonstantin Aladyshev         {
1119ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1120ac106bf6SEd Tanous                 "Once";
1121c21865c4SKonstantin Aladyshev         }
1122c21865c4SKonstantin Aladyshev         else
1123c21865c4SKonstantin Aladyshev         {
1124ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1125c21865c4SKonstantin Aladyshev                 "Continuous";
1126c21865c4SKonstantin Aladyshev         }
11271e1e598dSJonathan Doman     });
1128491d8ee7SSantosh Puranik }
1129491d8ee7SSantosh Puranik 
1130491d8ee7SSantosh Puranik /**
1131c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1132c21865c4SKonstantin Aladyshev  *
1133ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1134c21865c4SKonstantin Aladyshev  *
1135c21865c4SKonstantin Aladyshev  * @return None.
1136c21865c4SKonstantin Aladyshev  */
1137c21865c4SKonstantin Aladyshev 
1138c21865c4SKonstantin Aladyshev inline void
1139ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1140c21865c4SKonstantin Aladyshev {
11411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11421e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11431e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11441e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1145ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11461e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1147c21865c4SKonstantin Aladyshev         if (ec)
1148c21865c4SKonstantin Aladyshev         {
11495ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11505ef735c8SNan Zhou             {
11515ef735c8SNan Zhou                 return;
11525ef735c8SNan Zhou             }
1153b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1154ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1155c21865c4SKonstantin Aladyshev             return;
1156c21865c4SKonstantin Aladyshev         }
1157c21865c4SKonstantin Aladyshev 
1158ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11591e1e598dSJonathan Doman     });
1160c21865c4SKonstantin Aladyshev }
1161c21865c4SKonstantin Aladyshev 
1162c21865c4SKonstantin Aladyshev /**
1163c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1164c21865c4SKonstantin Aladyshev  *
1165ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1166c21865c4SKonstantin Aladyshev  *
1167c21865c4SKonstantin Aladyshev  * @return None.
1168c21865c4SKonstantin Aladyshev  */
1169ac106bf6SEd Tanous inline void
1170ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1171c21865c4SKonstantin Aladyshev {
117262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1173c21865c4SKonstantin Aladyshev 
1174ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1175ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1176ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1177c21865c4SKonstantin Aladyshev }
1178c21865c4SKonstantin Aladyshev 
1179c21865c4SKonstantin Aladyshev /**
1180c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1181c0557e1aSGunnar Mills  *
1182c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1183c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1184c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1185c0557e1aSGunnar Mills  * last power operation time.
1186c0557e1aSGunnar Mills  *
1187ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1188c0557e1aSGunnar Mills  *
1189c0557e1aSGunnar Mills  * @return None.
1190c0557e1aSGunnar Mills  */
1191ac106bf6SEd Tanous inline void
1192ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1193c0557e1aSGunnar Mills {
119462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1195c0557e1aSGunnar Mills 
11961e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11971e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11981e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11991e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1200ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1201ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1202c0557e1aSGunnar Mills         if (ec)
1203c0557e1aSGunnar Mills         {
120462598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1205c0557e1aSGunnar Mills             return;
1206c0557e1aSGunnar Mills         }
1207c0557e1aSGunnar Mills 
1208c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1209c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12101e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1211c0557e1aSGunnar Mills 
1212c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1213ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12142b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12151e1e598dSJonathan Doman     });
1216c0557e1aSGunnar Mills }
1217c0557e1aSGunnar Mills 
1218c0557e1aSGunnar Mills /**
1219797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1220797d5daeSCorey Hardesty  *
1221797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1222797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1223797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1224797d5daeSCorey Hardesty  * dbus.
1225797d5daeSCorey Hardesty  *
1226ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1227797d5daeSCorey Hardesty  *
1228797d5daeSCorey Hardesty  * @return None.
1229797d5daeSCorey Hardesty  */
1230ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1231ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1232797d5daeSCorey Hardesty {
123362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1234797d5daeSCorey Hardesty 
1235797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1236797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1237797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1238797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1239ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1240ac106bf6SEd Tanous             const boost::system::error_code& ec,
1241797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1242797d5daeSCorey Hardesty         if (ec)
1243797d5daeSCorey Hardesty         {
1244797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1245797d5daeSCorey Hardesty             {
124662598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1247ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1248797d5daeSCorey Hardesty             }
1249797d5daeSCorey Hardesty             return;
1250797d5daeSCorey Hardesty         }
1251797d5daeSCorey Hardesty 
1252797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1253797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1254797d5daeSCorey Hardesty 
1255797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1256797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1257797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1258797d5daeSCorey Hardesty 
1259797d5daeSCorey Hardesty         if (!success)
1260797d5daeSCorey Hardesty         {
1261ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1262797d5daeSCorey Hardesty             return;
1263797d5daeSCorey Hardesty         }
1264797d5daeSCorey Hardesty 
1265797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1266797d5daeSCorey Hardesty         {
1267ac106bf6SEd Tanous             asyncResp->res
1268ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1269797d5daeSCorey Hardesty                 *attemptsLeft;
1270797d5daeSCorey Hardesty         }
1271797d5daeSCorey Hardesty 
1272797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1273797d5daeSCorey Hardesty         {
1274ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1275797d5daeSCorey Hardesty                 *retryAttempts;
1276797d5daeSCorey Hardesty         }
1277797d5daeSCorey Hardesty     });
1278797d5daeSCorey Hardesty }
1279797d5daeSCorey Hardesty 
1280797d5daeSCorey Hardesty /**
12816bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12826bd5a8d2SGunnar Mills  *
1283ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12846bd5a8d2SGunnar Mills  *
12856bd5a8d2SGunnar Mills  * @return None.
12866bd5a8d2SGunnar Mills  */
1287797d5daeSCorey Hardesty inline void
1288ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12896bd5a8d2SGunnar Mills {
129062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12916bd5a8d2SGunnar Mills 
12921e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12931e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12941e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12951e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1296ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1297ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12986bd5a8d2SGunnar Mills         if (ec)
12996bd5a8d2SGunnar Mills         {
1300797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1301797d5daeSCorey Hardesty             {
130262598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1303ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1304797d5daeSCorey Hardesty             }
13056bd5a8d2SGunnar Mills             return;
13066bd5a8d2SGunnar Mills         }
13076bd5a8d2SGunnar Mills 
130862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1309e05aec50SEd Tanous         if (autoRebootEnabled)
13106bd5a8d2SGunnar Mills         {
1311ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13126bd5a8d2SGunnar Mills                 "RetryAttempts";
13136bd5a8d2SGunnar Mills         }
13146bd5a8d2SGunnar Mills         else
13156bd5a8d2SGunnar Mills         {
1316ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1317ac106bf6SEd Tanous                 "Disabled";
13186bd5a8d2SGunnar Mills         }
1319ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
132069f35306SGunnar Mills 
132169f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
132269f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
132369f35306SGunnar Mills         // RetryAttempts.
1324ac106bf6SEd Tanous         asyncResp->res
1325ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1326ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13271e1e598dSJonathan Doman     });
13286bd5a8d2SGunnar Mills }
13296bd5a8d2SGunnar Mills 
13306bd5a8d2SGunnar Mills /**
1331797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1332797d5daeSCorey Hardesty  *
1333ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1334797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1335797d5daeSCorey Hardesty  *
1336797d5daeSCorey Hardesty  *@return None.
1337797d5daeSCorey Hardesty  */
1338797d5daeSCorey Hardesty 
1339ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1340ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1341797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1342797d5daeSCorey Hardesty {
134362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
13449ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13459ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13469ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13479ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13489ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1349797d5daeSCorey Hardesty         if (ec)
1350797d5daeSCorey Hardesty         {
135162598e31SEd Tanous             BMCWEB_LOG_ERROR(
135262598e31SEd Tanous                 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1353ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1354797d5daeSCorey Hardesty             return;
1355797d5daeSCorey Hardesty         }
13569ae226faSGeorge Liu     });
1357797d5daeSCorey Hardesty }
1358797d5daeSCorey Hardesty 
13598d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13608d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13618d69c668SEd Tanous {
13628d69c668SEd Tanous     if (value ==
13638d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13648d69c668SEd Tanous     {
13658d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13668d69c668SEd Tanous     }
13678d69c668SEd Tanous     if (value ==
13688d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13698d69c668SEd Tanous     {
13708d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13718d69c668SEd Tanous     }
13728d69c668SEd Tanous     if (value ==
13733a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13748d69c668SEd Tanous     {
13758d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13768d69c668SEd Tanous     }
13778d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13788d69c668SEd Tanous     {
13798d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13808d69c668SEd Tanous     }
13818d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13828d69c668SEd Tanous }
1383797d5daeSCorey Hardesty /**
1384c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1385c6a620f2SGeorge Liu  *
1386ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1387c6a620f2SGeorge Liu  *
1388c6a620f2SGeorge Liu  * @return None.
1389c6a620f2SGeorge Liu  */
13908d1b46d7Szhanghch05 inline void
1391ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1392c6a620f2SGeorge Liu {
139362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1394c6a620f2SGeorge Liu 
13951e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13961e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13971e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13981e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1399ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
14005e7e2dc5SEd Tanous                     const std::string& policy) {
1401c6a620f2SGeorge Liu         if (ec)
1402c6a620f2SGeorge Liu         {
140362598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1404c6a620f2SGeorge Liu             return;
1405c6a620f2SGeorge Liu         }
14068d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
14078d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14088d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1409c6a620f2SGeorge Liu         {
1410ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1411c6a620f2SGeorge Liu             return;
1412c6a620f2SGeorge Liu         }
1413c6a620f2SGeorge Liu 
14148d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14151e1e598dSJonathan Doman     });
1416c6a620f2SGeorge Liu }
1417c6a620f2SGeorge Liu 
1418c6a620f2SGeorge Liu /**
14199dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14209dcfe8c1SAlbert Zhang  *
14219dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14229dcfe8c1SAlbert Zhang  *
14239dcfe8c1SAlbert Zhang  * @return None.
14249dcfe8c1SAlbert Zhang  */
14259dcfe8c1SAlbert Zhang inline void
14269dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14279dcfe8c1SAlbert Zhang {
142862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
14299dcfe8c1SAlbert Zhang 
14309dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
14319dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14329dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
14339dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14349dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14359dcfe8c1SAlbert Zhang         if (ec)
14369dcfe8c1SAlbert Zhang         {
14379dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
14389dcfe8c1SAlbert Zhang             {
1439b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
14409dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
14419dcfe8c1SAlbert Zhang             }
14429dcfe8c1SAlbert Zhang             return;
14439dcfe8c1SAlbert Zhang         }
14449dcfe8c1SAlbert Zhang 
14459dcfe8c1SAlbert Zhang         if (value)
14469dcfe8c1SAlbert Zhang         {
14479dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
14489dcfe8c1SAlbert Zhang         }
14499dcfe8c1SAlbert Zhang         else
14509dcfe8c1SAlbert Zhang         {
14519dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
14529dcfe8c1SAlbert Zhang         }
14539dcfe8c1SAlbert Zhang     });
14549dcfe8c1SAlbert Zhang }
14559dcfe8c1SAlbert Zhang 
14569dcfe8c1SAlbert Zhang /**
14571981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14581981771bSAli Ahmed  * TPM is required for booting the host.
14591981771bSAli Ahmed  *
1460ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14611981771bSAli Ahmed  *
14621981771bSAli Ahmed  * @return None.
14631981771bSAli Ahmed  */
14641981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1465ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14661981771bSAli Ahmed {
146762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1468e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1469e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1470e99073f5SGeorge Liu     dbus::utility::getSubTree(
1471e99073f5SGeorge Liu         "/", 0, interfaces,
1472ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1473b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14741981771bSAli Ahmed         if (ec)
14751981771bSAli Ahmed         {
147662598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
147762598e31SEd Tanous                              ec);
14781981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14791981771bSAli Ahmed             // error occurs
14801981771bSAli Ahmed             return;
14811981771bSAli Ahmed         }
148226f6976fSEd Tanous         if (subtree.empty())
14831981771bSAli Ahmed         {
14841981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14851981771bSAli Ahmed             // if there is no instance found
14861981771bSAli Ahmed             return;
14871981771bSAli Ahmed         }
14881981771bSAli Ahmed 
14891981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14901981771bSAli Ahmed         if (subtree.size() > 1)
14911981771bSAli Ahmed         {
149262598e31SEd Tanous             BMCWEB_LOG_DEBUG(
149362598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
149462598e31SEd Tanous                 subtree.size());
14951981771bSAli Ahmed             // Throw an internal Error and return
1496ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14971981771bSAli Ahmed             return;
14981981771bSAli Ahmed         }
14991981771bSAli Ahmed 
15001981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15011981771bSAli Ahmed         // field
15021981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15031981771bSAli Ahmed         {
150462598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1505ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15061981771bSAli Ahmed             return;
15071981771bSAli Ahmed         }
15081981771bSAli Ahmed 
15091981771bSAli Ahmed         const std::string& path = subtree[0].first;
15101981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15111981771bSAli Ahmed 
15121981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15131e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15141e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15151e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1516ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1517ac106bf6SEd Tanous                         bool tpmRequired) {
15188a592810SEd Tanous             if (ec2)
15191981771bSAli Ahmed             {
1520b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
152162598e31SEd Tanous                                  ec2);
1522ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15231981771bSAli Ahmed                 return;
15241981771bSAli Ahmed             }
15251981771bSAli Ahmed 
15261e1e598dSJonathan Doman             if (tpmRequired)
15271981771bSAli Ahmed             {
1528ac106bf6SEd Tanous                 asyncResp->res
1529ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15301981771bSAli Ahmed                     "Required";
15311981771bSAli Ahmed             }
15321981771bSAli Ahmed             else
15331981771bSAli Ahmed             {
1534ac106bf6SEd Tanous                 asyncResp->res
1535ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15361981771bSAli Ahmed                     "Disabled";
15371981771bSAli Ahmed             }
15381e1e598dSJonathan Doman         });
1539e99073f5SGeorge Liu     });
15401981771bSAli Ahmed }
15411981771bSAli Ahmed 
15421981771bSAli Ahmed /**
15431c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15441c05dae3SAli Ahmed  * TPM is required for booting the host.
15451c05dae3SAli Ahmed  *
1546ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15471c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15481c05dae3SAli Ahmed  *
15491c05dae3SAli Ahmed  * @return None.
15501c05dae3SAli Ahmed  */
15511c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1552ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15531c05dae3SAli Ahmed {
155462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1555e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1556e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1557e99073f5SGeorge Liu     dbus::utility::getSubTree(
1558e99073f5SGeorge Liu         "/", 0, interfaces,
1559ac106bf6SEd Tanous         [asyncResp,
1560e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1561e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15621c05dae3SAli Ahmed         if (ec)
15631c05dae3SAli Ahmed         {
1564b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
156562598e31SEd Tanous                              ec);
1566ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15671c05dae3SAli Ahmed             return;
15681c05dae3SAli Ahmed         }
156926f6976fSEd Tanous         if (subtree.empty())
15701c05dae3SAli Ahmed         {
1571ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15721c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15731c05dae3SAli Ahmed             return;
15741c05dae3SAli Ahmed         }
15751c05dae3SAli Ahmed 
15761c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15771c05dae3SAli Ahmed         if (subtree.size() > 1)
15781c05dae3SAli Ahmed         {
157962598e31SEd Tanous             BMCWEB_LOG_DEBUG(
158062598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
158162598e31SEd Tanous                 subtree.size());
15821c05dae3SAli Ahmed             // Throw an internal Error and return
1583ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15841c05dae3SAli Ahmed             return;
15851c05dae3SAli Ahmed         }
15861c05dae3SAli Ahmed 
15871c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15881c05dae3SAli Ahmed         // field
15891c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15901c05dae3SAli Ahmed         {
159162598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1592ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15931c05dae3SAli Ahmed             return;
15941c05dae3SAli Ahmed         }
15951c05dae3SAli Ahmed 
15961c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15971c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15981c05dae3SAli Ahmed 
15991c05dae3SAli Ahmed         if (serv.empty())
16001c05dae3SAli Ahmed         {
160162598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1602ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
16031c05dae3SAli Ahmed             return;
16041c05dae3SAli Ahmed         }
16051c05dae3SAli Ahmed 
16061c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
16079ae226faSGeorge Liu         sdbusplus::asio::setProperty(
16089ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16099ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1610ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16118a592810SEd Tanous             if (ec2)
16121c05dae3SAli Ahmed             {
1613b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
161462598e31SEd Tanous                     "DBUS response error: Set TrustedModuleRequiredToBoot{}",
161562598e31SEd Tanous                     ec2);
1616ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16171c05dae3SAli Ahmed                 return;
16181c05dae3SAli Ahmed             }
161962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
16209ae226faSGeorge Liu         });
1621e99073f5SGeorge Liu     });
16221c05dae3SAli Ahmed }
16231c05dae3SAli Ahmed 
16241c05dae3SAli Ahmed /**
1625491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1626491d8ee7SSantosh Puranik  *
1627ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1628cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1629cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1630cd9a4666SKonstantin Aladyshev  */
1631ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1632cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1633cd9a4666SKonstantin Aladyshev {
1634c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1635cd9a4666SKonstantin Aladyshev 
1636c21865c4SKonstantin Aladyshev     if (!bootType)
1637cd9a4666SKonstantin Aladyshev     {
1638c21865c4SKonstantin Aladyshev         return;
1639c21865c4SKonstantin Aladyshev     }
1640c21865c4SKonstantin Aladyshev 
1641cd9a4666SKonstantin Aladyshev     // Source target specified
164262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1643cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1644cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1645cd9a4666SKonstantin Aladyshev     {
1646cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1647cd9a4666SKonstantin Aladyshev     }
1648cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1649cd9a4666SKonstantin Aladyshev     {
1650cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1651cd9a4666SKonstantin Aladyshev     }
1652cd9a4666SKonstantin Aladyshev     else
1653cd9a4666SKonstantin Aladyshev     {
165462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
165562598e31SEd Tanous                          "BootSourceOverrideMode: {}",
165662598e31SEd Tanous                          *bootType);
1657ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1658cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1659cd9a4666SKonstantin Aladyshev         return;
1660cd9a4666SKonstantin Aladyshev     }
1661cd9a4666SKonstantin Aladyshev 
1662cd9a4666SKonstantin Aladyshev     // Act on validated parameters
166362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1664cd9a4666SKonstantin Aladyshev 
16659ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16669ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16679ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16689ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1669ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1670cd9a4666SKonstantin Aladyshev         if (ec)
1671cd9a4666SKonstantin Aladyshev         {
1672cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1673cd9a4666SKonstantin Aladyshev             {
1674ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1675cd9a4666SKonstantin Aladyshev                 return;
1676cd9a4666SKonstantin Aladyshev             }
1677b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1678ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1679cd9a4666SKonstantin Aladyshev             return;
1680cd9a4666SKonstantin Aladyshev         }
168162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type update done.");
16829ae226faSGeorge Liu     });
1683cd9a4666SKonstantin Aladyshev }
1684cd9a4666SKonstantin Aladyshev 
1685cd9a4666SKonstantin Aladyshev /**
1686cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1687cd9a4666SKonstantin Aladyshev  *
1688ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1689ac106bf6SEd Tanous  * message.
1690c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1691c21865c4SKonstantin Aladyshev  * @return Integer error code.
1692c21865c4SKonstantin Aladyshev  */
1693ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1694c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1695c21865c4SKonstantin Aladyshev {
1696c21865c4SKonstantin Aladyshev     if (!bootEnable)
1697c21865c4SKonstantin Aladyshev     {
1698c21865c4SKonstantin Aladyshev         return;
1699c21865c4SKonstantin Aladyshev     }
1700c21865c4SKonstantin Aladyshev     // Source target specified
170162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1702c21865c4SKonstantin Aladyshev 
1703c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1704c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1705c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1706c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1707c21865c4SKonstantin Aladyshev     {
1708c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1709c21865c4SKonstantin Aladyshev     }
1710c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1711c21865c4SKonstantin Aladyshev     {
1712c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1713c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1714c21865c4SKonstantin Aladyshev     }
1715c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1716c21865c4SKonstantin Aladyshev     {
1717c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1718c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1719c21865c4SKonstantin Aladyshev     }
1720c21865c4SKonstantin Aladyshev     else
1721c21865c4SKonstantin Aladyshev     {
172262598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172362598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
172462598e31SEd Tanous             *bootEnable);
1725ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1726c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1727c21865c4SKonstantin Aladyshev         return;
1728c21865c4SKonstantin Aladyshev     }
1729c21865c4SKonstantin Aladyshev 
1730c21865c4SKonstantin Aladyshev     // Act on validated parameters
173162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1732c21865c4SKonstantin Aladyshev 
17339ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17349ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17359ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17369ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1737ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17388a592810SEd Tanous         if (ec2)
1739c21865c4SKonstantin Aladyshev         {
1740b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
1741ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1742c21865c4SKonstantin Aladyshev             return;
1743c21865c4SKonstantin Aladyshev         }
174462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot override enable update done.");
17459ae226faSGeorge Liu     });
1746c21865c4SKonstantin Aladyshev 
1747c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1748c21865c4SKonstantin Aladyshev     {
1749c21865c4SKonstantin Aladyshev         return;
1750c21865c4SKonstantin Aladyshev     }
1751c21865c4SKonstantin Aladyshev 
1752c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1753c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
175462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
175562598e31SEd Tanous                      bootOverridePersistent);
1756c21865c4SKonstantin Aladyshev 
17579ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17589ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17599ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17609ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1761ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1762c21865c4SKonstantin Aladyshev         if (ec)
1763c21865c4SKonstantin Aladyshev         {
1764b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1765ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1766c21865c4SKonstantin Aladyshev             return;
1767c21865c4SKonstantin Aladyshev         }
176862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot one_time update done.");
17699ae226faSGeorge Liu     });
1770c21865c4SKonstantin Aladyshev }
1771c21865c4SKonstantin Aladyshev 
1772c21865c4SKonstantin Aladyshev /**
1773c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1774c21865c4SKonstantin Aladyshev  *
1775ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1776491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1777491d8ee7SSantosh Puranik  *
1778265c1602SJohnathan Mantey  * @return Integer error code.
1779491d8ee7SSantosh Puranik  */
1780ac106bf6SEd Tanous inline void
1781ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1782cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1783491d8ee7SSantosh Puranik {
1784c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1785c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1786944ffaf9SJohnathan Mantey 
1787c21865c4SKonstantin Aladyshev     if (!bootSource)
1788491d8ee7SSantosh Puranik     {
1789c21865c4SKonstantin Aladyshev         return;
1790c21865c4SKonstantin Aladyshev     }
1791c21865c4SKonstantin Aladyshev 
1792491d8ee7SSantosh Puranik     // Source target specified
179362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1794491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1795ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1796ac106bf6SEd Tanous                              bootModeStr) != 0)
1797491d8ee7SSantosh Puranik     {
179862598e31SEd Tanous         BMCWEB_LOG_DEBUG(
179962598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
180062598e31SEd Tanous             *bootSource);
1801ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1802491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1803491d8ee7SSantosh Puranik         return;
1804491d8ee7SSantosh Puranik     }
1805491d8ee7SSantosh Puranik 
1806944ffaf9SJohnathan Mantey     // Act on validated parameters
180762598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
180862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1809944ffaf9SJohnathan Mantey 
18109ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18119ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18129ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18139ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1814ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1815491d8ee7SSantosh Puranik         if (ec)
1816491d8ee7SSantosh Puranik         {
1817b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1818ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1819491d8ee7SSantosh Puranik             return;
1820491d8ee7SSantosh Puranik         }
182162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source update done.");
18229ae226faSGeorge Liu     });
1823944ffaf9SJohnathan Mantey 
18249ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18259ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18269ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18279ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1828ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1829491d8ee7SSantosh Puranik         if (ec)
1830491d8ee7SSantosh Puranik         {
1831b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1832ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1833491d8ee7SSantosh Puranik             return;
1834491d8ee7SSantosh Puranik         }
183562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode update done.");
18369ae226faSGeorge Liu     });
1837cd9a4666SKonstantin Aladyshev }
1838944ffaf9SJohnathan Mantey 
1839cd9a4666SKonstantin Aladyshev /**
1840c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1841491d8ee7SSantosh Puranik  *
1842ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1843491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1844cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1845491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1846491d8ee7SSantosh Puranik  *
1847265c1602SJohnathan Mantey  * @return Integer error code.
1848491d8ee7SSantosh Puranik  */
1849c21865c4SKonstantin Aladyshev 
1850ac106bf6SEd Tanous inline void
1851ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1852c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1853c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1854c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1855491d8ee7SSantosh Puranik {
185662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1857491d8ee7SSantosh Puranik 
1858ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1859ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1860ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1861491d8ee7SSantosh Puranik }
1862491d8ee7SSantosh Puranik 
1863c6a620f2SGeorge Liu /**
186498e386ecSGunnar Mills  * @brief Sets AssetTag
186598e386ecSGunnar Mills  *
1866ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
186798e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
186898e386ecSGunnar Mills  *
186998e386ecSGunnar Mills  * @return None.
187098e386ecSGunnar Mills  */
1871ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
187298e386ecSGunnar Mills                         const std::string& assetTag)
187398e386ecSGunnar Mills {
1874e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1875e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1876e99073f5SGeorge Liu     dbus::utility::getSubTree(
1877e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1878ac106bf6SEd Tanous         [asyncResp,
1879e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1880b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
188198e386ecSGunnar Mills         if (ec)
188298e386ecSGunnar Mills         {
188362598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1884ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188598e386ecSGunnar Mills             return;
188698e386ecSGunnar Mills         }
188726f6976fSEd Tanous         if (subtree.empty())
188898e386ecSGunnar Mills         {
188962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1890ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189198e386ecSGunnar Mills             return;
189298e386ecSGunnar Mills         }
189398e386ecSGunnar Mills         // Assume only 1 system D-Bus object
189498e386ecSGunnar Mills         // Throw an error if there is more than 1
189598e386ecSGunnar Mills         if (subtree.size() > 1)
189698e386ecSGunnar Mills         {
189762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1898ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189998e386ecSGunnar Mills             return;
190098e386ecSGunnar Mills         }
190198e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
190298e386ecSGunnar Mills         {
190362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1904ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190598e386ecSGunnar Mills             return;
190698e386ecSGunnar Mills         }
190798e386ecSGunnar Mills 
190898e386ecSGunnar Mills         const std::string& path = subtree[0].first;
190998e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
191098e386ecSGunnar Mills 
191198e386ecSGunnar Mills         if (service.empty())
191298e386ecSGunnar Mills         {
191362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1914ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
191598e386ecSGunnar Mills             return;
191698e386ecSGunnar Mills         }
191798e386ecSGunnar Mills 
19189ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19199ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19209ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19219ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
192298e386ecSGunnar Mills             if (ec2)
192398e386ecSGunnar Mills             {
1924b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
192562598e31SEd Tanous                                  ec2);
1926ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
192798e386ecSGunnar Mills                 return;
192898e386ecSGunnar Mills             }
19299ae226faSGeorge Liu         });
1930e99073f5SGeorge Liu     });
193198e386ecSGunnar Mills }
193298e386ecSGunnar Mills 
193398e386ecSGunnar Mills /**
19349dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19359dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19369dcfe8c1SAlbert Zhang  *
19379dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19389dcfe8c1SAlbert Zhang  * stopBootOnFault
19399dcfe8c1SAlbert Zhang  *
19409dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19419dcfe8c1SAlbert Zhang  */
19429dcfe8c1SAlbert Zhang inline std::optional<bool>
19439dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
19449dcfe8c1SAlbert Zhang {
19459dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19469dcfe8c1SAlbert Zhang     {
19479dcfe8c1SAlbert Zhang         return true;
19489dcfe8c1SAlbert Zhang     }
19499dcfe8c1SAlbert Zhang 
19509dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19519dcfe8c1SAlbert Zhang     {
19529dcfe8c1SAlbert Zhang         return false;
19539dcfe8c1SAlbert Zhang     }
19549dcfe8c1SAlbert Zhang 
19559dcfe8c1SAlbert Zhang     return std::nullopt;
19569dcfe8c1SAlbert Zhang }
19579dcfe8c1SAlbert Zhang 
19589dcfe8c1SAlbert Zhang /**
19599dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19609dcfe8c1SAlbert Zhang  *
1961fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
19629dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19639dcfe8c1SAlbert Zhang  *
19649dcfe8c1SAlbert Zhang  * @return None.
19659dcfe8c1SAlbert Zhang  */
1966fc3edfddSEd Tanous inline void
1967fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19689dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
19699dcfe8c1SAlbert Zhang {
197062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
19719dcfe8c1SAlbert Zhang 
19729dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19739dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19749dcfe8c1SAlbert Zhang     {
197562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
197662598e31SEd Tanous                          stopBootOnFault);
1977fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19789dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19799dcfe8c1SAlbert Zhang         return;
19809dcfe8c1SAlbert Zhang     }
19819dcfe8c1SAlbert Zhang 
1982fc3edfddSEd Tanous     sdbusplus::asio::setProperty(
1983fc3edfddSEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19849dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1985fc3edfddSEd Tanous         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1986fc3edfddSEd Tanous         *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
19879dcfe8c1SAlbert Zhang         if (ec)
19889dcfe8c1SAlbert Zhang         {
19899dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19909dcfe8c1SAlbert Zhang             {
1991b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1992fc3edfddSEd Tanous                 messages::internalError(asyncResp->res);
19939dcfe8c1SAlbert Zhang             }
19949dcfe8c1SAlbert Zhang             return;
19959dcfe8c1SAlbert Zhang         }
19969dcfe8c1SAlbert Zhang     });
19979dcfe8c1SAlbert Zhang }
19989dcfe8c1SAlbert Zhang 
19999dcfe8c1SAlbert Zhang /**
200069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
200169f35306SGunnar Mills  *
2002ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
200369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
200469f35306SGunnar Mills  *
200569f35306SGunnar Mills  * @return None.
200669f35306SGunnar Mills  */
2007ac106bf6SEd Tanous inline void
2008ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2009f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
201069f35306SGunnar Mills {
201162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
201269f35306SGunnar Mills 
201369f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2014543f4400SEd Tanous     bool autoRebootEnabled = false;
201569f35306SGunnar Mills 
201669f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
201769f35306SGunnar Mills     {
201869f35306SGunnar Mills         autoRebootEnabled = false;
201969f35306SGunnar Mills     }
202069f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
202169f35306SGunnar Mills     {
202269f35306SGunnar Mills         autoRebootEnabled = true;
202369f35306SGunnar Mills     }
202469f35306SGunnar Mills     else
202569f35306SGunnar Mills     {
202662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
202762598e31SEd Tanous                          automaticRetryConfig);
2028ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
202969f35306SGunnar Mills                                          "AutomaticRetryConfig");
203069f35306SGunnar Mills         return;
203169f35306SGunnar Mills     }
203269f35306SGunnar Mills 
20339ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20349ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20359ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20369ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20379ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
203869f35306SGunnar Mills         if (ec)
203969f35306SGunnar Mills         {
2040b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2041ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
204269f35306SGunnar Mills             return;
204369f35306SGunnar Mills         }
20449ae226faSGeorge Liu     });
204569f35306SGunnar Mills }
204669f35306SGunnar Mills 
20478d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20488d69c668SEd Tanous {
20498d69c668SEd Tanous     if (policy == "AlwaysOn")
20508d69c668SEd Tanous     {
20518d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20528d69c668SEd Tanous     }
20538d69c668SEd Tanous     if (policy == "AlwaysOff")
20548d69c668SEd Tanous     {
20558d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20568d69c668SEd Tanous     }
20578d69c668SEd Tanous     if (policy == "LastState")
20588d69c668SEd Tanous     {
20598d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20608d69c668SEd Tanous     }
20618d69c668SEd Tanous     return "";
20628d69c668SEd Tanous }
20638d69c668SEd Tanous 
206469f35306SGunnar Mills /**
2065c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2066c6a620f2SGeorge Liu  *
2067ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2068c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2069c6a620f2SGeorge Liu  *
2070c6a620f2SGeorge Liu  * @return None.
2071c6a620f2SGeorge Liu  */
20728d1b46d7Szhanghch05 inline void
2073ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20748d69c668SEd Tanous                           std::string_view policy)
2075c6a620f2SGeorge Liu {
207662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2077c6a620f2SGeorge Liu 
20788d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2079c6a620f2SGeorge Liu 
20808d69c668SEd Tanous     if (powerRestorePolicy.empty())
2081c6a620f2SGeorge Liu     {
2082ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20834e69c904SGunnar Mills                                          "PowerRestorePolicy");
2084c6a620f2SGeorge Liu         return;
2085c6a620f2SGeorge Liu     }
2086c6a620f2SGeorge Liu 
20879ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20889ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20899ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20909ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20919ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2092c6a620f2SGeorge Liu         if (ec)
2093c6a620f2SGeorge Liu         {
2094b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2095ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2096c6a620f2SGeorge Liu             return;
2097c6a620f2SGeorge Liu         }
20989ae226faSGeorge Liu     });
2099c6a620f2SGeorge Liu }
2100c6a620f2SGeorge Liu 
2101a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2102a6349918SAppaRao Puli /**
2103a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2104a6349918SAppaRao Puli  *
2105ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2106a6349918SAppaRao Puli  *
2107a6349918SAppaRao Puli  * @return None.
2108a6349918SAppaRao Puli  */
2109ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2110a6349918SAppaRao Puli {
211162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2112bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2113bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2114bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2115ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2116b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2117b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2118ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2119ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
212050626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
212150626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
212250626f4fSJames Feist 
2123a6349918SAppaRao Puli         if (ec)
2124a6349918SAppaRao Puli         {
212562598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2126b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2127b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2128a6349918SAppaRao Puli             return;
2129a6349918SAppaRao Puli         }
2130a6349918SAppaRao Puli 
2131a6349918SAppaRao Puli         const bool* provState = nullptr;
2132a6349918SAppaRao Puli         const bool* lockState = nullptr;
2133bc1d29deSKrzysztof Grobelny 
2134bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21350d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21360d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2137bc1d29deSKrzysztof Grobelny 
2138bc1d29deSKrzysztof Grobelny         if (!success)
2139a6349918SAppaRao Puli         {
2140ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2141bc1d29deSKrzysztof Grobelny             return;
2142a6349918SAppaRao Puli         }
2143a6349918SAppaRao Puli 
2144a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2145a6349918SAppaRao Puli         {
214662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2147ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2148a6349918SAppaRao Puli             return;
2149a6349918SAppaRao Puli         }
2150a6349918SAppaRao Puli 
2151a6349918SAppaRao Puli         if (*provState == true)
2152a6349918SAppaRao Puli         {
2153a6349918SAppaRao Puli             if (*lockState == true)
2154a6349918SAppaRao Puli             {
2155a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2156a6349918SAppaRao Puli             }
2157a6349918SAppaRao Puli             else
2158a6349918SAppaRao Puli             {
2159a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2160a6349918SAppaRao Puli             }
2161a6349918SAppaRao Puli         }
2162a6349918SAppaRao Puli         else
2163a6349918SAppaRao Puli         {
2164a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2165a6349918SAppaRao Puli         }
2166bc1d29deSKrzysztof Grobelny     });
2167a6349918SAppaRao Puli }
2168a6349918SAppaRao Puli #endif
2169a6349918SAppaRao Puli 
2170491d8ee7SSantosh Puranik /**
2171*6b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
21723a2d0424SChris Cain  *
2173*6b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
21743a2d0424SChris Cain  *
2175*6b9ac4f2SChris Cain  * @return PowerMode enum
21763a2d0424SChris Cain  */
2177*6b9ac4f2SChris Cain inline computer_system::PowerMode
2178*6b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
21793a2d0424SChris Cain {
2180b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2181b6655101SChris Cain 
2182*6b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21833a2d0424SChris Cain     {
2184*6b9ac4f2SChris Cain         return PowerMode::Static;
21853a2d0424SChris Cain     }
2186*6b9ac4f2SChris Cain     if (modeString ==
21870fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21883a2d0424SChris Cain     {
2189*6b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
21903a2d0424SChris Cain     }
2191*6b9ac4f2SChris Cain     if (modeString ==
21920fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21933a2d0424SChris Cain     {
2194*6b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2195b6655101SChris Cain     }
2196*6b9ac4f2SChris Cain     if (modeString ==
2197b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2198b6655101SChris Cain     {
2199*6b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2200b6655101SChris Cain     }
2201*6b9ac4f2SChris Cain     if (modeString ==
2202b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2203b6655101SChris Cain     {
2204*6b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2205b6655101SChris Cain     }
2206*6b9ac4f2SChris Cain     if (modeString ==
2207b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2208b6655101SChris Cain     {
2209*6b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
22103a2d0424SChris Cain     }
2211*6b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
22123a2d0424SChris Cain     {
2213*6b9ac4f2SChris Cain         return PowerMode::OEM;
2214*6b9ac4f2SChris Cain     }
2215*6b9ac4f2SChris Cain     // Any other values would be invalid
2216*6b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2217*6b9ac4f2SChris Cain     return PowerMode::Invalid;
2218*6b9ac4f2SChris Cain }
2219*6b9ac4f2SChris Cain 
2220*6b9ac4f2SChris Cain inline void
2221*6b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2222*6b9ac4f2SChris Cain                       const boost::system::error_code& ec,
2223*6b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
2224*6b9ac4f2SChris Cain {
2225*6b9ac4f2SChris Cain     if (ec)
2226*6b9ac4f2SChris Cain     {
2227*6b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2228*6b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
2229*6b9ac4f2SChris Cain         return;
2230*6b9ac4f2SChris Cain     }
2231*6b9ac4f2SChris Cain 
2232*6b9ac4f2SChris Cain     std::string powerMode;
2233*6b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
2234*6b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
2235*6b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2236*6b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
2237*6b9ac4f2SChris Cain 
2238*6b9ac4f2SChris Cain     if (!success)
2239*6b9ac4f2SChris Cain     {
2240*6b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
2241*6b9ac4f2SChris Cain         return;
2242*6b9ac4f2SChris Cain     }
2243*6b9ac4f2SChris Cain 
2244*6b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
2245*6b9ac4f2SChris Cain     if (allowedModes == nullptr)
2246*6b9ac4f2SChris Cain     {
2247*6b9ac4f2SChris Cain         modeList.emplace_back("Static");
2248*6b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
2249*6b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
22503a2d0424SChris Cain     }
22513a2d0424SChris Cain     else
22523a2d0424SChris Cain     {
2253*6b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
2254*6b9ac4f2SChris Cain         {
2255*6b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
2256*6b9ac4f2SChris Cain                 translatePowerModeString(aMode);
2257*6b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
2258*6b9ac4f2SChris Cain             {
2259ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2260*6b9ac4f2SChris Cain                 continue;
2261*6b9ac4f2SChris Cain             }
2262*6b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
22633a2d0424SChris Cain         }
22643a2d0424SChris Cain     }
2265*6b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
22663a2d0424SChris Cain 
2267*6b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2268*6b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
2269*6b9ac4f2SChris Cain         translatePowerModeString(powerMode);
2270*6b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
2271*6b9ac4f2SChris Cain     {
2272*6b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
2273*6b9ac4f2SChris Cain         return;
2274*6b9ac4f2SChris Cain     }
2275*6b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
2276*6b9ac4f2SChris Cain }
22773a2d0424SChris Cain /**
22783a2d0424SChris Cain  * @brief Retrieves system power mode
22793a2d0424SChris Cain  *
2280ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22813a2d0424SChris Cain  *
22823a2d0424SChris Cain  * @return None.
22833a2d0424SChris Cain  */
2284ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22853a2d0424SChris Cain {
228662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22873a2d0424SChris Cain 
22883a2d0424SChris Cain     // Get Power Mode object path:
2289e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2290e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2291e99073f5SGeorge Liu     dbus::utility::getSubTree(
2292e99073f5SGeorge Liu         "/", 0, interfaces,
2293ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2294b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22953a2d0424SChris Cain         if (ec)
22963a2d0424SChris Cain         {
229762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
229862598e31SEd Tanous                              ec);
22993a2d0424SChris Cain             // This is an optional D-Bus object so just return if
23003a2d0424SChris Cain             // error occurs
23013a2d0424SChris Cain             return;
23023a2d0424SChris Cain         }
23033a2d0424SChris Cain         if (subtree.empty())
23043a2d0424SChris Cain         {
23053a2d0424SChris Cain             // As noted above, this is an optional interface so just return
23063a2d0424SChris Cain             // if there is no instance found
23073a2d0424SChris Cain             return;
23083a2d0424SChris Cain         }
23093a2d0424SChris Cain         if (subtree.size() > 1)
23103a2d0424SChris Cain         {
23113a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23123a2d0424SChris Cain             // error
231362598e31SEd Tanous             BMCWEB_LOG_DEBUG(
231462598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
231562598e31SEd Tanous                 subtree.size());
2316ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23173a2d0424SChris Cain             return;
23183a2d0424SChris Cain         }
23193a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23203a2d0424SChris Cain         {
232162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2322ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23233a2d0424SChris Cain             return;
23243a2d0424SChris Cain         }
23253a2d0424SChris Cain         const std::string& path = subtree[0].first;
23263a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23273a2d0424SChris Cain         if (service.empty())
23283a2d0424SChris Cain         {
232962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2330ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23313a2d0424SChris Cain             return;
23323a2d0424SChris Cain         }
2333*6b9ac4f2SChris Cain 
2334*6b9ac4f2SChris Cain         // Valid Power Mode object found, now read the mode properties
2335*6b9ac4f2SChris Cain         sdbusplus::asio::getAllProperties(
23361e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
2337*6b9ac4f2SChris Cain             "xyz.openbmc_project.Control.Power.Mode",
2338ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
2339*6b9ac4f2SChris Cain                         const dbus::utility::DBusPropertiesMap& properties) {
2340*6b9ac4f2SChris Cain             afterGetPowerMode(asyncResp, ec2, properties);
23411e1e598dSJonathan Doman         });
2342e99073f5SGeorge Liu     });
23433a2d0424SChris Cain }
23443a2d0424SChris Cain 
23453a2d0424SChris Cain /**
23463a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
23473a2d0424SChris Cain  * name associated with that string
23483a2d0424SChris Cain  *
2349ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2350b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
23513a2d0424SChris Cain  *
23523a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
23533a2d0424SChris Cain  */
23543a2d0424SChris Cain inline std::string
2355ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2356b6655101SChris Cain                       const nlohmann::json& modeValue)
23573a2d0424SChris Cain {
2358b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
23593a2d0424SChris Cain     std::string mode;
23603a2d0424SChris Cain 
2361b6655101SChris Cain     if (modeValue == PowerMode::Static)
23623a2d0424SChris Cain     {
23633a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
23643a2d0424SChris Cain     }
2365b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
23663a2d0424SChris Cain     {
23670fda0f12SGeorge Liu         mode =
23680fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23693a2d0424SChris Cain     }
2370b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
23713a2d0424SChris Cain     {
23723a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23733a2d0424SChris Cain     }
2374b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2375b6655101SChris Cain     {
2376b6655101SChris Cain         mode =
2377b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2378b6655101SChris Cain     }
2379b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2380b6655101SChris Cain     {
2381b6655101SChris Cain         mode =
2382b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2383b6655101SChris Cain     }
2384b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2385b6655101SChris Cain     {
2386b6655101SChris Cain         mode =
2387b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2388b6655101SChris Cain     }
23893a2d0424SChris Cain     else
23903a2d0424SChris Cain     {
2391b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2392ac106bf6SEd Tanous                                          "PowerMode");
23933a2d0424SChris Cain     }
23943a2d0424SChris Cain     return mode;
23953a2d0424SChris Cain }
23963a2d0424SChris Cain 
23973a2d0424SChris Cain /**
23983a2d0424SChris Cain  * @brief Sets system power mode.
23993a2d0424SChris Cain  *
2400ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
24013a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
24023a2d0424SChris Cain  *
24033a2d0424SChris Cain  * @return None.
24043a2d0424SChris Cain  */
2405ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24063a2d0424SChris Cain                          const std::string& pmode)
24073a2d0424SChris Cain {
240862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
24093a2d0424SChris Cain 
2410ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
24113a2d0424SChris Cain     if (powerMode.empty())
24123a2d0424SChris Cain     {
24133a2d0424SChris Cain         return;
24143a2d0424SChris Cain     }
24153a2d0424SChris Cain 
24163a2d0424SChris Cain     // Get Power Mode object path:
2417e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2418e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2419e99073f5SGeorge Liu     dbus::utility::getSubTree(
2420e99073f5SGeorge Liu         "/", 0, interfaces,
2421ac106bf6SEd Tanous         [asyncResp,
2422e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2423b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
24243a2d0424SChris Cain         if (ec)
24253a2d0424SChris Cain         {
2426b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
242762598e31SEd Tanous                              ec);
24283a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2429ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24303a2d0424SChris Cain             return;
24313a2d0424SChris Cain         }
24323a2d0424SChris Cain         if (subtree.empty())
24333a2d0424SChris Cain         {
24343a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2435ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
24363a2d0424SChris Cain                                        "PowerMode");
24373a2d0424SChris Cain             return;
24383a2d0424SChris Cain         }
24393a2d0424SChris Cain         if (subtree.size() > 1)
24403a2d0424SChris Cain         {
24413a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
24423a2d0424SChris Cain             // error
244362598e31SEd Tanous             BMCWEB_LOG_DEBUG(
244462598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
244562598e31SEd Tanous                 subtree.size());
2446ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24473a2d0424SChris Cain             return;
24483a2d0424SChris Cain         }
24493a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
24503a2d0424SChris Cain         {
245162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2452ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24533a2d0424SChris Cain             return;
24543a2d0424SChris Cain         }
24553a2d0424SChris Cain         const std::string& path = subtree[0].first;
24563a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
24573a2d0424SChris Cain         if (service.empty())
24583a2d0424SChris Cain         {
245962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2460ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24613a2d0424SChris Cain             return;
24623a2d0424SChris Cain         }
24633a2d0424SChris Cain 
246462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
24653a2d0424SChris Cain 
24663a2d0424SChris Cain         // Set the Power Mode property
24679ae226faSGeorge Liu         sdbusplus::asio::setProperty(
24689ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
24699ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2470ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
24718a592810SEd Tanous             if (ec2)
24723a2d0424SChris Cain             {
2473b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2474ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24753a2d0424SChris Cain                 return;
24763a2d0424SChris Cain             }
24779ae226faSGeorge Liu         });
2478e99073f5SGeorge Liu     });
24793a2d0424SChris Cain }
24803a2d0424SChris Cain 
24813a2d0424SChris Cain /**
248251709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
248351709ffdSYong Li  *
248451709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
248551709ffdSYong Li  *
248651709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
248751709ffdSYong Li  * translation cannot be done, returns an empty string.
248851709ffdSYong Li  */
248923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
249051709ffdSYong Li {
249151709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
249251709ffdSYong Li     {
249351709ffdSYong Li         return "None";
249451709ffdSYong Li     }
24953174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
249651709ffdSYong Li     {
249751709ffdSYong Li         return "ResetSystem";
249851709ffdSYong Li     }
24993174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
250051709ffdSYong Li     {
250151709ffdSYong Li         return "PowerDown";
250251709ffdSYong Li     }
25033174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
250451709ffdSYong Li     {
250551709ffdSYong Li         return "PowerCycle";
250651709ffdSYong Li     }
250751709ffdSYong Li 
250851709ffdSYong Li     return "";
250951709ffdSYong Li }
251051709ffdSYong Li 
251151709ffdSYong Li /**
2512c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2513c45f0082SYong Li  *
2514c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2515c45f0082SYong Li  *
2516c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2517c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2518c45f0082SYong Li  */
2519c45f0082SYong Li 
252023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2521c45f0082SYong Li {
2522c45f0082SYong Li     if (rfAction == "None")
2523c45f0082SYong Li     {
2524c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2525c45f0082SYong Li     }
25263174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2527c45f0082SYong Li     {
2528c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2529c45f0082SYong Li     }
25303174e4dfSEd Tanous     if (rfAction == "PowerDown")
2531c45f0082SYong Li     {
2532c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2533c45f0082SYong Li     }
25343174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2535c45f0082SYong Li     {
2536c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2537c45f0082SYong Li     }
2538c45f0082SYong Li 
2539c45f0082SYong Li     return "";
2540c45f0082SYong Li }
2541c45f0082SYong Li 
2542c45f0082SYong Li /**
254351709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
254451709ffdSYong Li  *
2545ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
254651709ffdSYong Li  *
254751709ffdSYong Li  * @return None.
254851709ffdSYong Li  */
25498d1b46d7Szhanghch05 inline void
2550ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
255151709ffdSYong Li {
255262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2553bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2554bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2555bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2556bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2557ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2558b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
255951709ffdSYong Li         if (ec)
256051709ffdSYong Li         {
256151709ffdSYong Li             // watchdog service is stopped
256262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
256351709ffdSYong Li             return;
256451709ffdSYong Li         }
256551709ffdSYong Li 
256662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
256751709ffdSYong Li 
256851709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2569ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
257051709ffdSYong Li 
257151709ffdSYong Li         // watchdog service is running/enabled
257251709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
257351709ffdSYong Li 
2574bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2575bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
257651709ffdSYong Li 
2577bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2578bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2579bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2580bc1d29deSKrzysztof Grobelny 
2581bc1d29deSKrzysztof Grobelny         if (!success)
258251709ffdSYong Li         {
2583ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2584601af5edSChicago Duan             return;
258551709ffdSYong Li         }
258651709ffdSYong Li 
2587bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
258851709ffdSYong Li         {
2589bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
259051709ffdSYong Li         }
259151709ffdSYong Li 
2592bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2593bc1d29deSKrzysztof Grobelny         {
2594bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
259551709ffdSYong Li             if (action.empty())
259651709ffdSYong Li             {
2597ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2598601af5edSChicago Duan                 return;
259951709ffdSYong Li             }
260051709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
260151709ffdSYong Li         }
2602bc1d29deSKrzysztof Grobelny     });
260351709ffdSYong Li }
260451709ffdSYong Li 
260551709ffdSYong Li /**
2606c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2607c45f0082SYong Li  *
2608ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2609c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2610c45f0082SYong Li  *                       RF request.
2611c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2612c45f0082SYong Li  *
2613c45f0082SYong Li  * @return None.
2614c45f0082SYong Li  */
2615ac106bf6SEd Tanous inline void
2616ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2617c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2618c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2619c45f0082SYong Li {
262062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2621c45f0082SYong Li 
2622c45f0082SYong Li     if (wdtTimeOutAction)
2623c45f0082SYong Li     {
2624c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2625c45f0082SYong Li         // check if TimeOut Action is Valid
2626c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2627c45f0082SYong Li         {
262862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
262962598e31SEd Tanous                              *wdtTimeOutAction);
2630ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2631c45f0082SYong Li                                              "TimeoutAction");
2632c45f0082SYong Li             return;
2633c45f0082SYong Li         }
2634c45f0082SYong Li 
26359ae226faSGeorge Liu         sdbusplus::asio::setProperty(
26369ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26379ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26389ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
26399ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2640c45f0082SYong Li             if (ec)
2641c45f0082SYong Li             {
2642b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2643ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2644c45f0082SYong Li                 return;
2645c45f0082SYong Li             }
26469ae226faSGeorge Liu         });
2647c45f0082SYong Li     }
2648c45f0082SYong Li 
2649c45f0082SYong Li     if (wdtEnable)
2650c45f0082SYong Li     {
26519ae226faSGeorge Liu         sdbusplus::asio::setProperty(
26529ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26539ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26549ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2655ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2656c45f0082SYong Li             if (ec)
2657c45f0082SYong Li             {
2658b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2659ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2660c45f0082SYong Li                 return;
2661c45f0082SYong Li             }
26629ae226faSGeorge Liu         });
2663c45f0082SYong Li     }
2664c45f0082SYong Li }
2665c45f0082SYong Li 
266637bbf98cSChris Cain /**
266737bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
266837bbf98cSChris Cain  *
2669ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
267037bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
267137bbf98cSChris Cain  *
267237bbf98cSChris Cain  * @return true if successful
267337bbf98cSChris Cain  */
26741e5b7c88SJiaqing Zhao inline bool
2675ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26761e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
267737bbf98cSChris Cain {
2678bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2679bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2680bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2681bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2682bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2683bc1d29deSKrzysztof Grobelny 
2684bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2685bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26862661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26872661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26882661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2689bc1d29deSKrzysztof Grobelny 
2690bc1d29deSKrzysztof Grobelny     if (!success)
269137bbf98cSChris Cain     {
269237bbf98cSChris Cain         return false;
269337bbf98cSChris Cain     }
2694bc1d29deSKrzysztof Grobelny 
2695bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
269637bbf98cSChris Cain     {
2697ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
269837bbf98cSChris Cain     }
2699bc1d29deSKrzysztof Grobelny 
2700bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
270137bbf98cSChris Cain     {
2702ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2703bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
270437bbf98cSChris Cain     }
2705bc1d29deSKrzysztof Grobelny 
2706bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2707bc1d29deSKrzysztof Grobelny     {
2708bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2709ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
271037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
271137bbf98cSChris Cain                 .count();
271237bbf98cSChris Cain     }
2713bc1d29deSKrzysztof Grobelny 
2714bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
271537bbf98cSChris Cain     {
2716ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2717bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
271837bbf98cSChris Cain     }
2719bc1d29deSKrzysztof Grobelny 
2720bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
272137bbf98cSChris Cain     {
2722bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2723ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
272437bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
272537bbf98cSChris Cain                 .count();
272637bbf98cSChris Cain     }
272737bbf98cSChris Cain 
272837bbf98cSChris Cain     return true;
272937bbf98cSChris Cain }
273037bbf98cSChris Cain 
273137bbf98cSChris Cain /**
273237bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
273337bbf98cSChris Cain  *
2734ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
273537bbf98cSChris Cain  *
273637bbf98cSChris Cain  * @return None.
273737bbf98cSChris Cain  */
2738ac106bf6SEd Tanous inline void
2739ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
274037bbf98cSChris Cain {
274162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
274237bbf98cSChris Cain 
274337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2744e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2745e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2746e99073f5SGeorge Liu     dbus::utility::getSubTree(
2747e99073f5SGeorge Liu         "/", 0, interfaces,
2748ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2749b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
275037bbf98cSChris Cain         if (ec)
275137bbf98cSChris Cain         {
2752b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
275362598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
275462598e31SEd Tanous                 ec);
2755ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
275637bbf98cSChris Cain             return;
275737bbf98cSChris Cain         }
275837bbf98cSChris Cain         if (subtree.empty())
275937bbf98cSChris Cain         {
276037bbf98cSChris Cain             // This is an optional interface so just return
276137bbf98cSChris Cain             // if there is no instance found
276262598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
276337bbf98cSChris Cain             return;
276437bbf98cSChris Cain         }
276537bbf98cSChris Cain         if (subtree.size() > 1)
276637bbf98cSChris Cain         {
276737bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
276837bbf98cSChris Cain             // is an error
276962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
277062598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
277162598e31SEd Tanous                              subtree.size());
2772ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277337bbf98cSChris Cain             return;
277437bbf98cSChris Cain         }
277537bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
277637bbf98cSChris Cain         {
277762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2778ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277937bbf98cSChris Cain             return;
278037bbf98cSChris Cain         }
278137bbf98cSChris Cain         const std::string& path = subtree[0].first;
278237bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
278337bbf98cSChris Cain         if (service.empty())
278437bbf98cSChris Cain         {
278562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2786ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
278737bbf98cSChris Cain             return;
278837bbf98cSChris Cain         }
278937bbf98cSChris Cain 
279037bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2791bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2792bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2793bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2794ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27951e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27968a592810SEd Tanous             if (ec2)
279737bbf98cSChris Cain             {
279862598e31SEd Tanous                 BMCWEB_LOG_ERROR(
279962598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2800ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
280137bbf98cSChris Cain                 return;
280237bbf98cSChris Cain             }
280337bbf98cSChris Cain 
2804ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
280537bbf98cSChris Cain             {
2806ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
280737bbf98cSChris Cain                 return;
280837bbf98cSChris Cain             }
2809bc1d29deSKrzysztof Grobelny         });
2810e99073f5SGeorge Liu     });
281137bbf98cSChris Cain 
281262598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
281337bbf98cSChris Cain }
281437bbf98cSChris Cain 
281537bbf98cSChris Cain /**
281637bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
281737bbf98cSChris Cain  *
2818ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
281937bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
282037bbf98cSChris Cain  *                       RF request.
282137bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
282237bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
282337bbf98cSChris Cain  * before entering idle state.
282437bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
282537bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
282637bbf98cSChris Cain  * before exiting idle state
282737bbf98cSChris Cain  *
282837bbf98cSChris Cain  * @return None.
282937bbf98cSChris Cain  */
2830ac106bf6SEd Tanous inline void
2831ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
283237bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
283337bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
283437bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
283537bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
283637bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
283737bbf98cSChris Cain {
283862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
283937bbf98cSChris Cain 
284037bbf98cSChris Cain     // Get IdlePowerSaver object path:
2841e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2842e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2843e99073f5SGeorge Liu     dbus::utility::getSubTree(
2844e99073f5SGeorge Liu         "/", 0, interfaces,
2845ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2846e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2847b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
284837bbf98cSChris Cain         if (ec)
284937bbf98cSChris Cain         {
2850b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
285162598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
285262598e31SEd Tanous                 ec);
2853ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
285437bbf98cSChris Cain             return;
285537bbf98cSChris Cain         }
285637bbf98cSChris Cain         if (subtree.empty())
285737bbf98cSChris Cain         {
285837bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2859ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
286037bbf98cSChris Cain                                        "IdlePowerSaver");
286137bbf98cSChris Cain             return;
286237bbf98cSChris Cain         }
286337bbf98cSChris Cain         if (subtree.size() > 1)
286437bbf98cSChris Cain         {
286537bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
286637bbf98cSChris Cain             // is an error
286762598e31SEd Tanous             BMCWEB_LOG_DEBUG(
286862598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
286962598e31SEd Tanous                 subtree.size());
2870ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
287137bbf98cSChris Cain             return;
287237bbf98cSChris Cain         }
287337bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
287437bbf98cSChris Cain         {
287562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2876ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
287737bbf98cSChris Cain             return;
287837bbf98cSChris Cain         }
287937bbf98cSChris Cain         const std::string& path = subtree[0].first;
288037bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
288137bbf98cSChris Cain         if (service.empty())
288237bbf98cSChris Cain         {
288362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2884ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
288537bbf98cSChris Cain             return;
288637bbf98cSChris Cain         }
288737bbf98cSChris Cain 
288837bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
288937bbf98cSChris Cain         // need to be updated
289037bbf98cSChris Cain 
289137bbf98cSChris Cain         if (ipsEnable)
289237bbf98cSChris Cain         {
28939ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28949ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28959ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28969ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28978a592810SEd Tanous                 if (ec2)
289837bbf98cSChris Cain                 {
2899b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2900ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
290137bbf98cSChris Cain                     return;
290237bbf98cSChris Cain                 }
29039ae226faSGeorge Liu             });
290437bbf98cSChris Cain         }
290537bbf98cSChris Cain         if (ipsEnterUtil)
290637bbf98cSChris Cain         {
29079ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29089ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29099ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29109ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2911ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29128a592810SEd Tanous                 if (ec2)
291337bbf98cSChris Cain                 {
2914b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2915ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
291637bbf98cSChris Cain                     return;
291737bbf98cSChris Cain                 }
29189ae226faSGeorge Liu             });
291937bbf98cSChris Cain         }
292037bbf98cSChris Cain         if (ipsEnterTime)
292137bbf98cSChris Cain         {
292237bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
292337bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
29249ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29259ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29269ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29279ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2928ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29298a592810SEd Tanous                 if (ec2)
293037bbf98cSChris Cain                 {
2931b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2932ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
293337bbf98cSChris Cain                     return;
293437bbf98cSChris Cain                 }
29359ae226faSGeorge Liu             });
293637bbf98cSChris Cain         }
293737bbf98cSChris Cain         if (ipsExitUtil)
293837bbf98cSChris Cain         {
29399ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29409ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29419ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29429ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2943ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29448a592810SEd Tanous                 if (ec2)
294537bbf98cSChris Cain                 {
2946b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2947ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
294837bbf98cSChris Cain                     return;
294937bbf98cSChris Cain                 }
29509ae226faSGeorge Liu             });
295137bbf98cSChris Cain         }
295237bbf98cSChris Cain         if (ipsExitTime)
295337bbf98cSChris Cain         {
295437bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
295537bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
29569ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29579ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29589ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29599ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2960ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29618a592810SEd Tanous                 if (ec2)
296237bbf98cSChris Cain                 {
2963b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2964ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
296537bbf98cSChris Cain                     return;
296637bbf98cSChris Cain                 }
29679ae226faSGeorge Liu             });
296837bbf98cSChris Cain         }
2969e99073f5SGeorge Liu     });
297037bbf98cSChris Cain 
297162598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
297237bbf98cSChris Cain }
297337bbf98cSChris Cain 
2974c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2975dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2976dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2977dd60b9edSEd Tanous {
2978dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2979dd60b9edSEd Tanous     {
2980dd60b9edSEd Tanous         return;
2981dd60b9edSEd Tanous     }
2982dd60b9edSEd Tanous     asyncResp->res.addHeader(
2983dd60b9edSEd Tanous         boost::beast::http::field::link,
2984dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2985dd60b9edSEd Tanous }
2986dd60b9edSEd Tanous 
2987c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2988c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2989c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29901abe55efSEd Tanous {
29913ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2992f4c99e70SEd Tanous     {
2993f4c99e70SEd Tanous         return;
2994f4c99e70SEd Tanous     }
2995dd60b9edSEd Tanous 
2996dd60b9edSEd Tanous     asyncResp->res.addHeader(
2997dd60b9edSEd Tanous         boost::beast::http::field::link,
2998dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29998d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
30000f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
30018d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
30028d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
3003462023adSSunitha Harish 
30047f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
30057f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
30067f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30077f3e84a1SEd Tanous     {
30087f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
30097f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30107f3e84a1SEd Tanous         return;
30117f3e84a1SEd Tanous     }
30127f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
30137f3e84a1SEd Tanous     nlohmann::json::object_t system;
30147f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
30157f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
30161e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
3017002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
30181e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
3019002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
30205e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
30211e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
30227f3e84a1SEd Tanous         if (ec2)
3023462023adSSunitha Harish         {
30247f3e84a1SEd Tanous             return;
30257f3e84a1SEd Tanous         }
30267f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
30277f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
30287f3e84a1SEd Tanous         {
302962598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
30307f3e84a1SEd Tanous             return;
30317f3e84a1SEd Tanous         }
30327f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
30337f3e84a1SEd Tanous         if (count == nullptr)
30347f3e84a1SEd Tanous         {
303562598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
30367f3e84a1SEd Tanous             return;
30377f3e84a1SEd Tanous         }
30387f3e84a1SEd Tanous         *count = *count + 1;
303962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
30407f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
30411476687dSEd Tanous         nlohmann::json::object_t hypervisor;
3042002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
30437f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
30441e1e598dSJonathan Doman     });
3045c1e219d5SEd Tanous }
3046c1e219d5SEd Tanous 
3047c1e219d5SEd Tanous /**
30487e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
30497e860f15SJohn Edward Broadbent  */
30504f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
30517e860f15SJohn Edward Broadbent {
305289492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
305389492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
305489492a15SPatrick Williams     constexpr const char* interfaceName =
30557e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
305689492a15SPatrick Williams     constexpr const char* method = "NMI";
30577e860f15SJohn Edward Broadbent 
30587e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
30595e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
30607e860f15SJohn Edward Broadbent         if (ec)
30617e860f15SJohn Edward Broadbent         {
306262598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
30637e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
30647e860f15SJohn Edward Broadbent             return;
30657e860f15SJohn Edward Broadbent         }
30667e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
30677e860f15SJohn Edward Broadbent     },
30687e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
30697e860f15SJohn Edward Broadbent }
3070c5b2abe0SLewanczyk, Dawid 
3071c5b2abe0SLewanczyk, Dawid /**
3072fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
3073fc903b3dSAndrew Geissler  */
3074fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
3075fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
3076fc903b3dSAndrew Geissler                                          std::string_view resetType,
3077fc903b3dSAndrew Geissler                                          crow::Response& res)
3078fc903b3dSAndrew Geissler {
3079fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
3080fc903b3dSAndrew Geissler     {
3081fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
3082fc903b3dSAndrew Geissler         return;
3083fc903b3dSAndrew Geissler     }
3084fc903b3dSAndrew Geissler 
3085fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3086fc903b3dSAndrew Geissler     {
308762598e31SEd Tanous         BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
3088fc903b3dSAndrew Geissler         messages::internalError(res);
3089fc903b3dSAndrew Geissler         return;
3090fc903b3dSAndrew Geissler     }
3091fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3092fc903b3dSAndrew Geissler 
3093fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3094fc903b3dSAndrew Geissler     // user to retry in a bit
3095fc903b3dSAndrew Geissler     if ((errorMessage ==
3096fc903b3dSAndrew Geissler          std::string_view(
3097fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3098fc903b3dSAndrew Geissler         (errorMessage ==
3099fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3100fc903b3dSAndrew Geissler     {
310162598e31SEd Tanous         BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
3102fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3103fc903b3dSAndrew Geissler         return;
3104fc903b3dSAndrew Geissler     }
3105fc903b3dSAndrew Geissler 
310662598e31SEd Tanous     BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
310762598e31SEd Tanous                      errorMessage);
3108fc903b3dSAndrew Geissler     messages::internalError(res);
3109fc903b3dSAndrew Geissler }
3110fc903b3dSAndrew Geissler 
3111c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3112c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
31137f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3114c1e219d5SEd Tanous     const std::string& systemName)
3115c1e219d5SEd Tanous {
31163ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
311745ca1b86SEd Tanous     {
311845ca1b86SEd Tanous         return;
311945ca1b86SEd Tanous     }
3120c1e219d5SEd Tanous     if (systemName != "system")
3121c1e219d5SEd Tanous     {
3122c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3123c1e219d5SEd Tanous                                    systemName);
3124c1e219d5SEd Tanous         return;
3125c1e219d5SEd Tanous     }
31267f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
31277f3e84a1SEd Tanous     {
31287f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31297f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3130c1e219d5SEd Tanous                                    systemName);
31317f3e84a1SEd Tanous         return;
31327f3e84a1SEd Tanous     }
31339712f8acSEd Tanous     std::string resetType;
3134c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3135cc340dd9SEd Tanous     {
3136cc340dd9SEd Tanous         return;
3137cc340dd9SEd Tanous     }
3138cc340dd9SEd Tanous 
3139d22c8396SJason M. Bills     // Get the command and host vs. chassis
3140cc340dd9SEd Tanous     std::string command;
3141543f4400SEd Tanous     bool hostCommand = true;
3142d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3143cc340dd9SEd Tanous     {
3144cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3145d22c8396SJason M. Bills         hostCommand = true;
3146d22c8396SJason M. Bills     }
3147d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3148d22c8396SJason M. Bills     {
3149d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3150d22c8396SJason M. Bills         hostCommand = false;
3151d22c8396SJason M. Bills     }
3152d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3153d22c8396SJason M. Bills     {
3154c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
315586a0851aSJason M. Bills         hostCommand = true;
3156cc340dd9SEd Tanous     }
31579712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3158cc340dd9SEd Tanous     {
3159cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3160d22c8396SJason M. Bills         hostCommand = true;
3161cc340dd9SEd Tanous     }
31629712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3163cc340dd9SEd Tanous     {
31640fda0f12SGeorge Liu         command =
31650fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3166d22c8396SJason M. Bills         hostCommand = true;
3167d22c8396SJason M. Bills     }
3168d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3169d22c8396SJason M. Bills     {
317086a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
317186a0851aSJason M. Bills         hostCommand = true;
3172cc340dd9SEd Tanous     }
3173bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3174bfd5b826SLakshminarayana R. Kammath     {
3175bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3176bfd5b826SLakshminarayana R. Kammath         return;
3177bfd5b826SLakshminarayana R. Kammath     }
3178cc340dd9SEd Tanous     else
3179cc340dd9SEd Tanous     {
3180c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3181cc340dd9SEd Tanous         return;
3182cc340dd9SEd Tanous     }
3183cc340dd9SEd Tanous 
3184d22c8396SJason M. Bills     if (hostCommand)
3185d22c8396SJason M. Bills     {
31869ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31879ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31889ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31899ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31909ae226faSGeorge Liu             command,
3191fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3192fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3193cc340dd9SEd Tanous             if (ec)
3194cc340dd9SEd Tanous             {
3195fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3196fc903b3dSAndrew Geissler                                              asyncResp->res);
3197fc903b3dSAndrew Geissler 
3198cc340dd9SEd Tanous                 return;
3199cc340dd9SEd Tanous             }
3200f12894f8SJason M. Bills             messages::success(asyncResp->res);
32019ae226faSGeorge Liu         });
3202cc340dd9SEd Tanous     }
3203d22c8396SJason M. Bills     else
3204d22c8396SJason M. Bills     {
32059ae226faSGeorge Liu         sdbusplus::asio::setProperty(
32069ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
32079ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
32089ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
32099ae226faSGeorge Liu             command,
3210fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3211fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3212d22c8396SJason M. Bills             if (ec)
3213d22c8396SJason M. Bills             {
3214fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3215fc903b3dSAndrew Geissler                                              asyncResp->res);
3216d22c8396SJason M. Bills                 return;
3217d22c8396SJason M. Bills             }
3218d22c8396SJason M. Bills             messages::success(asyncResp->res);
32199ae226faSGeorge Liu         });
3220d22c8396SJason M. Bills     }
3221d22c8396SJason M. Bills }
3222cc340dd9SEd Tanous 
3223c1e219d5SEd Tanous inline void handleComputerSystemHead(
3224dd60b9edSEd Tanous     App& app, const crow::Request& req,
32257f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32267f3e84a1SEd Tanous     const std::string& /*systemName*/)
3227dd60b9edSEd Tanous {
3228dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3229dd60b9edSEd Tanous     {
3230dd60b9edSEd Tanous         return;
3231dd60b9edSEd Tanous     }
3232dd60b9edSEd Tanous 
3233dd60b9edSEd Tanous     asyncResp->res.addHeader(
3234dd60b9edSEd Tanous         boost::beast::http::field::link,
3235dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3236dd60b9edSEd Tanous }
3237dd60b9edSEd Tanous 
32385c3e9272SAbhishek Patel inline void afterPortRequest(
32395c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32405c3e9272SAbhishek Patel     const boost::system::error_code& ec,
32415c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
32425c3e9272SAbhishek Patel {
32435c3e9272SAbhishek Patel     if (ec)
32445c3e9272SAbhishek Patel     {
3245b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
32465c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
32475c3e9272SAbhishek Patel         return;
32485c3e9272SAbhishek Patel     }
32495c3e9272SAbhishek Patel     for (const auto& data : socketData)
32505c3e9272SAbhishek Patel     {
32515c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
32525c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
32535c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
32545c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
32555c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
32565c3e9272SAbhishek Patel         // need to retrieve port number for
32575c3e9272SAbhishek Patel         // obmc-console-ssh service
32585c3e9272SAbhishek Patel         if (protocolName == "SSH")
32595c3e9272SAbhishek Patel         {
32605c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
326181c4e330SEd Tanous                                           const boost::system::error_code& ec1,
32625c3e9272SAbhishek Patel                                           int portNumber) {
32635c3e9272SAbhishek Patel                 if (ec1)
32645c3e9272SAbhishek Patel                 {
3265b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
32665c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
32675c3e9272SAbhishek Patel                     return;
32685c3e9272SAbhishek Patel                 }
32695c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
32705c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
32715c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
32725c3e9272SAbhishek Patel             });
32735c3e9272SAbhishek Patel         }
32745c3e9272SAbhishek Patel     }
32755c3e9272SAbhishek Patel }
3276c1e219d5SEd Tanous 
3277c1e219d5SEd Tanous inline void
3278c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
327922d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3280c1e219d5SEd Tanous                             const std::string& systemName)
3281c1e219d5SEd Tanous {
32823ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
328345ca1b86SEd Tanous     {
328445ca1b86SEd Tanous         return;
328545ca1b86SEd Tanous     }
3286746b56f3SAsmitha Karunanithi 
32877f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32887f3e84a1SEd Tanous     {
32897f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32907f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32917f3e84a1SEd Tanous                                    systemName);
32927f3e84a1SEd Tanous         return;
32937f3e84a1SEd Tanous     }
32947f3e84a1SEd Tanous 
3295746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3296746b56f3SAsmitha Karunanithi     {
3297746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3298746b56f3SAsmitha Karunanithi         return;
3299746b56f3SAsmitha Karunanithi     }
3300746b56f3SAsmitha Karunanithi 
330122d268cbSEd Tanous     if (systemName != "system")
330222d268cbSEd Tanous     {
330322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
330422d268cbSEd Tanous                                    systemName);
330522d268cbSEd Tanous         return;
330622d268cbSEd Tanous     }
3307dd60b9edSEd Tanous     asyncResp->res.addHeader(
3308dd60b9edSEd Tanous         boost::beast::http::field::link,
3309dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
33108d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3311b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
33128d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
33138d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
33148d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
33158d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
33168d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
33175fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
33185fd0aafbSNinad Palsule     {
33198d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
33208d1b46d7Szhanghch05             "Disabled";
33218d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
33228d1b46d7Szhanghch05             "Disabled";
33235fd0aafbSNinad Palsule     }
3324cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3325dfb2b408SPriyanga Ramasamy         double(0);
3326002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
332704a258f4SEd Tanous 
33281476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
33291476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
33301476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
33311476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
33321476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
33331476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
33343179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
33353179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3336029573d4SEd Tanous 
3337002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
33381476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3339c1e219d5SEd Tanous     asyncResp->res
3340c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
33411476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3342c5b2abe0SLewanczyk, Dawid 
33431476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
33441476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
33451476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
33461476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3347c4bf6374SJason M. Bills 
33481476687dSEd Tanous     nlohmann::json::array_t managedBy;
33491476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
33501476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3351002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
33521476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
33531476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
33540e8ac5e7SGunnar Mills 
33550e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3356002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3357c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
33581476687dSEd Tanous 
3359c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
33601476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3361c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
33621476687dSEd Tanous         "Press ~. to exit console";
33635c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
33645c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
33650e8ac5e7SGunnar Mills 
33660e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
33670e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3368002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3369c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3370613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3371613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
33721476687dSEd Tanous 
33730e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
337413451e39SWilly Tu 
337513451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
337613451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
337713451e39SWilly Tu     {
33787a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3379b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
33802ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3381e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3382e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3383b49ac873SJames Feist 
33847a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
33857a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33867a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3387914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3388b49ac873SJames Feist             if (ec)
3389b49ac873SJames Feist             {
3390b49ac873SJames Feist                 // no inventory
3391b49ac873SJames Feist                 return;
3392b49ac873SJames Feist             }
3393b49ac873SJames Feist 
3394914e2d5dSEd Tanous             health->inventory = resp;
33957a1dbc48SGeorge Liu         });
3396b49ac873SJames Feist         health->populate();
339713451e39SWilly Tu     }
3398b49ac873SJames Feist 
3399002d39b4SEd Tanous     getMainChassisId(asyncResp,
3400002d39b4SEd Tanous                      [](const std::string& chassisId,
34018d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3402b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3403b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3404ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3405ef4c65b7SEd Tanous                                                    chassisId);
3406002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3407c5d03ff4SJennifer Lee     });
3408a3002228SAppaRao Puli 
340959a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
34109f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3411a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
34125bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
34136c34de48SEd Tanous     getHostState(asyncResp);
3414491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3415978b8803SAndrew Geissler     getBootProgress(asyncResp);
3416b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
341770c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
341870c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
341951709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3420c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
34219dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3422797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3423c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3424a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3425a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3426a6349918SAppaRao Puli #endif
34271981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
34283a2d0424SChris Cain     getPowerMode(asyncResp);
342937bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3430c1e219d5SEd Tanous }
3431550a6bf8SJiaqing Zhao 
3432c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3433c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
343422d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3435c1e219d5SEd Tanous     const std::string& systemName)
3436c1e219d5SEd Tanous {
34373ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
343845ca1b86SEd Tanous     {
343945ca1b86SEd Tanous         return;
344045ca1b86SEd Tanous     }
34417f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
34427f3e84a1SEd Tanous     {
34437f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34447f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34457f3e84a1SEd Tanous                                    systemName);
34467f3e84a1SEd Tanous         return;
34477f3e84a1SEd Tanous     }
344822d268cbSEd Tanous     if (systemName != "system")
344922d268cbSEd Tanous     {
345022d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
345122d268cbSEd Tanous                                    systemName);
345222d268cbSEd Tanous         return;
345322d268cbSEd Tanous     }
345422d268cbSEd Tanous 
3455dd60b9edSEd Tanous     asyncResp->res.addHeader(
3456dd60b9edSEd Tanous         boost::beast::http::field::link,
3457dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3458dd60b9edSEd Tanous 
34599f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3460cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
346198e386ecSGunnar Mills     std::optional<std::string> assetTag;
3462c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
34633a2d0424SChris Cain     std::optional<std::string> powerMode;
3464550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3465550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3466550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3467550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3468550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3469550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3470797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3471550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
34729dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3473550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3474550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3475550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3476550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3477550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3478550a6bf8SJiaqing Zhao 
3479550a6bf8SJiaqing Zhao     // clang-format off
348015ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3481550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3482550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
34837e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3484550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3485550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3486550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3487550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3488550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3489550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3490550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3491550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3492550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3493797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3494550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
34959dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3496550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3497550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3498550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3499550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3500550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
35016617338dSEd Tanous                 {
35026617338dSEd Tanous                     return;
35036617338dSEd Tanous                 }
3504550a6bf8SJiaqing Zhao     // clang-format on
3505491d8ee7SSantosh Puranik 
35068d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3507c45f0082SYong Li 
350898e386ecSGunnar Mills     if (assetTag)
350998e386ecSGunnar Mills     {
351098e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
351198e386ecSGunnar Mills     }
351298e386ecSGunnar Mills 
3513550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3514c45f0082SYong Li     {
3515f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3516c45f0082SYong Li     }
3517c45f0082SYong Li 
3518cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
351969f35306SGunnar Mills     {
3520002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3521491d8ee7SSantosh Puranik     }
3522550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
352369f35306SGunnar Mills     {
3524550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
352569f35306SGunnar Mills     }
3526ac7e1e0bSAli Ahmed 
3527797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3528797d5daeSCorey Hardesty     {
3529797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3530797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3531797d5daeSCorey Hardesty     }
3532797d5daeSCorey Hardesty 
3533550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3534ac7e1e0bSAli Ahmed     {
3535c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
353669f35306SGunnar Mills     }
3537265c1602SJohnathan Mantey 
35389dcfe8c1SAlbert Zhang     if (stopBootOnFault)
35399dcfe8c1SAlbert Zhang     {
35409dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
35419dcfe8c1SAlbert Zhang     }
35429dcfe8c1SAlbert Zhang 
35439f8bfa7cSGunnar Mills     if (locationIndicatorActive)
35449f8bfa7cSGunnar Mills     {
354559a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
35469f8bfa7cSGunnar Mills     }
35479f8bfa7cSGunnar Mills 
35487e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
35497e860f15SJohn Edward Broadbent     // passed
35509712f8acSEd Tanous     if (indicatorLed)
35516617338dSEd Tanous     {
3552f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3553002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3554d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3555d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
35566617338dSEd Tanous     }
3557c6a620f2SGeorge Liu 
3558c6a620f2SGeorge Liu     if (powerRestorePolicy)
3559c6a620f2SGeorge Liu     {
35604e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3561c6a620f2SGeorge Liu     }
35623a2d0424SChris Cain 
35633a2d0424SChris Cain     if (powerMode)
35643a2d0424SChris Cain     {
35653a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
35663a2d0424SChris Cain     }
356737bbf98cSChris Cain 
3568c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
356937bbf98cSChris Cain     {
3570002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3571002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
357237bbf98cSChris Cain     }
3573c1e219d5SEd Tanous }
35741cb1a9e6SAppaRao Puli 
357538c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3576dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
35777f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3578c1e219d5SEd Tanous     const std::string& /*systemName*/)
3579dd60b9edSEd Tanous {
3580dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3581dd60b9edSEd Tanous     {
3582dd60b9edSEd Tanous         return;
3583dd60b9edSEd Tanous     }
3584dd60b9edSEd Tanous     asyncResp->res.addHeader(
3585dd60b9edSEd Tanous         boost::beast::http::field::link,
3586dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3587dd60b9edSEd Tanous }
3588c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3589c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
359022d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3591c1e219d5SEd Tanous     const std::string& systemName)
3592c1e219d5SEd Tanous {
35933ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
359445ca1b86SEd Tanous     {
359545ca1b86SEd Tanous         return;
359645ca1b86SEd Tanous     }
35977f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35987f3e84a1SEd Tanous     {
35997f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
36007f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
36017f3e84a1SEd Tanous                                    systemName);
36027f3e84a1SEd Tanous         return;
36037f3e84a1SEd Tanous     }
3604746b56f3SAsmitha Karunanithi 
3605746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3606746b56f3SAsmitha Karunanithi     {
3607746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3608746b56f3SAsmitha Karunanithi         return;
3609746b56f3SAsmitha Karunanithi     }
3610746b56f3SAsmitha Karunanithi 
361122d268cbSEd Tanous     if (systemName != "system")
361222d268cbSEd Tanous     {
361322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
361422d268cbSEd Tanous                                    systemName);
361522d268cbSEd Tanous         return;
361622d268cbSEd Tanous     }
361722d268cbSEd Tanous 
3618dd60b9edSEd Tanous     asyncResp->res.addHeader(
3619dd60b9edSEd Tanous         boost::beast::http::field::link,
3620dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
36211476687dSEd Tanous 
36221476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
36231476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3624c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
36251476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
36261476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
36273215e700SNan Zhou 
36283215e700SNan Zhou     nlohmann::json::array_t parameters;
36293215e700SNan Zhou     nlohmann::json::object_t parameter;
36303215e700SNan Zhou 
36313215e700SNan Zhou     parameter["Name"] = "ResetType";
36323215e700SNan Zhou     parameter["Required"] = true;
36333215e700SNan Zhou     parameter["DataType"] = "String";
36343215e700SNan Zhou     nlohmann::json::array_t allowableValues;
36353215e700SNan Zhou     allowableValues.emplace_back("On");
36363215e700SNan Zhou     allowableValues.emplace_back("ForceOff");
36373215e700SNan Zhou     allowableValues.emplace_back("ForceOn");
36383215e700SNan Zhou     allowableValues.emplace_back("ForceRestart");
36393215e700SNan Zhou     allowableValues.emplace_back("GracefulRestart");
36403215e700SNan Zhou     allowableValues.emplace_back("GracefulShutdown");
36413215e700SNan Zhou     allowableValues.emplace_back("PowerCycle");
36423215e700SNan Zhou     allowableValues.emplace_back("Nmi");
36433215e700SNan Zhou     parameter["AllowableValues"] = std::move(allowableValues);
36443215e700SNan Zhou     parameters.emplace_back(std::move(parameter));
36453215e700SNan Zhou 
36463215e700SNan Zhou     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3647c1e219d5SEd Tanous }
3648c1e219d5SEd Tanous /**
3649c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3650c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3651c1e219d5SEd Tanous  */
3652100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3653c1e219d5SEd Tanous {
3654100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3655100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3656100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3657100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3658100afe56SEd Tanous 
3659100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3660100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3661100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3662100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3663100afe56SEd Tanous 
3664100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3665100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3666100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3667100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3668100afe56SEd Tanous 
3669100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3670100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3671100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3672100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3673100afe56SEd Tanous 
3674100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3675100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3676100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3677100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3678100afe56SEd Tanous 
3679100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3680100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3681100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3682100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3683100afe56SEd Tanous 
3684c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3685c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3686c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3687c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3688c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3689c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3690c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3691c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36921cb1a9e6SAppaRao Puli }
3693c5b2abe0SLewanczyk, Dawid } // namespace redfish
3694