xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision e715d14b258a764f0e41559fe4a5e9f7d2efe314)
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"
2433e1f122SAndrew Geissler #include "generated/enums/resource.hpp"
25b49ac873SJames Feist #include "health.hpp"
26746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
271c8fba97SJames Feist #include "led.hpp"
28f4c99e70SEd Tanous #include "query.hpp"
29c5d03ff4SJennifer Lee #include "redfish_util.hpp"
303ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
313ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
323ccb3adbSEd Tanous #include "utils/json_utils.hpp"
33472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
343ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
352b82937eSEd Tanous #include "utils/time_utils.hpp"
36c5d03ff4SJennifer Lee 
37fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
389712f8acSEd Tanous #include <boost/container/flat_map.hpp>
39e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
4033e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
41ef4c65b7SEd Tanous #include <boost/url/format.hpp>
42b6655101SChris Cain #include <generated/enums/computer_system.hpp>
431e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
44fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
45bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
461214b7e7SGunnar Mills 
477a1dbc48SGeorge Liu #include <array>
4833e1f122SAndrew Geissler #include <memory>
496b9ac4f2SChris Cain #include <string>
507a1dbc48SGeorge Liu #include <string_view>
51abf2add6SEd Tanous #include <variant>
526b9ac4f2SChris Cain #include <vector>
53c5b2abe0SLewanczyk, Dawid 
541abe55efSEd Tanous namespace redfish
551abe55efSEd Tanous {
56c5b2abe0SLewanczyk, Dawid 
575c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
585c3e9272SAbhishek Patel     protocolToDBusForSystems{
595c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
605c3e9272SAbhishek Patel 
619d3ae10eSAlpana Kumari /**
629d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
639d3ae10eSAlpana Kumari  *
64ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
659d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
669d3ae10eSAlpana Kumari  *
679d3ae10eSAlpana Kumari  * @return None.
689d3ae10eSAlpana Kumari  */
698d1b46d7Szhanghch05 inline void
70ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
711e1e598dSJonathan Doman                          bool isDimmFunctional)
729d3ae10eSAlpana Kumari {
7362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
749d3ae10eSAlpana Kumari 
759d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
769d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
779d3ae10eSAlpana Kumari     // ENABLED.
7802cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
79ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
809d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
819d3ae10eSAlpana Kumari     {
82e05aec50SEd Tanous         if (isDimmFunctional)
839d3ae10eSAlpana Kumari         {
84ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
859d3ae10eSAlpana Kumari                 "Enabled";
869d3ae10eSAlpana Kumari         }
879d3ae10eSAlpana Kumari     }
889d3ae10eSAlpana Kumari }
899d3ae10eSAlpana Kumari 
9057e8c9beSAlpana Kumari /*
9157e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9257e8c9beSAlpana Kumari  *        CPU Functional State
9357e8c9beSAlpana Kumari  *
94ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9557e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9657e8c9beSAlpana Kumari  *
9757e8c9beSAlpana Kumari  * @return None.
9857e8c9beSAlpana Kumari  */
99ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
100ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10157e8c9beSAlpana Kumari {
10262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10357e8c9beSAlpana Kumari 
10402cad96eSEd Tanous     const nlohmann::json& prevProcState =
105ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10657e8c9beSAlpana Kumari 
10757e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10857e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10957e8c9beSAlpana Kumari     // Functional.
11057e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11157e8c9beSAlpana Kumari     {
112e05aec50SEd Tanous         if (isCpuFunctional)
11357e8c9beSAlpana Kumari         {
114ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11557e8c9beSAlpana Kumari                 "Enabled";
11657e8c9beSAlpana Kumari         }
11757e8c9beSAlpana Kumari     }
11857e8c9beSAlpana Kumari }
11957e8c9beSAlpana Kumari 
120cf0e004cSNinad Palsule /*
121cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
122cf0e004cSNinad Palsule  *
123ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
124cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
125cf0e004cSNinad Palsule  *
126cf0e004cSNinad Palsule  * @return None.
127cf0e004cSNinad Palsule  */
128cf0e004cSNinad Palsule inline void
129ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
130cf0e004cSNinad Palsule                            bool isCpuPresent)
131cf0e004cSNinad Palsule {
13262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
133cf0e004cSNinad Palsule 
134cf0e004cSNinad Palsule     if (isCpuPresent)
135cf0e004cSNinad Palsule     {
136cf0e004cSNinad Palsule         nlohmann::json& procCount =
137ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
138cf0e004cSNinad Palsule         auto* procCountPtr =
139cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
140cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
141cf0e004cSNinad Palsule         {
142cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
143cf0e004cSNinad Palsule             *procCountPtr += 1;
144cf0e004cSNinad Palsule         }
145cf0e004cSNinad Palsule     }
146cf0e004cSNinad Palsule }
147cf0e004cSNinad Palsule 
148382d6475SAli Ahmed inline void getProcessorProperties(
149ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
150382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
151382d6475SAli Ahmed         properties)
15203fbed92SAli Ahmed {
15362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15403fbed92SAli Ahmed 
15503fbed92SAli Ahmed     // TODO: Get Model
15603fbed92SAli Ahmed 
157bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15803fbed92SAli Ahmed 
159bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
160bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16103fbed92SAli Ahmed 
162bc1d29deSKrzysztof Grobelny     if (!success)
16303fbed92SAli Ahmed     {
164ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16503fbed92SAli Ahmed         return;
16603fbed92SAli Ahmed     }
16703fbed92SAli Ahmed 
168bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16903fbed92SAli Ahmed     {
170bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
171ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
172bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
173bc1d29deSKrzysztof Grobelny 
174bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
175bc1d29deSKrzysztof Grobelny         {
176bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17703fbed92SAli Ahmed         }
17803fbed92SAli Ahmed         else
17903fbed92SAli Ahmed         {
180bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18103fbed92SAli Ahmed         }
18203fbed92SAli Ahmed     }
18303fbed92SAli Ahmed }
18403fbed92SAli Ahmed 
18503fbed92SAli Ahmed /*
18603fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18703fbed92SAli Ahmed  *
188ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18903fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
19003fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19103fbed92SAli Ahmed  *
19203fbed92SAli Ahmed  * @return None.
19303fbed92SAli Ahmed  */
194ac106bf6SEd Tanous inline void
195ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
196ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19703fbed92SAli Ahmed {
198ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
199382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
200382d6475SAli Ahmed         if (ec3)
201382d6475SAli Ahmed         {
20262598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
203382d6475SAli Ahmed             return;
204382d6475SAli Ahmed         }
205ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
206382d6475SAli Ahmed     };
207382d6475SAli Ahmed 
208cf0e004cSNinad Palsule     // Get the Presence of CPU
209cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
210cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
211cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
212cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
213cf0e004cSNinad Palsule 
2145fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
2155fd0aafbSNinad Palsule     {
2165fd0aafbSNinad Palsule         auto getCpuFunctionalState =
217ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec3,
218382d6475SAli Ahmed                         const bool cpuFunctionalCheck) {
219382d6475SAli Ahmed             if (ec3)
220382d6475SAli Ahmed             {
22162598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
222382d6475SAli Ahmed                 return;
223382d6475SAli Ahmed             }
224ac106bf6SEd Tanous             modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
225382d6475SAli Ahmed         };
226382d6475SAli Ahmed 
227382d6475SAli Ahmed         // Get the Functional State
228382d6475SAli Ahmed         sdbusplus::asio::getProperty<bool>(
229382d6475SAli Ahmed             *crow::connections::systemBus, service, path,
2305fd0aafbSNinad Palsule             "xyz.openbmc_project.State.Decorator.OperationalStatus",
2315fd0aafbSNinad Palsule             "Functional", std::move(getCpuFunctionalState));
2325fd0aafbSNinad Palsule     }
233382d6475SAli Ahmed 
234bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
235bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
236bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
237ac106bf6SEd Tanous         [asyncResp, service,
2385e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
239b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
24003fbed92SAli Ahmed         if (ec2)
24103fbed92SAli Ahmed         {
24262598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
243ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24403fbed92SAli Ahmed             return;
24503fbed92SAli Ahmed         }
246ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
247bc1d29deSKrzysztof Grobelny     });
24803fbed92SAli Ahmed }
24903fbed92SAli Ahmed 
25057e8c9beSAlpana Kumari /*
251cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
252cf0e004cSNinad Palsule  *
253ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
254cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
255cf0e004cSNinad Palsule  * @param[in] path dbus path for Memory
256cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
257cf0e004cSNinad Palsule  *
258cf0e004cSNinad Palsule  * @return None.
259cf0e004cSNinad Palsule  */
260cf0e004cSNinad Palsule inline void
261ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2625fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& service,
2635fd0aafbSNinad Palsule                             [[maybe_unused]] const std::string& path,
264cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
265cf0e004cSNinad Palsule {
26662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
267cf0e004cSNinad Palsule 
268cf0e004cSNinad Palsule     if (properties.empty())
269cf0e004cSNinad Palsule     {
2705fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
2715fd0aafbSNinad Palsule         {
272cf0e004cSNinad Palsule             sdbusplus::asio::getProperty<bool>(
273cf0e004cSNinad Palsule                 *crow::connections::systemBus, service, path,
274cf0e004cSNinad Palsule                 "xyz.openbmc_project.State."
275cf0e004cSNinad Palsule                 "Decorator.OperationalStatus",
276cf0e004cSNinad Palsule                 "Functional",
277ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec3,
278ac106bf6SEd Tanous                             bool dimmState) {
279cf0e004cSNinad Palsule                 if (ec3)
280cf0e004cSNinad Palsule                 {
28162598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
282cf0e004cSNinad Palsule                     return;
283cf0e004cSNinad Palsule                 }
284ac106bf6SEd Tanous                 updateDimmProperties(asyncResp, dimmState);
285cf0e004cSNinad Palsule             });
2865fd0aafbSNinad Palsule         }
287cf0e004cSNinad Palsule         return;
288cf0e004cSNinad Palsule     }
289cf0e004cSNinad Palsule 
290cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
291cf0e004cSNinad Palsule 
292cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
293cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
294cf0e004cSNinad Palsule         memorySizeInKB);
295cf0e004cSNinad Palsule 
296cf0e004cSNinad Palsule     if (!success)
297cf0e004cSNinad Palsule     {
298ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
299cf0e004cSNinad Palsule         return;
300cf0e004cSNinad Palsule     }
301cf0e004cSNinad Palsule 
302cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
303cf0e004cSNinad Palsule     {
304cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
305ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
306dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
307cf0e004cSNinad Palsule         if (preValue == nullptr)
308cf0e004cSNinad Palsule         {
309ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
310dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
311cf0e004cSNinad Palsule         }
312cf0e004cSNinad Palsule         else
313cf0e004cSNinad Palsule         {
314ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
315dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
316dfb2b408SPriyanga Ramasamy                 *preValue;
317cf0e004cSNinad Palsule         }
3185fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
3195fd0aafbSNinad Palsule         {
320ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3215fd0aafbSNinad Palsule                 "Enabled";
3225fd0aafbSNinad Palsule         }
323cf0e004cSNinad Palsule     }
324cf0e004cSNinad Palsule }
325cf0e004cSNinad Palsule 
326cf0e004cSNinad Palsule /*
327cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
328cf0e004cSNinad Palsule  *
329ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
330cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
331cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
332cf0e004cSNinad Palsule  *
333cf0e004cSNinad Palsule  * @return None.
334cf0e004cSNinad Palsule  */
335ac106bf6SEd Tanous inline void
336ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
337ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
338cf0e004cSNinad Palsule {
339cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
340cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
341cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
342ac106bf6SEd Tanous         [asyncResp, service,
343cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
344cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
345cf0e004cSNinad Palsule         if (ec2)
346cf0e004cSNinad Palsule         {
34762598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
348ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
349cf0e004cSNinad Palsule             return;
350cf0e004cSNinad Palsule         }
351ac106bf6SEd Tanous         processMemoryProperties(asyncResp, service, path, properties);
352cf0e004cSNinad Palsule     });
353cf0e004cSNinad Palsule }
354cf0e004cSNinad Palsule 
355a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
356a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
357a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3581abe55efSEd Tanous {
359a974c132SLakshmi Yadlapati     if (ec)
360a974c132SLakshmi Yadlapati     {
361a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
362a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
363a974c132SLakshmi Yadlapati         return;
364a974c132SLakshmi Yadlapati     }
365a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
366a974c132SLakshmi Yadlapati 
367a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
368a974c132SLakshmi Yadlapati 
369a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
370a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
371a974c132SLakshmi Yadlapati 
372a974c132SLakshmi Yadlapati     if (!success)
373a974c132SLakshmi Yadlapati     {
374a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
375a974c132SLakshmi Yadlapati         return;
376a974c132SLakshmi Yadlapati     }
377a974c132SLakshmi Yadlapati 
378a974c132SLakshmi Yadlapati     if (uUID != nullptr)
379a974c132SLakshmi Yadlapati     {
380a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
381a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
382a974c132SLakshmi Yadlapati         {
383a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
384a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
385a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
386a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
387a974c132SLakshmi Yadlapati         }
388a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
389a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
390a974c132SLakshmi Yadlapati     }
391a974c132SLakshmi Yadlapati }
392a974c132SLakshmi Yadlapati 
393a974c132SLakshmi Yadlapati inline void
394a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
395a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
396a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
397a974c132SLakshmi Yadlapati {
398a974c132SLakshmi Yadlapati     if (ec)
399a974c132SLakshmi Yadlapati     {
400a974c132SLakshmi Yadlapati         // doesn't have to include this
401a974c132SLakshmi Yadlapati         // interface
402a974c132SLakshmi Yadlapati         return;
403a974c132SLakshmi Yadlapati     }
404a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
405a974c132SLakshmi Yadlapati 
406a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
407a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
408a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
409a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
410a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
411a974c132SLakshmi Yadlapati 
412a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
413a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
414a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
415a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
416a974c132SLakshmi Yadlapati 
417a974c132SLakshmi Yadlapati     if (!success)
418a974c132SLakshmi Yadlapati     {
419a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
420a974c132SLakshmi Yadlapati         return;
421a974c132SLakshmi Yadlapati     }
422a974c132SLakshmi Yadlapati 
423a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
424a974c132SLakshmi Yadlapati     {
425a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
426a974c132SLakshmi Yadlapati     }
427a974c132SLakshmi Yadlapati 
428a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
429a974c132SLakshmi Yadlapati     {
430a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
431a974c132SLakshmi Yadlapati     }
432a974c132SLakshmi Yadlapati 
433a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
434a974c132SLakshmi Yadlapati     {
435a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
436a974c132SLakshmi Yadlapati     }
437a974c132SLakshmi Yadlapati 
438a974c132SLakshmi Yadlapati     if (model != nullptr)
439a974c132SLakshmi Yadlapati     {
440a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
441a974c132SLakshmi Yadlapati     }
442a974c132SLakshmi Yadlapati 
443a974c132SLakshmi Yadlapati     if (subModel != nullptr)
444a974c132SLakshmi Yadlapati     {
445a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
446a974c132SLakshmi Yadlapati     }
447a974c132SLakshmi Yadlapati 
448a974c132SLakshmi Yadlapati     // Grab the bios version
449a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
450a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
451a974c132SLakshmi Yadlapati }
452a974c132SLakshmi Yadlapati 
453a974c132SLakshmi Yadlapati inline void
454a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
455a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
456a974c132SLakshmi Yadlapati                      const std::string& value)
457a974c132SLakshmi Yadlapati {
458a974c132SLakshmi Yadlapati     if (ec)
459a974c132SLakshmi Yadlapati     {
460a974c132SLakshmi Yadlapati         // doesn't have to include this
461a974c132SLakshmi Yadlapati         // interface
462a974c132SLakshmi Yadlapati         return;
463a974c132SLakshmi Yadlapati     }
464a974c132SLakshmi Yadlapati 
465a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
466a974c132SLakshmi Yadlapati }
467a974c132SLakshmi Yadlapati 
468a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
469a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
470a974c132SLakshmi Yadlapati     const std::shared_ptr<HealthPopulate>& systemHealth,
471a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
472a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
473a974c132SLakshmi Yadlapati {
4741abe55efSEd Tanous     if (ec)
4751abe55efSEd Tanous     {
476b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
477ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
478c5b2abe0SLewanczyk, Dawid         return;
479c5b2abe0SLewanczyk, Dawid     }
480c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
481002d39b4SEd Tanous     for (const std::pair<
482002d39b4SEd Tanous              std::string,
483002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4841214b7e7SGunnar Mills              object : subtree)
4851abe55efSEd Tanous     {
486c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
48762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
488002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4891214b7e7SGunnar Mills             connectionNames = object.second;
49026f6976fSEd Tanous         if (connectionNames.empty())
4911abe55efSEd Tanous         {
492c5b2abe0SLewanczyk, Dawid             continue;
493c5b2abe0SLewanczyk, Dawid         }
494029573d4SEd Tanous 
4955fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
4965fd0aafbSNinad Palsule         std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
4975bc2dc8eSJames Feist 
4985fd0aafbSNinad Palsule         if constexpr (bmcwebEnableProcMemStatus)
4995fd0aafbSNinad Palsule         {
5005fd0aafbSNinad Palsule             memoryHealth = std::make_shared<HealthPopulate>(
501ac106bf6SEd Tanous                 asyncResp, "/MemorySummary/Status"_json_pointer);
5025fd0aafbSNinad Palsule             systemHealth->children.emplace_back(memoryHealth);
5035bc2dc8eSJames Feist 
50413451e39SWilly Tu             if constexpr (bmcwebEnableHealthPopulate)
50513451e39SWilly Tu             {
5065fd0aafbSNinad Palsule                 cpuHealth = std::make_shared<HealthPopulate>(
507ac106bf6SEd Tanous                     asyncResp, "/ProcessorSummary/Status"_json_pointer);
5085fd0aafbSNinad Palsule 
5095bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
51013451e39SWilly Tu             }
5115fd0aafbSNinad Palsule         }
5125bc2dc8eSJames Feist 
5136c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
5146c34de48SEd Tanous         // BiosVer
51504a258f4SEd Tanous         for (const auto& connection : connectionNames)
5161abe55efSEd Tanous         {
51704a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
5181abe55efSEd Tanous             {
519a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
5201abe55efSEd Tanous                 {
52162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
5229d3ae10eSAlpana Kumari 
523ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
5245bc2dc8eSJames Feist 
5255fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5265fd0aafbSNinad Palsule                     {
5275bc2dc8eSJames Feist                         memoryHealth->inventory.emplace_back(path);
5281abe55efSEd Tanous                     }
5295fd0aafbSNinad Palsule                 }
53004a258f4SEd Tanous                 else if (interfaceName ==
53104a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
5321abe55efSEd Tanous                 {
53362598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
53457e8c9beSAlpana Kumari 
535ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
5365bc2dc8eSJames Feist 
5375fd0aafbSNinad Palsule                     if constexpr (bmcwebEnableProcMemStatus)
5385fd0aafbSNinad Palsule                     {
5395bc2dc8eSJames Feist                         cpuHealth->inventory.emplace_back(path);
5401abe55efSEd Tanous                     }
5415fd0aafbSNinad Palsule                 }
542002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
5431abe55efSEd Tanous                 {
54462598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
545bc1d29deSKrzysztof Grobelny 
546bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
547a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
548a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
549ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
550b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
5511214b7e7SGunnar Mills                                         properties) {
552a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
553bc1d29deSKrzysztof Grobelny                     });
554c5b2abe0SLewanczyk, Dawid                 }
555029573d4SEd Tanous                 else if (interfaceName ==
556029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
5571abe55efSEd Tanous                 {
558bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
559a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
560bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
561a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
562b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
563a974c132SLakshmi Yadlapati                                         properties) {
564a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
565bc1d29deSKrzysztof Grobelny                     });
566e4a4b9a9SJames Feist 
5671e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
568a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
5691e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
5701e1e598dSJonathan Doman                         "AssetTag",
5711e1e598dSJonathan Doman                         "AssetTag",
572a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
573a974c132SLakshmi Yadlapati                 }
574a974c132SLakshmi Yadlapati             }
575a974c132SLakshmi Yadlapati         }
576a974c132SLakshmi Yadlapati     }
577a974c132SLakshmi Yadlapati }
578a974c132SLakshmi Yadlapati 
579a974c132SLakshmi Yadlapati /*
580a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
581a974c132SLakshmi Yadlapati  *
582a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
583a974c132SLakshmi Yadlapati  * @param[in] systemHealth  Shared HealthPopulate pointer
584a974c132SLakshmi Yadlapati  *
585a974c132SLakshmi Yadlapati  * @return None.
586a974c132SLakshmi Yadlapati  */
587a974c132SLakshmi Yadlapati inline void
588a974c132SLakshmi Yadlapati     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
589a974c132SLakshmi Yadlapati                       const std::shared_ptr<HealthPopulate>& systemHealth)
590e4a4b9a9SJames Feist {
591a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
592a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
593a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
594a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
595a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
596a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
597a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
598a974c132SLakshmi Yadlapati     };
599a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
600a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
601a974c132SLakshmi Yadlapati         std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
602c5b2abe0SLewanczyk, Dawid }
603c5b2abe0SLewanczyk, Dawid 
604c5b2abe0SLewanczyk, Dawid /**
605c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
606c5b2abe0SLewanczyk, Dawid  *
607ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
608c5b2abe0SLewanczyk, Dawid  *
609c5b2abe0SLewanczyk, Dawid  * @return None.
610c5b2abe0SLewanczyk, Dawid  */
611ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
6121abe55efSEd Tanous {
61362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
6141e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
6151e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
6161e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
6171e1e598dSJonathan Doman         "CurrentHostState",
618ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
6191e1e598dSJonathan Doman                     const std::string& hostState) {
6201abe55efSEd Tanous         if (ec)
6211abe55efSEd Tanous         {
62222228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
62322228c28SAndrew Geissler             {
62422228c28SAndrew Geissler                 // Service not available, no error, just don't return
62522228c28SAndrew Geissler                 // host state info
62662598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
62722228c28SAndrew Geissler                 return;
62822228c28SAndrew Geissler             }
62962598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
630ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
631c5b2abe0SLewanczyk, Dawid             return;
632c5b2abe0SLewanczyk, Dawid         }
6336617338dSEd Tanous 
63462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
635c5b2abe0SLewanczyk, Dawid         // Verify Host State
6361e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
6371abe55efSEd Tanous         {
638ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
639ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
6401abe55efSEd Tanous         }
6411e1e598dSJonathan Doman         else if (hostState ==
6420fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
6438c888608SGunnar Mills         {
644ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
645ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
6468c888608SGunnar Mills         }
6471e1e598dSJonathan Doman         else if (hostState ==
6480fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
64983935af9SAndrew Geissler         {
650ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
651ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
65283935af9SAndrew Geissler         }
6530fda0f12SGeorge Liu         else if (
6541e1e598dSJonathan Doman             hostState ==
6550fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6561a2a1437SAndrew Geissler         {
657ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
658ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
6591a2a1437SAndrew Geissler         }
660002d39b4SEd Tanous         else if (hostState ==
6610fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6621a2a1437SAndrew Geissler         {
663ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
664ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
6651a2a1437SAndrew Geissler         }
6661abe55efSEd Tanous         else
6671abe55efSEd Tanous         {
668ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
669ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
670c5b2abe0SLewanczyk, Dawid         }
6711e1e598dSJonathan Doman     });
672c5b2abe0SLewanczyk, Dawid }
673c5b2abe0SLewanczyk, Dawid 
674c5b2abe0SLewanczyk, Dawid /**
675786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
676491d8ee7SSantosh Puranik  *
677491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
678491d8ee7SSantosh Puranik  *
679491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
680491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
681491d8ee7SSantosh Puranik  */
68223a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
683491d8ee7SSantosh Puranik {
684491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
685491d8ee7SSantosh Puranik     {
686491d8ee7SSantosh Puranik         return "None";
687491d8ee7SSantosh Puranik     }
6883174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
689491d8ee7SSantosh Puranik     {
690491d8ee7SSantosh Puranik         return "Hdd";
691491d8ee7SSantosh Puranik     }
6923174e4dfSEd Tanous     if (dbusSource ==
693a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
694491d8ee7SSantosh Puranik     {
695491d8ee7SSantosh Puranik         return "Cd";
696491d8ee7SSantosh Puranik     }
6973174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
698491d8ee7SSantosh Puranik     {
699491d8ee7SSantosh Puranik         return "Pxe";
700491d8ee7SSantosh Puranik     }
7013174e4dfSEd Tanous     if (dbusSource ==
702944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
7039f16b2c1SJennifer Lee     {
7049f16b2c1SJennifer Lee         return "Usb";
7059f16b2c1SJennifer Lee     }
706491d8ee7SSantosh Puranik     return "";
707491d8ee7SSantosh Puranik }
708491d8ee7SSantosh Puranik 
709491d8ee7SSantosh Puranik /**
710cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
711cd9a4666SKonstantin Aladyshev  *
712cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
713cd9a4666SKonstantin Aladyshev  *
714cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
715cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
716cd9a4666SKonstantin Aladyshev  */
717cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
718cd9a4666SKonstantin Aladyshev {
719cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
720cd9a4666SKonstantin Aladyshev     {
721cd9a4666SKonstantin Aladyshev         return "Legacy";
722cd9a4666SKonstantin Aladyshev     }
723cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
724cd9a4666SKonstantin Aladyshev     {
725cd9a4666SKonstantin Aladyshev         return "UEFI";
726cd9a4666SKonstantin Aladyshev     }
727cd9a4666SKonstantin Aladyshev     return "";
728cd9a4666SKonstantin Aladyshev }
729cd9a4666SKonstantin Aladyshev 
730cd9a4666SKonstantin Aladyshev /**
731786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
732491d8ee7SSantosh Puranik  *
733491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
734491d8ee7SSantosh Puranik  *
735491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
736491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
737491d8ee7SSantosh Puranik  */
73823a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
739491d8ee7SSantosh Puranik {
740491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
741491d8ee7SSantosh Puranik     {
742491d8ee7SSantosh Puranik         return "None";
743491d8ee7SSantosh Puranik     }
7443174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
745491d8ee7SSantosh Puranik     {
746491d8ee7SSantosh Puranik         return "Diags";
747491d8ee7SSantosh Puranik     }
7483174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
749491d8ee7SSantosh Puranik     {
750491d8ee7SSantosh Puranik         return "BiosSetup";
751491d8ee7SSantosh Puranik     }
752491d8ee7SSantosh Puranik     return "";
753491d8ee7SSantosh Puranik }
754491d8ee7SSantosh Puranik 
755491d8ee7SSantosh Puranik /**
756e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
757e43914b3SAndrew Geissler  *
758e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
759e43914b3SAndrew Geissler  *
760e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
761e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
762e43914b3SAndrew Geissler  */
763e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
764e43914b3SAndrew Geissler {
765e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
766e43914b3SAndrew Geissler     // enum
767e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
768e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
769e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
770e43914b3SAndrew Geissler     {
771e43914b3SAndrew Geissler         rfBpLastState = "None";
772e43914b3SAndrew Geissler     }
773e43914b3SAndrew Geissler     else if (dbusBootProgress ==
774e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
775e43914b3SAndrew Geissler              "PrimaryProcInit")
776e43914b3SAndrew Geissler     {
777e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
778e43914b3SAndrew Geissler     }
779e43914b3SAndrew Geissler     else if (dbusBootProgress ==
780e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
781e43914b3SAndrew Geissler              "BusInit")
782e43914b3SAndrew Geissler     {
783e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
784e43914b3SAndrew Geissler     }
785e43914b3SAndrew Geissler     else if (dbusBootProgress ==
786e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
787e43914b3SAndrew Geissler              "MemoryInit")
788e43914b3SAndrew Geissler     {
789e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
790e43914b3SAndrew Geissler     }
791e43914b3SAndrew Geissler     else if (dbusBootProgress ==
792e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
793e43914b3SAndrew Geissler              "SecondaryProcInit")
794e43914b3SAndrew Geissler     {
795e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
796e43914b3SAndrew Geissler     }
797e43914b3SAndrew Geissler     else if (dbusBootProgress ==
798e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
799e43914b3SAndrew Geissler              "PCIInit")
800e43914b3SAndrew Geissler     {
801e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
802e43914b3SAndrew Geissler     }
803e43914b3SAndrew Geissler     else if (dbusBootProgress ==
804e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
805e43914b3SAndrew Geissler              "SystemSetup")
806e43914b3SAndrew Geissler     {
807e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
808e43914b3SAndrew Geissler     }
809e43914b3SAndrew Geissler     else if (dbusBootProgress ==
810e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
811e43914b3SAndrew Geissler              "SystemInitComplete")
812e43914b3SAndrew Geissler     {
813e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
814e43914b3SAndrew Geissler     }
815e43914b3SAndrew Geissler     else if (dbusBootProgress ==
816e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
817e43914b3SAndrew Geissler              "OSStart")
818e43914b3SAndrew Geissler     {
819e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
820e43914b3SAndrew Geissler     }
821e43914b3SAndrew Geissler     else if (dbusBootProgress ==
822e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
823e43914b3SAndrew Geissler              "OSRunning")
824e43914b3SAndrew Geissler     {
825e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
826e43914b3SAndrew Geissler     }
827e43914b3SAndrew Geissler     else
828e43914b3SAndrew Geissler     {
82962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
830e43914b3SAndrew Geissler         // Just return the default
831e43914b3SAndrew Geissler     }
832e43914b3SAndrew Geissler     return rfBpLastState;
833e43914b3SAndrew Geissler }
834e43914b3SAndrew Geissler 
835e43914b3SAndrew Geissler /**
836786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
837491d8ee7SSantosh Puranik  *
838491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
839944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
840944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
841491d8ee7SSantosh Puranik  *
842944ffaf9SJohnathan Mantey  * @return Integer error code.
843491d8ee7SSantosh Puranik  */
844ac106bf6SEd Tanous inline int
845ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
846ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
847ac106bf6SEd Tanous                          std::string& bootMode)
848491d8ee7SSantosh Puranik {
849c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
850c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
851944ffaf9SJohnathan Mantey 
852491d8ee7SSantosh Puranik     if (rfSource == "None")
853491d8ee7SSantosh Puranik     {
854944ffaf9SJohnathan Mantey         return 0;
855491d8ee7SSantosh Puranik     }
8563174e4dfSEd Tanous     if (rfSource == "Pxe")
857491d8ee7SSantosh Puranik     {
858944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
859944ffaf9SJohnathan Mantey     }
860944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
861944ffaf9SJohnathan Mantey     {
862944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
863944ffaf9SJohnathan Mantey     }
864944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
865944ffaf9SJohnathan Mantey     {
866944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
867944ffaf9SJohnathan Mantey     }
868944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
869944ffaf9SJohnathan Mantey     {
870944ffaf9SJohnathan Mantey         bootSource =
871944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
872944ffaf9SJohnathan Mantey     }
873944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
874944ffaf9SJohnathan Mantey     {
875944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
876491d8ee7SSantosh Puranik     }
8779f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8789f16b2c1SJennifer Lee     {
879944ffaf9SJohnathan Mantey         bootSource =
880944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8819f16b2c1SJennifer Lee     }
882491d8ee7SSantosh Puranik     else
883491d8ee7SSantosh Puranik     {
88462598e31SEd Tanous         BMCWEB_LOG_DEBUG(
88562598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
88662598e31SEd Tanous             bootSource);
887ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
888944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
889944ffaf9SJohnathan Mantey         return -1;
890491d8ee7SSantosh Puranik     }
891944ffaf9SJohnathan Mantey     return 0;
892491d8ee7SSantosh Puranik }
8931981771bSAli Ahmed 
894978b8803SAndrew Geissler /**
895978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
896978b8803SAndrew Geissler  *
897ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
898978b8803SAndrew Geissler  *
899978b8803SAndrew Geissler  * @return None.
900978b8803SAndrew Geissler  */
901ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
902978b8803SAndrew Geissler {
9031e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9041e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
9051e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
9061e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
907ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9081e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
909978b8803SAndrew Geissler         if (ec)
910978b8803SAndrew Geissler         {
911978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
912978b8803SAndrew Geissler             // not found
913978b8803SAndrew Geissler             return;
914978b8803SAndrew Geissler         }
915978b8803SAndrew Geissler 
91662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
917978b8803SAndrew Geissler 
918ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
919e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
9201e1e598dSJonathan Doman     });
921978b8803SAndrew Geissler }
922491d8ee7SSantosh Puranik 
923491d8ee7SSantosh Puranik /**
924b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
925b6d5d45cSHieu Huynh  *
926ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
927b6d5d45cSHieu Huynh  *
928b6d5d45cSHieu Huynh  * @return None.
929b6d5d45cSHieu Huynh  */
930b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
931ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
932b6d5d45cSHieu Huynh {
933b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
934b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
935b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
936b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
937ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
938b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
939b6d5d45cSHieu Huynh         if (ec)
940b6d5d45cSHieu Huynh         {
94162598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
942b6d5d45cSHieu Huynh             return;
943b6d5d45cSHieu Huynh         }
944b6d5d45cSHieu Huynh 
945b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
946b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
947b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
948b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
949b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
950b6d5d45cSHieu Huynh 
951b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
952ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
953b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
954b6d5d45cSHieu Huynh     });
955b6d5d45cSHieu Huynh }
956b6d5d45cSHieu Huynh 
957b6d5d45cSHieu Huynh /**
958c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
959cd9a4666SKonstantin Aladyshev  *
960ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
961cd9a4666SKonstantin Aladyshev  *
962cd9a4666SKonstantin Aladyshev  * @return None.
963cd9a4666SKonstantin Aladyshev  */
964cd9a4666SKonstantin Aladyshev 
965ac106bf6SEd Tanous inline void
966ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
967cd9a4666SKonstantin Aladyshev {
9681e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9691e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9701e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9711e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
972ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9731e1e598dSJonathan Doman                     const std::string& bootType) {
974cd9a4666SKonstantin Aladyshev         if (ec)
975cd9a4666SKonstantin Aladyshev         {
976cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
977cd9a4666SKonstantin Aladyshev             return;
978cd9a4666SKonstantin Aladyshev         }
979cd9a4666SKonstantin Aladyshev 
98062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
981cd9a4666SKonstantin Aladyshev 
982ac106bf6SEd Tanous         asyncResp->res
983ac106bf6SEd Tanous             .jsonValue["Boot"]
984002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
985613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
986cd9a4666SKonstantin Aladyshev 
9871e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
988cd9a4666SKonstantin Aladyshev         if (rfType.empty())
989cd9a4666SKonstantin Aladyshev         {
990ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
991cd9a4666SKonstantin Aladyshev             return;
992cd9a4666SKonstantin Aladyshev         }
993cd9a4666SKonstantin Aladyshev 
994ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9951e1e598dSJonathan Doman     });
996cd9a4666SKonstantin Aladyshev }
997cd9a4666SKonstantin Aladyshev 
998cd9a4666SKonstantin Aladyshev /**
999c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
1000491d8ee7SSantosh Puranik  *
1001ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1002491d8ee7SSantosh Puranik  *
1003491d8ee7SSantosh Puranik  * @return None.
1004491d8ee7SSantosh Puranik  */
1005c21865c4SKonstantin Aladyshev 
1006ac106bf6SEd Tanous inline void
1007ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1008491d8ee7SSantosh Puranik {
10091e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10101e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10111e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10121e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1013ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10141e1e598dSJonathan Doman                     const std::string& bootModeStr) {
1015491d8ee7SSantosh Puranik         if (ec)
1016491d8ee7SSantosh Puranik         {
1017b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1018ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1019491d8ee7SSantosh Puranik             return;
1020491d8ee7SSantosh Puranik         }
1021491d8ee7SSantosh Puranik 
102262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
1023491d8ee7SSantosh Puranik 
1024ac106bf6SEd Tanous         asyncResp->res
10250fda0f12SGeorge Liu             .jsonValue["Boot"]
1026002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1027002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1028491d8ee7SSantosh Puranik 
10291e1e598dSJonathan Doman         if (bootModeStr !=
1030491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1031491d8ee7SSantosh Puranik         {
10321e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
1033491d8ee7SSantosh Puranik             if (!rfMode.empty())
1034491d8ee7SSantosh Puranik             {
1035ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1036491d8ee7SSantosh Puranik                     rfMode;
1037491d8ee7SSantosh Puranik             }
1038491d8ee7SSantosh Puranik         }
10391e1e598dSJonathan Doman     });
1040491d8ee7SSantosh Puranik }
1041491d8ee7SSantosh Puranik 
1042491d8ee7SSantosh Puranik /**
1043c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1044491d8ee7SSantosh Puranik  *
1045ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
1046491d8ee7SSantosh Puranik  *
1047491d8ee7SSantosh Puranik  * @return None.
1048491d8ee7SSantosh Puranik  */
1049c21865c4SKonstantin Aladyshev 
1050c21865c4SKonstantin Aladyshev inline void
1051ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1052491d8ee7SSantosh Puranik {
10531e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
10541e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10551e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10561e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1057ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10581e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
1059491d8ee7SSantosh Puranik         if (ec)
1060491d8ee7SSantosh Puranik         {
10615ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10625ef735c8SNan Zhou             {
10635ef735c8SNan Zhou                 return;
10645ef735c8SNan Zhou             }
1065b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1066ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1067491d8ee7SSantosh Puranik             return;
1068491d8ee7SSantosh Puranik         }
1069491d8ee7SSantosh Puranik 
107062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
1071491d8ee7SSantosh Puranik 
10721e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
1073491d8ee7SSantosh Puranik         if (!rfSource.empty())
1074491d8ee7SSantosh Puranik         {
1075ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1076ac106bf6SEd Tanous                 rfSource;
1077491d8ee7SSantosh Puranik         }
1078cd9a4666SKonstantin Aladyshev 
1079cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1080cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1081ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10821e1e598dSJonathan Doman     });
1083491d8ee7SSantosh Puranik }
1084491d8ee7SSantosh Puranik 
1085491d8ee7SSantosh Puranik /**
1086c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1087c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1088c21865c4SKonstantin Aladyshev  * state
1089491d8ee7SSantosh Puranik  *
1090ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1091491d8ee7SSantosh Puranik  *
1092491d8ee7SSantosh Puranik  * @return None.
1093491d8ee7SSantosh Puranik  */
1094491d8ee7SSantosh Puranik 
1095ac106bf6SEd Tanous inline void processBootOverrideEnable(
1096ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1097c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1098c21865c4SKonstantin Aladyshev {
1099c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1100c21865c4SKonstantin Aladyshev     {
1101ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1102ac106bf6SEd Tanous             "Disabled";
1103c21865c4SKonstantin Aladyshev         return;
1104c21865c4SKonstantin Aladyshev     }
1105c21865c4SKonstantin Aladyshev 
1106c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1107c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
11081e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11091e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11101e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
11111e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1112ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1113491d8ee7SSantosh Puranik         if (ec)
1114491d8ee7SSantosh Puranik         {
1115b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1116ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1117491d8ee7SSantosh Puranik             return;
1118491d8ee7SSantosh Puranik         }
1119491d8ee7SSantosh Puranik 
1120c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1121c21865c4SKonstantin Aladyshev         {
1122ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1123ac106bf6SEd Tanous                 "Once";
1124c21865c4SKonstantin Aladyshev         }
1125c21865c4SKonstantin Aladyshev         else
1126c21865c4SKonstantin Aladyshev         {
1127ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1128c21865c4SKonstantin Aladyshev                 "Continuous";
1129c21865c4SKonstantin Aladyshev         }
11301e1e598dSJonathan Doman     });
1131491d8ee7SSantosh Puranik }
1132491d8ee7SSantosh Puranik 
1133491d8ee7SSantosh Puranik /**
1134c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1135c21865c4SKonstantin Aladyshev  *
1136ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1137c21865c4SKonstantin Aladyshev  *
1138c21865c4SKonstantin Aladyshev  * @return None.
1139c21865c4SKonstantin Aladyshev  */
1140c21865c4SKonstantin Aladyshev 
1141c21865c4SKonstantin Aladyshev inline void
1142ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1143c21865c4SKonstantin Aladyshev {
11441e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
11451e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
11461e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
11471e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1148ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
11491e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1150c21865c4SKonstantin Aladyshev         if (ec)
1151c21865c4SKonstantin Aladyshev         {
11525ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
11535ef735c8SNan Zhou             {
11545ef735c8SNan Zhou                 return;
11555ef735c8SNan Zhou             }
1156b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1157ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1158c21865c4SKonstantin Aladyshev             return;
1159c21865c4SKonstantin Aladyshev         }
1160c21865c4SKonstantin Aladyshev 
1161ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
11621e1e598dSJonathan Doman     });
1163c21865c4SKonstantin Aladyshev }
1164c21865c4SKonstantin Aladyshev 
1165c21865c4SKonstantin Aladyshev /**
1166c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1167c21865c4SKonstantin Aladyshev  *
1168ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1169c21865c4SKonstantin Aladyshev  *
1170c21865c4SKonstantin Aladyshev  * @return None.
1171c21865c4SKonstantin Aladyshev  */
1172ac106bf6SEd Tanous inline void
1173ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1174c21865c4SKonstantin Aladyshev {
117562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1176c21865c4SKonstantin Aladyshev 
1177ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1178ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1179ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1180c21865c4SKonstantin Aladyshev }
1181c21865c4SKonstantin Aladyshev 
1182c21865c4SKonstantin Aladyshev /**
1183c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1184c0557e1aSGunnar Mills  *
1185c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1186c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1187c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1188c0557e1aSGunnar Mills  * last power operation time.
1189c0557e1aSGunnar Mills  *
1190ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1191c0557e1aSGunnar Mills  *
1192c0557e1aSGunnar Mills  * @return None.
1193c0557e1aSGunnar Mills  */
1194ac106bf6SEd Tanous inline void
1195ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1196c0557e1aSGunnar Mills {
119762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1198c0557e1aSGunnar Mills 
11991e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
12001e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
12011e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
12021e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1203ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1204ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1205c0557e1aSGunnar Mills         if (ec)
1206c0557e1aSGunnar Mills         {
120762598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1208c0557e1aSGunnar Mills             return;
1209c0557e1aSGunnar Mills         }
1210c0557e1aSGunnar Mills 
1211c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1212c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
12131e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1214c0557e1aSGunnar Mills 
1215c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1216ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
12172b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
12181e1e598dSJonathan Doman     });
1219c0557e1aSGunnar Mills }
1220c0557e1aSGunnar Mills 
1221c0557e1aSGunnar Mills /**
1222797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1223797d5daeSCorey Hardesty  *
1224797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1225797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1226797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1227797d5daeSCorey Hardesty  * dbus.
1228797d5daeSCorey Hardesty  *
1229ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1230797d5daeSCorey Hardesty  *
1231797d5daeSCorey Hardesty  * @return None.
1232797d5daeSCorey Hardesty  */
1233ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1234ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1235797d5daeSCorey Hardesty {
123662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1237797d5daeSCorey Hardesty 
1238797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1239797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1240797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1241797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1242ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1243ac106bf6SEd Tanous             const boost::system::error_code& ec,
1244797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1245797d5daeSCorey Hardesty         if (ec)
1246797d5daeSCorey Hardesty         {
1247797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1248797d5daeSCorey Hardesty             {
124962598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1250ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1251797d5daeSCorey Hardesty             }
1252797d5daeSCorey Hardesty             return;
1253797d5daeSCorey Hardesty         }
1254797d5daeSCorey Hardesty 
1255797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1256797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1257797d5daeSCorey Hardesty 
1258797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1259797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1260797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1261797d5daeSCorey Hardesty 
1262797d5daeSCorey Hardesty         if (!success)
1263797d5daeSCorey Hardesty         {
1264ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1265797d5daeSCorey Hardesty             return;
1266797d5daeSCorey Hardesty         }
1267797d5daeSCorey Hardesty 
1268797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1269797d5daeSCorey Hardesty         {
1270ac106bf6SEd Tanous             asyncResp->res
1271ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1272797d5daeSCorey Hardesty                 *attemptsLeft;
1273797d5daeSCorey Hardesty         }
1274797d5daeSCorey Hardesty 
1275797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1276797d5daeSCorey Hardesty         {
1277ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1278797d5daeSCorey Hardesty                 *retryAttempts;
1279797d5daeSCorey Hardesty         }
1280797d5daeSCorey Hardesty     });
1281797d5daeSCorey Hardesty }
1282797d5daeSCorey Hardesty 
1283797d5daeSCorey Hardesty /**
12846bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12856bd5a8d2SGunnar Mills  *
1286ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12876bd5a8d2SGunnar Mills  *
12886bd5a8d2SGunnar Mills  * @return None.
12896bd5a8d2SGunnar Mills  */
1290797d5daeSCorey Hardesty inline void
1291ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12926bd5a8d2SGunnar Mills {
129362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12946bd5a8d2SGunnar Mills 
12951e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12961e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12971e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12981e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1299ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1300ac106bf6SEd Tanous                     bool autoRebootEnabled) {
13016bd5a8d2SGunnar Mills         if (ec)
13026bd5a8d2SGunnar Mills         {
1303797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1304797d5daeSCorey Hardesty             {
130562598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1306ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1307797d5daeSCorey Hardesty             }
13086bd5a8d2SGunnar Mills             return;
13096bd5a8d2SGunnar Mills         }
13106bd5a8d2SGunnar Mills 
131162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1312e05aec50SEd Tanous         if (autoRebootEnabled)
13136bd5a8d2SGunnar Mills         {
1314ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13156bd5a8d2SGunnar Mills                 "RetryAttempts";
13166bd5a8d2SGunnar Mills         }
13176bd5a8d2SGunnar Mills         else
13186bd5a8d2SGunnar Mills         {
1319ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1320ac106bf6SEd Tanous                 "Disabled";
13216bd5a8d2SGunnar Mills         }
1322ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
132369f35306SGunnar Mills 
132469f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
132569f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
132669f35306SGunnar Mills         // RetryAttempts.
1327ac106bf6SEd Tanous         asyncResp->res
1328ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1329ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
13301e1e598dSJonathan Doman     });
13316bd5a8d2SGunnar Mills }
13326bd5a8d2SGunnar Mills 
13336bd5a8d2SGunnar Mills /**
1334797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1335797d5daeSCorey Hardesty  *
1336ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1337797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1338797d5daeSCorey Hardesty  *
1339797d5daeSCorey Hardesty  *@return None.
1340797d5daeSCorey Hardesty  */
1341797d5daeSCorey Hardesty 
1342ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1343ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1344797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1345797d5daeSCorey Hardesty {
134662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
13479ae226faSGeorge Liu     sdbusplus::asio::setProperty(
13489ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
13499ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
13509ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
13519ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1352797d5daeSCorey Hardesty         if (ec)
1353797d5daeSCorey Hardesty         {
135462598e31SEd Tanous             BMCWEB_LOG_ERROR(
135562598e31SEd Tanous                 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1356ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1357797d5daeSCorey Hardesty             return;
1358797d5daeSCorey Hardesty         }
13599ae226faSGeorge Liu     });
1360797d5daeSCorey Hardesty }
1361797d5daeSCorey Hardesty 
13628d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
13638d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
13648d69c668SEd Tanous {
13658d69c668SEd Tanous     if (value ==
13668d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
13678d69c668SEd Tanous     {
13688d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
13698d69c668SEd Tanous     }
13708d69c668SEd Tanous     if (value ==
13718d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
13728d69c668SEd Tanous     {
13738d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13748d69c668SEd Tanous     }
13758d69c668SEd Tanous     if (value ==
13763a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
13778d69c668SEd Tanous     {
13788d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13798d69c668SEd Tanous     }
13808d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13818d69c668SEd Tanous     {
13828d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13838d69c668SEd Tanous     }
13848d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13858d69c668SEd Tanous }
1386797d5daeSCorey Hardesty /**
1387c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1388c6a620f2SGeorge Liu  *
1389ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1390c6a620f2SGeorge Liu  *
1391c6a620f2SGeorge Liu  * @return None.
1392c6a620f2SGeorge Liu  */
13938d1b46d7Szhanghch05 inline void
1394ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1395c6a620f2SGeorge Liu {
139662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1397c6a620f2SGeorge Liu 
13981e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13991e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14001e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
14011e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1402ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
14035e7e2dc5SEd Tanous                     const std::string& policy) {
1404c6a620f2SGeorge Liu         if (ec)
1405c6a620f2SGeorge Liu         {
140662598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1407c6a620f2SGeorge Liu             return;
1408c6a620f2SGeorge Liu         }
14098d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
14108d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
14118d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1412c6a620f2SGeorge Liu         {
1413ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1414c6a620f2SGeorge Liu             return;
1415c6a620f2SGeorge Liu         }
1416c6a620f2SGeorge Liu 
14178d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
14181e1e598dSJonathan Doman     });
1419c6a620f2SGeorge Liu }
1420c6a620f2SGeorge Liu 
1421c6a620f2SGeorge Liu /**
14229dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
14239dcfe8c1SAlbert Zhang  *
14249dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
14259dcfe8c1SAlbert Zhang  *
14269dcfe8c1SAlbert Zhang  * @return None.
14279dcfe8c1SAlbert Zhang  */
14289dcfe8c1SAlbert Zhang inline void
14299dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14309dcfe8c1SAlbert Zhang {
143162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
14329dcfe8c1SAlbert Zhang 
14339dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
14349dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
14359dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
14369dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
14379dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
14389dcfe8c1SAlbert Zhang         if (ec)
14399dcfe8c1SAlbert Zhang         {
14409dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
14419dcfe8c1SAlbert Zhang             {
1442b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
14439dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
14449dcfe8c1SAlbert Zhang             }
14459dcfe8c1SAlbert Zhang             return;
14469dcfe8c1SAlbert Zhang         }
14479dcfe8c1SAlbert Zhang 
14489dcfe8c1SAlbert Zhang         if (value)
14499dcfe8c1SAlbert Zhang         {
14509dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
14519dcfe8c1SAlbert Zhang         }
14529dcfe8c1SAlbert Zhang         else
14539dcfe8c1SAlbert Zhang         {
14549dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
14559dcfe8c1SAlbert Zhang         }
14569dcfe8c1SAlbert Zhang     });
14579dcfe8c1SAlbert Zhang }
14589dcfe8c1SAlbert Zhang 
14599dcfe8c1SAlbert Zhang /**
14601981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
14611981771bSAli Ahmed  * TPM is required for booting the host.
14621981771bSAli Ahmed  *
1463ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14641981771bSAli Ahmed  *
14651981771bSAli Ahmed  * @return None.
14661981771bSAli Ahmed  */
14671981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1468ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
14691981771bSAli Ahmed {
147062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1471e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1472e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1473e99073f5SGeorge Liu     dbus::utility::getSubTree(
1474e99073f5SGeorge Liu         "/", 0, interfaces,
1475ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1476b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
14771981771bSAli Ahmed         if (ec)
14781981771bSAli Ahmed         {
147962598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
148062598e31SEd Tanous                              ec);
14811981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14821981771bSAli Ahmed             // error occurs
14831981771bSAli Ahmed             return;
14841981771bSAli Ahmed         }
148526f6976fSEd Tanous         if (subtree.empty())
14861981771bSAli Ahmed         {
14871981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14881981771bSAli Ahmed             // if there is no instance found
14891981771bSAli Ahmed             return;
14901981771bSAli Ahmed         }
14911981771bSAli Ahmed 
14921981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14931981771bSAli Ahmed         if (subtree.size() > 1)
14941981771bSAli Ahmed         {
149562598e31SEd Tanous             BMCWEB_LOG_DEBUG(
149662598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
149762598e31SEd Tanous                 subtree.size());
14981981771bSAli Ahmed             // Throw an internal Error and return
1499ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15001981771bSAli Ahmed             return;
15011981771bSAli Ahmed         }
15021981771bSAli Ahmed 
15031981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15041981771bSAli Ahmed         // field
15051981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15061981771bSAli Ahmed         {
150762598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1508ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15091981771bSAli Ahmed             return;
15101981771bSAli Ahmed         }
15111981771bSAli Ahmed 
15121981771bSAli Ahmed         const std::string& path = subtree[0].first;
15131981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15141981771bSAli Ahmed 
15151981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
15161e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
15171e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
15181e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1519ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1520ac106bf6SEd Tanous                         bool tpmRequired) {
15218a592810SEd Tanous             if (ec2)
15221981771bSAli Ahmed             {
1523b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
152462598e31SEd Tanous                                  ec2);
1525ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15261981771bSAli Ahmed                 return;
15271981771bSAli Ahmed             }
15281981771bSAli Ahmed 
15291e1e598dSJonathan Doman             if (tpmRequired)
15301981771bSAli Ahmed             {
1531ac106bf6SEd Tanous                 asyncResp->res
1532ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15331981771bSAli Ahmed                     "Required";
15341981771bSAli Ahmed             }
15351981771bSAli Ahmed             else
15361981771bSAli Ahmed             {
1537ac106bf6SEd Tanous                 asyncResp->res
1538ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
15391981771bSAli Ahmed                     "Disabled";
15401981771bSAli Ahmed             }
15411e1e598dSJonathan Doman         });
1542e99073f5SGeorge Liu     });
15431981771bSAli Ahmed }
15441981771bSAli Ahmed 
15451981771bSAli Ahmed /**
15461c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
15471c05dae3SAli Ahmed  * TPM is required for booting the host.
15481c05dae3SAli Ahmed  *
1549ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
15501c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
15511c05dae3SAli Ahmed  *
15521c05dae3SAli Ahmed  * @return None.
15531c05dae3SAli Ahmed  */
15541c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1555ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
15561c05dae3SAli Ahmed {
155762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1558e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1559e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1560e99073f5SGeorge Liu     dbus::utility::getSubTree(
1561e99073f5SGeorge Liu         "/", 0, interfaces,
1562ac106bf6SEd Tanous         [asyncResp,
1563e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1564e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
15651c05dae3SAli Ahmed         if (ec)
15661c05dae3SAli Ahmed         {
1567b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
156862598e31SEd Tanous                              ec);
1569ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15701c05dae3SAli Ahmed             return;
15711c05dae3SAli Ahmed         }
157226f6976fSEd Tanous         if (subtree.empty())
15731c05dae3SAli Ahmed         {
1574ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
15751c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
15761c05dae3SAli Ahmed             return;
15771c05dae3SAli Ahmed         }
15781c05dae3SAli Ahmed 
15791c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15801c05dae3SAli Ahmed         if (subtree.size() > 1)
15811c05dae3SAli Ahmed         {
158262598e31SEd Tanous             BMCWEB_LOG_DEBUG(
158362598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
158462598e31SEd Tanous                 subtree.size());
15851c05dae3SAli Ahmed             // Throw an internal Error and return
1586ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15871c05dae3SAli Ahmed             return;
15881c05dae3SAli Ahmed         }
15891c05dae3SAli Ahmed 
15901c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15911c05dae3SAli Ahmed         // field
15921c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15931c05dae3SAli Ahmed         {
159462598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1595ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15961c05dae3SAli Ahmed             return;
15971c05dae3SAli Ahmed         }
15981c05dae3SAli Ahmed 
15991c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
16001c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
16011c05dae3SAli Ahmed 
16021c05dae3SAli Ahmed         if (serv.empty())
16031c05dae3SAli Ahmed         {
160462598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1605ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
16061c05dae3SAli Ahmed             return;
16071c05dae3SAli Ahmed         }
16081c05dae3SAli Ahmed 
16091c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
16109ae226faSGeorge Liu         sdbusplus::asio::setProperty(
16119ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
16129ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1613ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
16148a592810SEd Tanous             if (ec2)
16151c05dae3SAli Ahmed             {
1616b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
161762598e31SEd Tanous                     "DBUS response error: Set TrustedModuleRequiredToBoot{}",
161862598e31SEd Tanous                     ec2);
1619ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
16201c05dae3SAli Ahmed                 return;
16211c05dae3SAli Ahmed             }
162262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
16239ae226faSGeorge Liu         });
1624e99073f5SGeorge Liu     });
16251c05dae3SAli Ahmed }
16261c05dae3SAli Ahmed 
16271c05dae3SAli Ahmed /**
1628491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1629491d8ee7SSantosh Puranik  *
1630ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1631cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1632cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1633cd9a4666SKonstantin Aladyshev  */
1634ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1635cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1636cd9a4666SKonstantin Aladyshev {
1637c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1638cd9a4666SKonstantin Aladyshev 
1639c21865c4SKonstantin Aladyshev     if (!bootType)
1640cd9a4666SKonstantin Aladyshev     {
1641c21865c4SKonstantin Aladyshev         return;
1642c21865c4SKonstantin Aladyshev     }
1643c21865c4SKonstantin Aladyshev 
1644cd9a4666SKonstantin Aladyshev     // Source target specified
164562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1646cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1647cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1648cd9a4666SKonstantin Aladyshev     {
1649cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1650cd9a4666SKonstantin Aladyshev     }
1651cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1652cd9a4666SKonstantin Aladyshev     {
1653cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1654cd9a4666SKonstantin Aladyshev     }
1655cd9a4666SKonstantin Aladyshev     else
1656cd9a4666SKonstantin Aladyshev     {
165762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
165862598e31SEd Tanous                          "BootSourceOverrideMode: {}",
165962598e31SEd Tanous                          *bootType);
1660ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1661cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1662cd9a4666SKonstantin Aladyshev         return;
1663cd9a4666SKonstantin Aladyshev     }
1664cd9a4666SKonstantin Aladyshev 
1665cd9a4666SKonstantin Aladyshev     // Act on validated parameters
166662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1667cd9a4666SKonstantin Aladyshev 
16689ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16699ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16709ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16719ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1672ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1673cd9a4666SKonstantin Aladyshev         if (ec)
1674cd9a4666SKonstantin Aladyshev         {
1675cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1676cd9a4666SKonstantin Aladyshev             {
1677ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1678cd9a4666SKonstantin Aladyshev                 return;
1679cd9a4666SKonstantin Aladyshev             }
1680b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1681ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1682cd9a4666SKonstantin Aladyshev             return;
1683cd9a4666SKonstantin Aladyshev         }
168462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type update done.");
16859ae226faSGeorge Liu     });
1686cd9a4666SKonstantin Aladyshev }
1687cd9a4666SKonstantin Aladyshev 
1688cd9a4666SKonstantin Aladyshev /**
1689cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1690cd9a4666SKonstantin Aladyshev  *
1691ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1692ac106bf6SEd Tanous  * message.
1693c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1694c21865c4SKonstantin Aladyshev  * @return Integer error code.
1695c21865c4SKonstantin Aladyshev  */
1696ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1697c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1698c21865c4SKonstantin Aladyshev {
1699c21865c4SKonstantin Aladyshev     if (!bootEnable)
1700c21865c4SKonstantin Aladyshev     {
1701c21865c4SKonstantin Aladyshev         return;
1702c21865c4SKonstantin Aladyshev     }
1703c21865c4SKonstantin Aladyshev     // Source target specified
170462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1705c21865c4SKonstantin Aladyshev 
1706c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1707c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1708c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1709c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1710c21865c4SKonstantin Aladyshev     {
1711c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1712c21865c4SKonstantin Aladyshev     }
1713c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1714c21865c4SKonstantin Aladyshev     {
1715c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1716c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1717c21865c4SKonstantin Aladyshev     }
1718c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1719c21865c4SKonstantin Aladyshev     {
1720c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1721c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1722c21865c4SKonstantin Aladyshev     }
1723c21865c4SKonstantin Aladyshev     else
1724c21865c4SKonstantin Aladyshev     {
172562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172662598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
172762598e31SEd Tanous             *bootEnable);
1728ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1729c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1730c21865c4SKonstantin Aladyshev         return;
1731c21865c4SKonstantin Aladyshev     }
1732c21865c4SKonstantin Aladyshev 
1733c21865c4SKonstantin Aladyshev     // Act on validated parameters
173462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1735c21865c4SKonstantin Aladyshev 
17369ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17379ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17389ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17399ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1740ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
17418a592810SEd Tanous         if (ec2)
1742c21865c4SKonstantin Aladyshev         {
1743b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
1744ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1745c21865c4SKonstantin Aladyshev             return;
1746c21865c4SKonstantin Aladyshev         }
174762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot override enable update done.");
17489ae226faSGeorge Liu     });
1749c21865c4SKonstantin Aladyshev 
1750c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1751c21865c4SKonstantin Aladyshev     {
1752c21865c4SKonstantin Aladyshev         return;
1753c21865c4SKonstantin Aladyshev     }
1754c21865c4SKonstantin Aladyshev 
1755c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1756c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
175762598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
175862598e31SEd Tanous                      bootOverridePersistent);
1759c21865c4SKonstantin Aladyshev 
17609ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17619ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17629ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
17639ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1764ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1765c21865c4SKonstantin Aladyshev         if (ec)
1766c21865c4SKonstantin Aladyshev         {
1767b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1768ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1769c21865c4SKonstantin Aladyshev             return;
1770c21865c4SKonstantin Aladyshev         }
177162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot one_time update done.");
17729ae226faSGeorge Liu     });
1773c21865c4SKonstantin Aladyshev }
1774c21865c4SKonstantin Aladyshev 
1775c21865c4SKonstantin Aladyshev /**
1776c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1777c21865c4SKonstantin Aladyshev  *
1778ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1779491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1780491d8ee7SSantosh Puranik  *
1781265c1602SJohnathan Mantey  * @return Integer error code.
1782491d8ee7SSantosh Puranik  */
1783ac106bf6SEd Tanous inline void
1784ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1785cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1786491d8ee7SSantosh Puranik {
1787c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1788c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1789944ffaf9SJohnathan Mantey 
1790c21865c4SKonstantin Aladyshev     if (!bootSource)
1791491d8ee7SSantosh Puranik     {
1792c21865c4SKonstantin Aladyshev         return;
1793c21865c4SKonstantin Aladyshev     }
1794c21865c4SKonstantin Aladyshev 
1795491d8ee7SSantosh Puranik     // Source target specified
179662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1797491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1798ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1799ac106bf6SEd Tanous                              bootModeStr) != 0)
1800491d8ee7SSantosh Puranik     {
180162598e31SEd Tanous         BMCWEB_LOG_DEBUG(
180262598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
180362598e31SEd Tanous             *bootSource);
1804ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1805491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1806491d8ee7SSantosh Puranik         return;
1807491d8ee7SSantosh Puranik     }
1808491d8ee7SSantosh Puranik 
1809944ffaf9SJohnathan Mantey     // Act on validated parameters
181062598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
181162598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1812944ffaf9SJohnathan Mantey 
18139ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18149ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18159ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18169ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1817ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1818491d8ee7SSantosh Puranik         if (ec)
1819491d8ee7SSantosh Puranik         {
1820b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1821ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1822491d8ee7SSantosh Puranik             return;
1823491d8ee7SSantosh Puranik         }
182462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source update done.");
18259ae226faSGeorge Liu     });
1826944ffaf9SJohnathan Mantey 
18279ae226faSGeorge Liu     sdbusplus::asio::setProperty(
18289ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
18299ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
18309ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1831ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1832491d8ee7SSantosh Puranik         if (ec)
1833491d8ee7SSantosh Puranik         {
1834b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1835ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1836491d8ee7SSantosh Puranik             return;
1837491d8ee7SSantosh Puranik         }
183862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode update done.");
18399ae226faSGeorge Liu     });
1840cd9a4666SKonstantin Aladyshev }
1841944ffaf9SJohnathan Mantey 
1842cd9a4666SKonstantin Aladyshev /**
1843c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1844491d8ee7SSantosh Puranik  *
1845ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1846491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1847cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1848491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1849491d8ee7SSantosh Puranik  *
1850265c1602SJohnathan Mantey  * @return Integer error code.
1851491d8ee7SSantosh Puranik  */
1852c21865c4SKonstantin Aladyshev 
1853ac106bf6SEd Tanous inline void
1854ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1855c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1856c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1857c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1858491d8ee7SSantosh Puranik {
185962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1860491d8ee7SSantosh Puranik 
1861ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1862ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1863ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1864491d8ee7SSantosh Puranik }
1865491d8ee7SSantosh Puranik 
1866c6a620f2SGeorge Liu /**
186798e386ecSGunnar Mills  * @brief Sets AssetTag
186898e386ecSGunnar Mills  *
1869ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
187098e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
187198e386ecSGunnar Mills  *
187298e386ecSGunnar Mills  * @return None.
187398e386ecSGunnar Mills  */
1874ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
187598e386ecSGunnar Mills                         const std::string& assetTag)
187698e386ecSGunnar Mills {
1877e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1878e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1879e99073f5SGeorge Liu     dbus::utility::getSubTree(
1880e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1881ac106bf6SEd Tanous         [asyncResp,
1882e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1883b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
188498e386ecSGunnar Mills         if (ec)
188598e386ecSGunnar Mills         {
188662598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1887ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
188898e386ecSGunnar Mills             return;
188998e386ecSGunnar Mills         }
189026f6976fSEd Tanous         if (subtree.empty())
189198e386ecSGunnar Mills         {
189262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1893ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
189498e386ecSGunnar Mills             return;
189598e386ecSGunnar Mills         }
189698e386ecSGunnar Mills         // Assume only 1 system D-Bus object
189798e386ecSGunnar Mills         // Throw an error if there is more than 1
189898e386ecSGunnar Mills         if (subtree.size() > 1)
189998e386ecSGunnar Mills         {
190062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1901ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190298e386ecSGunnar Mills             return;
190398e386ecSGunnar Mills         }
190498e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
190598e386ecSGunnar Mills         {
190662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1907ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
190898e386ecSGunnar Mills             return;
190998e386ecSGunnar Mills         }
191098e386ecSGunnar Mills 
191198e386ecSGunnar Mills         const std::string& path = subtree[0].first;
191298e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
191398e386ecSGunnar Mills 
191498e386ecSGunnar Mills         if (service.empty())
191598e386ecSGunnar Mills         {
191662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1917ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
191898e386ecSGunnar Mills             return;
191998e386ecSGunnar Mills         }
192098e386ecSGunnar Mills 
19219ae226faSGeorge Liu         sdbusplus::asio::setProperty(
19229ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
19239ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
19249ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
192598e386ecSGunnar Mills             if (ec2)
192698e386ecSGunnar Mills             {
1927b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
192862598e31SEd Tanous                                  ec2);
1929ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
193098e386ecSGunnar Mills                 return;
193198e386ecSGunnar Mills             }
19329ae226faSGeorge Liu         });
1933e99073f5SGeorge Liu     });
193498e386ecSGunnar Mills }
193598e386ecSGunnar Mills 
193698e386ecSGunnar Mills /**
19379dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
19389dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
19399dcfe8c1SAlbert Zhang  *
19409dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
19419dcfe8c1SAlbert Zhang  * stopBootOnFault
19429dcfe8c1SAlbert Zhang  *
19439dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
19449dcfe8c1SAlbert Zhang  */
19459dcfe8c1SAlbert Zhang inline std::optional<bool>
19469dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
19479dcfe8c1SAlbert Zhang {
19489dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
19499dcfe8c1SAlbert Zhang     {
19509dcfe8c1SAlbert Zhang         return true;
19519dcfe8c1SAlbert Zhang     }
19529dcfe8c1SAlbert Zhang 
19539dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
19549dcfe8c1SAlbert Zhang     {
19559dcfe8c1SAlbert Zhang         return false;
19569dcfe8c1SAlbert Zhang     }
19579dcfe8c1SAlbert Zhang 
19589dcfe8c1SAlbert Zhang     return std::nullopt;
19599dcfe8c1SAlbert Zhang }
19609dcfe8c1SAlbert Zhang 
19619dcfe8c1SAlbert Zhang /**
19629dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
19639dcfe8c1SAlbert Zhang  *
1964fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
19659dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
19669dcfe8c1SAlbert Zhang  *
19679dcfe8c1SAlbert Zhang  * @return None.
19689dcfe8c1SAlbert Zhang  */
1969fc3edfddSEd Tanous inline void
1970fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19719dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
19729dcfe8c1SAlbert Zhang {
197362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
19749dcfe8c1SAlbert Zhang 
19759dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
19769dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
19779dcfe8c1SAlbert Zhang     {
197862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
197962598e31SEd Tanous                          stopBootOnFault);
1980fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19819dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19829dcfe8c1SAlbert Zhang         return;
19839dcfe8c1SAlbert Zhang     }
19849dcfe8c1SAlbert Zhang 
1985fc3edfddSEd Tanous     sdbusplus::asio::setProperty(
1986fc3edfddSEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19879dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1988fc3edfddSEd Tanous         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1989fc3edfddSEd Tanous         *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
19909dcfe8c1SAlbert Zhang         if (ec)
19919dcfe8c1SAlbert Zhang         {
19929dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19939dcfe8c1SAlbert Zhang             {
1994b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1995fc3edfddSEd Tanous                 messages::internalError(asyncResp->res);
19969dcfe8c1SAlbert Zhang             }
19979dcfe8c1SAlbert Zhang             return;
19989dcfe8c1SAlbert Zhang         }
19999dcfe8c1SAlbert Zhang     });
20009dcfe8c1SAlbert Zhang }
20019dcfe8c1SAlbert Zhang 
20029dcfe8c1SAlbert Zhang /**
200369f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
200469f35306SGunnar Mills  *
2005ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
200669f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
200769f35306SGunnar Mills  *
200869f35306SGunnar Mills  * @return None.
200969f35306SGunnar Mills  */
2010ac106bf6SEd Tanous inline void
2011ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2012f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
201369f35306SGunnar Mills {
201462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
201569f35306SGunnar Mills 
201669f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
2017543f4400SEd Tanous     bool autoRebootEnabled = false;
201869f35306SGunnar Mills 
201969f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
202069f35306SGunnar Mills     {
202169f35306SGunnar Mills         autoRebootEnabled = false;
202269f35306SGunnar Mills     }
202369f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
202469f35306SGunnar Mills     {
202569f35306SGunnar Mills         autoRebootEnabled = true;
202669f35306SGunnar Mills     }
202769f35306SGunnar Mills     else
202869f35306SGunnar Mills     {
202962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
203062598e31SEd Tanous                          automaticRetryConfig);
2031ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
203269f35306SGunnar Mills                                          "AutomaticRetryConfig");
203369f35306SGunnar Mills         return;
203469f35306SGunnar Mills     }
203569f35306SGunnar Mills 
20369ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20379ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20389ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
20399ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
20409ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
204169f35306SGunnar Mills         if (ec)
204269f35306SGunnar Mills         {
2043b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2044ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
204569f35306SGunnar Mills             return;
204669f35306SGunnar Mills         }
20479ae226faSGeorge Liu     });
204869f35306SGunnar Mills }
204969f35306SGunnar Mills 
20508d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
20518d69c668SEd Tanous {
20528d69c668SEd Tanous     if (policy == "AlwaysOn")
20538d69c668SEd Tanous     {
20548d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
20558d69c668SEd Tanous     }
20568d69c668SEd Tanous     if (policy == "AlwaysOff")
20578d69c668SEd Tanous     {
20588d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
20598d69c668SEd Tanous     }
20608d69c668SEd Tanous     if (policy == "LastState")
20618d69c668SEd Tanous     {
20628d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
20638d69c668SEd Tanous     }
20648d69c668SEd Tanous     return "";
20658d69c668SEd Tanous }
20668d69c668SEd Tanous 
206769f35306SGunnar Mills /**
2068c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
2069c6a620f2SGeorge Liu  *
2070ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2071c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
2072c6a620f2SGeorge Liu  *
2073c6a620f2SGeorge Liu  * @return None.
2074c6a620f2SGeorge Liu  */
20758d1b46d7Szhanghch05 inline void
2076ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20778d69c668SEd Tanous                           std::string_view policy)
2078c6a620f2SGeorge Liu {
207962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2080c6a620f2SGeorge Liu 
20818d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2082c6a620f2SGeorge Liu 
20838d69c668SEd Tanous     if (powerRestorePolicy.empty())
2084c6a620f2SGeorge Liu     {
2085ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20864e69c904SGunnar Mills                                          "PowerRestorePolicy");
2087c6a620f2SGeorge Liu         return;
2088c6a620f2SGeorge Liu     }
2089c6a620f2SGeorge Liu 
20909ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20919ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20929ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20939ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20949ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2095c6a620f2SGeorge Liu         if (ec)
2096c6a620f2SGeorge Liu         {
2097b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2098ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2099c6a620f2SGeorge Liu             return;
2100c6a620f2SGeorge Liu         }
21019ae226faSGeorge Liu     });
2102c6a620f2SGeorge Liu }
2103c6a620f2SGeorge Liu 
2104a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2105a6349918SAppaRao Puli /**
2106a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2107a6349918SAppaRao Puli  *
2108ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2109a6349918SAppaRao Puli  *
2110a6349918SAppaRao Puli  * @return None.
2111a6349918SAppaRao Puli  */
2112ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2113a6349918SAppaRao Puli {
211462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2115bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2116bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2117bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2118ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2119b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2120b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2121ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2122ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
212350626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
212450626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
212550626f4fSJames Feist 
2126a6349918SAppaRao Puli         if (ec)
2127a6349918SAppaRao Puli         {
212862598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2129b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2130b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2131a6349918SAppaRao Puli             return;
2132a6349918SAppaRao Puli         }
2133a6349918SAppaRao Puli 
2134a6349918SAppaRao Puli         const bool* provState = nullptr;
2135a6349918SAppaRao Puli         const bool* lockState = nullptr;
2136bc1d29deSKrzysztof Grobelny 
2137bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
21380d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
21390d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2140bc1d29deSKrzysztof Grobelny 
2141bc1d29deSKrzysztof Grobelny         if (!success)
2142a6349918SAppaRao Puli         {
2143ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2144bc1d29deSKrzysztof Grobelny             return;
2145a6349918SAppaRao Puli         }
2146a6349918SAppaRao Puli 
2147a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2148a6349918SAppaRao Puli         {
214962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2150ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2151a6349918SAppaRao Puli             return;
2152a6349918SAppaRao Puli         }
2153a6349918SAppaRao Puli 
2154a6349918SAppaRao Puli         if (*provState == true)
2155a6349918SAppaRao Puli         {
2156a6349918SAppaRao Puli             if (*lockState == true)
2157a6349918SAppaRao Puli             {
2158a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2159a6349918SAppaRao Puli             }
2160a6349918SAppaRao Puli             else
2161a6349918SAppaRao Puli             {
2162a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2163a6349918SAppaRao Puli             }
2164a6349918SAppaRao Puli         }
2165a6349918SAppaRao Puli         else
2166a6349918SAppaRao Puli         {
2167a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2168a6349918SAppaRao Puli         }
2169bc1d29deSKrzysztof Grobelny     });
2170a6349918SAppaRao Puli }
2171a6349918SAppaRao Puli #endif
2172a6349918SAppaRao Puli 
2173491d8ee7SSantosh Puranik /**
21746b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
21753a2d0424SChris Cain  *
21766b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
21773a2d0424SChris Cain  *
21786b9ac4f2SChris Cain  * @return PowerMode enum
21793a2d0424SChris Cain  */
21806b9ac4f2SChris Cain inline computer_system::PowerMode
21816b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
21823a2d0424SChris Cain {
2183b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2184b6655101SChris Cain 
21856b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21863a2d0424SChris Cain     {
21876b9ac4f2SChris Cain         return PowerMode::Static;
21883a2d0424SChris Cain     }
21896b9ac4f2SChris Cain     if (modeString ==
21900fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21913a2d0424SChris Cain     {
21926b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
21933a2d0424SChris Cain     }
21946b9ac4f2SChris Cain     if (modeString ==
21950fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21963a2d0424SChris Cain     {
21976b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2198b6655101SChris Cain     }
21996b9ac4f2SChris Cain     if (modeString ==
2200b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2201b6655101SChris Cain     {
22026b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2203b6655101SChris Cain     }
22046b9ac4f2SChris Cain     if (modeString ==
2205b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2206b6655101SChris Cain     {
22076b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2208b6655101SChris Cain     }
22096b9ac4f2SChris Cain     if (modeString ==
2210b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2211b6655101SChris Cain     {
22126b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
22133a2d0424SChris Cain     }
22146b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
22153a2d0424SChris Cain     {
22166b9ac4f2SChris Cain         return PowerMode::OEM;
22176b9ac4f2SChris Cain     }
22186b9ac4f2SChris Cain     // Any other values would be invalid
22196b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
22206b9ac4f2SChris Cain     return PowerMode::Invalid;
22216b9ac4f2SChris Cain }
22226b9ac4f2SChris Cain 
22236b9ac4f2SChris Cain inline void
22246b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22256b9ac4f2SChris Cain                       const boost::system::error_code& ec,
22266b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
22276b9ac4f2SChris Cain {
22286b9ac4f2SChris Cain     if (ec)
22296b9ac4f2SChris Cain     {
22306b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
22316b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
22326b9ac4f2SChris Cain         return;
22336b9ac4f2SChris Cain     }
22346b9ac4f2SChris Cain 
22356b9ac4f2SChris Cain     std::string powerMode;
22366b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
22376b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
22386b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
22396b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
22406b9ac4f2SChris Cain 
22416b9ac4f2SChris Cain     if (!success)
22426b9ac4f2SChris Cain     {
22436b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
22446b9ac4f2SChris Cain         return;
22456b9ac4f2SChris Cain     }
22466b9ac4f2SChris Cain 
22476b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
22486b9ac4f2SChris Cain     if (allowedModes == nullptr)
22496b9ac4f2SChris Cain     {
22506b9ac4f2SChris Cain         modeList.emplace_back("Static");
22516b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
22526b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
22533a2d0424SChris Cain     }
22543a2d0424SChris Cain     else
22553a2d0424SChris Cain     {
22566b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
22576b9ac4f2SChris Cain         {
22586b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
22596b9ac4f2SChris Cain                 translatePowerModeString(aMode);
22606b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
22616b9ac4f2SChris Cain             {
2262ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
22636b9ac4f2SChris Cain                 continue;
22646b9ac4f2SChris Cain             }
22656b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
22663a2d0424SChris Cain         }
22673a2d0424SChris Cain     }
22686b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
22693a2d0424SChris Cain 
22706b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
22716b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
22726b9ac4f2SChris Cain         translatePowerModeString(powerMode);
22736b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
22746b9ac4f2SChris Cain     {
22756b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
22766b9ac4f2SChris Cain         return;
22776b9ac4f2SChris Cain     }
22786b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
22796b9ac4f2SChris Cain }
22803a2d0424SChris Cain /**
22813a2d0424SChris Cain  * @brief Retrieves system power mode
22823a2d0424SChris Cain  *
2283ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22843a2d0424SChris Cain  *
22853a2d0424SChris Cain  * @return None.
22863a2d0424SChris Cain  */
2287ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22883a2d0424SChris Cain {
228962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22903a2d0424SChris Cain 
22913a2d0424SChris Cain     // Get Power Mode object path:
2292e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2293e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2294e99073f5SGeorge Liu     dbus::utility::getSubTree(
2295e99073f5SGeorge Liu         "/", 0, interfaces,
2296ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2297b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22983a2d0424SChris Cain         if (ec)
22993a2d0424SChris Cain         {
230062598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
230162598e31SEd Tanous                              ec);
23023a2d0424SChris Cain             // This is an optional D-Bus object so just return if
23033a2d0424SChris Cain             // error occurs
23043a2d0424SChris Cain             return;
23053a2d0424SChris Cain         }
23063a2d0424SChris Cain         if (subtree.empty())
23073a2d0424SChris Cain         {
23083a2d0424SChris Cain             // As noted above, this is an optional interface so just return
23093a2d0424SChris Cain             // if there is no instance found
23103a2d0424SChris Cain             return;
23113a2d0424SChris Cain         }
23123a2d0424SChris Cain         if (subtree.size() > 1)
23133a2d0424SChris Cain         {
23143a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23153a2d0424SChris Cain             // error
231662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
231762598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
231862598e31SEd Tanous                 subtree.size());
2319ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23203a2d0424SChris Cain             return;
23213a2d0424SChris Cain         }
23223a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23233a2d0424SChris Cain         {
232462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2325ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23263a2d0424SChris Cain             return;
23273a2d0424SChris Cain         }
23283a2d0424SChris Cain         const std::string& path = subtree[0].first;
23293a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23303a2d0424SChris Cain         if (service.empty())
23313a2d0424SChris Cain         {
233262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2333ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23343a2d0424SChris Cain             return;
23353a2d0424SChris Cain         }
23366b9ac4f2SChris Cain 
23376b9ac4f2SChris Cain         // Valid Power Mode object found, now read the mode properties
23386b9ac4f2SChris Cain         sdbusplus::asio::getAllProperties(
23391e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
23406b9ac4f2SChris Cain             "xyz.openbmc_project.Control.Power.Mode",
2341ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
23426b9ac4f2SChris Cain                         const dbus::utility::DBusPropertiesMap& properties) {
23436b9ac4f2SChris Cain             afterGetPowerMode(asyncResp, ec2, properties);
23441e1e598dSJonathan Doman         });
2345e99073f5SGeorge Liu     });
23463a2d0424SChris Cain }
23473a2d0424SChris Cain 
23483a2d0424SChris Cain /**
23493a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
23503a2d0424SChris Cain  * name associated with that string
23513a2d0424SChris Cain  *
2352ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2353b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
23543a2d0424SChris Cain  *
23553a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
23563a2d0424SChris Cain  */
23573a2d0424SChris Cain inline std::string
2358ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2359b6655101SChris Cain                       const nlohmann::json& modeValue)
23603a2d0424SChris Cain {
2361b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
23623a2d0424SChris Cain     std::string mode;
23633a2d0424SChris Cain 
2364b6655101SChris Cain     if (modeValue == PowerMode::Static)
23653a2d0424SChris Cain     {
23663a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
23673a2d0424SChris Cain     }
2368b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
23693a2d0424SChris Cain     {
23700fda0f12SGeorge Liu         mode =
23710fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
23723a2d0424SChris Cain     }
2373b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
23743a2d0424SChris Cain     {
23753a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
23763a2d0424SChris Cain     }
2377b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2378b6655101SChris Cain     {
2379b6655101SChris Cain         mode =
2380b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2381b6655101SChris Cain     }
2382b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2383b6655101SChris Cain     {
2384b6655101SChris Cain         mode =
2385b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2386b6655101SChris Cain     }
2387b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2388b6655101SChris Cain     {
2389b6655101SChris Cain         mode =
2390b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2391b6655101SChris Cain     }
23923a2d0424SChris Cain     else
23933a2d0424SChris Cain     {
2394b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2395ac106bf6SEd Tanous                                          "PowerMode");
23963a2d0424SChris Cain     }
23973a2d0424SChris Cain     return mode;
23983a2d0424SChris Cain }
23993a2d0424SChris Cain 
24003a2d0424SChris Cain /**
24013a2d0424SChris Cain  * @brief Sets system power mode.
24023a2d0424SChris Cain  *
2403ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
24043a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
24053a2d0424SChris Cain  *
24063a2d0424SChris Cain  * @return None.
24073a2d0424SChris Cain  */
2408ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24093a2d0424SChris Cain                          const std::string& pmode)
24103a2d0424SChris Cain {
241162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
24123a2d0424SChris Cain 
2413ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
24143a2d0424SChris Cain     if (powerMode.empty())
24153a2d0424SChris Cain     {
24163a2d0424SChris Cain         return;
24173a2d0424SChris Cain     }
24183a2d0424SChris Cain 
24193a2d0424SChris Cain     // Get Power Mode object path:
2420e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2421e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2422e99073f5SGeorge Liu     dbus::utility::getSubTree(
2423e99073f5SGeorge Liu         "/", 0, interfaces,
2424ac106bf6SEd Tanous         [asyncResp,
2425e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2426b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
24273a2d0424SChris Cain         if (ec)
24283a2d0424SChris Cain         {
2429b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
243062598e31SEd Tanous                              ec);
24313a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2432ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24333a2d0424SChris Cain             return;
24343a2d0424SChris Cain         }
24353a2d0424SChris Cain         if (subtree.empty())
24363a2d0424SChris Cain         {
24373a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2438ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
24393a2d0424SChris Cain                                        "PowerMode");
24403a2d0424SChris Cain             return;
24413a2d0424SChris Cain         }
24423a2d0424SChris Cain         if (subtree.size() > 1)
24433a2d0424SChris Cain         {
24443a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
24453a2d0424SChris Cain             // error
244662598e31SEd Tanous             BMCWEB_LOG_DEBUG(
244762598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
244862598e31SEd Tanous                 subtree.size());
2449ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24503a2d0424SChris Cain             return;
24513a2d0424SChris Cain         }
24523a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
24533a2d0424SChris Cain         {
245462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2455ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24563a2d0424SChris Cain             return;
24573a2d0424SChris Cain         }
24583a2d0424SChris Cain         const std::string& path = subtree[0].first;
24593a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
24603a2d0424SChris Cain         if (service.empty())
24613a2d0424SChris Cain         {
246262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2463ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
24643a2d0424SChris Cain             return;
24653a2d0424SChris Cain         }
24663a2d0424SChris Cain 
246762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
24683a2d0424SChris Cain 
24693a2d0424SChris Cain         // Set the Power Mode property
24709ae226faSGeorge Liu         sdbusplus::asio::setProperty(
24719ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
24729ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2473ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
24748a592810SEd Tanous             if (ec2)
24753a2d0424SChris Cain             {
2476b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2477ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24783a2d0424SChris Cain                 return;
24793a2d0424SChris Cain             }
24809ae226faSGeorge Liu         });
2481e99073f5SGeorge Liu     });
24823a2d0424SChris Cain }
24833a2d0424SChris Cain 
24843a2d0424SChris Cain /**
248551709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
248651709ffdSYong Li  *
248751709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
248851709ffdSYong Li  *
248951709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
249051709ffdSYong Li  * translation cannot be done, returns an empty string.
249151709ffdSYong Li  */
249223a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
249351709ffdSYong Li {
249451709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
249551709ffdSYong Li     {
249651709ffdSYong Li         return "None";
249751709ffdSYong Li     }
24983174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
249951709ffdSYong Li     {
250051709ffdSYong Li         return "ResetSystem";
250151709ffdSYong Li     }
25023174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
250351709ffdSYong Li     {
250451709ffdSYong Li         return "PowerDown";
250551709ffdSYong Li     }
25063174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
250751709ffdSYong Li     {
250851709ffdSYong Li         return "PowerCycle";
250951709ffdSYong Li     }
251051709ffdSYong Li 
251151709ffdSYong Li     return "";
251251709ffdSYong Li }
251351709ffdSYong Li 
251451709ffdSYong Li /**
2515c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2516c45f0082SYong Li  *
2517c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2518c45f0082SYong Li  *
2519c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2520c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2521c45f0082SYong Li  */
2522c45f0082SYong Li 
252323a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2524c45f0082SYong Li {
2525c45f0082SYong Li     if (rfAction == "None")
2526c45f0082SYong Li     {
2527c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2528c45f0082SYong Li     }
25293174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2530c45f0082SYong Li     {
2531c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2532c45f0082SYong Li     }
25333174e4dfSEd Tanous     if (rfAction == "PowerDown")
2534c45f0082SYong Li     {
2535c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2536c45f0082SYong Li     }
25373174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2538c45f0082SYong Li     {
2539c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2540c45f0082SYong Li     }
2541c45f0082SYong Li 
2542c45f0082SYong Li     return "";
2543c45f0082SYong Li }
2544c45f0082SYong Li 
2545c45f0082SYong Li /**
254651709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
254751709ffdSYong Li  *
2548ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
254951709ffdSYong Li  *
255051709ffdSYong Li  * @return None.
255151709ffdSYong Li  */
25528d1b46d7Szhanghch05 inline void
2553ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
255451709ffdSYong Li {
255562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2556bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2557bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2558bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2559bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2560ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2561b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
256251709ffdSYong Li         if (ec)
256351709ffdSYong Li         {
256451709ffdSYong Li             // watchdog service is stopped
256562598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
256651709ffdSYong Li             return;
256751709ffdSYong Li         }
256851709ffdSYong Li 
256962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
257051709ffdSYong Li 
257151709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2572ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
257351709ffdSYong Li 
257451709ffdSYong Li         // watchdog service is running/enabled
257551709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
257651709ffdSYong Li 
2577bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2578bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
257951709ffdSYong Li 
2580bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2581bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2582bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2583bc1d29deSKrzysztof Grobelny 
2584bc1d29deSKrzysztof Grobelny         if (!success)
258551709ffdSYong Li         {
2586ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2587601af5edSChicago Duan             return;
258851709ffdSYong Li         }
258951709ffdSYong Li 
2590bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
259151709ffdSYong Li         {
2592bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
259351709ffdSYong Li         }
259451709ffdSYong Li 
2595bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2596bc1d29deSKrzysztof Grobelny         {
2597bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
259851709ffdSYong Li             if (action.empty())
259951709ffdSYong Li             {
2600ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2601601af5edSChicago Duan                 return;
260251709ffdSYong Li             }
260351709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
260451709ffdSYong Li         }
2605bc1d29deSKrzysztof Grobelny     });
260651709ffdSYong Li }
260751709ffdSYong Li 
260851709ffdSYong Li /**
2609c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2610c45f0082SYong Li  *
2611ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2612c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2613c45f0082SYong Li  *                       RF request.
2614c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2615c45f0082SYong Li  *
2616c45f0082SYong Li  * @return None.
2617c45f0082SYong Li  */
2618ac106bf6SEd Tanous inline void
2619ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2620c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2621c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2622c45f0082SYong Li {
262362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2624c45f0082SYong Li 
2625c45f0082SYong Li     if (wdtTimeOutAction)
2626c45f0082SYong Li     {
2627c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2628c45f0082SYong Li         // check if TimeOut Action is Valid
2629c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2630c45f0082SYong Li         {
263162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
263262598e31SEd Tanous                              *wdtTimeOutAction);
2633ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2634c45f0082SYong Li                                              "TimeoutAction");
2635c45f0082SYong Li             return;
2636c45f0082SYong Li         }
2637c45f0082SYong Li 
26389ae226faSGeorge Liu         sdbusplus::asio::setProperty(
26399ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26409ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26419ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
26429ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2643c45f0082SYong Li             if (ec)
2644c45f0082SYong Li             {
2645b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2646ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2647c45f0082SYong Li                 return;
2648c45f0082SYong Li             }
26499ae226faSGeorge Liu         });
2650c45f0082SYong Li     }
2651c45f0082SYong Li 
2652c45f0082SYong Li     if (wdtEnable)
2653c45f0082SYong Li     {
26549ae226faSGeorge Liu         sdbusplus::asio::setProperty(
26559ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
26569ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
26579ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2658ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2659c45f0082SYong Li             if (ec)
2660c45f0082SYong Li             {
2661b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2662ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2663c45f0082SYong Li                 return;
2664c45f0082SYong Li             }
26659ae226faSGeorge Liu         });
2666c45f0082SYong Li     }
2667c45f0082SYong Li }
2668c45f0082SYong Li 
266937bbf98cSChris Cain /**
267037bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
267137bbf98cSChris Cain  *
2672ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
267337bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
267437bbf98cSChris Cain  *
267537bbf98cSChris Cain  * @return true if successful
267637bbf98cSChris Cain  */
26771e5b7c88SJiaqing Zhao inline bool
2678ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26791e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
268037bbf98cSChris Cain {
2681bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2682bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2683bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2684bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2685bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2686bc1d29deSKrzysztof Grobelny 
2687bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2688bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26892661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26902661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26912661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2692bc1d29deSKrzysztof Grobelny 
2693bc1d29deSKrzysztof Grobelny     if (!success)
269437bbf98cSChris Cain     {
269537bbf98cSChris Cain         return false;
269637bbf98cSChris Cain     }
2697bc1d29deSKrzysztof Grobelny 
2698bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
269937bbf98cSChris Cain     {
2700ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
270137bbf98cSChris Cain     }
2702bc1d29deSKrzysztof Grobelny 
2703bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
270437bbf98cSChris Cain     {
2705ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2706bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
270737bbf98cSChris Cain     }
2708bc1d29deSKrzysztof Grobelny 
2709bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2710bc1d29deSKrzysztof Grobelny     {
2711bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2712ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
271337bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
271437bbf98cSChris Cain                 .count();
271537bbf98cSChris Cain     }
2716bc1d29deSKrzysztof Grobelny 
2717bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
271837bbf98cSChris Cain     {
2719ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2720bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
272137bbf98cSChris Cain     }
2722bc1d29deSKrzysztof Grobelny 
2723bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
272437bbf98cSChris Cain     {
2725bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2726ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
272737bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
272837bbf98cSChris Cain                 .count();
272937bbf98cSChris Cain     }
273037bbf98cSChris Cain 
273137bbf98cSChris Cain     return true;
273237bbf98cSChris Cain }
273337bbf98cSChris Cain 
273437bbf98cSChris Cain /**
273537bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
273637bbf98cSChris Cain  *
2737ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
273837bbf98cSChris Cain  *
273937bbf98cSChris Cain  * @return None.
274037bbf98cSChris Cain  */
2741ac106bf6SEd Tanous inline void
2742ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
274337bbf98cSChris Cain {
274462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
274537bbf98cSChris Cain 
274637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2747e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2748e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2749e99073f5SGeorge Liu     dbus::utility::getSubTree(
2750e99073f5SGeorge Liu         "/", 0, interfaces,
2751ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2752b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
275337bbf98cSChris Cain         if (ec)
275437bbf98cSChris Cain         {
2755b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
275662598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
275762598e31SEd Tanous                 ec);
2758ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
275937bbf98cSChris Cain             return;
276037bbf98cSChris Cain         }
276137bbf98cSChris Cain         if (subtree.empty())
276237bbf98cSChris Cain         {
276337bbf98cSChris Cain             // This is an optional interface so just return
276437bbf98cSChris Cain             // if there is no instance found
276562598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
276637bbf98cSChris Cain             return;
276737bbf98cSChris Cain         }
276837bbf98cSChris Cain         if (subtree.size() > 1)
276937bbf98cSChris Cain         {
277037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
277137bbf98cSChris Cain             // is an error
277262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
277362598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
277462598e31SEd Tanous                              subtree.size());
2775ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277637bbf98cSChris Cain             return;
277737bbf98cSChris Cain         }
277837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
277937bbf98cSChris Cain         {
278062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2781ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
278237bbf98cSChris Cain             return;
278337bbf98cSChris Cain         }
278437bbf98cSChris Cain         const std::string& path = subtree[0].first;
278537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
278637bbf98cSChris Cain         if (service.empty())
278737bbf98cSChris Cain         {
278862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2789ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
279037bbf98cSChris Cain             return;
279137bbf98cSChris Cain         }
279237bbf98cSChris Cain 
279337bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2794bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2795bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2796bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2797ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27981e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27998a592810SEd Tanous             if (ec2)
280037bbf98cSChris Cain             {
280162598e31SEd Tanous                 BMCWEB_LOG_ERROR(
280262598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2803ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
280437bbf98cSChris Cain                 return;
280537bbf98cSChris Cain             }
280637bbf98cSChris Cain 
2807ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
280837bbf98cSChris Cain             {
2809ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
281037bbf98cSChris Cain                 return;
281137bbf98cSChris Cain             }
2812bc1d29deSKrzysztof Grobelny         });
2813e99073f5SGeorge Liu     });
281437bbf98cSChris Cain 
281562598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
281637bbf98cSChris Cain }
281737bbf98cSChris Cain 
281837bbf98cSChris Cain /**
281937bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
282037bbf98cSChris Cain  *
2821ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
282237bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
282337bbf98cSChris Cain  *                       RF request.
282437bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
282537bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
282637bbf98cSChris Cain  * before entering idle state.
282737bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
282837bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
282937bbf98cSChris Cain  * before exiting idle state
283037bbf98cSChris Cain  *
283137bbf98cSChris Cain  * @return None.
283237bbf98cSChris Cain  */
2833ac106bf6SEd Tanous inline void
2834ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
283537bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
283637bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
283737bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
283837bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
283937bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
284037bbf98cSChris Cain {
284162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
284237bbf98cSChris Cain 
284337bbf98cSChris Cain     // Get IdlePowerSaver object path:
2844e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2845e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2846e99073f5SGeorge Liu     dbus::utility::getSubTree(
2847e99073f5SGeorge Liu         "/", 0, interfaces,
2848ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2849e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2850b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
285137bbf98cSChris Cain         if (ec)
285237bbf98cSChris Cain         {
2853b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
285462598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
285562598e31SEd Tanous                 ec);
2856ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
285737bbf98cSChris Cain             return;
285837bbf98cSChris Cain         }
285937bbf98cSChris Cain         if (subtree.empty())
286037bbf98cSChris Cain         {
286137bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2862ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
286337bbf98cSChris Cain                                        "IdlePowerSaver");
286437bbf98cSChris Cain             return;
286537bbf98cSChris Cain         }
286637bbf98cSChris Cain         if (subtree.size() > 1)
286737bbf98cSChris Cain         {
286837bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
286937bbf98cSChris Cain             // is an error
287062598e31SEd Tanous             BMCWEB_LOG_DEBUG(
287162598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
287262598e31SEd Tanous                 subtree.size());
2873ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
287437bbf98cSChris Cain             return;
287537bbf98cSChris Cain         }
287637bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
287737bbf98cSChris Cain         {
287862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2879ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
288037bbf98cSChris Cain             return;
288137bbf98cSChris Cain         }
288237bbf98cSChris Cain         const std::string& path = subtree[0].first;
288337bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
288437bbf98cSChris Cain         if (service.empty())
288537bbf98cSChris Cain         {
288662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2887ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
288837bbf98cSChris Cain             return;
288937bbf98cSChris Cain         }
289037bbf98cSChris Cain 
289137bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
289237bbf98cSChris Cain         // need to be updated
289337bbf98cSChris Cain 
289437bbf98cSChris Cain         if (ipsEnable)
289537bbf98cSChris Cain         {
28969ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28979ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28989ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28999ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
29008a592810SEd Tanous                 if (ec2)
290137bbf98cSChris Cain                 {
2902b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2903ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
290437bbf98cSChris Cain                     return;
290537bbf98cSChris Cain                 }
29069ae226faSGeorge Liu             });
290737bbf98cSChris Cain         }
290837bbf98cSChris Cain         if (ipsEnterUtil)
290937bbf98cSChris Cain         {
29109ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29119ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29129ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29139ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2914ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29158a592810SEd Tanous                 if (ec2)
291637bbf98cSChris Cain                 {
2917b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2918ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
291937bbf98cSChris Cain                     return;
292037bbf98cSChris Cain                 }
29219ae226faSGeorge Liu             });
292237bbf98cSChris Cain         }
292337bbf98cSChris Cain         if (ipsEnterTime)
292437bbf98cSChris Cain         {
292537bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
292637bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
29279ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29289ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29299ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29309ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2931ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29328a592810SEd Tanous                 if (ec2)
293337bbf98cSChris Cain                 {
2934b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2935ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
293637bbf98cSChris Cain                     return;
293737bbf98cSChris Cain                 }
29389ae226faSGeorge Liu             });
293937bbf98cSChris Cain         }
294037bbf98cSChris Cain         if (ipsExitUtil)
294137bbf98cSChris Cain         {
29429ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29439ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29449ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29459ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2946ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29478a592810SEd Tanous                 if (ec2)
294837bbf98cSChris Cain                 {
2949b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2950ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
295137bbf98cSChris Cain                     return;
295237bbf98cSChris Cain                 }
29539ae226faSGeorge Liu             });
295437bbf98cSChris Cain         }
295537bbf98cSChris Cain         if (ipsExitTime)
295637bbf98cSChris Cain         {
295737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
295837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
29599ae226faSGeorge Liu             sdbusplus::asio::setProperty(
29609ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
29619ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
29629ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2963ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
29648a592810SEd Tanous                 if (ec2)
296537bbf98cSChris Cain                 {
2966b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2967ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
296837bbf98cSChris Cain                     return;
296937bbf98cSChris Cain                 }
29709ae226faSGeorge Liu             });
297137bbf98cSChris Cain         }
2972e99073f5SGeorge Liu     });
297337bbf98cSChris Cain 
297462598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
297537bbf98cSChris Cain }
297637bbf98cSChris Cain 
2977c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2978dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2979dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2980dd60b9edSEd Tanous {
2981dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2982dd60b9edSEd Tanous     {
2983dd60b9edSEd Tanous         return;
2984dd60b9edSEd Tanous     }
2985dd60b9edSEd Tanous     asyncResp->res.addHeader(
2986dd60b9edSEd Tanous         boost::beast::http::field::link,
2987dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2988dd60b9edSEd Tanous }
2989dd60b9edSEd Tanous 
2990c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2991c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2992c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29931abe55efSEd Tanous {
29943ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2995f4c99e70SEd Tanous     {
2996f4c99e70SEd Tanous         return;
2997f4c99e70SEd Tanous     }
2998dd60b9edSEd Tanous 
2999dd60b9edSEd Tanous     asyncResp->res.addHeader(
3000dd60b9edSEd Tanous         boost::beast::http::field::link,
3001dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
30028d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
30030f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
30048d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
30058d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
3006462023adSSunitha Harish 
30077f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
30087f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
30097f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30107f3e84a1SEd Tanous     {
30117f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
30127f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30137f3e84a1SEd Tanous         return;
30147f3e84a1SEd Tanous     }
30157f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
30167f3e84a1SEd Tanous     nlohmann::json::object_t system;
30177f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
30187f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
30191e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
3020002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
30211e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
3022002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
30235e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
30241e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
30257f3e84a1SEd Tanous         if (ec2)
3026462023adSSunitha Harish         {
30277f3e84a1SEd Tanous             return;
30287f3e84a1SEd Tanous         }
30297f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
30307f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
30317f3e84a1SEd Tanous         {
303262598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
30337f3e84a1SEd Tanous             return;
30347f3e84a1SEd Tanous         }
30357f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
30367f3e84a1SEd Tanous         if (count == nullptr)
30377f3e84a1SEd Tanous         {
303862598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
30397f3e84a1SEd Tanous             return;
30407f3e84a1SEd Tanous         }
30417f3e84a1SEd Tanous         *count = *count + 1;
304262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
30437f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
30441476687dSEd Tanous         nlohmann::json::object_t hypervisor;
3045002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
30467f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
30471e1e598dSJonathan Doman     });
3048c1e219d5SEd Tanous }
3049c1e219d5SEd Tanous 
3050c1e219d5SEd Tanous /**
30517e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
30527e860f15SJohn Edward Broadbent  */
30534f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
30547e860f15SJohn Edward Broadbent {
305589492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
305689492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
305789492a15SPatrick Williams     constexpr const char* interfaceName =
30587e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
305989492a15SPatrick Williams     constexpr const char* method = "NMI";
30607e860f15SJohn Edward Broadbent 
30617e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
30625e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
30637e860f15SJohn Edward Broadbent         if (ec)
30647e860f15SJohn Edward Broadbent         {
306562598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
30667e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
30677e860f15SJohn Edward Broadbent             return;
30687e860f15SJohn Edward Broadbent         }
30697e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
30707e860f15SJohn Edward Broadbent     },
30717e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
30727e860f15SJohn Edward Broadbent }
3073c5b2abe0SLewanczyk, Dawid 
3074c5b2abe0SLewanczyk, Dawid /**
3075fc903b3dSAndrew Geissler  * Handle error responses from d-bus for system power requests
3076fc903b3dSAndrew Geissler  */
3077fc903b3dSAndrew Geissler inline void handleSystemActionResetError(const boost::system::error_code& ec,
3078fc903b3dSAndrew Geissler                                          const sdbusplus::message_t& eMsg,
3079fc903b3dSAndrew Geissler                                          std::string_view resetType,
3080fc903b3dSAndrew Geissler                                          crow::Response& res)
3081fc903b3dSAndrew Geissler {
3082fc903b3dSAndrew Geissler     if (ec.value() == boost::asio::error::invalid_argument)
3083fc903b3dSAndrew Geissler     {
3084fc903b3dSAndrew Geissler         messages::actionParameterNotSupported(res, resetType, "Reset");
3085fc903b3dSAndrew Geissler         return;
3086fc903b3dSAndrew Geissler     }
3087fc903b3dSAndrew Geissler 
3088fc903b3dSAndrew Geissler     if (eMsg.get_error() == nullptr)
3089fc903b3dSAndrew Geissler     {
309062598e31SEd Tanous         BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
3091fc903b3dSAndrew Geissler         messages::internalError(res);
3092fc903b3dSAndrew Geissler         return;
3093fc903b3dSAndrew Geissler     }
3094fc903b3dSAndrew Geissler     std::string_view errorMessage = eMsg.get_error()->name;
3095fc903b3dSAndrew Geissler 
3096fc903b3dSAndrew Geissler     // If operation failed due to BMC not being in Ready state, tell
3097fc903b3dSAndrew Geissler     // user to retry in a bit
3098fc903b3dSAndrew Geissler     if ((errorMessage ==
3099fc903b3dSAndrew Geissler          std::string_view(
3100fc903b3dSAndrew Geissler              "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3101fc903b3dSAndrew Geissler         (errorMessage ==
3102fc903b3dSAndrew Geissler          std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3103fc903b3dSAndrew Geissler     {
310462598e31SEd Tanous         BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
3105fc903b3dSAndrew Geissler         messages::serviceTemporarilyUnavailable(res, "10");
3106fc903b3dSAndrew Geissler         return;
3107fc903b3dSAndrew Geissler     }
3108fc903b3dSAndrew Geissler 
310962598e31SEd Tanous     BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
311062598e31SEd Tanous                      errorMessage);
3111fc903b3dSAndrew Geissler     messages::internalError(res);
3112fc903b3dSAndrew Geissler }
3113fc903b3dSAndrew Geissler 
3114c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
3115c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
31167f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3117c1e219d5SEd Tanous     const std::string& systemName)
3118c1e219d5SEd Tanous {
31193ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
312045ca1b86SEd Tanous     {
312145ca1b86SEd Tanous         return;
312245ca1b86SEd Tanous     }
3123c1e219d5SEd Tanous     if (systemName != "system")
3124c1e219d5SEd Tanous     {
3125c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3126c1e219d5SEd Tanous                                    systemName);
3127c1e219d5SEd Tanous         return;
3128c1e219d5SEd Tanous     }
31297f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
31307f3e84a1SEd Tanous     {
31317f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31327f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3133c1e219d5SEd Tanous                                    systemName);
31347f3e84a1SEd Tanous         return;
31357f3e84a1SEd Tanous     }
31369712f8acSEd Tanous     std::string resetType;
3137c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3138cc340dd9SEd Tanous     {
3139cc340dd9SEd Tanous         return;
3140cc340dd9SEd Tanous     }
3141cc340dd9SEd Tanous 
3142d22c8396SJason M. Bills     // Get the command and host vs. chassis
3143cc340dd9SEd Tanous     std::string command;
3144543f4400SEd Tanous     bool hostCommand = true;
3145d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3146cc340dd9SEd Tanous     {
3147cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3148d22c8396SJason M. Bills         hostCommand = true;
3149d22c8396SJason M. Bills     }
3150d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3151d22c8396SJason M. Bills     {
3152d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3153d22c8396SJason M. Bills         hostCommand = false;
3154d22c8396SJason M. Bills     }
3155d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3156d22c8396SJason M. Bills     {
3157c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
315886a0851aSJason M. Bills         hostCommand = true;
3159cc340dd9SEd Tanous     }
31609712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3161cc340dd9SEd Tanous     {
3162cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3163d22c8396SJason M. Bills         hostCommand = true;
3164cc340dd9SEd Tanous     }
31659712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3166cc340dd9SEd Tanous     {
31670fda0f12SGeorge Liu         command =
31680fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3169d22c8396SJason M. Bills         hostCommand = true;
3170d22c8396SJason M. Bills     }
3171d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3172d22c8396SJason M. Bills     {
317386a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
317486a0851aSJason M. Bills         hostCommand = true;
3175cc340dd9SEd Tanous     }
3176bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3177bfd5b826SLakshminarayana R. Kammath     {
3178bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3179bfd5b826SLakshminarayana R. Kammath         return;
3180bfd5b826SLakshminarayana R. Kammath     }
3181cc340dd9SEd Tanous     else
3182cc340dd9SEd Tanous     {
3183c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3184cc340dd9SEd Tanous         return;
3185cc340dd9SEd Tanous     }
3186cc340dd9SEd Tanous 
3187d22c8396SJason M. Bills     if (hostCommand)
3188d22c8396SJason M. Bills     {
31899ae226faSGeorge Liu         sdbusplus::asio::setProperty(
31909ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
31919ae226faSGeorge Liu             "/xyz/openbmc_project/state/host0",
31929ae226faSGeorge Liu             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
31939ae226faSGeorge Liu             command,
3194fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3195fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3196cc340dd9SEd Tanous             if (ec)
3197cc340dd9SEd Tanous             {
3198fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3199fc903b3dSAndrew Geissler                                              asyncResp->res);
3200fc903b3dSAndrew Geissler 
3201cc340dd9SEd Tanous                 return;
3202cc340dd9SEd Tanous             }
3203f12894f8SJason M. Bills             messages::success(asyncResp->res);
32049ae226faSGeorge Liu         });
3205cc340dd9SEd Tanous     }
3206d22c8396SJason M. Bills     else
3207d22c8396SJason M. Bills     {
32089ae226faSGeorge Liu         sdbusplus::asio::setProperty(
32099ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
32109ae226faSGeorge Liu             "/xyz/openbmc_project/state/chassis0",
32119ae226faSGeorge Liu             "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
32129ae226faSGeorge Liu             command,
3213fc903b3dSAndrew Geissler             [asyncResp, resetType](const boost::system::error_code& ec,
3214fc903b3dSAndrew Geissler                                    sdbusplus::message_t& sdbusErrMsg) {
3215d22c8396SJason M. Bills             if (ec)
3216d22c8396SJason M. Bills             {
3217fc903b3dSAndrew Geissler                 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3218fc903b3dSAndrew Geissler                                              asyncResp->res);
3219d22c8396SJason M. Bills                 return;
3220d22c8396SJason M. Bills             }
3221d22c8396SJason M. Bills             messages::success(asyncResp->res);
32229ae226faSGeorge Liu         });
3223d22c8396SJason M. Bills     }
3224d22c8396SJason M. Bills }
3225cc340dd9SEd Tanous 
3226c1e219d5SEd Tanous inline void handleComputerSystemHead(
3227dd60b9edSEd Tanous     App& app, const crow::Request& req,
32287f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32297f3e84a1SEd Tanous     const std::string& /*systemName*/)
3230dd60b9edSEd Tanous {
3231dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3232dd60b9edSEd Tanous     {
3233dd60b9edSEd Tanous         return;
3234dd60b9edSEd Tanous     }
3235dd60b9edSEd Tanous 
3236dd60b9edSEd Tanous     asyncResp->res.addHeader(
3237dd60b9edSEd Tanous         boost::beast::http::field::link,
3238dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3239dd60b9edSEd Tanous }
3240dd60b9edSEd Tanous 
32415c3e9272SAbhishek Patel inline void afterPortRequest(
32425c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32435c3e9272SAbhishek Patel     const boost::system::error_code& ec,
32445c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
32455c3e9272SAbhishek Patel {
32465c3e9272SAbhishek Patel     if (ec)
32475c3e9272SAbhishek Patel     {
3248b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
32495c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
32505c3e9272SAbhishek Patel         return;
32515c3e9272SAbhishek Patel     }
32525c3e9272SAbhishek Patel     for (const auto& data : socketData)
32535c3e9272SAbhishek Patel     {
32545c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
32555c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
32565c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
32575c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
32585c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
32595c3e9272SAbhishek Patel         // need to retrieve port number for
32605c3e9272SAbhishek Patel         // obmc-console-ssh service
32615c3e9272SAbhishek Patel         if (protocolName == "SSH")
32625c3e9272SAbhishek Patel         {
32635c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
326481c4e330SEd Tanous                                           const boost::system::error_code& ec1,
32655c3e9272SAbhishek Patel                                           int portNumber) {
32665c3e9272SAbhishek Patel                 if (ec1)
32675c3e9272SAbhishek Patel                 {
3268b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
32695c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
32705c3e9272SAbhishek Patel                     return;
32715c3e9272SAbhishek Patel                 }
32725c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
32735c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
32745c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
32755c3e9272SAbhishek Patel             });
32765c3e9272SAbhishek Patel         }
32775c3e9272SAbhishek Patel     }
32785c3e9272SAbhishek Patel }
3279c1e219d5SEd Tanous 
3280c1e219d5SEd Tanous inline void
3281c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
328222d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3283c1e219d5SEd Tanous                             const std::string& systemName)
3284c1e219d5SEd Tanous {
32853ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
328645ca1b86SEd Tanous     {
328745ca1b86SEd Tanous         return;
328845ca1b86SEd Tanous     }
3289746b56f3SAsmitha Karunanithi 
32907f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32917f3e84a1SEd Tanous     {
32927f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32937f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
32947f3e84a1SEd Tanous                                    systemName);
32957f3e84a1SEd Tanous         return;
32967f3e84a1SEd Tanous     }
32977f3e84a1SEd Tanous 
3298746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3299746b56f3SAsmitha Karunanithi     {
3300746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3301746b56f3SAsmitha Karunanithi         return;
3302746b56f3SAsmitha Karunanithi     }
3303746b56f3SAsmitha Karunanithi 
330422d268cbSEd Tanous     if (systemName != "system")
330522d268cbSEd Tanous     {
330622d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
330722d268cbSEd Tanous                                    systemName);
330822d268cbSEd Tanous         return;
330922d268cbSEd Tanous     }
3310dd60b9edSEd Tanous     asyncResp->res.addHeader(
3311dd60b9edSEd Tanous         boost::beast::http::field::link,
3312dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
33138d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3314b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
33158d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
33168d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
33178d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
33188d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
33198d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
33205fd0aafbSNinad Palsule     if constexpr (bmcwebEnableProcMemStatus)
33215fd0aafbSNinad Palsule     {
33228d1b46d7Szhanghch05         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
33238d1b46d7Szhanghch05             "Disabled";
33248d1b46d7Szhanghch05         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
33258d1b46d7Szhanghch05             "Disabled";
33265fd0aafbSNinad Palsule     }
3327cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3328dfb2b408SPriyanga Ramasamy         double(0);
3329002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
333004a258f4SEd Tanous 
33311476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
33321476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
33331476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
33341476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
33351476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
33361476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
33373179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
33383179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3339029573d4SEd Tanous 
3340002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
33411476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3342c1e219d5SEd Tanous     asyncResp->res
3343c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
33441476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3345c5b2abe0SLewanczyk, Dawid 
33461476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
33471476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
33481476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
33491476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3350c4bf6374SJason M. Bills 
33511476687dSEd Tanous     nlohmann::json::array_t managedBy;
33521476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
33531476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3354002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
33551476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
33561476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
33570e8ac5e7SGunnar Mills 
33580e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3359002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3360c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
33611476687dSEd Tanous 
3362c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
33631476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3364c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
33651476687dSEd Tanous         "Press ~. to exit console";
33665c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
33675c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
33680e8ac5e7SGunnar Mills 
33690e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
33700e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3371002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3372c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3373613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3374613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
33751476687dSEd Tanous 
33760e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
337713451e39SWilly Tu 
337813451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
337913451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
338013451e39SWilly Tu     {
33817a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3382b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
33832ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3384e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3385e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3386b49ac873SJames Feist 
33877a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
33887a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
33897a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3390914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3391b49ac873SJames Feist             if (ec)
3392b49ac873SJames Feist             {
3393b49ac873SJames Feist                 // no inventory
3394b49ac873SJames Feist                 return;
3395b49ac873SJames Feist             }
3396b49ac873SJames Feist 
3397914e2d5dSEd Tanous             health->inventory = resp;
33987a1dbc48SGeorge Liu         });
3399b49ac873SJames Feist         health->populate();
340013451e39SWilly Tu     }
3401b49ac873SJames Feist 
3402002d39b4SEd Tanous     getMainChassisId(asyncResp,
3403002d39b4SEd Tanous                      [](const std::string& chassisId,
34048d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3405b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3406b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3407ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3408ef4c65b7SEd Tanous                                                    chassisId);
3409002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3410c5d03ff4SJennifer Lee     });
3411a3002228SAppaRao Puli 
341259a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
34139f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3414a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
34155bc2dc8eSJames Feist     getComputerSystem(asyncResp, health);
34166c34de48SEd Tanous     getHostState(asyncResp);
3417491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3418978b8803SAndrew Geissler     getBootProgress(asyncResp);
3419b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
342070c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
342170c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
342251709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3423c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
34249dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3425797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3426c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3427a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3428a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3429a6349918SAppaRao Puli #endif
34301981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
34313a2d0424SChris Cain     getPowerMode(asyncResp);
343237bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3433c1e219d5SEd Tanous }
3434550a6bf8SJiaqing Zhao 
3435c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3436c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
343722d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3438c1e219d5SEd Tanous     const std::string& systemName)
3439c1e219d5SEd Tanous {
34403ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
344145ca1b86SEd Tanous     {
344245ca1b86SEd Tanous         return;
344345ca1b86SEd Tanous     }
34447f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
34457f3e84a1SEd Tanous     {
34467f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
34477f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
34487f3e84a1SEd Tanous                                    systemName);
34497f3e84a1SEd Tanous         return;
34507f3e84a1SEd Tanous     }
345122d268cbSEd Tanous     if (systemName != "system")
345222d268cbSEd Tanous     {
345322d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
345422d268cbSEd Tanous                                    systemName);
345522d268cbSEd Tanous         return;
345622d268cbSEd Tanous     }
345722d268cbSEd Tanous 
3458dd60b9edSEd Tanous     asyncResp->res.addHeader(
3459dd60b9edSEd Tanous         boost::beast::http::field::link,
3460dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3461dd60b9edSEd Tanous 
34629f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3463cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
346498e386ecSGunnar Mills     std::optional<std::string> assetTag;
3465c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
34663a2d0424SChris Cain     std::optional<std::string> powerMode;
3467550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3468550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3469550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3470550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3471550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3472550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3473797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3474550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
34759dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3476550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3477550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3478550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3479550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3480550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3481550a6bf8SJiaqing Zhao 
3482550a6bf8SJiaqing Zhao     // clang-format off
348315ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3484550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3485550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
34867e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3487550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3488550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3489550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3490550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3491550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3492550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3493550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3494550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3495550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3496797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3497550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
34989dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3499550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3500550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3501550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3502550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3503550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
35046617338dSEd Tanous                 {
35056617338dSEd Tanous                     return;
35066617338dSEd Tanous                 }
3507550a6bf8SJiaqing Zhao     // clang-format on
3508491d8ee7SSantosh Puranik 
35098d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3510c45f0082SYong Li 
351198e386ecSGunnar Mills     if (assetTag)
351298e386ecSGunnar Mills     {
351398e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
351498e386ecSGunnar Mills     }
351598e386ecSGunnar Mills 
3516550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3517c45f0082SYong Li     {
3518f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3519c45f0082SYong Li     }
3520c45f0082SYong Li 
3521cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
352269f35306SGunnar Mills     {
3523002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3524491d8ee7SSantosh Puranik     }
3525550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
352669f35306SGunnar Mills     {
3527550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
352869f35306SGunnar Mills     }
3529ac7e1e0bSAli Ahmed 
3530797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3531797d5daeSCorey Hardesty     {
3532797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3533797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3534797d5daeSCorey Hardesty     }
3535797d5daeSCorey Hardesty 
3536550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3537ac7e1e0bSAli Ahmed     {
3538c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
353969f35306SGunnar Mills     }
3540265c1602SJohnathan Mantey 
35419dcfe8c1SAlbert Zhang     if (stopBootOnFault)
35429dcfe8c1SAlbert Zhang     {
35439dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
35449dcfe8c1SAlbert Zhang     }
35459dcfe8c1SAlbert Zhang 
35469f8bfa7cSGunnar Mills     if (locationIndicatorActive)
35479f8bfa7cSGunnar Mills     {
354859a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
35499f8bfa7cSGunnar Mills     }
35509f8bfa7cSGunnar Mills 
35517e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
35527e860f15SJohn Edward Broadbent     // passed
35539712f8acSEd Tanous     if (indicatorLed)
35546617338dSEd Tanous     {
3555f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3556002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3557d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3558d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
35596617338dSEd Tanous     }
3560c6a620f2SGeorge Liu 
3561c6a620f2SGeorge Liu     if (powerRestorePolicy)
3562c6a620f2SGeorge Liu     {
35634e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3564c6a620f2SGeorge Liu     }
35653a2d0424SChris Cain 
35663a2d0424SChris Cain     if (powerMode)
35673a2d0424SChris Cain     {
35683a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
35693a2d0424SChris Cain     }
357037bbf98cSChris Cain 
3571c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
357237bbf98cSChris Cain     {
3573002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3574002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
357537bbf98cSChris Cain     }
3576c1e219d5SEd Tanous }
35771cb1a9e6SAppaRao Puli 
357838c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3579dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
35807f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3581c1e219d5SEd Tanous     const std::string& /*systemName*/)
3582dd60b9edSEd Tanous {
3583dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3584dd60b9edSEd Tanous     {
3585dd60b9edSEd Tanous         return;
3586dd60b9edSEd Tanous     }
3587dd60b9edSEd Tanous     asyncResp->res.addHeader(
3588dd60b9edSEd Tanous         boost::beast::http::field::link,
3589dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3590dd60b9edSEd Tanous }
359133e1f122SAndrew Geissler 
359233e1f122SAndrew Geissler /**
359333e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
359433e1f122SAndrew Geissler  *
359533e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
359633e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
359733e1f122SAndrew Geissler  *
359833e1f122SAndrew Geissler  * @return Emplaces correpsonding Redfish translated value(s) in
359933e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
360033e1f122SAndrew Geissler  * allowableValues.
360133e1f122SAndrew Geissler  */
360233e1f122SAndrew Geissler inline void
360333e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
360433e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
360533e1f122SAndrew Geissler {
360633e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
360733e1f122SAndrew Geissler     {
360833e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
360933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
361033e1f122SAndrew Geissler     }
361133e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
361233e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
361333e1f122SAndrew Geissler     {
361433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
361533e1f122SAndrew Geissler     }
361633e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
361733e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
361833e1f122SAndrew Geissler     {
361933e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
362033e1f122SAndrew Geissler     }
362133e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
362233e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
362333e1f122SAndrew Geissler     {
362433e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
362533e1f122SAndrew Geissler     }
362633e1f122SAndrew Geissler     else
362733e1f122SAndrew Geissler     {
362833e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
362933e1f122SAndrew Geissler     }
363033e1f122SAndrew Geissler }
363133e1f122SAndrew Geissler 
363233e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
363333e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
363433e1f122SAndrew Geissler     const boost::system::error_code& ec,
363533e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
363633e1f122SAndrew Geissler {
363733e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
363833e1f122SAndrew Geissler 
363933e1f122SAndrew Geissler     // Supported on all systems currently
364033e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
364133e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
364233e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
364333e1f122SAndrew Geissler 
364433e1f122SAndrew Geissler     if (ec)
364533e1f122SAndrew Geissler     {
3646*e715d14bSEd Tanous         if ((ec.value() ==
3647*e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3648*e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
364933e1f122SAndrew Geissler         {
365033e1f122SAndrew Geissler             // Property not implemented so just return defaults
365133e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
365233e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
365333e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
365433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
365533e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
365633e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
365733e1f122SAndrew Geissler         }
365833e1f122SAndrew Geissler         else
365933e1f122SAndrew Geissler         {
366033e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
366133e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
366233e1f122SAndrew Geissler             return;
366333e1f122SAndrew Geissler         }
366433e1f122SAndrew Geissler     }
366533e1f122SAndrew Geissler     else
366633e1f122SAndrew Geissler     {
366733e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
366833e1f122SAndrew Geissler         {
366933e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
367033e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
367133e1f122SAndrew Geissler         }
367233e1f122SAndrew Geissler     }
367333e1f122SAndrew Geissler 
367433e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
367533e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
367633e1f122SAndrew Geissler     parameter["Required"] = true;
367733e1f122SAndrew Geissler     parameter["DataType"] = "String";
367833e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
367933e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
368033e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
368133e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
368233e1f122SAndrew Geissler }
368333e1f122SAndrew Geissler 
3684c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3685c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
368622d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3687c1e219d5SEd Tanous     const std::string& systemName)
3688c1e219d5SEd Tanous {
36893ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
369045ca1b86SEd Tanous     {
369145ca1b86SEd Tanous         return;
369245ca1b86SEd Tanous     }
36937f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
36947f3e84a1SEd Tanous     {
36957f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
36967f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
36977f3e84a1SEd Tanous                                    systemName);
36987f3e84a1SEd Tanous         return;
36997f3e84a1SEd Tanous     }
3700746b56f3SAsmitha Karunanithi 
3701746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3702746b56f3SAsmitha Karunanithi     {
3703746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3704746b56f3SAsmitha Karunanithi         return;
3705746b56f3SAsmitha Karunanithi     }
3706746b56f3SAsmitha Karunanithi 
370722d268cbSEd Tanous     if (systemName != "system")
370822d268cbSEd Tanous     {
370922d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
371022d268cbSEd Tanous                                    systemName);
371122d268cbSEd Tanous         return;
371222d268cbSEd Tanous     }
371322d268cbSEd Tanous 
3714dd60b9edSEd Tanous     asyncResp->res.addHeader(
3715dd60b9edSEd Tanous         boost::beast::http::field::link,
3716dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
37171476687dSEd Tanous 
37181476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
37191476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3720c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
37211476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
37221476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
37233215e700SNan Zhou 
372433e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
372533e1f122SAndrew Geissler     sdbusplus::asio::getProperty<std::vector<std::string>>(
372633e1f122SAndrew Geissler         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
372733e1f122SAndrew Geissler         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
372833e1f122SAndrew Geissler         "AllowedHostTransitions",
372933e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
373033e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
373133e1f122SAndrew Geissler         afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
373233e1f122SAndrew Geissler     });
3733c1e219d5SEd Tanous }
3734c1e219d5SEd Tanous /**
3735c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3736c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3737c1e219d5SEd Tanous  */
3738100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3739c1e219d5SEd Tanous {
3740100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3741100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3742100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3743100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3744100afe56SEd Tanous 
3745100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3746100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3747100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3748100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3749100afe56SEd Tanous 
3750100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3751100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3752100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3753100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3754100afe56SEd Tanous 
3755100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3756100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3757100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3758100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3759100afe56SEd Tanous 
3760100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3761100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3762100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3763100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3764100afe56SEd Tanous 
3765100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3766100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3767100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3768100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3769100afe56SEd Tanous 
3770c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3771c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3772c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3773c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3774c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3775c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3776c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3777c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
37781cb1a9e6SAppaRao Puli }
3779c5b2abe0SLewanczyk, Dawid } // namespace redfish
3780