xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 51bd2d8a8b9d73d4e86981c0d68056aa9e2c76b2)
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>
421e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
43fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
44bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
451214b7e7SGunnar Mills 
467a1dbc48SGeorge Liu #include <array>
4733e1f122SAndrew Geissler #include <memory>
486b9ac4f2SChris Cain #include <string>
497a1dbc48SGeorge Liu #include <string_view>
50abf2add6SEd Tanous #include <variant>
516b9ac4f2SChris Cain #include <vector>
52c5b2abe0SLewanczyk, Dawid 
531abe55efSEd Tanous namespace redfish
541abe55efSEd Tanous {
55c5b2abe0SLewanczyk, Dawid 
565c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
575c3e9272SAbhishek Patel     protocolToDBusForSystems{
585c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
595c3e9272SAbhishek Patel 
609d3ae10eSAlpana Kumari /**
619d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
629d3ae10eSAlpana Kumari  *
63ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
649d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
659d3ae10eSAlpana Kumari  *
669d3ae10eSAlpana Kumari  * @return None.
679d3ae10eSAlpana Kumari  */
688d1b46d7Szhanghch05 inline void
69ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
701e1e598dSJonathan Doman                          bool isDimmFunctional)
719d3ae10eSAlpana Kumari {
7262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
739d3ae10eSAlpana Kumari 
749d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
759d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
769d3ae10eSAlpana Kumari     // ENABLED.
7702cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
78ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
799d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
809d3ae10eSAlpana Kumari     {
81e05aec50SEd Tanous         if (isDimmFunctional)
829d3ae10eSAlpana Kumari         {
83ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
849d3ae10eSAlpana Kumari                 "Enabled";
859d3ae10eSAlpana Kumari         }
869d3ae10eSAlpana Kumari     }
879d3ae10eSAlpana Kumari }
889d3ae10eSAlpana Kumari 
8957e8c9beSAlpana Kumari /*
9057e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9157e8c9beSAlpana Kumari  *        CPU Functional State
9257e8c9beSAlpana Kumari  *
93ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9457e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9557e8c9beSAlpana Kumari  *
9657e8c9beSAlpana Kumari  * @return None.
9757e8c9beSAlpana Kumari  */
98ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
99ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
10057e8c9beSAlpana Kumari {
10162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10257e8c9beSAlpana Kumari 
10302cad96eSEd Tanous     const nlohmann::json& prevProcState =
104ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10557e8c9beSAlpana Kumari 
10657e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10757e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10857e8c9beSAlpana Kumari     // Functional.
10957e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
11057e8c9beSAlpana Kumari     {
111e05aec50SEd Tanous         if (isCpuFunctional)
11257e8c9beSAlpana Kumari         {
113ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11457e8c9beSAlpana Kumari                 "Enabled";
11557e8c9beSAlpana Kumari         }
11657e8c9beSAlpana Kumari     }
11757e8c9beSAlpana Kumari }
11857e8c9beSAlpana Kumari 
119cf0e004cSNinad Palsule /*
120cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
121cf0e004cSNinad Palsule  *
122ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
123cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
124cf0e004cSNinad Palsule  *
125cf0e004cSNinad Palsule  * @return None.
126cf0e004cSNinad Palsule  */
127cf0e004cSNinad Palsule inline void
128ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
129cf0e004cSNinad Palsule                            bool isCpuPresent)
130cf0e004cSNinad Palsule {
13162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
132cf0e004cSNinad Palsule 
133cf0e004cSNinad Palsule     if (isCpuPresent)
134cf0e004cSNinad Palsule     {
135cf0e004cSNinad Palsule         nlohmann::json& procCount =
136ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
137cf0e004cSNinad Palsule         auto* procCountPtr =
138cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
139cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
140cf0e004cSNinad Palsule         {
141cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
142cf0e004cSNinad Palsule             *procCountPtr += 1;
143cf0e004cSNinad Palsule         }
144cf0e004cSNinad Palsule     }
145cf0e004cSNinad Palsule }
146cf0e004cSNinad Palsule 
147382d6475SAli Ahmed inline void getProcessorProperties(
148ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
149382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150382d6475SAli Ahmed         properties)
15103fbed92SAli Ahmed {
15262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15303fbed92SAli Ahmed 
15403fbed92SAli Ahmed     // TODO: Get Model
15503fbed92SAli Ahmed 
156bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15703fbed92SAli Ahmed 
158bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
159bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
16003fbed92SAli Ahmed 
161bc1d29deSKrzysztof Grobelny     if (!success)
16203fbed92SAli Ahmed     {
163ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16403fbed92SAli Ahmed         return;
16503fbed92SAli Ahmed     }
16603fbed92SAli Ahmed 
167bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16803fbed92SAli Ahmed     {
169bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
170ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
171bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
172bc1d29deSKrzysztof Grobelny 
173bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
174bc1d29deSKrzysztof Grobelny         {
175bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17603fbed92SAli Ahmed         }
17703fbed92SAli Ahmed         else
17803fbed92SAli Ahmed         {
179bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
18003fbed92SAli Ahmed         }
18103fbed92SAli Ahmed     }
18203fbed92SAli Ahmed }
18303fbed92SAli Ahmed 
18403fbed92SAli Ahmed /*
18503fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18603fbed92SAli Ahmed  *
187ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18803fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18903fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
19003fbed92SAli Ahmed  *
19103fbed92SAli Ahmed  * @return None.
19203fbed92SAli Ahmed  */
193ac106bf6SEd Tanous inline void
194ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19603fbed92SAli Ahmed {
197ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
199382d6475SAli Ahmed         if (ec3)
200382d6475SAli Ahmed         {
20162598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
202382d6475SAli Ahmed             return;
203382d6475SAli Ahmed         }
204ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
205382d6475SAli Ahmed     };
206382d6475SAli Ahmed 
207cf0e004cSNinad Palsule     // Get the Presence of CPU
208cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
209cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
210cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
211cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
212cf0e004cSNinad Palsule 
213bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
214bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
215bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
216ac106bf6SEd Tanous         [asyncResp, service,
2175e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
218b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21903fbed92SAli Ahmed         if (ec2)
22003fbed92SAli Ahmed         {
22162598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
222ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22303fbed92SAli Ahmed             return;
22403fbed92SAli Ahmed         }
225ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
226bc1d29deSKrzysztof Grobelny     });
22703fbed92SAli Ahmed }
22803fbed92SAli Ahmed 
22957e8c9beSAlpana Kumari /*
230cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
231cf0e004cSNinad Palsule  *
232ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
233cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
234cf0e004cSNinad Palsule  *
235cf0e004cSNinad Palsule  * @return None.
236cf0e004cSNinad Palsule  */
237cf0e004cSNinad Palsule inline void
238ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
239cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
240cf0e004cSNinad Palsule {
24162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
242cf0e004cSNinad Palsule 
243cf0e004cSNinad Palsule     if (properties.empty())
244cf0e004cSNinad Palsule     {
245cf0e004cSNinad Palsule         return;
246cf0e004cSNinad Palsule     }
247cf0e004cSNinad Palsule 
248cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
249cf0e004cSNinad Palsule 
250cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
251cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
252cf0e004cSNinad Palsule         memorySizeInKB);
253cf0e004cSNinad Palsule 
254cf0e004cSNinad Palsule     if (!success)
255cf0e004cSNinad Palsule     {
256ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
257cf0e004cSNinad Palsule         return;
258cf0e004cSNinad Palsule     }
259cf0e004cSNinad Palsule 
260cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
261cf0e004cSNinad Palsule     {
262cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
263ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
264dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
265cf0e004cSNinad Palsule         if (preValue == nullptr)
266cf0e004cSNinad Palsule         {
267ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
268dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
269cf0e004cSNinad Palsule         }
270cf0e004cSNinad Palsule         else
271cf0e004cSNinad Palsule         {
272ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
273dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
274dfb2b408SPriyanga Ramasamy                 *preValue;
275cf0e004cSNinad Palsule         }
276cf0e004cSNinad Palsule     }
277cf0e004cSNinad Palsule }
278cf0e004cSNinad Palsule 
279cf0e004cSNinad Palsule /*
280cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
281cf0e004cSNinad Palsule  *
282ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
283cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
284cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
285cf0e004cSNinad Palsule  *
286cf0e004cSNinad Palsule  * @return None.
287cf0e004cSNinad Palsule  */
288ac106bf6SEd Tanous inline void
289ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
291cf0e004cSNinad Palsule {
292cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
293cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
294cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
295ac106bf6SEd Tanous         [asyncResp, service,
296cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
297cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
298cf0e004cSNinad Palsule         if (ec2)
299cf0e004cSNinad Palsule         {
30062598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
301ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
302cf0e004cSNinad Palsule             return;
303cf0e004cSNinad Palsule         }
304*51bd2d8aSGunnar Mills         processMemoryProperties(asyncResp, properties);
305cf0e004cSNinad Palsule     });
306cf0e004cSNinad Palsule }
307cf0e004cSNinad Palsule 
308a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
309a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
310a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3111abe55efSEd Tanous {
312a974c132SLakshmi Yadlapati     if (ec)
313a974c132SLakshmi Yadlapati     {
314a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
315a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
316a974c132SLakshmi Yadlapati         return;
317a974c132SLakshmi Yadlapati     }
318a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
319a974c132SLakshmi Yadlapati 
320a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
321a974c132SLakshmi Yadlapati 
322a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
323a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
324a974c132SLakshmi Yadlapati 
325a974c132SLakshmi Yadlapati     if (!success)
326a974c132SLakshmi Yadlapati     {
327a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
328a974c132SLakshmi Yadlapati         return;
329a974c132SLakshmi Yadlapati     }
330a974c132SLakshmi Yadlapati 
331a974c132SLakshmi Yadlapati     if (uUID != nullptr)
332a974c132SLakshmi Yadlapati     {
333a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
334a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
335a974c132SLakshmi Yadlapati         {
336a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
337a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
338a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
339a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
340a974c132SLakshmi Yadlapati         }
341a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
342a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
343a974c132SLakshmi Yadlapati     }
344a974c132SLakshmi Yadlapati }
345a974c132SLakshmi Yadlapati 
346a974c132SLakshmi Yadlapati inline void
347a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
349a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
350a974c132SLakshmi Yadlapati {
351a974c132SLakshmi Yadlapati     if (ec)
352a974c132SLakshmi Yadlapati     {
353a974c132SLakshmi Yadlapati         // doesn't have to include this
354a974c132SLakshmi Yadlapati         // interface
355a974c132SLakshmi Yadlapati         return;
356a974c132SLakshmi Yadlapati     }
357a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
358a974c132SLakshmi Yadlapati 
359a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
360a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
361a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
362a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
363a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
364a974c132SLakshmi Yadlapati 
365a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
366a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
367a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
368a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
369a974c132SLakshmi Yadlapati 
370a974c132SLakshmi Yadlapati     if (!success)
371a974c132SLakshmi Yadlapati     {
372a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
373a974c132SLakshmi Yadlapati         return;
374a974c132SLakshmi Yadlapati     }
375a974c132SLakshmi Yadlapati 
376a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
377a974c132SLakshmi Yadlapati     {
378a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
379a974c132SLakshmi Yadlapati     }
380a974c132SLakshmi Yadlapati 
381a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
382a974c132SLakshmi Yadlapati     {
383a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
384a974c132SLakshmi Yadlapati     }
385a974c132SLakshmi Yadlapati 
386a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
387a974c132SLakshmi Yadlapati     {
388a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
389a974c132SLakshmi Yadlapati     }
390a974c132SLakshmi Yadlapati 
391a974c132SLakshmi Yadlapati     if (model != nullptr)
392a974c132SLakshmi Yadlapati     {
393a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
394a974c132SLakshmi Yadlapati     }
395a974c132SLakshmi Yadlapati 
396a974c132SLakshmi Yadlapati     if (subModel != nullptr)
397a974c132SLakshmi Yadlapati     {
398a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
399a974c132SLakshmi Yadlapati     }
400a974c132SLakshmi Yadlapati 
401a974c132SLakshmi Yadlapati     // Grab the bios version
402a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
403a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
404a974c132SLakshmi Yadlapati }
405a974c132SLakshmi Yadlapati 
406a974c132SLakshmi Yadlapati inline void
407a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
408a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
409a974c132SLakshmi Yadlapati                      const std::string& value)
410a974c132SLakshmi Yadlapati {
411a974c132SLakshmi Yadlapati     if (ec)
412a974c132SLakshmi Yadlapati     {
413a974c132SLakshmi Yadlapati         // doesn't have to include this
414a974c132SLakshmi Yadlapati         // interface
415a974c132SLakshmi Yadlapati         return;
416a974c132SLakshmi Yadlapati     }
417a974c132SLakshmi Yadlapati 
418a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
419a974c132SLakshmi Yadlapati }
420a974c132SLakshmi Yadlapati 
421a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
422a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
423a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
424a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
425a974c132SLakshmi Yadlapati {
4261abe55efSEd Tanous     if (ec)
4271abe55efSEd Tanous     {
428b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
429ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
430c5b2abe0SLewanczyk, Dawid         return;
431c5b2abe0SLewanczyk, Dawid     }
432c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
433002d39b4SEd Tanous     for (const std::pair<
434002d39b4SEd Tanous              std::string,
435002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4361214b7e7SGunnar Mills              object : subtree)
4371abe55efSEd Tanous     {
438c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
43962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
440002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4411214b7e7SGunnar Mills             connectionNames = object.second;
44226f6976fSEd Tanous         if (connectionNames.empty())
4431abe55efSEd Tanous         {
444c5b2abe0SLewanczyk, Dawid             continue;
445c5b2abe0SLewanczyk, Dawid         }
446029573d4SEd Tanous 
4476c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4486c34de48SEd Tanous         // BiosVer
44904a258f4SEd Tanous         for (const auto& connection : connectionNames)
4501abe55efSEd Tanous         {
45104a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4521abe55efSEd Tanous             {
453a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4541abe55efSEd Tanous                 {
45562598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4569d3ae10eSAlpana Kumari 
457ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4585fd0aafbSNinad Palsule                 }
45904a258f4SEd Tanous                 else if (interfaceName ==
46004a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4611abe55efSEd Tanous                 {
46262598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
46357e8c9beSAlpana Kumari 
464ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4655fd0aafbSNinad Palsule                 }
466002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4671abe55efSEd Tanous                 {
46862598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
469bc1d29deSKrzysztof Grobelny 
470bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
471a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
472a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
473ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
474b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4751214b7e7SGunnar Mills                                         properties) {
476a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
477bc1d29deSKrzysztof Grobelny                     });
478c5b2abe0SLewanczyk, Dawid                 }
479029573d4SEd Tanous                 else if (interfaceName ==
480029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4811abe55efSEd Tanous                 {
482bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
483a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
484bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
485a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
486b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
487a974c132SLakshmi Yadlapati                                         properties) {
488a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
489bc1d29deSKrzysztof Grobelny                     });
490e4a4b9a9SJames Feist 
4911e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
492a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
4931e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4941e1e598dSJonathan Doman                         "AssetTag",
4951e1e598dSJonathan Doman                         "AssetTag",
496a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
497a974c132SLakshmi Yadlapati                 }
498a974c132SLakshmi Yadlapati             }
499a974c132SLakshmi Yadlapati         }
500a974c132SLakshmi Yadlapati     }
501a974c132SLakshmi Yadlapati }
502a974c132SLakshmi Yadlapati 
503a974c132SLakshmi Yadlapati /*
504a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
505a974c132SLakshmi Yadlapati  *
506a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
507a974c132SLakshmi Yadlapati  *
508a974c132SLakshmi Yadlapati  * @return None.
509a974c132SLakshmi Yadlapati  */
510a974c132SLakshmi Yadlapati inline void
511*51bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
512e4a4b9a9SJames Feist {
513a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
514a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
515a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
516a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
517a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
518a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
519a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
520a974c132SLakshmi Yadlapati     };
521a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
522a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
523*51bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
524c5b2abe0SLewanczyk, Dawid }
525c5b2abe0SLewanczyk, Dawid 
526c5b2abe0SLewanczyk, Dawid /**
527c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
528c5b2abe0SLewanczyk, Dawid  *
529ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
530c5b2abe0SLewanczyk, Dawid  *
531c5b2abe0SLewanczyk, Dawid  * @return None.
532c5b2abe0SLewanczyk, Dawid  */
533ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5341abe55efSEd Tanous {
53562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
5361e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5371e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5381e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5391e1e598dSJonathan Doman         "CurrentHostState",
540ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5411e1e598dSJonathan Doman                     const std::string& hostState) {
5421abe55efSEd Tanous         if (ec)
5431abe55efSEd Tanous         {
54422228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
54522228c28SAndrew Geissler             {
54622228c28SAndrew Geissler                 // Service not available, no error, just don't return
54722228c28SAndrew Geissler                 // host state info
54862598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
54922228c28SAndrew Geissler                 return;
55022228c28SAndrew Geissler             }
55162598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
552ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
553c5b2abe0SLewanczyk, Dawid             return;
554c5b2abe0SLewanczyk, Dawid         }
5556617338dSEd Tanous 
55662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
557c5b2abe0SLewanczyk, Dawid         // Verify Host State
5581e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5591abe55efSEd Tanous         {
560ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
561ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
5621abe55efSEd Tanous         }
5631e1e598dSJonathan Doman         else if (hostState ==
5640fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5658c888608SGunnar Mills         {
566ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
567ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
5688c888608SGunnar Mills         }
5691e1e598dSJonathan Doman         else if (hostState ==
5700fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57183935af9SAndrew Geissler         {
572ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
573ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
57483935af9SAndrew Geissler         }
5750fda0f12SGeorge Liu         else if (
5761e1e598dSJonathan Doman             hostState ==
5770fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5781a2a1437SAndrew Geissler         {
579ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
580ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
5811a2a1437SAndrew Geissler         }
582002d39b4SEd Tanous         else if (hostState ==
5830fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5841a2a1437SAndrew Geissler         {
585ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
586ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
5871a2a1437SAndrew Geissler         }
5881abe55efSEd Tanous         else
5891abe55efSEd Tanous         {
590ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
591ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
592c5b2abe0SLewanczyk, Dawid         }
5931e1e598dSJonathan Doman     });
594c5b2abe0SLewanczyk, Dawid }
595c5b2abe0SLewanczyk, Dawid 
596c5b2abe0SLewanczyk, Dawid /**
597786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
598491d8ee7SSantosh Puranik  *
599491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
600491d8ee7SSantosh Puranik  *
601491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
602491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
603491d8ee7SSantosh Puranik  */
60423a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
605491d8ee7SSantosh Puranik {
606491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
607491d8ee7SSantosh Puranik     {
608491d8ee7SSantosh Puranik         return "None";
609491d8ee7SSantosh Puranik     }
6103174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
611491d8ee7SSantosh Puranik     {
612491d8ee7SSantosh Puranik         return "Hdd";
613491d8ee7SSantosh Puranik     }
6143174e4dfSEd Tanous     if (dbusSource ==
615a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
616491d8ee7SSantosh Puranik     {
617491d8ee7SSantosh Puranik         return "Cd";
618491d8ee7SSantosh Puranik     }
6193174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
620491d8ee7SSantosh Puranik     {
621491d8ee7SSantosh Puranik         return "Pxe";
622491d8ee7SSantosh Puranik     }
6233174e4dfSEd Tanous     if (dbusSource ==
624944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6259f16b2c1SJennifer Lee     {
6269f16b2c1SJennifer Lee         return "Usb";
6279f16b2c1SJennifer Lee     }
628491d8ee7SSantosh Puranik     return "";
629491d8ee7SSantosh Puranik }
630491d8ee7SSantosh Puranik 
631491d8ee7SSantosh Puranik /**
632cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
633cd9a4666SKonstantin Aladyshev  *
634cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
635cd9a4666SKonstantin Aladyshev  *
636cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
637cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
638cd9a4666SKonstantin Aladyshev  */
639cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
640cd9a4666SKonstantin Aladyshev {
641cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
642cd9a4666SKonstantin Aladyshev     {
643cd9a4666SKonstantin Aladyshev         return "Legacy";
644cd9a4666SKonstantin Aladyshev     }
645cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
646cd9a4666SKonstantin Aladyshev     {
647cd9a4666SKonstantin Aladyshev         return "UEFI";
648cd9a4666SKonstantin Aladyshev     }
649cd9a4666SKonstantin Aladyshev     return "";
650cd9a4666SKonstantin Aladyshev }
651cd9a4666SKonstantin Aladyshev 
652cd9a4666SKonstantin Aladyshev /**
653786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
654491d8ee7SSantosh Puranik  *
655491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
656491d8ee7SSantosh Puranik  *
657491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
658491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
659491d8ee7SSantosh Puranik  */
66023a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
661491d8ee7SSantosh Puranik {
662491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
663491d8ee7SSantosh Puranik     {
664491d8ee7SSantosh Puranik         return "None";
665491d8ee7SSantosh Puranik     }
6663174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
667491d8ee7SSantosh Puranik     {
668491d8ee7SSantosh Puranik         return "Diags";
669491d8ee7SSantosh Puranik     }
6703174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
671491d8ee7SSantosh Puranik     {
672491d8ee7SSantosh Puranik         return "BiosSetup";
673491d8ee7SSantosh Puranik     }
674491d8ee7SSantosh Puranik     return "";
675491d8ee7SSantosh Puranik }
676491d8ee7SSantosh Puranik 
677491d8ee7SSantosh Puranik /**
678e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
679e43914b3SAndrew Geissler  *
680e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
681e43914b3SAndrew Geissler  *
682e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
683e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
684e43914b3SAndrew Geissler  */
685e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
686e43914b3SAndrew Geissler {
687e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
688e43914b3SAndrew Geissler     // enum
689e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
690e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
691e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
692e43914b3SAndrew Geissler     {
693e43914b3SAndrew Geissler         rfBpLastState = "None";
694e43914b3SAndrew Geissler     }
695e43914b3SAndrew Geissler     else if (dbusBootProgress ==
696e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
697e43914b3SAndrew Geissler              "PrimaryProcInit")
698e43914b3SAndrew Geissler     {
699e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
700e43914b3SAndrew Geissler     }
701e43914b3SAndrew Geissler     else if (dbusBootProgress ==
702e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
703e43914b3SAndrew Geissler              "BusInit")
704e43914b3SAndrew Geissler     {
705e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
706e43914b3SAndrew Geissler     }
707e43914b3SAndrew Geissler     else if (dbusBootProgress ==
708e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
709e43914b3SAndrew Geissler              "MemoryInit")
710e43914b3SAndrew Geissler     {
711e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
712e43914b3SAndrew Geissler     }
713e43914b3SAndrew Geissler     else if (dbusBootProgress ==
714e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715e43914b3SAndrew Geissler              "SecondaryProcInit")
716e43914b3SAndrew Geissler     {
717e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
718e43914b3SAndrew Geissler     }
719e43914b3SAndrew Geissler     else if (dbusBootProgress ==
720e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721e43914b3SAndrew Geissler              "PCIInit")
722e43914b3SAndrew Geissler     {
723e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
724e43914b3SAndrew Geissler     }
725e43914b3SAndrew Geissler     else if (dbusBootProgress ==
726e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727e43914b3SAndrew Geissler              "SystemSetup")
728e43914b3SAndrew Geissler     {
729e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
730e43914b3SAndrew Geissler     }
731e43914b3SAndrew Geissler     else if (dbusBootProgress ==
732e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733e43914b3SAndrew Geissler              "SystemInitComplete")
734e43914b3SAndrew Geissler     {
735e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
736e43914b3SAndrew Geissler     }
737e43914b3SAndrew Geissler     else if (dbusBootProgress ==
738e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739e43914b3SAndrew Geissler              "OSStart")
740e43914b3SAndrew Geissler     {
741e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
742e43914b3SAndrew Geissler     }
743e43914b3SAndrew Geissler     else if (dbusBootProgress ==
744e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745e43914b3SAndrew Geissler              "OSRunning")
746e43914b3SAndrew Geissler     {
747e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
748e43914b3SAndrew Geissler     }
749e43914b3SAndrew Geissler     else
750e43914b3SAndrew Geissler     {
75162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
752e43914b3SAndrew Geissler         // Just return the default
753e43914b3SAndrew Geissler     }
754e43914b3SAndrew Geissler     return rfBpLastState;
755e43914b3SAndrew Geissler }
756e43914b3SAndrew Geissler 
757e43914b3SAndrew Geissler /**
758786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
759491d8ee7SSantosh Puranik  *
760491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
761944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
762944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
763491d8ee7SSantosh Puranik  *
764944ffaf9SJohnathan Mantey  * @return Integer error code.
765491d8ee7SSantosh Puranik  */
766ac106bf6SEd Tanous inline int
767ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
768ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
769ac106bf6SEd Tanous                          std::string& bootMode)
770491d8ee7SSantosh Puranik {
771c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
772c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
773944ffaf9SJohnathan Mantey 
774491d8ee7SSantosh Puranik     if (rfSource == "None")
775491d8ee7SSantosh Puranik     {
776944ffaf9SJohnathan Mantey         return 0;
777491d8ee7SSantosh Puranik     }
7783174e4dfSEd Tanous     if (rfSource == "Pxe")
779491d8ee7SSantosh Puranik     {
780944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
781944ffaf9SJohnathan Mantey     }
782944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
783944ffaf9SJohnathan Mantey     {
784944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
785944ffaf9SJohnathan Mantey     }
786944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
787944ffaf9SJohnathan Mantey     {
788944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
789944ffaf9SJohnathan Mantey     }
790944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
791944ffaf9SJohnathan Mantey     {
792944ffaf9SJohnathan Mantey         bootSource =
793944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
794944ffaf9SJohnathan Mantey     }
795944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
796944ffaf9SJohnathan Mantey     {
797944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
798491d8ee7SSantosh Puranik     }
7999f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8009f16b2c1SJennifer Lee     {
801944ffaf9SJohnathan Mantey         bootSource =
802944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8039f16b2c1SJennifer Lee     }
804491d8ee7SSantosh Puranik     else
805491d8ee7SSantosh Puranik     {
80662598e31SEd Tanous         BMCWEB_LOG_DEBUG(
80762598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
80862598e31SEd Tanous             bootSource);
809ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
810944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
811944ffaf9SJohnathan Mantey         return -1;
812491d8ee7SSantosh Puranik     }
813944ffaf9SJohnathan Mantey     return 0;
814491d8ee7SSantosh Puranik }
8151981771bSAli Ahmed 
816978b8803SAndrew Geissler /**
817978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
818978b8803SAndrew Geissler  *
819ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
820978b8803SAndrew Geissler  *
821978b8803SAndrew Geissler  * @return None.
822978b8803SAndrew Geissler  */
823ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
824978b8803SAndrew Geissler {
8251e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8261e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8271e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8281e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
829ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8301e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
831978b8803SAndrew Geissler         if (ec)
832978b8803SAndrew Geissler         {
833978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
834978b8803SAndrew Geissler             // not found
835978b8803SAndrew Geissler             return;
836978b8803SAndrew Geissler         }
837978b8803SAndrew Geissler 
83862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
839978b8803SAndrew Geissler 
840ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
841e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8421e1e598dSJonathan Doman     });
843978b8803SAndrew Geissler }
844491d8ee7SSantosh Puranik 
845491d8ee7SSantosh Puranik /**
846b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
847b6d5d45cSHieu Huynh  *
848ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
849b6d5d45cSHieu Huynh  *
850b6d5d45cSHieu Huynh  * @return None.
851b6d5d45cSHieu Huynh  */
852b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
853ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
854b6d5d45cSHieu Huynh {
855b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
856b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
857b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
858b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
859ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
860b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
861b6d5d45cSHieu Huynh         if (ec)
862b6d5d45cSHieu Huynh         {
86362598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
864b6d5d45cSHieu Huynh             return;
865b6d5d45cSHieu Huynh         }
866b6d5d45cSHieu Huynh 
867b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
868b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
869b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
870b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
871b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
872b6d5d45cSHieu Huynh 
873b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
874ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
875b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
876b6d5d45cSHieu Huynh     });
877b6d5d45cSHieu Huynh }
878b6d5d45cSHieu Huynh 
879b6d5d45cSHieu Huynh /**
880c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
881cd9a4666SKonstantin Aladyshev  *
882ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
883cd9a4666SKonstantin Aladyshev  *
884cd9a4666SKonstantin Aladyshev  * @return None.
885cd9a4666SKonstantin Aladyshev  */
886cd9a4666SKonstantin Aladyshev 
887ac106bf6SEd Tanous inline void
888ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
889cd9a4666SKonstantin Aladyshev {
8901e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8911e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8921e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8931e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
894ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8951e1e598dSJonathan Doman                     const std::string& bootType) {
896cd9a4666SKonstantin Aladyshev         if (ec)
897cd9a4666SKonstantin Aladyshev         {
898cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
899cd9a4666SKonstantin Aladyshev             return;
900cd9a4666SKonstantin Aladyshev         }
901cd9a4666SKonstantin Aladyshev 
90262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
903cd9a4666SKonstantin Aladyshev 
904ac106bf6SEd Tanous         asyncResp->res
905ac106bf6SEd Tanous             .jsonValue["Boot"]
906002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
907613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
908cd9a4666SKonstantin Aladyshev 
9091e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
910cd9a4666SKonstantin Aladyshev         if (rfType.empty())
911cd9a4666SKonstantin Aladyshev         {
912ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
913cd9a4666SKonstantin Aladyshev             return;
914cd9a4666SKonstantin Aladyshev         }
915cd9a4666SKonstantin Aladyshev 
916ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9171e1e598dSJonathan Doman     });
918cd9a4666SKonstantin Aladyshev }
919cd9a4666SKonstantin Aladyshev 
920cd9a4666SKonstantin Aladyshev /**
921c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
922491d8ee7SSantosh Puranik  *
923ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
924491d8ee7SSantosh Puranik  *
925491d8ee7SSantosh Puranik  * @return None.
926491d8ee7SSantosh Puranik  */
927c21865c4SKonstantin Aladyshev 
928ac106bf6SEd Tanous inline void
929ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
930491d8ee7SSantosh Puranik {
9311e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9321e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9331e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9341e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
935ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9361e1e598dSJonathan Doman                     const std::string& bootModeStr) {
937491d8ee7SSantosh Puranik         if (ec)
938491d8ee7SSantosh Puranik         {
939b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
940ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
941491d8ee7SSantosh Puranik             return;
942491d8ee7SSantosh Puranik         }
943491d8ee7SSantosh Puranik 
94462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
945491d8ee7SSantosh Puranik 
946ac106bf6SEd Tanous         asyncResp->res
9470fda0f12SGeorge Liu             .jsonValue["Boot"]
948002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
949002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
950491d8ee7SSantosh Puranik 
9511e1e598dSJonathan Doman         if (bootModeStr !=
952491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
953491d8ee7SSantosh Puranik         {
9541e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
955491d8ee7SSantosh Puranik             if (!rfMode.empty())
956491d8ee7SSantosh Puranik             {
957ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
958491d8ee7SSantosh Puranik                     rfMode;
959491d8ee7SSantosh Puranik             }
960491d8ee7SSantosh Puranik         }
9611e1e598dSJonathan Doman     });
962491d8ee7SSantosh Puranik }
963491d8ee7SSantosh Puranik 
964491d8ee7SSantosh Puranik /**
965c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
966491d8ee7SSantosh Puranik  *
967ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
968491d8ee7SSantosh Puranik  *
969491d8ee7SSantosh Puranik  * @return None.
970491d8ee7SSantosh Puranik  */
971c21865c4SKonstantin Aladyshev 
972c21865c4SKonstantin Aladyshev inline void
973ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
974491d8ee7SSantosh Puranik {
9751e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9761e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9771e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9781e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
979ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9801e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
981491d8ee7SSantosh Puranik         if (ec)
982491d8ee7SSantosh Puranik         {
9835ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9845ef735c8SNan Zhou             {
9855ef735c8SNan Zhou                 return;
9865ef735c8SNan Zhou             }
987b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
988ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
989491d8ee7SSantosh Puranik             return;
990491d8ee7SSantosh Puranik         }
991491d8ee7SSantosh Puranik 
99262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
993491d8ee7SSantosh Puranik 
9941e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
995491d8ee7SSantosh Puranik         if (!rfSource.empty())
996491d8ee7SSantosh Puranik         {
997ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
998ac106bf6SEd Tanous                 rfSource;
999491d8ee7SSantosh Puranik         }
1000cd9a4666SKonstantin Aladyshev 
1001cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1002cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1003ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10041e1e598dSJonathan Doman     });
1005491d8ee7SSantosh Puranik }
1006491d8ee7SSantosh Puranik 
1007491d8ee7SSantosh Puranik /**
1008c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1009c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1010c21865c4SKonstantin Aladyshev  * state
1011491d8ee7SSantosh Puranik  *
1012ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1013491d8ee7SSantosh Puranik  *
1014491d8ee7SSantosh Puranik  * @return None.
1015491d8ee7SSantosh Puranik  */
1016491d8ee7SSantosh Puranik 
1017ac106bf6SEd Tanous inline void processBootOverrideEnable(
1018ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1019c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1020c21865c4SKonstantin Aladyshev {
1021c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1022c21865c4SKonstantin Aladyshev     {
1023ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1024ac106bf6SEd Tanous             "Disabled";
1025c21865c4SKonstantin Aladyshev         return;
1026c21865c4SKonstantin Aladyshev     }
1027c21865c4SKonstantin Aladyshev 
1028c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1029c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10301e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10311e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10321e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10331e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1034ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1035491d8ee7SSantosh Puranik         if (ec)
1036491d8ee7SSantosh Puranik         {
1037b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1038ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1039491d8ee7SSantosh Puranik             return;
1040491d8ee7SSantosh Puranik         }
1041491d8ee7SSantosh Puranik 
1042c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1043c21865c4SKonstantin Aladyshev         {
1044ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1045ac106bf6SEd Tanous                 "Once";
1046c21865c4SKonstantin Aladyshev         }
1047c21865c4SKonstantin Aladyshev         else
1048c21865c4SKonstantin Aladyshev         {
1049ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1050c21865c4SKonstantin Aladyshev                 "Continuous";
1051c21865c4SKonstantin Aladyshev         }
10521e1e598dSJonathan Doman     });
1053491d8ee7SSantosh Puranik }
1054491d8ee7SSantosh Puranik 
1055491d8ee7SSantosh Puranik /**
1056c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1057c21865c4SKonstantin Aladyshev  *
1058ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1059c21865c4SKonstantin Aladyshev  *
1060c21865c4SKonstantin Aladyshev  * @return None.
1061c21865c4SKonstantin Aladyshev  */
1062c21865c4SKonstantin Aladyshev 
1063c21865c4SKonstantin Aladyshev inline void
1064ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1065c21865c4SKonstantin Aladyshev {
10661e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10671e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10681e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10691e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1070ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10711e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1072c21865c4SKonstantin Aladyshev         if (ec)
1073c21865c4SKonstantin Aladyshev         {
10745ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10755ef735c8SNan Zhou             {
10765ef735c8SNan Zhou                 return;
10775ef735c8SNan Zhou             }
1078b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1079ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1080c21865c4SKonstantin Aladyshev             return;
1081c21865c4SKonstantin Aladyshev         }
1082c21865c4SKonstantin Aladyshev 
1083ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
10841e1e598dSJonathan Doman     });
1085c21865c4SKonstantin Aladyshev }
1086c21865c4SKonstantin Aladyshev 
1087c21865c4SKonstantin Aladyshev /**
1088c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1089c21865c4SKonstantin Aladyshev  *
1090ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1091c21865c4SKonstantin Aladyshev  *
1092c21865c4SKonstantin Aladyshev  * @return None.
1093c21865c4SKonstantin Aladyshev  */
1094ac106bf6SEd Tanous inline void
1095ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1096c21865c4SKonstantin Aladyshev {
109762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1098c21865c4SKonstantin Aladyshev 
1099ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1100ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1101ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1102c21865c4SKonstantin Aladyshev }
1103c21865c4SKonstantin Aladyshev 
1104c21865c4SKonstantin Aladyshev /**
1105c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1106c0557e1aSGunnar Mills  *
1107c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1108c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1109c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1110c0557e1aSGunnar Mills  * last power operation time.
1111c0557e1aSGunnar Mills  *
1112ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1113c0557e1aSGunnar Mills  *
1114c0557e1aSGunnar Mills  * @return None.
1115c0557e1aSGunnar Mills  */
1116ac106bf6SEd Tanous inline void
1117ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1118c0557e1aSGunnar Mills {
111962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1120c0557e1aSGunnar Mills 
11211e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11221e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11231e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11241e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1125ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1126ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1127c0557e1aSGunnar Mills         if (ec)
1128c0557e1aSGunnar Mills         {
112962598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1130c0557e1aSGunnar Mills             return;
1131c0557e1aSGunnar Mills         }
1132c0557e1aSGunnar Mills 
1133c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1134c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11351e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1136c0557e1aSGunnar Mills 
1137c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1138ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
11392b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11401e1e598dSJonathan Doman     });
1141c0557e1aSGunnar Mills }
1142c0557e1aSGunnar Mills 
1143c0557e1aSGunnar Mills /**
1144797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1145797d5daeSCorey Hardesty  *
1146797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1147797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1148797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1149797d5daeSCorey Hardesty  * dbus.
1150797d5daeSCorey Hardesty  *
1151ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1152797d5daeSCorey Hardesty  *
1153797d5daeSCorey Hardesty  * @return None.
1154797d5daeSCorey Hardesty  */
1155ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1156ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1157797d5daeSCorey Hardesty {
115862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1159797d5daeSCorey Hardesty 
1160797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1161797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1162797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1163797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1164ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1165ac106bf6SEd Tanous             const boost::system::error_code& ec,
1166797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1167797d5daeSCorey Hardesty         if (ec)
1168797d5daeSCorey Hardesty         {
1169797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1170797d5daeSCorey Hardesty             {
117162598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1172ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1173797d5daeSCorey Hardesty             }
1174797d5daeSCorey Hardesty             return;
1175797d5daeSCorey Hardesty         }
1176797d5daeSCorey Hardesty 
1177797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1178797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1179797d5daeSCorey Hardesty 
1180797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1181797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1182797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1183797d5daeSCorey Hardesty 
1184797d5daeSCorey Hardesty         if (!success)
1185797d5daeSCorey Hardesty         {
1186ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1187797d5daeSCorey Hardesty             return;
1188797d5daeSCorey Hardesty         }
1189797d5daeSCorey Hardesty 
1190797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1191797d5daeSCorey Hardesty         {
1192ac106bf6SEd Tanous             asyncResp->res
1193ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1194797d5daeSCorey Hardesty                 *attemptsLeft;
1195797d5daeSCorey Hardesty         }
1196797d5daeSCorey Hardesty 
1197797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1198797d5daeSCorey Hardesty         {
1199ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1200797d5daeSCorey Hardesty                 *retryAttempts;
1201797d5daeSCorey Hardesty         }
1202797d5daeSCorey Hardesty     });
1203797d5daeSCorey Hardesty }
1204797d5daeSCorey Hardesty 
1205797d5daeSCorey Hardesty /**
12066bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12076bd5a8d2SGunnar Mills  *
1208ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12096bd5a8d2SGunnar Mills  *
12106bd5a8d2SGunnar Mills  * @return None.
12116bd5a8d2SGunnar Mills  */
1212797d5daeSCorey Hardesty inline void
1213ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12146bd5a8d2SGunnar Mills {
121562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12166bd5a8d2SGunnar Mills 
12171e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12181e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12191e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12201e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1221ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1222ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12236bd5a8d2SGunnar Mills         if (ec)
12246bd5a8d2SGunnar Mills         {
1225797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1226797d5daeSCorey Hardesty             {
122762598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1228ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1229797d5daeSCorey Hardesty             }
12306bd5a8d2SGunnar Mills             return;
12316bd5a8d2SGunnar Mills         }
12326bd5a8d2SGunnar Mills 
123362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1234e05aec50SEd Tanous         if (autoRebootEnabled)
12356bd5a8d2SGunnar Mills         {
1236ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12376bd5a8d2SGunnar Mills                 "RetryAttempts";
12386bd5a8d2SGunnar Mills         }
12396bd5a8d2SGunnar Mills         else
12406bd5a8d2SGunnar Mills         {
1241ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1242ac106bf6SEd Tanous                 "Disabled";
12436bd5a8d2SGunnar Mills         }
1244ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
124569f35306SGunnar Mills 
124669f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
124769f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
124869f35306SGunnar Mills         // RetryAttempts.
1249ac106bf6SEd Tanous         asyncResp->res
1250ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1251ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
12521e1e598dSJonathan Doman     });
12536bd5a8d2SGunnar Mills }
12546bd5a8d2SGunnar Mills 
12556bd5a8d2SGunnar Mills /**
1256797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1257797d5daeSCorey Hardesty  *
1258ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1259797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1260797d5daeSCorey Hardesty  *
1261797d5daeSCorey Hardesty  *@return None.
1262797d5daeSCorey Hardesty  */
1263797d5daeSCorey Hardesty 
1264ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1265ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1266797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1267797d5daeSCorey Hardesty {
126862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
12699ae226faSGeorge Liu     sdbusplus::asio::setProperty(
12709ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
12719ae226faSGeorge Liu         "/xyz/openbmc_project/state/host0",
12729ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
12739ae226faSGeorge Liu         retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1274797d5daeSCorey Hardesty         if (ec)
1275797d5daeSCorey Hardesty         {
127662598e31SEd Tanous             BMCWEB_LOG_ERROR(
127762598e31SEd Tanous                 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1278ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1279797d5daeSCorey Hardesty             return;
1280797d5daeSCorey Hardesty         }
12819ae226faSGeorge Liu     });
1282797d5daeSCorey Hardesty }
1283797d5daeSCorey Hardesty 
12848d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12858d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12868d69c668SEd Tanous {
12878d69c668SEd Tanous     if (value ==
12888d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12898d69c668SEd Tanous     {
12908d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
12918d69c668SEd Tanous     }
12928d69c668SEd Tanous     if (value ==
12938d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
12948d69c668SEd Tanous     {
12958d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12968d69c668SEd Tanous     }
12978d69c668SEd Tanous     if (value ==
12983a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
12998d69c668SEd Tanous     {
13008d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
13018d69c668SEd Tanous     }
13028d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
13038d69c668SEd Tanous     {
13048d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
13058d69c668SEd Tanous     }
13068d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
13078d69c668SEd Tanous }
1308797d5daeSCorey Hardesty /**
1309c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1310c6a620f2SGeorge Liu  *
1311ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1312c6a620f2SGeorge Liu  *
1313c6a620f2SGeorge Liu  * @return None.
1314c6a620f2SGeorge Liu  */
13158d1b46d7Szhanghch05 inline void
1316ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1317c6a620f2SGeorge Liu {
131862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1319c6a620f2SGeorge Liu 
13201e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13211e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13221e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13231e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1324ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13255e7e2dc5SEd Tanous                     const std::string& policy) {
1326c6a620f2SGeorge Liu         if (ec)
1327c6a620f2SGeorge Liu         {
132862598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1329c6a620f2SGeorge Liu             return;
1330c6a620f2SGeorge Liu         }
13318d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
13328d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
13338d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1334c6a620f2SGeorge Liu         {
1335ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1336c6a620f2SGeorge Liu             return;
1337c6a620f2SGeorge Liu         }
1338c6a620f2SGeorge Liu 
13398d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13401e1e598dSJonathan Doman     });
1341c6a620f2SGeorge Liu }
1342c6a620f2SGeorge Liu 
1343c6a620f2SGeorge Liu /**
13449dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13459dcfe8c1SAlbert Zhang  *
13469dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13479dcfe8c1SAlbert Zhang  *
13489dcfe8c1SAlbert Zhang  * @return None.
13499dcfe8c1SAlbert Zhang  */
13509dcfe8c1SAlbert Zhang inline void
13519dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13529dcfe8c1SAlbert Zhang {
135362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13549dcfe8c1SAlbert Zhang 
13559dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
13569dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13579dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
13589dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13599dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13609dcfe8c1SAlbert Zhang         if (ec)
13619dcfe8c1SAlbert Zhang         {
13629dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
13639dcfe8c1SAlbert Zhang             {
1364b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13659dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
13669dcfe8c1SAlbert Zhang             }
13679dcfe8c1SAlbert Zhang             return;
13689dcfe8c1SAlbert Zhang         }
13699dcfe8c1SAlbert Zhang 
13709dcfe8c1SAlbert Zhang         if (value)
13719dcfe8c1SAlbert Zhang         {
13729dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
13739dcfe8c1SAlbert Zhang         }
13749dcfe8c1SAlbert Zhang         else
13759dcfe8c1SAlbert Zhang         {
13769dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
13779dcfe8c1SAlbert Zhang         }
13789dcfe8c1SAlbert Zhang     });
13799dcfe8c1SAlbert Zhang }
13809dcfe8c1SAlbert Zhang 
13819dcfe8c1SAlbert Zhang /**
13821981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13831981771bSAli Ahmed  * TPM is required for booting the host.
13841981771bSAli Ahmed  *
1385ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
13861981771bSAli Ahmed  *
13871981771bSAli Ahmed  * @return None.
13881981771bSAli Ahmed  */
13891981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1390ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13911981771bSAli Ahmed {
139262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1393e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1394e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1395e99073f5SGeorge Liu     dbus::utility::getSubTree(
1396e99073f5SGeorge Liu         "/", 0, interfaces,
1397ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1398b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
13991981771bSAli Ahmed         if (ec)
14001981771bSAli Ahmed         {
140162598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
140262598e31SEd Tanous                              ec);
14031981771bSAli Ahmed             // This is an optional D-Bus object so just return if
14041981771bSAli Ahmed             // error occurs
14051981771bSAli Ahmed             return;
14061981771bSAli Ahmed         }
140726f6976fSEd Tanous         if (subtree.empty())
14081981771bSAli Ahmed         {
14091981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14101981771bSAli Ahmed             // if there is no instance found
14111981771bSAli Ahmed             return;
14121981771bSAli Ahmed         }
14131981771bSAli Ahmed 
14141981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14151981771bSAli Ahmed         if (subtree.size() > 1)
14161981771bSAli Ahmed         {
141762598e31SEd Tanous             BMCWEB_LOG_DEBUG(
141862598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
141962598e31SEd Tanous                 subtree.size());
14201981771bSAli Ahmed             // Throw an internal Error and return
1421ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14221981771bSAli Ahmed             return;
14231981771bSAli Ahmed         }
14241981771bSAli Ahmed 
14251981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14261981771bSAli Ahmed         // field
14271981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14281981771bSAli Ahmed         {
142962598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1430ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14311981771bSAli Ahmed             return;
14321981771bSAli Ahmed         }
14331981771bSAli Ahmed 
14341981771bSAli Ahmed         const std::string& path = subtree[0].first;
14351981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14361981771bSAli Ahmed 
14371981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14381e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14391e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14401e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1441ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1442ac106bf6SEd Tanous                         bool tpmRequired) {
14438a592810SEd Tanous             if (ec2)
14441981771bSAli Ahmed             {
1445b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
144662598e31SEd Tanous                                  ec2);
1447ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14481981771bSAli Ahmed                 return;
14491981771bSAli Ahmed             }
14501981771bSAli Ahmed 
14511e1e598dSJonathan Doman             if (tpmRequired)
14521981771bSAli Ahmed             {
1453ac106bf6SEd Tanous                 asyncResp->res
1454ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14551981771bSAli Ahmed                     "Required";
14561981771bSAli Ahmed             }
14571981771bSAli Ahmed             else
14581981771bSAli Ahmed             {
1459ac106bf6SEd Tanous                 asyncResp->res
1460ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14611981771bSAli Ahmed                     "Disabled";
14621981771bSAli Ahmed             }
14631e1e598dSJonathan Doman         });
1464e99073f5SGeorge Liu     });
14651981771bSAli Ahmed }
14661981771bSAli Ahmed 
14671981771bSAli Ahmed /**
14681c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14691c05dae3SAli Ahmed  * TPM is required for booting the host.
14701c05dae3SAli Ahmed  *
1471ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14721c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14731c05dae3SAli Ahmed  *
14741c05dae3SAli Ahmed  * @return None.
14751c05dae3SAli Ahmed  */
14761c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1477ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14781c05dae3SAli Ahmed {
147962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1480e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1481e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1482e99073f5SGeorge Liu     dbus::utility::getSubTree(
1483e99073f5SGeorge Liu         "/", 0, interfaces,
1484ac106bf6SEd Tanous         [asyncResp,
1485e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1486e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14871c05dae3SAli Ahmed         if (ec)
14881c05dae3SAli Ahmed         {
1489b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
149062598e31SEd Tanous                              ec);
1491ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14921c05dae3SAli Ahmed             return;
14931c05dae3SAli Ahmed         }
149426f6976fSEd Tanous         if (subtree.empty())
14951c05dae3SAli Ahmed         {
1496ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
14971c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14981c05dae3SAli Ahmed             return;
14991c05dae3SAli Ahmed         }
15001c05dae3SAli Ahmed 
15011c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
15021c05dae3SAli Ahmed         if (subtree.size() > 1)
15031c05dae3SAli Ahmed         {
150462598e31SEd Tanous             BMCWEB_LOG_DEBUG(
150562598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
150662598e31SEd Tanous                 subtree.size());
15071c05dae3SAli Ahmed             // Throw an internal Error and return
1508ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15091c05dae3SAli Ahmed             return;
15101c05dae3SAli Ahmed         }
15111c05dae3SAli Ahmed 
15121c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15131c05dae3SAli Ahmed         // field
15141c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15151c05dae3SAli Ahmed         {
151662598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1517ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15181c05dae3SAli Ahmed             return;
15191c05dae3SAli Ahmed         }
15201c05dae3SAli Ahmed 
15211c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15221c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15231c05dae3SAli Ahmed 
15241c05dae3SAli Ahmed         if (serv.empty())
15251c05dae3SAli Ahmed         {
152662598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1527ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15281c05dae3SAli Ahmed             return;
15291c05dae3SAli Ahmed         }
15301c05dae3SAli Ahmed 
15311c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
15329ae226faSGeorge Liu         sdbusplus::asio::setProperty(
15339ae226faSGeorge Liu             *crow::connections::systemBus, serv, path,
15349ae226faSGeorge Liu             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
1535ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
15368a592810SEd Tanous             if (ec2)
15371c05dae3SAli Ahmed             {
1538b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR(
153962598e31SEd Tanous                     "DBUS response error: Set TrustedModuleRequiredToBoot{}",
154062598e31SEd Tanous                     ec2);
1541ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
15421c05dae3SAli Ahmed                 return;
15431c05dae3SAli Ahmed             }
154462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
15459ae226faSGeorge Liu         });
1546e99073f5SGeorge Liu     });
15471c05dae3SAli Ahmed }
15481c05dae3SAli Ahmed 
15491c05dae3SAli Ahmed /**
1550491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1551491d8ee7SSantosh Puranik  *
1552ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1553cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1554cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1555cd9a4666SKonstantin Aladyshev  */
1556ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1557cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1558cd9a4666SKonstantin Aladyshev {
1559c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1560cd9a4666SKonstantin Aladyshev 
1561c21865c4SKonstantin Aladyshev     if (!bootType)
1562cd9a4666SKonstantin Aladyshev     {
1563c21865c4SKonstantin Aladyshev         return;
1564c21865c4SKonstantin Aladyshev     }
1565c21865c4SKonstantin Aladyshev 
1566cd9a4666SKonstantin Aladyshev     // Source target specified
156762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1568cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1569cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1570cd9a4666SKonstantin Aladyshev     {
1571cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1572cd9a4666SKonstantin Aladyshev     }
1573cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1574cd9a4666SKonstantin Aladyshev     {
1575cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1576cd9a4666SKonstantin Aladyshev     }
1577cd9a4666SKonstantin Aladyshev     else
1578cd9a4666SKonstantin Aladyshev     {
157962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
158062598e31SEd Tanous                          "BootSourceOverrideMode: {}",
158162598e31SEd Tanous                          *bootType);
1582ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1583cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1584cd9a4666SKonstantin Aladyshev         return;
1585cd9a4666SKonstantin Aladyshev     }
1586cd9a4666SKonstantin Aladyshev 
1587cd9a4666SKonstantin Aladyshev     // Act on validated parameters
158862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1589cd9a4666SKonstantin Aladyshev 
15909ae226faSGeorge Liu     sdbusplus::asio::setProperty(
15919ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
15929ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
15939ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
1594ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1595cd9a4666SKonstantin Aladyshev         if (ec)
1596cd9a4666SKonstantin Aladyshev         {
1597cd9a4666SKonstantin Aladyshev             if (ec.value() == boost::asio::error::host_unreachable)
1598cd9a4666SKonstantin Aladyshev             {
1599ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
1600cd9a4666SKonstantin Aladyshev                 return;
1601cd9a4666SKonstantin Aladyshev             }
1602b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1603ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1604cd9a4666SKonstantin Aladyshev             return;
1605cd9a4666SKonstantin Aladyshev         }
160662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type update done.");
16079ae226faSGeorge Liu     });
1608cd9a4666SKonstantin Aladyshev }
1609cd9a4666SKonstantin Aladyshev 
1610cd9a4666SKonstantin Aladyshev /**
1611cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1612cd9a4666SKonstantin Aladyshev  *
1613ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1614ac106bf6SEd Tanous  * message.
1615c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1616c21865c4SKonstantin Aladyshev  * @return Integer error code.
1617c21865c4SKonstantin Aladyshev  */
1618ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1619c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1620c21865c4SKonstantin Aladyshev {
1621c21865c4SKonstantin Aladyshev     if (!bootEnable)
1622c21865c4SKonstantin Aladyshev     {
1623c21865c4SKonstantin Aladyshev         return;
1624c21865c4SKonstantin Aladyshev     }
1625c21865c4SKonstantin Aladyshev     // Source target specified
162662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1627c21865c4SKonstantin Aladyshev 
1628c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1629c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1630c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1631c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1632c21865c4SKonstantin Aladyshev     {
1633c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1634c21865c4SKonstantin Aladyshev     }
1635c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1636c21865c4SKonstantin Aladyshev     {
1637c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1638c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1639c21865c4SKonstantin Aladyshev     }
1640c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1641c21865c4SKonstantin Aladyshev     {
1642c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1643c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1644c21865c4SKonstantin Aladyshev     }
1645c21865c4SKonstantin Aladyshev     else
1646c21865c4SKonstantin Aladyshev     {
164762598e31SEd Tanous         BMCWEB_LOG_DEBUG(
164862598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
164962598e31SEd Tanous             *bootEnable);
1650ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1651c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1652c21865c4SKonstantin Aladyshev         return;
1653c21865c4SKonstantin Aladyshev     }
1654c21865c4SKonstantin Aladyshev 
1655c21865c4SKonstantin Aladyshev     // Act on validated parameters
165662598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1657c21865c4SKonstantin Aladyshev 
16589ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16599ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16609ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
16619ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
1662ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec2) {
16638a592810SEd Tanous         if (ec2)
1664c21865c4SKonstantin Aladyshev         {
1665b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
1666ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1667c21865c4SKonstantin Aladyshev             return;
1668c21865c4SKonstantin Aladyshev         }
166962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot override enable update done.");
16709ae226faSGeorge Liu     });
1671c21865c4SKonstantin Aladyshev 
1672c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1673c21865c4SKonstantin Aladyshev     {
1674c21865c4SKonstantin Aladyshev         return;
1675c21865c4SKonstantin Aladyshev     }
1676c21865c4SKonstantin Aladyshev 
1677c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1678c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
167962598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
168062598e31SEd Tanous                      bootOverridePersistent);
1681c21865c4SKonstantin Aladyshev 
16829ae226faSGeorge Liu     sdbusplus::asio::setProperty(
16839ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
16849ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot/one_time",
16859ae226faSGeorge Liu         "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
1686ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1687c21865c4SKonstantin Aladyshev         if (ec)
1688c21865c4SKonstantin Aladyshev         {
1689b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1690ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1691c21865c4SKonstantin Aladyshev             return;
1692c21865c4SKonstantin Aladyshev         }
169362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot one_time update done.");
16949ae226faSGeorge Liu     });
1695c21865c4SKonstantin Aladyshev }
1696c21865c4SKonstantin Aladyshev 
1697c21865c4SKonstantin Aladyshev /**
1698c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1699c21865c4SKonstantin Aladyshev  *
1700ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1701491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1702491d8ee7SSantosh Puranik  *
1703265c1602SJohnathan Mantey  * @return Integer error code.
1704491d8ee7SSantosh Puranik  */
1705ac106bf6SEd Tanous inline void
1706ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1707cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1708491d8ee7SSantosh Puranik {
1709c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1710c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1711944ffaf9SJohnathan Mantey 
1712c21865c4SKonstantin Aladyshev     if (!bootSource)
1713491d8ee7SSantosh Puranik     {
1714c21865c4SKonstantin Aladyshev         return;
1715c21865c4SKonstantin Aladyshev     }
1716c21865c4SKonstantin Aladyshev 
1717491d8ee7SSantosh Puranik     // Source target specified
171862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1719491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1720ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1721ac106bf6SEd Tanous                              bootModeStr) != 0)
1722491d8ee7SSantosh Puranik     {
172362598e31SEd Tanous         BMCWEB_LOG_DEBUG(
172462598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
172562598e31SEd Tanous             *bootSource);
1726ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1727491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1728491d8ee7SSantosh Puranik         return;
1729491d8ee7SSantosh Puranik     }
1730491d8ee7SSantosh Puranik 
1731944ffaf9SJohnathan Mantey     // Act on validated parameters
173262598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
173362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1734944ffaf9SJohnathan Mantey 
17359ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17369ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17379ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17389ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
1739ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1740491d8ee7SSantosh Puranik         if (ec)
1741491d8ee7SSantosh Puranik         {
1742b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1743ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1744491d8ee7SSantosh Puranik             return;
1745491d8ee7SSantosh Puranik         }
174662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source update done.");
17479ae226faSGeorge Liu     });
1748944ffaf9SJohnathan Mantey 
17499ae226faSGeorge Liu     sdbusplus::asio::setProperty(
17509ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
17519ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/boot",
17529ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
1753ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
1754491d8ee7SSantosh Puranik         if (ec)
1755491d8ee7SSantosh Puranik         {
1756b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1757ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1758491d8ee7SSantosh Puranik             return;
1759491d8ee7SSantosh Puranik         }
176062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode update done.");
17619ae226faSGeorge Liu     });
1762cd9a4666SKonstantin Aladyshev }
1763944ffaf9SJohnathan Mantey 
1764cd9a4666SKonstantin Aladyshev /**
1765c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1766491d8ee7SSantosh Puranik  *
1767ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1768491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1769cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1770491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1771491d8ee7SSantosh Puranik  *
1772265c1602SJohnathan Mantey  * @return Integer error code.
1773491d8ee7SSantosh Puranik  */
1774c21865c4SKonstantin Aladyshev 
1775ac106bf6SEd Tanous inline void
1776ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1777c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1778c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1779c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1780491d8ee7SSantosh Puranik {
178162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1782491d8ee7SSantosh Puranik 
1783ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1784ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1785ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1786491d8ee7SSantosh Puranik }
1787491d8ee7SSantosh Puranik 
1788c6a620f2SGeorge Liu /**
178998e386ecSGunnar Mills  * @brief Sets AssetTag
179098e386ecSGunnar Mills  *
1791ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
179298e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
179398e386ecSGunnar Mills  *
179498e386ecSGunnar Mills  * @return None.
179598e386ecSGunnar Mills  */
1796ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
179798e386ecSGunnar Mills                         const std::string& assetTag)
179898e386ecSGunnar Mills {
1799e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1800e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1801e99073f5SGeorge Liu     dbus::utility::getSubTree(
1802e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1803ac106bf6SEd Tanous         [asyncResp,
1804e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1805b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
180698e386ecSGunnar Mills         if (ec)
180798e386ecSGunnar Mills         {
180862598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1809ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
181098e386ecSGunnar Mills             return;
181198e386ecSGunnar Mills         }
181226f6976fSEd Tanous         if (subtree.empty())
181398e386ecSGunnar Mills         {
181462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1815ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
181698e386ecSGunnar Mills             return;
181798e386ecSGunnar Mills         }
181898e386ecSGunnar Mills         // Assume only 1 system D-Bus object
181998e386ecSGunnar Mills         // Throw an error if there is more than 1
182098e386ecSGunnar Mills         if (subtree.size() > 1)
182198e386ecSGunnar Mills         {
182262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1823ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
182498e386ecSGunnar Mills             return;
182598e386ecSGunnar Mills         }
182698e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
182798e386ecSGunnar Mills         {
182862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1829ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
183098e386ecSGunnar Mills             return;
183198e386ecSGunnar Mills         }
183298e386ecSGunnar Mills 
183398e386ecSGunnar Mills         const std::string& path = subtree[0].first;
183498e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
183598e386ecSGunnar Mills 
183698e386ecSGunnar Mills         if (service.empty())
183798e386ecSGunnar Mills         {
183862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1839ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
184098e386ecSGunnar Mills             return;
184198e386ecSGunnar Mills         }
184298e386ecSGunnar Mills 
18439ae226faSGeorge Liu         sdbusplus::asio::setProperty(
18449ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
18459ae226faSGeorge Liu             "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
18469ae226faSGeorge Liu             assetTag, [asyncResp](const boost::system::error_code& ec2) {
184798e386ecSGunnar Mills             if (ec2)
184898e386ecSGunnar Mills             {
1849b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
185062598e31SEd Tanous                                  ec2);
1851ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
185298e386ecSGunnar Mills                 return;
185398e386ecSGunnar Mills             }
18549ae226faSGeorge Liu         });
1855e99073f5SGeorge Liu     });
185698e386ecSGunnar Mills }
185798e386ecSGunnar Mills 
185898e386ecSGunnar Mills /**
18599dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
18609dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
18619dcfe8c1SAlbert Zhang  *
18629dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
18639dcfe8c1SAlbert Zhang  * stopBootOnFault
18649dcfe8c1SAlbert Zhang  *
18659dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
18669dcfe8c1SAlbert Zhang  */
18679dcfe8c1SAlbert Zhang inline std::optional<bool>
18689dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
18699dcfe8c1SAlbert Zhang {
18709dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
18719dcfe8c1SAlbert Zhang     {
18729dcfe8c1SAlbert Zhang         return true;
18739dcfe8c1SAlbert Zhang     }
18749dcfe8c1SAlbert Zhang 
18759dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18769dcfe8c1SAlbert Zhang     {
18779dcfe8c1SAlbert Zhang         return false;
18789dcfe8c1SAlbert Zhang     }
18799dcfe8c1SAlbert Zhang 
18809dcfe8c1SAlbert Zhang     return std::nullopt;
18819dcfe8c1SAlbert Zhang }
18829dcfe8c1SAlbert Zhang 
18839dcfe8c1SAlbert Zhang /**
18849dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18859dcfe8c1SAlbert Zhang  *
1886fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18879dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18889dcfe8c1SAlbert Zhang  *
18899dcfe8c1SAlbert Zhang  * @return None.
18909dcfe8c1SAlbert Zhang  */
1891fc3edfddSEd Tanous inline void
1892fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18939dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18949dcfe8c1SAlbert Zhang {
189562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18969dcfe8c1SAlbert Zhang 
18979dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18989dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18999dcfe8c1SAlbert Zhang     {
190062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
190162598e31SEd Tanous                          stopBootOnFault);
1902fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
19039dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
19049dcfe8c1SAlbert Zhang         return;
19059dcfe8c1SAlbert Zhang     }
19069dcfe8c1SAlbert Zhang 
1907fc3edfddSEd Tanous     sdbusplus::asio::setProperty(
1908fc3edfddSEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19099dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
1910fc3edfddSEd Tanous         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1911fc3edfddSEd Tanous         *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
19129dcfe8c1SAlbert Zhang         if (ec)
19139dcfe8c1SAlbert Zhang         {
19149dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
19159dcfe8c1SAlbert Zhang             {
1916b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1917fc3edfddSEd Tanous                 messages::internalError(asyncResp->res);
19189dcfe8c1SAlbert Zhang             }
19199dcfe8c1SAlbert Zhang             return;
19209dcfe8c1SAlbert Zhang         }
19219dcfe8c1SAlbert Zhang     });
19229dcfe8c1SAlbert Zhang }
19239dcfe8c1SAlbert Zhang 
19249dcfe8c1SAlbert Zhang /**
192569f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
192669f35306SGunnar Mills  *
1927ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
192869f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
192969f35306SGunnar Mills  *
193069f35306SGunnar Mills  * @return None.
193169f35306SGunnar Mills  */
1932ac106bf6SEd Tanous inline void
1933ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1934f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
193569f35306SGunnar Mills {
193662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
193769f35306SGunnar Mills 
193869f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1939543f4400SEd Tanous     bool autoRebootEnabled = false;
194069f35306SGunnar Mills 
194169f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
194269f35306SGunnar Mills     {
194369f35306SGunnar Mills         autoRebootEnabled = false;
194469f35306SGunnar Mills     }
194569f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
194669f35306SGunnar Mills     {
194769f35306SGunnar Mills         autoRebootEnabled = true;
194869f35306SGunnar Mills     }
194969f35306SGunnar Mills     else
195069f35306SGunnar Mills     {
195162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
195262598e31SEd Tanous                          automaticRetryConfig);
1953ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
195469f35306SGunnar Mills                                          "AutomaticRetryConfig");
195569f35306SGunnar Mills         return;
195669f35306SGunnar Mills     }
195769f35306SGunnar Mills 
19589ae226faSGeorge Liu     sdbusplus::asio::setProperty(
19599ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
19609ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/auto_reboot",
19619ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
19629ae226faSGeorge Liu         autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
196369f35306SGunnar Mills         if (ec)
196469f35306SGunnar Mills         {
1965b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1966ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
196769f35306SGunnar Mills             return;
196869f35306SGunnar Mills         }
19699ae226faSGeorge Liu     });
197069f35306SGunnar Mills }
197169f35306SGunnar Mills 
19728d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
19738d69c668SEd Tanous {
19748d69c668SEd Tanous     if (policy == "AlwaysOn")
19758d69c668SEd Tanous     {
19768d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
19778d69c668SEd Tanous     }
19788d69c668SEd Tanous     if (policy == "AlwaysOff")
19798d69c668SEd Tanous     {
19808d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
19818d69c668SEd Tanous     }
19828d69c668SEd Tanous     if (policy == "LastState")
19838d69c668SEd Tanous     {
19848d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
19858d69c668SEd Tanous     }
19868d69c668SEd Tanous     return "";
19878d69c668SEd Tanous }
19888d69c668SEd Tanous 
198969f35306SGunnar Mills /**
1990c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1991c6a620f2SGeorge Liu  *
1992ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1993c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1994c6a620f2SGeorge Liu  *
1995c6a620f2SGeorge Liu  * @return None.
1996c6a620f2SGeorge Liu  */
19978d1b46d7Szhanghch05 inline void
1998ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19998d69c668SEd Tanous                           std::string_view policy)
2000c6a620f2SGeorge Liu {
200162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
2002c6a620f2SGeorge Liu 
20038d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
2004c6a620f2SGeorge Liu 
20058d69c668SEd Tanous     if (powerRestorePolicy.empty())
2006c6a620f2SGeorge Liu     {
2007ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
20084e69c904SGunnar Mills                                          "PowerRestorePolicy");
2009c6a620f2SGeorge Liu         return;
2010c6a620f2SGeorge Liu     }
2011c6a620f2SGeorge Liu 
20129ae226faSGeorge Liu     sdbusplus::asio::setProperty(
20139ae226faSGeorge Liu         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
20149ae226faSGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
20159ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
20169ae226faSGeorge Liu         powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2017c6a620f2SGeorge Liu         if (ec)
2018c6a620f2SGeorge Liu         {
2019b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2020ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2021c6a620f2SGeorge Liu             return;
2022c6a620f2SGeorge Liu         }
20239ae226faSGeorge Liu     });
2024c6a620f2SGeorge Liu }
2025c6a620f2SGeorge Liu 
2026a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2027a6349918SAppaRao Puli /**
2028a6349918SAppaRao Puli  * @brief Retrieves provisioning status
2029a6349918SAppaRao Puli  *
2030ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
2031a6349918SAppaRao Puli  *
2032a6349918SAppaRao Puli  * @return None.
2033a6349918SAppaRao Puli  */
2034ac106bf6SEd Tanous inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
2035a6349918SAppaRao Puli {
203662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
2037bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2038bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2039bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
2040ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2041b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
2042b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
2043ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2044ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
204550626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
204650626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
204750626f4fSJames Feist 
2048a6349918SAppaRao Puli         if (ec)
2049a6349918SAppaRao Puli         {
205062598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2051b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
2052b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2053a6349918SAppaRao Puli             return;
2054a6349918SAppaRao Puli         }
2055a6349918SAppaRao Puli 
2056a6349918SAppaRao Puli         const bool* provState = nullptr;
2057a6349918SAppaRao Puli         const bool* lockState = nullptr;
2058bc1d29deSKrzysztof Grobelny 
2059bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
20600d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
20610d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
2062bc1d29deSKrzysztof Grobelny 
2063bc1d29deSKrzysztof Grobelny         if (!success)
2064a6349918SAppaRao Puli         {
2065ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2066bc1d29deSKrzysztof Grobelny             return;
2067a6349918SAppaRao Puli         }
2068a6349918SAppaRao Puli 
2069a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
2070a6349918SAppaRao Puli         {
207162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2072ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2073a6349918SAppaRao Puli             return;
2074a6349918SAppaRao Puli         }
2075a6349918SAppaRao Puli 
2076a6349918SAppaRao Puli         if (*provState == true)
2077a6349918SAppaRao Puli         {
2078a6349918SAppaRao Puli             if (*lockState == true)
2079a6349918SAppaRao Puli             {
2080a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2081a6349918SAppaRao Puli             }
2082a6349918SAppaRao Puli             else
2083a6349918SAppaRao Puli             {
2084a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2085a6349918SAppaRao Puli             }
2086a6349918SAppaRao Puli         }
2087a6349918SAppaRao Puli         else
2088a6349918SAppaRao Puli         {
2089a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
2090a6349918SAppaRao Puli         }
2091bc1d29deSKrzysztof Grobelny     });
2092a6349918SAppaRao Puli }
2093a6349918SAppaRao Puli #endif
2094a6349918SAppaRao Puli 
2095491d8ee7SSantosh Puranik /**
20966b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20973a2d0424SChris Cain  *
20986b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20993a2d0424SChris Cain  *
21006b9ac4f2SChris Cain  * @return PowerMode enum
21013a2d0424SChris Cain  */
21026b9ac4f2SChris Cain inline computer_system::PowerMode
21036b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
21043a2d0424SChris Cain {
2105b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2106b6655101SChris Cain 
21076b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
21083a2d0424SChris Cain     {
21096b9ac4f2SChris Cain         return PowerMode::Static;
21103a2d0424SChris Cain     }
21116b9ac4f2SChris Cain     if (modeString ==
21120fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
21133a2d0424SChris Cain     {
21146b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
21153a2d0424SChris Cain     }
21166b9ac4f2SChris Cain     if (modeString ==
21170fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
21183a2d0424SChris Cain     {
21196b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2120b6655101SChris Cain     }
21216b9ac4f2SChris Cain     if (modeString ==
2122b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2123b6655101SChris Cain     {
21246b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2125b6655101SChris Cain     }
21266b9ac4f2SChris Cain     if (modeString ==
2127b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2128b6655101SChris Cain     {
21296b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2130b6655101SChris Cain     }
21316b9ac4f2SChris Cain     if (modeString ==
2132b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2133b6655101SChris Cain     {
21346b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
21353a2d0424SChris Cain     }
21366b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
21373a2d0424SChris Cain     {
21386b9ac4f2SChris Cain         return PowerMode::OEM;
21396b9ac4f2SChris Cain     }
21406b9ac4f2SChris Cain     // Any other values would be invalid
21416b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
21426b9ac4f2SChris Cain     return PowerMode::Invalid;
21436b9ac4f2SChris Cain }
21446b9ac4f2SChris Cain 
21456b9ac4f2SChris Cain inline void
21466b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21476b9ac4f2SChris Cain                       const boost::system::error_code& ec,
21486b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
21496b9ac4f2SChris Cain {
21506b9ac4f2SChris Cain     if (ec)
21516b9ac4f2SChris Cain     {
21526b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
21536b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21546b9ac4f2SChris Cain         return;
21556b9ac4f2SChris Cain     }
21566b9ac4f2SChris Cain 
21576b9ac4f2SChris Cain     std::string powerMode;
21586b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
21596b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
21606b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
21616b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
21626b9ac4f2SChris Cain 
21636b9ac4f2SChris Cain     if (!success)
21646b9ac4f2SChris Cain     {
21656b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21666b9ac4f2SChris Cain         return;
21676b9ac4f2SChris Cain     }
21686b9ac4f2SChris Cain 
21696b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
21706b9ac4f2SChris Cain     if (allowedModes == nullptr)
21716b9ac4f2SChris Cain     {
21726b9ac4f2SChris Cain         modeList.emplace_back("Static");
21736b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
21746b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
21753a2d0424SChris Cain     }
21763a2d0424SChris Cain     else
21773a2d0424SChris Cain     {
21786b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
21796b9ac4f2SChris Cain         {
21806b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
21816b9ac4f2SChris Cain                 translatePowerModeString(aMode);
21826b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
21836b9ac4f2SChris Cain             {
2184ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
21856b9ac4f2SChris Cain                 continue;
21866b9ac4f2SChris Cain             }
21876b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
21883a2d0424SChris Cain         }
21893a2d0424SChris Cain     }
21906b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
21913a2d0424SChris Cain 
21926b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
21936b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
21946b9ac4f2SChris Cain         translatePowerModeString(powerMode);
21956b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
21966b9ac4f2SChris Cain     {
21976b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21986b9ac4f2SChris Cain         return;
21996b9ac4f2SChris Cain     }
22006b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
22016b9ac4f2SChris Cain }
22023a2d0424SChris Cain /**
22033a2d0424SChris Cain  * @brief Retrieves system power mode
22043a2d0424SChris Cain  *
2205ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
22063a2d0424SChris Cain  *
22073a2d0424SChris Cain  * @return None.
22083a2d0424SChris Cain  */
2209ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
22103a2d0424SChris Cain {
221162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
22123a2d0424SChris Cain 
22133a2d0424SChris Cain     // Get Power Mode object path:
2214e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2215e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2216e99073f5SGeorge Liu     dbus::utility::getSubTree(
2217e99073f5SGeorge Liu         "/", 0, interfaces,
2218ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2219b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22203a2d0424SChris Cain         if (ec)
22213a2d0424SChris Cain         {
222262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
222362598e31SEd Tanous                              ec);
22243a2d0424SChris Cain             // This is an optional D-Bus object so just return if
22253a2d0424SChris Cain             // error occurs
22263a2d0424SChris Cain             return;
22273a2d0424SChris Cain         }
22283a2d0424SChris Cain         if (subtree.empty())
22293a2d0424SChris Cain         {
22303a2d0424SChris Cain             // As noted above, this is an optional interface so just return
22313a2d0424SChris Cain             // if there is no instance found
22323a2d0424SChris Cain             return;
22333a2d0424SChris Cain         }
22343a2d0424SChris Cain         if (subtree.size() > 1)
22353a2d0424SChris Cain         {
22363a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22373a2d0424SChris Cain             // error
223862598e31SEd Tanous             BMCWEB_LOG_DEBUG(
223962598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
224062598e31SEd Tanous                 subtree.size());
2241ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22423a2d0424SChris Cain             return;
22433a2d0424SChris Cain         }
22443a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22453a2d0424SChris Cain         {
224662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2247ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22483a2d0424SChris Cain             return;
22493a2d0424SChris Cain         }
22503a2d0424SChris Cain         const std::string& path = subtree[0].first;
22513a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22523a2d0424SChris Cain         if (service.empty())
22533a2d0424SChris Cain         {
225462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2255ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22563a2d0424SChris Cain             return;
22573a2d0424SChris Cain         }
22586b9ac4f2SChris Cain 
22596b9ac4f2SChris Cain         // Valid Power Mode object found, now read the mode properties
22606b9ac4f2SChris Cain         sdbusplus::asio::getAllProperties(
22611e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
22626b9ac4f2SChris Cain             "xyz.openbmc_project.Control.Power.Mode",
2263ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
22646b9ac4f2SChris Cain                         const dbus::utility::DBusPropertiesMap& properties) {
22656b9ac4f2SChris Cain             afterGetPowerMode(asyncResp, ec2, properties);
22661e1e598dSJonathan Doman         });
2267e99073f5SGeorge Liu     });
22683a2d0424SChris Cain }
22693a2d0424SChris Cain 
22703a2d0424SChris Cain /**
22713a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
22723a2d0424SChris Cain  * name associated with that string
22733a2d0424SChris Cain  *
2274ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2275b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
22763a2d0424SChris Cain  *
22773a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22783a2d0424SChris Cain  */
22793a2d0424SChris Cain inline std::string
2280ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2281b6655101SChris Cain                       const nlohmann::json& modeValue)
22823a2d0424SChris Cain {
2283b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
22843a2d0424SChris Cain     std::string mode;
22853a2d0424SChris Cain 
2286b6655101SChris Cain     if (modeValue == PowerMode::Static)
22873a2d0424SChris Cain     {
22883a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22893a2d0424SChris Cain     }
2290b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
22913a2d0424SChris Cain     {
22920fda0f12SGeorge Liu         mode =
22930fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
22943a2d0424SChris Cain     }
2295b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
22963a2d0424SChris Cain     {
22973a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22983a2d0424SChris Cain     }
2299b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2300b6655101SChris Cain     {
2301b6655101SChris Cain         mode =
2302b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2303b6655101SChris Cain     }
2304b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2305b6655101SChris Cain     {
2306b6655101SChris Cain         mode =
2307b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2308b6655101SChris Cain     }
2309b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2310b6655101SChris Cain     {
2311b6655101SChris Cain         mode =
2312b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2313b6655101SChris Cain     }
23143a2d0424SChris Cain     else
23153a2d0424SChris Cain     {
2316b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2317ac106bf6SEd Tanous                                          "PowerMode");
23183a2d0424SChris Cain     }
23193a2d0424SChris Cain     return mode;
23203a2d0424SChris Cain }
23213a2d0424SChris Cain 
23223a2d0424SChris Cain /**
23233a2d0424SChris Cain  * @brief Sets system power mode.
23243a2d0424SChris Cain  *
2325ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
23263a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
23273a2d0424SChris Cain  *
23283a2d0424SChris Cain  * @return None.
23293a2d0424SChris Cain  */
2330ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23313a2d0424SChris Cain                          const std::string& pmode)
23323a2d0424SChris Cain {
233362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
23343a2d0424SChris Cain 
2335ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
23363a2d0424SChris Cain     if (powerMode.empty())
23373a2d0424SChris Cain     {
23383a2d0424SChris Cain         return;
23393a2d0424SChris Cain     }
23403a2d0424SChris Cain 
23413a2d0424SChris Cain     // Get Power Mode object path:
2342e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2343e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2344e99073f5SGeorge Liu     dbus::utility::getSubTree(
2345e99073f5SGeorge Liu         "/", 0, interfaces,
2346ac106bf6SEd Tanous         [asyncResp,
2347e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2348b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
23493a2d0424SChris Cain         if (ec)
23503a2d0424SChris Cain         {
2351b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
235262598e31SEd Tanous                              ec);
23533a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2354ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23553a2d0424SChris Cain             return;
23563a2d0424SChris Cain         }
23573a2d0424SChris Cain         if (subtree.empty())
23583a2d0424SChris Cain         {
23593a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2360ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
23613a2d0424SChris Cain                                        "PowerMode");
23623a2d0424SChris Cain             return;
23633a2d0424SChris Cain         }
23643a2d0424SChris Cain         if (subtree.size() > 1)
23653a2d0424SChris Cain         {
23663a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
23673a2d0424SChris Cain             // error
236862598e31SEd Tanous             BMCWEB_LOG_DEBUG(
236962598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
237062598e31SEd Tanous                 subtree.size());
2371ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23723a2d0424SChris Cain             return;
23733a2d0424SChris Cain         }
23743a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
23753a2d0424SChris Cain         {
237662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2377ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23783a2d0424SChris Cain             return;
23793a2d0424SChris Cain         }
23803a2d0424SChris Cain         const std::string& path = subtree[0].first;
23813a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
23823a2d0424SChris Cain         if (service.empty())
23833a2d0424SChris Cain         {
238462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2385ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
23863a2d0424SChris Cain             return;
23873a2d0424SChris Cain         }
23883a2d0424SChris Cain 
238962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
23903a2d0424SChris Cain 
23913a2d0424SChris Cain         // Set the Power Mode property
23929ae226faSGeorge Liu         sdbusplus::asio::setProperty(
23939ae226faSGeorge Liu             *crow::connections::systemBus, service, path,
23949ae226faSGeorge Liu             "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
2395ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2) {
23968a592810SEd Tanous             if (ec2)
23973a2d0424SChris Cain             {
2398b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2399ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
24003a2d0424SChris Cain                 return;
24013a2d0424SChris Cain             }
24029ae226faSGeorge Liu         });
2403e99073f5SGeorge Liu     });
24043a2d0424SChris Cain }
24053a2d0424SChris Cain 
24063a2d0424SChris Cain /**
240751709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
240851709ffdSYong Li  *
240951709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
241051709ffdSYong Li  *
241151709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
241251709ffdSYong Li  * translation cannot be done, returns an empty string.
241351709ffdSYong Li  */
241423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
241551709ffdSYong Li {
241651709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
241751709ffdSYong Li     {
241851709ffdSYong Li         return "None";
241951709ffdSYong Li     }
24203174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
242151709ffdSYong Li     {
242251709ffdSYong Li         return "ResetSystem";
242351709ffdSYong Li     }
24243174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
242551709ffdSYong Li     {
242651709ffdSYong Li         return "PowerDown";
242751709ffdSYong Li     }
24283174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
242951709ffdSYong Li     {
243051709ffdSYong Li         return "PowerCycle";
243151709ffdSYong Li     }
243251709ffdSYong Li 
243351709ffdSYong Li     return "";
243451709ffdSYong Li }
243551709ffdSYong Li 
243651709ffdSYong Li /**
2437c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2438c45f0082SYong Li  *
2439c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2440c45f0082SYong Li  *
2441c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2442c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2443c45f0082SYong Li  */
2444c45f0082SYong Li 
244523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2446c45f0082SYong Li {
2447c45f0082SYong Li     if (rfAction == "None")
2448c45f0082SYong Li     {
2449c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2450c45f0082SYong Li     }
24513174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2452c45f0082SYong Li     {
2453c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2454c45f0082SYong Li     }
24553174e4dfSEd Tanous     if (rfAction == "PowerDown")
2456c45f0082SYong Li     {
2457c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2458c45f0082SYong Li     }
24593174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2460c45f0082SYong Li     {
2461c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2462c45f0082SYong Li     }
2463c45f0082SYong Li 
2464c45f0082SYong Li     return "";
2465c45f0082SYong Li }
2466c45f0082SYong Li 
2467c45f0082SYong Li /**
246851709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
246951709ffdSYong Li  *
2470ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
247151709ffdSYong Li  *
247251709ffdSYong Li  * @return None.
247351709ffdSYong Li  */
24748d1b46d7Szhanghch05 inline void
2475ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
247651709ffdSYong Li {
247762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2478bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2479bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2480bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2481bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2482ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2483b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
248451709ffdSYong Li         if (ec)
248551709ffdSYong Li         {
248651709ffdSYong Li             // watchdog service is stopped
248762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
248851709ffdSYong Li             return;
248951709ffdSYong Li         }
249051709ffdSYong Li 
249162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
249251709ffdSYong Li 
249351709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2494ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
249551709ffdSYong Li 
249651709ffdSYong Li         // watchdog service is running/enabled
249751709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
249851709ffdSYong Li 
2499bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2500bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
250151709ffdSYong Li 
2502bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2503bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2504bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2505bc1d29deSKrzysztof Grobelny 
2506bc1d29deSKrzysztof Grobelny         if (!success)
250751709ffdSYong Li         {
2508ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2509601af5edSChicago Duan             return;
251051709ffdSYong Li         }
251151709ffdSYong Li 
2512bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
251351709ffdSYong Li         {
2514bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
251551709ffdSYong Li         }
251651709ffdSYong Li 
2517bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2518bc1d29deSKrzysztof Grobelny         {
2519bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
252051709ffdSYong Li             if (action.empty())
252151709ffdSYong Li             {
2522ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2523601af5edSChicago Duan                 return;
252451709ffdSYong Li             }
252551709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
252651709ffdSYong Li         }
2527bc1d29deSKrzysztof Grobelny     });
252851709ffdSYong Li }
252951709ffdSYong Li 
253051709ffdSYong Li /**
2531c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2532c45f0082SYong Li  *
2533ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2534c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2535c45f0082SYong Li  *                       RF request.
2536c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2537c45f0082SYong Li  *
2538c45f0082SYong Li  * @return None.
2539c45f0082SYong Li  */
2540ac106bf6SEd Tanous inline void
2541ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2542c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2543c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2544c45f0082SYong Li {
254562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2546c45f0082SYong Li 
2547c45f0082SYong Li     if (wdtTimeOutAction)
2548c45f0082SYong Li     {
2549c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2550c45f0082SYong Li         // check if TimeOut Action is Valid
2551c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2552c45f0082SYong Li         {
255362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
255462598e31SEd Tanous                              *wdtTimeOutAction);
2555ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2556c45f0082SYong Li                                              "TimeoutAction");
2557c45f0082SYong Li             return;
2558c45f0082SYong Li         }
2559c45f0082SYong Li 
25609ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25619ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25629ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25639ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
25649ae226faSGeorge Liu             wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2565c45f0082SYong Li             if (ec)
2566c45f0082SYong Li             {
2567b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2568ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2569c45f0082SYong Li                 return;
2570c45f0082SYong Li             }
25719ae226faSGeorge Liu         });
2572c45f0082SYong Li     }
2573c45f0082SYong Li 
2574c45f0082SYong Li     if (wdtEnable)
2575c45f0082SYong Li     {
25769ae226faSGeorge Liu         sdbusplus::asio::setProperty(
25779ae226faSGeorge Liu             *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
25789ae226faSGeorge Liu             "/xyz/openbmc_project/watchdog/host0",
25799ae226faSGeorge Liu             "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
2580ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec) {
2581c45f0082SYong Li             if (ec)
2582c45f0082SYong Li             {
2583b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2584ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2585c45f0082SYong Li                 return;
2586c45f0082SYong Li             }
25879ae226faSGeorge Liu         });
2588c45f0082SYong Li     }
2589c45f0082SYong Li }
2590c45f0082SYong Li 
259137bbf98cSChris Cain /**
259237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
259337bbf98cSChris Cain  *
2594ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
259537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
259637bbf98cSChris Cain  *
259737bbf98cSChris Cain  * @return true if successful
259837bbf98cSChris Cain  */
25991e5b7c88SJiaqing Zhao inline bool
2600ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26011e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
260237bbf98cSChris Cain {
2603bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2604bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2605bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2606bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2607bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2608bc1d29deSKrzysztof Grobelny 
2609bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2610bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
26112661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
26122661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
26132661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2614bc1d29deSKrzysztof Grobelny 
2615bc1d29deSKrzysztof Grobelny     if (!success)
261637bbf98cSChris Cain     {
261737bbf98cSChris Cain         return false;
261837bbf98cSChris Cain     }
2619bc1d29deSKrzysztof Grobelny 
2620bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
262137bbf98cSChris Cain     {
2622ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
262337bbf98cSChris Cain     }
2624bc1d29deSKrzysztof Grobelny 
2625bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
262637bbf98cSChris Cain     {
2627ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2628bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
262937bbf98cSChris Cain     }
2630bc1d29deSKrzysztof Grobelny 
2631bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2632bc1d29deSKrzysztof Grobelny     {
2633bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2634ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
263537bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
263637bbf98cSChris Cain                 .count();
263737bbf98cSChris Cain     }
2638bc1d29deSKrzysztof Grobelny 
2639bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
264037bbf98cSChris Cain     {
2641ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2642bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
264337bbf98cSChris Cain     }
2644bc1d29deSKrzysztof Grobelny 
2645bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
264637bbf98cSChris Cain     {
2647bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2648ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
264937bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
265037bbf98cSChris Cain                 .count();
265137bbf98cSChris Cain     }
265237bbf98cSChris Cain 
265337bbf98cSChris Cain     return true;
265437bbf98cSChris Cain }
265537bbf98cSChris Cain 
265637bbf98cSChris Cain /**
265737bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
265837bbf98cSChris Cain  *
2659ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
266037bbf98cSChris Cain  *
266137bbf98cSChris Cain  * @return None.
266237bbf98cSChris Cain  */
2663ac106bf6SEd Tanous inline void
2664ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
266537bbf98cSChris Cain {
266662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
266737bbf98cSChris Cain 
266837bbf98cSChris Cain     // Get IdlePowerSaver object path:
2669e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2670e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2671e99073f5SGeorge Liu     dbus::utility::getSubTree(
2672e99073f5SGeorge Liu         "/", 0, interfaces,
2673ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2674b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
267537bbf98cSChris Cain         if (ec)
267637bbf98cSChris Cain         {
2677b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
267862598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
267962598e31SEd Tanous                 ec);
2680ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
268137bbf98cSChris Cain             return;
268237bbf98cSChris Cain         }
268337bbf98cSChris Cain         if (subtree.empty())
268437bbf98cSChris Cain         {
268537bbf98cSChris Cain             // This is an optional interface so just return
268637bbf98cSChris Cain             // if there is no instance found
268762598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
268837bbf98cSChris Cain             return;
268937bbf98cSChris Cain         }
269037bbf98cSChris Cain         if (subtree.size() > 1)
269137bbf98cSChris Cain         {
269237bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
269337bbf98cSChris Cain             // is an error
269462598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
269562598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
269662598e31SEd Tanous                              subtree.size());
2697ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269837bbf98cSChris Cain             return;
269937bbf98cSChris Cain         }
270037bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
270137bbf98cSChris Cain         {
270262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2703ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
270437bbf98cSChris Cain             return;
270537bbf98cSChris Cain         }
270637bbf98cSChris Cain         const std::string& path = subtree[0].first;
270737bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
270837bbf98cSChris Cain         if (service.empty())
270937bbf98cSChris Cain         {
271062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2711ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
271237bbf98cSChris Cain             return;
271337bbf98cSChris Cain         }
271437bbf98cSChris Cain 
271537bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2716bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2717bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2718bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2719ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
27201e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
27218a592810SEd Tanous             if (ec2)
272237bbf98cSChris Cain             {
272362598e31SEd Tanous                 BMCWEB_LOG_ERROR(
272462598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2725ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
272637bbf98cSChris Cain                 return;
272737bbf98cSChris Cain             }
272837bbf98cSChris Cain 
2729ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
273037bbf98cSChris Cain             {
2731ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
273237bbf98cSChris Cain                 return;
273337bbf98cSChris Cain             }
2734bc1d29deSKrzysztof Grobelny         });
2735e99073f5SGeorge Liu     });
273637bbf98cSChris Cain 
273762598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
273837bbf98cSChris Cain }
273937bbf98cSChris Cain 
274037bbf98cSChris Cain /**
274137bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
274237bbf98cSChris Cain  *
2743ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
274437bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
274537bbf98cSChris Cain  *                       RF request.
274637bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
274737bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
274837bbf98cSChris Cain  * before entering idle state.
274937bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
275037bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
275137bbf98cSChris Cain  * before exiting idle state
275237bbf98cSChris Cain  *
275337bbf98cSChris Cain  * @return None.
275437bbf98cSChris Cain  */
2755ac106bf6SEd Tanous inline void
2756ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
275737bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
275837bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
275937bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
276037bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
276137bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
276237bbf98cSChris Cain {
276362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
276437bbf98cSChris Cain 
276537bbf98cSChris Cain     // Get IdlePowerSaver object path:
2766e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2767e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2768e99073f5SGeorge Liu     dbus::utility::getSubTree(
2769e99073f5SGeorge Liu         "/", 0, interfaces,
2770ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2771e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2772b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
277337bbf98cSChris Cain         if (ec)
277437bbf98cSChris Cain         {
2775b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
277662598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
277762598e31SEd Tanous                 ec);
2778ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
277937bbf98cSChris Cain             return;
278037bbf98cSChris Cain         }
278137bbf98cSChris Cain         if (subtree.empty())
278237bbf98cSChris Cain         {
278337bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2784ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
278537bbf98cSChris Cain                                        "IdlePowerSaver");
278637bbf98cSChris Cain             return;
278737bbf98cSChris Cain         }
278837bbf98cSChris Cain         if (subtree.size() > 1)
278937bbf98cSChris Cain         {
279037bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
279137bbf98cSChris Cain             // is an error
279262598e31SEd Tanous             BMCWEB_LOG_DEBUG(
279362598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
279462598e31SEd Tanous                 subtree.size());
2795ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
279637bbf98cSChris Cain             return;
279737bbf98cSChris Cain         }
279837bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
279937bbf98cSChris Cain         {
280062598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2801ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
280237bbf98cSChris Cain             return;
280337bbf98cSChris Cain         }
280437bbf98cSChris Cain         const std::string& path = subtree[0].first;
280537bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
280637bbf98cSChris Cain         if (service.empty())
280737bbf98cSChris Cain         {
280862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2809ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
281037bbf98cSChris Cain             return;
281137bbf98cSChris Cain         }
281237bbf98cSChris Cain 
281337bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
281437bbf98cSChris Cain         // need to be updated
281537bbf98cSChris Cain 
281637bbf98cSChris Cain         if (ipsEnable)
281737bbf98cSChris Cain         {
28189ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28199ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28209ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
28219ae226faSGeorge Liu                 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
28228a592810SEd Tanous                 if (ec2)
282337bbf98cSChris Cain                 {
2824b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2825ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
282637bbf98cSChris Cain                     return;
282737bbf98cSChris Cain                 }
28289ae226faSGeorge Liu             });
282937bbf98cSChris Cain         }
283037bbf98cSChris Cain         if (ipsEnterUtil)
283137bbf98cSChris Cain         {
28329ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28339ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28349ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28359ae226faSGeorge Liu                 "EnterUtilizationPercent", *ipsEnterUtil,
2836ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28378a592810SEd Tanous                 if (ec2)
283837bbf98cSChris Cain                 {
2839b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2840ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
284137bbf98cSChris Cain                     return;
284237bbf98cSChris Cain                 }
28439ae226faSGeorge Liu             });
284437bbf98cSChris Cain         }
284537bbf98cSChris Cain         if (ipsEnterTime)
284637bbf98cSChris Cain         {
284737bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
284837bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
28499ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28509ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28519ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28529ae226faSGeorge Liu                 "EnterDwellTime", timeMilliseconds,
2853ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28548a592810SEd Tanous                 if (ec2)
285537bbf98cSChris Cain                 {
2856b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2857ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
285837bbf98cSChris Cain                     return;
285937bbf98cSChris Cain                 }
28609ae226faSGeorge Liu             });
286137bbf98cSChris Cain         }
286237bbf98cSChris Cain         if (ipsExitUtil)
286337bbf98cSChris Cain         {
28649ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28659ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28669ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28679ae226faSGeorge Liu                 "ExitUtilizationPercent", *ipsExitUtil,
2868ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28698a592810SEd Tanous                 if (ec2)
287037bbf98cSChris Cain                 {
2871b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2872ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
287337bbf98cSChris Cain                     return;
287437bbf98cSChris Cain                 }
28759ae226faSGeorge Liu             });
287637bbf98cSChris Cain         }
287737bbf98cSChris Cain         if (ipsExitTime)
287837bbf98cSChris Cain         {
287937bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
288037bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
28819ae226faSGeorge Liu             sdbusplus::asio::setProperty(
28829ae226faSGeorge Liu                 *crow::connections::systemBus, service, path,
28839ae226faSGeorge Liu                 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
28849ae226faSGeorge Liu                 "ExitDwellTime", timeMilliseconds,
2885ac106bf6SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
28868a592810SEd Tanous                 if (ec2)
288737bbf98cSChris Cain                 {
2888b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2889ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
289037bbf98cSChris Cain                     return;
289137bbf98cSChris Cain                 }
28929ae226faSGeorge Liu             });
289337bbf98cSChris Cain         }
2894e99073f5SGeorge Liu     });
289537bbf98cSChris Cain 
289662598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
289737bbf98cSChris Cain }
289837bbf98cSChris Cain 
2899c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2900dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2901dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2902dd60b9edSEd Tanous {
2903dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2904dd60b9edSEd Tanous     {
2905dd60b9edSEd Tanous         return;
2906dd60b9edSEd Tanous     }
2907dd60b9edSEd Tanous     asyncResp->res.addHeader(
2908dd60b9edSEd Tanous         boost::beast::http::field::link,
2909dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2910dd60b9edSEd Tanous }
2911dd60b9edSEd Tanous 
2912c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2913c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2914c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29151abe55efSEd Tanous {
29163ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2917f4c99e70SEd Tanous     {
2918f4c99e70SEd Tanous         return;
2919f4c99e70SEd Tanous     }
2920dd60b9edSEd Tanous 
2921dd60b9edSEd Tanous     asyncResp->res.addHeader(
2922dd60b9edSEd Tanous         boost::beast::http::field::link,
2923dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
29248d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
29250f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
29268d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
29278d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2928462023adSSunitha Harish 
29297f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
29307f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
29317f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
29327f3e84a1SEd Tanous     {
29337f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
29347f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29357f3e84a1SEd Tanous         return;
29367f3e84a1SEd Tanous     }
29377f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
29387f3e84a1SEd Tanous     nlohmann::json::object_t system;
29397f3e84a1SEd Tanous     system["@odata.id"] = "/redfish/v1/Systems/system";
29407f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
29411e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2942002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
29431e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2944002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
29455e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
29461e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
29477f3e84a1SEd Tanous         if (ec2)
2948462023adSSunitha Harish         {
29497f3e84a1SEd Tanous             return;
29507f3e84a1SEd Tanous         }
29517f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
29527f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
29537f3e84a1SEd Tanous         {
295462598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29557f3e84a1SEd Tanous             return;
29567f3e84a1SEd Tanous         }
29577f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
29587f3e84a1SEd Tanous         if (count == nullptr)
29597f3e84a1SEd Tanous         {
296062598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
29617f3e84a1SEd Tanous             return;
29627f3e84a1SEd Tanous         }
29637f3e84a1SEd Tanous         *count = *count + 1;
296462598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
29657f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
29661476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2967002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
29687f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
29691e1e598dSJonathan Doman     });
2970c1e219d5SEd Tanous }
2971c1e219d5SEd Tanous 
2972c1e219d5SEd Tanous /**
29737e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
29747e860f15SJohn Edward Broadbent  */
29754f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
29767e860f15SJohn Edward Broadbent {
297789492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
297889492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
297989492a15SPatrick Williams     constexpr const char* interfaceName =
29807e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
298189492a15SPatrick Williams     constexpr const char* method = "NMI";
29827e860f15SJohn Edward Broadbent 
29837e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
29845e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
29857e860f15SJohn Edward Broadbent         if (ec)
29867e860f15SJohn Edward Broadbent         {
298762598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
29887e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
29897e860f15SJohn Edward Broadbent             return;
29907e860f15SJohn Edward Broadbent         }
29917e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
29927e860f15SJohn Edward Broadbent     },
29937e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
29947e860f15SJohn Edward Broadbent }
2995c5b2abe0SLewanczyk, Dawid 
2996c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2997c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
29987f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2999c1e219d5SEd Tanous     const std::string& systemName)
3000c1e219d5SEd Tanous {
30013ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
300245ca1b86SEd Tanous     {
300345ca1b86SEd Tanous         return;
300445ca1b86SEd Tanous     }
3005c1e219d5SEd Tanous     if (systemName != "system")
3006c1e219d5SEd Tanous     {
3007c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3008c1e219d5SEd Tanous                                    systemName);
3009c1e219d5SEd Tanous         return;
3010c1e219d5SEd Tanous     }
30117f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
30127f3e84a1SEd Tanous     {
30137f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
30147f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3015c1e219d5SEd Tanous                                    systemName);
30167f3e84a1SEd Tanous         return;
30177f3e84a1SEd Tanous     }
30189712f8acSEd Tanous     std::string resetType;
3019c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3020cc340dd9SEd Tanous     {
3021cc340dd9SEd Tanous         return;
3022cc340dd9SEd Tanous     }
3023cc340dd9SEd Tanous 
3024d22c8396SJason M. Bills     // Get the command and host vs. chassis
3025cc340dd9SEd Tanous     std::string command;
3026543f4400SEd Tanous     bool hostCommand = true;
3027d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
3028cc340dd9SEd Tanous     {
3029cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
3030d22c8396SJason M. Bills         hostCommand = true;
3031d22c8396SJason M. Bills     }
3032d22c8396SJason M. Bills     else if (resetType == "ForceOff")
3033d22c8396SJason M. Bills     {
3034d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3035d22c8396SJason M. Bills         hostCommand = false;
3036d22c8396SJason M. Bills     }
3037d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
3038d22c8396SJason M. Bills     {
3039c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
304086a0851aSJason M. Bills         hostCommand = true;
3041cc340dd9SEd Tanous     }
30429712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
3043cc340dd9SEd Tanous     {
3044cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
3045d22c8396SJason M. Bills         hostCommand = true;
3046cc340dd9SEd Tanous     }
30479712f8acSEd Tanous     else if (resetType == "GracefulRestart")
3048cc340dd9SEd Tanous     {
30490fda0f12SGeorge Liu         command =
30500fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3051d22c8396SJason M. Bills         hostCommand = true;
3052d22c8396SJason M. Bills     }
3053d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
3054d22c8396SJason M. Bills     {
305586a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
305686a0851aSJason M. Bills         hostCommand = true;
3057cc340dd9SEd Tanous     }
3058bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
3059bfd5b826SLakshminarayana R. Kammath     {
3060bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
3061bfd5b826SLakshminarayana R. Kammath         return;
3062bfd5b826SLakshminarayana R. Kammath     }
3063cc340dd9SEd Tanous     else
3064cc340dd9SEd Tanous     {
3065c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3066cc340dd9SEd Tanous         return;
3067cc340dd9SEd Tanous     }
3068d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
3069cc340dd9SEd Tanous 
3070d22c8396SJason M. Bills     if (hostCommand)
3071d22c8396SJason M. Bills     {
3072d02aad39SEd Tanous         setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host",
3073d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
3074d02aad39SEd Tanous                         "RequestedHostTransition", "Reset", command);
3075cc340dd9SEd Tanous     }
3076d22c8396SJason M. Bills     else
3077d22c8396SJason M. Bills     {
3078d02aad39SEd Tanous         setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis",
3079d02aad39SEd Tanous                         statePath / "chassis0",
3080d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
3081d02aad39SEd Tanous                         "RequestedPowerTransition", "Reset", command);
3082d22c8396SJason M. Bills     }
3083d22c8396SJason M. Bills }
3084cc340dd9SEd Tanous 
3085c1e219d5SEd Tanous inline void handleComputerSystemHead(
3086dd60b9edSEd Tanous     App& app, const crow::Request& req,
30877f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30887f3e84a1SEd Tanous     const std::string& /*systemName*/)
3089dd60b9edSEd Tanous {
3090dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3091dd60b9edSEd Tanous     {
3092dd60b9edSEd Tanous         return;
3093dd60b9edSEd Tanous     }
3094dd60b9edSEd Tanous 
3095dd60b9edSEd Tanous     asyncResp->res.addHeader(
3096dd60b9edSEd Tanous         boost::beast::http::field::link,
3097dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3098dd60b9edSEd Tanous }
3099dd60b9edSEd Tanous 
31005c3e9272SAbhishek Patel inline void afterPortRequest(
31015c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31025c3e9272SAbhishek Patel     const boost::system::error_code& ec,
31035c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
31045c3e9272SAbhishek Patel {
31055c3e9272SAbhishek Patel     if (ec)
31065c3e9272SAbhishek Patel     {
3107b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
31085c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
31095c3e9272SAbhishek Patel         return;
31105c3e9272SAbhishek Patel     }
31115c3e9272SAbhishek Patel     for (const auto& data : socketData)
31125c3e9272SAbhishek Patel     {
31135c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
31145c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
31155c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
31165c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
31175c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
31185c3e9272SAbhishek Patel         // need to retrieve port number for
31195c3e9272SAbhishek Patel         // obmc-console-ssh service
31205c3e9272SAbhishek Patel         if (protocolName == "SSH")
31215c3e9272SAbhishek Patel         {
31225c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
312381c4e330SEd Tanous                                           const boost::system::error_code& ec1,
31245c3e9272SAbhishek Patel                                           int portNumber) {
31255c3e9272SAbhishek Patel                 if (ec1)
31265c3e9272SAbhishek Patel                 {
3127b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
31285c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
31295c3e9272SAbhishek Patel                     return;
31305c3e9272SAbhishek Patel                 }
31315c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
31325c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
31335c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
31345c3e9272SAbhishek Patel             });
31355c3e9272SAbhishek Patel         }
31365c3e9272SAbhishek Patel     }
31375c3e9272SAbhishek Patel }
3138c1e219d5SEd Tanous 
3139c1e219d5SEd Tanous inline void
3140c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
314122d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3142c1e219d5SEd Tanous                             const std::string& systemName)
3143c1e219d5SEd Tanous {
31443ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
314545ca1b86SEd Tanous     {
314645ca1b86SEd Tanous         return;
314745ca1b86SEd Tanous     }
3148746b56f3SAsmitha Karunanithi 
31497f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
31507f3e84a1SEd Tanous     {
31517f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31527f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31537f3e84a1SEd Tanous                                    systemName);
31547f3e84a1SEd Tanous         return;
31557f3e84a1SEd Tanous     }
31567f3e84a1SEd Tanous 
3157746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3158746b56f3SAsmitha Karunanithi     {
3159746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3160746b56f3SAsmitha Karunanithi         return;
3161746b56f3SAsmitha Karunanithi     }
3162746b56f3SAsmitha Karunanithi 
316322d268cbSEd Tanous     if (systemName != "system")
316422d268cbSEd Tanous     {
316522d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
316622d268cbSEd Tanous                                    systemName);
316722d268cbSEd Tanous         return;
316822d268cbSEd Tanous     }
3169dd60b9edSEd Tanous     asyncResp->res.addHeader(
3170dd60b9edSEd Tanous         boost::beast::http::field::link,
3171dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
31728d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3173b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
31748d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "system";
31758d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "system";
31768d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
31778d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
31788d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3179cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3180dfb2b408SPriyanga Ramasamy         double(0);
3181002d39b4SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
318204a258f4SEd Tanous 
31831476687dSEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] =
31841476687dSEd Tanous         "/redfish/v1/Systems/system/Processors";
31851476687dSEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] =
31861476687dSEd Tanous         "/redfish/v1/Systems/system/Memory";
31871476687dSEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] =
31881476687dSEd Tanous         "/redfish/v1/Systems/system/Storage";
31893179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
31903179105bSSunny Srivastava         "/redfish/v1/Systems/system/FabricAdapters";
3191029573d4SEd Tanous 
3192002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
31931476687dSEd Tanous         "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3194c1e219d5SEd Tanous     asyncResp->res
3195c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
31961476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3197c5b2abe0SLewanczyk, Dawid 
31981476687dSEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
31991476687dSEd Tanous         "/redfish/v1/Systems/system/LogServices";
32001476687dSEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] =
32011476687dSEd Tanous         "/redfish/v1/Systems/system/Bios";
3202c4bf6374SJason M. Bills 
32031476687dSEd Tanous     nlohmann::json::array_t managedBy;
32041476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
32051476687dSEd Tanous     manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3206002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
32071476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
32081476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
32090e8ac5e7SGunnar Mills 
32100e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3211002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3212c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
32131476687dSEd Tanous 
3214c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
32151476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3216c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
32171476687dSEd Tanous         "Press ~. to exit console";
32185c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
32195c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
32200e8ac5e7SGunnar Mills 
32210e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
32220e8ac5e7SGunnar Mills     // Fill in GraphicalConsole info
3223002d39b4SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3224c1e219d5SEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3225613dabeaSEd Tanous     asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3226613dabeaSEd Tanous         nlohmann::json::array_t({"KVMIP"});
32271476687dSEd Tanous 
32280e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
322913451e39SWilly Tu 
323013451e39SWilly Tu     auto health = std::make_shared<HealthPopulate>(asyncResp);
323113451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
323213451e39SWilly Tu     {
32337a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 4> inventoryForSystems{
3234b49ac873SJames Feist             "xyz.openbmc_project.Inventory.Item.Dimm",
32352ad9c2f6SJames Feist             "xyz.openbmc_project.Inventory.Item.Cpu",
3236e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.Drive",
3237e284a7c1SJames Feist             "xyz.openbmc_project.Inventory.Item.StorageController"};
3238b49ac873SJames Feist 
32397a1dbc48SGeorge Liu         dbus::utility::getSubTreePaths(
32407a1dbc48SGeorge Liu             "/", 0, inventoryForSystems,
32417a1dbc48SGeorge Liu             [health](const boost::system::error_code& ec,
3242914e2d5dSEd Tanous                      const std::vector<std::string>& resp) {
3243b49ac873SJames Feist             if (ec)
3244b49ac873SJames Feist             {
3245b49ac873SJames Feist                 // no inventory
3246b49ac873SJames Feist                 return;
3247b49ac873SJames Feist             }
3248b49ac873SJames Feist 
3249914e2d5dSEd Tanous             health->inventory = resp;
32507a1dbc48SGeorge Liu         });
3251b49ac873SJames Feist         health->populate();
325213451e39SWilly Tu     }
3253b49ac873SJames Feist 
3254002d39b4SEd Tanous     getMainChassisId(asyncResp,
3255002d39b4SEd Tanous                      [](const std::string& chassisId,
32568d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3257b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3258b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3259ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3260ef4c65b7SEd Tanous                                                    chassisId);
3261002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3262c5d03ff4SJennifer Lee     });
3263a3002228SAppaRao Puli 
326459a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
32659f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3266a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
3267*51bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
32686c34de48SEd Tanous     getHostState(asyncResp);
3269491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3270978b8803SAndrew Geissler     getBootProgress(asyncResp);
3271b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
327270c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
327370c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
327451709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3275c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
32769dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3277797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3278c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
3279a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3280a6349918SAppaRao Puli     getProvisioningStatus(asyncResp);
3281a6349918SAppaRao Puli #endif
32821981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
32833a2d0424SChris Cain     getPowerMode(asyncResp);
328437bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3285c1e219d5SEd Tanous }
3286550a6bf8SJiaqing Zhao 
3287c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3288c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
328922d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3290c1e219d5SEd Tanous     const std::string& systemName)
3291c1e219d5SEd Tanous {
32923ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
329345ca1b86SEd Tanous     {
329445ca1b86SEd Tanous         return;
329545ca1b86SEd Tanous     }
32967f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
32977f3e84a1SEd Tanous     {
32987f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
32997f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33007f3e84a1SEd Tanous                                    systemName);
33017f3e84a1SEd Tanous         return;
33027f3e84a1SEd Tanous     }
330322d268cbSEd Tanous     if (systemName != "system")
330422d268cbSEd Tanous     {
330522d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
330622d268cbSEd Tanous                                    systemName);
330722d268cbSEd Tanous         return;
330822d268cbSEd Tanous     }
330922d268cbSEd Tanous 
3310dd60b9edSEd Tanous     asyncResp->res.addHeader(
3311dd60b9edSEd Tanous         boost::beast::http::field::link,
3312dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3313dd60b9edSEd Tanous 
33149f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3315cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
331698e386ecSGunnar Mills     std::optional<std::string> assetTag;
3317c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
33183a2d0424SChris Cain     std::optional<std::string> powerMode;
3319550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3320550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3321550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3322550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3323550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3324550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3325797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3326550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
33279dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3328550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3329550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3330550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3331550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3332550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3333550a6bf8SJiaqing Zhao 
3334550a6bf8SJiaqing Zhao     // clang-format off
333515ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3336550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3337550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
33387e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3339550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3340550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3341550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3342550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3343550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3344550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3345550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3346550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3347550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3348797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3349550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
33509dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3351550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3352550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3353550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3354550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3355550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
33566617338dSEd Tanous                 {
33576617338dSEd Tanous                     return;
33586617338dSEd Tanous                 }
3359550a6bf8SJiaqing Zhao     // clang-format on
3360491d8ee7SSantosh Puranik 
33618d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3362c45f0082SYong Li 
336398e386ecSGunnar Mills     if (assetTag)
336498e386ecSGunnar Mills     {
336598e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
336698e386ecSGunnar Mills     }
336798e386ecSGunnar Mills 
3368550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3369c45f0082SYong Li     {
3370f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3371c45f0082SYong Li     }
3372c45f0082SYong Li 
3373cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
337469f35306SGunnar Mills     {
3375002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3376491d8ee7SSantosh Puranik     }
3377550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
337869f35306SGunnar Mills     {
3379550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
338069f35306SGunnar Mills     }
3381ac7e1e0bSAli Ahmed 
3382797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3383797d5daeSCorey Hardesty     {
3384797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3385797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3386797d5daeSCorey Hardesty     }
3387797d5daeSCorey Hardesty 
3388550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3389ac7e1e0bSAli Ahmed     {
3390c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
339169f35306SGunnar Mills     }
3392265c1602SJohnathan Mantey 
33939dcfe8c1SAlbert Zhang     if (stopBootOnFault)
33949dcfe8c1SAlbert Zhang     {
33959dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
33969dcfe8c1SAlbert Zhang     }
33979dcfe8c1SAlbert Zhang 
33989f8bfa7cSGunnar Mills     if (locationIndicatorActive)
33999f8bfa7cSGunnar Mills     {
340059a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
34019f8bfa7cSGunnar Mills     }
34029f8bfa7cSGunnar Mills 
34037e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
34047e860f15SJohn Edward Broadbent     // passed
34059712f8acSEd Tanous     if (indicatorLed)
34066617338dSEd Tanous     {
3407f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3408002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3409d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3410d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
34116617338dSEd Tanous     }
3412c6a620f2SGeorge Liu 
3413c6a620f2SGeorge Liu     if (powerRestorePolicy)
3414c6a620f2SGeorge Liu     {
34154e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3416c6a620f2SGeorge Liu     }
34173a2d0424SChris Cain 
34183a2d0424SChris Cain     if (powerMode)
34193a2d0424SChris Cain     {
34203a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
34213a2d0424SChris Cain     }
342237bbf98cSChris Cain 
3423c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
342437bbf98cSChris Cain     {
3425002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3426002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
342737bbf98cSChris Cain     }
3428c1e219d5SEd Tanous }
34291cb1a9e6SAppaRao Puli 
343038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3431dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
34327f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3433c1e219d5SEd Tanous     const std::string& /*systemName*/)
3434dd60b9edSEd Tanous {
3435dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3436dd60b9edSEd Tanous     {
3437dd60b9edSEd Tanous         return;
3438dd60b9edSEd Tanous     }
3439dd60b9edSEd Tanous     asyncResp->res.addHeader(
3440dd60b9edSEd Tanous         boost::beast::http::field::link,
3441dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3442dd60b9edSEd Tanous }
344333e1f122SAndrew Geissler 
344433e1f122SAndrew Geissler /**
344533e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
344633e1f122SAndrew Geissler  *
344733e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
344833e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
344933e1f122SAndrew Geissler  *
345033e1f122SAndrew Geissler  * @return Emplaces correpsonding Redfish translated value(s) in
345133e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
345233e1f122SAndrew Geissler  * allowableValues.
345333e1f122SAndrew Geissler  */
345433e1f122SAndrew Geissler inline void
345533e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
345633e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
345733e1f122SAndrew Geissler {
345833e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
345933e1f122SAndrew Geissler     {
346033e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
346133e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
346233e1f122SAndrew Geissler     }
346333e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
346433e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
346533e1f122SAndrew Geissler     {
346633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
346733e1f122SAndrew Geissler     }
346833e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
346933e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
347033e1f122SAndrew Geissler     {
347133e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
347233e1f122SAndrew Geissler     }
347333e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
347433e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
347533e1f122SAndrew Geissler     {
347633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
347733e1f122SAndrew Geissler     }
347833e1f122SAndrew Geissler     else
347933e1f122SAndrew Geissler     {
348033e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
348133e1f122SAndrew Geissler     }
348233e1f122SAndrew Geissler }
348333e1f122SAndrew Geissler 
348433e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
348533e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348633e1f122SAndrew Geissler     const boost::system::error_code& ec,
348733e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
348833e1f122SAndrew Geissler {
348933e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
349033e1f122SAndrew Geissler 
349133e1f122SAndrew Geissler     // Supported on all systems currently
349233e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
349333e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
349433e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
349533e1f122SAndrew Geissler 
349633e1f122SAndrew Geissler     if (ec)
349733e1f122SAndrew Geissler     {
3498e715d14bSEd Tanous         if ((ec.value() ==
3499e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3500e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
350133e1f122SAndrew Geissler         {
350233e1f122SAndrew Geissler             // Property not implemented so just return defaults
350333e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
350433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
350533e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
350633e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
350733e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
350833e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
350933e1f122SAndrew Geissler         }
351033e1f122SAndrew Geissler         else
351133e1f122SAndrew Geissler         {
351233e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
351333e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
351433e1f122SAndrew Geissler             return;
351533e1f122SAndrew Geissler         }
351633e1f122SAndrew Geissler     }
351733e1f122SAndrew Geissler     else
351833e1f122SAndrew Geissler     {
351933e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
352033e1f122SAndrew Geissler         {
352133e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
352233e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
352333e1f122SAndrew Geissler         }
352433e1f122SAndrew Geissler     }
352533e1f122SAndrew Geissler 
352633e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
352733e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
352833e1f122SAndrew Geissler     parameter["Required"] = true;
352933e1f122SAndrew Geissler     parameter["DataType"] = "String";
353033e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
353133e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
353233e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
353333e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
353433e1f122SAndrew Geissler }
353533e1f122SAndrew Geissler 
3536c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3537c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
353822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3539c1e219d5SEd Tanous     const std::string& systemName)
3540c1e219d5SEd Tanous {
35413ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
354245ca1b86SEd Tanous     {
354345ca1b86SEd Tanous         return;
354445ca1b86SEd Tanous     }
35457f3e84a1SEd Tanous     if constexpr (bmcwebEnableMultiHost)
35467f3e84a1SEd Tanous     {
35477f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
35487f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
35497f3e84a1SEd Tanous                                    systemName);
35507f3e84a1SEd Tanous         return;
35517f3e84a1SEd Tanous     }
3552746b56f3SAsmitha Karunanithi 
3553746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3554746b56f3SAsmitha Karunanithi     {
3555746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3556746b56f3SAsmitha Karunanithi         return;
3557746b56f3SAsmitha Karunanithi     }
3558746b56f3SAsmitha Karunanithi 
355922d268cbSEd Tanous     if (systemName != "system")
356022d268cbSEd Tanous     {
356122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
356222d268cbSEd Tanous                                    systemName);
356322d268cbSEd Tanous         return;
356422d268cbSEd Tanous     }
356522d268cbSEd Tanous 
3566dd60b9edSEd Tanous     asyncResp->res.addHeader(
3567dd60b9edSEd Tanous         boost::beast::http::field::link,
3568dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
35691476687dSEd Tanous 
35701476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
35711476687dSEd Tanous         "/redfish/v1/Systems/system/ResetActionInfo";
3572c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
35731476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
35741476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
35753215e700SNan Zhou 
357633e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
357733e1f122SAndrew Geissler     sdbusplus::asio::getProperty<std::vector<std::string>>(
357833e1f122SAndrew Geissler         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
357933e1f122SAndrew Geissler         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
358033e1f122SAndrew Geissler         "AllowedHostTransitions",
358133e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
358233e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
358333e1f122SAndrew Geissler         afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
358433e1f122SAndrew Geissler     });
3585c1e219d5SEd Tanous }
3586c1e219d5SEd Tanous /**
3587c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3588c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3589c1e219d5SEd Tanous  */
3590100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3591c1e219d5SEd Tanous {
3592100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3593100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3594100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3595100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3596100afe56SEd Tanous 
3597100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3598100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3599100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3600100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3601100afe56SEd Tanous 
3602100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3603100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3604100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3605100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3606100afe56SEd Tanous 
3607100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3608100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3609100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3610100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3611100afe56SEd Tanous 
3612100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3613100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3614100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3615100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3616100afe56SEd Tanous 
3617100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3618100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3619100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3620100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3621100afe56SEd Tanous 
3622c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3623c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3624c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3625c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3626c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3627c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3628c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3629c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
36301cb1a9e6SAppaRao Puli }
3631c5b2abe0SLewanczyk, Dawid } // namespace redfish
3632