xref: /openbmc/bmcweb/redfish-core/lib/systems.hpp (revision 253f11b84347de6bff7c6b624bef270fefae5f5a)
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"
25746b56f3SAsmitha Karunanithi #include "hypervisor_system.hpp"
261c8fba97SJames Feist #include "led.hpp"
27f4c99e70SEd Tanous #include "query.hpp"
28c5d03ff4SJennifer Lee #include "redfish_util.hpp"
293ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
303ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
313ccb3adbSEd Tanous #include "utils/json_utils.hpp"
32472bd202SLakshmi Yadlapati #include "utils/pcie_util.hpp"
333ccb3adbSEd Tanous #include "utils/sw_utils.hpp"
342b82937eSEd Tanous #include "utils/time_utils.hpp"
35c5d03ff4SJennifer Lee 
36fc903b3dSAndrew Geissler #include <boost/asio/error.hpp>
379712f8acSEd Tanous #include <boost/container/flat_map.hpp>
38e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
3933e1f122SAndrew Geissler #include <boost/system/linux_error.hpp>
40ef4c65b7SEd Tanous #include <boost/url/format.hpp>
411e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
42fc903b3dSAndrew Geissler #include <sdbusplus/message.hpp>
43bc1d29deSKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
441214b7e7SGunnar Mills 
457a1dbc48SGeorge Liu #include <array>
4633e1f122SAndrew Geissler #include <memory>
476b9ac4f2SChris Cain #include <string>
487a1dbc48SGeorge Liu #include <string_view>
49abf2add6SEd Tanous #include <variant>
506b9ac4f2SChris Cain #include <vector>
51c5b2abe0SLewanczyk, Dawid 
521abe55efSEd Tanous namespace redfish
531abe55efSEd Tanous {
54c5b2abe0SLewanczyk, Dawid 
555c3e9272SAbhishek Patel const static std::array<std::pair<std::string_view, std::string_view>, 2>
565c3e9272SAbhishek Patel     protocolToDBusForSystems{
575c3e9272SAbhishek Patel         {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
585c3e9272SAbhishek Patel 
599d3ae10eSAlpana Kumari /**
609d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
619d3ae10eSAlpana Kumari  *
62ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
639d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
649d3ae10eSAlpana Kumari  *
659d3ae10eSAlpana Kumari  * @return None.
669d3ae10eSAlpana Kumari  */
678d1b46d7Szhanghch05 inline void
68ac106bf6SEd Tanous     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
691e1e598dSJonathan Doman                          bool isDimmFunctional)
709d3ae10eSAlpana Kumari {
7162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
729d3ae10eSAlpana Kumari 
739d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
749d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
759d3ae10eSAlpana Kumari     // ENABLED.
7602cad96eSEd Tanous     const nlohmann::json& prevMemSummary =
77ac106bf6SEd Tanous         asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
789d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
799d3ae10eSAlpana Kumari     {
80e05aec50SEd Tanous         if (isDimmFunctional)
819d3ae10eSAlpana Kumari         {
82ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
839d3ae10eSAlpana Kumari                 "Enabled";
849d3ae10eSAlpana Kumari         }
859d3ae10eSAlpana Kumari     }
869d3ae10eSAlpana Kumari }
879d3ae10eSAlpana Kumari 
8857e8c9beSAlpana Kumari /*
8957e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
9057e8c9beSAlpana Kumari  *        CPU Functional State
9157e8c9beSAlpana Kumari  *
92ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
9357e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
9457e8c9beSAlpana Kumari  *
9557e8c9beSAlpana Kumari  * @return None.
9657e8c9beSAlpana Kumari  */
97ac106bf6SEd Tanous inline void modifyCpuFunctionalState(
98ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
9957e8c9beSAlpana Kumari {
10062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
10157e8c9beSAlpana Kumari 
10202cad96eSEd Tanous     const nlohmann::json& prevProcState =
103ac106bf6SEd Tanous         asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
10457e8c9beSAlpana Kumari 
10557e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
10657e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
10757e8c9beSAlpana Kumari     // Functional.
10857e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
10957e8c9beSAlpana Kumari     {
110e05aec50SEd Tanous         if (isCpuFunctional)
11157e8c9beSAlpana Kumari         {
112ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
11357e8c9beSAlpana Kumari                 "Enabled";
11457e8c9beSAlpana Kumari         }
11557e8c9beSAlpana Kumari     }
11657e8c9beSAlpana Kumari }
11757e8c9beSAlpana Kumari 
118cf0e004cSNinad Palsule /*
119cf0e004cSNinad Palsule  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
120cf0e004cSNinad Palsule  *
121ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
122cf0e004cSNinad Palsule  * @param[in] cpuPresenceState CPU present or not
123cf0e004cSNinad Palsule  *
124cf0e004cSNinad Palsule  * @return None.
125cf0e004cSNinad Palsule  */
126cf0e004cSNinad Palsule inline void
127ac106bf6SEd Tanous     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
128cf0e004cSNinad Palsule                            bool isCpuPresent)
129cf0e004cSNinad Palsule {
13062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
131cf0e004cSNinad Palsule 
132cf0e004cSNinad Palsule     if (isCpuPresent)
133cf0e004cSNinad Palsule     {
134cf0e004cSNinad Palsule         nlohmann::json& procCount =
135ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
136cf0e004cSNinad Palsule         auto* procCountPtr =
137cf0e004cSNinad Palsule             procCount.get_ptr<nlohmann::json::number_integer_t*>();
138cf0e004cSNinad Palsule         if (procCountPtr != nullptr)
139cf0e004cSNinad Palsule         {
140cf0e004cSNinad Palsule             // shouldn't be possible to be nullptr
141cf0e004cSNinad Palsule             *procCountPtr += 1;
142cf0e004cSNinad Palsule         }
143cf0e004cSNinad Palsule     }
144cf0e004cSNinad Palsule }
145cf0e004cSNinad Palsule 
146382d6475SAli Ahmed inline void getProcessorProperties(
147ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
148382d6475SAli Ahmed     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
149382d6475SAli Ahmed         properties)
15003fbed92SAli Ahmed {
15162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
15203fbed92SAli Ahmed 
15303fbed92SAli Ahmed     // TODO: Get Model
15403fbed92SAli Ahmed 
155bc1d29deSKrzysztof Grobelny     const uint16_t* coreCount = nullptr;
15603fbed92SAli Ahmed 
157bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
158bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
15903fbed92SAli Ahmed 
160bc1d29deSKrzysztof Grobelny     if (!success)
16103fbed92SAli Ahmed     {
162ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
16303fbed92SAli Ahmed         return;
16403fbed92SAli Ahmed     }
16503fbed92SAli Ahmed 
166bc1d29deSKrzysztof Grobelny     if (coreCount != nullptr)
16703fbed92SAli Ahmed     {
168bc1d29deSKrzysztof Grobelny         nlohmann::json& coreCountJson =
169ac106bf6SEd Tanous             asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
170bc1d29deSKrzysztof Grobelny         uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
171bc1d29deSKrzysztof Grobelny 
172bc1d29deSKrzysztof Grobelny         if (coreCountJsonPtr == nullptr)
173bc1d29deSKrzysztof Grobelny         {
174bc1d29deSKrzysztof Grobelny             coreCountJson = *coreCount;
17503fbed92SAli Ahmed         }
17603fbed92SAli Ahmed         else
17703fbed92SAli Ahmed         {
178bc1d29deSKrzysztof Grobelny             *coreCountJsonPtr += *coreCount;
17903fbed92SAli Ahmed         }
18003fbed92SAli Ahmed     }
18103fbed92SAli Ahmed }
18203fbed92SAli Ahmed 
18303fbed92SAli Ahmed /*
18403fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
18503fbed92SAli Ahmed  *
186ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
18703fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
18803fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
18903fbed92SAli Ahmed  *
19003fbed92SAli Ahmed  * @return None.
19103fbed92SAli Ahmed  */
192ac106bf6SEd Tanous inline void
193ac106bf6SEd Tanous     getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
194ac106bf6SEd Tanous                         const std::string& service, const std::string& path)
19503fbed92SAli Ahmed {
196ac106bf6SEd Tanous     auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
197382d6475SAli Ahmed                                            const bool cpuPresenceCheck) {
198382d6475SAli Ahmed         if (ec3)
199382d6475SAli Ahmed         {
20062598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
201382d6475SAli Ahmed             return;
202382d6475SAli Ahmed         }
203ac106bf6SEd Tanous         modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
204382d6475SAli Ahmed     };
205382d6475SAli Ahmed 
206cf0e004cSNinad Palsule     // Get the Presence of CPU
207cf0e004cSNinad Palsule     sdbusplus::asio::getProperty<bool>(
208cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
209cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item", "Present",
210cf0e004cSNinad Palsule         std::move(getCpuPresenceState));
211cf0e004cSNinad Palsule 
212bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
213bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, service, path,
214bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.Cpu",
215ac106bf6SEd Tanous         [asyncResp, service,
2165e7e2dc5SEd Tanous          path](const boost::system::error_code& ec2,
217b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
21803fbed92SAli Ahmed         if (ec2)
21903fbed92SAli Ahmed         {
22062598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
221ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22203fbed92SAli Ahmed             return;
22303fbed92SAli Ahmed         }
224ac106bf6SEd Tanous         getProcessorProperties(asyncResp, properties);
225bc1d29deSKrzysztof Grobelny     });
22603fbed92SAli Ahmed }
22703fbed92SAli Ahmed 
22857e8c9beSAlpana Kumari /*
229cf0e004cSNinad Palsule  * @brief processMemoryProperties fields
230cf0e004cSNinad Palsule  *
231ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
232cf0e004cSNinad Palsule  * @param[in] DBUS properties for memory
233cf0e004cSNinad Palsule  *
234cf0e004cSNinad Palsule  * @return None.
235cf0e004cSNinad Palsule  */
236cf0e004cSNinad Palsule inline void
237ac106bf6SEd Tanous     processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
238cf0e004cSNinad Palsule                             const dbus::utility::DBusPropertiesMap& properties)
239cf0e004cSNinad Palsule {
24062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
241cf0e004cSNinad Palsule 
242cf0e004cSNinad Palsule     if (properties.empty())
243cf0e004cSNinad Palsule     {
244cf0e004cSNinad Palsule         return;
245cf0e004cSNinad Palsule     }
246cf0e004cSNinad Palsule 
247cf0e004cSNinad Palsule     const size_t* memorySizeInKB = nullptr;
248cf0e004cSNinad Palsule 
249cf0e004cSNinad Palsule     const bool success = sdbusplus::unpackPropertiesNoThrow(
250cf0e004cSNinad Palsule         dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
251cf0e004cSNinad Palsule         memorySizeInKB);
252cf0e004cSNinad Palsule 
253cf0e004cSNinad Palsule     if (!success)
254cf0e004cSNinad Palsule     {
255ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
256cf0e004cSNinad Palsule         return;
257cf0e004cSNinad Palsule     }
258cf0e004cSNinad Palsule 
259cf0e004cSNinad Palsule     if (memorySizeInKB != nullptr)
260cf0e004cSNinad Palsule     {
261cf0e004cSNinad Palsule         nlohmann::json& totalMemory =
262ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
263dfb2b408SPriyanga Ramasamy         const double* preValue = totalMemory.get_ptr<const double*>();
264cf0e004cSNinad Palsule         if (preValue == nullptr)
265cf0e004cSNinad Palsule         {
266ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
267dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
268cf0e004cSNinad Palsule         }
269cf0e004cSNinad Palsule         else
270cf0e004cSNinad Palsule         {
271ac106bf6SEd Tanous             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
272dfb2b408SPriyanga Ramasamy                 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
273dfb2b408SPriyanga Ramasamy                 *preValue;
274cf0e004cSNinad Palsule         }
275cf0e004cSNinad Palsule     }
276cf0e004cSNinad Palsule }
277cf0e004cSNinad Palsule 
278cf0e004cSNinad Palsule /*
279cf0e004cSNinad Palsule  * @brief Get getMemorySummary fields
280cf0e004cSNinad Palsule  *
281ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for completing asynchronous calls
282cf0e004cSNinad Palsule  * @param[in] service dbus service for memory Information
283cf0e004cSNinad Palsule  * @param[in] path dbus path for memory
284cf0e004cSNinad Palsule  *
285cf0e004cSNinad Palsule  * @return None.
286cf0e004cSNinad Palsule  */
287ac106bf6SEd Tanous inline void
288ac106bf6SEd Tanous     getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
289ac106bf6SEd Tanous                      const std::string& service, const std::string& path)
290cf0e004cSNinad Palsule {
291cf0e004cSNinad Palsule     sdbusplus::asio::getAllProperties(
292cf0e004cSNinad Palsule         *crow::connections::systemBus, service, path,
293cf0e004cSNinad Palsule         "xyz.openbmc_project.Inventory.Item.Dimm",
294ac106bf6SEd Tanous         [asyncResp, service,
295cf0e004cSNinad Palsule          path](const boost::system::error_code& ec2,
296cf0e004cSNinad Palsule                const dbus::utility::DBusPropertiesMap& properties) {
297cf0e004cSNinad Palsule         if (ec2)
298cf0e004cSNinad Palsule         {
29962598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
300ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
301cf0e004cSNinad Palsule             return;
302cf0e004cSNinad Palsule         }
30351bd2d8aSGunnar Mills         processMemoryProperties(asyncResp, properties);
304cf0e004cSNinad Palsule     });
305cf0e004cSNinad Palsule }
306cf0e004cSNinad Palsule 
307a974c132SLakshmi Yadlapati inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
308a974c132SLakshmi Yadlapati                          const boost::system::error_code& ec,
309a974c132SLakshmi Yadlapati                          const dbus::utility::DBusPropertiesMap& properties)
3101abe55efSEd Tanous {
311a974c132SLakshmi Yadlapati     if (ec)
312a974c132SLakshmi Yadlapati     {
313a974c132SLakshmi Yadlapati         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
314a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
315a974c132SLakshmi Yadlapati         return;
316a974c132SLakshmi Yadlapati     }
317a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
318a974c132SLakshmi Yadlapati 
319a974c132SLakshmi Yadlapati     const std::string* uUID = nullptr;
320a974c132SLakshmi Yadlapati 
321a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
322a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
323a974c132SLakshmi Yadlapati 
324a974c132SLakshmi Yadlapati     if (!success)
325a974c132SLakshmi Yadlapati     {
326a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
327a974c132SLakshmi Yadlapati         return;
328a974c132SLakshmi Yadlapati     }
329a974c132SLakshmi Yadlapati 
330a974c132SLakshmi Yadlapati     if (uUID != nullptr)
331a974c132SLakshmi Yadlapati     {
332a974c132SLakshmi Yadlapati         std::string valueStr = *uUID;
333a974c132SLakshmi Yadlapati         if (valueStr.size() == 32)
334a974c132SLakshmi Yadlapati         {
335a974c132SLakshmi Yadlapati             valueStr.insert(8, 1, '-');
336a974c132SLakshmi Yadlapati             valueStr.insert(13, 1, '-');
337a974c132SLakshmi Yadlapati             valueStr.insert(18, 1, '-');
338a974c132SLakshmi Yadlapati             valueStr.insert(23, 1, '-');
339a974c132SLakshmi Yadlapati         }
340a974c132SLakshmi Yadlapati         BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
341a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["UUID"] = valueStr;
342a974c132SLakshmi Yadlapati     }
343a974c132SLakshmi Yadlapati }
344a974c132SLakshmi Yadlapati 
345a974c132SLakshmi Yadlapati inline void
346a974c132SLakshmi Yadlapati     afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
347a974c132SLakshmi Yadlapati                       const boost::system::error_code& ec,
348a974c132SLakshmi Yadlapati                       const dbus::utility::DBusPropertiesMap& propertiesList)
349a974c132SLakshmi Yadlapati {
350a974c132SLakshmi Yadlapati     if (ec)
351a974c132SLakshmi Yadlapati     {
352a974c132SLakshmi Yadlapati         // doesn't have to include this
353a974c132SLakshmi Yadlapati         // interface
354a974c132SLakshmi Yadlapati         return;
355a974c132SLakshmi Yadlapati     }
356a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
357a974c132SLakshmi Yadlapati 
358a974c132SLakshmi Yadlapati     const std::string* partNumber = nullptr;
359a974c132SLakshmi Yadlapati     const std::string* serialNumber = nullptr;
360a974c132SLakshmi Yadlapati     const std::string* manufacturer = nullptr;
361a974c132SLakshmi Yadlapati     const std::string* model = nullptr;
362a974c132SLakshmi Yadlapati     const std::string* subModel = nullptr;
363a974c132SLakshmi Yadlapati 
364a974c132SLakshmi Yadlapati     const bool success = sdbusplus::unpackPropertiesNoThrow(
365a974c132SLakshmi Yadlapati         dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
366a974c132SLakshmi Yadlapati         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
367a974c132SLakshmi Yadlapati         "Model", model, "SubModel", subModel);
368a974c132SLakshmi Yadlapati 
369a974c132SLakshmi Yadlapati     if (!success)
370a974c132SLakshmi Yadlapati     {
371a974c132SLakshmi Yadlapati         messages::internalError(asyncResp->res);
372a974c132SLakshmi Yadlapati         return;
373a974c132SLakshmi Yadlapati     }
374a974c132SLakshmi Yadlapati 
375a974c132SLakshmi Yadlapati     if (partNumber != nullptr)
376a974c132SLakshmi Yadlapati     {
377a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["PartNumber"] = *partNumber;
378a974c132SLakshmi Yadlapati     }
379a974c132SLakshmi Yadlapati 
380a974c132SLakshmi Yadlapati     if (serialNumber != nullptr)
381a974c132SLakshmi Yadlapati     {
382a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
383a974c132SLakshmi Yadlapati     }
384a974c132SLakshmi Yadlapati 
385a974c132SLakshmi Yadlapati     if (manufacturer != nullptr)
386a974c132SLakshmi Yadlapati     {
387a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
388a974c132SLakshmi Yadlapati     }
389a974c132SLakshmi Yadlapati 
390a974c132SLakshmi Yadlapati     if (model != nullptr)
391a974c132SLakshmi Yadlapati     {
392a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["Model"] = *model;
393a974c132SLakshmi Yadlapati     }
394a974c132SLakshmi Yadlapati 
395a974c132SLakshmi Yadlapati     if (subModel != nullptr)
396a974c132SLakshmi Yadlapati     {
397a974c132SLakshmi Yadlapati         asyncResp->res.jsonValue["SubModel"] = *subModel;
398a974c132SLakshmi Yadlapati     }
399a974c132SLakshmi Yadlapati 
400a974c132SLakshmi Yadlapati     // Grab the bios version
401a974c132SLakshmi Yadlapati     sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
402a974c132SLakshmi Yadlapati                                          "BiosVersion", false);
403a974c132SLakshmi Yadlapati }
404a974c132SLakshmi Yadlapati 
405a974c132SLakshmi Yadlapati inline void
406a974c132SLakshmi Yadlapati     afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
407a974c132SLakshmi Yadlapati                      const boost::system::error_code& ec,
408a974c132SLakshmi Yadlapati                      const std::string& value)
409a974c132SLakshmi Yadlapati {
410a974c132SLakshmi Yadlapati     if (ec)
411a974c132SLakshmi Yadlapati     {
412a974c132SLakshmi Yadlapati         // doesn't have to include this
413a974c132SLakshmi Yadlapati         // interface
414a974c132SLakshmi Yadlapati         return;
415a974c132SLakshmi Yadlapati     }
416a974c132SLakshmi Yadlapati 
417a974c132SLakshmi Yadlapati     asyncResp->res.jsonValue["AssetTag"] = value;
418a974c132SLakshmi Yadlapati }
419a974c132SLakshmi Yadlapati 
420a974c132SLakshmi Yadlapati inline void afterSystemGetSubTree(
421a974c132SLakshmi Yadlapati     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
422a974c132SLakshmi Yadlapati     const boost::system::error_code& ec,
423a974c132SLakshmi Yadlapati     const dbus::utility::MapperGetSubTreeResponse& subtree)
424a974c132SLakshmi Yadlapati {
4251abe55efSEd Tanous     if (ec)
4261abe55efSEd Tanous     {
427b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
428ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
429c5b2abe0SLewanczyk, Dawid         return;
430c5b2abe0SLewanczyk, Dawid     }
431c5b2abe0SLewanczyk, Dawid     // Iterate over all retrieved ObjectPaths.
432002d39b4SEd Tanous     for (const std::pair<
433002d39b4SEd Tanous              std::string,
434002d39b4SEd Tanous              std::vector<std::pair<std::string, std::vector<std::string>>>>&
4351214b7e7SGunnar Mills              object : subtree)
4361abe55efSEd Tanous     {
437c5b2abe0SLewanczyk, Dawid         const std::string& path = object.first;
43862598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got path: {}", path);
439002d39b4SEd Tanous         const std::vector<std::pair<std::string, std::vector<std::string>>>&
4401214b7e7SGunnar Mills             connectionNames = object.second;
44126f6976fSEd Tanous         if (connectionNames.empty())
4421abe55efSEd Tanous         {
443c5b2abe0SLewanczyk, Dawid             continue;
444c5b2abe0SLewanczyk, Dawid         }
445029573d4SEd Tanous 
4466c34de48SEd Tanous         // This is not system, so check if it's cpu, dimm, UUID or
4476c34de48SEd Tanous         // BiosVer
44804a258f4SEd Tanous         for (const auto& connection : connectionNames)
4491abe55efSEd Tanous         {
45004a258f4SEd Tanous             for (const auto& interfaceName : connection.second)
4511abe55efSEd Tanous             {
452a974c132SLakshmi Yadlapati                 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
4531abe55efSEd Tanous                 {
45462598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
4559d3ae10eSAlpana Kumari 
456ac106bf6SEd Tanous                     getMemorySummary(asyncResp, connection.first, path);
4575fd0aafbSNinad Palsule                 }
45804a258f4SEd Tanous                 else if (interfaceName ==
45904a258f4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.Cpu")
4601abe55efSEd Tanous                 {
46162598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
46257e8c9beSAlpana Kumari 
463ac106bf6SEd Tanous                     getProcessorSummary(asyncResp, connection.first, path);
4645fd0aafbSNinad Palsule                 }
465002d39b4SEd Tanous                 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
4661abe55efSEd Tanous                 {
46762598e31SEd Tanous                     BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
468bc1d29deSKrzysztof Grobelny 
469bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
470a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
471a974c132SLakshmi Yadlapati                         "xyz.openbmc_project.Common.UUID",
472ac106bf6SEd Tanous                         [asyncResp](const boost::system::error_code& ec3,
473b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
4741214b7e7SGunnar Mills                                         properties) {
475a974c132SLakshmi Yadlapati                         afterGetUUID(asyncResp, ec3, properties);
476bc1d29deSKrzysztof Grobelny                     });
477c5b2abe0SLewanczyk, Dawid                 }
478029573d4SEd Tanous                 else if (interfaceName ==
479029573d4SEd Tanous                          "xyz.openbmc_project.Inventory.Item.System")
4801abe55efSEd Tanous                 {
481bc1d29deSKrzysztof Grobelny                     sdbusplus::asio::getAllProperties(
482a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
483bc1d29deSKrzysztof Grobelny                         "xyz.openbmc_project.Inventory.Decorator.Asset",
484a974c132SLakshmi Yadlapati                         [asyncResp](const boost::system::error_code& ec3,
485b9d36b47SEd Tanous                                     const dbus::utility::DBusPropertiesMap&
486a974c132SLakshmi Yadlapati                                         properties) {
487a974c132SLakshmi Yadlapati                         afterGetInventory(asyncResp, ec3, properties);
488bc1d29deSKrzysztof Grobelny                     });
489e4a4b9a9SJames Feist 
4901e1e598dSJonathan Doman                     sdbusplus::asio::getProperty<std::string>(
491a974c132SLakshmi Yadlapati                         *crow::connections::systemBus, connection.first, path,
4921e1e598dSJonathan Doman                         "xyz.openbmc_project.Inventory.Decorator."
4931e1e598dSJonathan Doman                         "AssetTag",
4941e1e598dSJonathan Doman                         "AssetTag",
495a974c132SLakshmi Yadlapati                         std::bind_front(afterGetAssetTag, asyncResp));
496a974c132SLakshmi Yadlapati                 }
497a974c132SLakshmi Yadlapati             }
498a974c132SLakshmi Yadlapati         }
499a974c132SLakshmi Yadlapati     }
500a974c132SLakshmi Yadlapati }
501a974c132SLakshmi Yadlapati 
502a974c132SLakshmi Yadlapati /*
503a974c132SLakshmi Yadlapati  * @brief Retrieves computer system properties over dbus
504a974c132SLakshmi Yadlapati  *
505a974c132SLakshmi Yadlapati  * @param[in] asyncResp Shared pointer for completing asynchronous calls
506a974c132SLakshmi Yadlapati  *
507a974c132SLakshmi Yadlapati  * @return None.
508a974c132SLakshmi Yadlapati  */
509a974c132SLakshmi Yadlapati inline void
51051bd2d8aSGunnar Mills     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
511e4a4b9a9SJames Feist {
512a974c132SLakshmi Yadlapati     BMCWEB_LOG_DEBUG("Get available system components.");
513a974c132SLakshmi Yadlapati     constexpr std::array<std::string_view, 5> interfaces = {
514a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
515a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Cpu",
516a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.Dimm",
517a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item.System",
518a974c132SLakshmi Yadlapati         "xyz.openbmc_project.Common.UUID",
519a974c132SLakshmi Yadlapati     };
520a974c132SLakshmi Yadlapati     dbus::utility::getSubTree(
521a974c132SLakshmi Yadlapati         "/xyz/openbmc_project/inventory", 0, interfaces,
52251bd2d8aSGunnar Mills         std::bind_front(afterSystemGetSubTree, asyncResp));
523c5b2abe0SLewanczyk, Dawid }
524c5b2abe0SLewanczyk, Dawid 
525c5b2abe0SLewanczyk, Dawid /**
526c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
527c5b2abe0SLewanczyk, Dawid  *
528ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
529c5b2abe0SLewanczyk, Dawid  *
530c5b2abe0SLewanczyk, Dawid  * @return None.
531c5b2abe0SLewanczyk, Dawid  */
532ac106bf6SEd Tanous inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
5331abe55efSEd Tanous {
53462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host information.");
5351e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
5361e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
5371e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
5381e1e598dSJonathan Doman         "CurrentHostState",
539ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
5401e1e598dSJonathan Doman                     const std::string& hostState) {
5411abe55efSEd Tanous         if (ec)
5421abe55efSEd Tanous         {
54322228c28SAndrew Geissler             if (ec == boost::system::errc::host_unreachable)
54422228c28SAndrew Geissler             {
54522228c28SAndrew Geissler                 // Service not available, no error, just don't return
54622228c28SAndrew Geissler                 // host state info
54762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("Service not available {}", ec);
54822228c28SAndrew Geissler                 return;
54922228c28SAndrew Geissler             }
55062598e31SEd Tanous             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
551ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
552c5b2abe0SLewanczyk, Dawid             return;
553c5b2abe0SLewanczyk, Dawid         }
5546617338dSEd Tanous 
55562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Host state: {}", hostState);
556c5b2abe0SLewanczyk, Dawid         // Verify Host State
5571e1e598dSJonathan Doman         if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
5581abe55efSEd Tanous         {
559ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
560ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
5611abe55efSEd Tanous         }
5621e1e598dSJonathan Doman         else if (hostState ==
5630fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.Quiesced")
5648c888608SGunnar Mills         {
565ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
566ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
5678c888608SGunnar Mills         }
5681e1e598dSJonathan Doman         else if (hostState ==
5690fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
57083935af9SAndrew Geissler         {
571ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "On";
572ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "InTest";
57383935af9SAndrew Geissler         }
5740fda0f12SGeorge Liu         else if (
5751e1e598dSJonathan Doman             hostState ==
5760fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
5771a2a1437SAndrew Geissler         {
578ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
579ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Starting";
5801a2a1437SAndrew Geissler         }
581002d39b4SEd Tanous         else if (hostState ==
5820fda0f12SGeorge Liu                  "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
5831a2a1437SAndrew Geissler         {
584ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
585ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
5861a2a1437SAndrew Geissler         }
5871abe55efSEd Tanous         else
5881abe55efSEd Tanous         {
589ac106bf6SEd Tanous             asyncResp->res.jsonValue["PowerState"] = "Off";
590ac106bf6SEd Tanous             asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
591c5b2abe0SLewanczyk, Dawid         }
5921e1e598dSJonathan Doman     });
593c5b2abe0SLewanczyk, Dawid }
594c5b2abe0SLewanczyk, Dawid 
595c5b2abe0SLewanczyk, Dawid /**
596786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
597491d8ee7SSantosh Puranik  *
598491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
599491d8ee7SSantosh Puranik  *
600491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
601491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
602491d8ee7SSantosh Puranik  */
60323a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
604491d8ee7SSantosh Puranik {
605491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
606491d8ee7SSantosh Puranik     {
607491d8ee7SSantosh Puranik         return "None";
608491d8ee7SSantosh Puranik     }
6093174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
610491d8ee7SSantosh Puranik     {
611491d8ee7SSantosh Puranik         return "Hdd";
612491d8ee7SSantosh Puranik     }
6133174e4dfSEd Tanous     if (dbusSource ==
614a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
615491d8ee7SSantosh Puranik     {
616491d8ee7SSantosh Puranik         return "Cd";
617491d8ee7SSantosh Puranik     }
6183174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
619491d8ee7SSantosh Puranik     {
620491d8ee7SSantosh Puranik         return "Pxe";
621491d8ee7SSantosh Puranik     }
6223174e4dfSEd Tanous     if (dbusSource ==
623944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6249f16b2c1SJennifer Lee     {
6259f16b2c1SJennifer Lee         return "Usb";
6269f16b2c1SJennifer Lee     }
627491d8ee7SSantosh Puranik     return "";
628491d8ee7SSantosh Puranik }
629491d8ee7SSantosh Puranik 
630491d8ee7SSantosh Puranik /**
631cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
632cd9a4666SKonstantin Aladyshev  *
633cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
634cd9a4666SKonstantin Aladyshev  *
635cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
636cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
637cd9a4666SKonstantin Aladyshev  */
638cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
639cd9a4666SKonstantin Aladyshev {
640cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
641cd9a4666SKonstantin Aladyshev     {
642cd9a4666SKonstantin Aladyshev         return "Legacy";
643cd9a4666SKonstantin Aladyshev     }
644cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
645cd9a4666SKonstantin Aladyshev     {
646cd9a4666SKonstantin Aladyshev         return "UEFI";
647cd9a4666SKonstantin Aladyshev     }
648cd9a4666SKonstantin Aladyshev     return "";
649cd9a4666SKonstantin Aladyshev }
650cd9a4666SKonstantin Aladyshev 
651cd9a4666SKonstantin Aladyshev /**
652786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
653491d8ee7SSantosh Puranik  *
654491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
655491d8ee7SSantosh Puranik  *
656491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
657491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
658491d8ee7SSantosh Puranik  */
65923a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
660491d8ee7SSantosh Puranik {
661491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
662491d8ee7SSantosh Puranik     {
663491d8ee7SSantosh Puranik         return "None";
664491d8ee7SSantosh Puranik     }
6653174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
666491d8ee7SSantosh Puranik     {
667491d8ee7SSantosh Puranik         return "Diags";
668491d8ee7SSantosh Puranik     }
6693174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
670491d8ee7SSantosh Puranik     {
671491d8ee7SSantosh Puranik         return "BiosSetup";
672491d8ee7SSantosh Puranik     }
673491d8ee7SSantosh Puranik     return "";
674491d8ee7SSantosh Puranik }
675491d8ee7SSantosh Puranik 
676491d8ee7SSantosh Puranik /**
677e43914b3SAndrew Geissler  * @brief Translates boot progress DBUS property value to redfish.
678e43914b3SAndrew Geissler  *
679e43914b3SAndrew Geissler  * @param[in] dbusBootProgress    The boot progress in DBUS speak.
680e43914b3SAndrew Geissler  *
681e43914b3SAndrew Geissler  * @return Returns as a string, the boot progress in Redfish terms. If
682e43914b3SAndrew Geissler  *         translation cannot be done, returns "None".
683e43914b3SAndrew Geissler  */
684e43914b3SAndrew Geissler inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
685e43914b3SAndrew Geissler {
686e43914b3SAndrew Geissler     // Now convert the D-Bus BootProgress to the appropriate Redfish
687e43914b3SAndrew Geissler     // enum
688e43914b3SAndrew Geissler     std::string rfBpLastState = "None";
689e43914b3SAndrew Geissler     if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
690e43914b3SAndrew Geissler                             "ProgressStages.Unspecified")
691e43914b3SAndrew Geissler     {
692e43914b3SAndrew Geissler         rfBpLastState = "None";
693e43914b3SAndrew Geissler     }
694e43914b3SAndrew Geissler     else if (dbusBootProgress ==
695e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
696e43914b3SAndrew Geissler              "PrimaryProcInit")
697e43914b3SAndrew Geissler     {
698e43914b3SAndrew Geissler         rfBpLastState = "PrimaryProcessorInitializationStarted";
699e43914b3SAndrew Geissler     }
700e43914b3SAndrew Geissler     else if (dbusBootProgress ==
701e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
702e43914b3SAndrew Geissler              "BusInit")
703e43914b3SAndrew Geissler     {
704e43914b3SAndrew Geissler         rfBpLastState = "BusInitializationStarted";
705e43914b3SAndrew Geissler     }
706e43914b3SAndrew Geissler     else if (dbusBootProgress ==
707e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
708e43914b3SAndrew Geissler              "MemoryInit")
709e43914b3SAndrew Geissler     {
710e43914b3SAndrew Geissler         rfBpLastState = "MemoryInitializationStarted";
711e43914b3SAndrew Geissler     }
712e43914b3SAndrew Geissler     else if (dbusBootProgress ==
713e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
714e43914b3SAndrew Geissler              "SecondaryProcInit")
715e43914b3SAndrew Geissler     {
716e43914b3SAndrew Geissler         rfBpLastState = "SecondaryProcessorInitializationStarted";
717e43914b3SAndrew Geissler     }
718e43914b3SAndrew Geissler     else if (dbusBootProgress ==
719e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
720e43914b3SAndrew Geissler              "PCIInit")
721e43914b3SAndrew Geissler     {
722e43914b3SAndrew Geissler         rfBpLastState = "PCIResourceConfigStarted";
723e43914b3SAndrew Geissler     }
724e43914b3SAndrew Geissler     else if (dbusBootProgress ==
725e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
726e43914b3SAndrew Geissler              "SystemSetup")
727e43914b3SAndrew Geissler     {
728e43914b3SAndrew Geissler         rfBpLastState = "SetupEntered";
729e43914b3SAndrew Geissler     }
730e43914b3SAndrew Geissler     else if (dbusBootProgress ==
731e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
732e43914b3SAndrew Geissler              "SystemInitComplete")
733e43914b3SAndrew Geissler     {
734e43914b3SAndrew Geissler         rfBpLastState = "SystemHardwareInitializationComplete";
735e43914b3SAndrew Geissler     }
736e43914b3SAndrew Geissler     else if (dbusBootProgress ==
737e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
738e43914b3SAndrew Geissler              "OSStart")
739e43914b3SAndrew Geissler     {
740e43914b3SAndrew Geissler         rfBpLastState = "OSBootStarted";
741e43914b3SAndrew Geissler     }
742e43914b3SAndrew Geissler     else if (dbusBootProgress ==
743e43914b3SAndrew Geissler              "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
744e43914b3SAndrew Geissler              "OSRunning")
745e43914b3SAndrew Geissler     {
746e43914b3SAndrew Geissler         rfBpLastState = "OSRunning";
747e43914b3SAndrew Geissler     }
748e43914b3SAndrew Geissler     else
749e43914b3SAndrew Geissler     {
75062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
751e43914b3SAndrew Geissler         // Just return the default
752e43914b3SAndrew Geissler     }
753e43914b3SAndrew Geissler     return rfBpLastState;
754e43914b3SAndrew Geissler }
755e43914b3SAndrew Geissler 
756e43914b3SAndrew Geissler /**
757786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
758491d8ee7SSantosh Puranik  *
759491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
760944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
761944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
762491d8ee7SSantosh Puranik  *
763944ffaf9SJohnathan Mantey  * @return Integer error code.
764491d8ee7SSantosh Puranik  */
765ac106bf6SEd Tanous inline int
766ac106bf6SEd Tanous     assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
767ac106bf6SEd Tanous                          const std::string& rfSource, std::string& bootSource,
768ac106bf6SEd Tanous                          std::string& bootMode)
769491d8ee7SSantosh Puranik {
770c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
771c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
772944ffaf9SJohnathan Mantey 
773491d8ee7SSantosh Puranik     if (rfSource == "None")
774491d8ee7SSantosh Puranik     {
775944ffaf9SJohnathan Mantey         return 0;
776491d8ee7SSantosh Puranik     }
7773174e4dfSEd Tanous     if (rfSource == "Pxe")
778491d8ee7SSantosh Puranik     {
779944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
780944ffaf9SJohnathan Mantey     }
781944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
782944ffaf9SJohnathan Mantey     {
783944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
784944ffaf9SJohnathan Mantey     }
785944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
786944ffaf9SJohnathan Mantey     {
787944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
788944ffaf9SJohnathan Mantey     }
789944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
790944ffaf9SJohnathan Mantey     {
791944ffaf9SJohnathan Mantey         bootSource =
792944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
793944ffaf9SJohnathan Mantey     }
794944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
795944ffaf9SJohnathan Mantey     {
796944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
797491d8ee7SSantosh Puranik     }
7989f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7999f16b2c1SJennifer Lee     {
800944ffaf9SJohnathan Mantey         bootSource =
801944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8029f16b2c1SJennifer Lee     }
803491d8ee7SSantosh Puranik     else
804491d8ee7SSantosh Puranik     {
80562598e31SEd Tanous         BMCWEB_LOG_DEBUG(
80662598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
80762598e31SEd Tanous             bootSource);
808ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, rfSource,
809944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
810944ffaf9SJohnathan Mantey         return -1;
811491d8ee7SSantosh Puranik     }
812944ffaf9SJohnathan Mantey     return 0;
813491d8ee7SSantosh Puranik }
8141981771bSAli Ahmed 
815978b8803SAndrew Geissler /**
816978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
817978b8803SAndrew Geissler  *
818ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
819978b8803SAndrew Geissler  *
820978b8803SAndrew Geissler  * @return None.
821978b8803SAndrew Geissler  */
822ac106bf6SEd Tanous inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
823978b8803SAndrew Geissler {
8241e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8251e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
8261e1e598dSJonathan Doman         "/xyz/openbmc_project/state/host0",
8271e1e598dSJonathan Doman         "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
828ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8291e1e598dSJonathan Doman                     const std::string& bootProgressStr) {
830978b8803SAndrew Geissler         if (ec)
831978b8803SAndrew Geissler         {
832978b8803SAndrew Geissler             // BootProgress is an optional object so just do nothing if
833978b8803SAndrew Geissler             // not found
834978b8803SAndrew Geissler             return;
835978b8803SAndrew Geissler         }
836978b8803SAndrew Geissler 
83762598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
838978b8803SAndrew Geissler 
839ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastState"] =
840e43914b3SAndrew Geissler             dbusToRfBootProgress(bootProgressStr);
8411e1e598dSJonathan Doman     });
842978b8803SAndrew Geissler }
843491d8ee7SSantosh Puranik 
844491d8ee7SSantosh Puranik /**
845b6d5d45cSHieu Huynh  * @brief Retrieves boot progress Last Update of the system
846b6d5d45cSHieu Huynh  *
847ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
848b6d5d45cSHieu Huynh  *
849b6d5d45cSHieu Huynh  * @return None.
850b6d5d45cSHieu Huynh  */
851b6d5d45cSHieu Huynh inline void getBootProgressLastStateTime(
852ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
853b6d5d45cSHieu Huynh {
854b6d5d45cSHieu Huynh     sdbusplus::asio::getProperty<uint64_t>(
855b6d5d45cSHieu Huynh         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
856b6d5d45cSHieu Huynh         "/xyz/openbmc_project/state/host0",
857b6d5d45cSHieu Huynh         "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
858ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
859b6d5d45cSHieu Huynh                     const uint64_t lastStateTime) {
860b6d5d45cSHieu Huynh         if (ec)
861b6d5d45cSHieu Huynh         {
86262598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
863b6d5d45cSHieu Huynh             return;
864b6d5d45cSHieu Huynh         }
865b6d5d45cSHieu Huynh 
866b6d5d45cSHieu Huynh         // BootProgressLastUpdate is the last time the BootProgress property
867b6d5d45cSHieu Huynh         // was updated. The time is the Epoch time, number of microseconds
868b6d5d45cSHieu Huynh         // since 1 Jan 1970 00::00::00 UTC."
869b6d5d45cSHieu Huynh         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
870b6d5d45cSHieu Huynh         // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
871b6d5d45cSHieu Huynh 
872b6d5d45cSHieu Huynh         // Convert to ISO 8601 standard
873ac106bf6SEd Tanous         asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
874b6d5d45cSHieu Huynh             redfish::time_utils::getDateTimeUintUs(lastStateTime);
875b6d5d45cSHieu Huynh     });
876b6d5d45cSHieu Huynh }
877b6d5d45cSHieu Huynh 
878b6d5d45cSHieu Huynh /**
879c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
880cd9a4666SKonstantin Aladyshev  *
881ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
882cd9a4666SKonstantin Aladyshev  *
883cd9a4666SKonstantin Aladyshev  * @return None.
884cd9a4666SKonstantin Aladyshev  */
885cd9a4666SKonstantin Aladyshev 
886ac106bf6SEd Tanous inline void
887ac106bf6SEd Tanous     getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
888cd9a4666SKonstantin Aladyshev {
8891e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
8901e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
8911e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
8921e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Type", "BootType",
893ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
8941e1e598dSJonathan Doman                     const std::string& bootType) {
895cd9a4666SKonstantin Aladyshev         if (ec)
896cd9a4666SKonstantin Aladyshev         {
897cd9a4666SKonstantin Aladyshev             // not an error, don't have to have the interface
898cd9a4666SKonstantin Aladyshev             return;
899cd9a4666SKonstantin Aladyshev         }
900cd9a4666SKonstantin Aladyshev 
90162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
902cd9a4666SKonstantin Aladyshev 
903ac106bf6SEd Tanous         asyncResp->res
904ac106bf6SEd Tanous             .jsonValue["Boot"]
905002d39b4SEd Tanous                       ["BootSourceOverrideMode@Redfish.AllowableValues"] =
906613dabeaSEd Tanous             nlohmann::json::array_t({"Legacy", "UEFI"});
907cd9a4666SKonstantin Aladyshev 
9081e1e598dSJonathan Doman         auto rfType = dbusToRfBootType(bootType);
909cd9a4666SKonstantin Aladyshev         if (rfType.empty())
910cd9a4666SKonstantin Aladyshev         {
911ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
912cd9a4666SKonstantin Aladyshev             return;
913cd9a4666SKonstantin Aladyshev         }
914cd9a4666SKonstantin Aladyshev 
915ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
9161e1e598dSJonathan Doman     });
917cd9a4666SKonstantin Aladyshev }
918cd9a4666SKonstantin Aladyshev 
919cd9a4666SKonstantin Aladyshev /**
920c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
921491d8ee7SSantosh Puranik  *
922ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
923491d8ee7SSantosh Puranik  *
924491d8ee7SSantosh Puranik  * @return None.
925491d8ee7SSantosh Puranik  */
926c21865c4SKonstantin Aladyshev 
927ac106bf6SEd Tanous inline void
928ac106bf6SEd Tanous     getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
929491d8ee7SSantosh Puranik {
9301e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9311e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9321e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9331e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
934ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9351e1e598dSJonathan Doman                     const std::string& bootModeStr) {
936491d8ee7SSantosh Puranik         if (ec)
937491d8ee7SSantosh Puranik         {
938b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
939ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
940491d8ee7SSantosh Puranik             return;
941491d8ee7SSantosh Puranik         }
942491d8ee7SSantosh Puranik 
94362598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
944491d8ee7SSantosh Puranik 
945ac106bf6SEd Tanous         asyncResp->res
9460fda0f12SGeorge Liu             .jsonValue["Boot"]
947002d39b4SEd Tanous                       ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
948002d39b4SEd Tanous             "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
949491d8ee7SSantosh Puranik 
9501e1e598dSJonathan Doman         if (bootModeStr !=
951491d8ee7SSantosh Puranik             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
952491d8ee7SSantosh Puranik         {
9531e1e598dSJonathan Doman             auto rfMode = dbusToRfBootMode(bootModeStr);
954491d8ee7SSantosh Puranik             if (!rfMode.empty())
955491d8ee7SSantosh Puranik             {
956ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
957491d8ee7SSantosh Puranik                     rfMode;
958491d8ee7SSantosh Puranik             }
959491d8ee7SSantosh Puranik         }
9601e1e598dSJonathan Doman     });
961491d8ee7SSantosh Puranik }
962491d8ee7SSantosh Puranik 
963491d8ee7SSantosh Puranik /**
964c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
965491d8ee7SSantosh Puranik  *
966ac106bf6SEd Tanous  * @param[in] asyncResp         Shared pointer for generating response message.
967491d8ee7SSantosh Puranik  *
968491d8ee7SSantosh Puranik  * @return None.
969491d8ee7SSantosh Puranik  */
970c21865c4SKonstantin Aladyshev 
971c21865c4SKonstantin Aladyshev inline void
972ac106bf6SEd Tanous     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
973491d8ee7SSantosh Puranik {
9741e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
9751e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
9761e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
9771e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
978ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
9791e1e598dSJonathan Doman                     const std::string& bootSourceStr) {
980491d8ee7SSantosh Puranik         if (ec)
981491d8ee7SSantosh Puranik         {
9825ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
9835ef735c8SNan Zhou             {
9845ef735c8SNan Zhou                 return;
9855ef735c8SNan Zhou             }
986b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
987ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
988491d8ee7SSantosh Puranik             return;
989491d8ee7SSantosh Puranik         }
990491d8ee7SSantosh Puranik 
99162598e31SEd Tanous         BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
992491d8ee7SSantosh Puranik 
9931e1e598dSJonathan Doman         auto rfSource = dbusToRfBootSource(bootSourceStr);
994491d8ee7SSantosh Puranik         if (!rfSource.empty())
995491d8ee7SSantosh Puranik         {
996ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
997ac106bf6SEd Tanous                 rfSource;
998491d8ee7SSantosh Puranik         }
999cd9a4666SKonstantin Aladyshev 
1000cd9a4666SKonstantin Aladyshev         // Get BootMode as BootSourceOverrideTarget is constructed
1001cd9a4666SKonstantin Aladyshev         // from both BootSource and BootMode
1002ac106bf6SEd Tanous         getBootOverrideMode(asyncResp);
10031e1e598dSJonathan Doman     });
1004491d8ee7SSantosh Puranik }
1005491d8ee7SSantosh Puranik 
1006491d8ee7SSantosh Puranik /**
1007c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1008c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1009c21865c4SKonstantin Aladyshev  * state
1010491d8ee7SSantosh Puranik  *
1011ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1012491d8ee7SSantosh Puranik  *
1013491d8ee7SSantosh Puranik  * @return None.
1014491d8ee7SSantosh Puranik  */
1015491d8ee7SSantosh Puranik 
1016ac106bf6SEd Tanous inline void processBootOverrideEnable(
1017ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1018c21865c4SKonstantin Aladyshev     const bool bootOverrideEnableSetting)
1019c21865c4SKonstantin Aladyshev {
1020c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1021c21865c4SKonstantin Aladyshev     {
1022ac106bf6SEd Tanous         asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1023ac106bf6SEd Tanous             "Disabled";
1024c21865c4SKonstantin Aladyshev         return;
1025c21865c4SKonstantin Aladyshev     }
1026c21865c4SKonstantin Aladyshev 
1027c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1028c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
10291e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10301e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10311e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot/one_time",
10321e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1033ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
1034491d8ee7SSantosh Puranik         if (ec)
1035491d8ee7SSantosh Puranik         {
1036b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1037ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1038491d8ee7SSantosh Puranik             return;
1039491d8ee7SSantosh Puranik         }
1040491d8ee7SSantosh Puranik 
1041c21865c4SKonstantin Aladyshev         if (oneTimeSetting)
1042c21865c4SKonstantin Aladyshev         {
1043ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1044ac106bf6SEd Tanous                 "Once";
1045c21865c4SKonstantin Aladyshev         }
1046c21865c4SKonstantin Aladyshev         else
1047c21865c4SKonstantin Aladyshev         {
1048ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1049c21865c4SKonstantin Aladyshev                 "Continuous";
1050c21865c4SKonstantin Aladyshev         }
10511e1e598dSJonathan Doman     });
1052491d8ee7SSantosh Puranik }
1053491d8ee7SSantosh Puranik 
1054491d8ee7SSantosh Puranik /**
1055c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1056c21865c4SKonstantin Aladyshev  *
1057ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1058c21865c4SKonstantin Aladyshev  *
1059c21865c4SKonstantin Aladyshev  * @return None.
1060c21865c4SKonstantin Aladyshev  */
1061c21865c4SKonstantin Aladyshev 
1062c21865c4SKonstantin Aladyshev inline void
1063ac106bf6SEd Tanous     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1064c21865c4SKonstantin Aladyshev {
10651e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
10661e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
10671e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/boot",
10681e1e598dSJonathan Doman         "xyz.openbmc_project.Object.Enable", "Enabled",
1069ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
10701e1e598dSJonathan Doman                     const bool bootOverrideEnable) {
1071c21865c4SKonstantin Aladyshev         if (ec)
1072c21865c4SKonstantin Aladyshev         {
10735ef735c8SNan Zhou             if (ec.value() == boost::asio::error::host_unreachable)
10745ef735c8SNan Zhou             {
10755ef735c8SNan Zhou                 return;
10765ef735c8SNan Zhou             }
1077b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1078ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1079c21865c4SKonstantin Aladyshev             return;
1080c21865c4SKonstantin Aladyshev         }
1081c21865c4SKonstantin Aladyshev 
1082ac106bf6SEd Tanous         processBootOverrideEnable(asyncResp, bootOverrideEnable);
10831e1e598dSJonathan Doman     });
1084c21865c4SKonstantin Aladyshev }
1085c21865c4SKonstantin Aladyshev 
1086c21865c4SKonstantin Aladyshev /**
1087c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1088c21865c4SKonstantin Aladyshev  *
1089ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1090c21865c4SKonstantin Aladyshev  *
1091c21865c4SKonstantin Aladyshev  * @return None.
1092c21865c4SKonstantin Aladyshev  */
1093ac106bf6SEd Tanous inline void
1094ac106bf6SEd Tanous     getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1095c21865c4SKonstantin Aladyshev {
109662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get boot information.");
1097c21865c4SKonstantin Aladyshev 
1098ac106bf6SEd Tanous     getBootOverrideSource(asyncResp);
1099ac106bf6SEd Tanous     getBootOverrideType(asyncResp);
1100ac106bf6SEd Tanous     getBootOverrideEnable(asyncResp);
1101c21865c4SKonstantin Aladyshev }
1102c21865c4SKonstantin Aladyshev 
1103c21865c4SKonstantin Aladyshev /**
1104c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1105c0557e1aSGunnar Mills  *
1106c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1107c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1108c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1109c0557e1aSGunnar Mills  * last power operation time.
1110c0557e1aSGunnar Mills  *
1111ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1112c0557e1aSGunnar Mills  *
1113c0557e1aSGunnar Mills  * @return None.
1114c0557e1aSGunnar Mills  */
1115ac106bf6SEd Tanous inline void
1116ac106bf6SEd Tanous     getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1117c0557e1aSGunnar Mills {
111862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
1119c0557e1aSGunnar Mills 
11201e1e598dSJonathan Doman     sdbusplus::asio::getProperty<uint64_t>(
11211e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
11221e1e598dSJonathan Doman         "/xyz/openbmc_project/state/chassis0",
11231e1e598dSJonathan Doman         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1124ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1125ac106bf6SEd Tanous                     uint64_t lastResetTime) {
1126c0557e1aSGunnar Mills         if (ec)
1127c0557e1aSGunnar Mills         {
112862598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1129c0557e1aSGunnar Mills             return;
1130c0557e1aSGunnar Mills         }
1131c0557e1aSGunnar Mills 
1132c0557e1aSGunnar Mills         // LastStateChangeTime is epoch time, in milliseconds
1133c0557e1aSGunnar Mills         // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11341e1e598dSJonathan Doman         uint64_t lastResetTimeStamp = lastResetTime / 1000;
1135c0557e1aSGunnar Mills 
1136c0557e1aSGunnar Mills         // Convert to ISO 8601 standard
1137ac106bf6SEd Tanous         asyncResp->res.jsonValue["LastResetTime"] =
11382b82937eSEd Tanous             redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
11391e1e598dSJonathan Doman     });
1140c0557e1aSGunnar Mills }
1141c0557e1aSGunnar Mills 
1142c0557e1aSGunnar Mills /**
1143797d5daeSCorey Hardesty  * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1144797d5daeSCorey Hardesty  *
1145797d5daeSCorey Hardesty  * The total number of automatic reboot retries allowed "RetryAttempts" and its
1146797d5daeSCorey Hardesty  * corresponding property "AttemptsLeft" that keeps track of the amount of
1147797d5daeSCorey Hardesty  * automatic retry attempts left are hosted in phosphor-state-manager through
1148797d5daeSCorey Hardesty  * dbus.
1149797d5daeSCorey Hardesty  *
1150ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1151797d5daeSCorey Hardesty  *
1152797d5daeSCorey Hardesty  * @return None.
1153797d5daeSCorey Hardesty  */
1154ac106bf6SEd Tanous inline void getAutomaticRebootAttempts(
1155ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1156797d5daeSCorey Hardesty {
115762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
1158797d5daeSCorey Hardesty 
1159797d5daeSCorey Hardesty     sdbusplus::asio::getAllProperties(
1160797d5daeSCorey Hardesty         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1161797d5daeSCorey Hardesty         "/xyz/openbmc_project/state/host0",
1162797d5daeSCorey Hardesty         "xyz.openbmc_project.Control.Boot.RebootAttempts",
1163ac106bf6SEd Tanous         [asyncResp{asyncResp}](
1164ac106bf6SEd Tanous             const boost::system::error_code& ec,
1165797d5daeSCorey Hardesty             const dbus::utility::DBusPropertiesMap& propertiesList) {
1166797d5daeSCorey Hardesty         if (ec)
1167797d5daeSCorey Hardesty         {
1168797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1169797d5daeSCorey Hardesty             {
117062598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1171ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1172797d5daeSCorey Hardesty             }
1173797d5daeSCorey Hardesty             return;
1174797d5daeSCorey Hardesty         }
1175797d5daeSCorey Hardesty 
1176797d5daeSCorey Hardesty         const uint32_t* attemptsLeft = nullptr;
1177797d5daeSCorey Hardesty         const uint32_t* retryAttempts = nullptr;
1178797d5daeSCorey Hardesty 
1179797d5daeSCorey Hardesty         const bool success = sdbusplus::unpackPropertiesNoThrow(
1180797d5daeSCorey Hardesty             dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1181797d5daeSCorey Hardesty             attemptsLeft, "RetryAttempts", retryAttempts);
1182797d5daeSCorey Hardesty 
1183797d5daeSCorey Hardesty         if (!success)
1184797d5daeSCorey Hardesty         {
1185ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1186797d5daeSCorey Hardesty             return;
1187797d5daeSCorey Hardesty         }
1188797d5daeSCorey Hardesty 
1189797d5daeSCorey Hardesty         if (attemptsLeft != nullptr)
1190797d5daeSCorey Hardesty         {
1191ac106bf6SEd Tanous             asyncResp->res
1192ac106bf6SEd Tanous                 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1193797d5daeSCorey Hardesty                 *attemptsLeft;
1194797d5daeSCorey Hardesty         }
1195797d5daeSCorey Hardesty 
1196797d5daeSCorey Hardesty         if (retryAttempts != nullptr)
1197797d5daeSCorey Hardesty         {
1198ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1199797d5daeSCorey Hardesty                 *retryAttempts;
1200797d5daeSCorey Hardesty         }
1201797d5daeSCorey Hardesty     });
1202797d5daeSCorey Hardesty }
1203797d5daeSCorey Hardesty 
1204797d5daeSCorey Hardesty /**
12056bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12066bd5a8d2SGunnar Mills  *
1207ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
12086bd5a8d2SGunnar Mills  *
12096bd5a8d2SGunnar Mills  * @return None.
12106bd5a8d2SGunnar Mills  */
1211797d5daeSCorey Hardesty inline void
1212ac106bf6SEd Tanous     getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12136bd5a8d2SGunnar Mills {
121462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
12156bd5a8d2SGunnar Mills 
12161e1e598dSJonathan Doman     sdbusplus::asio::getProperty<bool>(
12171e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
12181e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/auto_reboot",
12191e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1220ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1221ac106bf6SEd Tanous                     bool autoRebootEnabled) {
12226bd5a8d2SGunnar Mills         if (ec)
12236bd5a8d2SGunnar Mills         {
1224797d5daeSCorey Hardesty             if (ec.value() != EBADR)
1225797d5daeSCorey Hardesty             {
122662598e31SEd Tanous                 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1227ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1228797d5daeSCorey Hardesty             }
12296bd5a8d2SGunnar Mills             return;
12306bd5a8d2SGunnar Mills         }
12316bd5a8d2SGunnar Mills 
123262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1233e05aec50SEd Tanous         if (autoRebootEnabled)
12346bd5a8d2SGunnar Mills         {
1235ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12366bd5a8d2SGunnar Mills                 "RetryAttempts";
12376bd5a8d2SGunnar Mills         }
12386bd5a8d2SGunnar Mills         else
12396bd5a8d2SGunnar Mills         {
1240ac106bf6SEd Tanous             asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1241ac106bf6SEd Tanous                 "Disabled";
12426bd5a8d2SGunnar Mills         }
1243ac106bf6SEd Tanous         getAutomaticRebootAttempts(asyncResp);
124469f35306SGunnar Mills 
124569f35306SGunnar Mills         // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
124669f35306SGunnar Mills         // and RetryAttempts. OpenBMC only supports Disabled and
124769f35306SGunnar Mills         // RetryAttempts.
1248ac106bf6SEd Tanous         asyncResp->res
1249ac106bf6SEd Tanous             .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1250ac106bf6SEd Tanous             {"Disabled", "RetryAttempts"};
12511e1e598dSJonathan Doman     });
12526bd5a8d2SGunnar Mills }
12536bd5a8d2SGunnar Mills 
12546bd5a8d2SGunnar Mills /**
1255797d5daeSCorey Hardesty  * @brief Sets RetryAttempts
1256797d5daeSCorey Hardesty  *
1257ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1258797d5daeSCorey Hardesty  * @param[in] retryAttempts  "AutomaticRetryAttempts" from request.
1259797d5daeSCorey Hardesty  *
1260797d5daeSCorey Hardesty  *@return None.
1261797d5daeSCorey Hardesty  */
1262797d5daeSCorey Hardesty 
1263ac106bf6SEd Tanous inline void setAutomaticRetryAttempts(
1264ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1265797d5daeSCorey Hardesty     const uint32_t retryAttempts)
1266797d5daeSCorey Hardesty {
126762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
126887c44966SAsmitha Karunanithi     setDbusProperty(
126987c44966SAsmitha Karunanithi         asyncResp, "xyz.openbmc_project.State.Host",
127087c44966SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
12719ae226faSGeorge Liu         "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
127287c44966SAsmitha Karunanithi         "Boot/AutomaticRetryAttempts", retryAttempts);
1273797d5daeSCorey Hardesty }
1274797d5daeSCorey Hardesty 
12758d69c668SEd Tanous inline computer_system::PowerRestorePolicyTypes
12768d69c668SEd Tanous     redfishPowerRestorePolicyFromDbus(std::string_view value)
12778d69c668SEd Tanous {
12788d69c668SEd Tanous     if (value ==
12798d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
12808d69c668SEd Tanous     {
12818d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOn;
12828d69c668SEd Tanous     }
12838d69c668SEd Tanous     if (value ==
12848d69c668SEd Tanous         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
12858d69c668SEd Tanous     {
12868d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12878d69c668SEd Tanous     }
12888d69c668SEd Tanous     if (value ==
12893a34b742SGunnar Mills         "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
12908d69c668SEd Tanous     {
12918d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::LastState;
12928d69c668SEd Tanous     }
12938d69c668SEd Tanous     if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
12948d69c668SEd Tanous     {
12958d69c668SEd Tanous         return computer_system::PowerRestorePolicyTypes::AlwaysOff;
12968d69c668SEd Tanous     }
12978d69c668SEd Tanous     return computer_system::PowerRestorePolicyTypes::Invalid;
12988d69c668SEd Tanous }
1299797d5daeSCorey Hardesty /**
1300c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1301c6a620f2SGeorge Liu  *
1302ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
1303c6a620f2SGeorge Liu  *
1304c6a620f2SGeorge Liu  * @return None.
1305c6a620f2SGeorge Liu  */
13068d1b46d7Szhanghch05 inline void
1307ac106bf6SEd Tanous     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1308c6a620f2SGeorge Liu {
130962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power restore policy");
1310c6a620f2SGeorge Liu 
13111e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
13121e1e598dSJonathan Doman         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13131e1e598dSJonathan Doman         "/xyz/openbmc_project/control/host0/power_restore_policy",
13141e1e598dSJonathan Doman         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1315ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
13165e7e2dc5SEd Tanous                     const std::string& policy) {
1317c6a620f2SGeorge Liu         if (ec)
1318c6a620f2SGeorge Liu         {
131962598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1320c6a620f2SGeorge Liu             return;
1321c6a620f2SGeorge Liu         }
13228d69c668SEd Tanous         computer_system::PowerRestorePolicyTypes restore =
13238d69c668SEd Tanous             redfishPowerRestorePolicyFromDbus(policy);
13248d69c668SEd Tanous         if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1325c6a620f2SGeorge Liu         {
1326ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1327c6a620f2SGeorge Liu             return;
1328c6a620f2SGeorge Liu         }
1329c6a620f2SGeorge Liu 
13308d69c668SEd Tanous         asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
13311e1e598dSJonathan Doman     });
1332c6a620f2SGeorge Liu }
1333c6a620f2SGeorge Liu 
1334c6a620f2SGeorge Liu /**
13359dcfe8c1SAlbert Zhang  * @brief Stop Boot On Fault over DBUS.
13369dcfe8c1SAlbert Zhang  *
13379dcfe8c1SAlbert Zhang  * @param[in] asyncResp     Shared pointer for generating response message.
13389dcfe8c1SAlbert Zhang  *
13399dcfe8c1SAlbert Zhang  * @return None.
13409dcfe8c1SAlbert Zhang  */
13419dcfe8c1SAlbert Zhang inline void
13429dcfe8c1SAlbert Zhang     getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13439dcfe8c1SAlbert Zhang {
134462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
13459dcfe8c1SAlbert Zhang 
13469dcfe8c1SAlbert Zhang     sdbusplus::asio::getProperty<bool>(
13479dcfe8c1SAlbert Zhang         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
13489dcfe8c1SAlbert Zhang         "/xyz/openbmc_project/logging/settings",
13499dcfe8c1SAlbert Zhang         "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
13509dcfe8c1SAlbert Zhang         [asyncResp](const boost::system::error_code& ec, bool value) {
13519dcfe8c1SAlbert Zhang         if (ec)
13529dcfe8c1SAlbert Zhang         {
13539dcfe8c1SAlbert Zhang             if (ec.value() != EBADR)
13549dcfe8c1SAlbert Zhang             {
1355b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
13569dcfe8c1SAlbert Zhang                 messages::internalError(asyncResp->res);
13579dcfe8c1SAlbert Zhang             }
13589dcfe8c1SAlbert Zhang             return;
13599dcfe8c1SAlbert Zhang         }
13609dcfe8c1SAlbert Zhang 
13619dcfe8c1SAlbert Zhang         if (value)
13629dcfe8c1SAlbert Zhang         {
13639dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
13649dcfe8c1SAlbert Zhang         }
13659dcfe8c1SAlbert Zhang         else
13669dcfe8c1SAlbert Zhang         {
13679dcfe8c1SAlbert Zhang             asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
13689dcfe8c1SAlbert Zhang         }
13699dcfe8c1SAlbert Zhang     });
13709dcfe8c1SAlbert Zhang }
13719dcfe8c1SAlbert Zhang 
13729dcfe8c1SAlbert Zhang /**
13731981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13741981771bSAli Ahmed  * TPM is required for booting the host.
13751981771bSAli Ahmed  *
1376ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
13771981771bSAli Ahmed  *
13781981771bSAli Ahmed  * @return None.
13791981771bSAli Ahmed  */
13801981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
1381ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
13821981771bSAli Ahmed {
138362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get TPM required to boot.");
1384e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1385e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1386e99073f5SGeorge Liu     dbus::utility::getSubTree(
1387e99073f5SGeorge Liu         "/", 0, interfaces,
1388ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1389b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
13901981771bSAli Ahmed         if (ec)
13911981771bSAli Ahmed         {
139262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
139362598e31SEd Tanous                              ec);
13941981771bSAli Ahmed             // This is an optional D-Bus object so just return if
13951981771bSAli Ahmed             // error occurs
13961981771bSAli Ahmed             return;
13971981771bSAli Ahmed         }
139826f6976fSEd Tanous         if (subtree.empty())
13991981771bSAli Ahmed         {
14001981771bSAli Ahmed             // As noted above, this is an optional interface so just return
14011981771bSAli Ahmed             // if there is no instance found
14021981771bSAli Ahmed             return;
14031981771bSAli Ahmed         }
14041981771bSAli Ahmed 
14051981771bSAli Ahmed         /* When there is more than one TPMEnable object... */
14061981771bSAli Ahmed         if (subtree.size() > 1)
14071981771bSAli Ahmed         {
140862598e31SEd Tanous             BMCWEB_LOG_DEBUG(
140962598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
141062598e31SEd Tanous                 subtree.size());
14111981771bSAli Ahmed             // Throw an internal Error and return
1412ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14131981771bSAli Ahmed             return;
14141981771bSAli Ahmed         }
14151981771bSAli Ahmed 
14161981771bSAli Ahmed         // Make sure the Dbus response map has a service and objectPath
14171981771bSAli Ahmed         // field
14181981771bSAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14191981771bSAli Ahmed         {
142062598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1421ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14221981771bSAli Ahmed             return;
14231981771bSAli Ahmed         }
14241981771bSAli Ahmed 
14251981771bSAli Ahmed         const std::string& path = subtree[0].first;
14261981771bSAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
14271981771bSAli Ahmed 
14281981771bSAli Ahmed         // Valid TPM Enable object found, now reading the current value
14291e1e598dSJonathan Doman         sdbusplus::asio::getProperty<bool>(
14301e1e598dSJonathan Doman             *crow::connections::systemBus, serv, path,
14311e1e598dSJonathan Doman             "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1432ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
1433ac106bf6SEd Tanous                         bool tpmRequired) {
14348a592810SEd Tanous             if (ec2)
14351981771bSAli Ahmed             {
1436b3e86cb0SGunnar Mills                 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
143762598e31SEd Tanous                                  ec2);
1438ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
14391981771bSAli Ahmed                 return;
14401981771bSAli Ahmed             }
14411981771bSAli Ahmed 
14421e1e598dSJonathan Doman             if (tpmRequired)
14431981771bSAli Ahmed             {
1444ac106bf6SEd Tanous                 asyncResp->res
1445ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14461981771bSAli Ahmed                     "Required";
14471981771bSAli Ahmed             }
14481981771bSAli Ahmed             else
14491981771bSAli Ahmed             {
1450ac106bf6SEd Tanous                 asyncResp->res
1451ac106bf6SEd Tanous                     .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14521981771bSAli Ahmed                     "Disabled";
14531981771bSAli Ahmed             }
14541e1e598dSJonathan Doman         });
1455e99073f5SGeorge Liu     });
14561981771bSAli Ahmed }
14571981771bSAli Ahmed 
14581981771bSAli Ahmed /**
14591c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14601c05dae3SAli Ahmed  * TPM is required for booting the host.
14611c05dae3SAli Ahmed  *
1462ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for generating response message.
14631c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14641c05dae3SAli Ahmed  *
14651c05dae3SAli Ahmed  * @return None.
14661c05dae3SAli Ahmed  */
14671c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1468ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
14691c05dae3SAli Ahmed {
147062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
1471e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1472e99073f5SGeorge Liu         "xyz.openbmc_project.Control.TPM.Policy"};
1473e99073f5SGeorge Liu     dbus::utility::getSubTree(
1474e99073f5SGeorge Liu         "/", 0, interfaces,
1475ac106bf6SEd Tanous         [asyncResp,
1476e99073f5SGeorge Liu          tpmRequired](const boost::system::error_code& ec,
1477e99073f5SGeorge Liu                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
14781c05dae3SAli Ahmed         if (ec)
14791c05dae3SAli Ahmed         {
1480b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
148162598e31SEd Tanous                              ec);
1482ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
14831c05dae3SAli Ahmed             return;
14841c05dae3SAli Ahmed         }
148526f6976fSEd Tanous         if (subtree.empty())
14861c05dae3SAli Ahmed         {
1487ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
14881c05dae3SAli Ahmed                                              "TrustedModuleRequiredToBoot");
14891c05dae3SAli Ahmed             return;
14901c05dae3SAli Ahmed         }
14911c05dae3SAli Ahmed 
14921c05dae3SAli Ahmed         /* When there is more than one TPMEnable object... */
14931c05dae3SAli Ahmed         if (subtree.size() > 1)
14941c05dae3SAli Ahmed         {
149562598e31SEd Tanous             BMCWEB_LOG_DEBUG(
149662598e31SEd Tanous                 "DBUS response has more than 1 TPM Enable object:{}",
149762598e31SEd Tanous                 subtree.size());
14981c05dae3SAli Ahmed             // Throw an internal Error and return
1499ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15001c05dae3SAli Ahmed             return;
15011c05dae3SAli Ahmed         }
15021c05dae3SAli Ahmed 
15031c05dae3SAli Ahmed         // Make sure the Dbus response map has a service and objectPath
15041c05dae3SAli Ahmed         // field
15051c05dae3SAli Ahmed         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
15061c05dae3SAli Ahmed         {
150762598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1508ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15091c05dae3SAli Ahmed             return;
15101c05dae3SAli Ahmed         }
15111c05dae3SAli Ahmed 
15121c05dae3SAli Ahmed         const std::string& path = subtree[0].first;
15131c05dae3SAli Ahmed         const std::string& serv = subtree[0].second.begin()->first;
15141c05dae3SAli Ahmed 
15151c05dae3SAli Ahmed         if (serv.empty())
15161c05dae3SAli Ahmed         {
151762598e31SEd Tanous             BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1518ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
15191c05dae3SAli Ahmed             return;
15201c05dae3SAli Ahmed         }
15211c05dae3SAli Ahmed 
15221c05dae3SAli Ahmed         // Valid TPM Enable object found, now setting the value
152387c44966SAsmitha Karunanithi         setDbusProperty(asyncResp, serv, path,
152487c44966SAsmitha Karunanithi                         "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
152587c44966SAsmitha Karunanithi                         "Boot/TrustedModuleRequiredToBoot", tpmRequired);
1526e99073f5SGeorge Liu     });
15271c05dae3SAli Ahmed }
15281c05dae3SAli Ahmed 
15291c05dae3SAli Ahmed /**
1530491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1531491d8ee7SSantosh Puranik  *
1532ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1533cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1534cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1535cd9a4666SKonstantin Aladyshev  */
1536ac106bf6SEd Tanous inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1537cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1538cd9a4666SKonstantin Aladyshev {
1539c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1540cd9a4666SKonstantin Aladyshev 
1541c21865c4SKonstantin Aladyshev     if (!bootType)
1542cd9a4666SKonstantin Aladyshev     {
1543c21865c4SKonstantin Aladyshev         return;
1544c21865c4SKonstantin Aladyshev     }
1545c21865c4SKonstantin Aladyshev 
1546cd9a4666SKonstantin Aladyshev     // Source target specified
154762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
1548cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1549cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1550cd9a4666SKonstantin Aladyshev     {
1551cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1552cd9a4666SKonstantin Aladyshev     }
1553cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1554cd9a4666SKonstantin Aladyshev     {
1555cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1556cd9a4666SKonstantin Aladyshev     }
1557cd9a4666SKonstantin Aladyshev     else
1558cd9a4666SKonstantin Aladyshev     {
155962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for "
156062598e31SEd Tanous                          "BootSourceOverrideMode: {}",
156162598e31SEd Tanous                          *bootType);
1562ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootType,
1563cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1564cd9a4666SKonstantin Aladyshev         return;
1565cd9a4666SKonstantin Aladyshev     }
1566cd9a4666SKonstantin Aladyshev 
1567cd9a4666SKonstantin Aladyshev     // Act on validated parameters
156862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
1569cd9a4666SKonstantin Aladyshev 
157087c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
157187c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
157287c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
157387c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Type", "BootType",
157487c44966SAsmitha Karunanithi                     "Boot/BootSourceOverrideMode", bootTypeStr);
1575cd9a4666SKonstantin Aladyshev }
1576cd9a4666SKonstantin Aladyshev 
1577cd9a4666SKonstantin Aladyshev /**
1578cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1579cd9a4666SKonstantin Aladyshev  *
1580ac106bf6SEd Tanous  * @param[in] asyncResp           Shared pointer for generating response
1581ac106bf6SEd Tanous  * message.
1582c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1583c21865c4SKonstantin Aladyshev  * @return Integer error code.
1584c21865c4SKonstantin Aladyshev  */
1585ac106bf6SEd Tanous inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1586c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1587c21865c4SKonstantin Aladyshev {
1588c21865c4SKonstantin Aladyshev     if (!bootEnable)
1589c21865c4SKonstantin Aladyshev     {
1590c21865c4SKonstantin Aladyshev         return;
1591c21865c4SKonstantin Aladyshev     }
1592c21865c4SKonstantin Aladyshev     // Source target specified
159362598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
1594c21865c4SKonstantin Aladyshev 
1595c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1596c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1597c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1598c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1599c21865c4SKonstantin Aladyshev     {
1600c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1601c21865c4SKonstantin Aladyshev     }
1602c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1603c21865c4SKonstantin Aladyshev     {
1604c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1605c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1606c21865c4SKonstantin Aladyshev     }
1607c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1608c21865c4SKonstantin Aladyshev     {
1609c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1610c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1611c21865c4SKonstantin Aladyshev     }
1612c21865c4SKonstantin Aladyshev     else
1613c21865c4SKonstantin Aladyshev     {
161462598e31SEd Tanous         BMCWEB_LOG_DEBUG(
161562598e31SEd Tanous             "Invalid property value for BootSourceOverrideEnabled: {}",
161662598e31SEd Tanous             *bootEnable);
1617ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootEnable,
1618c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1619c21865c4SKonstantin Aladyshev         return;
1620c21865c4SKonstantin Aladyshev     }
1621c21865c4SKonstantin Aladyshev 
1622c21865c4SKonstantin Aladyshev     // Act on validated parameters
162362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
1624c21865c4SKonstantin Aladyshev 
162587c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
162687c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
162787c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
162887c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
162987c44966SAsmitha Karunanithi                     "Boot/BootSourceOverrideEnabled", bootOverrideEnable);
1630c21865c4SKonstantin Aladyshev 
1631c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1632c21865c4SKonstantin Aladyshev     {
1633c21865c4SKonstantin Aladyshev         return;
1634c21865c4SKonstantin Aladyshev     }
1635c21865c4SKonstantin Aladyshev 
1636c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1637c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
163862598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
163962598e31SEd Tanous                      bootOverridePersistent);
1640c21865c4SKonstantin Aladyshev 
164187c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
164287c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
164387c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot/one_time"),
164487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Object.Enable", "Enabled",
164587c44966SAsmitha Karunanithi                     "Boot/BootSourceOverrideEnabled", !bootOverridePersistent);
1646c21865c4SKonstantin Aladyshev }
1647c21865c4SKonstantin Aladyshev 
1648c21865c4SKonstantin Aladyshev /**
1649c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1650c21865c4SKonstantin Aladyshev  *
1651ac106bf6SEd Tanous  * @param[in] asyncResp       Shared pointer for generating response message.
1652491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1653491d8ee7SSantosh Puranik  *
1654265c1602SJohnathan Mantey  * @return Integer error code.
1655491d8ee7SSantosh Puranik  */
1656ac106bf6SEd Tanous inline void
1657ac106bf6SEd Tanous     setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1658cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootSource)
1659491d8ee7SSantosh Puranik {
1660c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1661c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1662944ffaf9SJohnathan Mantey 
1663c21865c4SKonstantin Aladyshev     if (!bootSource)
1664491d8ee7SSantosh Puranik     {
1665c21865c4SKonstantin Aladyshev         return;
1666c21865c4SKonstantin Aladyshev     }
1667c21865c4SKonstantin Aladyshev 
1668491d8ee7SSantosh Puranik     // Source target specified
166962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
1670491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1671ac106bf6SEd Tanous     if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1672ac106bf6SEd Tanous                              bootModeStr) != 0)
1673491d8ee7SSantosh Puranik     {
167462598e31SEd Tanous         BMCWEB_LOG_DEBUG(
167562598e31SEd Tanous             "Invalid property value for BootSourceOverrideTarget: {}",
167662598e31SEd Tanous             *bootSource);
1677ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, *bootSource,
1678491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1679491d8ee7SSantosh Puranik         return;
1680491d8ee7SSantosh Puranik     }
1681491d8ee7SSantosh Puranik 
1682944ffaf9SJohnathan Mantey     // Act on validated parameters
168362598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
168462598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
1685944ffaf9SJohnathan Mantey 
168687c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
168787c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
168887c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
168987c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Source", "BootSource",
169087c44966SAsmitha Karunanithi                     "Boot/BootSourceOverrideTarget", bootSourceStr);
169187c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
169287c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
169387c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/boot"),
169487c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
169587c44966SAsmitha Karunanithi                     "Boot/BootSourceOverrideTarget", bootModeStr);
1696cd9a4666SKonstantin Aladyshev }
1697944ffaf9SJohnathan Mantey 
1698cd9a4666SKonstantin Aladyshev /**
1699c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1700491d8ee7SSantosh Puranik  *
1701ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
1702491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1703cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1704491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1705491d8ee7SSantosh Puranik  *
1706265c1602SJohnathan Mantey  * @return Integer error code.
1707491d8ee7SSantosh Puranik  */
1708c21865c4SKonstantin Aladyshev 
1709ac106bf6SEd Tanous inline void
1710ac106bf6SEd Tanous     setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1711c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootSource,
1712c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootType,
1713c21865c4SKonstantin Aladyshev                       const std::optional<std::string>& bootEnable)
1714491d8ee7SSantosh Puranik {
171562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set boot information.");
1716491d8ee7SSantosh Puranik 
1717ac106bf6SEd Tanous     setBootModeOrSource(asyncResp, bootSource);
1718ac106bf6SEd Tanous     setBootType(asyncResp, bootType);
1719ac106bf6SEd Tanous     setBootEnable(asyncResp, bootEnable);
1720491d8ee7SSantosh Puranik }
1721491d8ee7SSantosh Puranik 
1722c6a620f2SGeorge Liu /**
172398e386ecSGunnar Mills  * @brief Sets AssetTag
172498e386ecSGunnar Mills  *
1725ac106bf6SEd Tanous  * @param[in] asyncResp Shared pointer for generating response message.
172698e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
172798e386ecSGunnar Mills  *
172898e386ecSGunnar Mills  * @return None.
172998e386ecSGunnar Mills  */
1730ac106bf6SEd Tanous inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
173198e386ecSGunnar Mills                         const std::string& assetTag)
173298e386ecSGunnar Mills {
1733e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
1734e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.System"};
1735e99073f5SGeorge Liu     dbus::utility::getSubTree(
1736e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, interfaces,
1737ac106bf6SEd Tanous         [asyncResp,
1738e99073f5SGeorge Liu          assetTag](const boost::system::error_code& ec,
1739b9d36b47SEd Tanous                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
174098e386ecSGunnar Mills         if (ec)
174198e386ecSGunnar Mills         {
174262598e31SEd Tanous             BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1743ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
174498e386ecSGunnar Mills             return;
174598e386ecSGunnar Mills         }
174626f6976fSEd Tanous         if (subtree.empty())
174798e386ecSGunnar Mills         {
174862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1749ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
175098e386ecSGunnar Mills             return;
175198e386ecSGunnar Mills         }
175298e386ecSGunnar Mills         // Assume only 1 system D-Bus object
175398e386ecSGunnar Mills         // Throw an error if there is more than 1
175498e386ecSGunnar Mills         if (subtree.size() > 1)
175598e386ecSGunnar Mills         {
175662598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1757ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
175898e386ecSGunnar Mills             return;
175998e386ecSGunnar Mills         }
176098e386ecSGunnar Mills         if (subtree[0].first.empty() || subtree[0].second.size() != 1)
176198e386ecSGunnar Mills         {
176262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1763ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
176498e386ecSGunnar Mills             return;
176598e386ecSGunnar Mills         }
176698e386ecSGunnar Mills 
176798e386ecSGunnar Mills         const std::string& path = subtree[0].first;
176898e386ecSGunnar Mills         const std::string& service = subtree[0].second.begin()->first;
176998e386ecSGunnar Mills 
177098e386ecSGunnar Mills         if (service.empty())
177198e386ecSGunnar Mills         {
177262598e31SEd Tanous             BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1773ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
177498e386ecSGunnar Mills             return;
177598e386ecSGunnar Mills         }
177698e386ecSGunnar Mills 
177787c44966SAsmitha Karunanithi         setDbusProperty(asyncResp, service, path,
177887c44966SAsmitha Karunanithi                         "xyz.openbmc_project.Inventory.Decorator.AssetTag",
177987c44966SAsmitha Karunanithi                         "AssetTag", "AssetTag", assetTag);
1780e99073f5SGeorge Liu     });
178198e386ecSGunnar Mills }
178298e386ecSGunnar Mills 
178398e386ecSGunnar Mills /**
17849dcfe8c1SAlbert Zhang  * @brief Validate the specified stopBootOnFault is valid and return the
17859dcfe8c1SAlbert Zhang  * stopBootOnFault name associated with that string
17869dcfe8c1SAlbert Zhang  *
17879dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFaultString  String representing the desired
17889dcfe8c1SAlbert Zhang  * stopBootOnFault
17899dcfe8c1SAlbert Zhang  *
17909dcfe8c1SAlbert Zhang  * @return stopBootOnFault value or empty  if incoming value is not valid
17919dcfe8c1SAlbert Zhang  */
17929dcfe8c1SAlbert Zhang inline std::optional<bool>
17939dcfe8c1SAlbert Zhang     validstopBootOnFault(const std::string& stopBootOnFaultString)
17949dcfe8c1SAlbert Zhang {
17959dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "AnyFault")
17969dcfe8c1SAlbert Zhang     {
17979dcfe8c1SAlbert Zhang         return true;
17989dcfe8c1SAlbert Zhang     }
17999dcfe8c1SAlbert Zhang 
18009dcfe8c1SAlbert Zhang     if (stopBootOnFaultString == "Never")
18019dcfe8c1SAlbert Zhang     {
18029dcfe8c1SAlbert Zhang         return false;
18039dcfe8c1SAlbert Zhang     }
18049dcfe8c1SAlbert Zhang 
18059dcfe8c1SAlbert Zhang     return std::nullopt;
18069dcfe8c1SAlbert Zhang }
18079dcfe8c1SAlbert Zhang 
18089dcfe8c1SAlbert Zhang /**
18099dcfe8c1SAlbert Zhang  * @brief Sets stopBootOnFault
18109dcfe8c1SAlbert Zhang  *
1811fc3edfddSEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
18129dcfe8c1SAlbert Zhang  * @param[in] stopBootOnFault  "StopBootOnFault" from request.
18139dcfe8c1SAlbert Zhang  *
18149dcfe8c1SAlbert Zhang  * @return None.
18159dcfe8c1SAlbert Zhang  */
1816fc3edfddSEd Tanous inline void
1817fc3edfddSEd Tanous     setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
18189dcfe8c1SAlbert Zhang                        const std::string& stopBootOnFault)
18199dcfe8c1SAlbert Zhang {
182062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
18219dcfe8c1SAlbert Zhang 
18229dcfe8c1SAlbert Zhang     std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
18239dcfe8c1SAlbert Zhang     if (!stopBootEnabled)
18249dcfe8c1SAlbert Zhang     {
182562598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
182662598e31SEd Tanous                          stopBootOnFault);
1827fc3edfddSEd Tanous         messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
18289dcfe8c1SAlbert Zhang                                          "StopBootOnFault");
18299dcfe8c1SAlbert Zhang         return;
18309dcfe8c1SAlbert Zhang     }
18319dcfe8c1SAlbert Zhang 
183287c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
183387c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
183487c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/logging/settings"),
1835fc3edfddSEd Tanous                     "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
183687c44966SAsmitha Karunanithi                     "Boot/StopBootOnFault", *stopBootEnabled);
18379dcfe8c1SAlbert Zhang }
18389dcfe8c1SAlbert Zhang 
18399dcfe8c1SAlbert Zhang /**
184069f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
184169f35306SGunnar Mills  *
1842ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
184369f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
184469f35306SGunnar Mills  *
184569f35306SGunnar Mills  * @return None.
184669f35306SGunnar Mills  */
1847ac106bf6SEd Tanous inline void
1848ac106bf6SEd Tanous     setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1849f23b7296SEd Tanous                       const std::string& automaticRetryConfig)
185069f35306SGunnar Mills {
185162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set Automatic Retry.");
185269f35306SGunnar Mills 
185369f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
1854543f4400SEd Tanous     bool autoRebootEnabled = false;
185569f35306SGunnar Mills 
185669f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
185769f35306SGunnar Mills     {
185869f35306SGunnar Mills         autoRebootEnabled = false;
185969f35306SGunnar Mills     }
186069f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
186169f35306SGunnar Mills     {
186269f35306SGunnar Mills         autoRebootEnabled = true;
186369f35306SGunnar Mills     }
186469f35306SGunnar Mills     else
186569f35306SGunnar Mills     {
186662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
186762598e31SEd Tanous                          automaticRetryConfig);
1868ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
186969f35306SGunnar Mills                                          "AutomaticRetryConfig");
187069f35306SGunnar Mills         return;
187169f35306SGunnar Mills     }
187269f35306SGunnar Mills 
187387c44966SAsmitha Karunanithi     setDbusProperty(asyncResp, "xyz.openbmc_project.Settings",
187487c44966SAsmitha Karunanithi                     sdbusplus::message::object_path(
187587c44966SAsmitha Karunanithi                         "/xyz/openbmc_project/control/host0/auto_reboot"),
187687c44966SAsmitha Karunanithi                     "xyz.openbmc_project.Control.Boot.RebootPolicy",
187787c44966SAsmitha Karunanithi                     "AutoReboot", "Boot/AutomaticRetryConfig",
187887c44966SAsmitha Karunanithi                     autoRebootEnabled);
187969f35306SGunnar Mills }
188069f35306SGunnar Mills 
18818d69c668SEd Tanous inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
18828d69c668SEd Tanous {
18838d69c668SEd Tanous     if (policy == "AlwaysOn")
18848d69c668SEd Tanous     {
18858d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
18868d69c668SEd Tanous     }
18878d69c668SEd Tanous     if (policy == "AlwaysOff")
18888d69c668SEd Tanous     {
18898d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
18908d69c668SEd Tanous     }
18918d69c668SEd Tanous     if (policy == "LastState")
18928d69c668SEd Tanous     {
18938d69c668SEd Tanous         return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
18948d69c668SEd Tanous     }
18958d69c668SEd Tanous     return "";
18968d69c668SEd Tanous }
18978d69c668SEd Tanous 
189869f35306SGunnar Mills /**
1899c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1900c6a620f2SGeorge Liu  *
1901ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
1902c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1903c6a620f2SGeorge Liu  *
1904c6a620f2SGeorge Liu  * @return None.
1905c6a620f2SGeorge Liu  */
19068d1b46d7Szhanghch05 inline void
1907ac106bf6SEd Tanous     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19088d69c668SEd Tanous                           std::string_view policy)
1909c6a620f2SGeorge Liu {
191062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power restore policy.");
1911c6a620f2SGeorge Liu 
19128d69c668SEd Tanous     std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
1913c6a620f2SGeorge Liu 
19148d69c668SEd Tanous     if (powerRestorePolicy.empty())
1915c6a620f2SGeorge Liu     {
1916ac106bf6SEd Tanous         messages::propertyValueNotInList(asyncResp->res, policy,
19174e69c904SGunnar Mills                                          "PowerRestorePolicy");
1918c6a620f2SGeorge Liu         return;
1919c6a620f2SGeorge Liu     }
1920c6a620f2SGeorge Liu 
192187c44966SAsmitha Karunanithi     setDbusProperty(
192287c44966SAsmitha Karunanithi         asyncResp, "xyz.openbmc_project.Settings",
192387c44966SAsmitha Karunanithi         sdbusplus::message::object_path(
192487c44966SAsmitha Karunanithi             "/xyz/openbmc_project/control/host0/power_restore_policy"),
19259ae226faSGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
192687c44966SAsmitha Karunanithi         "PowerRestorePolicy", powerRestorePolicy);
1927c6a620f2SGeorge Liu }
1928c6a620f2SGeorge Liu 
1929a6349918SAppaRao Puli /**
1930a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1931a6349918SAppaRao Puli  *
193225b54dbaSEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous
193325b54dbaSEd Tanous  * calls.
1934a6349918SAppaRao Puli  *
1935a6349918SAppaRao Puli  * @return None.
1936a6349918SAppaRao Puli  */
193725b54dbaSEd Tanous inline void
193825b54dbaSEd Tanous     getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1939a6349918SAppaRao Puli {
194062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get OEM information.");
1941bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
1942bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1943bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
1944ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
1945b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& propertiesList) {
1946b99fb1a9SAppaRao Puli         nlohmann::json& oemPFR =
1947ac106bf6SEd Tanous             asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1948ac106bf6SEd Tanous         asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
194950626f4fSJames Feist             "#OemComputerSystem.OpenBmc";
195050626f4fSJames Feist         oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
195150626f4fSJames Feist 
1952a6349918SAppaRao Puli         if (ec)
1953a6349918SAppaRao Puli         {
195462598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1955b99fb1a9SAppaRao Puli             // not an error, don't have to have the interface
1956b99fb1a9SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1957a6349918SAppaRao Puli             return;
1958a6349918SAppaRao Puli         }
1959a6349918SAppaRao Puli 
1960a6349918SAppaRao Puli         const bool* provState = nullptr;
1961a6349918SAppaRao Puli         const bool* lockState = nullptr;
1962bc1d29deSKrzysztof Grobelny 
1963bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
19640d4befa8SJiaqing Zhao             dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
19650d4befa8SJiaqing Zhao             provState, "UfmLocked", lockState);
1966bc1d29deSKrzysztof Grobelny 
1967bc1d29deSKrzysztof Grobelny         if (!success)
1968a6349918SAppaRao Puli         {
1969ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1970bc1d29deSKrzysztof Grobelny             return;
1971a6349918SAppaRao Puli         }
1972a6349918SAppaRao Puli 
1973a6349918SAppaRao Puli         if ((provState == nullptr) || (lockState == nullptr))
1974a6349918SAppaRao Puli         {
197562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
1976ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
1977a6349918SAppaRao Puli             return;
1978a6349918SAppaRao Puli         }
1979a6349918SAppaRao Puli 
198025b54dbaSEd Tanous         if (*provState)
1981a6349918SAppaRao Puli         {
198225b54dbaSEd Tanous             if (*lockState)
1983a6349918SAppaRao Puli             {
1984a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1985a6349918SAppaRao Puli             }
1986a6349918SAppaRao Puli             else
1987a6349918SAppaRao Puli             {
1988a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1989a6349918SAppaRao Puli             }
1990a6349918SAppaRao Puli         }
1991a6349918SAppaRao Puli         else
1992a6349918SAppaRao Puli         {
1993a6349918SAppaRao Puli             oemPFR["ProvisioningStatus"] = "NotProvisioned";
1994a6349918SAppaRao Puli         }
1995bc1d29deSKrzysztof Grobelny     });
1996a6349918SAppaRao Puli }
1997a6349918SAppaRao Puli 
1998491d8ee7SSantosh Puranik /**
19996b9ac4f2SChris Cain  * @brief Translate the PowerMode string to enum value
20003a2d0424SChris Cain  *
20016b9ac4f2SChris Cain  * @param[in]  modeString PowerMode string to be translated
20023a2d0424SChris Cain  *
20036b9ac4f2SChris Cain  * @return PowerMode enum
20043a2d0424SChris Cain  */
20056b9ac4f2SChris Cain inline computer_system::PowerMode
20066b9ac4f2SChris Cain     translatePowerModeString(const std::string& modeString)
20073a2d0424SChris Cain {
2008b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
2009b6655101SChris Cain 
20106b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20113a2d0424SChris Cain     {
20126b9ac4f2SChris Cain         return PowerMode::Static;
20133a2d0424SChris Cain     }
20146b9ac4f2SChris Cain     if (modeString ==
20150fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20163a2d0424SChris Cain     {
20176b9ac4f2SChris Cain         return PowerMode::MaximumPerformance;
20183a2d0424SChris Cain     }
20196b9ac4f2SChris Cain     if (modeString ==
20200fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20213a2d0424SChris Cain     {
20226b9ac4f2SChris Cain         return PowerMode::PowerSaving;
2023b6655101SChris Cain     }
20246b9ac4f2SChris Cain     if (modeString ==
2025b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2026b6655101SChris Cain     {
20276b9ac4f2SChris Cain         return PowerMode::BalancedPerformance;
2028b6655101SChris Cain     }
20296b9ac4f2SChris Cain     if (modeString ==
2030b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2031b6655101SChris Cain     {
20326b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPerformance;
2033b6655101SChris Cain     }
20346b9ac4f2SChris Cain     if (modeString ==
2035b6655101SChris Cain         "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2036b6655101SChris Cain     {
20376b9ac4f2SChris Cain         return PowerMode::EfficiencyFavorPower;
20383a2d0424SChris Cain     }
20396b9ac4f2SChris Cain     if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20403a2d0424SChris Cain     {
20416b9ac4f2SChris Cain         return PowerMode::OEM;
20426b9ac4f2SChris Cain     }
20436b9ac4f2SChris Cain     // Any other values would be invalid
20446b9ac4f2SChris Cain     BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
20456b9ac4f2SChris Cain     return PowerMode::Invalid;
20466b9ac4f2SChris Cain }
20476b9ac4f2SChris Cain 
20486b9ac4f2SChris Cain inline void
20496b9ac4f2SChris Cain     afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20506b9ac4f2SChris Cain                       const boost::system::error_code& ec,
20516b9ac4f2SChris Cain                       const dbus::utility::DBusPropertiesMap& properties)
20526b9ac4f2SChris Cain {
20536b9ac4f2SChris Cain     if (ec)
20546b9ac4f2SChris Cain     {
20556b9ac4f2SChris Cain         BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
20566b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20576b9ac4f2SChris Cain         return;
20586b9ac4f2SChris Cain     }
20596b9ac4f2SChris Cain 
20606b9ac4f2SChris Cain     std::string powerMode;
20616b9ac4f2SChris Cain     const std::vector<std::string>* allowedModes = nullptr;
20626b9ac4f2SChris Cain     const bool success = sdbusplus::unpackPropertiesNoThrow(
20636b9ac4f2SChris Cain         dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
20646b9ac4f2SChris Cain         "AllowedPowerModes", allowedModes);
20656b9ac4f2SChris Cain 
20666b9ac4f2SChris Cain     if (!success)
20676b9ac4f2SChris Cain     {
20686b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
20696b9ac4f2SChris Cain         return;
20706b9ac4f2SChris Cain     }
20716b9ac4f2SChris Cain 
20726b9ac4f2SChris Cain     nlohmann::json::array_t modeList;
20736b9ac4f2SChris Cain     if (allowedModes == nullptr)
20746b9ac4f2SChris Cain     {
20756b9ac4f2SChris Cain         modeList.emplace_back("Static");
20766b9ac4f2SChris Cain         modeList.emplace_back("MaximumPerformance");
20776b9ac4f2SChris Cain         modeList.emplace_back("PowerSaving");
20783a2d0424SChris Cain     }
20793a2d0424SChris Cain     else
20803a2d0424SChris Cain     {
20816b9ac4f2SChris Cain         for (const auto& aMode : *allowedModes)
20826b9ac4f2SChris Cain         {
20836b9ac4f2SChris Cain             computer_system::PowerMode modeValue =
20846b9ac4f2SChris Cain                 translatePowerModeString(aMode);
20856b9ac4f2SChris Cain             if (modeValue == computer_system::PowerMode::Invalid)
20866b9ac4f2SChris Cain             {
2087ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
20886b9ac4f2SChris Cain                 continue;
20896b9ac4f2SChris Cain             }
20906b9ac4f2SChris Cain             modeList.emplace_back(modeValue);
20913a2d0424SChris Cain         }
20923a2d0424SChris Cain     }
20936b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
20943a2d0424SChris Cain 
20956b9ac4f2SChris Cain     BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
20966b9ac4f2SChris Cain     const computer_system::PowerMode modeValue =
20976b9ac4f2SChris Cain         translatePowerModeString(powerMode);
20986b9ac4f2SChris Cain     if (modeValue == computer_system::PowerMode::Invalid)
20996b9ac4f2SChris Cain     {
21006b9ac4f2SChris Cain         messages::internalError(asyncResp->res);
21016b9ac4f2SChris Cain         return;
21026b9ac4f2SChris Cain     }
21036b9ac4f2SChris Cain     asyncResp->res.jsonValue["PowerMode"] = modeValue;
21046b9ac4f2SChris Cain }
21053a2d0424SChris Cain /**
21063a2d0424SChris Cain  * @brief Retrieves system power mode
21073a2d0424SChris Cain  *
2108ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
21093a2d0424SChris Cain  *
21103a2d0424SChris Cain  * @return None.
21113a2d0424SChris Cain  */
2112ac106bf6SEd Tanous inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
21133a2d0424SChris Cain {
211462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get power mode.");
21153a2d0424SChris Cain 
21163a2d0424SChris Cain     // Get Power Mode object path:
2117e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2118e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2119e99073f5SGeorge Liu     dbus::utility::getSubTree(
2120e99073f5SGeorge Liu         "/", 0, interfaces,
2121ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2122b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
21233a2d0424SChris Cain         if (ec)
21243a2d0424SChris Cain         {
212562598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
212662598e31SEd Tanous                              ec);
21273a2d0424SChris Cain             // This is an optional D-Bus object so just return if
21283a2d0424SChris Cain             // error occurs
21293a2d0424SChris Cain             return;
21303a2d0424SChris Cain         }
21313a2d0424SChris Cain         if (subtree.empty())
21323a2d0424SChris Cain         {
21333a2d0424SChris Cain             // As noted above, this is an optional interface so just return
21343a2d0424SChris Cain             // if there is no instance found
21353a2d0424SChris Cain             return;
21363a2d0424SChris Cain         }
21373a2d0424SChris Cain         if (subtree.size() > 1)
21383a2d0424SChris Cain         {
21393a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
21403a2d0424SChris Cain             // error
214162598e31SEd Tanous             BMCWEB_LOG_DEBUG(
214262598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
214362598e31SEd Tanous                 subtree.size());
2144ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21453a2d0424SChris Cain             return;
21463a2d0424SChris Cain         }
21473a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21483a2d0424SChris Cain         {
214962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2150ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21513a2d0424SChris Cain             return;
21523a2d0424SChris Cain         }
21533a2d0424SChris Cain         const std::string& path = subtree[0].first;
21543a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
21553a2d0424SChris Cain         if (service.empty())
21563a2d0424SChris Cain         {
215762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2158ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
21593a2d0424SChris Cain             return;
21603a2d0424SChris Cain         }
21616b9ac4f2SChris Cain 
21626b9ac4f2SChris Cain         // Valid Power Mode object found, now read the mode properties
21636b9ac4f2SChris Cain         sdbusplus::asio::getAllProperties(
21641e1e598dSJonathan Doman             *crow::connections::systemBus, service, path,
21656b9ac4f2SChris Cain             "xyz.openbmc_project.Control.Power.Mode",
2166ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
21676b9ac4f2SChris Cain                         const dbus::utility::DBusPropertiesMap& properties) {
21686b9ac4f2SChris Cain             afterGetPowerMode(asyncResp, ec2, properties);
21691e1e598dSJonathan Doman         });
2170e99073f5SGeorge Liu     });
21713a2d0424SChris Cain }
21723a2d0424SChris Cain 
21733a2d0424SChris Cain /**
21743a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21753a2d0424SChris Cain  * name associated with that string
21763a2d0424SChris Cain  *
2177ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
2178b6655101SChris Cain  * @param[in] modeValue   String representing the desired PowerMode
21793a2d0424SChris Cain  *
21803a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21813a2d0424SChris Cain  */
21823a2d0424SChris Cain inline std::string
2183ac106bf6SEd Tanous     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2184b6655101SChris Cain                       const nlohmann::json& modeValue)
21853a2d0424SChris Cain {
2186b6655101SChris Cain     using PowerMode = computer_system::PowerMode;
21873a2d0424SChris Cain     std::string mode;
21883a2d0424SChris Cain 
2189b6655101SChris Cain     if (modeValue == PowerMode::Static)
21903a2d0424SChris Cain     {
21913a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21923a2d0424SChris Cain     }
2193b6655101SChris Cain     else if (modeValue == PowerMode::MaximumPerformance)
21943a2d0424SChris Cain     {
21950fda0f12SGeorge Liu         mode =
21960fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21973a2d0424SChris Cain     }
2198b6655101SChris Cain     else if (modeValue == PowerMode::PowerSaving)
21993a2d0424SChris Cain     {
22003a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22013a2d0424SChris Cain     }
2202b6655101SChris Cain     else if (modeValue == PowerMode::BalancedPerformance)
2203b6655101SChris Cain     {
2204b6655101SChris Cain         mode =
2205b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2206b6655101SChris Cain     }
2207b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2208b6655101SChris Cain     {
2209b6655101SChris Cain         mode =
2210b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2211b6655101SChris Cain     }
2212b6655101SChris Cain     else if (modeValue == PowerMode::EfficiencyFavorPower)
2213b6655101SChris Cain     {
2214b6655101SChris Cain         mode =
2215b6655101SChris Cain             "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2216b6655101SChris Cain     }
22173a2d0424SChris Cain     else
22183a2d0424SChris Cain     {
2219b6655101SChris Cain         messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
2220ac106bf6SEd Tanous                                          "PowerMode");
22213a2d0424SChris Cain     }
22223a2d0424SChris Cain     return mode;
22233a2d0424SChris Cain }
22243a2d0424SChris Cain 
22253a2d0424SChris Cain /**
22263a2d0424SChris Cain  * @brief Sets system power mode.
22273a2d0424SChris Cain  *
2228ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for generating response message.
22293a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22303a2d0424SChris Cain  *
22313a2d0424SChris Cain  * @return None.
22323a2d0424SChris Cain  */
2233ac106bf6SEd Tanous inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
22343a2d0424SChris Cain                          const std::string& pmode)
22353a2d0424SChris Cain {
223662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set power mode.");
22373a2d0424SChris Cain 
2238ac106bf6SEd Tanous     std::string powerMode = validatePowerMode(asyncResp, pmode);
22393a2d0424SChris Cain     if (powerMode.empty())
22403a2d0424SChris Cain     {
22413a2d0424SChris Cain         return;
22423a2d0424SChris Cain     }
22433a2d0424SChris Cain 
22443a2d0424SChris Cain     // Get Power Mode object path:
2245e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2246e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode"};
2247e99073f5SGeorge Liu     dbus::utility::getSubTree(
2248e99073f5SGeorge Liu         "/", 0, interfaces,
2249ac106bf6SEd Tanous         [asyncResp,
2250e99073f5SGeorge Liu          powerMode](const boost::system::error_code& ec,
2251b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
22523a2d0424SChris Cain         if (ec)
22533a2d0424SChris Cain         {
2254b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
225562598e31SEd Tanous                              ec);
22563a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2257ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22583a2d0424SChris Cain             return;
22593a2d0424SChris Cain         }
22603a2d0424SChris Cain         if (subtree.empty())
22613a2d0424SChris Cain         {
22623a2d0424SChris Cain             // This is an optional D-Bus object, but user attempted to patch
2263ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
22643a2d0424SChris Cain                                        "PowerMode");
22653a2d0424SChris Cain             return;
22663a2d0424SChris Cain         }
22673a2d0424SChris Cain         if (subtree.size() > 1)
22683a2d0424SChris Cain         {
22693a2d0424SChris Cain             // More then one PowerMode object is not supported and is an
22703a2d0424SChris Cain             // error
227162598e31SEd Tanous             BMCWEB_LOG_DEBUG(
227262598e31SEd Tanous                 "Found more than 1 system D-Bus Power.Mode objects: {}",
227362598e31SEd Tanous                 subtree.size());
2274ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22753a2d0424SChris Cain             return;
22763a2d0424SChris Cain         }
22773a2d0424SChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22783a2d0424SChris Cain         {
227962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2280ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22813a2d0424SChris Cain             return;
22823a2d0424SChris Cain         }
22833a2d0424SChris Cain         const std::string& path = subtree[0].first;
22843a2d0424SChris Cain         const std::string& service = subtree[0].second.begin()->first;
22853a2d0424SChris Cain         if (service.empty())
22863a2d0424SChris Cain         {
228762598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2288ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
22893a2d0424SChris Cain             return;
22903a2d0424SChris Cain         }
22913a2d0424SChris Cain 
229262598e31SEd Tanous         BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
22933a2d0424SChris Cain 
22943a2d0424SChris Cain         // Set the Power Mode property
229587c44966SAsmitha Karunanithi         setDbusProperty(asyncResp, service, path,
229687c44966SAsmitha Karunanithi                         "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
229787c44966SAsmitha Karunanithi                         "PowerMode", powerMode);
2298e99073f5SGeorge Liu     });
22993a2d0424SChris Cain }
23003a2d0424SChris Cain 
23013a2d0424SChris Cain /**
230251709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
230351709ffdSYong Li  *
230451709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
230551709ffdSYong Li  *
230651709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
230751709ffdSYong Li  * translation cannot be done, returns an empty string.
230851709ffdSYong Li  */
230923a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
231051709ffdSYong Li {
231151709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
231251709ffdSYong Li     {
231351709ffdSYong Li         return "None";
231451709ffdSYong Li     }
23153174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
231651709ffdSYong Li     {
231751709ffdSYong Li         return "ResetSystem";
231851709ffdSYong Li     }
23193174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
232051709ffdSYong Li     {
232151709ffdSYong Li         return "PowerDown";
232251709ffdSYong Li     }
23233174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
232451709ffdSYong Li     {
232551709ffdSYong Li         return "PowerCycle";
232651709ffdSYong Li     }
232751709ffdSYong Li 
232851709ffdSYong Li     return "";
232951709ffdSYong Li }
233051709ffdSYong Li 
233151709ffdSYong Li /**
2332c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2333c45f0082SYong Li  *
2334c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2335c45f0082SYong Li  *
2336c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2337c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2338c45f0082SYong Li  */
2339c45f0082SYong Li 
234023a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2341c45f0082SYong Li {
2342c45f0082SYong Li     if (rfAction == "None")
2343c45f0082SYong Li     {
2344c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2345c45f0082SYong Li     }
23463174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2347c45f0082SYong Li     {
2348c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2349c45f0082SYong Li     }
23503174e4dfSEd Tanous     if (rfAction == "PowerDown")
2351c45f0082SYong Li     {
2352c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2353c45f0082SYong Li     }
23543174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2355c45f0082SYong Li     {
2356c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2357c45f0082SYong Li     }
2358c45f0082SYong Li 
2359c45f0082SYong Li     return "";
2360c45f0082SYong Li }
2361c45f0082SYong Li 
2362c45f0082SYong Li /**
236351709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
236451709ffdSYong Li  *
2365ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
236651709ffdSYong Li  *
236751709ffdSYong Li  * @return None.
236851709ffdSYong Li  */
23698d1b46d7Szhanghch05 inline void
2370ac106bf6SEd Tanous     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
237151709ffdSYong Li {
237262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get host watchodg");
2373bc1d29deSKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
2374bc1d29deSKrzysztof Grobelny         *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2375bc1d29deSKrzysztof Grobelny         "/xyz/openbmc_project/watchdog/host0",
2376bc1d29deSKrzysztof Grobelny         "xyz.openbmc_project.State.Watchdog",
2377ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2378b9d36b47SEd Tanous                     const dbus::utility::DBusPropertiesMap& properties) {
237951709ffdSYong Li         if (ec)
238051709ffdSYong Li         {
238151709ffdSYong Li             // watchdog service is stopped
238262598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
238351709ffdSYong Li             return;
238451709ffdSYong Li         }
238551709ffdSYong Li 
238662598e31SEd Tanous         BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
238751709ffdSYong Li 
238851709ffdSYong Li         nlohmann::json& hostWatchdogTimer =
2389ac106bf6SEd Tanous             asyncResp->res.jsonValue["HostWatchdogTimer"];
239051709ffdSYong Li 
239151709ffdSYong Li         // watchdog service is running/enabled
239251709ffdSYong Li         hostWatchdogTimer["Status"]["State"] = "Enabled";
239351709ffdSYong Li 
2394bc1d29deSKrzysztof Grobelny         const bool* enabled = nullptr;
2395bc1d29deSKrzysztof Grobelny         const std::string* expireAction = nullptr;
239651709ffdSYong Li 
2397bc1d29deSKrzysztof Grobelny         const bool success = sdbusplus::unpackPropertiesNoThrow(
2398bc1d29deSKrzysztof Grobelny             dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2399bc1d29deSKrzysztof Grobelny             "ExpireAction", expireAction);
2400bc1d29deSKrzysztof Grobelny 
2401bc1d29deSKrzysztof Grobelny         if (!success)
240251709ffdSYong Li         {
2403ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
2404601af5edSChicago Duan             return;
240551709ffdSYong Li         }
240651709ffdSYong Li 
2407bc1d29deSKrzysztof Grobelny         if (enabled != nullptr)
240851709ffdSYong Li         {
2409bc1d29deSKrzysztof Grobelny             hostWatchdogTimer["FunctionEnabled"] = *enabled;
241051709ffdSYong Li         }
241151709ffdSYong Li 
2412bc1d29deSKrzysztof Grobelny         if (expireAction != nullptr)
2413bc1d29deSKrzysztof Grobelny         {
2414bc1d29deSKrzysztof Grobelny             std::string action = dbusToRfWatchdogAction(*expireAction);
241551709ffdSYong Li             if (action.empty())
241651709ffdSYong Li             {
2417ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
2418601af5edSChicago Duan                 return;
241951709ffdSYong Li             }
242051709ffdSYong Li             hostWatchdogTimer["TimeoutAction"] = action;
242151709ffdSYong Li         }
2422bc1d29deSKrzysztof Grobelny     });
242351709ffdSYong Li }
242451709ffdSYong Li 
242551709ffdSYong Li /**
2426c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2427c45f0082SYong Li  *
2428ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
2429c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2430c45f0082SYong Li  *                       RF request.
2431c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2432c45f0082SYong Li  *
2433c45f0082SYong Li  * @return None.
2434c45f0082SYong Li  */
2435ac106bf6SEd Tanous inline void
2436ac106bf6SEd Tanous     setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2437c45f0082SYong Li                      const std::optional<bool> wdtEnable,
2438c45f0082SYong Li                      const std::optional<std::string>& wdtTimeOutAction)
2439c45f0082SYong Li {
244062598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set host watchdog");
2441c45f0082SYong Li 
2442c45f0082SYong Li     if (wdtTimeOutAction)
2443c45f0082SYong Li     {
2444c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2445c45f0082SYong Li         // check if TimeOut Action is Valid
2446c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2447c45f0082SYong Li         {
244862598e31SEd Tanous             BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
244962598e31SEd Tanous                              *wdtTimeOutAction);
2450ac106bf6SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
2451c45f0082SYong Li                                              "TimeoutAction");
2452c45f0082SYong Li             return;
2453c45f0082SYong Li         }
2454c45f0082SYong Li 
245587c44966SAsmitha Karunanithi         setDbusProperty(asyncResp, "xyz.openbmc_project.Watchdog",
245687c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
245787c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
24589ae226faSGeorge Liu                         "xyz.openbmc_project.State.Watchdog", "ExpireAction",
245987c44966SAsmitha Karunanithi                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutActStr);
2460c45f0082SYong Li     }
2461c45f0082SYong Li 
2462c45f0082SYong Li     if (wdtEnable)
2463c45f0082SYong Li     {
246487c44966SAsmitha Karunanithi         setDbusProperty(asyncResp, "xyz.openbmc_project.Watchdog",
246587c44966SAsmitha Karunanithi                         sdbusplus::message::object_path(
246687c44966SAsmitha Karunanithi                             "/xyz/openbmc_project/watchdog/host0"),
246787c44966SAsmitha Karunanithi                         "xyz.openbmc_project.State.Watchdog", "Enabled",
246887c44966SAsmitha Karunanithi                         "HostWatchdogTimer/FunctionEnabled", *wdtEnable);
2469c45f0082SYong Li     }
2470c45f0082SYong Li }
2471c45f0082SYong Li 
247237bbf98cSChris Cain /**
247337bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
247437bbf98cSChris Cain  *
2475ac106bf6SEd Tanous  * @param[in] asyncResp   Shared pointer for completing asynchronous calls.
247637bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
247737bbf98cSChris Cain  *
247837bbf98cSChris Cain  * @return true if successful
247937bbf98cSChris Cain  */
24801e5b7c88SJiaqing Zhao inline bool
2481ac106bf6SEd Tanous     parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24821e5b7c88SJiaqing Zhao                        const dbus::utility::DBusPropertiesMap& properties)
248337bbf98cSChris Cain {
2484bc1d29deSKrzysztof Grobelny     const bool* enabled = nullptr;
2485bc1d29deSKrzysztof Grobelny     const uint8_t* enterUtilizationPercent = nullptr;
2486bc1d29deSKrzysztof Grobelny     const uint64_t* enterDwellTime = nullptr;
2487bc1d29deSKrzysztof Grobelny     const uint8_t* exitUtilizationPercent = nullptr;
2488bc1d29deSKrzysztof Grobelny     const uint64_t* exitDwellTime = nullptr;
2489bc1d29deSKrzysztof Grobelny 
2490bc1d29deSKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
2491bc1d29deSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
24922661b72cSChris Cain         "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
24932661b72cSChris Cain         enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
24942661b72cSChris Cain         "ExitDwellTime", exitDwellTime);
2495bc1d29deSKrzysztof Grobelny 
2496bc1d29deSKrzysztof Grobelny     if (!success)
249737bbf98cSChris Cain     {
249837bbf98cSChris Cain         return false;
249937bbf98cSChris Cain     }
2500bc1d29deSKrzysztof Grobelny 
2501bc1d29deSKrzysztof Grobelny     if (enabled != nullptr)
250237bbf98cSChris Cain     {
2503ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
250437bbf98cSChris Cain     }
2505bc1d29deSKrzysztof Grobelny 
2506bc1d29deSKrzysztof Grobelny     if (enterUtilizationPercent != nullptr)
250737bbf98cSChris Cain     {
2508ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2509bc1d29deSKrzysztof Grobelny             *enterUtilizationPercent;
251037bbf98cSChris Cain     }
2511bc1d29deSKrzysztof Grobelny 
2512bc1d29deSKrzysztof Grobelny     if (enterDwellTime != nullptr)
2513bc1d29deSKrzysztof Grobelny     {
2514bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2515ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
251637bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
251737bbf98cSChris Cain                 .count();
251837bbf98cSChris Cain     }
2519bc1d29deSKrzysztof Grobelny 
2520bc1d29deSKrzysztof Grobelny     if (exitUtilizationPercent != nullptr)
252137bbf98cSChris Cain     {
2522ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2523bc1d29deSKrzysztof Grobelny             *exitUtilizationPercent;
252437bbf98cSChris Cain     }
2525bc1d29deSKrzysztof Grobelny 
2526bc1d29deSKrzysztof Grobelny     if (exitDwellTime != nullptr)
252737bbf98cSChris Cain     {
2528bc1d29deSKrzysztof Grobelny         const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2529ac106bf6SEd Tanous         asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
253037bbf98cSChris Cain             std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
253137bbf98cSChris Cain                 .count();
253237bbf98cSChris Cain     }
253337bbf98cSChris Cain 
253437bbf98cSChris Cain     return true;
253537bbf98cSChris Cain }
253637bbf98cSChris Cain 
253737bbf98cSChris Cain /**
253837bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
253937bbf98cSChris Cain  *
2540ac106bf6SEd Tanous  * @param[in] asyncResp     Shared pointer for completing asynchronous calls.
254137bbf98cSChris Cain  *
254237bbf98cSChris Cain  * @return None.
254337bbf98cSChris Cain  */
2544ac106bf6SEd Tanous inline void
2545ac106bf6SEd Tanous     getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
254637bbf98cSChris Cain {
254762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get idle power saver parameters");
254837bbf98cSChris Cain 
254937bbf98cSChris Cain     // Get IdlePowerSaver object path:
2550e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2551e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2552e99073f5SGeorge Liu     dbus::utility::getSubTree(
2553e99073f5SGeorge Liu         "/", 0, interfaces,
2554ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
2555b9d36b47SEd Tanous                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
255637bbf98cSChris Cain         if (ec)
255737bbf98cSChris Cain         {
2558b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
255962598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
256062598e31SEd Tanous                 ec);
2561ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
256237bbf98cSChris Cain             return;
256337bbf98cSChris Cain         }
256437bbf98cSChris Cain         if (subtree.empty())
256537bbf98cSChris Cain         {
256637bbf98cSChris Cain             // This is an optional interface so just return
256737bbf98cSChris Cain             // if there is no instance found
256862598e31SEd Tanous             BMCWEB_LOG_DEBUG("No instances found");
256937bbf98cSChris Cain             return;
257037bbf98cSChris Cain         }
257137bbf98cSChris Cain         if (subtree.size() > 1)
257237bbf98cSChris Cain         {
257337bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
257437bbf98cSChris Cain             // is an error
257562598e31SEd Tanous             BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
257662598e31SEd Tanous                              "Power.IdlePowerSaver objects: {}",
257762598e31SEd Tanous                              subtree.size());
2578ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
257937bbf98cSChris Cain             return;
258037bbf98cSChris Cain         }
258137bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
258237bbf98cSChris Cain         {
258362598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2584ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
258537bbf98cSChris Cain             return;
258637bbf98cSChris Cain         }
258737bbf98cSChris Cain         const std::string& path = subtree[0].first;
258837bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
258937bbf98cSChris Cain         if (service.empty())
259037bbf98cSChris Cain         {
259162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2592ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
259337bbf98cSChris Cain             return;
259437bbf98cSChris Cain         }
259537bbf98cSChris Cain 
259637bbf98cSChris Cain         // Valid IdlePowerSaver object found, now read the current values
2597bc1d29deSKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
2598bc1d29deSKrzysztof Grobelny             *crow::connections::systemBus, service, path,
2599bc1d29deSKrzysztof Grobelny             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2600ac106bf6SEd Tanous             [asyncResp](const boost::system::error_code& ec2,
26011e5b7c88SJiaqing Zhao                         const dbus::utility::DBusPropertiesMap& properties) {
26028a592810SEd Tanous             if (ec2)
260337bbf98cSChris Cain             {
260462598e31SEd Tanous                 BMCWEB_LOG_ERROR(
260562598e31SEd Tanous                     "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
2606ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
260737bbf98cSChris Cain                 return;
260837bbf98cSChris Cain             }
260937bbf98cSChris Cain 
2610ac106bf6SEd Tanous             if (!parseIpsProperties(asyncResp, properties))
261137bbf98cSChris Cain             {
2612ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
261337bbf98cSChris Cain                 return;
261437bbf98cSChris Cain             }
2615bc1d29deSKrzysztof Grobelny         });
2616e99073f5SGeorge Liu     });
261737bbf98cSChris Cain 
261862598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
261937bbf98cSChris Cain }
262037bbf98cSChris Cain 
262137bbf98cSChris Cain /**
262237bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
262337bbf98cSChris Cain  *
2624ac106bf6SEd Tanous  * @param[in] asyncResp  Shared pointer for generating response message.
262537bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
262637bbf98cSChris Cain  *                       RF request.
262737bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
262837bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
262937bbf98cSChris Cain  * before entering idle state.
263037bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
263137bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
263237bbf98cSChris Cain  * before exiting idle state
263337bbf98cSChris Cain  *
263437bbf98cSChris Cain  * @return None.
263537bbf98cSChris Cain  */
2636ac106bf6SEd Tanous inline void
2637ac106bf6SEd Tanous     setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
263837bbf98cSChris Cain                       const std::optional<bool> ipsEnable,
263937bbf98cSChris Cain                       const std::optional<uint8_t> ipsEnterUtil,
264037bbf98cSChris Cain                       const std::optional<uint64_t> ipsEnterTime,
264137bbf98cSChris Cain                       const std::optional<uint8_t> ipsExitUtil,
264237bbf98cSChris Cain                       const std::optional<uint64_t> ipsExitTime)
264337bbf98cSChris Cain {
264462598e31SEd Tanous     BMCWEB_LOG_DEBUG("Set idle power saver properties");
264537bbf98cSChris Cain 
264637bbf98cSChris Cain     // Get IdlePowerSaver object path:
2647e99073f5SGeorge Liu     constexpr std::array<std::string_view, 1> interfaces = {
2648e99073f5SGeorge Liu         "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2649e99073f5SGeorge Liu     dbus::utility::getSubTree(
2650e99073f5SGeorge Liu         "/", 0, interfaces,
2651ac106bf6SEd Tanous         [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
2652e99073f5SGeorge Liu          ipsExitTime](const boost::system::error_code& ec,
2653b9d36b47SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
265437bbf98cSChris Cain         if (ec)
265537bbf98cSChris Cain         {
2656b3e86cb0SGunnar Mills             BMCWEB_LOG_ERROR(
265762598e31SEd Tanous                 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
265862598e31SEd Tanous                 ec);
2659ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
266037bbf98cSChris Cain             return;
266137bbf98cSChris Cain         }
266237bbf98cSChris Cain         if (subtree.empty())
266337bbf98cSChris Cain         {
266437bbf98cSChris Cain             // This is an optional D-Bus object, but user attempted to patch
2665ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
266637bbf98cSChris Cain                                        "IdlePowerSaver");
266737bbf98cSChris Cain             return;
266837bbf98cSChris Cain         }
266937bbf98cSChris Cain         if (subtree.size() > 1)
267037bbf98cSChris Cain         {
267137bbf98cSChris Cain             // More then one PowerIdlePowerSaver object is not supported and
267237bbf98cSChris Cain             // is an error
267362598e31SEd Tanous             BMCWEB_LOG_DEBUG(
267462598e31SEd Tanous                 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
267562598e31SEd Tanous                 subtree.size());
2676ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
267737bbf98cSChris Cain             return;
267837bbf98cSChris Cain         }
267937bbf98cSChris Cain         if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
268037bbf98cSChris Cain         {
268162598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2682ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
268337bbf98cSChris Cain             return;
268437bbf98cSChris Cain         }
268537bbf98cSChris Cain         const std::string& path = subtree[0].first;
268637bbf98cSChris Cain         const std::string& service = subtree[0].second.begin()->first;
268737bbf98cSChris Cain         if (service.empty())
268837bbf98cSChris Cain         {
268962598e31SEd Tanous             BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2690ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
269137bbf98cSChris Cain             return;
269237bbf98cSChris Cain         }
269337bbf98cSChris Cain 
269437bbf98cSChris Cain         // Valid Power IdlePowerSaver object found, now set any values that
269537bbf98cSChris Cain         // need to be updated
269637bbf98cSChris Cain 
269737bbf98cSChris Cain         if (ipsEnable)
269837bbf98cSChris Cain         {
269987c44966SAsmitha Karunanithi             setDbusProperty(asyncResp, service, path,
270087c44966SAsmitha Karunanithi                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
270187c44966SAsmitha Karunanithi                             "Enabled", "IdlePowerSaver/Enabled", *ipsEnable);
270237bbf98cSChris Cain         }
270337bbf98cSChris Cain         if (ipsEnterUtil)
270437bbf98cSChris Cain         {
270587c44966SAsmitha Karunanithi             setDbusProperty(asyncResp, service, path,
27069ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
270787c44966SAsmitha Karunanithi                             "EnterUtilizationPercent",
270887c44966SAsmitha Karunanithi                             "IdlePowerSaver/EnterUtilizationPercent",
270987c44966SAsmitha Karunanithi                             *ipsEnterUtil);
271037bbf98cSChris Cain         }
271137bbf98cSChris Cain         if (ipsEnterTime)
271237bbf98cSChris Cain         {
271337bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
271437bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
271587c44966SAsmitha Karunanithi             setDbusProperty(asyncResp, service, path,
27169ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
271787c44966SAsmitha Karunanithi                             "EnterDwellTime",
271887c44966SAsmitha Karunanithi                             "IdlePowerSaver/EnterDwellTimeSeconds",
271987c44966SAsmitha Karunanithi                             timeMilliseconds);
272037bbf98cSChris Cain         }
272137bbf98cSChris Cain         if (ipsExitUtil)
272237bbf98cSChris Cain         {
272387c44966SAsmitha Karunanithi             setDbusProperty(asyncResp, service, path,
27249ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
272587c44966SAsmitha Karunanithi                             "ExitUtilizationPercent",
272687c44966SAsmitha Karunanithi                             "IdlePowerSaver/ExitUtilizationPercent",
272787c44966SAsmitha Karunanithi                             *ipsExitUtil);
272837bbf98cSChris Cain         }
272937bbf98cSChris Cain         if (ipsExitTime)
273037bbf98cSChris Cain         {
273137bbf98cSChris Cain             // Convert from seconds into milliseconds for DBus
273237bbf98cSChris Cain             const uint64_t timeMilliseconds = *ipsExitTime * 1000;
273387c44966SAsmitha Karunanithi             setDbusProperty(asyncResp, service, path,
27349ae226faSGeorge Liu                             "xyz.openbmc_project.Control.Power.IdlePowerSaver",
273587c44966SAsmitha Karunanithi                             "ExitDwellTime",
273687c44966SAsmitha Karunanithi                             "IdlePowerSaver/ExitDwellTimeSeconds",
273787c44966SAsmitha Karunanithi                             timeMilliseconds);
273837bbf98cSChris Cain         }
2739e99073f5SGeorge Liu     });
274037bbf98cSChris Cain 
274162598e31SEd Tanous     BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
274237bbf98cSChris Cain }
274337bbf98cSChris Cain 
2744c1e219d5SEd Tanous inline void handleComputerSystemCollectionHead(
2745dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
2746dd60b9edSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2747dd60b9edSEd Tanous {
2748dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2749dd60b9edSEd Tanous     {
2750dd60b9edSEd Tanous         return;
2751dd60b9edSEd Tanous     }
2752dd60b9edSEd Tanous     asyncResp->res.addHeader(
2753dd60b9edSEd Tanous         boost::beast::http::field::link,
2754dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2755dd60b9edSEd Tanous }
2756dd60b9edSEd Tanous 
2757c1e219d5SEd Tanous inline void handleComputerSystemCollectionGet(
2758c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
2759c1e219d5SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
27601abe55efSEd Tanous {
27613ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2762f4c99e70SEd Tanous     {
2763f4c99e70SEd Tanous         return;
2764f4c99e70SEd Tanous     }
2765dd60b9edSEd Tanous 
2766dd60b9edSEd Tanous     asyncResp->res.addHeader(
2767dd60b9edSEd Tanous         boost::beast::http::field::link,
2768dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
27698d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
27700f74e643SEd Tanous         "#ComputerSystemCollection.ComputerSystemCollection";
27718d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
27728d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2773462023adSSunitha Harish 
27747f3e84a1SEd Tanous     nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
27757f3e84a1SEd Tanous     ifaceArray = nlohmann::json::array();
277625b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
27777f3e84a1SEd Tanous     {
27787f3e84a1SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = 0;
27797f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
27807f3e84a1SEd Tanous         return;
27817f3e84a1SEd Tanous     }
27827f3e84a1SEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] = 1;
27837f3e84a1SEd Tanous     nlohmann::json::object_t system;
2784*253f11b8SEd Tanous     system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2785*253f11b8SEd Tanous                                               BMCWEB_REDFISH_SYSTEM_URI_NAME);
27867f3e84a1SEd Tanous     ifaceArray.emplace_back(std::move(system));
27871e1e598dSJonathan Doman     sdbusplus::asio::getProperty<std::string>(
2788002d39b4SEd Tanous         *crow::connections::systemBus, "xyz.openbmc_project.Settings",
27891e1e598dSJonathan Doman         "/xyz/openbmc_project/network/hypervisor",
2790002d39b4SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
27915e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec2,
27921e1e598dSJonathan Doman                     const std::string& /*hostName*/) {
27937f3e84a1SEd Tanous         if (ec2)
2794462023adSSunitha Harish         {
27957f3e84a1SEd Tanous             return;
27967f3e84a1SEd Tanous         }
27977f3e84a1SEd Tanous         auto val = asyncResp->res.jsonValue.find("Members@odata.count");
27987f3e84a1SEd Tanous         if (val == asyncResp->res.jsonValue.end())
27997f3e84a1SEd Tanous         {
280062598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
28017f3e84a1SEd Tanous             return;
28027f3e84a1SEd Tanous         }
28037f3e84a1SEd Tanous         uint64_t* count = val->get_ptr<uint64_t*>();
28047f3e84a1SEd Tanous         if (count == nullptr)
28057f3e84a1SEd Tanous         {
280662598e31SEd Tanous             BMCWEB_LOG_CRITICAL("Count wasn't found??");
28077f3e84a1SEd Tanous             return;
28087f3e84a1SEd Tanous         }
28097f3e84a1SEd Tanous         *count = *count + 1;
281062598e31SEd Tanous         BMCWEB_LOG_DEBUG("Hypervisor is available");
28117f3e84a1SEd Tanous         nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
28121476687dSEd Tanous         nlohmann::json::object_t hypervisor;
2813002d39b4SEd Tanous         hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
28147f3e84a1SEd Tanous         ifaceArray2.emplace_back(std::move(hypervisor));
28151e1e598dSJonathan Doman     });
2816c1e219d5SEd Tanous }
2817c1e219d5SEd Tanous 
2818c1e219d5SEd Tanous /**
28197e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28207e860f15SJohn Edward Broadbent  */
28214f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28227e860f15SJohn Edward Broadbent {
282389492a15SPatrick Williams     constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
282489492a15SPatrick Williams     constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
282589492a15SPatrick Williams     constexpr const char* interfaceName =
28267e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
282789492a15SPatrick Williams     constexpr const char* method = "NMI";
28287e860f15SJohn Edward Broadbent 
28297e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28305e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
28317e860f15SJohn Edward Broadbent         if (ec)
28327e860f15SJohn Edward Broadbent         {
283362598e31SEd Tanous             BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
28347e860f15SJohn Edward Broadbent             messages::internalError(asyncResp->res);
28357e860f15SJohn Edward Broadbent             return;
28367e860f15SJohn Edward Broadbent         }
28377e860f15SJohn Edward Broadbent         messages::success(asyncResp->res);
28387e860f15SJohn Edward Broadbent     },
28397e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28407e860f15SJohn Edward Broadbent }
2841c5b2abe0SLewanczyk, Dawid 
2842c1e219d5SEd Tanous inline void handleComputerSystemResetActionPost(
2843c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
28447f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2845c1e219d5SEd Tanous     const std::string& systemName)
2846c1e219d5SEd Tanous {
28473ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
284845ca1b86SEd Tanous     {
284945ca1b86SEd Tanous         return;
285045ca1b86SEd Tanous     }
2851*253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2852c1e219d5SEd Tanous     {
2853c1e219d5SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2854c1e219d5SEd Tanous                                    systemName);
2855c1e219d5SEd Tanous         return;
2856c1e219d5SEd Tanous     }
285725b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
28587f3e84a1SEd Tanous     {
28597f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
28607f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2861c1e219d5SEd Tanous                                    systemName);
28627f3e84a1SEd Tanous         return;
28637f3e84a1SEd Tanous     }
28649712f8acSEd Tanous     std::string resetType;
2865c1e219d5SEd Tanous     if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2866cc340dd9SEd Tanous     {
2867cc340dd9SEd Tanous         return;
2868cc340dd9SEd Tanous     }
2869cc340dd9SEd Tanous 
2870d22c8396SJason M. Bills     // Get the command and host vs. chassis
2871cc340dd9SEd Tanous     std::string command;
2872543f4400SEd Tanous     bool hostCommand = true;
2873d4d25793SEd Tanous     if ((resetType == "On") || (resetType == "ForceOn"))
2874cc340dd9SEd Tanous     {
2875cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.On";
2876d22c8396SJason M. Bills         hostCommand = true;
2877d22c8396SJason M. Bills     }
2878d22c8396SJason M. Bills     else if (resetType == "ForceOff")
2879d22c8396SJason M. Bills     {
2880d22c8396SJason M. Bills         command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2881d22c8396SJason M. Bills         hostCommand = false;
2882d22c8396SJason M. Bills     }
2883d22c8396SJason M. Bills     else if (resetType == "ForceRestart")
2884d22c8396SJason M. Bills     {
2885c1e219d5SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
288686a0851aSJason M. Bills         hostCommand = true;
2887cc340dd9SEd Tanous     }
28889712f8acSEd Tanous     else if (resetType == "GracefulShutdown")
2889cc340dd9SEd Tanous     {
2890cc340dd9SEd Tanous         command = "xyz.openbmc_project.State.Host.Transition.Off";
2891d22c8396SJason M. Bills         hostCommand = true;
2892cc340dd9SEd Tanous     }
28939712f8acSEd Tanous     else if (resetType == "GracefulRestart")
2894cc340dd9SEd Tanous     {
28950fda0f12SGeorge Liu         command =
28960fda0f12SGeorge Liu             "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2897d22c8396SJason M. Bills         hostCommand = true;
2898d22c8396SJason M. Bills     }
2899d22c8396SJason M. Bills     else if (resetType == "PowerCycle")
2900d22c8396SJason M. Bills     {
290186a0851aSJason M. Bills         command = "xyz.openbmc_project.State.Host.Transition.Reboot";
290286a0851aSJason M. Bills         hostCommand = true;
2903cc340dd9SEd Tanous     }
2904bfd5b826SLakshminarayana R. Kammath     else if (resetType == "Nmi")
2905bfd5b826SLakshminarayana R. Kammath     {
2906bfd5b826SLakshminarayana R. Kammath         doNMI(asyncResp);
2907bfd5b826SLakshminarayana R. Kammath         return;
2908bfd5b826SLakshminarayana R. Kammath     }
2909cc340dd9SEd Tanous     else
2910cc340dd9SEd Tanous     {
2911c1e219d5SEd Tanous         messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2912cc340dd9SEd Tanous         return;
2913cc340dd9SEd Tanous     }
2914d02aad39SEd Tanous     sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
2915cc340dd9SEd Tanous 
2916d22c8396SJason M. Bills     if (hostCommand)
2917d22c8396SJason M. Bills     {
2918d02aad39SEd Tanous         setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host",
2919d02aad39SEd Tanous                         statePath / "host0", "xyz.openbmc_project.State.Host",
2920d02aad39SEd Tanous                         "RequestedHostTransition", "Reset", command);
2921cc340dd9SEd Tanous     }
2922d22c8396SJason M. Bills     else
2923d22c8396SJason M. Bills     {
2924d02aad39SEd Tanous         setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis",
2925d02aad39SEd Tanous                         statePath / "chassis0",
2926d02aad39SEd Tanous                         "xyz.openbmc_project.State.Chassis",
2927d02aad39SEd Tanous                         "RequestedPowerTransition", "Reset", command);
2928d22c8396SJason M. Bills     }
2929d22c8396SJason M. Bills }
2930cc340dd9SEd Tanous 
2931c1e219d5SEd Tanous inline void handleComputerSystemHead(
2932dd60b9edSEd Tanous     App& app, const crow::Request& req,
29337f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29347f3e84a1SEd Tanous     const std::string& /*systemName*/)
2935dd60b9edSEd Tanous {
2936dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2937dd60b9edSEd Tanous     {
2938dd60b9edSEd Tanous         return;
2939dd60b9edSEd Tanous     }
2940dd60b9edSEd Tanous 
2941dd60b9edSEd Tanous     asyncResp->res.addHeader(
2942dd60b9edSEd Tanous         boost::beast::http::field::link,
2943dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2944dd60b9edSEd Tanous }
2945dd60b9edSEd Tanous 
29465c3e9272SAbhishek Patel inline void afterPortRequest(
29475c3e9272SAbhishek Patel     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29485c3e9272SAbhishek Patel     const boost::system::error_code& ec,
29495c3e9272SAbhishek Patel     const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
29505c3e9272SAbhishek Patel {
29515c3e9272SAbhishek Patel     if (ec)
29525c3e9272SAbhishek Patel     {
2953b3e86cb0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
29545c3e9272SAbhishek Patel         messages::internalError(asyncResp->res);
29555c3e9272SAbhishek Patel         return;
29565c3e9272SAbhishek Patel     }
29575c3e9272SAbhishek Patel     for (const auto& data : socketData)
29585c3e9272SAbhishek Patel     {
29595c3e9272SAbhishek Patel         const std::string& socketPath = get<0>(data);
29605c3e9272SAbhishek Patel         const std::string& protocolName = get<1>(data);
29615c3e9272SAbhishek Patel         bool isProtocolEnabled = get<2>(data);
29625c3e9272SAbhishek Patel         nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
29635c3e9272SAbhishek Patel         dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
29645c3e9272SAbhishek Patel         // need to retrieve port number for
29655c3e9272SAbhishek Patel         // obmc-console-ssh service
29665c3e9272SAbhishek Patel         if (protocolName == "SSH")
29675c3e9272SAbhishek Patel         {
29685c3e9272SAbhishek Patel             getPortNumber(socketPath, [asyncResp, protocolName](
296981c4e330SEd Tanous                                           const boost::system::error_code& ec1,
29705c3e9272SAbhishek Patel                                           int portNumber) {
29715c3e9272SAbhishek Patel                 if (ec1)
29725c3e9272SAbhishek Patel                 {
2973b3e86cb0SGunnar Mills                     BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
29745c3e9272SAbhishek Patel                     messages::internalError(asyncResp->res);
29755c3e9272SAbhishek Patel                     return;
29765c3e9272SAbhishek Patel                 }
29775c3e9272SAbhishek Patel                 nlohmann::json& dataJson1 =
29785c3e9272SAbhishek Patel                     asyncResp->res.jsonValue["SerialConsole"];
29795c3e9272SAbhishek Patel                 dataJson1[protocolName]["Port"] = portNumber;
29805c3e9272SAbhishek Patel             });
29815c3e9272SAbhishek Patel         }
29825c3e9272SAbhishek Patel     }
29835c3e9272SAbhishek Patel }
2984c1e219d5SEd Tanous 
2985c1e219d5SEd Tanous inline void
2986c1e219d5SEd Tanous     handleComputerSystemGet(crow::App& app, const crow::Request& req,
298722d268cbSEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2988c1e219d5SEd Tanous                             const std::string& systemName)
2989c1e219d5SEd Tanous {
29903ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
299145ca1b86SEd Tanous     {
299245ca1b86SEd Tanous         return;
299345ca1b86SEd Tanous     }
2994746b56f3SAsmitha Karunanithi 
299525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
29967f3e84a1SEd Tanous     {
29977f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
29987f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
29997f3e84a1SEd Tanous                                    systemName);
30007f3e84a1SEd Tanous         return;
30017f3e84a1SEd Tanous     }
30027f3e84a1SEd Tanous 
3003746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3004746b56f3SAsmitha Karunanithi     {
3005746b56f3SAsmitha Karunanithi         handleHypervisorSystemGet(asyncResp);
3006746b56f3SAsmitha Karunanithi         return;
3007746b56f3SAsmitha Karunanithi     }
3008746b56f3SAsmitha Karunanithi 
3009*253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
301022d268cbSEd Tanous     {
301122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
301222d268cbSEd Tanous                                    systemName);
301322d268cbSEd Tanous         return;
301422d268cbSEd Tanous     }
3015dd60b9edSEd Tanous     asyncResp->res.addHeader(
3016dd60b9edSEd Tanous         boost::beast::http::field::link,
3017dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
30188d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3019b6655101SChris Cain         "#ComputerSystem.v1_22_0.ComputerSystem";
3020*253f11b8SEd Tanous     asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3021*253f11b8SEd Tanous     asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
30228d1b46d7Szhanghch05     asyncResp->res.jsonValue["SystemType"] = "Physical";
30238d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Computer System";
30248d1b46d7Szhanghch05     asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3025cf0e004cSNinad Palsule     asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3026dfb2b408SPriyanga Ramasamy         double(0);
3027*253f11b8SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3028*253f11b8SEd Tanous         "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
302904a258f4SEd Tanous 
3030*253f11b8SEd Tanous     asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3031*253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3032*253f11b8SEd Tanous     asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3033*253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3034*253f11b8SEd Tanous     asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3035*253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
30363179105bSSunny Srivastava     asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3037*253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3038*253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3039029573d4SEd Tanous 
3040002d39b4SEd Tanous     asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3041*253f11b8SEd Tanous         boost::urls::format(
3042*253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3043*253f11b8SEd Tanous             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3044c1e219d5SEd Tanous     asyncResp->res
3045c1e219d5SEd Tanous         .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3046*253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3047*253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3048c5b2abe0SLewanczyk, Dawid 
3049*253f11b8SEd Tanous     asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3050*253f11b8SEd Tanous         "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3051*253f11b8SEd Tanous     asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3052*253f11b8SEd Tanous         "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3053c4bf6374SJason M. Bills 
30541476687dSEd Tanous     nlohmann::json::array_t managedBy;
30551476687dSEd Tanous     nlohmann::json& manager = managedBy.emplace_back();
3056*253f11b8SEd Tanous     manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3057*253f11b8SEd Tanous                                                BMCWEB_REDFISH_MANAGER_URI_NAME);
3058002d39b4SEd Tanous     asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
30591476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
30601476687dSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
30610e8ac5e7SGunnar Mills 
30620e8ac5e7SGunnar Mills     // Fill in SerialConsole info
3063002d39b4SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3064c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
30651476687dSEd Tanous 
3066c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
30671476687dSEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3068c1e219d5SEd Tanous     asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
30691476687dSEd Tanous         "Press ~. to exit console";
30705c3e9272SAbhishek Patel     getPortStatusAndPath(std::span{protocolToDBusForSystems},
30715c3e9272SAbhishek Patel                          std::bind_front(afterPortRequest, asyncResp));
30720e8ac5e7SGunnar Mills 
307325b54dbaSEd Tanous     if constexpr (BMCWEB_KVM)
307425b54dbaSEd Tanous     {
30750e8ac5e7SGunnar Mills         // Fill in GraphicalConsole info
3076002d39b4SEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
307725b54dbaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
307825b54dbaSEd Tanous             4;
3079613dabeaSEd Tanous         asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3080613dabeaSEd Tanous             nlohmann::json::array_t({"KVMIP"});
308125b54dbaSEd Tanous     }
308213451e39SWilly Tu 
3083002d39b4SEd Tanous     getMainChassisId(asyncResp,
3084002d39b4SEd Tanous                      [](const std::string& chassisId,
30858d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3086b2c7e208SEd Tanous         nlohmann::json::array_t chassisArray;
3087b2c7e208SEd Tanous         nlohmann::json& chassis = chassisArray.emplace_back();
3088ef4c65b7SEd Tanous         chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3089ef4c65b7SEd Tanous                                                    chassisId);
3090002d39b4SEd Tanous         aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3091c5d03ff4SJennifer Lee     });
3092a3002228SAppaRao Puli 
309359a17e4fSGeorge Liu     getSystemLocationIndicatorActive(asyncResp);
30949f8bfa7cSGunnar Mills     // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3095a3002228SAppaRao Puli     getIndicatorLedState(asyncResp);
309651bd2d8aSGunnar Mills     getComputerSystem(asyncResp);
30976c34de48SEd Tanous     getHostState(asyncResp);
3098491d8ee7SSantosh Puranik     getBootProperties(asyncResp);
3099978b8803SAndrew Geissler     getBootProgress(asyncResp);
3100b6d5d45cSHieu Huynh     getBootProgressLastStateTime(asyncResp);
310170c4d545SLakshmi Yadlapati     pcie_util::getPCIeDeviceList(asyncResp,
310270c4d545SLakshmi Yadlapati                                  nlohmann::json::json_pointer("/PCIeDevices"));
310351709ffdSYong Li     getHostWatchdogTimer(asyncResp);
3104c6a620f2SGeorge Liu     getPowerRestorePolicy(asyncResp);
31059dcfe8c1SAlbert Zhang     getStopBootOnFault(asyncResp);
3106797d5daeSCorey Hardesty     getAutomaticRetryPolicy(asyncResp);
3107c0557e1aSGunnar Mills     getLastResetTime(asyncResp);
310825b54dbaSEd Tanous     if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
310925b54dbaSEd Tanous     {
3110a6349918SAppaRao Puli         getProvisioningStatus(asyncResp);
311125b54dbaSEd Tanous     }
31121981771bSAli Ahmed     getTrustedModuleRequiredToBoot(asyncResp);
31133a2d0424SChris Cain     getPowerMode(asyncResp);
311437bbf98cSChris Cain     getIdlePowerSaver(asyncResp);
3115c1e219d5SEd Tanous }
3116550a6bf8SJiaqing Zhao 
3117c1e219d5SEd Tanous inline void handleComputerSystemPatch(
3118c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
311922d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3120c1e219d5SEd Tanous     const std::string& systemName)
3121c1e219d5SEd Tanous {
31223ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
312345ca1b86SEd Tanous     {
312445ca1b86SEd Tanous         return;
312545ca1b86SEd Tanous     }
312625b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
31277f3e84a1SEd Tanous     {
31287f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
31297f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
31307f3e84a1SEd Tanous                                    systemName);
31317f3e84a1SEd Tanous         return;
31327f3e84a1SEd Tanous     }
3133*253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
313422d268cbSEd Tanous     {
313522d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
313622d268cbSEd Tanous                                    systemName);
313722d268cbSEd Tanous         return;
313822d268cbSEd Tanous     }
313922d268cbSEd Tanous 
3140dd60b9edSEd Tanous     asyncResp->res.addHeader(
3141dd60b9edSEd Tanous         boost::beast::http::field::link,
3142dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3143dd60b9edSEd Tanous 
31449f8bfa7cSGunnar Mills     std::optional<bool> locationIndicatorActive;
3145cde19e5fSSantosh Puranik     std::optional<std::string> indicatorLed;
314698e386ecSGunnar Mills     std::optional<std::string> assetTag;
3147c6a620f2SGeorge Liu     std::optional<std::string> powerRestorePolicy;
31483a2d0424SChris Cain     std::optional<std::string> powerMode;
3149550a6bf8SJiaqing Zhao     std::optional<bool> wdtEnable;
3150550a6bf8SJiaqing Zhao     std::optional<std::string> wdtTimeOutAction;
3151550a6bf8SJiaqing Zhao     std::optional<std::string> bootSource;
3152550a6bf8SJiaqing Zhao     std::optional<std::string> bootType;
3153550a6bf8SJiaqing Zhao     std::optional<std::string> bootEnable;
3154550a6bf8SJiaqing Zhao     std::optional<std::string> bootAutomaticRetry;
3155797d5daeSCorey Hardesty     std::optional<uint32_t> bootAutomaticRetryAttempts;
3156550a6bf8SJiaqing Zhao     std::optional<bool> bootTrustedModuleRequired;
31579dcfe8c1SAlbert Zhang     std::optional<std::string> stopBootOnFault;
3158550a6bf8SJiaqing Zhao     std::optional<bool> ipsEnable;
3159550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsEnterUtil;
3160550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsEnterTime;
3161550a6bf8SJiaqing Zhao     std::optional<uint8_t> ipsExitUtil;
3162550a6bf8SJiaqing Zhao     std::optional<uint64_t> ipsExitTime;
3163550a6bf8SJiaqing Zhao 
3164550a6bf8SJiaqing Zhao     // clang-format off
316515ed6780SWilly Tu                 if (!json_util::readJsonPatch(
3166550a6bf8SJiaqing Zhao                         req, asyncResp->res,
3167550a6bf8SJiaqing Zhao                         "IndicatorLED", indicatorLed,
31687e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
3169550a6bf8SJiaqing Zhao                         "AssetTag", assetTag,
3170550a6bf8SJiaqing Zhao                         "PowerRestorePolicy", powerRestorePolicy,
3171550a6bf8SJiaqing Zhao                         "PowerMode", powerMode,
3172550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3173550a6bf8SJiaqing Zhao                         "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3174550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideTarget", bootSource,
3175550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideMode", bootType,
3176550a6bf8SJiaqing Zhao                         "Boot/BootSourceOverrideEnabled", bootEnable,
3177550a6bf8SJiaqing Zhao                         "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3178797d5daeSCorey Hardesty                         "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3179550a6bf8SJiaqing Zhao                         "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
31809dcfe8c1SAlbert Zhang                         "Boot/StopBootOnFault", stopBootOnFault,
3181550a6bf8SJiaqing Zhao                         "IdlePowerSaver/Enabled", ipsEnable,
3182550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3183550a6bf8SJiaqing Zhao                         "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3184550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3185550a6bf8SJiaqing Zhao                         "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
31866617338dSEd Tanous                 {
31876617338dSEd Tanous                     return;
31886617338dSEd Tanous                 }
3189550a6bf8SJiaqing Zhao     // clang-format on
3190491d8ee7SSantosh Puranik 
31918d1b46d7Szhanghch05     asyncResp->res.result(boost::beast::http::status::no_content);
3192c45f0082SYong Li 
319398e386ecSGunnar Mills     if (assetTag)
319498e386ecSGunnar Mills     {
319598e386ecSGunnar Mills         setAssetTag(asyncResp, *assetTag);
319698e386ecSGunnar Mills     }
319798e386ecSGunnar Mills 
3198550a6bf8SJiaqing Zhao     if (wdtEnable || wdtTimeOutAction)
3199c45f0082SYong Li     {
3200f23b7296SEd Tanous         setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3201c45f0082SYong Li     }
3202c45f0082SYong Li 
3203cd9a4666SKonstantin Aladyshev     if (bootSource || bootType || bootEnable)
320469f35306SGunnar Mills     {
3205002d39b4SEd Tanous         setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3206491d8ee7SSantosh Puranik     }
3207550a6bf8SJiaqing Zhao     if (bootAutomaticRetry)
320869f35306SGunnar Mills     {
3209550a6bf8SJiaqing Zhao         setAutomaticRetry(asyncResp, *bootAutomaticRetry);
321069f35306SGunnar Mills     }
3211ac7e1e0bSAli Ahmed 
3212797d5daeSCorey Hardesty     if (bootAutomaticRetryAttempts)
3213797d5daeSCorey Hardesty     {
3214797d5daeSCorey Hardesty         setAutomaticRetryAttempts(asyncResp,
3215797d5daeSCorey Hardesty                                   bootAutomaticRetryAttempts.value());
3216797d5daeSCorey Hardesty     }
3217797d5daeSCorey Hardesty 
3218550a6bf8SJiaqing Zhao     if (bootTrustedModuleRequired)
3219ac7e1e0bSAli Ahmed     {
3220c1e219d5SEd Tanous         setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
322169f35306SGunnar Mills     }
3222265c1602SJohnathan Mantey 
32239dcfe8c1SAlbert Zhang     if (stopBootOnFault)
32249dcfe8c1SAlbert Zhang     {
32259dcfe8c1SAlbert Zhang         setStopBootOnFault(asyncResp, *stopBootOnFault);
32269dcfe8c1SAlbert Zhang     }
32279dcfe8c1SAlbert Zhang 
32289f8bfa7cSGunnar Mills     if (locationIndicatorActive)
32299f8bfa7cSGunnar Mills     {
323059a17e4fSGeorge Liu         setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
32319f8bfa7cSGunnar Mills     }
32329f8bfa7cSGunnar Mills 
32337e860f15SJohn Edward Broadbent     // TODO (Gunnar): Remove IndicatorLED after enough time has
32347e860f15SJohn Edward Broadbent     // passed
32359712f8acSEd Tanous     if (indicatorLed)
32366617338dSEd Tanous     {
3237f23b7296SEd Tanous         setIndicatorLedState(asyncResp, *indicatorLed);
3238002d39b4SEd Tanous         asyncResp->res.addHeader(boost::beast::http::field::warning,
3239d6aa0093SGunnar Mills                                  "299 - \"IndicatorLED is deprecated. Use "
3240d6aa0093SGunnar Mills                                  "LocationIndicatorActive instead.\"");
32416617338dSEd Tanous     }
3242c6a620f2SGeorge Liu 
3243c6a620f2SGeorge Liu     if (powerRestorePolicy)
3244c6a620f2SGeorge Liu     {
32454e69c904SGunnar Mills         setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3246c6a620f2SGeorge Liu     }
32473a2d0424SChris Cain 
32483a2d0424SChris Cain     if (powerMode)
32493a2d0424SChris Cain     {
32503a2d0424SChris Cain         setPowerMode(asyncResp, *powerMode);
32513a2d0424SChris Cain     }
325237bbf98cSChris Cain 
3253c1e219d5SEd Tanous     if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
325437bbf98cSChris Cain     {
3255002d39b4SEd Tanous         setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3256002d39b4SEd Tanous                           ipsExitUtil, ipsExitTime);
325737bbf98cSChris Cain     }
3258c1e219d5SEd Tanous }
32591cb1a9e6SAppaRao Puli 
326038c8a6f2SEd Tanous inline void handleSystemCollectionResetActionHead(
3261dd60b9edSEd Tanous     crow::App& app, const crow::Request& req,
32627f3e84a1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3263c1e219d5SEd Tanous     const std::string& /*systemName*/)
3264dd60b9edSEd Tanous {
3265dd60b9edSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3266dd60b9edSEd Tanous     {
3267dd60b9edSEd Tanous         return;
3268dd60b9edSEd Tanous     }
3269dd60b9edSEd Tanous     asyncResp->res.addHeader(
3270dd60b9edSEd Tanous         boost::beast::http::field::link,
3271dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3272dd60b9edSEd Tanous }
327333e1f122SAndrew Geissler 
327433e1f122SAndrew Geissler /**
327533e1f122SAndrew Geissler  * @brief Translates allowed host transitions to redfish string
327633e1f122SAndrew Geissler  *
327733e1f122SAndrew Geissler  * @param[in]  dbusAllowedHostTran The allowed host transition on dbus
327833e1f122SAndrew Geissler  * @param[out] allowableValues     The translated host transition(s)
327933e1f122SAndrew Geissler  *
328033e1f122SAndrew Geissler  * @return Emplaces correpsonding Redfish translated value(s) in
328133e1f122SAndrew Geissler  * allowableValues. If translation not possible, does nothing to
328233e1f122SAndrew Geissler  * allowableValues.
328333e1f122SAndrew Geissler  */
328433e1f122SAndrew Geissler inline void
328533e1f122SAndrew Geissler     dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
328633e1f122SAndrew Geissler                                    nlohmann::json::array_t& allowableValues)
328733e1f122SAndrew Geissler {
328833e1f122SAndrew Geissler     if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
328933e1f122SAndrew Geissler     {
329033e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::On);
329133e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceOn);
329233e1f122SAndrew Geissler     }
329333e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
329433e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.Off")
329533e1f122SAndrew Geissler     {
329633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
329733e1f122SAndrew Geissler     }
329833e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
329933e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
330033e1f122SAndrew Geissler     {
330133e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::GracefulRestart);
330233e1f122SAndrew Geissler     }
330333e1f122SAndrew Geissler     else if (dbusAllowedHostTran ==
330433e1f122SAndrew Geissler              "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
330533e1f122SAndrew Geissler     {
330633e1f122SAndrew Geissler         allowableValues.emplace_back(resource::ResetType::ForceRestart);
330733e1f122SAndrew Geissler     }
330833e1f122SAndrew Geissler     else
330933e1f122SAndrew Geissler     {
331033e1f122SAndrew Geissler         BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
331133e1f122SAndrew Geissler     }
331233e1f122SAndrew Geissler }
331333e1f122SAndrew Geissler 
331433e1f122SAndrew Geissler inline void afterGetAllowedHostTransitions(
331533e1f122SAndrew Geissler     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331633e1f122SAndrew Geissler     const boost::system::error_code& ec,
331733e1f122SAndrew Geissler     const std::vector<std::string>& allowedHostTransitions)
331833e1f122SAndrew Geissler {
331933e1f122SAndrew Geissler     nlohmann::json::array_t allowableValues;
332033e1f122SAndrew Geissler 
332133e1f122SAndrew Geissler     // Supported on all systems currently
332233e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::ForceOff);
332333e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::PowerCycle);
332433e1f122SAndrew Geissler     allowableValues.emplace_back(resource::ResetType::Nmi);
332533e1f122SAndrew Geissler 
332633e1f122SAndrew Geissler     if (ec)
332733e1f122SAndrew Geissler     {
3328e715d14bSEd Tanous         if ((ec.value() ==
3329e715d14bSEd Tanous              boost::system::linux_error::bad_request_descriptor) ||
3330e715d14bSEd Tanous             (ec.value() == boost::asio::error::basic_errors::host_unreachable))
333133e1f122SAndrew Geissler         {
333233e1f122SAndrew Geissler             // Property not implemented so just return defaults
333333e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Property not available {}", ec);
333433e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::On);
333533e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceOn);
333633e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::ForceRestart);
333733e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulRestart);
333833e1f122SAndrew Geissler             allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
333933e1f122SAndrew Geissler         }
334033e1f122SAndrew Geissler         else
334133e1f122SAndrew Geissler         {
334233e1f122SAndrew Geissler             BMCWEB_LOG_ERROR("DBUS response error {}", ec);
334333e1f122SAndrew Geissler             messages::internalError(asyncResp->res);
334433e1f122SAndrew Geissler             return;
334533e1f122SAndrew Geissler         }
334633e1f122SAndrew Geissler     }
334733e1f122SAndrew Geissler     else
334833e1f122SAndrew Geissler     {
334933e1f122SAndrew Geissler         for (const std::string& transition : allowedHostTransitions)
335033e1f122SAndrew Geissler         {
335133e1f122SAndrew Geissler             BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
335233e1f122SAndrew Geissler             dbusToRfAllowedHostTransitions(transition, allowableValues);
335333e1f122SAndrew Geissler         }
335433e1f122SAndrew Geissler     }
335533e1f122SAndrew Geissler 
335633e1f122SAndrew Geissler     nlohmann::json::object_t parameter;
335733e1f122SAndrew Geissler     parameter["Name"] = "ResetType";
335833e1f122SAndrew Geissler     parameter["Required"] = true;
335933e1f122SAndrew Geissler     parameter["DataType"] = "String";
336033e1f122SAndrew Geissler     parameter["AllowableValues"] = std::move(allowableValues);
336133e1f122SAndrew Geissler     nlohmann::json::array_t parameters;
336233e1f122SAndrew Geissler     parameters.emplace_back(std::move(parameter));
336333e1f122SAndrew Geissler     asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
336433e1f122SAndrew Geissler }
336533e1f122SAndrew Geissler 
3366c1e219d5SEd Tanous inline void handleSystemCollectionResetActionGet(
3367c1e219d5SEd Tanous     crow::App& app, const crow::Request& req,
336822d268cbSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3369c1e219d5SEd Tanous     const std::string& systemName)
3370c1e219d5SEd Tanous {
33713ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
337245ca1b86SEd Tanous     {
337345ca1b86SEd Tanous         return;
337445ca1b86SEd Tanous     }
337525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
33767f3e84a1SEd Tanous     {
33777f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
33787f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
33797f3e84a1SEd Tanous                                    systemName);
33807f3e84a1SEd Tanous         return;
33817f3e84a1SEd Tanous     }
3382746b56f3SAsmitha Karunanithi 
3383746b56f3SAsmitha Karunanithi     if (systemName == "hypervisor")
3384746b56f3SAsmitha Karunanithi     {
3385746b56f3SAsmitha Karunanithi         handleHypervisorResetActionGet(asyncResp);
3386746b56f3SAsmitha Karunanithi         return;
3387746b56f3SAsmitha Karunanithi     }
3388746b56f3SAsmitha Karunanithi 
3389*253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
339022d268cbSEd Tanous     {
339122d268cbSEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
339222d268cbSEd Tanous                                    systemName);
339322d268cbSEd Tanous         return;
339422d268cbSEd Tanous     }
339522d268cbSEd Tanous 
3396dd60b9edSEd Tanous     asyncResp->res.addHeader(
3397dd60b9edSEd Tanous         boost::beast::http::field::link,
3398dd60b9edSEd Tanous         "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
33991476687dSEd Tanous 
34001476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
3401*253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3402*253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME);
3403c1e219d5SEd Tanous     asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
34041476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "Reset Action Info";
34051476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
34063215e700SNan Zhou 
340733e1f122SAndrew Geissler     // Look to see if system defines AllowedHostTransitions
340833e1f122SAndrew Geissler     sdbusplus::asio::getProperty<std::vector<std::string>>(
340933e1f122SAndrew Geissler         *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
341033e1f122SAndrew Geissler         "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
341133e1f122SAndrew Geissler         "AllowedHostTransitions",
341233e1f122SAndrew Geissler         [asyncResp](const boost::system::error_code& ec,
341333e1f122SAndrew Geissler                     const std::vector<std::string>& allowedHostTransitions) {
341433e1f122SAndrew Geissler         afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
341533e1f122SAndrew Geissler     });
3416c1e219d5SEd Tanous }
3417c1e219d5SEd Tanous /**
3418c1e219d5SEd Tanous  * SystemResetActionInfo derived class for delivering Computer Systems
3419c1e219d5SEd Tanous  * ResetType AllowableValues using ResetInfo schema.
3420c1e219d5SEd Tanous  */
3421100afe56SEd Tanous inline void requestRoutesSystems(App& app)
3422c1e219d5SEd Tanous {
3423100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3424100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystemCollection)
3425100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3426100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3427100afe56SEd Tanous 
3428100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3429100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
3430100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3431100afe56SEd Tanous             std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3432100afe56SEd Tanous 
3433100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3434100afe56SEd Tanous         .privileges(redfish::privileges::headComputerSystem)
3435100afe56SEd Tanous         .methods(boost::beast::http::verb::head)(
3436100afe56SEd Tanous             std::bind_front(handleComputerSystemHead, std::ref(app)));
3437100afe56SEd Tanous 
3438100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3439100afe56SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
3440100afe56SEd Tanous         .methods(boost::beast::http::verb::get)(
3441100afe56SEd Tanous             std::bind_front(handleComputerSystemGet, std::ref(app)));
3442100afe56SEd Tanous 
3443100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3444100afe56SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
3445100afe56SEd Tanous         .methods(boost::beast::http::verb::patch)(
3446100afe56SEd Tanous             std::bind_front(handleComputerSystemPatch, std::ref(app)));
3447100afe56SEd Tanous 
3448100afe56SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3449100afe56SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
3450100afe56SEd Tanous         .methods(boost::beast::http::verb::post)(std::bind_front(
3451100afe56SEd Tanous             handleComputerSystemResetActionPost, std::ref(app)));
3452100afe56SEd Tanous 
3453c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3454c1e219d5SEd Tanous         .privileges(redfish::privileges::headActionInfo)
3455c1e219d5SEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
3456c1e219d5SEd Tanous             handleSystemCollectionResetActionHead, std::ref(app)));
3457c1e219d5SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
3458c1e219d5SEd Tanous         .privileges(redfish::privileges::getActionInfo)
3459c1e219d5SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
3460c1e219d5SEd Tanous             handleSystemCollectionResetActionGet, std::ref(app)));
34611cb1a9e6SAppaRao Puli }
3462c5b2abe0SLewanczyk, Dawid } // namespace redfish
3463