xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 1c05dae3011628e5726eefc3ec4dbe7733fbb4d5)
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>
25ed398213SEd Tanous #include <registries/privilege_registry.hpp>
26cb7e1e7bSAndrew Geissler #include <utils/fw_utils.hpp>
27c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
281214b7e7SGunnar Mills 
29abf2add6SEd Tanous #include <variant>
30c5b2abe0SLewanczyk, Dawid 
311abe55efSEd Tanous namespace redfish
321abe55efSEd Tanous {
33c5b2abe0SLewanczyk, Dawid 
349d3ae10eSAlpana Kumari /**
359d3ae10eSAlpana Kumari  * @brief Updates the Functional State of DIMMs
369d3ae10eSAlpana Kumari  *
379d3ae10eSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
389d3ae10eSAlpana Kumari  * @param[in] dimmState Dimm's Functional state, true/false
399d3ae10eSAlpana Kumari  *
409d3ae10eSAlpana Kumari  * @return None.
419d3ae10eSAlpana Kumari  */
428d1b46d7Szhanghch05 inline void
438d1b46d7Szhanghch05     updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
449d3ae10eSAlpana Kumari                          const std::variant<bool>& dimmState)
459d3ae10eSAlpana Kumari {
469d3ae10eSAlpana Kumari     const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
479d3ae10eSAlpana Kumari     if (isDimmFunctional == nullptr)
489d3ae10eSAlpana Kumari     {
499d3ae10eSAlpana Kumari         messages::internalError(aResp->res);
509d3ae10eSAlpana Kumari         return;
519d3ae10eSAlpana Kumari     }
529d3ae10eSAlpana Kumari     BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
539d3ae10eSAlpana Kumari 
549d3ae10eSAlpana Kumari     // Set it as Enabled if at least one DIMM is functional
559d3ae10eSAlpana Kumari     // Update STATE only if previous State was DISABLED and current Dimm is
569d3ae10eSAlpana Kumari     // ENABLED.
579d3ae10eSAlpana Kumari     nlohmann::json& prevMemSummary =
589d3ae10eSAlpana Kumari         aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
599d3ae10eSAlpana Kumari     if (prevMemSummary == "Disabled")
609d3ae10eSAlpana Kumari     {
619d3ae10eSAlpana Kumari         if (*isDimmFunctional == true)
629d3ae10eSAlpana Kumari         {
639d3ae10eSAlpana Kumari             aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
649d3ae10eSAlpana Kumari                 "Enabled";
659d3ae10eSAlpana Kumari         }
669d3ae10eSAlpana Kumari     }
679d3ae10eSAlpana Kumari }
689d3ae10eSAlpana Kumari 
6957e8c9beSAlpana Kumari /*
7057e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
7157e8c9beSAlpana Kumari  *
7257e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
7357e8c9beSAlpana Kumari  * @param[in] cpuPresenceState CPU present or not
7457e8c9beSAlpana Kumari  *
7557e8c9beSAlpana Kumari  * @return None.
7657e8c9beSAlpana Kumari  */
778d1b46d7Szhanghch05 inline void
788d1b46d7Szhanghch05     modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
7957e8c9beSAlpana Kumari                            const std::variant<bool>& cpuPresenceState)
8057e8c9beSAlpana Kumari {
8157e8c9beSAlpana Kumari     const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
8257e8c9beSAlpana Kumari 
8357e8c9beSAlpana Kumari     if (isCpuPresent == nullptr)
8457e8c9beSAlpana Kumari     {
8557e8c9beSAlpana Kumari         messages::internalError(aResp->res);
8657e8c9beSAlpana Kumari         return;
8757e8c9beSAlpana Kumari     }
8857e8c9beSAlpana Kumari     BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
8957e8c9beSAlpana Kumari 
9057e8c9beSAlpana Kumari     if (*isCpuPresent == true)
9157e8c9beSAlpana Kumari     {
92b4b9595aSJames Feist         nlohmann::json& procCount =
93b4b9595aSJames Feist             aResp->res.jsonValue["ProcessorSummary"]["Count"];
94b4b9595aSJames Feist         auto procCountPtr =
95b4b9595aSJames Feist             procCount.get_ptr<nlohmann::json::number_integer_t*>();
96b4b9595aSJames Feist         if (procCountPtr != nullptr)
97b4b9595aSJames Feist         {
98b4b9595aSJames Feist             // shouldn't be possible to be nullptr
99b4b9595aSJames Feist             *procCountPtr += 1;
10057e8c9beSAlpana Kumari         }
101b4b9595aSJames Feist     }
10257e8c9beSAlpana Kumari }
10357e8c9beSAlpana Kumari 
10457e8c9beSAlpana Kumari /*
10557e8c9beSAlpana Kumari  * @brief Update "ProcessorSummary" "Status" "State" based on
10657e8c9beSAlpana Kumari  *        CPU Functional State
10757e8c9beSAlpana Kumari  *
10857e8c9beSAlpana Kumari  * @param[in] aResp Shared pointer for completing asynchronous calls
10957e8c9beSAlpana Kumari  * @param[in] cpuFunctionalState is CPU functional true/false
11057e8c9beSAlpana Kumari  *
11157e8c9beSAlpana Kumari  * @return None.
11257e8c9beSAlpana Kumari  */
11323a21a1cSEd Tanous inline void
1148d1b46d7Szhanghch05     modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
11557e8c9beSAlpana Kumari                              const std::variant<bool>& cpuFunctionalState)
11657e8c9beSAlpana Kumari {
11757e8c9beSAlpana Kumari     const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
11857e8c9beSAlpana Kumari 
11957e8c9beSAlpana Kumari     if (isCpuFunctional == nullptr)
12057e8c9beSAlpana Kumari     {
12157e8c9beSAlpana Kumari         messages::internalError(aResp->res);
12257e8c9beSAlpana Kumari         return;
12357e8c9beSAlpana Kumari     }
12457e8c9beSAlpana Kumari     BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
12557e8c9beSAlpana Kumari 
12657e8c9beSAlpana Kumari     nlohmann::json& prevProcState =
12757e8c9beSAlpana Kumari         aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
12857e8c9beSAlpana Kumari 
12957e8c9beSAlpana Kumari     // Set it as Enabled if at least one CPU is functional
13057e8c9beSAlpana Kumari     // Update STATE only if previous State was Non_Functional and current CPU is
13157e8c9beSAlpana Kumari     // Functional.
13257e8c9beSAlpana Kumari     if (prevProcState == "Disabled")
13357e8c9beSAlpana Kumari     {
13457e8c9beSAlpana Kumari         if (*isCpuFunctional == true)
13557e8c9beSAlpana Kumari         {
13657e8c9beSAlpana Kumari             aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
13757e8c9beSAlpana Kumari                 "Enabled";
13857e8c9beSAlpana Kumari         }
13957e8c9beSAlpana Kumari     }
14057e8c9beSAlpana Kumari }
14157e8c9beSAlpana Kumari 
14257e8c9beSAlpana Kumari /*
143c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
144c5b2abe0SLewanczyk, Dawid  *
145c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
1468f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
147c5b2abe0SLewanczyk, Dawid  *
148c5b2abe0SLewanczyk, Dawid  * @return None.
149c5b2abe0SLewanczyk, Dawid  */
150b5a76932SEd Tanous inline void
1518d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
152b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
1531abe55efSEd Tanous {
15455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
1559d3ae10eSAlpana Kumari 
15655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
1575bc2dc8eSJames Feist         [aResp, systemHealth](
158c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
159c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
1606c34de48SEd Tanous                 std::string,
1611214b7e7SGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1621214b7e7SGunnar Mills                 subtree) {
1631abe55efSEd Tanous             if (ec)
1641abe55efSEd Tanous             {
16555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
166f12894f8SJason M. Bills                 messages::internalError(aResp->res);
167c5b2abe0SLewanczyk, Dawid                 return;
168c5b2abe0SLewanczyk, Dawid             }
169c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
1706c34de48SEd Tanous             for (const std::pair<std::string,
1716c34de48SEd Tanous                                  std::vector<std::pair<
1721214b7e7SGunnar Mills                                      std::string, std::vector<std::string>>>>&
1731214b7e7SGunnar Mills                      object : subtree)
1741abe55efSEd Tanous             {
175c5b2abe0SLewanczyk, Dawid                 const std::string& path = object.first;
17655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
1771abe55efSEd Tanous                 const std::vector<
1781214b7e7SGunnar Mills                     std::pair<std::string, std::vector<std::string>>>&
1791214b7e7SGunnar Mills                     connectionNames = object.second;
1801abe55efSEd Tanous                 if (connectionNames.size() < 1)
1811abe55efSEd Tanous                 {
182c5b2abe0SLewanczyk, Dawid                     continue;
183c5b2abe0SLewanczyk, Dawid                 }
184029573d4SEd Tanous 
1855bc2dc8eSJames Feist                 auto memoryHealth = std::make_shared<HealthPopulate>(
1865bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
1875bc2dc8eSJames Feist 
1885bc2dc8eSJames Feist                 auto cpuHealth = std::make_shared<HealthPopulate>(
1895bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
1905bc2dc8eSJames Feist 
1915bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
1925bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
1935bc2dc8eSJames Feist 
1946c34de48SEd Tanous                 // This is not system, so check if it's cpu, dimm, UUID or
1956c34de48SEd Tanous                 // BiosVer
19604a258f4SEd Tanous                 for (const auto& connection : connectionNames)
1971abe55efSEd Tanous                 {
19804a258f4SEd Tanous                     for (const auto& interfaceName : connection.second)
1991abe55efSEd Tanous                     {
20004a258f4SEd Tanous                         if (interfaceName ==
20104a258f4SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm")
2021abe55efSEd Tanous                         {
2031abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
20404a258f4SEd Tanous                                 << "Found Dimm, now get its properties.";
2059d3ae10eSAlpana Kumari 
20655c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
2079d3ae10eSAlpana Kumari                                 [aResp, service{connection.first},
208f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
2096c34de48SEd Tanous                                        const std::vector<
2101214b7e7SGunnar Mills                                            std::pair<std::string, VariantType>>&
2111214b7e7SGunnar Mills                                            properties) {
212cb13a392SEd Tanous                                     if (ec2)
2131abe55efSEd Tanous                                     {
2141abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
215cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
216f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
217c5b2abe0SLewanczyk, Dawid                                         return;
218c5b2abe0SLewanczyk, Dawid                                     }
2196c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
2206c34de48SEd Tanous                                                      << properties.size()
221c5b2abe0SLewanczyk, Dawid                                                      << " Dimm properties.";
2229d3ae10eSAlpana Kumari 
2239d3ae10eSAlpana Kumari                                     if (properties.size() > 0)
2249d3ae10eSAlpana Kumari                                     {
22504a258f4SEd Tanous                                         for (const std::pair<std::string,
2261214b7e7SGunnar Mills                                                              VariantType>&
2271214b7e7SGunnar Mills                                                  property : properties)
2281abe55efSEd Tanous                                         {
2295fd7ba65SCheng C Yang                                             if (property.first !=
2305fd7ba65SCheng C Yang                                                 "MemorySizeInKB")
2311abe55efSEd Tanous                                             {
2325fd7ba65SCheng C Yang                                                 continue;
2335fd7ba65SCheng C Yang                                             }
2345fd7ba65SCheng C Yang                                             const uint32_t* value =
2358d78b7a9SPatrick Williams                                                 std::get_if<uint32_t>(
2361b6b96c5SEd Tanous                                                     &property.second);
2375fd7ba65SCheng C Yang                                             if (value == nullptr)
2381abe55efSEd Tanous                                             {
2395fd7ba65SCheng C Yang                                                 BMCWEB_LOG_DEBUG
2405fd7ba65SCheng C Yang                                                     << "Find incorrect type of "
2415fd7ba65SCheng C Yang                                                        "MemorySize";
2425fd7ba65SCheng C Yang                                                 continue;
2435fd7ba65SCheng C Yang                                             }
2445fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
2455fd7ba65SCheng C Yang                                                 aResp->res
2465fd7ba65SCheng C Yang                                                     .jsonValue["MemorySummar"
2475fd7ba65SCheng C Yang                                                                "y"]
2485fd7ba65SCheng C Yang                                                               ["TotalSystemMe"
2495fd7ba65SCheng C Yang                                                                "moryGiB"];
2505fd7ba65SCheng C Yang                                             uint64_t* preValue =
2515fd7ba65SCheng C Yang                                                 totalMemory
2525fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
2535fd7ba65SCheng C Yang                                             if (preValue == nullptr)
2545fd7ba65SCheng C Yang                                             {
2555fd7ba65SCheng C Yang                                                 continue;
2565fd7ba65SCheng C Yang                                             }
2575fd7ba65SCheng C Yang                                             aResp->res
2585fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
2596c34de48SEd Tanous                                                           ["TotalSystemMemoryGi"
2605fd7ba65SCheng C Yang                                                            "B"] =
2615fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
2625fd7ba65SCheng C Yang                                                 *preValue;
2635fd7ba65SCheng C Yang                                             aResp->res
2645fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
2659d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
2661abe55efSEd Tanous                                                 "Enabled";
267c5b2abe0SLewanczyk, Dawid                                         }
268c5b2abe0SLewanczyk, Dawid                                     }
2699d3ae10eSAlpana Kumari                                     else
2709d3ae10eSAlpana Kumari                                     {
2719d3ae10eSAlpana Kumari                                         auto getDimmProperties =
2729d3ae10eSAlpana Kumari                                             [aResp](
2739d3ae10eSAlpana Kumari                                                 const boost::system::error_code
274cb13a392SEd Tanous                                                     ec3,
2751214b7e7SGunnar Mills                                                 const std::variant<bool>&
2761214b7e7SGunnar Mills                                                     dimmState) {
277cb13a392SEd Tanous                                                 if (ec3)
2789d3ae10eSAlpana Kumari                                                 {
2799d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
2809d3ae10eSAlpana Kumari                                                         << "DBUS response "
2819d3ae10eSAlpana Kumari                                                            "error "
282cb13a392SEd Tanous                                                         << ec3;
2839d3ae10eSAlpana Kumari                                                     return;
2849d3ae10eSAlpana Kumari                                                 }
2859d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
2869d3ae10eSAlpana Kumari                                                                      dimmState);
2879d3ae10eSAlpana Kumari                                             };
2889d3ae10eSAlpana Kumari                                         crow::connections::systemBus
2899d3ae10eSAlpana Kumari                                             ->async_method_call(
2909d3ae10eSAlpana Kumari                                                 std::move(getDimmProperties),
2919d3ae10eSAlpana Kumari                                                 service, path,
2929d3ae10eSAlpana Kumari                                                 "org.freedesktop.DBus."
2939d3ae10eSAlpana Kumari                                                 "Properties",
2949d3ae10eSAlpana Kumari                                                 "Get",
2959d3ae10eSAlpana Kumari                                                 "xyz.openbmc_project.State."
2969d3ae10eSAlpana Kumari                                                 "Decorator.OperationalStatus",
2979d3ae10eSAlpana Kumari                                                 "Functional");
2989d3ae10eSAlpana Kumari                                     }
299c5b2abe0SLewanczyk, Dawid                                 },
30004a258f4SEd Tanous                                 connection.first, path,
3016c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
3026c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
3035bc2dc8eSJames Feist 
3045bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
3051abe55efSEd Tanous                         }
30604a258f4SEd Tanous                         else if (interfaceName ==
30704a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
3081abe55efSEd Tanous                         {
3091abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
31004a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
31157e8c9beSAlpana Kumari 
312a0803efaSEd Tanous                             crow::connections::systemBus->async_method_call(
31357e8c9beSAlpana Kumari                                 [aResp, service{connection.first},
314f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
3156c34de48SEd Tanous                                        const std::vector<
3161214b7e7SGunnar Mills                                            std::pair<std::string, VariantType>>&
3171214b7e7SGunnar Mills                                            properties) {
318cb13a392SEd Tanous                                     if (ec2)
3191abe55efSEd Tanous                                     {
3201abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
321cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
322f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
323c5b2abe0SLewanczyk, Dawid                                         return;
324c5b2abe0SLewanczyk, Dawid                                     }
3256c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
3266c34de48SEd Tanous                                                      << properties.size()
327c5b2abe0SLewanczyk, Dawid                                                      << " Cpu properties.";
32857e8c9beSAlpana Kumari 
32957e8c9beSAlpana Kumari                                     if (properties.size() > 0)
33057e8c9beSAlpana Kumari                                     {
3319cf21522SZhikui Ren                                         const uint64_t* processorId = nullptr;
332029cc1f4SZhikui Ren                                         const std::string* procFamily = nullptr;
333029cc1f4SZhikui Ren                                         nlohmann::json& procSummary =
334029cc1f4SZhikui Ren                                             aResp->res.jsonValue["ProcessorSumm"
33504a258f4SEd Tanous                                                                  "ary"];
33604a258f4SEd Tanous                                         nlohmann::json& procCount =
33704a258f4SEd Tanous                                             procSummary["Count"];
338b4b9595aSJames Feist 
339029cc1f4SZhikui Ren                                         auto procCountPtr = procCount.get_ptr<
340b4b9595aSJames Feist                                             nlohmann::json::
3411214b7e7SGunnar Mills                                                 number_integer_t*>();
342029cc1f4SZhikui Ren                                         if (procCountPtr == nullptr)
343b4b9595aSJames Feist                                         {
344029cc1f4SZhikui Ren                                             messages::internalError(aResp->res);
345029cc1f4SZhikui Ren                                             return;
346029cc1f4SZhikui Ren                                         }
347029cc1f4SZhikui Ren                                         for (const auto& property : properties)
348029cc1f4SZhikui Ren                                         {
349029cc1f4SZhikui Ren 
3509cf21522SZhikui Ren                                             if (property.first == "Id")
351029cc1f4SZhikui Ren                                             {
352029cc1f4SZhikui Ren                                                 processorId =
3539cf21522SZhikui Ren                                                     std::get_if<uint64_t>(
354029cc1f4SZhikui Ren                                                         &property.second);
355029cc1f4SZhikui Ren                                                 if (nullptr != procFamily)
3563174e4dfSEd Tanous                                                 {
357029cc1f4SZhikui Ren                                                     break;
3583174e4dfSEd Tanous                                                 }
359029cc1f4SZhikui Ren                                                 continue;
360029cc1f4SZhikui Ren                                             }
361029cc1f4SZhikui Ren 
3629cf21522SZhikui Ren                                             if (property.first == "Family")
363029cc1f4SZhikui Ren                                             {
364029cc1f4SZhikui Ren                                                 procFamily =
365029cc1f4SZhikui Ren                                                     std::get_if<std::string>(
366029cc1f4SZhikui Ren                                                         &property.second);
367029cc1f4SZhikui Ren                                                 if (nullptr != processorId)
3683174e4dfSEd Tanous                                                 {
369029cc1f4SZhikui Ren                                                     break;
3703174e4dfSEd Tanous                                                 }
371029cc1f4SZhikui Ren                                                 continue;
372029cc1f4SZhikui Ren                                             }
373029cc1f4SZhikui Ren                                         }
374029cc1f4SZhikui Ren 
375029cc1f4SZhikui Ren                                         if (procFamily != nullptr &&
376029cc1f4SZhikui Ren                                             processorId != nullptr)
377029cc1f4SZhikui Ren                                         {
378029cc1f4SZhikui Ren                                             if (procCountPtr != nullptr &&
379029cc1f4SZhikui Ren                                                 *processorId != 0)
380029cc1f4SZhikui Ren                                             {
381b4b9595aSJames Feist                                                 *procCountPtr += 1;
382029cc1f4SZhikui Ren                                                 procSummary["Status"]["State"] =
383c5b2abe0SLewanczyk, Dawid                                                     "Enabled";
384029cc1f4SZhikui Ren 
38557e8c9beSAlpana Kumari                                                 procSummary["Model"] =
386029cc1f4SZhikui Ren                                                     *procFamily;
387c5b2abe0SLewanczyk, Dawid                                             }
388c5b2abe0SLewanczyk, Dawid                                         }
38957e8c9beSAlpana Kumari                                     }
39057e8c9beSAlpana Kumari                                     else
39157e8c9beSAlpana Kumari                                     {
39257e8c9beSAlpana Kumari                                         auto getCpuPresenceState =
39357e8c9beSAlpana Kumari                                             [aResp](
39457e8c9beSAlpana Kumari                                                 const boost::system::error_code
395cb13a392SEd Tanous                                                     ec3,
3961214b7e7SGunnar Mills                                                 const std::variant<bool>&
3971214b7e7SGunnar Mills                                                     cpuPresenceCheck) {
398cb13a392SEd Tanous                                                 if (ec3)
39957e8c9beSAlpana Kumari                                                 {
40057e8c9beSAlpana Kumari                                                     BMCWEB_LOG_ERROR
40157e8c9beSAlpana Kumari                                                         << "DBUS response "
40257e8c9beSAlpana Kumari                                                            "error "
403cb13a392SEd Tanous                                                         << ec3;
40457e8c9beSAlpana Kumari                                                     return;
40557e8c9beSAlpana Kumari                                                 }
40657e8c9beSAlpana Kumari                                                 modifyCpuPresenceState(
40757e8c9beSAlpana Kumari                                                     aResp, cpuPresenceCheck);
40857e8c9beSAlpana Kumari                                             };
40957e8c9beSAlpana Kumari 
41057e8c9beSAlpana Kumari                                         auto getCpuFunctionalState =
41157e8c9beSAlpana Kumari                                             [aResp](
41257e8c9beSAlpana Kumari                                                 const boost::system::error_code
413cb13a392SEd Tanous                                                     ec3,
4141214b7e7SGunnar Mills                                                 const std::variant<bool>&
4151214b7e7SGunnar Mills                                                     cpuFunctionalCheck) {
416cb13a392SEd Tanous                                                 if (ec3)
41757e8c9beSAlpana Kumari                                                 {
41857e8c9beSAlpana Kumari                                                     BMCWEB_LOG_ERROR
41957e8c9beSAlpana Kumari                                                         << "DBUS response "
42057e8c9beSAlpana Kumari                                                            "error "
421cb13a392SEd Tanous                                                         << ec3;
42257e8c9beSAlpana Kumari                                                     return;
42357e8c9beSAlpana Kumari                                                 }
42457e8c9beSAlpana Kumari                                                 modifyCpuFunctionalState(
42557e8c9beSAlpana Kumari                                                     aResp, cpuFunctionalCheck);
42657e8c9beSAlpana Kumari                                             };
42757e8c9beSAlpana Kumari                                         // Get the Presence of CPU
42857e8c9beSAlpana Kumari                                         crow::connections::systemBus
42957e8c9beSAlpana Kumari                                             ->async_method_call(
43057e8c9beSAlpana Kumari                                                 std::move(getCpuPresenceState),
43157e8c9beSAlpana Kumari                                                 service, path,
43257e8c9beSAlpana Kumari                                                 "org.freedesktop.DBus."
43357e8c9beSAlpana Kumari                                                 "Properties",
43457e8c9beSAlpana Kumari                                                 "Get",
43557e8c9beSAlpana Kumari                                                 "xyz.openbmc_project.Inventory."
43657e8c9beSAlpana Kumari                                                 "Item",
43757e8c9beSAlpana Kumari                                                 "Present");
43857e8c9beSAlpana Kumari 
43957e8c9beSAlpana Kumari                                         // Get the Functional State
44057e8c9beSAlpana Kumari                                         crow::connections::systemBus
44157e8c9beSAlpana Kumari                                             ->async_method_call(
44257e8c9beSAlpana Kumari                                                 std::move(
44357e8c9beSAlpana Kumari                                                     getCpuFunctionalState),
44457e8c9beSAlpana Kumari                                                 service, path,
44557e8c9beSAlpana Kumari                                                 "org.freedesktop.DBus."
44657e8c9beSAlpana Kumari                                                 "Properties",
44757e8c9beSAlpana Kumari                                                 "Get",
44857e8c9beSAlpana Kumari                                                 "xyz.openbmc_project.State."
44957e8c9beSAlpana Kumari                                                 "Decorator."
45057e8c9beSAlpana Kumari                                                 "OperationalStatus",
45157e8c9beSAlpana Kumari                                                 "Functional");
45257e8c9beSAlpana Kumari 
45357e8c9beSAlpana Kumari                                         // Get the MODEL from
45457e8c9beSAlpana Kumari                                         // xyz.openbmc_project.Inventory.Decorator.Asset
45557e8c9beSAlpana Kumari                                         // support it later as Model  is Empty
45657e8c9beSAlpana Kumari                                         // currently.
45757e8c9beSAlpana Kumari                                     }
458c5b2abe0SLewanczyk, Dawid                                 },
45904a258f4SEd Tanous                                 connection.first, path,
4606c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4616c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Cpu");
4625bc2dc8eSJames Feist 
4635bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4641abe55efSEd Tanous                         }
46504a258f4SEd Tanous                         else if (interfaceName ==
46604a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
4671abe55efSEd Tanous                         {
4681abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
46904a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
47055c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
4711214b7e7SGunnar Mills                                 [aResp](
472cb13a392SEd Tanous                                     const boost::system::error_code ec3,
4736c34de48SEd Tanous                                     const std::vector<
4741214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
4751214b7e7SGunnar Mills                                         properties) {
476cb13a392SEd Tanous                                     if (ec3)
4771abe55efSEd Tanous                                     {
4781abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
479cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
480f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
481c5b2abe0SLewanczyk, Dawid                                         return;
482c5b2abe0SLewanczyk, Dawid                                     }
4836c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4846c34de48SEd Tanous                                                      << properties.size()
485c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
4861abe55efSEd Tanous                                     for (const std::pair<std::string,
4871214b7e7SGunnar Mills                                                          VariantType>&
4881214b7e7SGunnar Mills                                              property : properties)
4891abe55efSEd Tanous                                     {
49004a258f4SEd Tanous                                         if (property.first == "UUID")
4911abe55efSEd Tanous                                         {
492c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4938d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4941b6b96c5SEd Tanous                                                     &property.second);
49504a258f4SEd Tanous 
4961abe55efSEd Tanous                                             if (value != nullptr)
4971abe55efSEd Tanous                                             {
498029573d4SEd Tanous                                                 std::string valueStr = *value;
49904a258f4SEd Tanous                                                 if (valueStr.size() == 32)
5001abe55efSEd Tanous                                                 {
501029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
502029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
503029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
504029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
50504a258f4SEd Tanous                                                 }
506029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
50704a258f4SEd Tanous                                                                  << valueStr;
508029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
50904a258f4SEd Tanous                                                     valueStr;
510c5b2abe0SLewanczyk, Dawid                                             }
511c5b2abe0SLewanczyk, Dawid                                         }
512c5b2abe0SLewanczyk, Dawid                                     }
513c5b2abe0SLewanczyk, Dawid                                 },
51404a258f4SEd Tanous                                 connection.first, path,
5156c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
5161abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
517c5b2abe0SLewanczyk, Dawid                         }
518029573d4SEd Tanous                         else if (interfaceName ==
519029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
5201abe55efSEd Tanous                         {
521029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
5221214b7e7SGunnar Mills                                 [aResp](
523cb13a392SEd Tanous                                     const boost::system::error_code ec2,
524029573d4SEd Tanous                                     const std::vector<
5251214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
5261214b7e7SGunnar Mills                                         propertiesList) {
527cb13a392SEd Tanous                                     if (ec2)
528029573d4SEd Tanous                                     {
529e4a4b9a9SJames Feist                                         // doesn't have to include this
530e4a4b9a9SJames Feist                                         // interface
531029573d4SEd Tanous                                         return;
532029573d4SEd Tanous                                     }
533698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
534698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
535029573d4SEd Tanous                                         << " properties for system";
536029573d4SEd Tanous                                     for (const std::pair<std::string,
5371214b7e7SGunnar Mills                                                          VariantType>&
5381214b7e7SGunnar Mills                                              property : propertiesList)
539029573d4SEd Tanous                                     {
540fc5afcf9Sbeccabroek                                         const std::string& propertyName =
541fc5afcf9Sbeccabroek                                             property.first;
542fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
543fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
544fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
5455235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
5465235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
547fc5afcf9Sbeccabroek                                         {
548029573d4SEd Tanous                                             const std::string* value =
549fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
550029573d4SEd Tanous                                                     &property.second);
551029573d4SEd Tanous                                             if (value != nullptr)
552029573d4SEd Tanous                                             {
553029573d4SEd Tanous                                                 aResp->res
554fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
555029573d4SEd Tanous                                                     *value;
556029573d4SEd Tanous                                             }
557029573d4SEd Tanous                                         }
558fc5afcf9Sbeccabroek                                     }
559c1e236a6SGunnar Mills 
560cb7e1e7bSAndrew Geissler                                     // Grab the bios version
561f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
562cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
56372d566d9SGunnar Mills                                         "BiosVersion", false);
564029573d4SEd Tanous                                 },
565029573d4SEd Tanous                                 connection.first, path,
566029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
567029573d4SEd Tanous                                 "xyz.openbmc_project.Inventory.Decorator."
568029573d4SEd Tanous                                 "Asset");
569e4a4b9a9SJames Feist 
570e4a4b9a9SJames Feist                             crow::connections::systemBus->async_method_call(
571e4a4b9a9SJames Feist                                 [aResp](
572cb13a392SEd Tanous                                     const boost::system::error_code ec2,
573e4a4b9a9SJames Feist                                     const std::variant<std::string>& property) {
574cb13a392SEd Tanous                                     if (ec2)
575e4a4b9a9SJames Feist                                     {
576e4a4b9a9SJames Feist                                         // doesn't have to include this
577e4a4b9a9SJames Feist                                         // interface
578e4a4b9a9SJames Feist                                         return;
579e4a4b9a9SJames Feist                                     }
580e4a4b9a9SJames Feist 
581e4a4b9a9SJames Feist                                     const std::string* value =
582e4a4b9a9SJames Feist                                         std::get_if<std::string>(&property);
583e4a4b9a9SJames Feist                                     if (value != nullptr)
584e4a4b9a9SJames Feist                                     {
585e4a4b9a9SJames Feist                                         aResp->res.jsonValue["AssetTag"] =
586e4a4b9a9SJames Feist                                             *value;
587e4a4b9a9SJames Feist                                     }
588e4a4b9a9SJames Feist                                 },
589e4a4b9a9SJames Feist                                 connection.first, path,
590e4a4b9a9SJames Feist                                 "org.freedesktop.DBus.Properties", "Get",
591e4a4b9a9SJames Feist                                 "xyz.openbmc_project.Inventory.Decorator."
592e4a4b9a9SJames Feist                                 "AssetTag",
593e4a4b9a9SJames Feist                                 "AssetTag");
594029573d4SEd Tanous                         }
595029573d4SEd Tanous                     }
596029573d4SEd Tanous                 }
597c5b2abe0SLewanczyk, Dawid             }
598c5b2abe0SLewanczyk, Dawid         },
599c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
600c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
601c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
6026617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
6036617338dSEd Tanous         std::array<const char*, 5>{
6046617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
6056617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
6066617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
6076617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
6086617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
6096617338dSEd Tanous         });
610c5b2abe0SLewanczyk, Dawid }
611c5b2abe0SLewanczyk, Dawid 
612c5b2abe0SLewanczyk, Dawid /**
613c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
614c5b2abe0SLewanczyk, Dawid  *
615c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
616c5b2abe0SLewanczyk, Dawid  *
617c5b2abe0SLewanczyk, Dawid  * @return None.
618c5b2abe0SLewanczyk, Dawid  */
6198d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
6201abe55efSEd Tanous {
62155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
62255c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
623c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
624abf2add6SEd Tanous                 const std::variant<std::string>& hostState) {
6251abe55efSEd Tanous             if (ec)
6261abe55efSEd Tanous             {
62755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
628f12894f8SJason M. Bills                 messages::internalError(aResp->res);
629c5b2abe0SLewanczyk, Dawid                 return;
630c5b2abe0SLewanczyk, Dawid             }
6316617338dSEd Tanous 
632abf2add6SEd Tanous             const std::string* s = std::get_if<std::string>(&hostState);
63355c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
6346617338dSEd Tanous             if (s != nullptr)
6351abe55efSEd Tanous             {
636c5b2abe0SLewanczyk, Dawid                 // Verify Host State
63794732661SAndrew Geissler                 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
6381abe55efSEd Tanous                 {
63955c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
6406617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
6411abe55efSEd Tanous                 }
64283935af9SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6438c888608SGunnar Mills                                "Quiesced")
6448c888608SGunnar Mills                 {
6458c888608SGunnar Mills                     aResp->res.jsonValue["PowerState"] = "On";
6468c888608SGunnar Mills                     aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6478c888608SGunnar Mills                 }
6488c888608SGunnar Mills                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
64983935af9SAndrew Geissler                                "DiagnosticMode")
65083935af9SAndrew Geissler                 {
65183935af9SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "On";
65283935af9SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "InTest";
65383935af9SAndrew Geissler                 }
6541a2a1437SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6551a2a1437SAndrew Geissler                                "TransitioningToRunning")
6561a2a1437SAndrew Geissler                 {
6571a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOn";
65815c27bf8SNoah Brewer                     aResp->res.jsonValue["Status"]["State"] = "Starting";
6591a2a1437SAndrew Geissler                 }
6601a2a1437SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6611a2a1437SAndrew Geissler                                "TransitioningToOff")
6621a2a1437SAndrew Geissler                 {
6631a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOff";
6641a2a1437SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
6651a2a1437SAndrew Geissler                 }
6661abe55efSEd Tanous                 else
6671abe55efSEd Tanous                 {
66855c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
6696617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
670c5b2abe0SLewanczyk, Dawid                 }
671c5b2abe0SLewanczyk, Dawid             }
672c5b2abe0SLewanczyk, Dawid         },
6736c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
6746617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
6756617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
676c5b2abe0SLewanczyk, Dawid }
677c5b2abe0SLewanczyk, Dawid 
678c5b2abe0SLewanczyk, Dawid /**
679786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
680491d8ee7SSantosh Puranik  *
681491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
682491d8ee7SSantosh Puranik  *
683491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
684491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
685491d8ee7SSantosh Puranik  */
68623a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
687491d8ee7SSantosh Puranik {
688491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
689491d8ee7SSantosh Puranik     {
690491d8ee7SSantosh Puranik         return "None";
691491d8ee7SSantosh Puranik     }
6923174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
693491d8ee7SSantosh Puranik     {
694491d8ee7SSantosh Puranik         return "Hdd";
695491d8ee7SSantosh Puranik     }
6963174e4dfSEd Tanous     if (dbusSource ==
697a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
698491d8ee7SSantosh Puranik     {
699491d8ee7SSantosh Puranik         return "Cd";
700491d8ee7SSantosh Puranik     }
7013174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
702491d8ee7SSantosh Puranik     {
703491d8ee7SSantosh Puranik         return "Pxe";
704491d8ee7SSantosh Puranik     }
7053174e4dfSEd Tanous     if (dbusSource ==
706944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
7079f16b2c1SJennifer Lee     {
7089f16b2c1SJennifer Lee         return "Usb";
7099f16b2c1SJennifer Lee     }
710491d8ee7SSantosh Puranik     return "";
711491d8ee7SSantosh Puranik }
712491d8ee7SSantosh Puranik 
713491d8ee7SSantosh Puranik /**
714cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
715cd9a4666SKonstantin Aladyshev  *
716cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
717cd9a4666SKonstantin Aladyshev  *
718cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
719cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
720cd9a4666SKonstantin Aladyshev  */
721cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
722cd9a4666SKonstantin Aladyshev {
723cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
724cd9a4666SKonstantin Aladyshev     {
725cd9a4666SKonstantin Aladyshev         return "Legacy";
726cd9a4666SKonstantin Aladyshev     }
727cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
728cd9a4666SKonstantin Aladyshev     {
729cd9a4666SKonstantin Aladyshev         return "UEFI";
730cd9a4666SKonstantin Aladyshev     }
731cd9a4666SKonstantin Aladyshev     return "";
732cd9a4666SKonstantin Aladyshev }
733cd9a4666SKonstantin Aladyshev 
734cd9a4666SKonstantin Aladyshev /**
735786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
736491d8ee7SSantosh Puranik  *
737491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
738491d8ee7SSantosh Puranik  *
739491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
740491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
741491d8ee7SSantosh Puranik  */
74223a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
743491d8ee7SSantosh Puranik {
744491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
745491d8ee7SSantosh Puranik     {
746491d8ee7SSantosh Puranik         return "None";
747491d8ee7SSantosh Puranik     }
7483174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
749491d8ee7SSantosh Puranik     {
750491d8ee7SSantosh Puranik         return "Diags";
751491d8ee7SSantosh Puranik     }
7523174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
753491d8ee7SSantosh Puranik     {
754491d8ee7SSantosh Puranik         return "BiosSetup";
755491d8ee7SSantosh Puranik     }
756491d8ee7SSantosh Puranik     return "";
757491d8ee7SSantosh Puranik }
758491d8ee7SSantosh Puranik 
759491d8ee7SSantosh Puranik /**
760786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
761491d8ee7SSantosh Puranik  *
762491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
763944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
764944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
765491d8ee7SSantosh Puranik  *
766944ffaf9SJohnathan Mantey  * @return Integer error code.
767491d8ee7SSantosh Puranik  */
7688d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
769944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
770944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
771491d8ee7SSantosh Puranik {
772c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
773c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
774944ffaf9SJohnathan Mantey 
775491d8ee7SSantosh Puranik     if (rfSource == "None")
776491d8ee7SSantosh Puranik     {
777944ffaf9SJohnathan Mantey         return 0;
778491d8ee7SSantosh Puranik     }
7793174e4dfSEd Tanous     if (rfSource == "Pxe")
780491d8ee7SSantosh Puranik     {
781944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
782944ffaf9SJohnathan Mantey     }
783944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
784944ffaf9SJohnathan Mantey     {
785944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
786944ffaf9SJohnathan Mantey     }
787944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
788944ffaf9SJohnathan Mantey     {
789944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
790944ffaf9SJohnathan Mantey     }
791944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
792944ffaf9SJohnathan Mantey     {
793944ffaf9SJohnathan Mantey         bootSource =
794944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
795944ffaf9SJohnathan Mantey     }
796944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
797944ffaf9SJohnathan Mantey     {
798944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
799491d8ee7SSantosh Puranik     }
8009f16b2c1SJennifer Lee     else if (rfSource == "Usb")
8019f16b2c1SJennifer Lee     {
802944ffaf9SJohnathan Mantey         bootSource =
803944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
8049f16b2c1SJennifer Lee     }
805491d8ee7SSantosh Puranik     else
806491d8ee7SSantosh Puranik     {
807944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG << "Invalid property value for "
808944ffaf9SJohnathan Mantey                             "BootSourceOverrideTarget: "
809944ffaf9SJohnathan Mantey                          << bootSource;
810944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
811944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
812944ffaf9SJohnathan Mantey         return -1;
813491d8ee7SSantosh Puranik     }
814944ffaf9SJohnathan Mantey     return 0;
815491d8ee7SSantosh Puranik }
8161981771bSAli Ahmed 
817978b8803SAndrew Geissler /**
818978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
819978b8803SAndrew Geissler  *
820978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
821978b8803SAndrew Geissler  *
822978b8803SAndrew Geissler  * @return None.
823978b8803SAndrew Geissler  */
8248d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
825978b8803SAndrew Geissler {
826978b8803SAndrew Geissler     crow::connections::systemBus->async_method_call(
827978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
828978b8803SAndrew Geissler                 const std::variant<std::string>& bootProgress) {
829978b8803SAndrew Geissler             if (ec)
830978b8803SAndrew Geissler             {
831978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
832978b8803SAndrew Geissler                 // not found
833978b8803SAndrew Geissler                 return;
834978b8803SAndrew Geissler             }
835978b8803SAndrew Geissler 
836978b8803SAndrew Geissler             const std::string* bootProgressStr =
837978b8803SAndrew Geissler                 std::get_if<std::string>(&bootProgress);
838978b8803SAndrew Geissler 
839978b8803SAndrew Geissler             if (!bootProgressStr)
840978b8803SAndrew Geissler             {
841978b8803SAndrew Geissler                 // Interface implemented but property not found, return error
842978b8803SAndrew Geissler                 // for that
843978b8803SAndrew Geissler                 messages::internalError(aResp->res);
844978b8803SAndrew Geissler                 return;
845978b8803SAndrew Geissler             }
846978b8803SAndrew Geissler 
847978b8803SAndrew Geissler             BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr;
848978b8803SAndrew Geissler 
849978b8803SAndrew Geissler             // Now convert the D-Bus BootProgress to the appropriate Redfish
850978b8803SAndrew Geissler             // enum
851978b8803SAndrew Geissler             std::string rfBpLastState = "None";
852978b8803SAndrew Geissler             if (*bootProgressStr == "xyz.openbmc_project.State.Boot.Progress."
853978b8803SAndrew Geissler                                     "ProgressStages.Unspecified")
854978b8803SAndrew Geissler             {
855978b8803SAndrew Geissler                 rfBpLastState = "None";
856978b8803SAndrew Geissler             }
857978b8803SAndrew Geissler             else if (*bootProgressStr ==
858978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
859978b8803SAndrew Geissler                      "PrimaryProcInit")
860978b8803SAndrew Geissler             {
861978b8803SAndrew Geissler                 rfBpLastState = "PrimaryProcessorInitializationStarted";
862978b8803SAndrew Geissler             }
863978b8803SAndrew Geissler             else if (*bootProgressStr ==
864978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
865978b8803SAndrew Geissler                      "BusInit")
866978b8803SAndrew Geissler             {
867978b8803SAndrew Geissler                 rfBpLastState = "BusInitializationStarted";
868978b8803SAndrew Geissler             }
869978b8803SAndrew Geissler             else if (*bootProgressStr ==
870978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
871978b8803SAndrew Geissler                      "MemoryInit")
872978b8803SAndrew Geissler             {
873978b8803SAndrew Geissler                 rfBpLastState = "MemoryInitializationStarted";
874978b8803SAndrew Geissler             }
875978b8803SAndrew Geissler             else if (*bootProgressStr ==
876978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
877978b8803SAndrew Geissler                      "SecondaryProcInit")
878978b8803SAndrew Geissler             {
879978b8803SAndrew Geissler                 rfBpLastState = "SecondaryProcessorInitializationStarted";
880978b8803SAndrew Geissler             }
881978b8803SAndrew Geissler             else if (*bootProgressStr ==
882978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
883978b8803SAndrew Geissler                      "PCIInit")
884978b8803SAndrew Geissler             {
885978b8803SAndrew Geissler                 rfBpLastState = "PCIResourceConfigStarted";
886978b8803SAndrew Geissler             }
887978b8803SAndrew Geissler             else if (*bootProgressStr ==
888978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
889978b8803SAndrew Geissler                      "SystemInitComplete")
890978b8803SAndrew Geissler             {
891978b8803SAndrew Geissler                 rfBpLastState = "SystemHardwareInitializationComplete";
892978b8803SAndrew Geissler             }
893978b8803SAndrew Geissler             else if (*bootProgressStr ==
894978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
895978b8803SAndrew Geissler                      "OSStart")
896978b8803SAndrew Geissler             {
897978b8803SAndrew Geissler                 rfBpLastState = "OSBootStarted";
898978b8803SAndrew Geissler             }
899978b8803SAndrew Geissler             else if (*bootProgressStr ==
900978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
901978b8803SAndrew Geissler                      "OSRunning")
902978b8803SAndrew Geissler             {
903978b8803SAndrew Geissler                 rfBpLastState = "OSRunning";
904978b8803SAndrew Geissler             }
905978b8803SAndrew Geissler             else
906978b8803SAndrew Geissler             {
907978b8803SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
908978b8803SAndrew Geissler                                  << *bootProgressStr;
909978b8803SAndrew Geissler                 // Just return the default
910978b8803SAndrew Geissler             }
911978b8803SAndrew Geissler 
912978b8803SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
913978b8803SAndrew Geissler         },
914978b8803SAndrew Geissler         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
915978b8803SAndrew Geissler         "org.freedesktop.DBus.Properties", "Get",
916978b8803SAndrew Geissler         "xyz.openbmc_project.State.Boot.Progress", "BootProgress");
917978b8803SAndrew Geissler }
918491d8ee7SSantosh Puranik 
919491d8ee7SSantosh Puranik /**
920c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
921cd9a4666SKonstantin Aladyshev  *
922cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
923cd9a4666SKonstantin Aladyshev  *
924cd9a4666SKonstantin Aladyshev  * @return None.
925cd9a4666SKonstantin Aladyshev  */
926cd9a4666SKonstantin Aladyshev 
927c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
928cd9a4666SKonstantin Aladyshev {
929cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
930cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
931cd9a4666SKonstantin Aladyshev                 const std::variant<std::string>& bootType) {
932cd9a4666SKonstantin Aladyshev             if (ec)
933cd9a4666SKonstantin Aladyshev             {
934cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
935cd9a4666SKonstantin Aladyshev                 return;
936cd9a4666SKonstantin Aladyshev             }
937cd9a4666SKonstantin Aladyshev 
938cd9a4666SKonstantin Aladyshev             const std::string* bootTypeStr =
939cd9a4666SKonstantin Aladyshev                 std::get_if<std::string>(&bootType);
940cd9a4666SKonstantin Aladyshev 
941cd9a4666SKonstantin Aladyshev             if (!bootTypeStr)
942cd9a4666SKonstantin Aladyshev             {
943cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
944cd9a4666SKonstantin Aladyshev                 return;
945cd9a4666SKonstantin Aladyshev             }
946cd9a4666SKonstantin Aladyshev 
947cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr;
948cd9a4666SKonstantin Aladyshev 
949cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode@Redfish."
950cd9a4666SKonstantin Aladyshev                                          "AllowableValues"] = {"Legacy",
951cd9a4666SKonstantin Aladyshev                                                                "UEFI"};
952cd9a4666SKonstantin Aladyshev 
953cd9a4666SKonstantin Aladyshev             auto rfType = dbusToRfBootType(*bootTypeStr);
954cd9a4666SKonstantin Aladyshev             if (rfType.empty())
955cd9a4666SKonstantin Aladyshev             {
956cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
957cd9a4666SKonstantin Aladyshev                 return;
958cd9a4666SKonstantin Aladyshev             }
959cd9a4666SKonstantin Aladyshev 
960cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
961cd9a4666SKonstantin Aladyshev         },
962c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
963c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
964cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
965cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType");
966cd9a4666SKonstantin Aladyshev }
967cd9a4666SKonstantin Aladyshev 
968cd9a4666SKonstantin Aladyshev /**
969c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
970491d8ee7SSantosh Puranik  *
971491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
972491d8ee7SSantosh Puranik  *
973491d8ee7SSantosh Puranik  * @return None.
974491d8ee7SSantosh Puranik  */
975c21865c4SKonstantin Aladyshev 
976c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
977491d8ee7SSantosh Puranik {
978491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
979c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
980491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootMode) {
981491d8ee7SSantosh Puranik             if (ec)
982491d8ee7SSantosh Puranik             {
983491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
984491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
985491d8ee7SSantosh Puranik                 return;
986491d8ee7SSantosh Puranik             }
987491d8ee7SSantosh Puranik 
988491d8ee7SSantosh Puranik             const std::string* bootModeStr =
989491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootMode);
990491d8ee7SSantosh Puranik 
991491d8ee7SSantosh Puranik             if (!bootModeStr)
992491d8ee7SSantosh Puranik             {
993491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
994491d8ee7SSantosh Puranik                 return;
995491d8ee7SSantosh Puranik             }
996491d8ee7SSantosh Puranik 
997491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
998491d8ee7SSantosh Puranik 
999491d8ee7SSantosh Puranik             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
1000491d8ee7SSantosh Puranik                                          "AllowableValues"] = {
1001944ffaf9SJohnathan Mantey                 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1002491d8ee7SSantosh Puranik 
1003491d8ee7SSantosh Puranik             if (*bootModeStr !=
1004491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1005491d8ee7SSantosh Puranik             {
1006491d8ee7SSantosh Puranik                 auto rfMode = dbusToRfBootMode(*bootModeStr);
1007491d8ee7SSantosh Puranik                 if (!rfMode.empty())
1008491d8ee7SSantosh Puranik                 {
1009491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1010491d8ee7SSantosh Puranik                         rfMode;
1011491d8ee7SSantosh Puranik                 }
1012491d8ee7SSantosh Puranik             }
1013491d8ee7SSantosh Puranik         },
1014c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1015c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1016491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1017491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
1018491d8ee7SSantosh Puranik }
1019491d8ee7SSantosh Puranik 
1020491d8ee7SSantosh Puranik /**
1021c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
1022491d8ee7SSantosh Puranik  *
1023491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
1024491d8ee7SSantosh Puranik  *
1025491d8ee7SSantosh Puranik  * @return None.
1026491d8ee7SSantosh Puranik  */
1027c21865c4SKonstantin Aladyshev 
1028c21865c4SKonstantin Aladyshev inline void
1029c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1030491d8ee7SSantosh Puranik {
1031491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1032c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
1033491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootSource) {
1034491d8ee7SSantosh Puranik             if (ec)
1035491d8ee7SSantosh Puranik             {
1036491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1037491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1038491d8ee7SSantosh Puranik                 return;
1039491d8ee7SSantosh Puranik             }
1040491d8ee7SSantosh Puranik 
1041491d8ee7SSantosh Puranik             const std::string* bootSourceStr =
1042491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootSource);
1043491d8ee7SSantosh Puranik 
1044491d8ee7SSantosh Puranik             if (!bootSourceStr)
1045491d8ee7SSantosh Puranik             {
1046491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1047491d8ee7SSantosh Puranik                 return;
1048491d8ee7SSantosh Puranik             }
1049491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
1050491d8ee7SSantosh Puranik 
1051491d8ee7SSantosh Puranik             auto rfSource = dbusToRfBootSource(*bootSourceStr);
1052491d8ee7SSantosh Puranik             if (!rfSource.empty())
1053491d8ee7SSantosh Puranik             {
1054491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1055491d8ee7SSantosh Puranik                     rfSource;
1056491d8ee7SSantosh Puranik             }
1057cd9a4666SKonstantin Aladyshev 
1058cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1059cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1060c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
1061491d8ee7SSantosh Puranik         },
1062c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1063c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1064491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1065491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource");
1066491d8ee7SSantosh Puranik }
1067491d8ee7SSantosh Puranik 
1068491d8ee7SSantosh Puranik /**
1069c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1070c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1071c21865c4SKonstantin Aladyshev  * state
1072491d8ee7SSantosh Puranik  *
1073491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1074491d8ee7SSantosh Puranik  *
1075491d8ee7SSantosh Puranik  * @return None.
1076491d8ee7SSantosh Puranik  */
1077491d8ee7SSantosh Puranik 
1078c21865c4SKonstantin Aladyshev inline void
1079c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1080c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1081c21865c4SKonstantin Aladyshev {
1082c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1083c21865c4SKonstantin Aladyshev     {
1084c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1085c21865c4SKonstantin Aladyshev         return;
1086c21865c4SKonstantin Aladyshev     }
1087c21865c4SKonstantin Aladyshev 
1088c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1089c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1090491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1091c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
109219bd78d9SPatrick Williams                 const std::variant<bool>& oneTime) {
1093491d8ee7SSantosh Puranik             if (ec)
1094491d8ee7SSantosh Puranik             {
1095491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1096c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1097491d8ee7SSantosh Puranik                 return;
1098491d8ee7SSantosh Puranik             }
1099491d8ee7SSantosh Puranik 
1100491d8ee7SSantosh Puranik             const bool* oneTimePtr = std::get_if<bool>(&oneTime);
1101491d8ee7SSantosh Puranik 
1102491d8ee7SSantosh Puranik             if (!oneTimePtr)
1103491d8ee7SSantosh Puranik             {
1104491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1105491d8ee7SSantosh Puranik                 return;
1106491d8ee7SSantosh Puranik             }
1107c21865c4SKonstantin Aladyshev 
1108c21865c4SKonstantin Aladyshev             bool oneTimeSetting = *oneTimePtr;
1109c21865c4SKonstantin Aladyshev 
1110c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1111c21865c4SKonstantin Aladyshev             {
1112c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1113c21865c4SKonstantin Aladyshev                     "Once";
1114c21865c4SKonstantin Aladyshev             }
1115c21865c4SKonstantin Aladyshev             else
1116c21865c4SKonstantin Aladyshev             {
1117c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1118c21865c4SKonstantin Aladyshev                     "Continuous";
1119c21865c4SKonstantin Aladyshev             }
1120491d8ee7SSantosh Puranik         },
1121491d8ee7SSantosh Puranik         "xyz.openbmc_project.Settings",
1122491d8ee7SSantosh Puranik         "/xyz/openbmc_project/control/host0/boot/one_time",
1123491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1124491d8ee7SSantosh Puranik         "xyz.openbmc_project.Object.Enable", "Enabled");
1125491d8ee7SSantosh Puranik }
1126491d8ee7SSantosh Puranik 
1127491d8ee7SSantosh Puranik /**
1128c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1129c21865c4SKonstantin Aladyshev  *
1130c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1131c21865c4SKonstantin Aladyshev  *
1132c21865c4SKonstantin Aladyshev  * @return None.
1133c21865c4SKonstantin Aladyshev  */
1134c21865c4SKonstantin Aladyshev 
1135c21865c4SKonstantin Aladyshev inline void
1136c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1137c21865c4SKonstantin Aladyshev {
1138c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1139c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
1140c21865c4SKonstantin Aladyshev                 const std::variant<bool>& bootOverrideEnable) {
1141c21865c4SKonstantin Aladyshev             if (ec)
1142c21865c4SKonstantin Aladyshev             {
1143c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1144c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1145c21865c4SKonstantin Aladyshev                 return;
1146c21865c4SKonstantin Aladyshev             }
1147c21865c4SKonstantin Aladyshev 
1148c21865c4SKonstantin Aladyshev             const bool* bootOverrideEnablePtr =
1149c21865c4SKonstantin Aladyshev                 std::get_if<bool>(&bootOverrideEnable);
1150c21865c4SKonstantin Aladyshev 
1151c21865c4SKonstantin Aladyshev             if (!bootOverrideEnablePtr)
1152c21865c4SKonstantin Aladyshev             {
1153c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1154c21865c4SKonstantin Aladyshev                 return;
1155c21865c4SKonstantin Aladyshev             }
1156c21865c4SKonstantin Aladyshev 
1157c21865c4SKonstantin Aladyshev             processBootOverrideEnable(aResp, *bootOverrideEnablePtr);
1158c21865c4SKonstantin Aladyshev         },
1159c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1160c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1161c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
1162c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled");
1163c21865c4SKonstantin Aladyshev }
1164c21865c4SKonstantin Aladyshev 
1165c21865c4SKonstantin Aladyshev /**
1166c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1167c21865c4SKonstantin Aladyshev  *
1168c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1169c21865c4SKonstantin Aladyshev  *
1170c21865c4SKonstantin Aladyshev  * @return None.
1171c21865c4SKonstantin Aladyshev  */
1172c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1173c21865c4SKonstantin Aladyshev {
1174c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1175c21865c4SKonstantin Aladyshev 
1176c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1177c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1178c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1179c21865c4SKonstantin Aladyshev }
1180c21865c4SKonstantin Aladyshev 
1181c21865c4SKonstantin Aladyshev /**
1182c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1183c0557e1aSGunnar Mills  *
1184c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1185c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1186c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1187c0557e1aSGunnar Mills  * last power operation time.
1188c0557e1aSGunnar Mills  *
1189c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1190c0557e1aSGunnar Mills  *
1191c0557e1aSGunnar Mills  * @return None.
1192c0557e1aSGunnar Mills  */
11938d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1194c0557e1aSGunnar Mills {
1195c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1196c0557e1aSGunnar Mills 
1197c0557e1aSGunnar Mills     crow::connections::systemBus->async_method_call(
1198c0557e1aSGunnar Mills         [aResp](const boost::system::error_code ec,
1199c0557e1aSGunnar Mills                 std::variant<uint64_t>& lastResetTime) {
1200c0557e1aSGunnar Mills             if (ec)
1201c0557e1aSGunnar Mills             {
1202c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1203c0557e1aSGunnar Mills                 return;
1204c0557e1aSGunnar Mills             }
1205c0557e1aSGunnar Mills 
1206c0557e1aSGunnar Mills             const uint64_t* lastResetTimePtr =
1207c0557e1aSGunnar Mills                 std::get_if<uint64_t>(&lastResetTime);
1208c0557e1aSGunnar Mills 
1209c0557e1aSGunnar Mills             if (!lastResetTimePtr)
1210c0557e1aSGunnar Mills             {
1211c0557e1aSGunnar Mills                 messages::internalError(aResp->res);
1212c0557e1aSGunnar Mills                 return;
1213c0557e1aSGunnar Mills             }
1214c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1215c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1216c0557e1aSGunnar Mills             time_t lastResetTimeStamp =
1217c0557e1aSGunnar Mills                 static_cast<time_t>(*lastResetTimePtr / 1000);
1218c0557e1aSGunnar Mills 
1219c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1220c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
1221c0557e1aSGunnar Mills                 crow::utility::getDateTime(lastResetTimeStamp);
1222c0557e1aSGunnar Mills         },
1223c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis",
1224c0557e1aSGunnar Mills         "/xyz/openbmc_project/state/chassis0",
1225c0557e1aSGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
1226c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
1227c0557e1aSGunnar Mills }
1228c0557e1aSGunnar Mills 
1229c0557e1aSGunnar Mills /**
12306bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
12316bd5a8d2SGunnar Mills  *
12326bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
12336bd5a8d2SGunnar Mills  *
12346bd5a8d2SGunnar Mills  * @return None.
12356bd5a8d2SGunnar Mills  */
12368d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
12376bd5a8d2SGunnar Mills {
12386bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12396bd5a8d2SGunnar Mills 
12406bd5a8d2SGunnar Mills     crow::connections::systemBus->async_method_call(
12416bd5a8d2SGunnar Mills         [aResp](const boost::system::error_code ec,
12426bd5a8d2SGunnar Mills                 std::variant<bool>& autoRebootEnabled) {
12436bd5a8d2SGunnar Mills             if (ec)
12446bd5a8d2SGunnar Mills             {
12456bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
12466bd5a8d2SGunnar Mills                 return;
12476bd5a8d2SGunnar Mills             }
12486bd5a8d2SGunnar Mills 
12496bd5a8d2SGunnar Mills             const bool* autoRebootEnabledPtr =
12506bd5a8d2SGunnar Mills                 std::get_if<bool>(&autoRebootEnabled);
12516bd5a8d2SGunnar Mills 
12526bd5a8d2SGunnar Mills             if (!autoRebootEnabledPtr)
12536bd5a8d2SGunnar Mills             {
12546bd5a8d2SGunnar Mills                 messages::internalError(aResp->res);
12556bd5a8d2SGunnar Mills                 return;
12566bd5a8d2SGunnar Mills             }
12576bd5a8d2SGunnar Mills 
12586bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
12596bd5a8d2SGunnar Mills             if (*autoRebootEnabledPtr == true)
12606bd5a8d2SGunnar Mills             {
12616bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12626bd5a8d2SGunnar Mills                     "RetryAttempts";
12636bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
12646bd5a8d2SGunnar Mills                 // attempts are left
12656bd5a8d2SGunnar Mills                 crow::connections::systemBus->async_method_call(
1266cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
12676bd5a8d2SGunnar Mills                             std::variant<uint32_t>& autoRebootAttemptsLeft) {
1268cb13a392SEd Tanous                         if (ec2)
12696bd5a8d2SGunnar Mills                         {
1270cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
12716bd5a8d2SGunnar Mills                             return;
12726bd5a8d2SGunnar Mills                         }
12736bd5a8d2SGunnar Mills 
12746bd5a8d2SGunnar Mills                         const uint32_t* autoRebootAttemptsLeftPtr =
12756bd5a8d2SGunnar Mills                             std::get_if<uint32_t>(&autoRebootAttemptsLeft);
12766bd5a8d2SGunnar Mills 
12776bd5a8d2SGunnar Mills                         if (!autoRebootAttemptsLeftPtr)
12786bd5a8d2SGunnar Mills                         {
12796bd5a8d2SGunnar Mills                             messages::internalError(aResp->res);
12806bd5a8d2SGunnar Mills                             return;
12816bd5a8d2SGunnar Mills                         }
12826bd5a8d2SGunnar Mills 
12836bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
12846bd5a8d2SGunnar Mills                                          << *autoRebootAttemptsLeftPtr;
12856bd5a8d2SGunnar Mills 
12866bd5a8d2SGunnar Mills                         aResp->res
12876bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
12886bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
12896bd5a8d2SGunnar Mills                             *autoRebootAttemptsLeftPtr;
12906bd5a8d2SGunnar Mills                     },
12916bd5a8d2SGunnar Mills                     "xyz.openbmc_project.State.Host",
12926bd5a8d2SGunnar Mills                     "/xyz/openbmc_project/state/host0",
12936bd5a8d2SGunnar Mills                     "org.freedesktop.DBus.Properties", "Get",
12946bd5a8d2SGunnar Mills                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
12956bd5a8d2SGunnar Mills                     "AttemptsLeft");
12966bd5a8d2SGunnar Mills             }
12976bd5a8d2SGunnar Mills             else
12986bd5a8d2SGunnar Mills             {
12996bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
13006bd5a8d2SGunnar Mills                     "Disabled";
13016bd5a8d2SGunnar Mills             }
13026bd5a8d2SGunnar Mills 
13036bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
13046bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
13056bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
130669f35306SGunnar Mills 
130769f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
130869f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
130969f35306SGunnar Mills             // RetryAttempts.
131069f35306SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
131169f35306SGunnar Mills                                          "AllowableValues"] = {"Disabled",
131269f35306SGunnar Mills                                                                "RetryAttempts"};
13136bd5a8d2SGunnar Mills         },
13146bd5a8d2SGunnar Mills         "xyz.openbmc_project.Settings",
13156bd5a8d2SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
13166bd5a8d2SGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
13176bd5a8d2SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
13186bd5a8d2SGunnar Mills }
13196bd5a8d2SGunnar Mills 
13206bd5a8d2SGunnar Mills /**
1321c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1322c6a620f2SGeorge Liu  *
1323c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1324c6a620f2SGeorge Liu  *
1325c6a620f2SGeorge Liu  * @return None.
1326c6a620f2SGeorge Liu  */
13278d1b46d7Szhanghch05 inline void
13288d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1329c6a620f2SGeorge Liu {
1330c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1331c6a620f2SGeorge Liu 
1332c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1333c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec,
133419bd78d9SPatrick Williams                 std::variant<std::string>& policy) {
1335c6a620f2SGeorge Liu             if (ec)
1336c6a620f2SGeorge Liu             {
1337c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1338c6a620f2SGeorge Liu                 return;
1339c6a620f2SGeorge Liu             }
1340c6a620f2SGeorge Liu 
1341c6a620f2SGeorge Liu             const boost::container::flat_map<std::string, std::string>
1342c6a620f2SGeorge Liu                 policyMaps = {
1343c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1344c6a620f2SGeorge Liu                      "AlwaysOn",
1345c6a620f2SGeorge Liu                      "AlwaysOn"},
1346c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1347c6a620f2SGeorge Liu                      "AlwaysOff",
1348c6a620f2SGeorge Liu                      "AlwaysOff"},
1349c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
135037ec9072SGunnar Mills                      "Restore",
1351c6a620f2SGeorge Liu                      "LastState"}};
1352c6a620f2SGeorge Liu 
1353c6a620f2SGeorge Liu             const std::string* policyPtr = std::get_if<std::string>(&policy);
1354c6a620f2SGeorge Liu 
1355c6a620f2SGeorge Liu             if (!policyPtr)
1356c6a620f2SGeorge Liu             {
1357c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1358c6a620f2SGeorge Liu                 return;
1359c6a620f2SGeorge Liu             }
1360c6a620f2SGeorge Liu 
1361c6a620f2SGeorge Liu             auto policyMapsIt = policyMaps.find(*policyPtr);
1362c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1363c6a620f2SGeorge Liu             {
1364c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1365c6a620f2SGeorge Liu                 return;
1366c6a620f2SGeorge Liu             }
1367c6a620f2SGeorge Liu 
1368c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1369c6a620f2SGeorge Liu         },
1370c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1371c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1372c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Get",
1373c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy",
1374c6a620f2SGeorge Liu         "PowerRestorePolicy");
1375c6a620f2SGeorge Liu }
1376c6a620f2SGeorge Liu 
1377c6a620f2SGeorge Liu /**
13781981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13791981771bSAli Ahmed  * TPM is required for booting the host.
13801981771bSAli Ahmed  *
13811981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13821981771bSAli Ahmed  *
13831981771bSAli Ahmed  * @return None.
13841981771bSAli Ahmed  */
13851981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13861981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13871981771bSAli Ahmed {
13881981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
13891981771bSAli Ahmed 
13901981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
13911981771bSAli Ahmed         [aResp](
13921981771bSAli Ahmed             const boost::system::error_code ec,
13931981771bSAli Ahmed             std::vector<std::pair<
13941981771bSAli Ahmed                 std::string,
13951981771bSAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
13961981771bSAli Ahmed                 subtree) {
13971981771bSAli Ahmed             if (ec)
13981981771bSAli Ahmed             {
13991981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
14001981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
14011981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
14021981771bSAli Ahmed                 // error occurs
14031981771bSAli Ahmed                 return;
14041981771bSAli Ahmed             }
14051981771bSAli Ahmed             if (subtree.size() == 0)
14061981771bSAli Ahmed             {
14071981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
14081981771bSAli Ahmed                 // if there is no instance found
14091981771bSAli Ahmed                 return;
14101981771bSAli Ahmed             }
14111981771bSAli Ahmed 
14121981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
14131981771bSAli Ahmed             if (subtree.size() > 1)
14141981771bSAli Ahmed             {
14151981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
14161981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
14171981771bSAli Ahmed                     << subtree.size();
14181981771bSAli Ahmed                 // Throw an internal Error and return
14191981771bSAli Ahmed                 messages::internalError(aResp->res);
14201981771bSAli Ahmed                 return;
14211981771bSAli Ahmed             }
14221981771bSAli Ahmed 
14231981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14241981771bSAli Ahmed             // field
14251981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14261981771bSAli Ahmed             {
14271981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14281981771bSAli Ahmed                 messages::internalError(aResp->res);
14291981771bSAli Ahmed                 return;
14301981771bSAli Ahmed             }
14311981771bSAli Ahmed 
14321981771bSAli Ahmed             const std::string& path = subtree[0].first;
14331981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14341981771bSAli Ahmed 
14351981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
14361981771bSAli Ahmed             crow::connections::systemBus->async_method_call(
14371981771bSAli Ahmed                 [aResp](const boost::system::error_code ec,
14381981771bSAli Ahmed                         std::variant<bool>& tpmRequired) {
14391981771bSAli Ahmed                     if (ec)
14401981771bSAli Ahmed                     {
14411981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
14421981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
14431981771bSAli Ahmed                         messages::internalError(aResp->res);
14441981771bSAli Ahmed                         return;
14451981771bSAli Ahmed                     }
14461981771bSAli Ahmed 
14471981771bSAli Ahmed                     const bool* tpmRequiredVal =
14481981771bSAli Ahmed                         std::get_if<bool>(&tpmRequired);
14491981771bSAli Ahmed 
14501981771bSAli Ahmed                     if (!tpmRequiredVal)
14511981771bSAli Ahmed                     {
14521981771bSAli Ahmed                         messages::internalError(aResp->res);
14531981771bSAli Ahmed                         return;
14541981771bSAli Ahmed                     }
14551981771bSAli Ahmed 
14561981771bSAli Ahmed                     if (*tpmRequiredVal == true)
14571981771bSAli Ahmed                     {
14581981771bSAli Ahmed                         aResp->res
14591981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14601981771bSAli Ahmed                             "Required";
14611981771bSAli Ahmed                     }
14621981771bSAli Ahmed                     else
14631981771bSAli Ahmed                     {
14641981771bSAli Ahmed                         aResp->res
14651981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14661981771bSAli Ahmed                             "Disabled";
14671981771bSAli Ahmed                     }
14681981771bSAli Ahmed                 },
14691981771bSAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Get",
14701981771bSAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable");
14711981771bSAli Ahmed         },
14721981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
14731981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
14741981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
14751981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
14761981771bSAli Ahmed }
14771981771bSAli Ahmed 
14781981771bSAli Ahmed /**
1479*1c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1480*1c05dae3SAli Ahmed  * TPM is required for booting the host.
1481*1c05dae3SAli Ahmed  *
1482*1c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
1483*1c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
1484*1c05dae3SAli Ahmed  *
1485*1c05dae3SAli Ahmed  * @return None.
1486*1c05dae3SAli Ahmed  */
1487*1c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
1488*1c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1489*1c05dae3SAli Ahmed {
1490*1c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1491*1c05dae3SAli Ahmed 
1492*1c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
1493*1c05dae3SAli Ahmed         [aResp, tpmRequired](
1494*1c05dae3SAli Ahmed             const boost::system::error_code ec,
1495*1c05dae3SAli Ahmed             std::vector<std::pair<
1496*1c05dae3SAli Ahmed                 std::string,
1497*1c05dae3SAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
1498*1c05dae3SAli Ahmed                 subtree) {
1499*1c05dae3SAli Ahmed             if (ec)
1500*1c05dae3SAli Ahmed             {
1501*1c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
1502*1c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
1503*1c05dae3SAli Ahmed                 messages::internalError(aResp->res);
1504*1c05dae3SAli Ahmed                 return;
1505*1c05dae3SAli Ahmed             }
1506*1c05dae3SAli Ahmed             if (subtree.size() == 0)
1507*1c05dae3SAli Ahmed             {
1508*1c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
1509*1c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
1510*1c05dae3SAli Ahmed                 return;
1511*1c05dae3SAli Ahmed             }
1512*1c05dae3SAli Ahmed 
1513*1c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
1514*1c05dae3SAli Ahmed             if (subtree.size() > 1)
1515*1c05dae3SAli Ahmed             {
1516*1c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
1517*1c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
1518*1c05dae3SAli Ahmed                     << subtree.size();
1519*1c05dae3SAli Ahmed                 // Throw an internal Error and return
1520*1c05dae3SAli Ahmed                 messages::internalError(aResp->res);
1521*1c05dae3SAli Ahmed                 return;
1522*1c05dae3SAli Ahmed             }
1523*1c05dae3SAli Ahmed 
1524*1c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
1525*1c05dae3SAli Ahmed             // field
1526*1c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1527*1c05dae3SAli Ahmed             {
1528*1c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1529*1c05dae3SAli Ahmed                 messages::internalError(aResp->res);
1530*1c05dae3SAli Ahmed                 return;
1531*1c05dae3SAli Ahmed             }
1532*1c05dae3SAli Ahmed 
1533*1c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
1534*1c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
1535*1c05dae3SAli Ahmed 
1536*1c05dae3SAli Ahmed             if (serv.empty())
1537*1c05dae3SAli Ahmed             {
1538*1c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1539*1c05dae3SAli Ahmed                 messages::internalError(aResp->res);
1540*1c05dae3SAli Ahmed                 return;
1541*1c05dae3SAli Ahmed             }
1542*1c05dae3SAli Ahmed 
1543*1c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
1544*1c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
1545*1c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
1546*1c05dae3SAli Ahmed                     if (ec)
1547*1c05dae3SAli Ahmed                     {
1548*1c05dae3SAli Ahmed                         BMCWEB_LOG_DEBUG << "DBUS response error: Set "
1549*1c05dae3SAli Ahmed                                             "TrustedModuleRequiredToBoot"
1550*1c05dae3SAli Ahmed                                          << ec;
1551*1c05dae3SAli Ahmed                         messages::internalError(aResp->res);
1552*1c05dae3SAli Ahmed                         return;
1553*1c05dae3SAli Ahmed                     }
1554*1c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1555*1c05dae3SAli Ahmed                 },
1556*1c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
1557*1c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1558*1c05dae3SAli Ahmed                 std::variant<bool>(tpmRequired));
1559*1c05dae3SAli Ahmed         },
1560*1c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
1561*1c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
1562*1c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1563*1c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1564*1c05dae3SAli Ahmed }
1565*1c05dae3SAli Ahmed 
1566*1c05dae3SAli Ahmed /**
1567491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1568491d8ee7SSantosh Puranik  *
1569491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1570cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1571cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1572cd9a4666SKonstantin Aladyshev  */
1573cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1574cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1575cd9a4666SKonstantin Aladyshev {
1576c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1577cd9a4666SKonstantin Aladyshev 
1578c21865c4SKonstantin Aladyshev     if (!bootType)
1579cd9a4666SKonstantin Aladyshev     {
1580c21865c4SKonstantin Aladyshev         return;
1581c21865c4SKonstantin Aladyshev     }
1582c21865c4SKonstantin Aladyshev 
1583cd9a4666SKonstantin Aladyshev     // Source target specified
1584cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1585cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1586cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1587cd9a4666SKonstantin Aladyshev     {
1588cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1589cd9a4666SKonstantin Aladyshev     }
1590cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1591cd9a4666SKonstantin Aladyshev     {
1592cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1593cd9a4666SKonstantin Aladyshev     }
1594cd9a4666SKonstantin Aladyshev     else
1595cd9a4666SKonstantin Aladyshev     {
1596cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1597cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1598cd9a4666SKonstantin Aladyshev                          << *bootType;
1599cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1600cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1601cd9a4666SKonstantin Aladyshev         return;
1602cd9a4666SKonstantin Aladyshev     }
1603cd9a4666SKonstantin Aladyshev 
1604cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1605cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1606cd9a4666SKonstantin Aladyshev 
1607cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1608c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1609cd9a4666SKonstantin Aladyshev             if (ec)
1610cd9a4666SKonstantin Aladyshev             {
1611cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1612cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1613cd9a4666SKonstantin Aladyshev                 {
1614cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1615cd9a4666SKonstantin Aladyshev                     return;
1616cd9a4666SKonstantin Aladyshev                 }
1617cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1618cd9a4666SKonstantin Aladyshev                 return;
1619cd9a4666SKonstantin Aladyshev             }
1620cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1621cd9a4666SKonstantin Aladyshev         },
1622c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1623c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1624cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1625cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1626cd9a4666SKonstantin Aladyshev         std::variant<std::string>(bootTypeStr));
1627cd9a4666SKonstantin Aladyshev }
1628cd9a4666SKonstantin Aladyshev 
1629cd9a4666SKonstantin Aladyshev /**
1630cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1631cd9a4666SKonstantin Aladyshev  *
1632cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1633c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1634c21865c4SKonstantin Aladyshev  * @return Integer error code.
1635c21865c4SKonstantin Aladyshev  */
1636c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1637c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1638c21865c4SKonstantin Aladyshev {
1639c21865c4SKonstantin Aladyshev     if (!bootEnable)
1640c21865c4SKonstantin Aladyshev     {
1641c21865c4SKonstantin Aladyshev         return;
1642c21865c4SKonstantin Aladyshev     }
1643c21865c4SKonstantin Aladyshev     // Source target specified
1644c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1645c21865c4SKonstantin Aladyshev 
1646c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1647c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1648c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1649c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1650c21865c4SKonstantin Aladyshev     {
1651c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1652c21865c4SKonstantin Aladyshev     }
1653c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1654c21865c4SKonstantin Aladyshev     {
1655c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1656c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1657c21865c4SKonstantin Aladyshev     }
1658c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1659c21865c4SKonstantin Aladyshev     {
1660c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1661c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1662c21865c4SKonstantin Aladyshev     }
1663c21865c4SKonstantin Aladyshev     else
1664c21865c4SKonstantin Aladyshev     {
1665c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1666c21865c4SKonstantin Aladyshev                             "BootSourceOverrideEnabled: "
1667c21865c4SKonstantin Aladyshev                          << *bootEnable;
1668c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1669c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1670c21865c4SKonstantin Aladyshev         return;
1671c21865c4SKonstantin Aladyshev     }
1672c21865c4SKonstantin Aladyshev 
1673c21865c4SKonstantin Aladyshev     // Act on validated parameters
1674c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1675c21865c4SKonstantin Aladyshev 
1676c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1677c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1678c21865c4SKonstantin Aladyshev             if (ec)
1679c21865c4SKonstantin Aladyshev             {
1680c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1681c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1682c21865c4SKonstantin Aladyshev                 return;
1683c21865c4SKonstantin Aladyshev             }
1684c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1685c21865c4SKonstantin Aladyshev         },
1686c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1687c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1688c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1689c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1690c21865c4SKonstantin Aladyshev         std::variant<bool>(bootOverrideEnable));
1691c21865c4SKonstantin Aladyshev 
1692c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1693c21865c4SKonstantin Aladyshev     {
1694c21865c4SKonstantin Aladyshev         return;
1695c21865c4SKonstantin Aladyshev     }
1696c21865c4SKonstantin Aladyshev 
1697c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1698c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1699c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1700c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1701c21865c4SKonstantin Aladyshev 
1702c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1703c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1704c21865c4SKonstantin Aladyshev             if (ec)
1705c21865c4SKonstantin Aladyshev             {
1706c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1707c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1708c21865c4SKonstantin Aladyshev                 return;
1709c21865c4SKonstantin Aladyshev             }
1710c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1711c21865c4SKonstantin Aladyshev         },
1712c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1713c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1714c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1715c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1716c21865c4SKonstantin Aladyshev         std::variant<bool>(!bootOverridePersistent));
1717c21865c4SKonstantin Aladyshev }
1718c21865c4SKonstantin Aladyshev 
1719c21865c4SKonstantin Aladyshev /**
1720c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1721c21865c4SKonstantin Aladyshev  *
1722c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1723491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1724491d8ee7SSantosh Puranik  *
1725265c1602SJohnathan Mantey  * @return Integer error code.
1726491d8ee7SSantosh Puranik  */
1727cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1728cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1729491d8ee7SSantosh Puranik {
1730c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1731c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1732944ffaf9SJohnathan Mantey 
1733c21865c4SKonstantin Aladyshev     if (!bootSource)
1734491d8ee7SSantosh Puranik     {
1735c21865c4SKonstantin Aladyshev         return;
1736c21865c4SKonstantin Aladyshev     }
1737c21865c4SKonstantin Aladyshev 
1738491d8ee7SSantosh Puranik     // Source target specified
1739491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1740491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1741c21865c4SKonstantin Aladyshev     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr))
1742491d8ee7SSantosh Puranik     {
1743944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1744944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1745491d8ee7SSantosh Puranik             << *bootSource;
1746491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1747491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1748491d8ee7SSantosh Puranik         return;
1749491d8ee7SSantosh Puranik     }
1750491d8ee7SSantosh Puranik 
1751944ffaf9SJohnathan Mantey     // Act on validated parameters
1752944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1753944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1754944ffaf9SJohnathan Mantey 
1755491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1756491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1757491d8ee7SSantosh Puranik             if (ec)
1758491d8ee7SSantosh Puranik             {
1759491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1760491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1761491d8ee7SSantosh Puranik                 return;
1762491d8ee7SSantosh Puranik             }
1763491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1764491d8ee7SSantosh Puranik         },
1765c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1766c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1767491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1768491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1769491d8ee7SSantosh Puranik         std::variant<std::string>(bootSourceStr));
1770944ffaf9SJohnathan Mantey 
1771491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1772491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1773491d8ee7SSantosh Puranik             if (ec)
1774491d8ee7SSantosh Puranik             {
1775491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1776491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1777491d8ee7SSantosh Puranik                 return;
1778491d8ee7SSantosh Puranik             }
1779491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1780491d8ee7SSantosh Puranik         },
1781c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1782c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1783491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1784491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1785491d8ee7SSantosh Puranik         std::variant<std::string>(bootModeStr));
1786cd9a4666SKonstantin Aladyshev }
1787944ffaf9SJohnathan Mantey 
1788cd9a4666SKonstantin Aladyshev /**
1789c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1790491d8ee7SSantosh Puranik  *
1791491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1792491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1793cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1794491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1795491d8ee7SSantosh Puranik  *
1796265c1602SJohnathan Mantey  * @return Integer error code.
1797491d8ee7SSantosh Puranik  */
1798c21865c4SKonstantin Aladyshev 
1799c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1800c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1801c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1802c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1803491d8ee7SSantosh Puranik {
1804491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1805491d8ee7SSantosh Puranik 
1806c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1807c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1808c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1809491d8ee7SSantosh Puranik }
1810491d8ee7SSantosh Puranik 
1811c6a620f2SGeorge Liu /**
181298e386ecSGunnar Mills  * @brief Sets AssetTag
181398e386ecSGunnar Mills  *
181498e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
181598e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
181698e386ecSGunnar Mills  *
181798e386ecSGunnar Mills  * @return None.
181898e386ecSGunnar Mills  */
18198d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
182098e386ecSGunnar Mills                         const std::string& assetTag)
182198e386ecSGunnar Mills {
182298e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
182398e386ecSGunnar Mills         [aResp, assetTag](
182498e386ecSGunnar Mills             const boost::system::error_code ec,
182598e386ecSGunnar Mills             const std::vector<std::pair<
182698e386ecSGunnar Mills                 std::string,
182798e386ecSGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
182898e386ecSGunnar Mills                 subtree) {
182998e386ecSGunnar Mills             if (ec)
183098e386ecSGunnar Mills             {
183198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
183298e386ecSGunnar Mills                 messages::internalError(aResp->res);
183398e386ecSGunnar Mills                 return;
183498e386ecSGunnar Mills             }
183598e386ecSGunnar Mills             if (subtree.size() == 0)
183698e386ecSGunnar Mills             {
183798e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
183898e386ecSGunnar Mills                 messages::internalError(aResp->res);
183998e386ecSGunnar Mills                 return;
184098e386ecSGunnar Mills             }
184198e386ecSGunnar Mills             // Assume only 1 system D-Bus object
184298e386ecSGunnar Mills             // Throw an error if there is more than 1
184398e386ecSGunnar Mills             if (subtree.size() > 1)
184498e386ecSGunnar Mills             {
184598e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
184698e386ecSGunnar Mills                 messages::internalError(aResp->res);
184798e386ecSGunnar Mills                 return;
184898e386ecSGunnar Mills             }
184998e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
185098e386ecSGunnar Mills             {
185198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
185298e386ecSGunnar Mills                 messages::internalError(aResp->res);
185398e386ecSGunnar Mills                 return;
185498e386ecSGunnar Mills             }
185598e386ecSGunnar Mills 
185698e386ecSGunnar Mills             const std::string& path = subtree[0].first;
185798e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
185898e386ecSGunnar Mills 
185998e386ecSGunnar Mills             if (service.empty())
186098e386ecSGunnar Mills             {
186198e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
186298e386ecSGunnar Mills                 messages::internalError(aResp->res);
186398e386ecSGunnar Mills                 return;
186498e386ecSGunnar Mills             }
186598e386ecSGunnar Mills 
186698e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
186798e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
186898e386ecSGunnar Mills                     if (ec2)
186998e386ecSGunnar Mills                     {
187098e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
187198e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
187298e386ecSGunnar Mills                         messages::internalError(aResp->res);
187398e386ecSGunnar Mills                         return;
187498e386ecSGunnar Mills                     }
187598e386ecSGunnar Mills                 },
187698e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
187798e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
187898e386ecSGunnar Mills                 std::variant<std::string>(assetTag));
187998e386ecSGunnar Mills         },
188098e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
188198e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
188298e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
188398e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
188498e386ecSGunnar Mills         std::array<const char*, 1>{
188598e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
188698e386ecSGunnar Mills }
188798e386ecSGunnar Mills 
188898e386ecSGunnar Mills /**
188969f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
189069f35306SGunnar Mills  *
189169f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
189269f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
189369f35306SGunnar Mills  *
189469f35306SGunnar Mills  * @return None.
189569f35306SGunnar Mills  */
18968d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1897f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
189869f35306SGunnar Mills {
189969f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
190069f35306SGunnar Mills 
190169f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
190269f35306SGunnar Mills     bool autoRebootEnabled;
190369f35306SGunnar Mills 
190469f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
190569f35306SGunnar Mills     {
190669f35306SGunnar Mills         autoRebootEnabled = false;
190769f35306SGunnar Mills     }
190869f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
190969f35306SGunnar Mills     {
191069f35306SGunnar Mills         autoRebootEnabled = true;
191169f35306SGunnar Mills     }
191269f35306SGunnar Mills     else
191369f35306SGunnar Mills     {
191469f35306SGunnar Mills         BMCWEB_LOG_DEBUG << "Invalid property value for "
191569f35306SGunnar Mills                             "AutomaticRetryConfig: "
191669f35306SGunnar Mills                          << automaticRetryConfig;
191769f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
191869f35306SGunnar Mills                                          "AutomaticRetryConfig");
191969f35306SGunnar Mills         return;
192069f35306SGunnar Mills     }
192169f35306SGunnar Mills 
192269f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
192369f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
192469f35306SGunnar Mills             if (ec)
192569f35306SGunnar Mills             {
192669f35306SGunnar Mills                 messages::internalError(aResp->res);
192769f35306SGunnar Mills                 return;
192869f35306SGunnar Mills             }
192969f35306SGunnar Mills         },
193069f35306SGunnar Mills         "xyz.openbmc_project.Settings",
193169f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
193269f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
193369f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
193469f35306SGunnar Mills         std::variant<bool>(autoRebootEnabled));
193569f35306SGunnar Mills }
193669f35306SGunnar Mills 
193769f35306SGunnar Mills /**
1938c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1939c6a620f2SGeorge Liu  *
1940c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1941c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1942c6a620f2SGeorge Liu  *
1943c6a620f2SGeorge Liu  * @return None.
1944c6a620f2SGeorge Liu  */
19458d1b46d7Szhanghch05 inline void
19468d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19474e69c904SGunnar Mills                           const std::string& policy)
1948c6a620f2SGeorge Liu {
1949c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1950c6a620f2SGeorge Liu 
1951c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
1952c6a620f2SGeorge Liu         {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1953c6a620f2SGeorge Liu                      "AlwaysOn"},
1954c6a620f2SGeorge Liu         {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1955c6a620f2SGeorge Liu                       "AlwaysOff"},
1956c6a620f2SGeorge Liu         {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
195737ec9072SGunnar Mills                       "Restore"}};
1958c6a620f2SGeorge Liu 
1959c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1960c6a620f2SGeorge Liu 
19614e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1962c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1963c6a620f2SGeorge Liu     {
19644e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19654e69c904SGunnar Mills                                          "PowerRestorePolicy");
1966c6a620f2SGeorge Liu         return;
1967c6a620f2SGeorge Liu     }
1968c6a620f2SGeorge Liu 
1969c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1970c6a620f2SGeorge Liu 
1971c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1972c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1973c6a620f2SGeorge Liu             if (ec)
1974c6a620f2SGeorge Liu             {
1975c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1976c6a620f2SGeorge Liu                 return;
1977c6a620f2SGeorge Liu             }
1978c6a620f2SGeorge Liu         },
1979c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1980c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1981c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1982c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1983c6a620f2SGeorge Liu         std::variant<std::string>(powerRestorPolicy));
1984c6a620f2SGeorge Liu }
1985c6a620f2SGeorge Liu 
1986a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1987a6349918SAppaRao Puli /**
1988a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1989a6349918SAppaRao Puli  *
1990a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1991a6349918SAppaRao Puli  *
1992a6349918SAppaRao Puli  * @return None.
1993a6349918SAppaRao Puli  */
19948d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1995a6349918SAppaRao Puli {
1996a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1997a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1998a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
19991214b7e7SGunnar Mills                 const std::vector<std::pair<std::string, VariantType>>&
20001214b7e7SGunnar Mills                     propertiesList) {
2001b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
2002b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
200350626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
200450626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
200550626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
200650626f4fSJames Feist 
2007a6349918SAppaRao Puli             if (ec)
2008a6349918SAppaRao Puli             {
2009a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2010b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
2011b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2012a6349918SAppaRao Puli                 return;
2013a6349918SAppaRao Puli             }
2014a6349918SAppaRao Puli 
2015a6349918SAppaRao Puli             const bool* provState = nullptr;
2016a6349918SAppaRao Puli             const bool* lockState = nullptr;
2017a6349918SAppaRao Puli             for (const std::pair<std::string, VariantType>& property :
2018a6349918SAppaRao Puli                  propertiesList)
2019a6349918SAppaRao Puli             {
2020a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
2021a6349918SAppaRao Puli                 {
2022a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
2023a6349918SAppaRao Puli                 }
2024a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
2025a6349918SAppaRao Puli                 {
2026a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
2027a6349918SAppaRao Puli                 }
2028a6349918SAppaRao Puli             }
2029a6349918SAppaRao Puli 
2030a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
2031a6349918SAppaRao Puli             {
2032a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
2033a6349918SAppaRao Puli                 messages::internalError(aResp->res);
2034a6349918SAppaRao Puli                 return;
2035a6349918SAppaRao Puli             }
2036a6349918SAppaRao Puli 
2037a6349918SAppaRao Puli             if (*provState == true)
2038a6349918SAppaRao Puli             {
2039a6349918SAppaRao Puli                 if (*lockState == true)
2040a6349918SAppaRao Puli                 {
2041a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2042a6349918SAppaRao Puli                 }
2043a6349918SAppaRao Puli                 else
2044a6349918SAppaRao Puli                 {
2045a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2046a6349918SAppaRao Puli                 }
2047a6349918SAppaRao Puli             }
2048a6349918SAppaRao Puli             else
2049a6349918SAppaRao Puli             {
2050a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2051a6349918SAppaRao Puli             }
2052a6349918SAppaRao Puli         },
2053a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2054a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
2055a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
2056a6349918SAppaRao Puli }
2057a6349918SAppaRao Puli #endif
2058a6349918SAppaRao Puli 
2059491d8ee7SSantosh Puranik /**
20603a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20613a2d0424SChris Cain  *
20623a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20633a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20643a2d0424SChris Cain  *
20653a2d0424SChris Cain  * @return None.
20663a2d0424SChris Cain  */
20673a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20683a2d0424SChris Cain                                const std::string& modeValue)
20693a2d0424SChris Cain {
20703a2d0424SChris Cain     std::string modeString;
20713a2d0424SChris Cain 
20723a2d0424SChris Cain     if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20733a2d0424SChris Cain                      "PowerMode.Static")
20743a2d0424SChris Cain     {
20753a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20763a2d0424SChris Cain     }
20773a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20783a2d0424SChris Cain                           "PowerMode.MaximumPerformance")
20793a2d0424SChris Cain     {
20803a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20813a2d0424SChris Cain     }
20823a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20833a2d0424SChris Cain                           "PowerMode.PowerSaving")
20843a2d0424SChris Cain     {
20853a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20863a2d0424SChris Cain     }
20873a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20883a2d0424SChris Cain                           "PowerMode.OEM")
20893a2d0424SChris Cain     {
20903a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20913a2d0424SChris Cain     }
20923a2d0424SChris Cain     else
20933a2d0424SChris Cain     {
20943a2d0424SChris Cain         // Any other values would be invalid
20953a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20963a2d0424SChris Cain         messages::internalError(aResp->res);
20973a2d0424SChris Cain     }
20983a2d0424SChris Cain }
20993a2d0424SChris Cain 
21003a2d0424SChris Cain /**
21013a2d0424SChris Cain  * @brief Retrieves system power mode
21023a2d0424SChris Cain  *
21033a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
21043a2d0424SChris Cain  *
21053a2d0424SChris Cain  * @return None.
21063a2d0424SChris Cain  */
21073a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
21083a2d0424SChris Cain {
21093a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
21103a2d0424SChris Cain 
21113a2d0424SChris Cain     // Get Power Mode object path:
21123a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
21133a2d0424SChris Cain         [aResp](
21143a2d0424SChris Cain             const boost::system::error_code ec,
21153a2d0424SChris Cain             const std::vector<std::pair<
21163a2d0424SChris Cain                 std::string,
21173a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
21183a2d0424SChris Cain                 subtree) {
21193a2d0424SChris Cain             if (ec)
21203a2d0424SChris Cain             {
21213a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
21223a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
21233a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
21243a2d0424SChris Cain                 // error occurs
21253a2d0424SChris Cain                 return;
21263a2d0424SChris Cain             }
21273a2d0424SChris Cain             if (subtree.empty())
21283a2d0424SChris Cain             {
21293a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
21303a2d0424SChris Cain                 // if there is no instance found
21313a2d0424SChris Cain                 return;
21323a2d0424SChris Cain             }
21333a2d0424SChris Cain             if (subtree.size() > 1)
21343a2d0424SChris Cain             {
21353a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
21363a2d0424SChris Cain                 // error
21373a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
21383a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
21393a2d0424SChris Cain                     << subtree.size();
21403a2d0424SChris Cain                 messages::internalError(aResp->res);
21413a2d0424SChris Cain                 return;
21423a2d0424SChris Cain             }
21433a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21443a2d0424SChris Cain             {
21453a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21463a2d0424SChris Cain                 messages::internalError(aResp->res);
21473a2d0424SChris Cain                 return;
21483a2d0424SChris Cain             }
21493a2d0424SChris Cain             const std::string& path = subtree[0].first;
21503a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21513a2d0424SChris Cain             if (service.empty())
21523a2d0424SChris Cain             {
21533a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21543a2d0424SChris Cain                 messages::internalError(aResp->res);
21553a2d0424SChris Cain                 return;
21563a2d0424SChris Cain             }
21573a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
21583a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
21593a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
21603a2d0424SChris Cain                         const std::variant<std::string>& pmode) {
21613a2d0424SChris Cain                     if (ec)
21623a2d0424SChris Cain                     {
21633a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
21643a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
21653a2d0424SChris Cain                         messages::internalError(aResp->res);
21663a2d0424SChris Cain                         return;
21673a2d0424SChris Cain                     }
21683a2d0424SChris Cain 
21693a2d0424SChris Cain                     const std::string* s = std::get_if<std::string>(&pmode);
21703a2d0424SChris Cain                     if (s == nullptr)
21713a2d0424SChris Cain                     {
21723a2d0424SChris Cain                         BMCWEB_LOG_DEBUG << "Unable to get PowerMode value";
21733a2d0424SChris Cain                         messages::internalError(aResp->res);
21743a2d0424SChris Cain                         return;
21753a2d0424SChris Cain                     }
21763a2d0424SChris Cain 
21773a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
21783a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
21793a2d0424SChris Cain 
21803a2d0424SChris Cain                     BMCWEB_LOG_DEBUG << "Current power mode: " << *s;
21813a2d0424SChris Cain                     translatePowerMode(aResp, *s);
21823a2d0424SChris Cain                 },
21833a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Get",
21843a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode");
21853a2d0424SChris Cain         },
21863a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21873a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21883a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21893a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21903a2d0424SChris Cain }
21913a2d0424SChris Cain 
21923a2d0424SChris Cain /**
21933a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21943a2d0424SChris Cain  * name associated with that string
21953a2d0424SChris Cain  *
21963a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21973a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21983a2d0424SChris Cain  *
21993a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
22003a2d0424SChris Cain  */
22013a2d0424SChris Cain inline std::string
22023a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
22033a2d0424SChris Cain                       const std::string& modeString)
22043a2d0424SChris Cain {
22053a2d0424SChris Cain     std::string mode;
22063a2d0424SChris Cain 
22073a2d0424SChris Cain     if (modeString == "Static")
22083a2d0424SChris Cain     {
22093a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
22103a2d0424SChris Cain     }
22113a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
22123a2d0424SChris Cain     {
22133a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode."
22143a2d0424SChris Cain                "MaximumPerformance";
22153a2d0424SChris Cain     }
22163a2d0424SChris Cain     else if (modeString == "PowerSaving")
22173a2d0424SChris Cain     {
22183a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
22193a2d0424SChris Cain     }
22203a2d0424SChris Cain     else
22213a2d0424SChris Cain     {
22223a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
22233a2d0424SChris Cain     }
22243a2d0424SChris Cain     return mode;
22253a2d0424SChris Cain }
22263a2d0424SChris Cain 
22273a2d0424SChris Cain /**
22283a2d0424SChris Cain  * @brief Sets system power mode.
22293a2d0424SChris Cain  *
22303a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
22313a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
22323a2d0424SChris Cain  *
22333a2d0424SChris Cain  * @return None.
22343a2d0424SChris Cain  */
22353a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
22363a2d0424SChris Cain                          const std::string& pmode)
22373a2d0424SChris Cain {
22383a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
22393a2d0424SChris Cain 
22403a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
22413a2d0424SChris Cain     if (powerMode.empty())
22423a2d0424SChris Cain     {
22433a2d0424SChris Cain         return;
22443a2d0424SChris Cain     }
22453a2d0424SChris Cain 
22463a2d0424SChris Cain     // Get Power Mode object path:
22473a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
22483a2d0424SChris Cain         [aResp, powerMode](
22493a2d0424SChris Cain             const boost::system::error_code ec,
22503a2d0424SChris Cain             const std::vector<std::pair<
22513a2d0424SChris Cain                 std::string,
22523a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
22533a2d0424SChris Cain                 subtree) {
22543a2d0424SChris Cain             if (ec)
22553a2d0424SChris Cain             {
22563a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22573a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
22583a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22593a2d0424SChris Cain                 messages::internalError(aResp->res);
22603a2d0424SChris Cain                 return;
22613a2d0424SChris Cain             }
22623a2d0424SChris Cain             if (subtree.empty())
22633a2d0424SChris Cain             {
22643a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22653a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
22663a2d0424SChris Cain                                            "PowerMode");
22673a2d0424SChris Cain                 return;
22683a2d0424SChris Cain             }
22693a2d0424SChris Cain             if (subtree.size() > 1)
22703a2d0424SChris Cain             {
22713a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22723a2d0424SChris Cain                 // error
22733a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22743a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
22753a2d0424SChris Cain                     << subtree.size();
22763a2d0424SChris Cain                 messages::internalError(aResp->res);
22773a2d0424SChris Cain                 return;
22783a2d0424SChris Cain             }
22793a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22803a2d0424SChris Cain             {
22813a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22823a2d0424SChris Cain                 messages::internalError(aResp->res);
22833a2d0424SChris Cain                 return;
22843a2d0424SChris Cain             }
22853a2d0424SChris Cain             const std::string& path = subtree[0].first;
22863a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22873a2d0424SChris Cain             if (service.empty())
22883a2d0424SChris Cain             {
22893a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22903a2d0424SChris Cain                 messages::internalError(aResp->res);
22913a2d0424SChris Cain                 return;
22923a2d0424SChris Cain             }
22933a2d0424SChris Cain 
22943a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22953a2d0424SChris Cain                              << path;
22963a2d0424SChris Cain 
22973a2d0424SChris Cain             // Set the Power Mode property
22983a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
22993a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
23003a2d0424SChris Cain                     if (ec)
23013a2d0424SChris Cain                     {
23023a2d0424SChris Cain                         messages::internalError(aResp->res);
23033a2d0424SChris Cain                         return;
23043a2d0424SChris Cain                     }
23053a2d0424SChris Cain                 },
23063a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
23073a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
23083a2d0424SChris Cain                 std::variant<std::string>(powerMode));
23093a2d0424SChris Cain         },
23103a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
23113a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
23123a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
23133a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
23143a2d0424SChris Cain }
23153a2d0424SChris Cain 
23163a2d0424SChris Cain /**
231751709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
231851709ffdSYong Li  *
231951709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
232051709ffdSYong Li  *
232151709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
232251709ffdSYong Li  * translation cannot be done, returns an empty string.
232351709ffdSYong Li  */
232423a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
232551709ffdSYong Li {
232651709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
232751709ffdSYong Li     {
232851709ffdSYong Li         return "None";
232951709ffdSYong Li     }
23303174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
233151709ffdSYong Li     {
233251709ffdSYong Li         return "ResetSystem";
233351709ffdSYong Li     }
23343174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
233551709ffdSYong Li     {
233651709ffdSYong Li         return "PowerDown";
233751709ffdSYong Li     }
23383174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
233951709ffdSYong Li     {
234051709ffdSYong Li         return "PowerCycle";
234151709ffdSYong Li     }
234251709ffdSYong Li 
234351709ffdSYong Li     return "";
234451709ffdSYong Li }
234551709ffdSYong Li 
234651709ffdSYong Li /**
2347c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2348c45f0082SYong Li  *
2349c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2350c45f0082SYong Li  *
2351c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2352c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2353c45f0082SYong Li  */
2354c45f0082SYong Li 
235523a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2356c45f0082SYong Li {
2357c45f0082SYong Li     if (rfAction == "None")
2358c45f0082SYong Li     {
2359c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2360c45f0082SYong Li     }
23613174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2362c45f0082SYong Li     {
2363c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2364c45f0082SYong Li     }
23653174e4dfSEd Tanous     if (rfAction == "PowerDown")
2366c45f0082SYong Li     {
2367c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2368c45f0082SYong Li     }
23693174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2370c45f0082SYong Li     {
2371c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2372c45f0082SYong Li     }
2373c45f0082SYong Li 
2374c45f0082SYong Li     return "";
2375c45f0082SYong Li }
2376c45f0082SYong Li 
2377c45f0082SYong Li /**
237851709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
237951709ffdSYong Li  *
238051709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
238151709ffdSYong Li  *
238251709ffdSYong Li  * @return None.
238351709ffdSYong Li  */
23848d1b46d7Szhanghch05 inline void
23858d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
238651709ffdSYong Li {
238751709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
238851709ffdSYong Li     crow::connections::systemBus->async_method_call(
238951709ffdSYong Li         [aResp](const boost::system::error_code ec,
239051709ffdSYong Li                 PropertiesType& properties) {
239151709ffdSYong Li             if (ec)
239251709ffdSYong Li             {
239351709ffdSYong Li                 // watchdog service is stopped
239451709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
239551709ffdSYong Li                 return;
239651709ffdSYong Li             }
239751709ffdSYong Li 
239851709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
239951709ffdSYong Li 
240051709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
240151709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
240251709ffdSYong Li 
240351709ffdSYong Li             // watchdog service is running/enabled
240451709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
240551709ffdSYong Li 
240651709ffdSYong Li             for (const auto& property : properties)
240751709ffdSYong Li             {
240851709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
240951709ffdSYong Li                 if (property.first == "Enabled")
241051709ffdSYong Li                 {
241151709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
241251709ffdSYong Li 
241351709ffdSYong Li                     if (!state)
241451709ffdSYong Li                     {
241551709ffdSYong Li                         messages::internalError(aResp->res);
2416601af5edSChicago Duan                         return;
241751709ffdSYong Li                     }
241851709ffdSYong Li 
241951709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
242051709ffdSYong Li                 }
242151709ffdSYong Li                 else if (property.first == "ExpireAction")
242251709ffdSYong Li                 {
242351709ffdSYong Li                     const std::string* s =
242451709ffdSYong Li                         std::get_if<std::string>(&property.second);
242551709ffdSYong Li                     if (!s)
242651709ffdSYong Li                     {
242751709ffdSYong Li                         messages::internalError(aResp->res);
2428601af5edSChicago Duan                         return;
242951709ffdSYong Li                     }
243051709ffdSYong Li 
243151709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
243251709ffdSYong Li                     if (action.empty())
243351709ffdSYong Li                     {
243451709ffdSYong Li                         messages::internalError(aResp->res);
2435601af5edSChicago Duan                         return;
243651709ffdSYong Li                     }
243751709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
243851709ffdSYong Li                 }
243951709ffdSYong Li             }
244051709ffdSYong Li         },
244151709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
244251709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
244351709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
244451709ffdSYong Li }
244551709ffdSYong Li 
244651709ffdSYong Li /**
2447c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2448c45f0082SYong Li  *
2449c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2450c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2451c45f0082SYong Li  *                       RF request.
2452c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2453c45f0082SYong Li  *
2454c45f0082SYong Li  * @return None.
2455c45f0082SYong Li  */
24568d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2457c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2458c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2459c45f0082SYong Li {
2460c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2461c45f0082SYong Li 
2462c45f0082SYong Li     if (wdtTimeOutAction)
2463c45f0082SYong Li     {
2464c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2465c45f0082SYong Li         // check if TimeOut Action is Valid
2466c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2467c45f0082SYong Li         {
2468c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2469c45f0082SYong Li                              << *wdtTimeOutAction;
2470c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2471c45f0082SYong Li                                              "TimeoutAction");
2472c45f0082SYong Li             return;
2473c45f0082SYong Li         }
2474c45f0082SYong Li 
2475c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2476c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2477c45f0082SYong Li                 if (ec)
2478c45f0082SYong Li                 {
2479c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2480c45f0082SYong Li                     messages::internalError(aResp->res);
2481c45f0082SYong Li                     return;
2482c45f0082SYong Li                 }
2483c45f0082SYong Li             },
2484c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2485c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2486c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2487c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2488c45f0082SYong Li             std::variant<std::string>(wdtTimeOutActStr));
2489c45f0082SYong Li     }
2490c45f0082SYong Li 
2491c45f0082SYong Li     if (wdtEnable)
2492c45f0082SYong Li     {
2493c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2494c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2495c45f0082SYong Li                 if (ec)
2496c45f0082SYong Li                 {
2497c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2498c45f0082SYong Li                     messages::internalError(aResp->res);
2499c45f0082SYong Li                     return;
2500c45f0082SYong Li                 }
2501c45f0082SYong Li             },
2502c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2503c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2504c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2505c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2506c45f0082SYong Li             std::variant<bool>(*wdtEnable));
2507c45f0082SYong Li     }
2508c45f0082SYong Li }
2509c45f0082SYong Li 
2510c45f0082SYong Li /**
2511c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2512c5b2abe0SLewanczyk, Dawid  * Schema
2513c5b2abe0SLewanczyk, Dawid  */
25147e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
25151abe55efSEd Tanous {
25167e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2517ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
25187e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
25194f48d5f6SEd Tanous             [](const crow::Request& /*req*/,
25207e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
25218d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
25220f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
25238d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
25248d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2525462023adSSunitha Harish 
2526462023adSSunitha Harish                 crow::connections::systemBus->async_method_call(
25274f48d5f6SEd Tanous                     [asyncResp](const boost::system::error_code ec,
2528cb13a392SEd Tanous                                 const std::variant<std::string>& /*hostName*/) {
25292c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2530462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
25312c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
25327e860f15SJohn Edward Broadbent                         auto& count =
25337e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
25342c70f800SEd Tanous                         ifaceArray.push_back(
2535cb13a392SEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/system"}});
253694bda602STim Lee                         count = ifaceArray.size();
2537cb13a392SEd Tanous                         if (!ec)
2538462023adSSunitha Harish                         {
2539462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
25402c70f800SEd Tanous                             ifaceArray.push_back(
25417e860f15SJohn Edward Broadbent                                 {{"@odata.id",
25427e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/hypervisor"}});
25432c70f800SEd Tanous                             count = ifaceArray.size();
2544cb13a392SEd Tanous                         }
2545462023adSSunitha Harish                     },
25468e651fbfSSunitha Harish                     "xyz.openbmc_project.Settings",
25478e651fbfSSunitha Harish                     "/xyz/openbmc_project/network/hypervisor",
2548462023adSSunitha Harish                     "org.freedesktop.DBus.Properties", "Get",
25497e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.Network.SystemConfiguration",
25507e860f15SJohn Edward Broadbent                     "HostName");
25517e860f15SJohn Edward Broadbent             });
2552c5b2abe0SLewanczyk, Dawid }
25537e860f15SJohn Edward Broadbent 
25547e860f15SJohn Edward Broadbent /**
25557e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
25567e860f15SJohn Edward Broadbent  */
25574f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
25587e860f15SJohn Edward Broadbent {
25597e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
25607e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
25617e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
25627e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
25637e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
25647e860f15SJohn Edward Broadbent 
25657e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
25667e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
25677e860f15SJohn Edward Broadbent             if (ec)
25687e860f15SJohn Edward Broadbent             {
25697e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
25707e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
25717e860f15SJohn Edward Broadbent                 return;
25727e860f15SJohn Edward Broadbent             }
25737e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
25747e860f15SJohn Edward Broadbent         },
25757e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
25767e860f15SJohn Edward Broadbent }
2577c5b2abe0SLewanczyk, Dawid 
2578c5b2abe0SLewanczyk, Dawid /**
2579cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2580cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2581cc340dd9SEd Tanous  */
25827e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2583cc340dd9SEd Tanous {
2584cc340dd9SEd Tanous     /**
2585cc340dd9SEd Tanous      * Function handles POST method request.
2586cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2587cc340dd9SEd Tanous      */
25887e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
25897e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2590ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
25917e860f15SJohn Edward Broadbent         .methods(
25927e860f15SJohn Edward Broadbent             boost::beast::http::verb::
25937e860f15SJohn Edward Broadbent                 post)([](const crow::Request& req,
25947e860f15SJohn Edward Broadbent                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
25959712f8acSEd Tanous             std::string resetType;
25967e860f15SJohn Edward Broadbent             if (!json_util::readJson(req, asyncResp->res, "ResetType",
25977e860f15SJohn Edward Broadbent                                      resetType))
2598cc340dd9SEd Tanous             {
2599cc340dd9SEd Tanous                 return;
2600cc340dd9SEd Tanous             }
2601cc340dd9SEd Tanous 
2602d22c8396SJason M. Bills             // Get the command and host vs. chassis
2603cc340dd9SEd Tanous             std::string command;
2604d22c8396SJason M. Bills             bool hostCommand;
2605d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2606cc340dd9SEd Tanous             {
2607cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2608d22c8396SJason M. Bills                 hostCommand = true;
2609d22c8396SJason M. Bills             }
2610d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2611d22c8396SJason M. Bills             {
2612d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2613d22c8396SJason M. Bills                 hostCommand = false;
2614d22c8396SJason M. Bills             }
2615d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2616d22c8396SJason M. Bills             {
261786a0851aSJason M. Bills                 command =
261886a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
261986a0851aSJason M. Bills                 hostCommand = true;
2620cc340dd9SEd Tanous             }
26219712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2622cc340dd9SEd Tanous             {
2623cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2624d22c8396SJason M. Bills                 hostCommand = true;
2625cc340dd9SEd Tanous             }
26269712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2627cc340dd9SEd Tanous             {
26287e860f15SJohn Edward Broadbent                 command = "xyz.openbmc_project.State.Host.Transition."
26297e860f15SJohn Edward Broadbent                           "GracefulWarmReboot";
2630d22c8396SJason M. Bills                 hostCommand = true;
2631d22c8396SJason M. Bills             }
2632d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2633d22c8396SJason M. Bills             {
263486a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
263586a0851aSJason M. Bills                 hostCommand = true;
2636cc340dd9SEd Tanous             }
2637bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2638bfd5b826SLakshminarayana R. Kammath             {
2639bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2640bfd5b826SLakshminarayana R. Kammath                 return;
2641bfd5b826SLakshminarayana R. Kammath             }
2642cc340dd9SEd Tanous             else
2643cc340dd9SEd Tanous             {
26448d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
26458d1b46d7Szhanghch05                                                  resetType);
2646cc340dd9SEd Tanous                 return;
2647cc340dd9SEd Tanous             }
2648cc340dd9SEd Tanous 
2649d22c8396SJason M. Bills             if (hostCommand)
2650d22c8396SJason M. Bills             {
2651cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2652d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2653cc340dd9SEd Tanous                         if (ec)
2654cc340dd9SEd Tanous                         {
2655cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
26567e860f15SJohn Edward Broadbent                             if (ec.value() ==
26577e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2658d22c8396SJason M. Bills                             {
2659d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2660d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2661d22c8396SJason M. Bills                             }
2662d22c8396SJason M. Bills                             else
2663d22c8396SJason M. Bills                             {
2664f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2665d22c8396SJason M. Bills                             }
2666cc340dd9SEd Tanous                             return;
2667cc340dd9SEd Tanous                         }
2668f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2669cc340dd9SEd Tanous                     },
2670cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2671cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2672cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
26739712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2674abf2add6SEd Tanous                     std::variant<std::string>{command});
2675cc340dd9SEd Tanous             }
2676d22c8396SJason M. Bills             else
2677d22c8396SJason M. Bills             {
2678d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2679d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2680d22c8396SJason M. Bills                         if (ec)
2681d22c8396SJason M. Bills                         {
2682d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
26837e860f15SJohn Edward Broadbent                             if (ec.value() ==
26847e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2685d22c8396SJason M. Bills                             {
2686d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2687d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2688d22c8396SJason M. Bills                             }
2689d22c8396SJason M. Bills                             else
2690d22c8396SJason M. Bills                             {
2691d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2692d22c8396SJason M. Bills                             }
2693d22c8396SJason M. Bills                             return;
2694d22c8396SJason M. Bills                         }
2695d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2696d22c8396SJason M. Bills                     },
2697d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
2698d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
2699d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
27007e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
27017e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
2702d22c8396SJason M. Bills                     std::variant<std::string>{command});
2703d22c8396SJason M. Bills             }
27047e860f15SJohn Edward Broadbent         });
2705d22c8396SJason M. Bills }
2706cc340dd9SEd Tanous 
2707cc340dd9SEd Tanous /**
27086617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2709c5b2abe0SLewanczyk, Dawid  */
27107e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
27111abe55efSEd Tanous {
2712c5b2abe0SLewanczyk, Dawid 
2713c5b2abe0SLewanczyk, Dawid     /**
2714c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2715c5b2abe0SLewanczyk, Dawid      */
27167e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2717ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
27187e860f15SJohn Edward Broadbent         .methods(
27197e860f15SJohn Edward Broadbent             boost::beast::http::verb::
27207e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
27217e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
27228d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
27233a2d0424SChris Cain                 "#ComputerSystem.v1_15_0.ComputerSystem";
27248d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
27258d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
27268d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
27278d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
27288d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
27298d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
27308d1b46d7Szhanghch05                 "Disabled";
27318d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
27328d1b46d7Szhanghch05                 uint64_t(0);
27338d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
27348d1b46d7Szhanghch05                 "Disabled";
27357e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
27367e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
273704a258f4SEd Tanous 
27388d1b46d7Szhanghch05             asyncResp->res.jsonValue["Processors"] = {
2739029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
27408d1b46d7Szhanghch05             asyncResp->res.jsonValue["Memory"] = {
2741029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
27428d1b46d7Szhanghch05             asyncResp->res.jsonValue["Storage"] = {
2743a25aeccfSNikhil Potade                 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
2744029573d4SEd Tanous 
27458d1b46d7Szhanghch05             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
2746cc340dd9SEd Tanous                 {"target",
2747029573d4SEd Tanous                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
27481cb1a9e6SAppaRao Puli                 {"@Redfish.ActionInfo",
27491cb1a9e6SAppaRao Puli                  "/redfish/v1/Systems/system/ResetActionInfo"}};
2750c5b2abe0SLewanczyk, Dawid 
27518d1b46d7Szhanghch05             asyncResp->res.jsonValue["LogServices"] = {
2752029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
2753c4bf6374SJason M. Bills 
27548d1b46d7Szhanghch05             asyncResp->res.jsonValue["Bios"] = {
2755d82a3acdSCarol Wang                 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
2756d82a3acdSCarol Wang 
27578d1b46d7Szhanghch05             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
2758c5d03ff4SJennifer Lee                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
2759c5d03ff4SJennifer Lee 
27608d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"] = {
2761c5d03ff4SJennifer Lee                 {"Health", "OK"},
2762c5d03ff4SJennifer Lee                 {"State", "Enabled"},
2763c5d03ff4SJennifer Lee             };
27640e8ac5e7SGunnar Mills 
27650e8ac5e7SGunnar Mills             // Fill in SerialConsole info
27660e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
27670e8ac5e7SGunnar Mills                 15;
27680e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
27690e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27700e8ac5e7SGunnar Mills             };
27710e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
27720e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
27730e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27740e8ac5e7SGunnar Mills                 {"Port", 2200},
27750e8ac5e7SGunnar Mills                 // https://github.com/openbmc/docs/blob/master/console.md
27760e8ac5e7SGunnar Mills                 {"HotKeySequenceDisplay", "Press ~. to exit console"},
27770e8ac5e7SGunnar Mills             };
27780e8ac5e7SGunnar Mills 
27790e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
27800e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
27810e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["GraphicalConsole"] = {
27820e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27830e8ac5e7SGunnar Mills                 {"MaxConcurrentSessions", 4},
27840e8ac5e7SGunnar Mills                 {"ConnectTypesSupported", {"KVMIP"}},
27850e8ac5e7SGunnar Mills             };
27860e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2787e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
2788b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
27892ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
2790e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
2791e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
2792b49ac873SJames Feist 
2793b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
2794b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
2795b49ac873SJames Feist                 [health](const boost::system::error_code ec,
2796b49ac873SJames Feist                          std::vector<std::string>& resp) {
2797b49ac873SJames Feist                     if (ec)
2798b49ac873SJames Feist                     {
2799b49ac873SJames Feist                         // no inventory
2800b49ac873SJames Feist                         return;
2801b49ac873SJames Feist                     }
2802b49ac873SJames Feist 
2803b49ac873SJames Feist                     health->inventory = std::move(resp);
2804b49ac873SJames Feist                 },
2805b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
2806b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
2807b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2808b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
2809b49ac873SJames Feist 
2810b49ac873SJames Feist             health->populate();
2811b49ac873SJames Feist 
28128d1b46d7Szhanghch05             getMainChassisId(
28138d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
28148d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2815c5d03ff4SJennifer Lee                     aRsp->res.jsonValue["Links"]["Chassis"] = {
2816c5d03ff4SJennifer Lee                         {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
2817c5d03ff4SJennifer Lee                 });
2818a3002228SAppaRao Puli 
28199f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
28209f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2821a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
28225bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
28236c34de48SEd Tanous             getHostState(asyncResp);
2824491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
2825978b8803SAndrew Geissler             getBootProgress(asyncResp);
2826adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
282751709ffdSYong Li             getHostWatchdogTimer(asyncResp);
2828c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
28296bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
2830c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
2831a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2832a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
2833a6349918SAppaRao Puli #endif
28341981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
28353a2d0424SChris Cain             getPowerMode(asyncResp);
28367e860f15SJohn Edward Broadbent         });
28377e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2838ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
28397e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
28407e860f15SJohn Edward Broadbent             [](const crow::Request& req,
28417e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28429f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
2843cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
2844491d8ee7SSantosh Puranik                 std::optional<nlohmann::json> bootProps;
2845c45f0082SYong Li                 std::optional<nlohmann::json> wdtTimerProps;
284698e386ecSGunnar Mills                 std::optional<std::string> assetTag;
2847c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
28483a2d0424SChris Cain                 std::optional<std::string> powerMode;
2849*1c05dae3SAli Ahmed                 std::optional<bool> trustedModuleRequiredToBoot;
28509f8bfa7cSGunnar Mills                 if (!json_util::readJson(
28518d1b46d7Szhanghch05                         req, asyncResp->res, "IndicatorLED", indicatorLed,
28527e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
28537e860f15SJohn Edward Broadbent                         "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
28547e860f15SJohn Edward Broadbent                         "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
2855*1c05dae3SAli Ahmed                         assetTag, "PowerMode", powerMode,
2856*1c05dae3SAli Ahmed                         "TrustedModuleRequiredToBoot",
2857*1c05dae3SAli Ahmed                         trustedModuleRequiredToBoot))
28586617338dSEd Tanous                 {
28596617338dSEd Tanous                     return;
28606617338dSEd Tanous                 }
2861491d8ee7SSantosh Puranik 
28628d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
2863c45f0082SYong Li 
286498e386ecSGunnar Mills                 if (assetTag)
286598e386ecSGunnar Mills                 {
286698e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
286798e386ecSGunnar Mills                 }
286898e386ecSGunnar Mills 
2869c45f0082SYong Li                 if (wdtTimerProps)
2870c45f0082SYong Li                 {
2871c45f0082SYong Li                     std::optional<bool> wdtEnable;
2872c45f0082SYong Li                     std::optional<std::string> wdtTimeOutAction;
2873c45f0082SYong Li 
2874c45f0082SYong Li                     if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2875c45f0082SYong Li                                              "FunctionEnabled", wdtEnable,
2876c45f0082SYong Li                                              "TimeoutAction", wdtTimeOutAction))
2877c45f0082SYong Li                     {
2878c45f0082SYong Li                         return;
2879c45f0082SYong Li                     }
2880f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
2881c45f0082SYong Li                 }
2882c45f0082SYong Li 
2883491d8ee7SSantosh Puranik                 if (bootProps)
2884491d8ee7SSantosh Puranik                 {
2885491d8ee7SSantosh Puranik                     std::optional<std::string> bootSource;
2886cd9a4666SKonstantin Aladyshev                     std::optional<std::string> bootType;
2887491d8ee7SSantosh Puranik                     std::optional<std::string> bootEnable;
288869f35306SGunnar Mills                     std::optional<std::string> automaticRetryConfig;
2889491d8ee7SSantosh Puranik 
289069f35306SGunnar Mills                     if (!json_util::readJson(
28917e860f15SJohn Edward Broadbent                             *bootProps, asyncResp->res,
28927e860f15SJohn Edward Broadbent                             "BootSourceOverrideTarget", bootSource,
2893cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode", bootType,
28947e860f15SJohn Edward Broadbent                             "BootSourceOverrideEnabled", bootEnable,
289569f35306SGunnar Mills                             "AutomaticRetryConfig", automaticRetryConfig))
2896491d8ee7SSantosh Puranik                     {
2897491d8ee7SSantosh Puranik                         return;
2898491d8ee7SSantosh Puranik                     }
2899c21865c4SKonstantin Aladyshev 
2900cd9a4666SKonstantin Aladyshev                     if (bootSource || bootType || bootEnable)
290169f35306SGunnar Mills                     {
2902c21865c4SKonstantin Aladyshev                         setBootProperties(asyncResp, bootSource, bootType,
2903c21865c4SKonstantin Aladyshev                                           bootEnable);
2904491d8ee7SSantosh Puranik                     }
290569f35306SGunnar Mills                     if (automaticRetryConfig)
290669f35306SGunnar Mills                     {
2907f23b7296SEd Tanous                         setAutomaticRetry(asyncResp, *automaticRetryConfig);
290869f35306SGunnar Mills                     }
290969f35306SGunnar Mills                 }
2910265c1602SJohnathan Mantey 
29119f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
29129f8bfa7cSGunnar Mills                 {
29137e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
29147e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
29159f8bfa7cSGunnar Mills                 }
29169f8bfa7cSGunnar Mills 
29177e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
29187e860f15SJohn Edward Broadbent                 // passed
29199712f8acSEd Tanous                 if (indicatorLed)
29206617338dSEd Tanous                 {
2921f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
29227e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
29237e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
2924d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
2925d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
29266617338dSEd Tanous                 }
2927c6a620f2SGeorge Liu 
2928c6a620f2SGeorge Liu                 if (powerRestorePolicy)
2929c6a620f2SGeorge Liu                 {
29304e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
2931c6a620f2SGeorge Liu                 }
29323a2d0424SChris Cain 
29333a2d0424SChris Cain                 if (powerMode)
29343a2d0424SChris Cain                 {
29353a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
29363a2d0424SChris Cain                 }
2937*1c05dae3SAli Ahmed 
2938*1c05dae3SAli Ahmed                 if (trustedModuleRequiredToBoot)
2939*1c05dae3SAli Ahmed                 {
2940*1c05dae3SAli Ahmed                     setTrustedModuleRequiredToBoot(
2941*1c05dae3SAli Ahmed                         asyncResp, *trustedModuleRequiredToBoot);
2942*1c05dae3SAli Ahmed                 }
29437e860f15SJohn Edward Broadbent             });
2944c5b2abe0SLewanczyk, Dawid }
29451cb1a9e6SAppaRao Puli 
29461cb1a9e6SAppaRao Puli /**
29471cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
29481cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
29491cb1a9e6SAppaRao Puli  */
29507e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
29511cb1a9e6SAppaRao Puli {
29521cb1a9e6SAppaRao Puli 
29531cb1a9e6SAppaRao Puli     /**
29541cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
29551cb1a9e6SAppaRao Puli      */
29567e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2957ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
29587e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
29597e860f15SJohn Edward Broadbent             [](const crow::Request&,
29607e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
29618d1b46d7Szhanghch05                 asyncResp->res.jsonValue = {
29621cb1a9e6SAppaRao Puli                     {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
29631cb1a9e6SAppaRao Puli                     {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
29641cb1a9e6SAppaRao Puli                     {"Name", "Reset Action Info"},
29651cb1a9e6SAppaRao Puli                     {"Id", "ResetActionInfo"},
29661cb1a9e6SAppaRao Puli                     {"Parameters",
29671cb1a9e6SAppaRao Puli                      {{{"Name", "ResetType"},
29681cb1a9e6SAppaRao Puli                        {"Required", true},
29691cb1a9e6SAppaRao Puli                        {"DataType", "String"},
29701cb1a9e6SAppaRao Puli                        {"AllowableValues",
29717e860f15SJohn Edward Broadbent                         {"On", "ForceOff", "ForceOn", "ForceRestart",
29727e860f15SJohn Edward Broadbent                          "GracefulRestart", "GracefulShutdown", "PowerCycle",
29737e860f15SJohn Edward Broadbent                          "Nmi"}}}}}};
29747e860f15SJohn Edward Broadbent             });
29751cb1a9e6SAppaRao Puli }
2976c5b2abe0SLewanczyk, Dawid } // namespace redfish
2977