xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 168e20c1306e3e689907ba43e14ea679e2328611)
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 
18b49ac873SJames Feist #include "health.hpp"
191c8fba97SJames Feist #include "led.hpp"
20f5c9f8bdSJason M. Bills #include "pcie.hpp"
21c5d03ff4SJennifer Lee #include "redfish_util.hpp"
22c5d03ff4SJennifer Lee 
237e860f15SJohn Edward Broadbent #include <app.hpp>
249712f8acSEd Tanous #include <boost/container/flat_map.hpp>
25*168e20c1SEd Tanous #include <dbus_utility.hpp>
26ed398213SEd Tanous #include <registries/privilege_registry.hpp>
27cb7e1e7bSAndrew Geissler #include <utils/fw_utils.hpp>
28c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
291214b7e7SGunnar Mills 
30abf2add6SEd Tanous #include <variant>
31c5b2abe0SLewanczyk, Dawid 
321abe55efSEd Tanous namespace redfish
331abe55efSEd Tanous {
34c5b2abe0SLewanczyk, Dawid 
359d3ae10eSAlpana Kumari /**
369d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
379d3ae10eSAlpana Kumari  *
389d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
399d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
409d3ae10eSAlpana Kumari  *
419d3ae10eSAlpana Kumari  * @return None.
429d3ae10eSAlpana Kumari  */
438d1b46d7Szhanghch05 inline void
448d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
45*168e20c1SEd Tanous                          const dbus::utility::DbusVariantType& dimmState)
469d3ae10eSAlpana Kumari {
479d3ae10eSAlpana Kumari     const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
489d3ae10eSAlpana Kumari     if (isDimmFunctional == nullptr)
499d3ae10eSAlpana Kumari     {
509d3ae10eSAlpana Kumari         messages::internalError(aResp->res);
519d3ae10eSAlpana Kumari         return;
529d3ae10eSAlpana Kumari     }
539d3ae10eSAlpana Kumari     BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
549d3ae10eSAlpana Kumari 
559d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
569d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
579d3ae10eSAlpana Kumari     // ENABLED.
589d3ae10eSAlpana Kumari     nlohmann::json& prevMemSummary =
599d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
609d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
619d3ae10eSAlpana Kumari     {
629d3ae10eSAlpana Kumari         if (*isDimmFunctional == true)
639d3ae10eSAlpana Kumari         {
649d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
659d3ae10eSAlpana Kumari                 "Enabled";
669d3ae10eSAlpana Kumari         }
679d3ae10eSAlpana Kumari     }
689d3ae10eSAlpana Kumari }
699d3ae10eSAlpana Kumari 
7057e8c9beSAlpana Kumari /*
7157e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
7257e8c9beSAlpana Kumari  *
7357e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7457e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7557e8c9beSAlpana Kumari  *
7657e8c9beSAlpana Kumari  * @return None.
7757e8c9beSAlpana Kumari  */
78*168e20c1SEd Tanous inline void modifyCpuPresenceState(
79*168e20c1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
80*168e20c1SEd Tanous     const dbus::utility::DbusVariantType& cpuPresenceState)
8157e8c9beSAlpana Kumari {
8257e8c9beSAlpana Kumari     const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
8357e8c9beSAlpana Kumari 
8457e8c9beSAlpana Kumari     if (isCpuPresent == nullptr)
8557e8c9beSAlpana Kumari     {
8657e8c9beSAlpana Kumari         messages::internalError(aResp->res);
8757e8c9beSAlpana Kumari         return;
8857e8c9beSAlpana Kumari     }
8957e8c9beSAlpana Kumari     BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
9057e8c9beSAlpana Kumari 
9157e8c9beSAlpana Kumari     if (*isCpuPresent == true)
9257e8c9beSAlpana Kumari     {
93b4b9595aSJames Feist         nlohmann::json& procCount =
94b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
95b4b9595aSJames Feist         auto procCountPtr =
96b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
97b4b9595aSJames Feist         if (procCountPtr != nullptr)
98b4b9595aSJames Feist         {
99b4b9595aSJames Feist             // shouldn't be possible to be nullptr
100b4b9595aSJames Feist             *procCountPtr += 1;
10157e8c9beSAlpana Kumari         }
102b4b9595aSJames Feist     }
10357e8c9beSAlpana Kumari }
10457e8c9beSAlpana Kumari 
10557e8c9beSAlpana Kumari /*
10657e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10757e8c9beSAlpana Kumari  *        CPU Functional State
10857e8c9beSAlpana Kumari  *
10957e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
11057e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
11157e8c9beSAlpana Kumari  *
11257e8c9beSAlpana Kumari  * @return None.
11357e8c9beSAlpana Kumari  */
114*168e20c1SEd Tanous inline void modifyCpuFunctionalState(
115*168e20c1SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
116*168e20c1SEd Tanous     const dbus::utility::DbusVariantType& cpuFunctionalState)
11757e8c9beSAlpana Kumari {
11857e8c9beSAlpana Kumari     const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
11957e8c9beSAlpana Kumari 
12057e8c9beSAlpana Kumari     if (isCpuFunctional == nullptr)
12157e8c9beSAlpana Kumari     {
12257e8c9beSAlpana Kumari         messages::internalError(aResp->res);
12357e8c9beSAlpana Kumari         return;
12457e8c9beSAlpana Kumari     }
12557e8c9beSAlpana Kumari     BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
12657e8c9beSAlpana Kumari 
12757e8c9beSAlpana Kumari     nlohmann::json& prevProcState =
12857e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
12957e8c9beSAlpana Kumari 
13057e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
13157e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
13257e8c9beSAlpana Kumari     // Functional.
13357e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
13457e8c9beSAlpana Kumari     {
13557e8c9beSAlpana Kumari         if (*isCpuFunctional == true)
13657e8c9beSAlpana Kumari         {
13757e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
13857e8c9beSAlpana Kumari                 "Enabled";
13957e8c9beSAlpana Kumari         }
14057e8c9beSAlpana Kumari     }
14157e8c9beSAlpana Kumari }
14257e8c9beSAlpana Kumari 
14303fbed92SAli Ahmed inline void getProcessorProperties(
14403fbed92SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
14503fbed92SAli Ahmed     const std::string& path,
146*168e20c1SEd Tanous     const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
14703fbed92SAli Ahmed         properties)
14803fbed92SAli Ahmed {
14903fbed92SAli Ahmed 
15003fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
15103fbed92SAli Ahmed 
15203fbed92SAli Ahmed     auto getCpuPresenceState =
15303fbed92SAli Ahmed         [aResp](const boost::system::error_code ec3,
154*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& cpuPresenceCheck) {
15503fbed92SAli Ahmed             if (ec3)
15603fbed92SAli Ahmed             {
15703fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
15803fbed92SAli Ahmed                 return;
15903fbed92SAli Ahmed             }
16003fbed92SAli Ahmed             modifyCpuPresenceState(aResp, cpuPresenceCheck);
16103fbed92SAli Ahmed         };
16203fbed92SAli Ahmed 
16303fbed92SAli Ahmed     auto getCpuFunctionalState =
16403fbed92SAli Ahmed         [aResp](const boost::system::error_code ec3,
165*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& cpuFunctionalCheck) {
16603fbed92SAli Ahmed             if (ec3)
16703fbed92SAli Ahmed             {
16803fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
16903fbed92SAli Ahmed                 return;
17003fbed92SAli Ahmed             }
17103fbed92SAli Ahmed             modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
17203fbed92SAli Ahmed         };
17303fbed92SAli Ahmed 
17403fbed92SAli Ahmed     // Get the Presence of CPU
17503fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
17603fbed92SAli Ahmed         std::move(getCpuPresenceState), service, path,
17703fbed92SAli Ahmed         "org.freedesktop.DBus.Properties", "Get",
17803fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present");
17903fbed92SAli Ahmed 
18003fbed92SAli Ahmed     // Get the Functional State
18103fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
18203fbed92SAli Ahmed         std::move(getCpuFunctionalState), service, path,
18303fbed92SAli Ahmed         "org.freedesktop.DBus.Properties", "Get",
18403fbed92SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional");
18503fbed92SAli Ahmed 
18603fbed92SAli Ahmed     for (const auto& property : properties)
18703fbed92SAli Ahmed     {
18803fbed92SAli Ahmed 
18903fbed92SAli Ahmed         // TODO: Get Model
19003fbed92SAli Ahmed 
19103fbed92SAli Ahmed         // Get CoreCount
19203fbed92SAli Ahmed         if (property.first == "CoreCount")
19303fbed92SAli Ahmed         {
19403fbed92SAli Ahmed 
19503fbed92SAli Ahmed             // Get CPU CoreCount and add it to the total
19603fbed92SAli Ahmed             const uint16_t* coreCountVal =
19703fbed92SAli Ahmed                 std::get_if<uint16_t>(&property.second);
19803fbed92SAli Ahmed 
19903fbed92SAli Ahmed             if (!coreCountVal)
20003fbed92SAli Ahmed             {
20103fbed92SAli Ahmed                 messages::internalError(aResp->res);
20203fbed92SAli Ahmed                 return;
20303fbed92SAli Ahmed             }
20403fbed92SAli Ahmed 
20503fbed92SAli Ahmed             nlohmann::json& coreCount =
20603fbed92SAli Ahmed                 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
20703fbed92SAli Ahmed             uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
20803fbed92SAli Ahmed 
20903fbed92SAli Ahmed             if (coreCountPtr == nullptr)
21003fbed92SAli Ahmed             {
21103fbed92SAli Ahmed                 coreCount = 0;
21203fbed92SAli Ahmed             }
21303fbed92SAli Ahmed             else
21403fbed92SAli Ahmed             {
21503fbed92SAli Ahmed                 *coreCountPtr += *coreCountVal;
21603fbed92SAli Ahmed             }
21703fbed92SAli Ahmed         }
21803fbed92SAli Ahmed     }
21903fbed92SAli Ahmed }
22003fbed92SAli Ahmed 
22103fbed92SAli Ahmed /*
22203fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
22303fbed92SAli Ahmed  *
22403fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
22503fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
22603fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
22703fbed92SAli Ahmed  *
22803fbed92SAli Ahmed  * @return None.
22903fbed92SAli Ahmed  */
23003fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
23103fbed92SAli Ahmed                                 const std::string& service,
23203fbed92SAli Ahmed                                 const std::string& path)
23303fbed92SAli Ahmed {
23403fbed92SAli Ahmed 
23503fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
23603fbed92SAli Ahmed         [aResp, service,
23703fbed92SAli Ahmed          path](const boost::system::error_code ec2,
23803fbed92SAli Ahmed                const std::vector<std::pair<
239*168e20c1SEd Tanous                    std::string, dbus::utility::DbusVariantType>>& properties) {
24003fbed92SAli Ahmed             if (ec2)
24103fbed92SAli Ahmed             {
24203fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
24303fbed92SAli Ahmed                 messages::internalError(aResp->res);
24403fbed92SAli Ahmed                 return;
24503fbed92SAli Ahmed             }
24603fbed92SAli Ahmed             getProcessorProperties(aResp, service, path, properties);
24703fbed92SAli Ahmed         },
24803fbed92SAli Ahmed         service, path, "org.freedesktop.DBus.Properties", "GetAll",
24903fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item.Cpu");
25003fbed92SAli Ahmed }
25103fbed92SAli Ahmed 
25257e8c9beSAlpana Kumari /*
253c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
254c5b2abe0SLewanczyk, Dawid  *
255c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2568f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
257c5b2abe0SLewanczyk, Dawid  *
258c5b2abe0SLewanczyk, Dawid  * @return None.
259c5b2abe0SLewanczyk, Dawid  */
260b5a76932SEd Tanous inline void
2618d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
262b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2631abe55efSEd Tanous {
26455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
2659d3ae10eSAlpana Kumari 
26655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
2675bc2dc8eSJames Feist         [aResp, systemHealth](
268c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
269c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
2706c34de48SEd Tanous                 std::string,
2711214b7e7SGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2721214b7e7SGunnar Mills                 subtree) {
2731abe55efSEd Tanous             if (ec)
2741abe55efSEd Tanous             {
27555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
276f12894f8SJason M. Bills                 messages::internalError(aResp->res);
277c5b2abe0SLewanczyk, Dawid                 return;
278c5b2abe0SLewanczyk, Dawid             }
279c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
2806c34de48SEd Tanous             for (const std::pair<std::string,
2816c34de48SEd Tanous                                  std::vector<std::pair<
2821214b7e7SGunnar Mills                                      std::string, std::vector<std::string>>>>&
2831214b7e7SGunnar Mills                      object : subtree)
2841abe55efSEd Tanous             {
285c5b2abe0SLewanczyk, Dawid                 const std::string& path = object.first;
28655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
2871abe55efSEd Tanous                 const std::vector<
2881214b7e7SGunnar Mills                     std::pair<std::string, std::vector<std::string>>>&
2891214b7e7SGunnar Mills                     connectionNames = object.second;
2901abe55efSEd Tanous                 if (connectionNames.size() < 1)
2911abe55efSEd Tanous                 {
292c5b2abe0SLewanczyk, Dawid                     continue;
293c5b2abe0SLewanczyk, Dawid                 }
294029573d4SEd Tanous 
2955bc2dc8eSJames Feist                 auto memoryHealth = std::make_shared<HealthPopulate>(
2965bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
2975bc2dc8eSJames Feist 
2985bc2dc8eSJames Feist                 auto cpuHealth = std::make_shared<HealthPopulate>(
2995bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
3005bc2dc8eSJames Feist 
3015bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
3025bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
3035bc2dc8eSJames Feist 
3046c34de48SEd Tanous                 // This is not system, so check if it's cpu, dimm, UUID or
3056c34de48SEd Tanous                 // BiosVer
30604a258f4SEd Tanous                 for (const auto& connection : connectionNames)
3071abe55efSEd Tanous                 {
30804a258f4SEd Tanous                     for (const auto& interfaceName : connection.second)
3091abe55efSEd Tanous                     {
31004a258f4SEd Tanous                         if (interfaceName ==
31104a258f4SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm")
3121abe55efSEd Tanous                         {
3131abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
31404a258f4SEd Tanous                                 << "Found Dimm, now get its properties.";
3159d3ae10eSAlpana Kumari 
31655c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
3179d3ae10eSAlpana Kumari                                 [aResp, service{connection.first},
318f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
319*168e20c1SEd Tanous                                        const std::vector<std::pair<
320*168e20c1SEd Tanous                                            std::string,
321*168e20c1SEd Tanous                                            dbus::utility::DbusVariantType>>&
3221214b7e7SGunnar Mills                                            properties) {
323cb13a392SEd Tanous                                     if (ec2)
3241abe55efSEd Tanous                                     {
3251abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
326cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
327f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
328c5b2abe0SLewanczyk, Dawid                                         return;
329c5b2abe0SLewanczyk, Dawid                                     }
3306c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
3316c34de48SEd Tanous                                                      << properties.size()
332c5b2abe0SLewanczyk, Dawid                                                      << " Dimm properties.";
3339d3ae10eSAlpana Kumari 
3349d3ae10eSAlpana Kumari                                     if (properties.size() > 0)
3359d3ae10eSAlpana Kumari                                     {
336*168e20c1SEd Tanous                                         for (const std::pair<
337*168e20c1SEd Tanous                                                  std::string,
338*168e20c1SEd Tanous                                                  dbus::utility::
339*168e20c1SEd Tanous                                                      DbusVariantType>&
3401214b7e7SGunnar Mills                                                  property : properties)
3411abe55efSEd Tanous                                         {
3425fd7ba65SCheng C Yang                                             if (property.first !=
3435fd7ba65SCheng C Yang                                                 "MemorySizeInKB")
3441abe55efSEd Tanous                                             {
3455fd7ba65SCheng C Yang                                                 continue;
3465fd7ba65SCheng C Yang                                             }
3475fd7ba65SCheng C Yang                                             const uint32_t* value =
3488d78b7a9SPatrick Williams                                                 std::get_if<uint32_t>(
3491b6b96c5SEd Tanous                                                     &property.second);
3505fd7ba65SCheng C Yang                                             if (value == nullptr)
3511abe55efSEd Tanous                                             {
3525fd7ba65SCheng C Yang                                                 BMCWEB_LOG_DEBUG
3530fda0f12SGeorge Liu                                                     << "Find incorrect type of MemorySize";
3545fd7ba65SCheng C Yang                                                 continue;
3555fd7ba65SCheng C Yang                                             }
3565fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
3570fda0f12SGeorge Liu                                                 aResp->res.jsonValue
3580fda0f12SGeorge Liu                                                     ["MemorySummary"]
3590fda0f12SGeorge Liu                                                     ["TotalSystemMemoryGiB"];
3605fd7ba65SCheng C Yang                                             uint64_t* preValue =
3615fd7ba65SCheng C Yang                                                 totalMemory
3625fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
3635fd7ba65SCheng C Yang                                             if (preValue == nullptr)
3645fd7ba65SCheng C Yang                                             {
3655fd7ba65SCheng C Yang                                                 continue;
3665fd7ba65SCheng C Yang                                             }
3670fda0f12SGeorge Liu                                             aResp->res.jsonValue
3680fda0f12SGeorge Liu                                                 ["MemorySummary"]
3690fda0f12SGeorge Liu                                                 ["TotalSystemMemoryGiB"] =
3705fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
3715fd7ba65SCheng C Yang                                                 *preValue;
3725fd7ba65SCheng C Yang                                             aResp->res
3735fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3749d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
3751abe55efSEd Tanous                                                 "Enabled";
376c5b2abe0SLewanczyk, Dawid                                         }
377c5b2abe0SLewanczyk, Dawid                                     }
3789d3ae10eSAlpana Kumari                                     else
3799d3ae10eSAlpana Kumari                                     {
3809d3ae10eSAlpana Kumari                                         auto getDimmProperties =
3819d3ae10eSAlpana Kumari                                             [aResp](
3829d3ae10eSAlpana Kumari                                                 const boost::system::error_code
383cb13a392SEd Tanous                                                     ec3,
384*168e20c1SEd Tanous                                                 const dbus::utility::
385*168e20c1SEd Tanous                                                     DbusVariantType&
3861214b7e7SGunnar Mills                                                         dimmState) {
387cb13a392SEd Tanous                                                 if (ec3)
3889d3ae10eSAlpana Kumari                                                 {
3899d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
3900fda0f12SGeorge Liu                                                         << "DBUS response error "
391cb13a392SEd Tanous                                                         << ec3;
3929d3ae10eSAlpana Kumari                                                     return;
3939d3ae10eSAlpana Kumari                                                 }
3949d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
3959d3ae10eSAlpana Kumari                                                                      dimmState);
3969d3ae10eSAlpana Kumari                                             };
3979d3ae10eSAlpana Kumari                                         crow::connections::systemBus
3989d3ae10eSAlpana Kumari                                             ->async_method_call(
3999d3ae10eSAlpana Kumari                                                 std::move(getDimmProperties),
4009d3ae10eSAlpana Kumari                                                 service, path,
4010fda0f12SGeorge Liu                                                 "org.freedesktop.DBus.Properties",
4029d3ae10eSAlpana Kumari                                                 "Get",
4030fda0f12SGeorge Liu                                                 "xyz.openbmc_project.State.Decorator.OperationalStatus",
4049d3ae10eSAlpana Kumari                                                 "Functional");
4059d3ae10eSAlpana Kumari                                     }
406c5b2abe0SLewanczyk, Dawid                                 },
40704a258f4SEd Tanous                                 connection.first, path,
4086c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4096c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
4105bc2dc8eSJames Feist 
4115bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4121abe55efSEd Tanous                         }
41304a258f4SEd Tanous                         else if (interfaceName ==
41404a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
4151abe55efSEd Tanous                         {
4161abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
41704a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
41857e8c9beSAlpana Kumari 
41903fbed92SAli Ahmed                             getProcessorSummary(aResp, connection.first, path);
4205bc2dc8eSJames Feist 
4215bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4221abe55efSEd Tanous                         }
42304a258f4SEd Tanous                         else if (interfaceName ==
42404a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
4251abe55efSEd Tanous                         {
4261abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
42704a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
42855c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
429*168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec3,
430*168e20c1SEd Tanous                                         const std::vector<std::pair<
431*168e20c1SEd Tanous                                             std::string,
432*168e20c1SEd Tanous                                             dbus::utility::DbusVariantType>>&
4331214b7e7SGunnar Mills                                             properties) {
434cb13a392SEd Tanous                                     if (ec3)
4351abe55efSEd Tanous                                     {
4361abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
437cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
438f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
439c5b2abe0SLewanczyk, Dawid                                         return;
440c5b2abe0SLewanczyk, Dawid                                     }
4416c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4426c34de48SEd Tanous                                                      << properties.size()
443c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
444*168e20c1SEd Tanous                                     for (const std::pair<
445*168e20c1SEd Tanous                                              std::string,
446*168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4471214b7e7SGunnar Mills                                              property : properties)
4481abe55efSEd Tanous                                     {
44904a258f4SEd Tanous                                         if (property.first == "UUID")
4501abe55efSEd Tanous                                         {
451c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4528d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4531b6b96c5SEd Tanous                                                     &property.second);
45404a258f4SEd Tanous 
4551abe55efSEd Tanous                                             if (value != nullptr)
4561abe55efSEd Tanous                                             {
457029573d4SEd Tanous                                                 std::string valueStr = *value;
45804a258f4SEd Tanous                                                 if (valueStr.size() == 32)
4591abe55efSEd Tanous                                                 {
460029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
461029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
462029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
463029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
46404a258f4SEd Tanous                                                 }
465029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
46604a258f4SEd Tanous                                                                  << valueStr;
467029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
46804a258f4SEd Tanous                                                     valueStr;
469c5b2abe0SLewanczyk, Dawid                                             }
470c5b2abe0SLewanczyk, Dawid                                         }
471c5b2abe0SLewanczyk, Dawid                                     }
472c5b2abe0SLewanczyk, Dawid                                 },
47304a258f4SEd Tanous                                 connection.first, path,
4746c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4751abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
476c5b2abe0SLewanczyk, Dawid                         }
477029573d4SEd Tanous                         else if (interfaceName ==
478029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
4791abe55efSEd Tanous                         {
480029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
481*168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
482*168e20c1SEd Tanous                                         const std::vector<std::pair<
483*168e20c1SEd Tanous                                             std::string,
484*168e20c1SEd Tanous                                             dbus::utility::DbusVariantType>>&
4851214b7e7SGunnar Mills                                             propertiesList) {
486cb13a392SEd Tanous                                     if (ec2)
487029573d4SEd Tanous                                     {
488e4a4b9a9SJames Feist                                         // doesn't have to include this
489e4a4b9a9SJames Feist                                         // interface
490029573d4SEd Tanous                                         return;
491029573d4SEd Tanous                                     }
492698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
493698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
494029573d4SEd Tanous                                         << " properties for system";
495*168e20c1SEd Tanous                                     for (const std::pair<
496*168e20c1SEd Tanous                                              std::string,
497*168e20c1SEd Tanous                                              dbus::utility::DbusVariantType>&
4981214b7e7SGunnar Mills                                              property : propertiesList)
499029573d4SEd Tanous                                     {
500fc5afcf9Sbeccabroek                                         const std::string& propertyName =
501fc5afcf9Sbeccabroek                                             property.first;
502fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
503fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
504fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
5055235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
5065235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
507fc5afcf9Sbeccabroek                                         {
508029573d4SEd Tanous                                             const std::string* value =
509fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
510029573d4SEd Tanous                                                     &property.second);
511029573d4SEd Tanous                                             if (value != nullptr)
512029573d4SEd Tanous                                             {
513029573d4SEd Tanous                                                 aResp->res
514fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
515029573d4SEd Tanous                                                     *value;
516029573d4SEd Tanous                                             }
517029573d4SEd Tanous                                         }
518fc5afcf9Sbeccabroek                                     }
519c1e236a6SGunnar Mills 
520cb7e1e7bSAndrew Geissler                                     // Grab the bios version
521f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
522cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
52372d566d9SGunnar Mills                                         "BiosVersion", false);
524029573d4SEd Tanous                                 },
525029573d4SEd Tanous                                 connection.first, path,
526029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
5270fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.Asset");
528e4a4b9a9SJames Feist 
529e4a4b9a9SJames Feist                             crow::connections::systemBus->async_method_call(
530*168e20c1SEd Tanous                                 [aResp](const boost::system::error_code ec2,
531*168e20c1SEd Tanous                                         const dbus::utility::DbusVariantType&
532*168e20c1SEd Tanous                                             property) {
533cb13a392SEd Tanous                                     if (ec2)
534e4a4b9a9SJames Feist                                     {
535e4a4b9a9SJames Feist                                         // doesn't have to include this
536e4a4b9a9SJames Feist                                         // interface
537e4a4b9a9SJames Feist                                         return;
538e4a4b9a9SJames Feist                                     }
539e4a4b9a9SJames Feist 
540e4a4b9a9SJames Feist                                     const std::string* value =
541e4a4b9a9SJames Feist                                         std::get_if<std::string>(&property);
542e4a4b9a9SJames Feist                                     if (value != nullptr)
543e4a4b9a9SJames Feist                                     {
544e4a4b9a9SJames Feist                                         aResp->res.jsonValue["AssetTag"] =
545e4a4b9a9SJames Feist                                             *value;
546e4a4b9a9SJames Feist                                     }
547e4a4b9a9SJames Feist                                 },
548e4a4b9a9SJames Feist                                 connection.first, path,
549e4a4b9a9SJames Feist                                 "org.freedesktop.DBus.Properties", "Get",
5500fda0f12SGeorge Liu                                 "xyz.openbmc_project.Inventory.Decorator.AssetTag",
551e4a4b9a9SJames Feist                                 "AssetTag");
552029573d4SEd Tanous                         }
553029573d4SEd Tanous                     }
554029573d4SEd Tanous                 }
555c5b2abe0SLewanczyk, Dawid             }
556c5b2abe0SLewanczyk, Dawid         },
557c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
558c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
559c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5606617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5616617338dSEd Tanous         std::array<const char*, 5>{
5626617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5636617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5646617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5656617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5666617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5676617338dSEd Tanous         });
568c5b2abe0SLewanczyk, Dawid }
569c5b2abe0SLewanczyk, Dawid 
570c5b2abe0SLewanczyk, Dawid /**
571c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
572c5b2abe0SLewanczyk, Dawid  *
573c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
574c5b2abe0SLewanczyk, Dawid  *
575c5b2abe0SLewanczyk, Dawid  * @return None.
576c5b2abe0SLewanczyk, Dawid  */
5778d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5781abe55efSEd Tanous {
57955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
58055c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
581c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
582*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& hostState) {
5831abe55efSEd Tanous             if (ec)
5841abe55efSEd Tanous             {
58555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
586f12894f8SJason M. Bills                 messages::internalError(aResp->res);
587c5b2abe0SLewanczyk, Dawid                 return;
588c5b2abe0SLewanczyk, Dawid             }
5896617338dSEd Tanous 
590abf2add6SEd Tanous             const std::string* s = std::get_if<std::string>(&hostState);
59155c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
5926617338dSEd Tanous             if (s != nullptr)
5931abe55efSEd Tanous             {
594c5b2abe0SLewanczyk, Dawid                 // Verify Host State
59594732661SAndrew Geissler                 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
5961abe55efSEd Tanous                 {
59755c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
5986617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
5991abe55efSEd Tanous                 }
6000fda0f12SGeorge Liu                 else if (*s ==
6010fda0f12SGeorge Liu                          "xyz.openbmc_project.State.Host.HostState.Quiesced")
6028c888608SGunnar Mills                 {
6038c888608SGunnar Mills                     aResp->res.jsonValue["PowerState"] = "On";
6048c888608SGunnar Mills                     aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6058c888608SGunnar Mills                 }
6060fda0f12SGeorge Liu                 else if (
6070fda0f12SGeorge Liu                     *s ==
6080fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
60983935af9SAndrew Geissler                 {
61083935af9SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "On";
61183935af9SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "InTest";
61283935af9SAndrew Geissler                 }
6130fda0f12SGeorge Liu                 else if (
6140fda0f12SGeorge Liu                     *s ==
6150fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
6161a2a1437SAndrew Geissler                 {
6171a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOn";
61815c27bf8SNoah Brewer                     aResp->res.jsonValue["Status"]["State"] = "Starting";
6191a2a1437SAndrew Geissler                 }
6200fda0f12SGeorge Liu                 else if (
6210fda0f12SGeorge Liu                     *s ==
6220fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
6231a2a1437SAndrew Geissler                 {
6241a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOff";
6251a2a1437SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
6261a2a1437SAndrew Geissler                 }
6271abe55efSEd Tanous                 else
6281abe55efSEd Tanous                 {
62955c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
6306617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
631c5b2abe0SLewanczyk, Dawid                 }
632c5b2abe0SLewanczyk, Dawid             }
633c5b2abe0SLewanczyk, Dawid         },
6346c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
6356617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
6366617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
637c5b2abe0SLewanczyk, Dawid }
638c5b2abe0SLewanczyk, Dawid 
639c5b2abe0SLewanczyk, Dawid /**
640786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
641491d8ee7SSantosh Puranik  *
642491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
643491d8ee7SSantosh Puranik  *
644491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
645491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
646491d8ee7SSantosh Puranik  */
64723a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
648491d8ee7SSantosh Puranik {
649491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
650491d8ee7SSantosh Puranik     {
651491d8ee7SSantosh Puranik         return "None";
652491d8ee7SSantosh Puranik     }
6533174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
654491d8ee7SSantosh Puranik     {
655491d8ee7SSantosh Puranik         return "Hdd";
656491d8ee7SSantosh Puranik     }
6573174e4dfSEd Tanous     if (dbusSource ==
658a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
659491d8ee7SSantosh Puranik     {
660491d8ee7SSantosh Puranik         return "Cd";
661491d8ee7SSantosh Puranik     }
6623174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
663491d8ee7SSantosh Puranik     {
664491d8ee7SSantosh Puranik         return "Pxe";
665491d8ee7SSantosh Puranik     }
6663174e4dfSEd Tanous     if (dbusSource ==
667944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6689f16b2c1SJennifer Lee     {
6699f16b2c1SJennifer Lee         return "Usb";
6709f16b2c1SJennifer Lee     }
671491d8ee7SSantosh Puranik     return "";
672491d8ee7SSantosh Puranik }
673491d8ee7SSantosh Puranik 
674491d8ee7SSantosh Puranik /**
675cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
676cd9a4666SKonstantin Aladyshev  *
677cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
678cd9a4666SKonstantin Aladyshev  *
679cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
680cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
681cd9a4666SKonstantin Aladyshev  */
682cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
683cd9a4666SKonstantin Aladyshev {
684cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
685cd9a4666SKonstantin Aladyshev     {
686cd9a4666SKonstantin Aladyshev         return "Legacy";
687cd9a4666SKonstantin Aladyshev     }
688cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
689cd9a4666SKonstantin Aladyshev     {
690cd9a4666SKonstantin Aladyshev         return "UEFI";
691cd9a4666SKonstantin Aladyshev     }
692cd9a4666SKonstantin Aladyshev     return "";
693cd9a4666SKonstantin Aladyshev }
694cd9a4666SKonstantin Aladyshev 
695cd9a4666SKonstantin Aladyshev /**
696786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
697491d8ee7SSantosh Puranik  *
698491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
699491d8ee7SSantosh Puranik  *
700491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
701491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
702491d8ee7SSantosh Puranik  */
70323a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
704491d8ee7SSantosh Puranik {
705491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
706491d8ee7SSantosh Puranik     {
707491d8ee7SSantosh Puranik         return "None";
708491d8ee7SSantosh Puranik     }
7093174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
710491d8ee7SSantosh Puranik     {
711491d8ee7SSantosh Puranik         return "Diags";
712491d8ee7SSantosh Puranik     }
7133174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
714491d8ee7SSantosh Puranik     {
715491d8ee7SSantosh Puranik         return "BiosSetup";
716491d8ee7SSantosh Puranik     }
717491d8ee7SSantosh Puranik     return "";
718491d8ee7SSantosh Puranik }
719491d8ee7SSantosh Puranik 
720491d8ee7SSantosh Puranik /**
721786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
722491d8ee7SSantosh Puranik  *
723491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
724944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
725944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
726491d8ee7SSantosh Puranik  *
727944ffaf9SJohnathan Mantey  * @return Integer error code.
728491d8ee7SSantosh Puranik  */
7298d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
730944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
731944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
732491d8ee7SSantosh Puranik {
733c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
734c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
735944ffaf9SJohnathan Mantey 
736491d8ee7SSantosh Puranik     if (rfSource == "None")
737491d8ee7SSantosh Puranik     {
738944ffaf9SJohnathan Mantey         return 0;
739491d8ee7SSantosh Puranik     }
7403174e4dfSEd Tanous     if (rfSource == "Pxe")
741491d8ee7SSantosh Puranik     {
742944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
743944ffaf9SJohnathan Mantey     }
744944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
745944ffaf9SJohnathan Mantey     {
746944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
747944ffaf9SJohnathan Mantey     }
748944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
749944ffaf9SJohnathan Mantey     {
750944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
751944ffaf9SJohnathan Mantey     }
752944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
753944ffaf9SJohnathan Mantey     {
754944ffaf9SJohnathan Mantey         bootSource =
755944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
756944ffaf9SJohnathan Mantey     }
757944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
758944ffaf9SJohnathan Mantey     {
759944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
760491d8ee7SSantosh Puranik     }
7619f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7629f16b2c1SJennifer Lee     {
763944ffaf9SJohnathan Mantey         bootSource =
764944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7659f16b2c1SJennifer Lee     }
766491d8ee7SSantosh Puranik     else
767491d8ee7SSantosh Puranik     {
7680fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
7690fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideTarget: "
770944ffaf9SJohnathan Mantey             << bootSource;
771944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
772944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
773944ffaf9SJohnathan Mantey         return -1;
774491d8ee7SSantosh Puranik     }
775944ffaf9SJohnathan Mantey     return 0;
776491d8ee7SSantosh Puranik }
7771981771bSAli Ahmed 
778978b8803SAndrew Geissler /**
779978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
780978b8803SAndrew Geissler  *
781978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
782978b8803SAndrew Geissler  *
783978b8803SAndrew Geissler  * @return None.
784978b8803SAndrew Geissler  */
7858d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
786978b8803SAndrew Geissler {
787978b8803SAndrew Geissler     crow::connections::systemBus->async_method_call(
788978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
789*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& bootProgress) {
790978b8803SAndrew Geissler             if (ec)
791978b8803SAndrew Geissler             {
792978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
793978b8803SAndrew Geissler                 // not found
794978b8803SAndrew Geissler                 return;
795978b8803SAndrew Geissler             }
796978b8803SAndrew Geissler 
797978b8803SAndrew Geissler             const std::string* bootProgressStr =
798978b8803SAndrew Geissler                 std::get_if<std::string>(&bootProgress);
799978b8803SAndrew Geissler 
800978b8803SAndrew Geissler             if (!bootProgressStr)
801978b8803SAndrew Geissler             {
802978b8803SAndrew Geissler                 // Interface implemented but property not found, return error
803978b8803SAndrew Geissler                 // for that
804978b8803SAndrew Geissler                 messages::internalError(aResp->res);
805978b8803SAndrew Geissler                 return;
806978b8803SAndrew Geissler             }
807978b8803SAndrew Geissler 
808978b8803SAndrew Geissler             BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr;
809978b8803SAndrew Geissler 
810978b8803SAndrew Geissler             // Now convert the D-Bus BootProgress to the appropriate Redfish
811978b8803SAndrew Geissler             // enum
812978b8803SAndrew Geissler             std::string rfBpLastState = "None";
8130fda0f12SGeorge Liu             if (*bootProgressStr ==
8140fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified")
815978b8803SAndrew Geissler             {
816978b8803SAndrew Geissler                 rfBpLastState = "None";
817978b8803SAndrew Geissler             }
8180fda0f12SGeorge Liu             else if (
8190fda0f12SGeorge Liu                 *bootProgressStr ==
8200fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PrimaryProcInit")
821978b8803SAndrew Geissler             {
822978b8803SAndrew Geissler                 rfBpLastState = "PrimaryProcessorInitializationStarted";
823978b8803SAndrew Geissler             }
8240fda0f12SGeorge Liu             else if (
8250fda0f12SGeorge Liu                 *bootProgressStr ==
8260fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.BusInit")
827978b8803SAndrew Geissler             {
828978b8803SAndrew Geissler                 rfBpLastState = "BusInitializationStarted";
829978b8803SAndrew Geissler             }
8300fda0f12SGeorge Liu             else if (
8310fda0f12SGeorge Liu                 *bootProgressStr ==
8320fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MemoryInit")
833978b8803SAndrew Geissler             {
834978b8803SAndrew Geissler                 rfBpLastState = "MemoryInitializationStarted";
835978b8803SAndrew Geissler             }
8360fda0f12SGeorge Liu             else if (
8370fda0f12SGeorge Liu                 *bootProgressStr ==
8380fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SecondaryProcInit")
839978b8803SAndrew Geissler             {
840978b8803SAndrew Geissler                 rfBpLastState = "SecondaryProcessorInitializationStarted";
841978b8803SAndrew Geissler             }
8420fda0f12SGeorge Liu             else if (
8430fda0f12SGeorge Liu                 *bootProgressStr ==
8440fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.PCIInit")
845978b8803SAndrew Geissler             {
846978b8803SAndrew Geissler                 rfBpLastState = "PCIResourceConfigStarted";
847978b8803SAndrew Geissler             }
8480fda0f12SGeorge Liu             else if (
8490fda0f12SGeorge Liu                 *bootProgressStr ==
8500fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.SystemInitComplete")
851978b8803SAndrew Geissler             {
852978b8803SAndrew Geissler                 rfBpLastState = "SystemHardwareInitializationComplete";
853978b8803SAndrew Geissler             }
8540fda0f12SGeorge Liu             else if (
8550fda0f12SGeorge Liu                 *bootProgressStr ==
8560fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart")
857978b8803SAndrew Geissler             {
858978b8803SAndrew Geissler                 rfBpLastState = "OSBootStarted";
859978b8803SAndrew Geissler             }
8600fda0f12SGeorge Liu             else if (
8610fda0f12SGeorge Liu                 *bootProgressStr ==
8620fda0f12SGeorge Liu                 "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSRunning")
863978b8803SAndrew Geissler             {
864978b8803SAndrew Geissler                 rfBpLastState = "OSRunning";
865978b8803SAndrew Geissler             }
866978b8803SAndrew Geissler             else
867978b8803SAndrew Geissler             {
868978b8803SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
869978b8803SAndrew Geissler                                  << *bootProgressStr;
870978b8803SAndrew Geissler                 // Just return the default
871978b8803SAndrew Geissler             }
872978b8803SAndrew Geissler 
873978b8803SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
874978b8803SAndrew Geissler         },
875978b8803SAndrew Geissler         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
876978b8803SAndrew Geissler         "org.freedesktop.DBus.Properties", "Get",
877978b8803SAndrew Geissler         "xyz.openbmc_project.State.Boot.Progress", "BootProgress");
878978b8803SAndrew Geissler }
879491d8ee7SSantosh Puranik 
880491d8ee7SSantosh Puranik /**
881c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
882cd9a4666SKonstantin Aladyshev  *
883cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
884cd9a4666SKonstantin Aladyshev  *
885cd9a4666SKonstantin Aladyshev  * @return None.
886cd9a4666SKonstantin Aladyshev  */
887cd9a4666SKonstantin Aladyshev 
888c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
889cd9a4666SKonstantin Aladyshev {
890cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
891cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
892*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& bootType) {
893cd9a4666SKonstantin Aladyshev             if (ec)
894cd9a4666SKonstantin Aladyshev             {
895cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
896cd9a4666SKonstantin Aladyshev                 return;
897cd9a4666SKonstantin Aladyshev             }
898cd9a4666SKonstantin Aladyshev 
899cd9a4666SKonstantin Aladyshev             const std::string* bootTypeStr =
900cd9a4666SKonstantin Aladyshev                 std::get_if<std::string>(&bootType);
901cd9a4666SKonstantin Aladyshev 
902cd9a4666SKonstantin Aladyshev             if (!bootTypeStr)
903cd9a4666SKonstantin Aladyshev             {
904cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
905cd9a4666SKonstantin Aladyshev                 return;
906cd9a4666SKonstantin Aladyshev             }
907cd9a4666SKonstantin Aladyshev 
908cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr;
909cd9a4666SKonstantin Aladyshev 
9100fda0f12SGeorge Liu             aResp->res
9110fda0f12SGeorge Liu                 .jsonValue["Boot"]
9120fda0f12SGeorge Liu                           ["BootSourceOverrideMode@Redfish.AllowableValues"] = {
9130fda0f12SGeorge Liu                 "Legacy", "UEFI"};
914cd9a4666SKonstantin Aladyshev 
915cd9a4666SKonstantin Aladyshev             auto rfType = dbusToRfBootType(*bootTypeStr);
916cd9a4666SKonstantin Aladyshev             if (rfType.empty())
917cd9a4666SKonstantin Aladyshev             {
918cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
919cd9a4666SKonstantin Aladyshev                 return;
920cd9a4666SKonstantin Aladyshev             }
921cd9a4666SKonstantin Aladyshev 
922cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
923cd9a4666SKonstantin Aladyshev         },
924c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
925c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
926cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
927cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType");
928cd9a4666SKonstantin Aladyshev }
929cd9a4666SKonstantin Aladyshev 
930cd9a4666SKonstantin Aladyshev /**
931c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
932491d8ee7SSantosh Puranik  *
933491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
934491d8ee7SSantosh Puranik  *
935491d8ee7SSantosh Puranik  * @return None.
936491d8ee7SSantosh Puranik  */
937c21865c4SKonstantin Aladyshev 
938c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
939491d8ee7SSantosh Puranik {
940491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
941c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
942*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& bootMode) {
943491d8ee7SSantosh Puranik             if (ec)
944491d8ee7SSantosh Puranik             {
945491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
946491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
947491d8ee7SSantosh Puranik                 return;
948491d8ee7SSantosh Puranik             }
949491d8ee7SSantosh Puranik 
950491d8ee7SSantosh Puranik             const std::string* bootModeStr =
951491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootMode);
952491d8ee7SSantosh Puranik 
953491d8ee7SSantosh Puranik             if (!bootModeStr)
954491d8ee7SSantosh Puranik             {
955491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
956491d8ee7SSantosh Puranik                 return;
957491d8ee7SSantosh Puranik             }
958491d8ee7SSantosh Puranik 
959491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
960491d8ee7SSantosh Puranik 
9610fda0f12SGeorge Liu             aResp->res
9620fda0f12SGeorge Liu                 .jsonValue["Boot"]
9630fda0f12SGeorge Liu                           ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
9640fda0f12SGeorge Liu                 {"None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
965491d8ee7SSantosh Puranik 
966491d8ee7SSantosh Puranik             if (*bootModeStr !=
967491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
968491d8ee7SSantosh Puranik             {
969491d8ee7SSantosh Puranik                 auto rfMode = dbusToRfBootMode(*bootModeStr);
970491d8ee7SSantosh Puranik                 if (!rfMode.empty())
971491d8ee7SSantosh Puranik                 {
972491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
973491d8ee7SSantosh Puranik                         rfMode;
974491d8ee7SSantosh Puranik                 }
975491d8ee7SSantosh Puranik             }
976491d8ee7SSantosh Puranik         },
977c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
978c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
979491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
980491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
981491d8ee7SSantosh Puranik }
982491d8ee7SSantosh Puranik 
983491d8ee7SSantosh Puranik /**
984c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
985491d8ee7SSantosh Puranik  *
986491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
987491d8ee7SSantosh Puranik  *
988491d8ee7SSantosh Puranik  * @return None.
989491d8ee7SSantosh Puranik  */
990c21865c4SKonstantin Aladyshev 
991c21865c4SKonstantin Aladyshev inline void
992c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
993491d8ee7SSantosh Puranik {
994491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
995c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
996*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& bootSource) {
997491d8ee7SSantosh Puranik             if (ec)
998491d8ee7SSantosh Puranik             {
999491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1000491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1001491d8ee7SSantosh Puranik                 return;
1002491d8ee7SSantosh Puranik             }
1003491d8ee7SSantosh Puranik 
1004491d8ee7SSantosh Puranik             const std::string* bootSourceStr =
1005491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootSource);
1006491d8ee7SSantosh Puranik 
1007491d8ee7SSantosh Puranik             if (!bootSourceStr)
1008491d8ee7SSantosh Puranik             {
1009491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1010491d8ee7SSantosh Puranik                 return;
1011491d8ee7SSantosh Puranik             }
1012491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
1013491d8ee7SSantosh Puranik 
1014491d8ee7SSantosh Puranik             auto rfSource = dbusToRfBootSource(*bootSourceStr);
1015491d8ee7SSantosh Puranik             if (!rfSource.empty())
1016491d8ee7SSantosh Puranik             {
1017491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1018491d8ee7SSantosh Puranik                     rfSource;
1019491d8ee7SSantosh Puranik             }
1020cd9a4666SKonstantin Aladyshev 
1021cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1022cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1023c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
1024491d8ee7SSantosh Puranik         },
1025c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1026c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1027491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1028491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource");
1029491d8ee7SSantosh Puranik }
1030491d8ee7SSantosh Puranik 
1031491d8ee7SSantosh Puranik /**
1032c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1033c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1034c21865c4SKonstantin Aladyshev  * state
1035491d8ee7SSantosh Puranik  *
1036491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1037491d8ee7SSantosh Puranik  *
1038491d8ee7SSantosh Puranik  * @return None.
1039491d8ee7SSantosh Puranik  */
1040491d8ee7SSantosh Puranik 
1041c21865c4SKonstantin Aladyshev inline void
1042c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1043c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1044c21865c4SKonstantin Aladyshev {
1045c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1046c21865c4SKonstantin Aladyshev     {
1047c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1048c21865c4SKonstantin Aladyshev         return;
1049c21865c4SKonstantin Aladyshev     }
1050c21865c4SKonstantin Aladyshev 
1051c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1052c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1053491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1054c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
1055*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& oneTime) {
1056491d8ee7SSantosh Puranik             if (ec)
1057491d8ee7SSantosh Puranik             {
1058491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1059c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1060491d8ee7SSantosh Puranik                 return;
1061491d8ee7SSantosh Puranik             }
1062491d8ee7SSantosh Puranik 
1063491d8ee7SSantosh Puranik             const bool* oneTimePtr = std::get_if<bool>(&oneTime);
1064491d8ee7SSantosh Puranik 
1065491d8ee7SSantosh Puranik             if (!oneTimePtr)
1066491d8ee7SSantosh Puranik             {
1067491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1068491d8ee7SSantosh Puranik                 return;
1069491d8ee7SSantosh Puranik             }
1070c21865c4SKonstantin Aladyshev 
1071c21865c4SKonstantin Aladyshev             bool oneTimeSetting = *oneTimePtr;
1072c21865c4SKonstantin Aladyshev 
1073c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1074c21865c4SKonstantin Aladyshev             {
1075c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1076c21865c4SKonstantin Aladyshev                     "Once";
1077c21865c4SKonstantin Aladyshev             }
1078c21865c4SKonstantin Aladyshev             else
1079c21865c4SKonstantin Aladyshev             {
1080c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1081c21865c4SKonstantin Aladyshev                     "Continuous";
1082c21865c4SKonstantin Aladyshev             }
1083491d8ee7SSantosh Puranik         },
1084491d8ee7SSantosh Puranik         "xyz.openbmc_project.Settings",
1085491d8ee7SSantosh Puranik         "/xyz/openbmc_project/control/host0/boot/one_time",
1086491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1087491d8ee7SSantosh Puranik         "xyz.openbmc_project.Object.Enable", "Enabled");
1088491d8ee7SSantosh Puranik }
1089491d8ee7SSantosh Puranik 
1090491d8ee7SSantosh Puranik /**
1091c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1092c21865c4SKonstantin Aladyshev  *
1093c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1094c21865c4SKonstantin Aladyshev  *
1095c21865c4SKonstantin Aladyshev  * @return None.
1096c21865c4SKonstantin Aladyshev  */
1097c21865c4SKonstantin Aladyshev 
1098c21865c4SKonstantin Aladyshev inline void
1099c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1100c21865c4SKonstantin Aladyshev {
1101c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1102c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
1103*168e20c1SEd Tanous                 const dbus::utility::DbusVariantType& bootOverrideEnable) {
1104c21865c4SKonstantin Aladyshev             if (ec)
1105c21865c4SKonstantin Aladyshev             {
1106c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1107c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1108c21865c4SKonstantin Aladyshev                 return;
1109c21865c4SKonstantin Aladyshev             }
1110c21865c4SKonstantin Aladyshev 
1111c21865c4SKonstantin Aladyshev             const bool* bootOverrideEnablePtr =
1112c21865c4SKonstantin Aladyshev                 std::get_if<bool>(&bootOverrideEnable);
1113c21865c4SKonstantin Aladyshev 
1114c21865c4SKonstantin Aladyshev             if (!bootOverrideEnablePtr)
1115c21865c4SKonstantin Aladyshev             {
1116c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1117c21865c4SKonstantin Aladyshev                 return;
1118c21865c4SKonstantin Aladyshev             }
1119c21865c4SKonstantin Aladyshev 
1120c21865c4SKonstantin Aladyshev             processBootOverrideEnable(aResp, *bootOverrideEnablePtr);
1121c21865c4SKonstantin Aladyshev         },
1122c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1123c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1124c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
1125c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled");
1126c21865c4SKonstantin Aladyshev }
1127c21865c4SKonstantin Aladyshev 
1128c21865c4SKonstantin Aladyshev /**
1129c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1130c21865c4SKonstantin Aladyshev  *
1131c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1132c21865c4SKonstantin Aladyshev  *
1133c21865c4SKonstantin Aladyshev  * @return None.
1134c21865c4SKonstantin Aladyshev  */
1135c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1136c21865c4SKonstantin Aladyshev {
1137c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1138c21865c4SKonstantin Aladyshev 
1139c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1140c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1141c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1142c21865c4SKonstantin Aladyshev }
1143c21865c4SKonstantin Aladyshev 
1144c21865c4SKonstantin Aladyshev /**
1145c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1146c0557e1aSGunnar Mills  *
1147c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1148c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1149c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1150c0557e1aSGunnar Mills  * last power operation time.
1151c0557e1aSGunnar Mills  *
1152c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1153c0557e1aSGunnar Mills  *
1154c0557e1aSGunnar Mills  * @return None.
1155c0557e1aSGunnar Mills  */
11568d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1157c0557e1aSGunnar Mills {
1158c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1159c0557e1aSGunnar Mills 
1160c0557e1aSGunnar Mills     crow::connections::systemBus->async_method_call(
1161c0557e1aSGunnar Mills         [aResp](const boost::system::error_code ec,
1162*168e20c1SEd Tanous                 dbus::utility::DbusVariantType& lastResetTime) {
1163c0557e1aSGunnar Mills             if (ec)
1164c0557e1aSGunnar Mills             {
1165c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1166c0557e1aSGunnar Mills                 return;
1167c0557e1aSGunnar Mills             }
1168c0557e1aSGunnar Mills 
1169c0557e1aSGunnar Mills             const uint64_t* lastResetTimePtr =
1170c0557e1aSGunnar Mills                 std::get_if<uint64_t>(&lastResetTime);
1171c0557e1aSGunnar Mills 
1172c0557e1aSGunnar Mills             if (!lastResetTimePtr)
1173c0557e1aSGunnar Mills             {
1174c0557e1aSGunnar Mills                 messages::internalError(aResp->res);
1175c0557e1aSGunnar Mills                 return;
1176c0557e1aSGunnar Mills             }
1177c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1178c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
11791d8782e7SNan Zhou             uint64_t lastResetTimeStamp = *lastResetTimePtr / 1000;
1180c0557e1aSGunnar Mills 
1181c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1182c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
11831d8782e7SNan Zhou                 crow::utility::getDateTimeUint(lastResetTimeStamp);
1184c0557e1aSGunnar Mills         },
1185c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis",
1186c0557e1aSGunnar Mills         "/xyz/openbmc_project/state/chassis0",
1187c0557e1aSGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
1188c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
1189c0557e1aSGunnar Mills }
1190c0557e1aSGunnar Mills 
1191c0557e1aSGunnar Mills /**
11926bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11936bd5a8d2SGunnar Mills  *
11946bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11956bd5a8d2SGunnar Mills  *
11966bd5a8d2SGunnar Mills  * @return None.
11976bd5a8d2SGunnar Mills  */
11988d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11996bd5a8d2SGunnar Mills {
12006bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12016bd5a8d2SGunnar Mills 
12026bd5a8d2SGunnar Mills     crow::connections::systemBus->async_method_call(
12036bd5a8d2SGunnar Mills         [aResp](const boost::system::error_code ec,
1204*168e20c1SEd Tanous                 dbus::utility::DbusVariantType& autoRebootEnabled) {
12056bd5a8d2SGunnar Mills             if (ec)
12066bd5a8d2SGunnar Mills             {
12076bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
12086bd5a8d2SGunnar Mills                 return;
12096bd5a8d2SGunnar Mills             }
12106bd5a8d2SGunnar Mills 
12116bd5a8d2SGunnar Mills             const bool* autoRebootEnabledPtr =
12126bd5a8d2SGunnar Mills                 std::get_if<bool>(&autoRebootEnabled);
12136bd5a8d2SGunnar Mills 
12146bd5a8d2SGunnar Mills             if (!autoRebootEnabledPtr)
12156bd5a8d2SGunnar Mills             {
12166bd5a8d2SGunnar Mills                 messages::internalError(aResp->res);
12176bd5a8d2SGunnar Mills                 return;
12186bd5a8d2SGunnar Mills             }
12196bd5a8d2SGunnar Mills 
12206bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
12216bd5a8d2SGunnar Mills             if (*autoRebootEnabledPtr == true)
12226bd5a8d2SGunnar Mills             {
12236bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12246bd5a8d2SGunnar Mills                     "RetryAttempts";
12256bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
12266bd5a8d2SGunnar Mills                 // attempts are left
12276bd5a8d2SGunnar Mills                 crow::connections::systemBus->async_method_call(
1228cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
1229*168e20c1SEd Tanous                             dbus::utility::DbusVariantType&
1230*168e20c1SEd Tanous                                 autoRebootAttemptsLeft) {
1231cb13a392SEd Tanous                         if (ec2)
12326bd5a8d2SGunnar Mills                         {
1233cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
12346bd5a8d2SGunnar Mills                             return;
12356bd5a8d2SGunnar Mills                         }
12366bd5a8d2SGunnar Mills 
12376bd5a8d2SGunnar Mills                         const uint32_t* autoRebootAttemptsLeftPtr =
12386bd5a8d2SGunnar Mills                             std::get_if<uint32_t>(&autoRebootAttemptsLeft);
12396bd5a8d2SGunnar Mills 
12406bd5a8d2SGunnar Mills                         if (!autoRebootAttemptsLeftPtr)
12416bd5a8d2SGunnar Mills                         {
12426bd5a8d2SGunnar Mills                             messages::internalError(aResp->res);
12436bd5a8d2SGunnar Mills                             return;
12446bd5a8d2SGunnar Mills                         }
12456bd5a8d2SGunnar Mills 
12466bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
12476bd5a8d2SGunnar Mills                                          << *autoRebootAttemptsLeftPtr;
12486bd5a8d2SGunnar Mills 
12496bd5a8d2SGunnar Mills                         aResp->res
12506bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
12516bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
12526bd5a8d2SGunnar Mills                             *autoRebootAttemptsLeftPtr;
12536bd5a8d2SGunnar Mills                     },
12546bd5a8d2SGunnar Mills                     "xyz.openbmc_project.State.Host",
12556bd5a8d2SGunnar Mills                     "/xyz/openbmc_project/state/host0",
12566bd5a8d2SGunnar Mills                     "org.freedesktop.DBus.Properties", "Get",
12576bd5a8d2SGunnar Mills                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
12586bd5a8d2SGunnar Mills                     "AttemptsLeft");
12596bd5a8d2SGunnar Mills             }
12606bd5a8d2SGunnar Mills             else
12616bd5a8d2SGunnar Mills             {
12626bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12636bd5a8d2SGunnar Mills                     "Disabled";
12646bd5a8d2SGunnar Mills             }
12656bd5a8d2SGunnar Mills 
12666bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
12676bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
12686bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
126969f35306SGunnar Mills 
127069f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
127169f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
127269f35306SGunnar Mills             // RetryAttempts.
12730fda0f12SGeorge Liu             aResp->res
12740fda0f12SGeorge Liu                 .jsonValue["Boot"]
12750fda0f12SGeorge Liu                           ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
12760fda0f12SGeorge Liu                 "Disabled", "RetryAttempts"};
12776bd5a8d2SGunnar Mills         },
12786bd5a8d2SGunnar Mills         "xyz.openbmc_project.Settings",
12796bd5a8d2SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
12806bd5a8d2SGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
12816bd5a8d2SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
12826bd5a8d2SGunnar Mills }
12836bd5a8d2SGunnar Mills 
12846bd5a8d2SGunnar Mills /**
1285c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1286c6a620f2SGeorge Liu  *
1287c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1288c6a620f2SGeorge Liu  *
1289c6a620f2SGeorge Liu  * @return None.
1290c6a620f2SGeorge Liu  */
12918d1b46d7Szhanghch05 inline void
12928d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1293c6a620f2SGeorge Liu {
1294c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1295c6a620f2SGeorge Liu 
1296c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1297c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec,
1298*168e20c1SEd Tanous                 dbus::utility::DbusVariantType& policy) {
1299c6a620f2SGeorge Liu             if (ec)
1300c6a620f2SGeorge Liu             {
1301c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1302c6a620f2SGeorge Liu                 return;
1303c6a620f2SGeorge Liu             }
1304c6a620f2SGeorge Liu 
13050fda0f12SGeorge Liu             const boost::container::flat_map<std::string, std::string> policyMaps = {
13060fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1307c6a620f2SGeorge Liu                  "AlwaysOn"},
13080fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1309c6a620f2SGeorge Liu                  "AlwaysOff"},
13100fda0f12SGeorge Liu                 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1311c6a620f2SGeorge Liu                  "LastState"}};
1312c6a620f2SGeorge Liu 
1313c6a620f2SGeorge Liu             const std::string* policyPtr = std::get_if<std::string>(&policy);
1314c6a620f2SGeorge Liu 
1315c6a620f2SGeorge Liu             if (!policyPtr)
1316c6a620f2SGeorge Liu             {
1317c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1318c6a620f2SGeorge Liu                 return;
1319c6a620f2SGeorge Liu             }
1320c6a620f2SGeorge Liu 
1321c6a620f2SGeorge Liu             auto policyMapsIt = policyMaps.find(*policyPtr);
1322c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1323c6a620f2SGeorge Liu             {
1324c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1325c6a620f2SGeorge Liu                 return;
1326c6a620f2SGeorge Liu             }
1327c6a620f2SGeorge Liu 
1328c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1329c6a620f2SGeorge Liu         },
1330c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1331c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1332c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Get",
1333c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy",
1334c6a620f2SGeorge Liu         "PowerRestorePolicy");
1335c6a620f2SGeorge Liu }
1336c6a620f2SGeorge Liu 
1337c6a620f2SGeorge Liu /**
13381981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13391981771bSAli Ahmed  * TPM is required for booting the host.
13401981771bSAli Ahmed  *
13411981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13421981771bSAli Ahmed  *
13431981771bSAli Ahmed  * @return None.
13441981771bSAli Ahmed  */
13451981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13461981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13471981771bSAli Ahmed {
13481981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
13491981771bSAli Ahmed 
13501981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
13511981771bSAli Ahmed         [aResp](
13521981771bSAli Ahmed             const boost::system::error_code ec,
13531981771bSAli Ahmed             std::vector<std::pair<
13541981771bSAli Ahmed                 std::string,
13551981771bSAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
13561981771bSAli Ahmed                 subtree) {
13571981771bSAli Ahmed             if (ec)
13581981771bSAli Ahmed             {
13591981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13601981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
13611981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
13621981771bSAli Ahmed                 // error occurs
13631981771bSAli Ahmed                 return;
13641981771bSAli Ahmed             }
13651981771bSAli Ahmed             if (subtree.size() == 0)
13661981771bSAli Ahmed             {
13671981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
13681981771bSAli Ahmed                 // if there is no instance found
13691981771bSAli Ahmed                 return;
13701981771bSAli Ahmed             }
13711981771bSAli Ahmed 
13721981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
13731981771bSAli Ahmed             if (subtree.size() > 1)
13741981771bSAli Ahmed             {
13751981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13761981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
13771981771bSAli Ahmed                     << subtree.size();
13781981771bSAli Ahmed                 // Throw an internal Error and return
13791981771bSAli Ahmed                 messages::internalError(aResp->res);
13801981771bSAli Ahmed                 return;
13811981771bSAli Ahmed             }
13821981771bSAli Ahmed 
13831981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
13841981771bSAli Ahmed             // field
13851981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13861981771bSAli Ahmed             {
13871981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13881981771bSAli Ahmed                 messages::internalError(aResp->res);
13891981771bSAli Ahmed                 return;
13901981771bSAli Ahmed             }
13911981771bSAli Ahmed 
13921981771bSAli Ahmed             const std::string& path = subtree[0].first;
13931981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
13941981771bSAli Ahmed 
13951981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
13961981771bSAli Ahmed             crow::connections::systemBus->async_method_call(
13971981771bSAli Ahmed                 [aResp](const boost::system::error_code ec,
1398*168e20c1SEd Tanous                         dbus::utility::DbusVariantType& tpmRequired) {
13991981771bSAli Ahmed                     if (ec)
14001981771bSAli Ahmed                     {
14011981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
14021981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
14031981771bSAli Ahmed                         messages::internalError(aResp->res);
14041981771bSAli Ahmed                         return;
14051981771bSAli Ahmed                     }
14061981771bSAli Ahmed 
14071981771bSAli Ahmed                     const bool* tpmRequiredVal =
14081981771bSAli Ahmed                         std::get_if<bool>(&tpmRequired);
14091981771bSAli Ahmed 
14101981771bSAli Ahmed                     if (!tpmRequiredVal)
14111981771bSAli Ahmed                     {
14121981771bSAli Ahmed                         messages::internalError(aResp->res);
14131981771bSAli Ahmed                         return;
14141981771bSAli Ahmed                     }
14151981771bSAli Ahmed 
14161981771bSAli Ahmed                     if (*tpmRequiredVal == true)
14171981771bSAli Ahmed                     {
14181981771bSAli Ahmed                         aResp->res
14191981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14201981771bSAli Ahmed                             "Required";
14211981771bSAli Ahmed                     }
14221981771bSAli Ahmed                     else
14231981771bSAli Ahmed                     {
14241981771bSAli Ahmed                         aResp->res
14251981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14261981771bSAli Ahmed                             "Disabled";
14271981771bSAli Ahmed                     }
14281981771bSAli Ahmed                 },
14291981771bSAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Get",
14301981771bSAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable");
14311981771bSAli Ahmed         },
14321981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
14331981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
14341981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
14351981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
14361981771bSAli Ahmed }
14371981771bSAli Ahmed 
14381981771bSAli Ahmed /**
14391c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14401c05dae3SAli Ahmed  * TPM is required for booting the host.
14411c05dae3SAli Ahmed  *
14421c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14431c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14441c05dae3SAli Ahmed  *
14451c05dae3SAli Ahmed  * @return None.
14461c05dae3SAli Ahmed  */
14471c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14481c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14491c05dae3SAli Ahmed {
14501c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
14511c05dae3SAli Ahmed 
14521c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
14531c05dae3SAli Ahmed         [aResp, tpmRequired](
14541c05dae3SAli Ahmed             const boost::system::error_code ec,
14551c05dae3SAli Ahmed             std::vector<std::pair<
14561c05dae3SAli Ahmed                 std::string,
14571c05dae3SAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
14581c05dae3SAli Ahmed                 subtree) {
14591c05dae3SAli Ahmed             if (ec)
14601c05dae3SAli Ahmed             {
14611c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14621c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
14631c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14641c05dae3SAli Ahmed                 return;
14651c05dae3SAli Ahmed             }
14661c05dae3SAli Ahmed             if (subtree.size() == 0)
14671c05dae3SAli Ahmed             {
14681c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14691c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
14701c05dae3SAli Ahmed                 return;
14711c05dae3SAli Ahmed             }
14721c05dae3SAli Ahmed 
14731c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
14741c05dae3SAli Ahmed             if (subtree.size() > 1)
14751c05dae3SAli Ahmed             {
14761c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14771c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
14781c05dae3SAli Ahmed                     << subtree.size();
14791c05dae3SAli Ahmed                 // Throw an internal Error and return
14801c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14811c05dae3SAli Ahmed                 return;
14821c05dae3SAli Ahmed             }
14831c05dae3SAli Ahmed 
14841c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14851c05dae3SAli Ahmed             // field
14861c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14871c05dae3SAli Ahmed             {
14881c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14891c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14901c05dae3SAli Ahmed                 return;
14911c05dae3SAli Ahmed             }
14921c05dae3SAli Ahmed 
14931c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
14941c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14951c05dae3SAli Ahmed 
14961c05dae3SAli Ahmed             if (serv.empty())
14971c05dae3SAli Ahmed             {
14981c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
14991c05dae3SAli Ahmed                 messages::internalError(aResp->res);
15001c05dae3SAli Ahmed                 return;
15011c05dae3SAli Ahmed             }
15021c05dae3SAli Ahmed 
15031c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
15041c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
15051c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
15061c05dae3SAli Ahmed                     if (ec)
15071c05dae3SAli Ahmed                     {
15080fda0f12SGeorge Liu                         BMCWEB_LOG_DEBUG
15090fda0f12SGeorge Liu                             << "DBUS response error: Set TrustedModuleRequiredToBoot"
15101c05dae3SAli Ahmed                             << ec;
15111c05dae3SAli Ahmed                         messages::internalError(aResp->res);
15121c05dae3SAli Ahmed                         return;
15131c05dae3SAli Ahmed                     }
15141c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15151c05dae3SAli Ahmed                 },
15161c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
15171c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1518*168e20c1SEd Tanous                 dbus::utility::DbusVariantType(tpmRequired));
15191c05dae3SAli Ahmed         },
15201c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
15211c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
15221c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
15231c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
15241c05dae3SAli Ahmed }
15251c05dae3SAli Ahmed 
15261c05dae3SAli Ahmed /**
1527491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1528491d8ee7SSantosh Puranik  *
1529491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1530cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1531cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1532cd9a4666SKonstantin Aladyshev  */
1533cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1534cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1535cd9a4666SKonstantin Aladyshev {
1536c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1537cd9a4666SKonstantin Aladyshev 
1538c21865c4SKonstantin Aladyshev     if (!bootType)
1539cd9a4666SKonstantin Aladyshev     {
1540c21865c4SKonstantin Aladyshev         return;
1541c21865c4SKonstantin Aladyshev     }
1542c21865c4SKonstantin Aladyshev 
1543cd9a4666SKonstantin Aladyshev     // Source target specified
1544cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1545cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1546cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1547cd9a4666SKonstantin Aladyshev     {
1548cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1549cd9a4666SKonstantin Aladyshev     }
1550cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1551cd9a4666SKonstantin Aladyshev     {
1552cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1553cd9a4666SKonstantin Aladyshev     }
1554cd9a4666SKonstantin Aladyshev     else
1555cd9a4666SKonstantin Aladyshev     {
1556cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1557cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1558cd9a4666SKonstantin Aladyshev                          << *bootType;
1559cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1560cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1561cd9a4666SKonstantin Aladyshev         return;
1562cd9a4666SKonstantin Aladyshev     }
1563cd9a4666SKonstantin Aladyshev 
1564cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1565cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1566cd9a4666SKonstantin Aladyshev 
1567cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1568c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1569cd9a4666SKonstantin Aladyshev             if (ec)
1570cd9a4666SKonstantin Aladyshev             {
1571cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1572cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1573cd9a4666SKonstantin Aladyshev                 {
1574cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1575cd9a4666SKonstantin Aladyshev                     return;
1576cd9a4666SKonstantin Aladyshev                 }
1577cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1578cd9a4666SKonstantin Aladyshev                 return;
1579cd9a4666SKonstantin Aladyshev             }
1580cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1581cd9a4666SKonstantin Aladyshev         },
1582c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1583c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1584cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1585cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1586*168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootTypeStr));
1587cd9a4666SKonstantin Aladyshev }
1588cd9a4666SKonstantin Aladyshev 
1589cd9a4666SKonstantin Aladyshev /**
1590cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1591cd9a4666SKonstantin Aladyshev  *
1592cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1593c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1594c21865c4SKonstantin Aladyshev  * @return Integer error code.
1595c21865c4SKonstantin Aladyshev  */
1596c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1597c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1598c21865c4SKonstantin Aladyshev {
1599c21865c4SKonstantin Aladyshev     if (!bootEnable)
1600c21865c4SKonstantin Aladyshev     {
1601c21865c4SKonstantin Aladyshev         return;
1602c21865c4SKonstantin Aladyshev     }
1603c21865c4SKonstantin Aladyshev     // Source target specified
1604c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1605c21865c4SKonstantin Aladyshev 
1606c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1607c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1608c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1609c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1610c21865c4SKonstantin Aladyshev     {
1611c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1612c21865c4SKonstantin Aladyshev     }
1613c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1614c21865c4SKonstantin Aladyshev     {
1615c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1616c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1617c21865c4SKonstantin Aladyshev     }
1618c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1619c21865c4SKonstantin Aladyshev     {
1620c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1621c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1622c21865c4SKonstantin Aladyshev     }
1623c21865c4SKonstantin Aladyshev     else
1624c21865c4SKonstantin Aladyshev     {
16250fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG
16260fda0f12SGeorge Liu             << "Invalid property value for BootSourceOverrideEnabled: "
1627c21865c4SKonstantin Aladyshev             << *bootEnable;
1628c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1629c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1630c21865c4SKonstantin Aladyshev         return;
1631c21865c4SKonstantin Aladyshev     }
1632c21865c4SKonstantin Aladyshev 
1633c21865c4SKonstantin Aladyshev     // Act on validated parameters
1634c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1635c21865c4SKonstantin Aladyshev 
1636c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1637c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1638c21865c4SKonstantin Aladyshev             if (ec)
1639c21865c4SKonstantin Aladyshev             {
1640c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1641c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1642c21865c4SKonstantin Aladyshev                 return;
1643c21865c4SKonstantin Aladyshev             }
1644c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1645c21865c4SKonstantin Aladyshev         },
1646c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1647c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1648c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1649c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1650*168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootOverrideEnable));
1651c21865c4SKonstantin Aladyshev 
1652c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1653c21865c4SKonstantin Aladyshev     {
1654c21865c4SKonstantin Aladyshev         return;
1655c21865c4SKonstantin Aladyshev     }
1656c21865c4SKonstantin Aladyshev 
1657c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1658c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1659c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1660c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1661c21865c4SKonstantin Aladyshev 
1662c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1663c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1664c21865c4SKonstantin Aladyshev             if (ec)
1665c21865c4SKonstantin Aladyshev             {
1666c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1667c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1668c21865c4SKonstantin Aladyshev                 return;
1669c21865c4SKonstantin Aladyshev             }
1670c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1671c21865c4SKonstantin Aladyshev         },
1672c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1673c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1674c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1675c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1676*168e20c1SEd Tanous         dbus::utility::DbusVariantType(!bootOverridePersistent));
1677c21865c4SKonstantin Aladyshev }
1678c21865c4SKonstantin Aladyshev 
1679c21865c4SKonstantin Aladyshev /**
1680c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1681c21865c4SKonstantin Aladyshev  *
1682c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1683491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1684491d8ee7SSantosh Puranik  *
1685265c1602SJohnathan Mantey  * @return Integer error code.
1686491d8ee7SSantosh Puranik  */
1687cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1688cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1689491d8ee7SSantosh Puranik {
1690c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1691c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1692944ffaf9SJohnathan Mantey 
1693c21865c4SKonstantin Aladyshev     if (!bootSource)
1694491d8ee7SSantosh Puranik     {
1695c21865c4SKonstantin Aladyshev         return;
1696c21865c4SKonstantin Aladyshev     }
1697c21865c4SKonstantin Aladyshev 
1698491d8ee7SSantosh Puranik     // Source target specified
1699491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1700491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1701c21865c4SKonstantin Aladyshev     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr))
1702491d8ee7SSantosh Puranik     {
1703944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1704944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1705491d8ee7SSantosh Puranik             << *bootSource;
1706491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1707491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1708491d8ee7SSantosh Puranik         return;
1709491d8ee7SSantosh Puranik     }
1710491d8ee7SSantosh Puranik 
1711944ffaf9SJohnathan Mantey     // Act on validated parameters
1712944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1713944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1714944ffaf9SJohnathan Mantey 
1715491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1716491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1717491d8ee7SSantosh Puranik             if (ec)
1718491d8ee7SSantosh Puranik             {
1719491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1720491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1721491d8ee7SSantosh Puranik                 return;
1722491d8ee7SSantosh Puranik             }
1723491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1724491d8ee7SSantosh Puranik         },
1725c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1726c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1727491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1728491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1729*168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootSourceStr));
1730944ffaf9SJohnathan Mantey 
1731491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1732491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1733491d8ee7SSantosh Puranik             if (ec)
1734491d8ee7SSantosh Puranik             {
1735491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1736491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1737491d8ee7SSantosh Puranik                 return;
1738491d8ee7SSantosh Puranik             }
1739491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1740491d8ee7SSantosh Puranik         },
1741c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1742c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1743491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1744491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1745*168e20c1SEd Tanous         dbus::utility::DbusVariantType(bootModeStr));
1746cd9a4666SKonstantin Aladyshev }
1747944ffaf9SJohnathan Mantey 
1748cd9a4666SKonstantin Aladyshev /**
1749c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1750491d8ee7SSantosh Puranik  *
1751491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1752491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1753cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1754491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1755491d8ee7SSantosh Puranik  *
1756265c1602SJohnathan Mantey  * @return Integer error code.
1757491d8ee7SSantosh Puranik  */
1758c21865c4SKonstantin Aladyshev 
1759c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1760c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1761c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1762c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1763491d8ee7SSantosh Puranik {
1764491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1765491d8ee7SSantosh Puranik 
1766c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1767c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1768c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1769491d8ee7SSantosh Puranik }
1770491d8ee7SSantosh Puranik 
1771c6a620f2SGeorge Liu /**
177298e386ecSGunnar Mills  * @brief Sets AssetTag
177398e386ecSGunnar Mills  *
177498e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
177598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
177698e386ecSGunnar Mills  *
177798e386ecSGunnar Mills  * @return None.
177898e386ecSGunnar Mills  */
17798d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
178098e386ecSGunnar Mills                         const std::string& assetTag)
178198e386ecSGunnar Mills {
178298e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
178398e386ecSGunnar Mills         [aResp, assetTag](
178498e386ecSGunnar Mills             const boost::system::error_code ec,
178598e386ecSGunnar Mills             const std::vector<std::pair<
178698e386ecSGunnar Mills                 std::string,
178798e386ecSGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
178898e386ecSGunnar Mills                 subtree) {
178998e386ecSGunnar Mills             if (ec)
179098e386ecSGunnar Mills             {
179198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
179298e386ecSGunnar Mills                 messages::internalError(aResp->res);
179398e386ecSGunnar Mills                 return;
179498e386ecSGunnar Mills             }
179598e386ecSGunnar Mills             if (subtree.size() == 0)
179698e386ecSGunnar Mills             {
179798e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
179898e386ecSGunnar Mills                 messages::internalError(aResp->res);
179998e386ecSGunnar Mills                 return;
180098e386ecSGunnar Mills             }
180198e386ecSGunnar Mills             // Assume only 1 system D-Bus object
180298e386ecSGunnar Mills             // Throw an error if there is more than 1
180398e386ecSGunnar Mills             if (subtree.size() > 1)
180498e386ecSGunnar Mills             {
180598e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
180698e386ecSGunnar Mills                 messages::internalError(aResp->res);
180798e386ecSGunnar Mills                 return;
180898e386ecSGunnar Mills             }
180998e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
181098e386ecSGunnar Mills             {
181198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
181298e386ecSGunnar Mills                 messages::internalError(aResp->res);
181398e386ecSGunnar Mills                 return;
181498e386ecSGunnar Mills             }
181598e386ecSGunnar Mills 
181698e386ecSGunnar Mills             const std::string& path = subtree[0].first;
181798e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
181898e386ecSGunnar Mills 
181998e386ecSGunnar Mills             if (service.empty())
182098e386ecSGunnar Mills             {
182198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
182298e386ecSGunnar Mills                 messages::internalError(aResp->res);
182398e386ecSGunnar Mills                 return;
182498e386ecSGunnar Mills             }
182598e386ecSGunnar Mills 
182698e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
182798e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
182898e386ecSGunnar Mills                     if (ec2)
182998e386ecSGunnar Mills                     {
183098e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
183198e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
183298e386ecSGunnar Mills                         messages::internalError(aResp->res);
183398e386ecSGunnar Mills                         return;
183498e386ecSGunnar Mills                     }
183598e386ecSGunnar Mills                 },
183698e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
183798e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1838*168e20c1SEd Tanous                 dbus::utility::DbusVariantType(assetTag));
183998e386ecSGunnar Mills         },
184098e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
184198e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
184298e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
184398e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
184498e386ecSGunnar Mills         std::array<const char*, 1>{
184598e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
184698e386ecSGunnar Mills }
184798e386ecSGunnar Mills 
184898e386ecSGunnar Mills /**
184969f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
185069f35306SGunnar Mills  *
185169f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
185269f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
185369f35306SGunnar Mills  *
185469f35306SGunnar Mills  * @return None.
185569f35306SGunnar Mills  */
18568d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1857f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
185869f35306SGunnar Mills {
185969f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
186069f35306SGunnar Mills 
186169f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
186269f35306SGunnar Mills     bool autoRebootEnabled;
186369f35306SGunnar Mills 
186469f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
186569f35306SGunnar Mills     {
186669f35306SGunnar Mills         autoRebootEnabled = false;
186769f35306SGunnar Mills     }
186869f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
186969f35306SGunnar Mills     {
187069f35306SGunnar Mills         autoRebootEnabled = true;
187169f35306SGunnar Mills     }
187269f35306SGunnar Mills     else
187369f35306SGunnar Mills     {
18740fda0f12SGeorge Liu         BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
187569f35306SGunnar Mills                          << automaticRetryConfig;
187669f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
187769f35306SGunnar Mills                                          "AutomaticRetryConfig");
187869f35306SGunnar Mills         return;
187969f35306SGunnar Mills     }
188069f35306SGunnar Mills 
188169f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
188269f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
188369f35306SGunnar Mills             if (ec)
188469f35306SGunnar Mills             {
188569f35306SGunnar Mills                 messages::internalError(aResp->res);
188669f35306SGunnar Mills                 return;
188769f35306SGunnar Mills             }
188869f35306SGunnar Mills         },
188969f35306SGunnar Mills         "xyz.openbmc_project.Settings",
189069f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
189169f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
189269f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1893*168e20c1SEd Tanous         dbus::utility::DbusVariantType(autoRebootEnabled));
189469f35306SGunnar Mills }
189569f35306SGunnar Mills 
189669f35306SGunnar Mills /**
1897c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1898c6a620f2SGeorge Liu  *
1899c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1900c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1901c6a620f2SGeorge Liu  *
1902c6a620f2SGeorge Liu  * @return None.
1903c6a620f2SGeorge Liu  */
19048d1b46d7Szhanghch05 inline void
19058d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19064e69c904SGunnar Mills                           const std::string& policy)
1907c6a620f2SGeorge Liu {
1908c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1909c6a620f2SGeorge Liu 
1910c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
19110fda0f12SGeorge Liu         {"AlwaysOn",
19120fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
19130fda0f12SGeorge Liu         {"AlwaysOff",
19140fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
19150fda0f12SGeorge Liu         {"LastState",
19160fda0f12SGeorge Liu          "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
1917c6a620f2SGeorge Liu 
1918c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1919c6a620f2SGeorge Liu 
19204e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1921c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1922c6a620f2SGeorge Liu     {
19234e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19244e69c904SGunnar Mills                                          "PowerRestorePolicy");
1925c6a620f2SGeorge Liu         return;
1926c6a620f2SGeorge Liu     }
1927c6a620f2SGeorge Liu 
1928c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1929c6a620f2SGeorge Liu 
1930c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1931c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1932c6a620f2SGeorge Liu             if (ec)
1933c6a620f2SGeorge Liu             {
1934c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1935c6a620f2SGeorge Liu                 return;
1936c6a620f2SGeorge Liu             }
1937c6a620f2SGeorge Liu         },
1938c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1939c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1940c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1941c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1942*168e20c1SEd Tanous         dbus::utility::DbusVariantType(powerRestorPolicy));
1943c6a620f2SGeorge Liu }
1944c6a620f2SGeorge Liu 
1945a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1946a6349918SAppaRao Puli /**
1947a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1948a6349918SAppaRao Puli  *
1949a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1950a6349918SAppaRao Puli  *
1951a6349918SAppaRao Puli  * @return None.
1952a6349918SAppaRao Puli  */
19538d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1954a6349918SAppaRao Puli {
1955a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1956a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1957a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
19581214b7e7SGunnar Mills                 const std::vector<std::pair<std::string, VariantType>>&
19591214b7e7SGunnar Mills                     propertiesList) {
1960b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1961b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
196250626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
196350626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
196450626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
196550626f4fSJames Feist 
1966a6349918SAppaRao Puli             if (ec)
1967a6349918SAppaRao Puli             {
1968a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1969b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1970b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1971a6349918SAppaRao Puli                 return;
1972a6349918SAppaRao Puli             }
1973a6349918SAppaRao Puli 
1974a6349918SAppaRao Puli             const bool* provState = nullptr;
1975a6349918SAppaRao Puli             const bool* lockState = nullptr;
1976a6349918SAppaRao Puli             for (const std::pair<std::string, VariantType>& property :
1977a6349918SAppaRao Puli                  propertiesList)
1978a6349918SAppaRao Puli             {
1979a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
1980a6349918SAppaRao Puli                 {
1981a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
1982a6349918SAppaRao Puli                 }
1983a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
1984a6349918SAppaRao Puli                 {
1985a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
1986a6349918SAppaRao Puli                 }
1987a6349918SAppaRao Puli             }
1988a6349918SAppaRao Puli 
1989a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1990a6349918SAppaRao Puli             {
1991a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1992a6349918SAppaRao Puli                 messages::internalError(aResp->res);
1993a6349918SAppaRao Puli                 return;
1994a6349918SAppaRao Puli             }
1995a6349918SAppaRao Puli 
1996a6349918SAppaRao Puli             if (*provState == true)
1997a6349918SAppaRao Puli             {
1998a6349918SAppaRao Puli                 if (*lockState == true)
1999a6349918SAppaRao Puli                 {
2000a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2001a6349918SAppaRao Puli                 }
2002a6349918SAppaRao Puli                 else
2003a6349918SAppaRao Puli                 {
2004a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2005a6349918SAppaRao Puli                 }
2006a6349918SAppaRao Puli             }
2007a6349918SAppaRao Puli             else
2008a6349918SAppaRao Puli             {
2009a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2010a6349918SAppaRao Puli             }
2011a6349918SAppaRao Puli         },
2012a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2013a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
2014a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
2015a6349918SAppaRao Puli }
2016a6349918SAppaRao Puli #endif
2017a6349918SAppaRao Puli 
2018491d8ee7SSantosh Puranik /**
20193a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20203a2d0424SChris Cain  *
20213a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20223a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20233a2d0424SChris Cain  *
20243a2d0424SChris Cain  * @return None.
20253a2d0424SChris Cain  */
20263a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20273a2d0424SChris Cain                                const std::string& modeValue)
20283a2d0424SChris Cain {
20293a2d0424SChris Cain     std::string modeString;
20303a2d0424SChris Cain 
20310fda0f12SGeorge Liu     if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
20323a2d0424SChris Cain     {
20333a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20343a2d0424SChris Cain     }
20350fda0f12SGeorge Liu     else if (
20360fda0f12SGeorge Liu         modeValue ==
20370fda0f12SGeorge Liu         "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
20383a2d0424SChris Cain     {
20393a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20403a2d0424SChris Cain     }
20410fda0f12SGeorge Liu     else if (modeValue ==
20420fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
20433a2d0424SChris Cain     {
20443a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20453a2d0424SChris Cain     }
20460fda0f12SGeorge Liu     else if (modeValue ==
20470fda0f12SGeorge Liu              "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
20483a2d0424SChris Cain     {
20493a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20503a2d0424SChris Cain     }
20513a2d0424SChris Cain     else
20523a2d0424SChris Cain     {
20533a2d0424SChris Cain         // Any other values would be invalid
20543a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20553a2d0424SChris Cain         messages::internalError(aResp->res);
20563a2d0424SChris Cain     }
20573a2d0424SChris Cain }
20583a2d0424SChris Cain 
20593a2d0424SChris Cain /**
20603a2d0424SChris Cain  * @brief Retrieves system power mode
20613a2d0424SChris Cain  *
20623a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20633a2d0424SChris Cain  *
20643a2d0424SChris Cain  * @return None.
20653a2d0424SChris Cain  */
20663a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20673a2d0424SChris Cain {
20683a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20693a2d0424SChris Cain 
20703a2d0424SChris Cain     // Get Power Mode object path:
20713a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
20723a2d0424SChris Cain         [aResp](
20733a2d0424SChris Cain             const boost::system::error_code ec,
20743a2d0424SChris Cain             const std::vector<std::pair<
20753a2d0424SChris Cain                 std::string,
20763a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
20773a2d0424SChris Cain                 subtree) {
20783a2d0424SChris Cain             if (ec)
20793a2d0424SChris Cain             {
20803a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20813a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
20823a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
20833a2d0424SChris Cain                 // error occurs
20843a2d0424SChris Cain                 return;
20853a2d0424SChris Cain             }
20863a2d0424SChris Cain             if (subtree.empty())
20873a2d0424SChris Cain             {
20883a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
20893a2d0424SChris Cain                 // if there is no instance found
20903a2d0424SChris Cain                 return;
20913a2d0424SChris Cain             }
20923a2d0424SChris Cain             if (subtree.size() > 1)
20933a2d0424SChris Cain             {
20943a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
20953a2d0424SChris Cain                 // error
20963a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20973a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
20983a2d0424SChris Cain                     << subtree.size();
20993a2d0424SChris Cain                 messages::internalError(aResp->res);
21003a2d0424SChris Cain                 return;
21013a2d0424SChris Cain             }
21023a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21033a2d0424SChris Cain             {
21043a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21053a2d0424SChris Cain                 messages::internalError(aResp->res);
21063a2d0424SChris Cain                 return;
21073a2d0424SChris Cain             }
21083a2d0424SChris Cain             const std::string& path = subtree[0].first;
21093a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21103a2d0424SChris Cain             if (service.empty())
21113a2d0424SChris Cain             {
21123a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21133a2d0424SChris Cain                 messages::internalError(aResp->res);
21143a2d0424SChris Cain                 return;
21153a2d0424SChris Cain             }
21163a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
21173a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
21183a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
2119*168e20c1SEd Tanous                         const dbus::utility::DbusVariantType& pmode) {
21203a2d0424SChris Cain                     if (ec)
21213a2d0424SChris Cain                     {
21223a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
21233a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
21243a2d0424SChris Cain                         messages::internalError(aResp->res);
21253a2d0424SChris Cain                         return;
21263a2d0424SChris Cain                     }
21273a2d0424SChris Cain 
21283a2d0424SChris Cain                     const std::string* s = std::get_if<std::string>(&pmode);
21293a2d0424SChris Cain                     if (s == nullptr)
21303a2d0424SChris Cain                     {
21313a2d0424SChris Cain                         BMCWEB_LOG_DEBUG << "Unable to get PowerMode value";
21323a2d0424SChris Cain                         messages::internalError(aResp->res);
21333a2d0424SChris Cain                         return;
21343a2d0424SChris Cain                     }
21353a2d0424SChris Cain 
21363a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
21373a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
21383a2d0424SChris Cain 
21393a2d0424SChris Cain                     BMCWEB_LOG_DEBUG << "Current power mode: " << *s;
21403a2d0424SChris Cain                     translatePowerMode(aResp, *s);
21413a2d0424SChris Cain                 },
21423a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Get",
21433a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode");
21443a2d0424SChris Cain         },
21453a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21463a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21473a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21483a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21493a2d0424SChris Cain }
21503a2d0424SChris Cain 
21513a2d0424SChris Cain /**
21523a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21533a2d0424SChris Cain  * name associated with that string
21543a2d0424SChris Cain  *
21553a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21563a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21573a2d0424SChris Cain  *
21583a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21593a2d0424SChris Cain  */
21603a2d0424SChris Cain inline std::string
21613a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21623a2d0424SChris Cain                       const std::string& modeString)
21633a2d0424SChris Cain {
21643a2d0424SChris Cain     std::string mode;
21653a2d0424SChris Cain 
21663a2d0424SChris Cain     if (modeString == "Static")
21673a2d0424SChris Cain     {
21683a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21693a2d0424SChris Cain     }
21703a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21713a2d0424SChris Cain     {
21720fda0f12SGeorge Liu         mode =
21730fda0f12SGeorge Liu             "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
21743a2d0424SChris Cain     }
21753a2d0424SChris Cain     else if (modeString == "PowerSaving")
21763a2d0424SChris Cain     {
21773a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21783a2d0424SChris Cain     }
21793a2d0424SChris Cain     else
21803a2d0424SChris Cain     {
21813a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21823a2d0424SChris Cain     }
21833a2d0424SChris Cain     return mode;
21843a2d0424SChris Cain }
21853a2d0424SChris Cain 
21863a2d0424SChris Cain /**
21873a2d0424SChris Cain  * @brief Sets system power mode.
21883a2d0424SChris Cain  *
21893a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21903a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21913a2d0424SChris Cain  *
21923a2d0424SChris Cain  * @return None.
21933a2d0424SChris Cain  */
21943a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21953a2d0424SChris Cain                          const std::string& pmode)
21963a2d0424SChris Cain {
21973a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
21983a2d0424SChris Cain 
21993a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
22003a2d0424SChris Cain     if (powerMode.empty())
22013a2d0424SChris Cain     {
22023a2d0424SChris Cain         return;
22033a2d0424SChris Cain     }
22043a2d0424SChris Cain 
22053a2d0424SChris Cain     // Get Power Mode object path:
22063a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
22073a2d0424SChris Cain         [aResp, powerMode](
22083a2d0424SChris Cain             const boost::system::error_code ec,
22093a2d0424SChris Cain             const std::vector<std::pair<
22103a2d0424SChris Cain                 std::string,
22113a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
22123a2d0424SChris Cain                 subtree) {
22133a2d0424SChris Cain             if (ec)
22143a2d0424SChris Cain             {
22153a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22163a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
22173a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22183a2d0424SChris Cain                 messages::internalError(aResp->res);
22193a2d0424SChris Cain                 return;
22203a2d0424SChris Cain             }
22213a2d0424SChris Cain             if (subtree.empty())
22223a2d0424SChris Cain             {
22233a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22243a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
22253a2d0424SChris Cain                                            "PowerMode");
22263a2d0424SChris Cain                 return;
22273a2d0424SChris Cain             }
22283a2d0424SChris Cain             if (subtree.size() > 1)
22293a2d0424SChris Cain             {
22303a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22313a2d0424SChris Cain                 // error
22323a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22333a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
22343a2d0424SChris Cain                     << subtree.size();
22353a2d0424SChris Cain                 messages::internalError(aResp->res);
22363a2d0424SChris Cain                 return;
22373a2d0424SChris Cain             }
22383a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22393a2d0424SChris Cain             {
22403a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22413a2d0424SChris Cain                 messages::internalError(aResp->res);
22423a2d0424SChris Cain                 return;
22433a2d0424SChris Cain             }
22443a2d0424SChris Cain             const std::string& path = subtree[0].first;
22453a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22463a2d0424SChris Cain             if (service.empty())
22473a2d0424SChris Cain             {
22483a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22493a2d0424SChris Cain                 messages::internalError(aResp->res);
22503a2d0424SChris Cain                 return;
22513a2d0424SChris Cain             }
22523a2d0424SChris Cain 
22533a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22543a2d0424SChris Cain                              << path;
22553a2d0424SChris Cain 
22563a2d0424SChris Cain             // Set the Power Mode property
22573a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
22583a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
22593a2d0424SChris Cain                     if (ec)
22603a2d0424SChris Cain                     {
22613a2d0424SChris Cain                         messages::internalError(aResp->res);
22623a2d0424SChris Cain                         return;
22633a2d0424SChris Cain                     }
22643a2d0424SChris Cain                 },
22653a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
22663a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2267*168e20c1SEd Tanous                 dbus::utility::DbusVariantType(powerMode));
22683a2d0424SChris Cain         },
22693a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
22703a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
22713a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
22723a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
22733a2d0424SChris Cain }
22743a2d0424SChris Cain 
22753a2d0424SChris Cain /**
227651709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
227751709ffdSYong Li  *
227851709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
227951709ffdSYong Li  *
228051709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
228151709ffdSYong Li  * translation cannot be done, returns an empty string.
228251709ffdSYong Li  */
228323a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
228451709ffdSYong Li {
228551709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
228651709ffdSYong Li     {
228751709ffdSYong Li         return "None";
228851709ffdSYong Li     }
22893174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
229051709ffdSYong Li     {
229151709ffdSYong Li         return "ResetSystem";
229251709ffdSYong Li     }
22933174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
229451709ffdSYong Li     {
229551709ffdSYong Li         return "PowerDown";
229651709ffdSYong Li     }
22973174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
229851709ffdSYong Li     {
229951709ffdSYong Li         return "PowerCycle";
230051709ffdSYong Li     }
230151709ffdSYong Li 
230251709ffdSYong Li     return "";
230351709ffdSYong Li }
230451709ffdSYong Li 
230551709ffdSYong Li /**
2306c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2307c45f0082SYong Li  *
2308c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2309c45f0082SYong Li  *
2310c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2311c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2312c45f0082SYong Li  */
2313c45f0082SYong Li 
231423a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2315c45f0082SYong Li {
2316c45f0082SYong Li     if (rfAction == "None")
2317c45f0082SYong Li     {
2318c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2319c45f0082SYong Li     }
23203174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2321c45f0082SYong Li     {
2322c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2323c45f0082SYong Li     }
23243174e4dfSEd Tanous     if (rfAction == "PowerDown")
2325c45f0082SYong Li     {
2326c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2327c45f0082SYong Li     }
23283174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2329c45f0082SYong Li     {
2330c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2331c45f0082SYong Li     }
2332c45f0082SYong Li 
2333c45f0082SYong Li     return "";
2334c45f0082SYong Li }
2335c45f0082SYong Li 
2336c45f0082SYong Li /**
233751709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
233851709ffdSYong Li  *
233951709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
234051709ffdSYong Li  *
234151709ffdSYong Li  * @return None.
234251709ffdSYong Li  */
23438d1b46d7Szhanghch05 inline void
23448d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
234551709ffdSYong Li {
234651709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
234751709ffdSYong Li     crow::connections::systemBus->async_method_call(
234851709ffdSYong Li         [aResp](const boost::system::error_code ec,
234951709ffdSYong Li                 PropertiesType& properties) {
235051709ffdSYong Li             if (ec)
235151709ffdSYong Li             {
235251709ffdSYong Li                 // watchdog service is stopped
235351709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
235451709ffdSYong Li                 return;
235551709ffdSYong Li             }
235651709ffdSYong Li 
235751709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
235851709ffdSYong Li 
235951709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
236051709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
236151709ffdSYong Li 
236251709ffdSYong Li             // watchdog service is running/enabled
236351709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
236451709ffdSYong Li 
236551709ffdSYong Li             for (const auto& property : properties)
236651709ffdSYong Li             {
236751709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
236851709ffdSYong Li                 if (property.first == "Enabled")
236951709ffdSYong Li                 {
237051709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
237151709ffdSYong Li 
237251709ffdSYong Li                     if (!state)
237351709ffdSYong Li                     {
237451709ffdSYong Li                         messages::internalError(aResp->res);
2375601af5edSChicago Duan                         return;
237651709ffdSYong Li                     }
237751709ffdSYong Li 
237851709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
237951709ffdSYong Li                 }
238051709ffdSYong Li                 else if (property.first == "ExpireAction")
238151709ffdSYong Li                 {
238251709ffdSYong Li                     const std::string* s =
238351709ffdSYong Li                         std::get_if<std::string>(&property.second);
238451709ffdSYong Li                     if (!s)
238551709ffdSYong Li                     {
238651709ffdSYong Li                         messages::internalError(aResp->res);
2387601af5edSChicago Duan                         return;
238851709ffdSYong Li                     }
238951709ffdSYong Li 
239051709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
239151709ffdSYong Li                     if (action.empty())
239251709ffdSYong Li                     {
239351709ffdSYong Li                         messages::internalError(aResp->res);
2394601af5edSChicago Duan                         return;
239551709ffdSYong Li                     }
239651709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
239751709ffdSYong Li                 }
239851709ffdSYong Li             }
239951709ffdSYong Li         },
240051709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
240151709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
240251709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
240351709ffdSYong Li }
240451709ffdSYong Li 
240551709ffdSYong Li /**
2406c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2407c45f0082SYong Li  *
2408c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2409c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2410c45f0082SYong Li  *                       RF request.
2411c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2412c45f0082SYong Li  *
2413c45f0082SYong Li  * @return None.
2414c45f0082SYong Li  */
24158d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2416c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2417c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2418c45f0082SYong Li {
2419c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2420c45f0082SYong Li 
2421c45f0082SYong Li     if (wdtTimeOutAction)
2422c45f0082SYong Li     {
2423c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2424c45f0082SYong Li         // check if TimeOut Action is Valid
2425c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2426c45f0082SYong Li         {
2427c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2428c45f0082SYong Li                              << *wdtTimeOutAction;
2429c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2430c45f0082SYong Li                                              "TimeoutAction");
2431c45f0082SYong Li             return;
2432c45f0082SYong Li         }
2433c45f0082SYong Li 
2434c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2435c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2436c45f0082SYong Li                 if (ec)
2437c45f0082SYong Li                 {
2438c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2439c45f0082SYong Li                     messages::internalError(aResp->res);
2440c45f0082SYong Li                     return;
2441c45f0082SYong Li                 }
2442c45f0082SYong Li             },
2443c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2444c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2445c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2446c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2447*168e20c1SEd Tanous             dbus::utility::DbusVariantType(wdtTimeOutActStr));
2448c45f0082SYong Li     }
2449c45f0082SYong Li 
2450c45f0082SYong Li     if (wdtEnable)
2451c45f0082SYong Li     {
2452c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2453c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2454c45f0082SYong Li                 if (ec)
2455c45f0082SYong Li                 {
2456c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2457c45f0082SYong Li                     messages::internalError(aResp->res);
2458c45f0082SYong Li                     return;
2459c45f0082SYong Li                 }
2460c45f0082SYong Li             },
2461c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2462c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2463c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2464c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2465*168e20c1SEd Tanous             dbus::utility::DbusVariantType(*wdtEnable));
2466c45f0082SYong Li     }
2467c45f0082SYong Li }
2468c45f0082SYong Li 
246937bbf98cSChris Cain using ipsPropertiesType =
247037bbf98cSChris Cain     std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>;
247137bbf98cSChris Cain /**
247237bbf98cSChris Cain  * @brief Parse the Idle Power Saver properties into json
247337bbf98cSChris Cain  *
247437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
247537bbf98cSChris Cain  * @param[in] properties  IPS property data from DBus.
247637bbf98cSChris Cain  *
247737bbf98cSChris Cain  * @return true if successful
247837bbf98cSChris Cain  */
2479f6674220SEd Tanous inline bool parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
248037bbf98cSChris Cain                                ipsPropertiesType& properties)
248137bbf98cSChris Cain {
248237bbf98cSChris Cain     for (const auto& property : properties)
248337bbf98cSChris Cain     {
248437bbf98cSChris Cain         if (property.first == "Enabled")
248537bbf98cSChris Cain         {
248637bbf98cSChris Cain             const bool* state = std::get_if<bool>(&property.second);
248737bbf98cSChris Cain             if (!state)
248837bbf98cSChris Cain             {
248937bbf98cSChris Cain                 return false;
249037bbf98cSChris Cain             }
249137bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *state;
249237bbf98cSChris Cain         }
249337bbf98cSChris Cain         else if (property.first == "EnterUtilizationPercent")
249437bbf98cSChris Cain         {
249537bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
249637bbf98cSChris Cain             if (!util)
249737bbf98cSChris Cain             {
249837bbf98cSChris Cain                 return false;
249937bbf98cSChris Cain             }
250037bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
250137bbf98cSChris Cain         }
250237bbf98cSChris Cain         else if (property.first == "EnterDwellTime")
250337bbf98cSChris Cain         {
250437bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
250537bbf98cSChris Cain             const uint64_t* timeMilliseconds =
250637bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
250737bbf98cSChris Cain             if (!timeMilliseconds)
250837bbf98cSChris Cain             {
250937bbf98cSChris Cain                 return false;
251037bbf98cSChris Cain             }
251137bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
251237bbf98cSChris Cain                 *timeMilliseconds);
251337bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
251437bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
251537bbf98cSChris Cain                     .count();
251637bbf98cSChris Cain         }
251737bbf98cSChris Cain         else if (property.first == "ExitUtilizationPercent")
251837bbf98cSChris Cain         {
251937bbf98cSChris Cain             const uint8_t* util = std::get_if<uint8_t>(&property.second);
252037bbf98cSChris Cain             if (!util)
252137bbf98cSChris Cain             {
252237bbf98cSChris Cain                 return false;
252337bbf98cSChris Cain             }
252437bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"][property.first] = *util;
252537bbf98cSChris Cain         }
252637bbf98cSChris Cain         else if (property.first == "ExitDwellTime")
252737bbf98cSChris Cain         {
252837bbf98cSChris Cain             // Convert Dbus time from milliseconds to seconds
252937bbf98cSChris Cain             const uint64_t* timeMilliseconds =
253037bbf98cSChris Cain                 std::get_if<uint64_t>(&property.second);
253137bbf98cSChris Cain             if (!timeMilliseconds)
253237bbf98cSChris Cain             {
253337bbf98cSChris Cain                 return false;
253437bbf98cSChris Cain             }
253537bbf98cSChris Cain             const std::chrono::duration<uint64_t, std::milli> ms(
253637bbf98cSChris Cain                 *timeMilliseconds);
253737bbf98cSChris Cain             aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
253837bbf98cSChris Cain                 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
253937bbf98cSChris Cain                     .count();
254037bbf98cSChris Cain         }
254137bbf98cSChris Cain         else
254237bbf98cSChris Cain         {
254337bbf98cSChris Cain             BMCWEB_LOG_WARNING << "Unexpected IdlePowerSaver property: "
254437bbf98cSChris Cain                                << property.first;
254537bbf98cSChris Cain         }
254637bbf98cSChris Cain     }
254737bbf98cSChris Cain 
254837bbf98cSChris Cain     return true;
254937bbf98cSChris Cain }
255037bbf98cSChris Cain 
255137bbf98cSChris Cain /**
255237bbf98cSChris Cain  * @brief Retrieves host watchdog timer properties over DBUS
255337bbf98cSChris Cain  *
255437bbf98cSChris Cain  * @param[in] aResp     Shared pointer for completing asynchronous calls.
255537bbf98cSChris Cain  *
255637bbf98cSChris Cain  * @return None.
255737bbf98cSChris Cain  */
255837bbf98cSChris Cain inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
255937bbf98cSChris Cain {
256037bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
256137bbf98cSChris Cain 
256237bbf98cSChris Cain     // Get IdlePowerSaver object path:
256337bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
256437bbf98cSChris Cain         [aResp](
256537bbf98cSChris Cain             const boost::system::error_code ec,
256637bbf98cSChris Cain             const std::vector<std::pair<
256737bbf98cSChris Cain                 std::string,
256837bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
256937bbf98cSChris Cain                 subtree) {
257037bbf98cSChris Cain             if (ec)
257137bbf98cSChris Cain             {
257237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
257337bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
257437bbf98cSChris Cain                     << ec;
257537bbf98cSChris Cain                 messages::internalError(aResp->res);
257637bbf98cSChris Cain                 return;
257737bbf98cSChris Cain             }
257837bbf98cSChris Cain             if (subtree.empty())
257937bbf98cSChris Cain             {
258037bbf98cSChris Cain                 // This is an optional interface so just return
258137bbf98cSChris Cain                 // if there is no instance found
258237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "No instances found";
258337bbf98cSChris Cain                 return;
258437bbf98cSChris Cain             }
258537bbf98cSChris Cain             if (subtree.size() > 1)
258637bbf98cSChris Cain             {
258737bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
258837bbf98cSChris Cain                 // is an error
258937bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
259037bbf98cSChris Cain                                     "Power.IdlePowerSaver objects: "
259137bbf98cSChris Cain                                  << subtree.size();
259237bbf98cSChris Cain                 messages::internalError(aResp->res);
259337bbf98cSChris Cain                 return;
259437bbf98cSChris Cain             }
259537bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
259637bbf98cSChris Cain             {
259737bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
259837bbf98cSChris Cain                 messages::internalError(aResp->res);
259937bbf98cSChris Cain                 return;
260037bbf98cSChris Cain             }
260137bbf98cSChris Cain             const std::string& path = subtree[0].first;
260237bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
260337bbf98cSChris Cain             if (service.empty())
260437bbf98cSChris Cain             {
260537bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
260637bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
260737bbf98cSChris Cain                 messages::internalError(aResp->res);
260837bbf98cSChris Cain                 return;
260937bbf98cSChris Cain             }
261037bbf98cSChris Cain 
261137bbf98cSChris Cain             // Valid IdlePowerSaver object found, now read the current values
261237bbf98cSChris Cain             crow::connections::systemBus->async_method_call(
261337bbf98cSChris Cain                 [aResp](const boost::system::error_code ec,
261437bbf98cSChris Cain                         ipsPropertiesType& properties) {
261537bbf98cSChris Cain                     if (ec)
261637bbf98cSChris Cain                     {
261737bbf98cSChris Cain                         BMCWEB_LOG_ERROR
261837bbf98cSChris Cain                             << "DBUS response error on IdlePowerSaver GetAll: "
261937bbf98cSChris Cain                             << ec;
262037bbf98cSChris Cain                         messages::internalError(aResp->res);
262137bbf98cSChris Cain                         return;
262237bbf98cSChris Cain                     }
262337bbf98cSChris Cain 
262437bbf98cSChris Cain                     if (parseIpsProperties(aResp, properties) == false)
262537bbf98cSChris Cain                     {
262637bbf98cSChris Cain                         messages::internalError(aResp->res);
262737bbf98cSChris Cain                         return;
262837bbf98cSChris Cain                     }
262937bbf98cSChris Cain                 },
263037bbf98cSChris Cain                 service, path, "org.freedesktop.DBus.Properties", "GetAll",
263137bbf98cSChris Cain                 "xyz.openbmc_project.Control.Power.IdlePowerSaver");
263237bbf98cSChris Cain         },
263337bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
263437bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
263537bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
263637bbf98cSChris Cain         std::array<const char*, 1>{
263737bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
263837bbf98cSChris Cain 
263937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
264037bbf98cSChris Cain }
264137bbf98cSChris Cain 
264237bbf98cSChris Cain /**
264337bbf98cSChris Cain  * @brief Sets Idle Power Saver properties.
264437bbf98cSChris Cain  *
264537bbf98cSChris Cain  * @param[in] aResp      Shared pointer for generating response message.
264637bbf98cSChris Cain  * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
264737bbf98cSChris Cain  *                       RF request.
264837bbf98cSChris Cain  * @param[in] ipsEnterUtil The utilization limit to enter idle state.
264937bbf98cSChris Cain  * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
265037bbf98cSChris Cain  * before entering idle state.
265137bbf98cSChris Cain  * @param[in] ipsExitUtil The utilization limit when exiting idle state.
265237bbf98cSChris Cain  * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
265337bbf98cSChris Cain  * before exiting idle state
265437bbf98cSChris Cain  *
265537bbf98cSChris Cain  * @return None.
265637bbf98cSChris Cain  */
265737bbf98cSChris Cain inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
265837bbf98cSChris Cain                               const std::optional<bool> ipsEnable,
265937bbf98cSChris Cain                               const std::optional<uint8_t> ipsEnterUtil,
266037bbf98cSChris Cain                               const std::optional<uint64_t> ipsEnterTime,
266137bbf98cSChris Cain                               const std::optional<uint8_t> ipsExitUtil,
266237bbf98cSChris Cain                               const std::optional<uint64_t> ipsExitTime)
266337bbf98cSChris Cain {
266437bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "Set idle power saver properties";
266537bbf98cSChris Cain 
266637bbf98cSChris Cain     // Get IdlePowerSaver object path:
266737bbf98cSChris Cain     crow::connections::systemBus->async_method_call(
266837bbf98cSChris Cain         [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
266937bbf98cSChris Cain          ipsExitTime](
267037bbf98cSChris Cain             const boost::system::error_code ec,
267137bbf98cSChris Cain             const std::vector<std::pair<
267237bbf98cSChris Cain                 std::string,
267337bbf98cSChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
267437bbf98cSChris Cain                 subtree) {
267537bbf98cSChris Cain             if (ec)
267637bbf98cSChris Cain             {
267737bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
267837bbf98cSChris Cain                     << "DBUS response error on Power.IdlePowerSaver GetSubTree "
267937bbf98cSChris Cain                     << ec;
268037bbf98cSChris Cain                 messages::internalError(aResp->res);
268137bbf98cSChris Cain                 return;
268237bbf98cSChris Cain             }
268337bbf98cSChris Cain             if (subtree.empty())
268437bbf98cSChris Cain             {
268537bbf98cSChris Cain                 // This is an optional D-Bus object, but user attempted to patch
268637bbf98cSChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
268737bbf98cSChris Cain                                            "IdlePowerSaver");
268837bbf98cSChris Cain                 return;
268937bbf98cSChris Cain             }
269037bbf98cSChris Cain             if (subtree.size() > 1)
269137bbf98cSChris Cain             {
269237bbf98cSChris Cain                 // More then one PowerIdlePowerSaver object is not supported and
269337bbf98cSChris Cain                 // is an error
26940fda0f12SGeorge Liu                 BMCWEB_LOG_DEBUG
26950fda0f12SGeorge Liu                     << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
269637bbf98cSChris Cain                     << subtree.size();
269737bbf98cSChris Cain                 messages::internalError(aResp->res);
269837bbf98cSChris Cain                 return;
269937bbf98cSChris Cain             }
270037bbf98cSChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
270137bbf98cSChris Cain             {
270237bbf98cSChris Cain                 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
270337bbf98cSChris Cain                 messages::internalError(aResp->res);
270437bbf98cSChris Cain                 return;
270537bbf98cSChris Cain             }
270637bbf98cSChris Cain             const std::string& path = subtree[0].first;
270737bbf98cSChris Cain             const std::string& service = subtree[0].second.begin()->first;
270837bbf98cSChris Cain             if (service.empty())
270937bbf98cSChris Cain             {
271037bbf98cSChris Cain                 BMCWEB_LOG_DEBUG
271137bbf98cSChris Cain                     << "Power.IdlePowerSaver service mapper error!";
271237bbf98cSChris Cain                 messages::internalError(aResp->res);
271337bbf98cSChris Cain                 return;
271437bbf98cSChris Cain             }
271537bbf98cSChris Cain 
271637bbf98cSChris Cain             // Valid Power IdlePowerSaver object found, now set any values that
271737bbf98cSChris Cain             // need to be updated
271837bbf98cSChris Cain 
271937bbf98cSChris Cain             if (ipsEnable)
272037bbf98cSChris Cain             {
272137bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
272237bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
272337bbf98cSChris Cain                         if (ec)
272437bbf98cSChris Cain                         {
272537bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
272637bbf98cSChris Cain                             messages::internalError(aResp->res);
272737bbf98cSChris Cain                             return;
272837bbf98cSChris Cain                         }
272937bbf98cSChris Cain                     },
273037bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
273137bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2732*168e20c1SEd Tanous                     "Enabled", dbus::utility::DbusVariantType(*ipsEnable));
273337bbf98cSChris Cain             }
273437bbf98cSChris Cain             if (ipsEnterUtil)
273537bbf98cSChris Cain             {
273637bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
273737bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
273837bbf98cSChris Cain                         if (ec)
273937bbf98cSChris Cain                         {
274037bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
274137bbf98cSChris Cain                             messages::internalError(aResp->res);
274237bbf98cSChris Cain                             return;
274337bbf98cSChris Cain                         }
274437bbf98cSChris Cain                     },
274537bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
274637bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
274737bbf98cSChris Cain                     "EnterUtilizationPercent",
2748*168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsEnterUtil));
274937bbf98cSChris Cain             }
275037bbf98cSChris Cain             if (ipsEnterTime)
275137bbf98cSChris Cain             {
275237bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
275337bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
275437bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
275537bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
275637bbf98cSChris Cain                         if (ec)
275737bbf98cSChris Cain                         {
275837bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
275937bbf98cSChris Cain                             messages::internalError(aResp->res);
276037bbf98cSChris Cain                             return;
276137bbf98cSChris Cain                         }
276237bbf98cSChris Cain                     },
276337bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
276437bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2765*168e20c1SEd Tanous                     "EnterDwellTime",
2766*168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
276737bbf98cSChris Cain             }
276837bbf98cSChris Cain             if (ipsExitUtil)
276937bbf98cSChris Cain             {
277037bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
277137bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
277237bbf98cSChris Cain                         if (ec)
277337bbf98cSChris Cain                         {
277437bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
277537bbf98cSChris Cain                             messages::internalError(aResp->res);
277637bbf98cSChris Cain                             return;
277737bbf98cSChris Cain                         }
277837bbf98cSChris Cain                     },
277937bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
278037bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
278137bbf98cSChris Cain                     "ExitUtilizationPercent",
2782*168e20c1SEd Tanous                     dbus::utility::DbusVariantType(*ipsExitUtil));
278337bbf98cSChris Cain             }
278437bbf98cSChris Cain             if (ipsExitTime)
278537bbf98cSChris Cain             {
278637bbf98cSChris Cain                 // Convert from seconds into milliseconds for DBus
278737bbf98cSChris Cain                 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
278837bbf98cSChris Cain                 crow::connections::systemBus->async_method_call(
278937bbf98cSChris Cain                     [aResp](const boost::system::error_code ec) {
279037bbf98cSChris Cain                         if (ec)
279137bbf98cSChris Cain                         {
279237bbf98cSChris Cain                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
279337bbf98cSChris Cain                             messages::internalError(aResp->res);
279437bbf98cSChris Cain                             return;
279537bbf98cSChris Cain                         }
279637bbf98cSChris Cain                     },
279737bbf98cSChris Cain                     service, path, "org.freedesktop.DBus.Properties", "Set",
279837bbf98cSChris Cain                     "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2799*168e20c1SEd Tanous                     "ExitDwellTime",
2800*168e20c1SEd Tanous                     dbus::utility::DbusVariantType(timeMilliseconds));
280137bbf98cSChris Cain             }
280237bbf98cSChris Cain         },
280337bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper",
280437bbf98cSChris Cain         "/xyz/openbmc_project/object_mapper",
280537bbf98cSChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
280637bbf98cSChris Cain         std::array<const char*, 1>{
280737bbf98cSChris Cain             "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
280837bbf98cSChris Cain 
280937bbf98cSChris Cain     BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
281037bbf98cSChris Cain }
281137bbf98cSChris Cain 
2812c45f0082SYong Li /**
2813c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2814c5b2abe0SLewanczyk, Dawid  * Schema
2815c5b2abe0SLewanczyk, Dawid  */
28167e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
28171abe55efSEd Tanous {
28187e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2819ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
28207e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
28214f48d5f6SEd Tanous             [](const crow::Request& /*req*/,
28227e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28238d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
28240f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
28258d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
28268d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2827462023adSSunitha Harish 
2828462023adSSunitha Harish                 crow::connections::systemBus->async_method_call(
2829*168e20c1SEd Tanous                     [asyncResp](
2830*168e20c1SEd Tanous                         const boost::system::error_code ec,
2831*168e20c1SEd Tanous                         const dbus::utility::DbusVariantType& /*hostName*/) {
28322c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2833462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
28342c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
28357e860f15SJohn Edward Broadbent                         auto& count =
28367e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
28372c70f800SEd Tanous                         ifaceArray.push_back(
2838cb13a392SEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/system"}});
283994bda602STim Lee                         count = ifaceArray.size();
2840cb13a392SEd Tanous                         if (!ec)
2841462023adSSunitha Harish                         {
2842462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
28432c70f800SEd Tanous                             ifaceArray.push_back(
28447e860f15SJohn Edward Broadbent                                 {{"@odata.id",
28457e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/hypervisor"}});
28462c70f800SEd Tanous                             count = ifaceArray.size();
2847cb13a392SEd Tanous                         }
2848462023adSSunitha Harish                     },
28498e651fbfSSunitha Harish                     "xyz.openbmc_project.Settings",
28508e651fbfSSunitha Harish                     "/xyz/openbmc_project/network/hypervisor",
2851462023adSSunitha Harish                     "org.freedesktop.DBus.Properties", "Get",
28527e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.Network.SystemConfiguration",
28537e860f15SJohn Edward Broadbent                     "HostName");
28547e860f15SJohn Edward Broadbent             });
2855c5b2abe0SLewanczyk, Dawid }
28567e860f15SJohn Edward Broadbent 
28577e860f15SJohn Edward Broadbent /**
28587e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
28597e860f15SJohn Edward Broadbent  */
28604f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
28617e860f15SJohn Edward Broadbent {
28627e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
28637e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
28647e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
28657e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
28667e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
28677e860f15SJohn Edward Broadbent 
28687e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
28697e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
28707e860f15SJohn Edward Broadbent             if (ec)
28717e860f15SJohn Edward Broadbent             {
28727e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
28737e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
28747e860f15SJohn Edward Broadbent                 return;
28757e860f15SJohn Edward Broadbent             }
28767e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
28777e860f15SJohn Edward Broadbent         },
28787e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
28797e860f15SJohn Edward Broadbent }
2880c5b2abe0SLewanczyk, Dawid 
2881c5b2abe0SLewanczyk, Dawid /**
2882cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2883cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2884cc340dd9SEd Tanous  */
28857e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2886cc340dd9SEd Tanous {
2887cc340dd9SEd Tanous     /**
2888cc340dd9SEd Tanous      * Function handles POST method request.
2889cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2890cc340dd9SEd Tanous      */
28917e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
28927e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2893ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
28947e860f15SJohn Edward Broadbent         .methods(
28957e860f15SJohn Edward Broadbent             boost::beast::http::verb::
28967e860f15SJohn Edward Broadbent                 post)([](const crow::Request& req,
28977e860f15SJohn Edward Broadbent                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28989712f8acSEd Tanous             std::string resetType;
28997e860f15SJohn Edward Broadbent             if (!json_util::readJson(req, asyncResp->res, "ResetType",
29007e860f15SJohn Edward Broadbent                                      resetType))
2901cc340dd9SEd Tanous             {
2902cc340dd9SEd Tanous                 return;
2903cc340dd9SEd Tanous             }
2904cc340dd9SEd Tanous 
2905d22c8396SJason M. Bills             // Get the command and host vs. chassis
2906cc340dd9SEd Tanous             std::string command;
2907d22c8396SJason M. Bills             bool hostCommand;
2908d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2909cc340dd9SEd Tanous             {
2910cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2911d22c8396SJason M. Bills                 hostCommand = true;
2912d22c8396SJason M. Bills             }
2913d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2914d22c8396SJason M. Bills             {
2915d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2916d22c8396SJason M. Bills                 hostCommand = false;
2917d22c8396SJason M. Bills             }
2918d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2919d22c8396SJason M. Bills             {
292086a0851aSJason M. Bills                 command =
292186a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
292286a0851aSJason M. Bills                 hostCommand = true;
2923cc340dd9SEd Tanous             }
29249712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2925cc340dd9SEd Tanous             {
2926cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2927d22c8396SJason M. Bills                 hostCommand = true;
2928cc340dd9SEd Tanous             }
29299712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2930cc340dd9SEd Tanous             {
29310fda0f12SGeorge Liu                 command =
29320fda0f12SGeorge Liu                     "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2933d22c8396SJason M. Bills                 hostCommand = true;
2934d22c8396SJason M. Bills             }
2935d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2936d22c8396SJason M. Bills             {
293786a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
293886a0851aSJason M. Bills                 hostCommand = true;
2939cc340dd9SEd Tanous             }
2940bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2941bfd5b826SLakshminarayana R. Kammath             {
2942bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2943bfd5b826SLakshminarayana R. Kammath                 return;
2944bfd5b826SLakshminarayana R. Kammath             }
2945cc340dd9SEd Tanous             else
2946cc340dd9SEd Tanous             {
29478d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
29488d1b46d7Szhanghch05                                                  resetType);
2949cc340dd9SEd Tanous                 return;
2950cc340dd9SEd Tanous             }
2951cc340dd9SEd Tanous 
2952d22c8396SJason M. Bills             if (hostCommand)
2953d22c8396SJason M. Bills             {
2954cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2955d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2956cc340dd9SEd Tanous                         if (ec)
2957cc340dd9SEd Tanous                         {
2958cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
29597e860f15SJohn Edward Broadbent                             if (ec.value() ==
29607e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2961d22c8396SJason M. Bills                             {
2962d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2963d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2964d22c8396SJason M. Bills                             }
2965d22c8396SJason M. Bills                             else
2966d22c8396SJason M. Bills                             {
2967f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2968d22c8396SJason M. Bills                             }
2969cc340dd9SEd Tanous                             return;
2970cc340dd9SEd Tanous                         }
2971f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2972cc340dd9SEd Tanous                     },
2973cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2974cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2975cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
29769712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2977*168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
2978cc340dd9SEd Tanous             }
2979d22c8396SJason M. Bills             else
2980d22c8396SJason M. Bills             {
2981d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2982d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2983d22c8396SJason M. Bills                         if (ec)
2984d22c8396SJason M. Bills                         {
2985d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
29867e860f15SJohn Edward Broadbent                             if (ec.value() ==
29877e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2988d22c8396SJason M. Bills                             {
2989d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2990d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2991d22c8396SJason M. Bills                             }
2992d22c8396SJason M. Bills                             else
2993d22c8396SJason M. Bills                             {
2994d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2995d22c8396SJason M. Bills                             }
2996d22c8396SJason M. Bills                             return;
2997d22c8396SJason M. Bills                         }
2998d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2999d22c8396SJason M. Bills                     },
3000d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
3001d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
3002d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
30037e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
30047e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
3005*168e20c1SEd Tanous                     dbus::utility::DbusVariantType{command});
3006d22c8396SJason M. Bills             }
30077e860f15SJohn Edward Broadbent         });
3008d22c8396SJason M. Bills }
3009cc340dd9SEd Tanous 
3010cc340dd9SEd Tanous /**
30116617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
3012c5b2abe0SLewanczyk, Dawid  */
30137e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
30141abe55efSEd Tanous {
3015c5b2abe0SLewanczyk, Dawid 
3016c5b2abe0SLewanczyk, Dawid     /**
3017c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
3018c5b2abe0SLewanczyk, Dawid      */
30197e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3020ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
30217e860f15SJohn Edward Broadbent         .methods(
30227e860f15SJohn Edward Broadbent             boost::beast::http::verb::
30237e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
30247e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
30258d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
302637bbf98cSChris Cain                 "#ComputerSystem.v1_16_0.ComputerSystem";
30278d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
30288d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
30298d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
30308d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
30318d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
30328d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
30338d1b46d7Szhanghch05                 "Disabled";
30348d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
30358d1b46d7Szhanghch05                 uint64_t(0);
30368d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
30378d1b46d7Szhanghch05                 "Disabled";
30387e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
30397e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
304004a258f4SEd Tanous 
30418d1b46d7Szhanghch05             asyncResp->res.jsonValue["Processors"] = {
3042029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
30438d1b46d7Szhanghch05             asyncResp->res.jsonValue["Memory"] = {
3044029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
30458d1b46d7Szhanghch05             asyncResp->res.jsonValue["Storage"] = {
3046a25aeccfSNikhil Potade                 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
3047029573d4SEd Tanous 
30488d1b46d7Szhanghch05             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
3049cc340dd9SEd Tanous                 {"target",
3050029573d4SEd Tanous                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
30511cb1a9e6SAppaRao Puli                 {"@Redfish.ActionInfo",
30521cb1a9e6SAppaRao Puli                  "/redfish/v1/Systems/system/ResetActionInfo"}};
3053c5b2abe0SLewanczyk, Dawid 
30548d1b46d7Szhanghch05             asyncResp->res.jsonValue["LogServices"] = {
3055029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
3056c4bf6374SJason M. Bills 
30578d1b46d7Szhanghch05             asyncResp->res.jsonValue["Bios"] = {
3058d82a3acdSCarol Wang                 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
3059d82a3acdSCarol Wang 
30608d1b46d7Szhanghch05             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
3061c5d03ff4SJennifer Lee                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
3062c5d03ff4SJennifer Lee 
30638d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"] = {
3064c5d03ff4SJennifer Lee                 {"Health", "OK"},
3065c5d03ff4SJennifer Lee                 {"State", "Enabled"},
3066c5d03ff4SJennifer Lee             };
30670e8ac5e7SGunnar Mills 
30680e8ac5e7SGunnar Mills             // Fill in SerialConsole info
30690e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
30700e8ac5e7SGunnar Mills                 15;
30710e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
30720e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30730e8ac5e7SGunnar Mills             };
30740e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
30750e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
30760e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30770e8ac5e7SGunnar Mills                 {"Port", 2200},
30780e8ac5e7SGunnar Mills                 // https://github.com/openbmc/docs/blob/master/console.md
30790e8ac5e7SGunnar Mills                 {"HotKeySequenceDisplay", "Press ~. to exit console"},
30800e8ac5e7SGunnar Mills             };
30810e8ac5e7SGunnar Mills 
30820e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
30830e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
30840e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["GraphicalConsole"] = {
30850e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
30860e8ac5e7SGunnar Mills                 {"MaxConcurrentSessions", 4},
30870e8ac5e7SGunnar Mills                 {"ConnectTypesSupported", {"KVMIP"}},
30880e8ac5e7SGunnar Mills             };
30890e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
3090e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
3091b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
30922ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
3093e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
3094e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
3095b49ac873SJames Feist 
3096b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
3097b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
3098b49ac873SJames Feist                 [health](const boost::system::error_code ec,
3099b49ac873SJames Feist                          std::vector<std::string>& resp) {
3100b49ac873SJames Feist                     if (ec)
3101b49ac873SJames Feist                     {
3102b49ac873SJames Feist                         // no inventory
3103b49ac873SJames Feist                         return;
3104b49ac873SJames Feist                     }
3105b49ac873SJames Feist 
3106b49ac873SJames Feist                     health->inventory = std::move(resp);
3107b49ac873SJames Feist                 },
3108b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
3109b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
3110b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
3111b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
3112b49ac873SJames Feist 
3113b49ac873SJames Feist             health->populate();
3114b49ac873SJames Feist 
31158d1b46d7Szhanghch05             getMainChassisId(
31168d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
31178d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3118c5d03ff4SJennifer Lee                     aRsp->res.jsonValue["Links"]["Chassis"] = {
3119c5d03ff4SJennifer Lee                         {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
3120c5d03ff4SJennifer Lee                 });
3121a3002228SAppaRao Puli 
31229f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
31239f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3124a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
31255bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
31266c34de48SEd Tanous             getHostState(asyncResp);
3127491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
3128978b8803SAndrew Geissler             getBootProgress(asyncResp);
3129adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
313051709ffdSYong Li             getHostWatchdogTimer(asyncResp);
3131c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
31326bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
3133c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
3134a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
3135a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
3136a6349918SAppaRao Puli #endif
31371981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
31383a2d0424SChris Cain             getPowerMode(asyncResp);
313937bbf98cSChris Cain             getIdlePowerSaver(asyncResp);
31407e860f15SJohn Edward Broadbent         });
31417e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
3142ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
31437e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
31447e860f15SJohn Edward Broadbent             [](const crow::Request& req,
31457e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
31469f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
3147cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
3148491d8ee7SSantosh Puranik                 std::optional<nlohmann::json> bootProps;
3149c45f0082SYong Li                 std::optional<nlohmann::json> wdtTimerProps;
315098e386ecSGunnar Mills                 std::optional<std::string> assetTag;
3151c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
31523a2d0424SChris Cain                 std::optional<std::string> powerMode;
315337bbf98cSChris Cain                 std::optional<nlohmann::json> ipsProps;
31549f8bfa7cSGunnar Mills                 if (!json_util::readJson(
31558d1b46d7Szhanghch05                         req, asyncResp->res, "IndicatorLED", indicatorLed,
31567e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
31577e860f15SJohn Edward Broadbent                         "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
31587e860f15SJohn Edward Broadbent                         "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
315937bbf98cSChris Cain                         assetTag, "PowerMode", powerMode, "IdlePowerSaver",
316037bbf98cSChris Cain                         ipsProps))
31616617338dSEd Tanous                 {
31626617338dSEd Tanous                     return;
31636617338dSEd Tanous                 }
3164491d8ee7SSantosh Puranik 
31658d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
3166c45f0082SYong Li 
316798e386ecSGunnar Mills                 if (assetTag)
316898e386ecSGunnar Mills                 {
316998e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
317098e386ecSGunnar Mills                 }
317198e386ecSGunnar Mills 
3172c45f0082SYong Li                 if (wdtTimerProps)
3173c45f0082SYong Li                 {
3174c45f0082SYong Li                     std::optional<bool> wdtEnable;
3175c45f0082SYong Li                     std::optional<std::string> wdtTimeOutAction;
3176c45f0082SYong Li 
3177c45f0082SYong Li                     if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
3178c45f0082SYong Li                                              "FunctionEnabled", wdtEnable,
3179c45f0082SYong Li                                              "TimeoutAction", wdtTimeOutAction))
3180c45f0082SYong Li                     {
3181c45f0082SYong Li                         return;
3182c45f0082SYong Li                     }
3183f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3184c45f0082SYong Li                 }
3185c45f0082SYong Li 
3186491d8ee7SSantosh Puranik                 if (bootProps)
3187491d8ee7SSantosh Puranik                 {
3188491d8ee7SSantosh Puranik                     std::optional<std::string> bootSource;
3189cd9a4666SKonstantin Aladyshev                     std::optional<std::string> bootType;
3190491d8ee7SSantosh Puranik                     std::optional<std::string> bootEnable;
319169f35306SGunnar Mills                     std::optional<std::string> automaticRetryConfig;
3192ac7e1e0bSAli Ahmed                     std::optional<bool> trustedModuleRequiredToBoot;
3193491d8ee7SSantosh Puranik 
319469f35306SGunnar Mills                     if (!json_util::readJson(
31957e860f15SJohn Edward Broadbent                             *bootProps, asyncResp->res,
31967e860f15SJohn Edward Broadbent                             "BootSourceOverrideTarget", bootSource,
3197cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode", bootType,
31987e860f15SJohn Edward Broadbent                             "BootSourceOverrideEnabled", bootEnable,
3199ac7e1e0bSAli Ahmed                             "AutomaticRetryConfig", automaticRetryConfig,
3200ac7e1e0bSAli Ahmed                             "TrustedModuleRequiredToBoot",
3201ac7e1e0bSAli Ahmed                             trustedModuleRequiredToBoot))
3202491d8ee7SSantosh Puranik                     {
3203491d8ee7SSantosh Puranik                         return;
3204491d8ee7SSantosh Puranik                     }
3205c21865c4SKonstantin Aladyshev 
3206cd9a4666SKonstantin Aladyshev                     if (bootSource || bootType || bootEnable)
320769f35306SGunnar Mills                     {
3208c21865c4SKonstantin Aladyshev                         setBootProperties(asyncResp, bootSource, bootType,
3209c21865c4SKonstantin Aladyshev                                           bootEnable);
3210491d8ee7SSantosh Puranik                     }
321169f35306SGunnar Mills                     if (automaticRetryConfig)
321269f35306SGunnar Mills                     {
3213f23b7296SEd Tanous                         setAutomaticRetry(asyncResp, *automaticRetryConfig);
321469f35306SGunnar Mills                     }
3215ac7e1e0bSAli Ahmed 
3216ac7e1e0bSAli Ahmed                     if (trustedModuleRequiredToBoot)
3217ac7e1e0bSAli Ahmed                     {
3218ac7e1e0bSAli Ahmed                         setTrustedModuleRequiredToBoot(
3219ac7e1e0bSAli Ahmed                             asyncResp, *trustedModuleRequiredToBoot);
3220ac7e1e0bSAli Ahmed                     }
322169f35306SGunnar Mills                 }
3222265c1602SJohnathan Mantey 
32239f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
32249f8bfa7cSGunnar Mills                 {
32257e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
32267e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
32279f8bfa7cSGunnar Mills                 }
32289f8bfa7cSGunnar Mills 
32297e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
32307e860f15SJohn Edward Broadbent                 // passed
32319712f8acSEd Tanous                 if (indicatorLed)
32326617338dSEd Tanous                 {
3233f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
32347e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
32357e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
3236d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
3237d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
32386617338dSEd Tanous                 }
3239c6a620f2SGeorge Liu 
3240c6a620f2SGeorge Liu                 if (powerRestorePolicy)
3241c6a620f2SGeorge Liu                 {
32424e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3243c6a620f2SGeorge Liu                 }
32443a2d0424SChris Cain 
32453a2d0424SChris Cain                 if (powerMode)
32463a2d0424SChris Cain                 {
32473a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
32483a2d0424SChris Cain                 }
324937bbf98cSChris Cain 
325037bbf98cSChris Cain                 if (ipsProps)
325137bbf98cSChris Cain                 {
325237bbf98cSChris Cain                     std::optional<bool> ipsEnable;
325337bbf98cSChris Cain                     std::optional<uint8_t> ipsEnterUtil;
325437bbf98cSChris Cain                     std::optional<uint64_t> ipsEnterTime;
325537bbf98cSChris Cain                     std::optional<uint8_t> ipsExitUtil;
325637bbf98cSChris Cain                     std::optional<uint64_t> ipsExitTime;
325737bbf98cSChris Cain 
325837bbf98cSChris Cain                     if (!json_util::readJson(
325937bbf98cSChris Cain                             *ipsProps, asyncResp->res, "Enabled", ipsEnable,
326037bbf98cSChris Cain                             "EnterUtilizationPercent", ipsEnterUtil,
326137bbf98cSChris Cain                             "EnterDwellTimeSeconds", ipsEnterTime,
326237bbf98cSChris Cain                             "ExitUtilizationPercent", ipsExitUtil,
326337bbf98cSChris Cain                             "ExitDwellTimeSeconds", ipsExitTime))
326437bbf98cSChris Cain                     {
326537bbf98cSChris Cain                         return;
326637bbf98cSChris Cain                     }
326737bbf98cSChris Cain                     setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil,
326837bbf98cSChris Cain                                       ipsEnterTime, ipsExitUtil, ipsExitTime);
326937bbf98cSChris Cain                 }
32707e860f15SJohn Edward Broadbent             });
3271c5b2abe0SLewanczyk, Dawid }
32721cb1a9e6SAppaRao Puli 
32731cb1a9e6SAppaRao Puli /**
32741cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
32751cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
32761cb1a9e6SAppaRao Puli  */
32777e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
32781cb1a9e6SAppaRao Puli {
32791cb1a9e6SAppaRao Puli 
32801cb1a9e6SAppaRao Puli     /**
32811cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
32821cb1a9e6SAppaRao Puli      */
32837e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3284ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
32857e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
32867e860f15SJohn Edward Broadbent             [](const crow::Request&,
32877e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
32888d1b46d7Szhanghch05                 asyncResp->res.jsonValue = {
32891cb1a9e6SAppaRao Puli                     {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
32901cb1a9e6SAppaRao Puli                     {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
32911cb1a9e6SAppaRao Puli                     {"Name", "Reset Action Info"},
32921cb1a9e6SAppaRao Puli                     {"Id", "ResetActionInfo"},
32931cb1a9e6SAppaRao Puli                     {"Parameters",
32941cb1a9e6SAppaRao Puli                      {{{"Name", "ResetType"},
32951cb1a9e6SAppaRao Puli                        {"Required", true},
32961cb1a9e6SAppaRao Puli                        {"DataType", "String"},
32971cb1a9e6SAppaRao Puli                        {"AllowableValues",
32987e860f15SJohn Edward Broadbent                         {"On", "ForceOff", "ForceOn", "ForceRestart",
32997e860f15SJohn Edward Broadbent                          "GracefulRestart", "GracefulShutdown", "PowerCycle",
33007e860f15SJohn Edward Broadbent                          "Nmi"}}}}}};
33017e860f15SJohn Edward Broadbent             });
33021cb1a9e6SAppaRao Puli }
3303c5b2abe0SLewanczyk, Dawid } // namespace redfish
3304