xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 03fbed9286a2086abd43b05c34f2ebbc1cc79c1f)
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 
142*03fbed92SAli Ahmed inline void getProcessorProperties(
143*03fbed92SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
144*03fbed92SAli Ahmed     const std::string& path,
145*03fbed92SAli Ahmed     const std::vector<std::pair<
146*03fbed92SAli Ahmed         std::string, std::variant<std::string, uint64_t, uint32_t, uint16_t>>>&
147*03fbed92SAli Ahmed         properties)
148*03fbed92SAli Ahmed {
149*03fbed92SAli Ahmed 
150*03fbed92SAli Ahmed     BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
151*03fbed92SAli Ahmed 
152*03fbed92SAli Ahmed     auto getCpuPresenceState =
153*03fbed92SAli Ahmed         [aResp](const boost::system::error_code ec3,
154*03fbed92SAli Ahmed                 const std::variant<bool>& cpuPresenceCheck) {
155*03fbed92SAli Ahmed             if (ec3)
156*03fbed92SAli Ahmed             {
157*03fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
158*03fbed92SAli Ahmed                 return;
159*03fbed92SAli Ahmed             }
160*03fbed92SAli Ahmed             modifyCpuPresenceState(aResp, cpuPresenceCheck);
161*03fbed92SAli Ahmed         };
162*03fbed92SAli Ahmed 
163*03fbed92SAli Ahmed     auto getCpuFunctionalState =
164*03fbed92SAli Ahmed         [aResp](const boost::system::error_code ec3,
165*03fbed92SAli Ahmed                 const std::variant<bool>& cpuFunctionalCheck) {
166*03fbed92SAli Ahmed             if (ec3)
167*03fbed92SAli Ahmed             {
168*03fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
169*03fbed92SAli Ahmed                 return;
170*03fbed92SAli Ahmed             }
171*03fbed92SAli Ahmed             modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
172*03fbed92SAli Ahmed         };
173*03fbed92SAli Ahmed 
174*03fbed92SAli Ahmed     // Get the Presence of CPU
175*03fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
176*03fbed92SAli Ahmed         std::move(getCpuPresenceState), service, path,
177*03fbed92SAli Ahmed         "org.freedesktop.DBus.Properties", "Get",
178*03fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item", "Present");
179*03fbed92SAli Ahmed 
180*03fbed92SAli Ahmed     // Get the Functional State
181*03fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
182*03fbed92SAli Ahmed         std::move(getCpuFunctionalState), service, path,
183*03fbed92SAli Ahmed         "org.freedesktop.DBus.Properties", "Get",
184*03fbed92SAli Ahmed         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional");
185*03fbed92SAli Ahmed 
186*03fbed92SAli Ahmed     for (const auto& property : properties)
187*03fbed92SAli Ahmed     {
188*03fbed92SAli Ahmed 
189*03fbed92SAli Ahmed         // TODO: Get Model
190*03fbed92SAli Ahmed 
191*03fbed92SAli Ahmed         // Get CoreCount
192*03fbed92SAli Ahmed         if (property.first == "CoreCount")
193*03fbed92SAli Ahmed         {
194*03fbed92SAli Ahmed 
195*03fbed92SAli Ahmed             // Get CPU CoreCount and add it to the total
196*03fbed92SAli Ahmed             const uint16_t* coreCountVal =
197*03fbed92SAli Ahmed                 std::get_if<uint16_t>(&property.second);
198*03fbed92SAli Ahmed 
199*03fbed92SAli Ahmed             if (!coreCountVal)
200*03fbed92SAli Ahmed             {
201*03fbed92SAli Ahmed                 messages::internalError(aResp->res);
202*03fbed92SAli Ahmed                 return;
203*03fbed92SAli Ahmed             }
204*03fbed92SAli Ahmed 
205*03fbed92SAli Ahmed             nlohmann::json& coreCount =
206*03fbed92SAli Ahmed                 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
207*03fbed92SAli Ahmed             uint64_t* coreCountPtr = coreCount.get_ptr<uint64_t*>();
208*03fbed92SAli Ahmed 
209*03fbed92SAli Ahmed             if (coreCountPtr == nullptr)
210*03fbed92SAli Ahmed             {
211*03fbed92SAli Ahmed                 coreCount = 0;
212*03fbed92SAli Ahmed             }
213*03fbed92SAli Ahmed             else
214*03fbed92SAli Ahmed             {
215*03fbed92SAli Ahmed                 *coreCountPtr += *coreCountVal;
216*03fbed92SAli Ahmed             }
217*03fbed92SAli Ahmed         }
218*03fbed92SAli Ahmed     }
219*03fbed92SAli Ahmed }
220*03fbed92SAli Ahmed 
221*03fbed92SAli Ahmed /*
222*03fbed92SAli Ahmed  * @brief Get ProcessorSummary fields
223*03fbed92SAli Ahmed  *
224*03fbed92SAli Ahmed  * @param[in] aResp Shared pointer for completing asynchronous calls
225*03fbed92SAli Ahmed  * @param[in] service dbus service for Cpu Information
226*03fbed92SAli Ahmed  * @param[in] path dbus path for Cpu
227*03fbed92SAli Ahmed  *
228*03fbed92SAli Ahmed  * @return None.
229*03fbed92SAli Ahmed  */
230*03fbed92SAli Ahmed inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
231*03fbed92SAli Ahmed                                 const std::string& service,
232*03fbed92SAli Ahmed                                 const std::string& path)
233*03fbed92SAli Ahmed {
234*03fbed92SAli Ahmed 
235*03fbed92SAli Ahmed     crow::connections::systemBus->async_method_call(
236*03fbed92SAli Ahmed         [aResp, service,
237*03fbed92SAli Ahmed          path](const boost::system::error_code ec2,
238*03fbed92SAli Ahmed                const std::vector<std::pair<
239*03fbed92SAli Ahmed                    std::string, std::variant<std::string, uint64_t, uint32_t,
240*03fbed92SAli Ahmed                                              uint16_t>>>& properties) {
241*03fbed92SAli Ahmed             if (ec2)
242*03fbed92SAli Ahmed             {
243*03fbed92SAli Ahmed                 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
244*03fbed92SAli Ahmed                 messages::internalError(aResp->res);
245*03fbed92SAli Ahmed                 return;
246*03fbed92SAli Ahmed             }
247*03fbed92SAli Ahmed             getProcessorProperties(aResp, service, path, properties);
248*03fbed92SAli Ahmed         },
249*03fbed92SAli Ahmed         service, path, "org.freedesktop.DBus.Properties", "GetAll",
250*03fbed92SAli Ahmed         "xyz.openbmc_project.Inventory.Item.Cpu");
251*03fbed92SAli Ahmed }
252*03fbed92SAli Ahmed 
25357e8c9beSAlpana Kumari /*
254c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
255c5b2abe0SLewanczyk, Dawid  *
256c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
2578f9ee3cdSGunnar Mills  * @param[in] systemHealth  Shared HealthPopulate pointer
258c5b2abe0SLewanczyk, Dawid  *
259c5b2abe0SLewanczyk, Dawid  * @return None.
260c5b2abe0SLewanczyk, Dawid  */
261b5a76932SEd Tanous inline void
2628d1b46d7Szhanghch05     getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
263b5a76932SEd Tanous                       const std::shared_ptr<HealthPopulate>& systemHealth)
2641abe55efSEd Tanous {
26555c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
2669d3ae10eSAlpana Kumari 
26755c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
2685bc2dc8eSJames Feist         [aResp, systemHealth](
269c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
270c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
2716c34de48SEd Tanous                 std::string,
2721214b7e7SGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
2731214b7e7SGunnar Mills                 subtree) {
2741abe55efSEd Tanous             if (ec)
2751abe55efSEd Tanous             {
27655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
277f12894f8SJason M. Bills                 messages::internalError(aResp->res);
278c5b2abe0SLewanczyk, Dawid                 return;
279c5b2abe0SLewanczyk, Dawid             }
280c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
2816c34de48SEd Tanous             for (const std::pair<std::string,
2826c34de48SEd Tanous                                  std::vector<std::pair<
2831214b7e7SGunnar Mills                                      std::string, std::vector<std::string>>>>&
2841214b7e7SGunnar Mills                      object : subtree)
2851abe55efSEd Tanous             {
286c5b2abe0SLewanczyk, Dawid                 const std::string& path = object.first;
28755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
2881abe55efSEd Tanous                 const std::vector<
2891214b7e7SGunnar Mills                     std::pair<std::string, std::vector<std::string>>>&
2901214b7e7SGunnar Mills                     connectionNames = object.second;
2911abe55efSEd Tanous                 if (connectionNames.size() < 1)
2921abe55efSEd Tanous                 {
293c5b2abe0SLewanczyk, Dawid                     continue;
294c5b2abe0SLewanczyk, Dawid                 }
295029573d4SEd Tanous 
2965bc2dc8eSJames Feist                 auto memoryHealth = std::make_shared<HealthPopulate>(
2975bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
2985bc2dc8eSJames Feist 
2995bc2dc8eSJames Feist                 auto cpuHealth = std::make_shared<HealthPopulate>(
3005bc2dc8eSJames Feist                     aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
3015bc2dc8eSJames Feist 
3025bc2dc8eSJames Feist                 systemHealth->children.emplace_back(memoryHealth);
3035bc2dc8eSJames Feist                 systemHealth->children.emplace_back(cpuHealth);
3045bc2dc8eSJames Feist 
3056c34de48SEd Tanous                 // This is not system, so check if it's cpu, dimm, UUID or
3066c34de48SEd Tanous                 // BiosVer
30704a258f4SEd Tanous                 for (const auto& connection : connectionNames)
3081abe55efSEd Tanous                 {
30904a258f4SEd Tanous                     for (const auto& interfaceName : connection.second)
3101abe55efSEd Tanous                     {
31104a258f4SEd Tanous                         if (interfaceName ==
31204a258f4SEd Tanous                             "xyz.openbmc_project.Inventory.Item.Dimm")
3131abe55efSEd Tanous                         {
3141abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
31504a258f4SEd Tanous                                 << "Found Dimm, now get its properties.";
3169d3ae10eSAlpana Kumari 
31755c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
3189d3ae10eSAlpana Kumari                                 [aResp, service{connection.first},
319f23b7296SEd Tanous                                  path](const boost::system::error_code ec2,
3206c34de48SEd Tanous                                        const std::vector<
3211214b7e7SGunnar Mills                                            std::pair<std::string, VariantType>>&
3221214b7e7SGunnar Mills                                            properties) {
323cb13a392SEd Tanous                                     if (ec2)
3241abe55efSEd Tanous                                     {
3251abe55efSEd Tanous                                         BMCWEB_LOG_ERROR
326cb13a392SEd Tanous                                             << "DBUS response error " << ec2;
327f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
328c5b2abe0SLewanczyk, Dawid                                         return;
329c5b2abe0SLewanczyk, Dawid                                     }
3306c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
3316c34de48SEd Tanous                                                      << properties.size()
332c5b2abe0SLewanczyk, Dawid                                                      << " Dimm properties.";
3339d3ae10eSAlpana Kumari 
3349d3ae10eSAlpana Kumari                                     if (properties.size() > 0)
3359d3ae10eSAlpana Kumari                                     {
33604a258f4SEd Tanous                                         for (const std::pair<std::string,
3371214b7e7SGunnar Mills                                                              VariantType>&
3381214b7e7SGunnar Mills                                                  property : properties)
3391abe55efSEd Tanous                                         {
3405fd7ba65SCheng C Yang                                             if (property.first !=
3415fd7ba65SCheng C Yang                                                 "MemorySizeInKB")
3421abe55efSEd Tanous                                             {
3435fd7ba65SCheng C Yang                                                 continue;
3445fd7ba65SCheng C Yang                                             }
3455fd7ba65SCheng C Yang                                             const uint32_t* value =
3468d78b7a9SPatrick Williams                                                 std::get_if<uint32_t>(
3471b6b96c5SEd Tanous                                                     &property.second);
3485fd7ba65SCheng C Yang                                             if (value == nullptr)
3491abe55efSEd Tanous                                             {
3505fd7ba65SCheng C Yang                                                 BMCWEB_LOG_DEBUG
3515fd7ba65SCheng C Yang                                                     << "Find incorrect type of "
3525fd7ba65SCheng C Yang                                                        "MemorySize";
3535fd7ba65SCheng C Yang                                                 continue;
3545fd7ba65SCheng C Yang                                             }
3555fd7ba65SCheng C Yang                                             nlohmann::json& totalMemory =
3565fd7ba65SCheng C Yang                                                 aResp->res
3575fd7ba65SCheng C Yang                                                     .jsonValue["MemorySummar"
3585fd7ba65SCheng C Yang                                                                "y"]
3595fd7ba65SCheng C Yang                                                               ["TotalSystemMe"
3605fd7ba65SCheng C Yang                                                                "moryGiB"];
3615fd7ba65SCheng C Yang                                             uint64_t* preValue =
3625fd7ba65SCheng C Yang                                                 totalMemory
3635fd7ba65SCheng C Yang                                                     .get_ptr<uint64_t*>();
3645fd7ba65SCheng C Yang                                             if (preValue == nullptr)
3655fd7ba65SCheng C Yang                                             {
3665fd7ba65SCheng C Yang                                                 continue;
3675fd7ba65SCheng C Yang                                             }
3685fd7ba65SCheng C Yang                                             aResp->res
3695fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3706c34de48SEd Tanous                                                           ["TotalSystemMemoryGi"
3715fd7ba65SCheng C Yang                                                            "B"] =
3725fd7ba65SCheng C Yang                                                 *value / (1024 * 1024) +
3735fd7ba65SCheng C Yang                                                 *preValue;
3745fd7ba65SCheng C Yang                                             aResp->res
3755fd7ba65SCheng C Yang                                                 .jsonValue["MemorySummary"]
3769d3ae10eSAlpana Kumari                                                           ["Status"]["State"] =
3771abe55efSEd Tanous                                                 "Enabled";
378c5b2abe0SLewanczyk, Dawid                                         }
379c5b2abe0SLewanczyk, Dawid                                     }
3809d3ae10eSAlpana Kumari                                     else
3819d3ae10eSAlpana Kumari                                     {
3829d3ae10eSAlpana Kumari                                         auto getDimmProperties =
3839d3ae10eSAlpana Kumari                                             [aResp](
3849d3ae10eSAlpana Kumari                                                 const boost::system::error_code
385cb13a392SEd Tanous                                                     ec3,
3861214b7e7SGunnar Mills                                                 const std::variant<bool>&
3871214b7e7SGunnar Mills                                                     dimmState) {
388cb13a392SEd Tanous                                                 if (ec3)
3899d3ae10eSAlpana Kumari                                                 {
3909d3ae10eSAlpana Kumari                                                     BMCWEB_LOG_ERROR
3919d3ae10eSAlpana Kumari                                                         << "DBUS response "
3929d3ae10eSAlpana Kumari                                                            "error "
393cb13a392SEd Tanous                                                         << ec3;
3949d3ae10eSAlpana Kumari                                                     return;
3959d3ae10eSAlpana Kumari                                                 }
3969d3ae10eSAlpana Kumari                                                 updateDimmProperties(aResp,
3979d3ae10eSAlpana Kumari                                                                      dimmState);
3989d3ae10eSAlpana Kumari                                             };
3999d3ae10eSAlpana Kumari                                         crow::connections::systemBus
4009d3ae10eSAlpana Kumari                                             ->async_method_call(
4019d3ae10eSAlpana Kumari                                                 std::move(getDimmProperties),
4029d3ae10eSAlpana Kumari                                                 service, path,
4039d3ae10eSAlpana Kumari                                                 "org.freedesktop.DBus."
4049d3ae10eSAlpana Kumari                                                 "Properties",
4059d3ae10eSAlpana Kumari                                                 "Get",
4069d3ae10eSAlpana Kumari                                                 "xyz.openbmc_project.State."
4079d3ae10eSAlpana Kumari                                                 "Decorator.OperationalStatus",
4089d3ae10eSAlpana Kumari                                                 "Functional");
4099d3ae10eSAlpana Kumari                                     }
410c5b2abe0SLewanczyk, Dawid                                 },
41104a258f4SEd Tanous                                 connection.first, path,
4126c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4136c34de48SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm");
4145bc2dc8eSJames Feist 
4155bc2dc8eSJames Feist                             memoryHealth->inventory.emplace_back(path);
4161abe55efSEd Tanous                         }
41704a258f4SEd Tanous                         else if (interfaceName ==
41804a258f4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.Cpu")
4191abe55efSEd Tanous                         {
4201abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
42104a258f4SEd Tanous                                 << "Found Cpu, now get its properties.";
42257e8c9beSAlpana Kumari 
423*03fbed92SAli Ahmed                             getProcessorSummary(aResp, connection.first, path);
4245bc2dc8eSJames Feist 
4255bc2dc8eSJames Feist                             cpuHealth->inventory.emplace_back(path);
4261abe55efSEd Tanous                         }
42704a258f4SEd Tanous                         else if (interfaceName ==
42804a258f4SEd Tanous                                  "xyz.openbmc_project.Common.UUID")
4291abe55efSEd Tanous                         {
4301abe55efSEd Tanous                             BMCWEB_LOG_DEBUG
43104a258f4SEd Tanous                                 << "Found UUID, now get its properties.";
43255c7b7a2SEd Tanous                             crow::connections::systemBus->async_method_call(
4331214b7e7SGunnar Mills                                 [aResp](
434cb13a392SEd Tanous                                     const boost::system::error_code ec3,
4356c34de48SEd Tanous                                     const std::vector<
4361214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
4371214b7e7SGunnar Mills                                         properties) {
438cb13a392SEd Tanous                                     if (ec3)
4391abe55efSEd Tanous                                     {
4401abe55efSEd Tanous                                         BMCWEB_LOG_DEBUG
441cb13a392SEd Tanous                                             << "DBUS response error " << ec3;
442f12894f8SJason M. Bills                                         messages::internalError(aResp->res);
443c5b2abe0SLewanczyk, Dawid                                         return;
444c5b2abe0SLewanczyk, Dawid                                     }
4456c34de48SEd Tanous                                     BMCWEB_LOG_DEBUG << "Got "
4466c34de48SEd Tanous                                                      << properties.size()
447c5b2abe0SLewanczyk, Dawid                                                      << " UUID properties.";
4481abe55efSEd Tanous                                     for (const std::pair<std::string,
4491214b7e7SGunnar Mills                                                          VariantType>&
4501214b7e7SGunnar Mills                                              property : properties)
4511abe55efSEd Tanous                                     {
45204a258f4SEd Tanous                                         if (property.first == "UUID")
4531abe55efSEd Tanous                                         {
454c5b2abe0SLewanczyk, Dawid                                             const std::string* value =
4558d78b7a9SPatrick Williams                                                 std::get_if<std::string>(
4561b6b96c5SEd Tanous                                                     &property.second);
45704a258f4SEd Tanous 
4581abe55efSEd Tanous                                             if (value != nullptr)
4591abe55efSEd Tanous                                             {
460029573d4SEd Tanous                                                 std::string valueStr = *value;
46104a258f4SEd Tanous                                                 if (valueStr.size() == 32)
4621abe55efSEd Tanous                                                 {
463029573d4SEd Tanous                                                     valueStr.insert(8, 1, '-');
464029573d4SEd Tanous                                                     valueStr.insert(13, 1, '-');
465029573d4SEd Tanous                                                     valueStr.insert(18, 1, '-');
466029573d4SEd Tanous                                                     valueStr.insert(23, 1, '-');
46704a258f4SEd Tanous                                                 }
468029573d4SEd Tanous                                                 BMCWEB_LOG_DEBUG << "UUID = "
46904a258f4SEd Tanous                                                                  << valueStr;
470029573d4SEd Tanous                                                 aResp->res.jsonValue["UUID"] =
47104a258f4SEd Tanous                                                     valueStr;
472c5b2abe0SLewanczyk, Dawid                                             }
473c5b2abe0SLewanczyk, Dawid                                         }
474c5b2abe0SLewanczyk, Dawid                                     }
475c5b2abe0SLewanczyk, Dawid                                 },
47604a258f4SEd Tanous                                 connection.first, path,
4776c34de48SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
4781abe55efSEd Tanous                                 "xyz.openbmc_project.Common.UUID");
479c5b2abe0SLewanczyk, Dawid                         }
480029573d4SEd Tanous                         else if (interfaceName ==
481029573d4SEd Tanous                                  "xyz.openbmc_project.Inventory.Item.System")
4821abe55efSEd Tanous                         {
483029573d4SEd Tanous                             crow::connections::systemBus->async_method_call(
4841214b7e7SGunnar Mills                                 [aResp](
485cb13a392SEd Tanous                                     const boost::system::error_code ec2,
486029573d4SEd Tanous                                     const std::vector<
4871214b7e7SGunnar Mills                                         std::pair<std::string, VariantType>>&
4881214b7e7SGunnar Mills                                         propertiesList) {
489cb13a392SEd Tanous                                     if (ec2)
490029573d4SEd Tanous                                     {
491e4a4b9a9SJames Feist                                         // doesn't have to include this
492e4a4b9a9SJames Feist                                         // interface
493029573d4SEd Tanous                                         return;
494029573d4SEd Tanous                                     }
495698654b6SGunnar Mills                                     BMCWEB_LOG_DEBUG
496698654b6SGunnar Mills                                         << "Got " << propertiesList.size()
497029573d4SEd Tanous                                         << " properties for system";
498029573d4SEd Tanous                                     for (const std::pair<std::string,
4991214b7e7SGunnar Mills                                                          VariantType>&
5001214b7e7SGunnar Mills                                              property : propertiesList)
501029573d4SEd Tanous                                     {
502fc5afcf9Sbeccabroek                                         const std::string& propertyName =
503fc5afcf9Sbeccabroek                                             property.first;
504fc5afcf9Sbeccabroek                                         if ((propertyName == "PartNumber") ||
505fc5afcf9Sbeccabroek                                             (propertyName == "SerialNumber") ||
506fc5afcf9Sbeccabroek                                             (propertyName == "Manufacturer") ||
5075235d964SSunnySrivastava1984                                             (propertyName == "Model") ||
5085235d964SSunnySrivastava1984                                             (propertyName == "SubModel"))
509fc5afcf9Sbeccabroek                                         {
510029573d4SEd Tanous                                             const std::string* value =
511fc5afcf9Sbeccabroek                                                 std::get_if<std::string>(
512029573d4SEd Tanous                                                     &property.second);
513029573d4SEd Tanous                                             if (value != nullptr)
514029573d4SEd Tanous                                             {
515029573d4SEd Tanous                                                 aResp->res
516fc5afcf9Sbeccabroek                                                     .jsonValue[propertyName] =
517029573d4SEd Tanous                                                     *value;
518029573d4SEd Tanous                                             }
519029573d4SEd Tanous                                         }
520fc5afcf9Sbeccabroek                                     }
521c1e236a6SGunnar Mills 
522cb7e1e7bSAndrew Geissler                                     // Grab the bios version
523f97ddba7SGunnar Mills                                     fw_util::populateFirmwareInformation(
524cb7e1e7bSAndrew Geissler                                         aResp, fw_util::biosPurpose,
52572d566d9SGunnar Mills                                         "BiosVersion", false);
526029573d4SEd Tanous                                 },
527029573d4SEd Tanous                                 connection.first, path,
528029573d4SEd Tanous                                 "org.freedesktop.DBus.Properties", "GetAll",
529029573d4SEd Tanous                                 "xyz.openbmc_project.Inventory.Decorator."
530029573d4SEd Tanous                                 "Asset");
531e4a4b9a9SJames Feist 
532e4a4b9a9SJames Feist                             crow::connections::systemBus->async_method_call(
533e4a4b9a9SJames Feist                                 [aResp](
534cb13a392SEd Tanous                                     const boost::system::error_code ec2,
535e4a4b9a9SJames Feist                                     const std::variant<std::string>& property) {
536cb13a392SEd Tanous                                     if (ec2)
537e4a4b9a9SJames Feist                                     {
538e4a4b9a9SJames Feist                                         // doesn't have to include this
539e4a4b9a9SJames Feist                                         // interface
540e4a4b9a9SJames Feist                                         return;
541e4a4b9a9SJames Feist                                     }
542e4a4b9a9SJames Feist 
543e4a4b9a9SJames Feist                                     const std::string* value =
544e4a4b9a9SJames Feist                                         std::get_if<std::string>(&property);
545e4a4b9a9SJames Feist                                     if (value != nullptr)
546e4a4b9a9SJames Feist                                     {
547e4a4b9a9SJames Feist                                         aResp->res.jsonValue["AssetTag"] =
548e4a4b9a9SJames Feist                                             *value;
549e4a4b9a9SJames Feist                                     }
550e4a4b9a9SJames Feist                                 },
551e4a4b9a9SJames Feist                                 connection.first, path,
552e4a4b9a9SJames Feist                                 "org.freedesktop.DBus.Properties", "Get",
553e4a4b9a9SJames Feist                                 "xyz.openbmc_project.Inventory.Decorator."
554e4a4b9a9SJames Feist                                 "AssetTag",
555e4a4b9a9SJames Feist                                 "AssetTag");
556029573d4SEd Tanous                         }
557029573d4SEd Tanous                     }
558029573d4SEd Tanous                 }
559c5b2abe0SLewanczyk, Dawid             }
560c5b2abe0SLewanczyk, Dawid         },
561c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
562c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
563c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
5646617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
5656617338dSEd Tanous         std::array<const char*, 5>{
5666617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
5676617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
5686617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
5696617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
5706617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
5716617338dSEd Tanous         });
572c5b2abe0SLewanczyk, Dawid }
573c5b2abe0SLewanczyk, Dawid 
574c5b2abe0SLewanczyk, Dawid /**
575c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
576c5b2abe0SLewanczyk, Dawid  *
577c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
578c5b2abe0SLewanczyk, Dawid  *
579c5b2abe0SLewanczyk, Dawid  * @return None.
580c5b2abe0SLewanczyk, Dawid  */
5818d1b46d7Szhanghch05 inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
5821abe55efSEd Tanous {
58355c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
58455c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
585c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
586abf2add6SEd Tanous                 const std::variant<std::string>& hostState) {
5871abe55efSEd Tanous             if (ec)
5881abe55efSEd Tanous             {
58955c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
590f12894f8SJason M. Bills                 messages::internalError(aResp->res);
591c5b2abe0SLewanczyk, Dawid                 return;
592c5b2abe0SLewanczyk, Dawid             }
5936617338dSEd Tanous 
594abf2add6SEd Tanous             const std::string* s = std::get_if<std::string>(&hostState);
59555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
5966617338dSEd Tanous             if (s != nullptr)
5971abe55efSEd Tanous             {
598c5b2abe0SLewanczyk, Dawid                 // Verify Host State
59994732661SAndrew Geissler                 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
6001abe55efSEd Tanous                 {
60155c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
6026617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
6031abe55efSEd Tanous                 }
60483935af9SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6058c888608SGunnar Mills                                "Quiesced")
6068c888608SGunnar Mills                 {
6078c888608SGunnar Mills                     aResp->res.jsonValue["PowerState"] = "On";
6088c888608SGunnar Mills                     aResp->res.jsonValue["Status"]["State"] = "Quiesced";
6098c888608SGunnar Mills                 }
6108c888608SGunnar Mills                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
61183935af9SAndrew Geissler                                "DiagnosticMode")
61283935af9SAndrew Geissler                 {
61383935af9SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "On";
61483935af9SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "InTest";
61583935af9SAndrew Geissler                 }
6161a2a1437SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6171a2a1437SAndrew Geissler                                "TransitioningToRunning")
6181a2a1437SAndrew Geissler                 {
6191a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOn";
62015c27bf8SNoah Brewer                     aResp->res.jsonValue["Status"]["State"] = "Starting";
6211a2a1437SAndrew Geissler                 }
6221a2a1437SAndrew Geissler                 else if (*s == "xyz.openbmc_project.State.Host.HostState."
6231a2a1437SAndrew Geissler                                "TransitioningToOff")
6241a2a1437SAndrew Geissler                 {
6251a2a1437SAndrew Geissler                     aResp->res.jsonValue["PowerState"] = "PoweringOff";
6261a2a1437SAndrew Geissler                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
6271a2a1437SAndrew Geissler                 }
6281abe55efSEd Tanous                 else
6291abe55efSEd Tanous                 {
63055c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
6316617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
632c5b2abe0SLewanczyk, Dawid                 }
633c5b2abe0SLewanczyk, Dawid             }
634c5b2abe0SLewanczyk, Dawid         },
6356c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
6366617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
6376617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
638c5b2abe0SLewanczyk, Dawid }
639c5b2abe0SLewanczyk, Dawid 
640c5b2abe0SLewanczyk, Dawid /**
641786d0f60SGunnar Mills  * @brief Translates boot source DBUS property value to redfish.
642491d8ee7SSantosh Puranik  *
643491d8ee7SSantosh Puranik  * @param[in] dbusSource    The boot source in DBUS speak.
644491d8ee7SSantosh Puranik  *
645491d8ee7SSantosh Puranik  * @return Returns as a string, the boot source in Redfish terms. If translation
646491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
647491d8ee7SSantosh Puranik  */
64823a21a1cSEd Tanous inline std::string dbusToRfBootSource(const std::string& dbusSource)
649491d8ee7SSantosh Puranik {
650491d8ee7SSantosh Puranik     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
651491d8ee7SSantosh Puranik     {
652491d8ee7SSantosh Puranik         return "None";
653491d8ee7SSantosh Puranik     }
6543174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
655491d8ee7SSantosh Puranik     {
656491d8ee7SSantosh Puranik         return "Hdd";
657491d8ee7SSantosh Puranik     }
6583174e4dfSEd Tanous     if (dbusSource ==
659a71dc0b7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
660491d8ee7SSantosh Puranik     {
661491d8ee7SSantosh Puranik         return "Cd";
662491d8ee7SSantosh Puranik     }
6633174e4dfSEd Tanous     if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
664491d8ee7SSantosh Puranik     {
665491d8ee7SSantosh Puranik         return "Pxe";
666491d8ee7SSantosh Puranik     }
6673174e4dfSEd Tanous     if (dbusSource ==
668944ffaf9SJohnathan Mantey         "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
6699f16b2c1SJennifer Lee     {
6709f16b2c1SJennifer Lee         return "Usb";
6719f16b2c1SJennifer Lee     }
672491d8ee7SSantosh Puranik     return "";
673491d8ee7SSantosh Puranik }
674491d8ee7SSantosh Puranik 
675491d8ee7SSantosh Puranik /**
676cd9a4666SKonstantin Aladyshev  * @brief Translates boot type DBUS property value to redfish.
677cd9a4666SKonstantin Aladyshev  *
678cd9a4666SKonstantin Aladyshev  * @param[in] dbusType    The boot type in DBUS speak.
679cd9a4666SKonstantin Aladyshev  *
680cd9a4666SKonstantin Aladyshev  * @return Returns as a string, the boot type in Redfish terms. If translation
681cd9a4666SKonstantin Aladyshev  * cannot be done, returns an empty string.
682cd9a4666SKonstantin Aladyshev  */
683cd9a4666SKonstantin Aladyshev inline std::string dbusToRfBootType(const std::string& dbusType)
684cd9a4666SKonstantin Aladyshev {
685cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
686cd9a4666SKonstantin Aladyshev     {
687cd9a4666SKonstantin Aladyshev         return "Legacy";
688cd9a4666SKonstantin Aladyshev     }
689cd9a4666SKonstantin Aladyshev     if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
690cd9a4666SKonstantin Aladyshev     {
691cd9a4666SKonstantin Aladyshev         return "UEFI";
692cd9a4666SKonstantin Aladyshev     }
693cd9a4666SKonstantin Aladyshev     return "";
694cd9a4666SKonstantin Aladyshev }
695cd9a4666SKonstantin Aladyshev 
696cd9a4666SKonstantin Aladyshev /**
697786d0f60SGunnar Mills  * @brief Translates boot mode DBUS property value to redfish.
698491d8ee7SSantosh Puranik  *
699491d8ee7SSantosh Puranik  * @param[in] dbusMode    The boot mode in DBUS speak.
700491d8ee7SSantosh Puranik  *
701491d8ee7SSantosh Puranik  * @return Returns as a string, the boot mode in Redfish terms. If translation
702491d8ee7SSantosh Puranik  * cannot be done, returns an empty string.
703491d8ee7SSantosh Puranik  */
70423a21a1cSEd Tanous inline std::string dbusToRfBootMode(const std::string& dbusMode)
705491d8ee7SSantosh Puranik {
706491d8ee7SSantosh Puranik     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
707491d8ee7SSantosh Puranik     {
708491d8ee7SSantosh Puranik         return "None";
709491d8ee7SSantosh Puranik     }
7103174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
711491d8ee7SSantosh Puranik     {
712491d8ee7SSantosh Puranik         return "Diags";
713491d8ee7SSantosh Puranik     }
7143174e4dfSEd Tanous     if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
715491d8ee7SSantosh Puranik     {
716491d8ee7SSantosh Puranik         return "BiosSetup";
717491d8ee7SSantosh Puranik     }
718491d8ee7SSantosh Puranik     return "";
719491d8ee7SSantosh Puranik }
720491d8ee7SSantosh Puranik 
721491d8ee7SSantosh Puranik /**
722786d0f60SGunnar Mills  * @brief Translates boot source from Redfish to the DBus boot paths.
723491d8ee7SSantosh Puranik  *
724491d8ee7SSantosh Puranik  * @param[in] rfSource    The boot source in Redfish.
725944ffaf9SJohnathan Mantey  * @param[out] bootSource The DBus source
726944ffaf9SJohnathan Mantey  * @param[out] bootMode   the DBus boot mode
727491d8ee7SSantosh Puranik  *
728944ffaf9SJohnathan Mantey  * @return Integer error code.
729491d8ee7SSantosh Puranik  */
7308d1b46d7Szhanghch05 inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
731944ffaf9SJohnathan Mantey                                 const std::string& rfSource,
732944ffaf9SJohnathan Mantey                                 std::string& bootSource, std::string& bootMode)
733491d8ee7SSantosh Puranik {
734c21865c4SKonstantin Aladyshev     bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
735c21865c4SKonstantin Aladyshev     bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
736944ffaf9SJohnathan Mantey 
737491d8ee7SSantosh Puranik     if (rfSource == "None")
738491d8ee7SSantosh Puranik     {
739944ffaf9SJohnathan Mantey         return 0;
740491d8ee7SSantosh Puranik     }
7413174e4dfSEd Tanous     if (rfSource == "Pxe")
742491d8ee7SSantosh Puranik     {
743944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
744944ffaf9SJohnathan Mantey     }
745944ffaf9SJohnathan Mantey     else if (rfSource == "Hdd")
746944ffaf9SJohnathan Mantey     {
747944ffaf9SJohnathan Mantey         bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
748944ffaf9SJohnathan Mantey     }
749944ffaf9SJohnathan Mantey     else if (rfSource == "Diags")
750944ffaf9SJohnathan Mantey     {
751944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
752944ffaf9SJohnathan Mantey     }
753944ffaf9SJohnathan Mantey     else if (rfSource == "Cd")
754944ffaf9SJohnathan Mantey     {
755944ffaf9SJohnathan Mantey         bootSource =
756944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
757944ffaf9SJohnathan Mantey     }
758944ffaf9SJohnathan Mantey     else if (rfSource == "BiosSetup")
759944ffaf9SJohnathan Mantey     {
760944ffaf9SJohnathan Mantey         bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
761491d8ee7SSantosh Puranik     }
7629f16b2c1SJennifer Lee     else if (rfSource == "Usb")
7639f16b2c1SJennifer Lee     {
764944ffaf9SJohnathan Mantey         bootSource =
765944ffaf9SJohnathan Mantey             "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
7669f16b2c1SJennifer Lee     }
767491d8ee7SSantosh Puranik     else
768491d8ee7SSantosh Puranik     {
769944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG << "Invalid property value for "
770944ffaf9SJohnathan Mantey                             "BootSourceOverrideTarget: "
771944ffaf9SJohnathan Mantey                          << bootSource;
772944ffaf9SJohnathan Mantey         messages::propertyValueNotInList(aResp->res, rfSource,
773944ffaf9SJohnathan Mantey                                          "BootSourceTargetOverride");
774944ffaf9SJohnathan Mantey         return -1;
775491d8ee7SSantosh Puranik     }
776944ffaf9SJohnathan Mantey     return 0;
777491d8ee7SSantosh Puranik }
7781981771bSAli Ahmed 
779978b8803SAndrew Geissler /**
780978b8803SAndrew Geissler  * @brief Retrieves boot progress of the system
781978b8803SAndrew Geissler  *
782978b8803SAndrew Geissler  * @param[in] aResp  Shared pointer for generating response message.
783978b8803SAndrew Geissler  *
784978b8803SAndrew Geissler  * @return None.
785978b8803SAndrew Geissler  */
7868d1b46d7Szhanghch05 inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
787978b8803SAndrew Geissler {
788978b8803SAndrew Geissler     crow::connections::systemBus->async_method_call(
789978b8803SAndrew Geissler         [aResp](const boost::system::error_code ec,
790978b8803SAndrew Geissler                 const std::variant<std::string>& bootProgress) {
791978b8803SAndrew Geissler             if (ec)
792978b8803SAndrew Geissler             {
793978b8803SAndrew Geissler                 // BootProgress is an optional object so just do nothing if
794978b8803SAndrew Geissler                 // not found
795978b8803SAndrew Geissler                 return;
796978b8803SAndrew Geissler             }
797978b8803SAndrew Geissler 
798978b8803SAndrew Geissler             const std::string* bootProgressStr =
799978b8803SAndrew Geissler                 std::get_if<std::string>(&bootProgress);
800978b8803SAndrew Geissler 
801978b8803SAndrew Geissler             if (!bootProgressStr)
802978b8803SAndrew Geissler             {
803978b8803SAndrew Geissler                 // Interface implemented but property not found, return error
804978b8803SAndrew Geissler                 // for that
805978b8803SAndrew Geissler                 messages::internalError(aResp->res);
806978b8803SAndrew Geissler                 return;
807978b8803SAndrew Geissler             }
808978b8803SAndrew Geissler 
809978b8803SAndrew Geissler             BMCWEB_LOG_DEBUG << "Boot Progress: " << *bootProgressStr;
810978b8803SAndrew Geissler 
811978b8803SAndrew Geissler             // Now convert the D-Bus BootProgress to the appropriate Redfish
812978b8803SAndrew Geissler             // enum
813978b8803SAndrew Geissler             std::string rfBpLastState = "None";
814978b8803SAndrew Geissler             if (*bootProgressStr == "xyz.openbmc_project.State.Boot.Progress."
815978b8803SAndrew Geissler                                     "ProgressStages.Unspecified")
816978b8803SAndrew Geissler             {
817978b8803SAndrew Geissler                 rfBpLastState = "None";
818978b8803SAndrew Geissler             }
819978b8803SAndrew Geissler             else if (*bootProgressStr ==
820978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
821978b8803SAndrew Geissler                      "PrimaryProcInit")
822978b8803SAndrew Geissler             {
823978b8803SAndrew Geissler                 rfBpLastState = "PrimaryProcessorInitializationStarted";
824978b8803SAndrew Geissler             }
825978b8803SAndrew Geissler             else if (*bootProgressStr ==
826978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
827978b8803SAndrew Geissler                      "BusInit")
828978b8803SAndrew Geissler             {
829978b8803SAndrew Geissler                 rfBpLastState = "BusInitializationStarted";
830978b8803SAndrew Geissler             }
831978b8803SAndrew Geissler             else if (*bootProgressStr ==
832978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
833978b8803SAndrew Geissler                      "MemoryInit")
834978b8803SAndrew Geissler             {
835978b8803SAndrew Geissler                 rfBpLastState = "MemoryInitializationStarted";
836978b8803SAndrew Geissler             }
837978b8803SAndrew Geissler             else if (*bootProgressStr ==
838978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
839978b8803SAndrew Geissler                      "SecondaryProcInit")
840978b8803SAndrew Geissler             {
841978b8803SAndrew Geissler                 rfBpLastState = "SecondaryProcessorInitializationStarted";
842978b8803SAndrew Geissler             }
843978b8803SAndrew Geissler             else if (*bootProgressStr ==
844978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
845978b8803SAndrew Geissler                      "PCIInit")
846978b8803SAndrew Geissler             {
847978b8803SAndrew Geissler                 rfBpLastState = "PCIResourceConfigStarted";
848978b8803SAndrew Geissler             }
849978b8803SAndrew Geissler             else if (*bootProgressStr ==
850978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
851978b8803SAndrew Geissler                      "SystemInitComplete")
852978b8803SAndrew Geissler             {
853978b8803SAndrew Geissler                 rfBpLastState = "SystemHardwareInitializationComplete";
854978b8803SAndrew Geissler             }
855978b8803SAndrew Geissler             else if (*bootProgressStr ==
856978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
857978b8803SAndrew Geissler                      "OSStart")
858978b8803SAndrew Geissler             {
859978b8803SAndrew Geissler                 rfBpLastState = "OSBootStarted";
860978b8803SAndrew Geissler             }
861978b8803SAndrew Geissler             else if (*bootProgressStr ==
862978b8803SAndrew Geissler                      "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
863978b8803SAndrew Geissler                      "OSRunning")
864978b8803SAndrew Geissler             {
865978b8803SAndrew Geissler                 rfBpLastState = "OSRunning";
866978b8803SAndrew Geissler             }
867978b8803SAndrew Geissler             else
868978b8803SAndrew Geissler             {
869978b8803SAndrew Geissler                 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
870978b8803SAndrew Geissler                                  << *bootProgressStr;
871978b8803SAndrew Geissler                 // Just return the default
872978b8803SAndrew Geissler             }
873978b8803SAndrew Geissler 
874978b8803SAndrew Geissler             aResp->res.jsonValue["BootProgress"]["LastState"] = rfBpLastState;
875978b8803SAndrew Geissler         },
876978b8803SAndrew Geissler         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
877978b8803SAndrew Geissler         "org.freedesktop.DBus.Properties", "Get",
878978b8803SAndrew Geissler         "xyz.openbmc_project.State.Boot.Progress", "BootProgress");
879978b8803SAndrew Geissler }
880491d8ee7SSantosh Puranik 
881491d8ee7SSantosh Puranik /**
882c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override type over DBUS and fills out the response
883cd9a4666SKonstantin Aladyshev  *
884cd9a4666SKonstantin Aladyshev  * @param[in] aResp         Shared pointer for generating response message.
885cd9a4666SKonstantin Aladyshev  *
886cd9a4666SKonstantin Aladyshev  * @return None.
887cd9a4666SKonstantin Aladyshev  */
888cd9a4666SKonstantin Aladyshev 
889c21865c4SKonstantin Aladyshev inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
890cd9a4666SKonstantin Aladyshev {
891cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
892cd9a4666SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
893cd9a4666SKonstantin Aladyshev                 const std::variant<std::string>& bootType) {
894cd9a4666SKonstantin Aladyshev             if (ec)
895cd9a4666SKonstantin Aladyshev             {
896cd9a4666SKonstantin Aladyshev                 // not an error, don't have to have the interface
897cd9a4666SKonstantin Aladyshev                 return;
898cd9a4666SKonstantin Aladyshev             }
899cd9a4666SKonstantin Aladyshev 
900cd9a4666SKonstantin Aladyshev             const std::string* bootTypeStr =
901cd9a4666SKonstantin Aladyshev                 std::get_if<std::string>(&bootType);
902cd9a4666SKonstantin Aladyshev 
903cd9a4666SKonstantin Aladyshev             if (!bootTypeStr)
904cd9a4666SKonstantin Aladyshev             {
905cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
906cd9a4666SKonstantin Aladyshev                 return;
907cd9a4666SKonstantin Aladyshev             }
908cd9a4666SKonstantin Aladyshev 
909cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type: " << *bootTypeStr;
910cd9a4666SKonstantin Aladyshev 
911cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode@Redfish."
912cd9a4666SKonstantin Aladyshev                                          "AllowableValues"] = {"Legacy",
913cd9a4666SKonstantin Aladyshev                                                                "UEFI"};
914cd9a4666SKonstantin Aladyshev 
915cd9a4666SKonstantin Aladyshev             auto rfType = dbusToRfBootType(*bootTypeStr);
916cd9a4666SKonstantin Aladyshev             if (rfType.empty())
917cd9a4666SKonstantin Aladyshev             {
918cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
919cd9a4666SKonstantin Aladyshev                 return;
920cd9a4666SKonstantin Aladyshev             }
921cd9a4666SKonstantin Aladyshev 
922cd9a4666SKonstantin Aladyshev             aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
923cd9a4666SKonstantin Aladyshev         },
924c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
925c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
926cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
927cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType");
928cd9a4666SKonstantin Aladyshev }
929cd9a4666SKonstantin Aladyshev 
930cd9a4666SKonstantin Aladyshev /**
931c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override mode over DBUS and fills out the response
932491d8ee7SSantosh Puranik  *
933491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
934491d8ee7SSantosh Puranik  *
935491d8ee7SSantosh Puranik  * @return None.
936491d8ee7SSantosh Puranik  */
937c21865c4SKonstantin Aladyshev 
938c21865c4SKonstantin Aladyshev inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
939491d8ee7SSantosh Puranik {
940491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
941c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
942491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootMode) {
943491d8ee7SSantosh Puranik             if (ec)
944491d8ee7SSantosh Puranik             {
945491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
946491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
947491d8ee7SSantosh Puranik                 return;
948491d8ee7SSantosh Puranik             }
949491d8ee7SSantosh Puranik 
950491d8ee7SSantosh Puranik             const std::string* bootModeStr =
951491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootMode);
952491d8ee7SSantosh Puranik 
953491d8ee7SSantosh Puranik             if (!bootModeStr)
954491d8ee7SSantosh Puranik             {
955491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
956491d8ee7SSantosh Puranik                 return;
957491d8ee7SSantosh Puranik             }
958491d8ee7SSantosh Puranik 
959491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
960491d8ee7SSantosh Puranik 
961491d8ee7SSantosh Puranik             aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
962491d8ee7SSantosh Puranik                                          "AllowableValues"] = {
963944ffaf9SJohnathan Mantey                 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
964491d8ee7SSantosh Puranik 
965491d8ee7SSantosh Puranik             if (*bootModeStr !=
966491d8ee7SSantosh Puranik                 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
967491d8ee7SSantosh Puranik             {
968491d8ee7SSantosh Puranik                 auto rfMode = dbusToRfBootMode(*bootModeStr);
969491d8ee7SSantosh Puranik                 if (!rfMode.empty())
970491d8ee7SSantosh Puranik                 {
971491d8ee7SSantosh Puranik                     aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
972491d8ee7SSantosh Puranik                         rfMode;
973491d8ee7SSantosh Puranik                 }
974491d8ee7SSantosh Puranik             }
975491d8ee7SSantosh Puranik         },
976c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
977c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
978491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
979491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
980491d8ee7SSantosh Puranik }
981491d8ee7SSantosh Puranik 
982491d8ee7SSantosh Puranik /**
983c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override source over DBUS
984491d8ee7SSantosh Puranik  *
985491d8ee7SSantosh Puranik  * @param[in] aResp         Shared pointer for generating response message.
986491d8ee7SSantosh Puranik  *
987491d8ee7SSantosh Puranik  * @return None.
988491d8ee7SSantosh Puranik  */
989c21865c4SKonstantin Aladyshev 
990c21865c4SKonstantin Aladyshev inline void
991c21865c4SKonstantin Aladyshev     getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
992491d8ee7SSantosh Puranik {
993491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
994c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
995491d8ee7SSantosh Puranik                 const std::variant<std::string>& bootSource) {
996491d8ee7SSantosh Puranik             if (ec)
997491d8ee7SSantosh Puranik             {
998491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
999491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1000491d8ee7SSantosh Puranik                 return;
1001491d8ee7SSantosh Puranik             }
1002491d8ee7SSantosh Puranik 
1003491d8ee7SSantosh Puranik             const std::string* bootSourceStr =
1004491d8ee7SSantosh Puranik                 std::get_if<std::string>(&bootSource);
1005491d8ee7SSantosh Puranik 
1006491d8ee7SSantosh Puranik             if (!bootSourceStr)
1007491d8ee7SSantosh Puranik             {
1008491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1009491d8ee7SSantosh Puranik                 return;
1010491d8ee7SSantosh Puranik             }
1011491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
1012491d8ee7SSantosh Puranik 
1013491d8ee7SSantosh Puranik             auto rfSource = dbusToRfBootSource(*bootSourceStr);
1014491d8ee7SSantosh Puranik             if (!rfSource.empty())
1015491d8ee7SSantosh Puranik             {
1016491d8ee7SSantosh Puranik                 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1017491d8ee7SSantosh Puranik                     rfSource;
1018491d8ee7SSantosh Puranik             }
1019cd9a4666SKonstantin Aladyshev 
1020cd9a4666SKonstantin Aladyshev             // Get BootMode as BootSourceOverrideTarget is constructed
1021cd9a4666SKonstantin Aladyshev             // from both BootSource and BootMode
1022c21865c4SKonstantin Aladyshev             getBootOverrideMode(aResp);
1023491d8ee7SSantosh Puranik         },
1024c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1025c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1026491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1027491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource");
1028491d8ee7SSantosh Puranik }
1029491d8ee7SSantosh Puranik 
1030491d8ee7SSantosh Puranik /**
1031c21865c4SKonstantin Aladyshev  * @brief This functions abstracts all the logic behind getting a
1032c21865c4SKonstantin Aladyshev  * "BootSourceOverrideEnabled" property from an overall boot override enable
1033c21865c4SKonstantin Aladyshev  * state
1034491d8ee7SSantosh Puranik  *
1035491d8ee7SSantosh Puranik  * @param[in] aResp     Shared pointer for generating response message.
1036491d8ee7SSantosh Puranik  *
1037491d8ee7SSantosh Puranik  * @return None.
1038491d8ee7SSantosh Puranik  */
1039491d8ee7SSantosh Puranik 
1040c21865c4SKonstantin Aladyshev inline void
1041c21865c4SKonstantin Aladyshev     processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1042c21865c4SKonstantin Aladyshev                               const bool bootOverrideEnableSetting)
1043c21865c4SKonstantin Aladyshev {
1044c21865c4SKonstantin Aladyshev     if (!bootOverrideEnableSetting)
1045c21865c4SKonstantin Aladyshev     {
1046c21865c4SKonstantin Aladyshev         aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1047c21865c4SKonstantin Aladyshev         return;
1048c21865c4SKonstantin Aladyshev     }
1049c21865c4SKonstantin Aladyshev 
1050c21865c4SKonstantin Aladyshev     // If boot source override is enabled, we need to check 'one_time'
1051c21865c4SKonstantin Aladyshev     // property to set a correct value for the "BootSourceOverrideEnabled"
1052491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1053c5d03ff4SJennifer Lee         [aResp](const boost::system::error_code ec,
105419bd78d9SPatrick Williams                 const std::variant<bool>& oneTime) {
1055491d8ee7SSantosh Puranik             if (ec)
1056491d8ee7SSantosh Puranik             {
1057491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1058c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1059491d8ee7SSantosh Puranik                 return;
1060491d8ee7SSantosh Puranik             }
1061491d8ee7SSantosh Puranik 
1062491d8ee7SSantosh Puranik             const bool* oneTimePtr = std::get_if<bool>(&oneTime);
1063491d8ee7SSantosh Puranik 
1064491d8ee7SSantosh Puranik             if (!oneTimePtr)
1065491d8ee7SSantosh Puranik             {
1066491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1067491d8ee7SSantosh Puranik                 return;
1068491d8ee7SSantosh Puranik             }
1069c21865c4SKonstantin Aladyshev 
1070c21865c4SKonstantin Aladyshev             bool oneTimeSetting = *oneTimePtr;
1071c21865c4SKonstantin Aladyshev 
1072c21865c4SKonstantin Aladyshev             if (oneTimeSetting)
1073c21865c4SKonstantin Aladyshev             {
1074c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1075c21865c4SKonstantin Aladyshev                     "Once";
1076c21865c4SKonstantin Aladyshev             }
1077c21865c4SKonstantin Aladyshev             else
1078c21865c4SKonstantin Aladyshev             {
1079c21865c4SKonstantin Aladyshev                 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1080c21865c4SKonstantin Aladyshev                     "Continuous";
1081c21865c4SKonstantin Aladyshev             }
1082491d8ee7SSantosh Puranik         },
1083491d8ee7SSantosh Puranik         "xyz.openbmc_project.Settings",
1084491d8ee7SSantosh Puranik         "/xyz/openbmc_project/control/host0/boot/one_time",
1085491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Get",
1086491d8ee7SSantosh Puranik         "xyz.openbmc_project.Object.Enable", "Enabled");
1087491d8ee7SSantosh Puranik }
1088491d8ee7SSantosh Puranik 
1089491d8ee7SSantosh Puranik /**
1090c21865c4SKonstantin Aladyshev  * @brief Retrieves boot override enable over DBUS
1091c21865c4SKonstantin Aladyshev  *
1092c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1093c21865c4SKonstantin Aladyshev  *
1094c21865c4SKonstantin Aladyshev  * @return None.
1095c21865c4SKonstantin Aladyshev  */
1096c21865c4SKonstantin Aladyshev 
1097c21865c4SKonstantin Aladyshev inline void
1098c21865c4SKonstantin Aladyshev     getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1099c21865c4SKonstantin Aladyshev {
1100c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1101c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec,
1102c21865c4SKonstantin Aladyshev                 const std::variant<bool>& bootOverrideEnable) {
1103c21865c4SKonstantin Aladyshev             if (ec)
1104c21865c4SKonstantin Aladyshev             {
1105c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1106c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1107c21865c4SKonstantin Aladyshev                 return;
1108c21865c4SKonstantin Aladyshev             }
1109c21865c4SKonstantin Aladyshev 
1110c21865c4SKonstantin Aladyshev             const bool* bootOverrideEnablePtr =
1111c21865c4SKonstantin Aladyshev                 std::get_if<bool>(&bootOverrideEnable);
1112c21865c4SKonstantin Aladyshev 
1113c21865c4SKonstantin Aladyshev             if (!bootOverrideEnablePtr)
1114c21865c4SKonstantin Aladyshev             {
1115c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1116c21865c4SKonstantin Aladyshev                 return;
1117c21865c4SKonstantin Aladyshev             }
1118c21865c4SKonstantin Aladyshev 
1119c21865c4SKonstantin Aladyshev             processBootOverrideEnable(aResp, *bootOverrideEnablePtr);
1120c21865c4SKonstantin Aladyshev         },
1121c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1122c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1123c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Get",
1124c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled");
1125c21865c4SKonstantin Aladyshev }
1126c21865c4SKonstantin Aladyshev 
1127c21865c4SKonstantin Aladyshev /**
1128c21865c4SKonstantin Aladyshev  * @brief Retrieves boot source override properties
1129c21865c4SKonstantin Aladyshev  *
1130c21865c4SKonstantin Aladyshev  * @param[in] aResp     Shared pointer for generating response message.
1131c21865c4SKonstantin Aladyshev  *
1132c21865c4SKonstantin Aladyshev  * @return None.
1133c21865c4SKonstantin Aladyshev  */
1134c21865c4SKonstantin Aladyshev inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1135c21865c4SKonstantin Aladyshev {
1136c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Get boot information.";
1137c21865c4SKonstantin Aladyshev 
1138c21865c4SKonstantin Aladyshev     getBootOverrideSource(aResp);
1139c21865c4SKonstantin Aladyshev     getBootOverrideType(aResp);
1140c21865c4SKonstantin Aladyshev     getBootOverrideEnable(aResp);
1141c21865c4SKonstantin Aladyshev }
1142c21865c4SKonstantin Aladyshev 
1143c21865c4SKonstantin Aladyshev /**
1144c0557e1aSGunnar Mills  * @brief Retrieves the Last Reset Time
1145c0557e1aSGunnar Mills  *
1146c0557e1aSGunnar Mills  * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1147c0557e1aSGunnar Mills  * and power off. Even though this is the "system" Redfish object look at the
1148c0557e1aSGunnar Mills  * chassis D-Bus interface for the LastStateChangeTime since this has the
1149c0557e1aSGunnar Mills  * last power operation time.
1150c0557e1aSGunnar Mills  *
1151c0557e1aSGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
1152c0557e1aSGunnar Mills  *
1153c0557e1aSGunnar Mills  * @return None.
1154c0557e1aSGunnar Mills  */
11558d1b46d7Szhanghch05 inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1156c0557e1aSGunnar Mills {
1157c0557e1aSGunnar Mills     BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1158c0557e1aSGunnar Mills 
1159c0557e1aSGunnar Mills     crow::connections::systemBus->async_method_call(
1160c0557e1aSGunnar Mills         [aResp](const boost::system::error_code ec,
1161c0557e1aSGunnar Mills                 std::variant<uint64_t>& lastResetTime) {
1162c0557e1aSGunnar Mills             if (ec)
1163c0557e1aSGunnar Mills             {
1164c0557e1aSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1165c0557e1aSGunnar Mills                 return;
1166c0557e1aSGunnar Mills             }
1167c0557e1aSGunnar Mills 
1168c0557e1aSGunnar Mills             const uint64_t* lastResetTimePtr =
1169c0557e1aSGunnar Mills                 std::get_if<uint64_t>(&lastResetTime);
1170c0557e1aSGunnar Mills 
1171c0557e1aSGunnar Mills             if (!lastResetTimePtr)
1172c0557e1aSGunnar Mills             {
1173c0557e1aSGunnar Mills                 messages::internalError(aResp->res);
1174c0557e1aSGunnar Mills                 return;
1175c0557e1aSGunnar Mills             }
1176c0557e1aSGunnar Mills             // LastStateChangeTime is epoch time, in milliseconds
1177c0557e1aSGunnar Mills             // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1178c0557e1aSGunnar Mills             time_t lastResetTimeStamp =
1179c0557e1aSGunnar Mills                 static_cast<time_t>(*lastResetTimePtr / 1000);
1180c0557e1aSGunnar Mills 
1181c0557e1aSGunnar Mills             // Convert to ISO 8601 standard
1182c0557e1aSGunnar Mills             aResp->res.jsonValue["LastResetTime"] =
1183c0557e1aSGunnar Mills                 crow::utility::getDateTime(lastResetTimeStamp);
1184c0557e1aSGunnar Mills         },
1185c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis",
1186c0557e1aSGunnar Mills         "/xyz/openbmc_project/state/chassis0",
1187c0557e1aSGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
1188c0557e1aSGunnar Mills         "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
1189c0557e1aSGunnar Mills }
1190c0557e1aSGunnar Mills 
1191c0557e1aSGunnar Mills /**
11926bd5a8d2SGunnar Mills  * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
11936bd5a8d2SGunnar Mills  *
11946bd5a8d2SGunnar Mills  * @param[in] aResp     Shared pointer for generating response message.
11956bd5a8d2SGunnar Mills  *
11966bd5a8d2SGunnar Mills  * @return None.
11976bd5a8d2SGunnar Mills  */
11988d1b46d7Szhanghch05 inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
11996bd5a8d2SGunnar Mills {
12006bd5a8d2SGunnar Mills     BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
12016bd5a8d2SGunnar Mills 
12026bd5a8d2SGunnar Mills     crow::connections::systemBus->async_method_call(
12036bd5a8d2SGunnar Mills         [aResp](const boost::system::error_code ec,
12046bd5a8d2SGunnar Mills                 std::variant<bool>& autoRebootEnabled) {
12056bd5a8d2SGunnar Mills             if (ec)
12066bd5a8d2SGunnar Mills             {
12076bd5a8d2SGunnar Mills                 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
12086bd5a8d2SGunnar Mills                 return;
12096bd5a8d2SGunnar Mills             }
12106bd5a8d2SGunnar Mills 
12116bd5a8d2SGunnar Mills             const bool* autoRebootEnabledPtr =
12126bd5a8d2SGunnar Mills                 std::get_if<bool>(&autoRebootEnabled);
12136bd5a8d2SGunnar Mills 
12146bd5a8d2SGunnar Mills             if (!autoRebootEnabledPtr)
12156bd5a8d2SGunnar Mills             {
12166bd5a8d2SGunnar Mills                 messages::internalError(aResp->res);
12176bd5a8d2SGunnar Mills                 return;
12186bd5a8d2SGunnar Mills             }
12196bd5a8d2SGunnar Mills 
12206bd5a8d2SGunnar Mills             BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
12216bd5a8d2SGunnar Mills             if (*autoRebootEnabledPtr == true)
12226bd5a8d2SGunnar Mills             {
12236bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12246bd5a8d2SGunnar Mills                     "RetryAttempts";
12256bd5a8d2SGunnar Mills                 // If AutomaticRetry (AutoReboot) is enabled see how many
12266bd5a8d2SGunnar Mills                 // attempts are left
12276bd5a8d2SGunnar Mills                 crow::connections::systemBus->async_method_call(
1228cb13a392SEd Tanous                     [aResp](const boost::system::error_code ec2,
12296bd5a8d2SGunnar Mills                             std::variant<uint32_t>& autoRebootAttemptsLeft) {
1230cb13a392SEd Tanous                         if (ec2)
12316bd5a8d2SGunnar Mills                         {
1232cb13a392SEd Tanous                             BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
12336bd5a8d2SGunnar Mills                             return;
12346bd5a8d2SGunnar Mills                         }
12356bd5a8d2SGunnar Mills 
12366bd5a8d2SGunnar Mills                         const uint32_t* autoRebootAttemptsLeftPtr =
12376bd5a8d2SGunnar Mills                             std::get_if<uint32_t>(&autoRebootAttemptsLeft);
12386bd5a8d2SGunnar Mills 
12396bd5a8d2SGunnar Mills                         if (!autoRebootAttemptsLeftPtr)
12406bd5a8d2SGunnar Mills                         {
12416bd5a8d2SGunnar Mills                             messages::internalError(aResp->res);
12426bd5a8d2SGunnar Mills                             return;
12436bd5a8d2SGunnar Mills                         }
12446bd5a8d2SGunnar Mills 
12456bd5a8d2SGunnar Mills                         BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
12466bd5a8d2SGunnar Mills                                          << *autoRebootAttemptsLeftPtr;
12476bd5a8d2SGunnar Mills 
12486bd5a8d2SGunnar Mills                         aResp->res
12496bd5a8d2SGunnar Mills                             .jsonValue["Boot"]
12506bd5a8d2SGunnar Mills                                       ["RemainingAutomaticRetryAttempts"] =
12516bd5a8d2SGunnar Mills                             *autoRebootAttemptsLeftPtr;
12526bd5a8d2SGunnar Mills                     },
12536bd5a8d2SGunnar Mills                     "xyz.openbmc_project.State.Host",
12546bd5a8d2SGunnar Mills                     "/xyz/openbmc_project/state/host0",
12556bd5a8d2SGunnar Mills                     "org.freedesktop.DBus.Properties", "Get",
12566bd5a8d2SGunnar Mills                     "xyz.openbmc_project.Control.Boot.RebootAttempts",
12576bd5a8d2SGunnar Mills                     "AttemptsLeft");
12586bd5a8d2SGunnar Mills             }
12596bd5a8d2SGunnar Mills             else
12606bd5a8d2SGunnar Mills             {
12616bd5a8d2SGunnar Mills                 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
12626bd5a8d2SGunnar Mills                     "Disabled";
12636bd5a8d2SGunnar Mills             }
12646bd5a8d2SGunnar Mills 
12656bd5a8d2SGunnar Mills             // Not on D-Bus. Hardcoded here:
12666bd5a8d2SGunnar Mills             // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
12676bd5a8d2SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
126869f35306SGunnar Mills 
126969f35306SGunnar Mills             // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
127069f35306SGunnar Mills             // and RetryAttempts. OpenBMC only supports Disabled and
127169f35306SGunnar Mills             // RetryAttempts.
127269f35306SGunnar Mills             aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
127369f35306SGunnar Mills                                          "AllowableValues"] = {"Disabled",
127469f35306SGunnar Mills                                                                "RetryAttempts"};
12756bd5a8d2SGunnar Mills         },
12766bd5a8d2SGunnar Mills         "xyz.openbmc_project.Settings",
12776bd5a8d2SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
12786bd5a8d2SGunnar Mills         "org.freedesktop.DBus.Properties", "Get",
12796bd5a8d2SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
12806bd5a8d2SGunnar Mills }
12816bd5a8d2SGunnar Mills 
12826bd5a8d2SGunnar Mills /**
1283c6a620f2SGeorge Liu  * @brief Retrieves power restore policy over DBUS.
1284c6a620f2SGeorge Liu  *
1285c6a620f2SGeorge Liu  * @param[in] aResp     Shared pointer for generating response message.
1286c6a620f2SGeorge Liu  *
1287c6a620f2SGeorge Liu  * @return None.
1288c6a620f2SGeorge Liu  */
12898d1b46d7Szhanghch05 inline void
12908d1b46d7Szhanghch05     getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1291c6a620f2SGeorge Liu {
1292c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Get power restore policy";
1293c6a620f2SGeorge Liu 
1294c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1295c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec,
129619bd78d9SPatrick Williams                 std::variant<std::string>& policy) {
1297c6a620f2SGeorge Liu             if (ec)
1298c6a620f2SGeorge Liu             {
1299c6a620f2SGeorge Liu                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1300c6a620f2SGeorge Liu                 return;
1301c6a620f2SGeorge Liu             }
1302c6a620f2SGeorge Liu 
1303c6a620f2SGeorge Liu             const boost::container::flat_map<std::string, std::string>
1304c6a620f2SGeorge Liu                 policyMaps = {
1305c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1306c6a620f2SGeorge Liu                      "AlwaysOn",
1307c6a620f2SGeorge Liu                      "AlwaysOn"},
1308c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1309c6a620f2SGeorge Liu                      "AlwaysOff",
1310c6a620f2SGeorge Liu                      "AlwaysOff"},
1311c6a620f2SGeorge Liu                     {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
131237ec9072SGunnar Mills                      "Restore",
1313c6a620f2SGeorge Liu                      "LastState"}};
1314c6a620f2SGeorge Liu 
1315c6a620f2SGeorge Liu             const std::string* policyPtr = std::get_if<std::string>(&policy);
1316c6a620f2SGeorge Liu 
1317c6a620f2SGeorge Liu             if (!policyPtr)
1318c6a620f2SGeorge Liu             {
1319c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1320c6a620f2SGeorge Liu                 return;
1321c6a620f2SGeorge Liu             }
1322c6a620f2SGeorge Liu 
1323c6a620f2SGeorge Liu             auto policyMapsIt = policyMaps.find(*policyPtr);
1324c6a620f2SGeorge Liu             if (policyMapsIt == policyMaps.end())
1325c6a620f2SGeorge Liu             {
1326c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1327c6a620f2SGeorge Liu                 return;
1328c6a620f2SGeorge Liu             }
1329c6a620f2SGeorge Liu 
1330c6a620f2SGeorge Liu             aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1331c6a620f2SGeorge Liu         },
1332c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1333c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1334c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Get",
1335c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy",
1336c6a620f2SGeorge Liu         "PowerRestorePolicy");
1337c6a620f2SGeorge Liu }
1338c6a620f2SGeorge Liu 
1339c6a620f2SGeorge Liu /**
13401981771bSAli Ahmed  * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
13411981771bSAli Ahmed  * TPM is required for booting the host.
13421981771bSAli Ahmed  *
13431981771bSAli Ahmed  * @param[in] aResp     Shared pointer for generating response message.
13441981771bSAli Ahmed  *
13451981771bSAli Ahmed  * @return None.
13461981771bSAli Ahmed  */
13471981771bSAli Ahmed inline void getTrustedModuleRequiredToBoot(
13481981771bSAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp)
13491981771bSAli Ahmed {
13501981771bSAli Ahmed     BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
13511981771bSAli Ahmed 
13521981771bSAli Ahmed     crow::connections::systemBus->async_method_call(
13531981771bSAli Ahmed         [aResp](
13541981771bSAli Ahmed             const boost::system::error_code ec,
13551981771bSAli Ahmed             std::vector<std::pair<
13561981771bSAli Ahmed                 std::string,
13571981771bSAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
13581981771bSAli Ahmed                 subtree) {
13591981771bSAli Ahmed             if (ec)
13601981771bSAli Ahmed             {
13611981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13621981771bSAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
13631981771bSAli Ahmed                 // This is an optional D-Bus object so just return if
13641981771bSAli Ahmed                 // error occurs
13651981771bSAli Ahmed                 return;
13661981771bSAli Ahmed             }
13671981771bSAli Ahmed             if (subtree.size() == 0)
13681981771bSAli Ahmed             {
13691981771bSAli Ahmed                 // As noted above, this is an optional interface so just return
13701981771bSAli Ahmed                 // if there is no instance found
13711981771bSAli Ahmed                 return;
13721981771bSAli Ahmed             }
13731981771bSAli Ahmed 
13741981771bSAli Ahmed             /* When there is more than one TPMEnable object... */
13751981771bSAli Ahmed             if (subtree.size() > 1)
13761981771bSAli Ahmed             {
13771981771bSAli Ahmed                 BMCWEB_LOG_DEBUG
13781981771bSAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
13791981771bSAli Ahmed                     << subtree.size();
13801981771bSAli Ahmed                 // Throw an internal Error and return
13811981771bSAli Ahmed                 messages::internalError(aResp->res);
13821981771bSAli Ahmed                 return;
13831981771bSAli Ahmed             }
13841981771bSAli Ahmed 
13851981771bSAli Ahmed             // Make sure the Dbus response map has a service and objectPath
13861981771bSAli Ahmed             // field
13871981771bSAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
13881981771bSAli Ahmed             {
13891981771bSAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
13901981771bSAli Ahmed                 messages::internalError(aResp->res);
13911981771bSAli Ahmed                 return;
13921981771bSAli Ahmed             }
13931981771bSAli Ahmed 
13941981771bSAli Ahmed             const std::string& path = subtree[0].first;
13951981771bSAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
13961981771bSAli Ahmed 
13971981771bSAli Ahmed             // Valid TPM Enable object found, now reading the current value
13981981771bSAli Ahmed             crow::connections::systemBus->async_method_call(
13991981771bSAli Ahmed                 [aResp](const boost::system::error_code ec,
14001981771bSAli Ahmed                         std::variant<bool>& tpmRequired) {
14011981771bSAli Ahmed                     if (ec)
14021981771bSAli Ahmed                     {
14031981771bSAli Ahmed                         BMCWEB_LOG_DEBUG
14041981771bSAli Ahmed                             << "D-BUS response error on TPM.Policy Get" << ec;
14051981771bSAli Ahmed                         messages::internalError(aResp->res);
14061981771bSAli Ahmed                         return;
14071981771bSAli Ahmed                     }
14081981771bSAli Ahmed 
14091981771bSAli Ahmed                     const bool* tpmRequiredVal =
14101981771bSAli Ahmed                         std::get_if<bool>(&tpmRequired);
14111981771bSAli Ahmed 
14121981771bSAli Ahmed                     if (!tpmRequiredVal)
14131981771bSAli Ahmed                     {
14141981771bSAli Ahmed                         messages::internalError(aResp->res);
14151981771bSAli Ahmed                         return;
14161981771bSAli Ahmed                     }
14171981771bSAli Ahmed 
14181981771bSAli Ahmed                     if (*tpmRequiredVal == true)
14191981771bSAli Ahmed                     {
14201981771bSAli Ahmed                         aResp->res
14211981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14221981771bSAli Ahmed                             "Required";
14231981771bSAli Ahmed                     }
14241981771bSAli Ahmed                     else
14251981771bSAli Ahmed                     {
14261981771bSAli Ahmed                         aResp->res
14271981771bSAli Ahmed                             .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
14281981771bSAli Ahmed                             "Disabled";
14291981771bSAli Ahmed                     }
14301981771bSAli Ahmed                 },
14311981771bSAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Get",
14321981771bSAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable");
14331981771bSAli Ahmed         },
14341981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper",
14351981771bSAli Ahmed         "/xyz/openbmc_project/object_mapper",
14361981771bSAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
14371981771bSAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
14381981771bSAli Ahmed }
14391981771bSAli Ahmed 
14401981771bSAli Ahmed /**
14411c05dae3SAli Ahmed  * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
14421c05dae3SAli Ahmed  * TPM is required for booting the host.
14431c05dae3SAli Ahmed  *
14441c05dae3SAli Ahmed  * @param[in] aResp         Shared pointer for generating response message.
14451c05dae3SAli Ahmed  * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
14461c05dae3SAli Ahmed  *
14471c05dae3SAli Ahmed  * @return None.
14481c05dae3SAli Ahmed  */
14491c05dae3SAli Ahmed inline void setTrustedModuleRequiredToBoot(
14501c05dae3SAli Ahmed     const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
14511c05dae3SAli Ahmed {
14521c05dae3SAli Ahmed     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
14531c05dae3SAli Ahmed 
14541c05dae3SAli Ahmed     crow::connections::systemBus->async_method_call(
14551c05dae3SAli Ahmed         [aResp, tpmRequired](
14561c05dae3SAli Ahmed             const boost::system::error_code ec,
14571c05dae3SAli Ahmed             std::vector<std::pair<
14581c05dae3SAli Ahmed                 std::string,
14591c05dae3SAli Ahmed                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
14601c05dae3SAli Ahmed                 subtree) {
14611c05dae3SAli Ahmed             if (ec)
14621c05dae3SAli Ahmed             {
14631c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14641c05dae3SAli Ahmed                     << "DBUS response error on TPM.Policy GetSubTree" << ec;
14651c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14661c05dae3SAli Ahmed                 return;
14671c05dae3SAli Ahmed             }
14681c05dae3SAli Ahmed             if (subtree.size() == 0)
14691c05dae3SAli Ahmed             {
14701c05dae3SAli Ahmed                 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
14711c05dae3SAli Ahmed                                                  "TrustedModuleRequiredToBoot");
14721c05dae3SAli Ahmed                 return;
14731c05dae3SAli Ahmed             }
14741c05dae3SAli Ahmed 
14751c05dae3SAli Ahmed             /* When there is more than one TPMEnable object... */
14761c05dae3SAli Ahmed             if (subtree.size() > 1)
14771c05dae3SAli Ahmed             {
14781c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG
14791c05dae3SAli Ahmed                     << "DBUS response has more than 1 TPM Enable object:"
14801c05dae3SAli Ahmed                     << subtree.size();
14811c05dae3SAli Ahmed                 // Throw an internal Error and return
14821c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14831c05dae3SAli Ahmed                 return;
14841c05dae3SAli Ahmed             }
14851c05dae3SAli Ahmed 
14861c05dae3SAli Ahmed             // Make sure the Dbus response map has a service and objectPath
14871c05dae3SAli Ahmed             // field
14881c05dae3SAli Ahmed             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
14891c05dae3SAli Ahmed             {
14901c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
14911c05dae3SAli Ahmed                 messages::internalError(aResp->res);
14921c05dae3SAli Ahmed                 return;
14931c05dae3SAli Ahmed             }
14941c05dae3SAli Ahmed 
14951c05dae3SAli Ahmed             const std::string& path = subtree[0].first;
14961c05dae3SAli Ahmed             const std::string& serv = subtree[0].second.begin()->first;
14971c05dae3SAli Ahmed 
14981c05dae3SAli Ahmed             if (serv.empty())
14991c05dae3SAli Ahmed             {
15001c05dae3SAli Ahmed                 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
15011c05dae3SAli Ahmed                 messages::internalError(aResp->res);
15021c05dae3SAli Ahmed                 return;
15031c05dae3SAli Ahmed             }
15041c05dae3SAli Ahmed 
15051c05dae3SAli Ahmed             // Valid TPM Enable object found, now setting the value
15061c05dae3SAli Ahmed             crow::connections::systemBus->async_method_call(
15071c05dae3SAli Ahmed                 [aResp](const boost::system::error_code ec) {
15081c05dae3SAli Ahmed                     if (ec)
15091c05dae3SAli Ahmed                     {
15101c05dae3SAli Ahmed                         BMCWEB_LOG_DEBUG << "DBUS response error: Set "
15111c05dae3SAli Ahmed                                             "TrustedModuleRequiredToBoot"
15121c05dae3SAli Ahmed                                          << ec;
15131c05dae3SAli Ahmed                         messages::internalError(aResp->res);
15141c05dae3SAli Ahmed                         return;
15151c05dae3SAli Ahmed                     }
15161c05dae3SAli Ahmed                     BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
15171c05dae3SAli Ahmed                 },
15181c05dae3SAli Ahmed                 serv, path, "org.freedesktop.DBus.Properties", "Set",
15191c05dae3SAli Ahmed                 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
15201c05dae3SAli Ahmed                 std::variant<bool>(tpmRequired));
15211c05dae3SAli Ahmed         },
15221c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper",
15231c05dae3SAli Ahmed         "/xyz/openbmc_project/object_mapper",
15241c05dae3SAli Ahmed         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
15251c05dae3SAli Ahmed         std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
15261c05dae3SAli Ahmed }
15271c05dae3SAli Ahmed 
15281c05dae3SAli Ahmed /**
1529491d8ee7SSantosh Puranik  * @brief Sets boot properties into DBUS object(s).
1530491d8ee7SSantosh Puranik  *
1531491d8ee7SSantosh Puranik  * @param[in] aResp           Shared pointer for generating response message.
1532cd9a4666SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1533cd9a4666SKonstantin Aladyshev  * @return Integer error code.
1534cd9a4666SKonstantin Aladyshev  */
1535cd9a4666SKonstantin Aladyshev inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1536cd9a4666SKonstantin Aladyshev                         const std::optional<std::string>& bootType)
1537cd9a4666SKonstantin Aladyshev {
1538c21865c4SKonstantin Aladyshev     std::string bootTypeStr;
1539cd9a4666SKonstantin Aladyshev 
1540c21865c4SKonstantin Aladyshev     if (!bootType)
1541cd9a4666SKonstantin Aladyshev     {
1542c21865c4SKonstantin Aladyshev         return;
1543c21865c4SKonstantin Aladyshev     }
1544c21865c4SKonstantin Aladyshev 
1545cd9a4666SKonstantin Aladyshev     // Source target specified
1546cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1547cd9a4666SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1548cd9a4666SKonstantin Aladyshev     if (*bootType == "Legacy")
1549cd9a4666SKonstantin Aladyshev     {
1550cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1551cd9a4666SKonstantin Aladyshev     }
1552cd9a4666SKonstantin Aladyshev     else if (*bootType == "UEFI")
1553cd9a4666SKonstantin Aladyshev     {
1554cd9a4666SKonstantin Aladyshev         bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1555cd9a4666SKonstantin Aladyshev     }
1556cd9a4666SKonstantin Aladyshev     else
1557cd9a4666SKonstantin Aladyshev     {
1558cd9a4666SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1559cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode: "
1560cd9a4666SKonstantin Aladyshev                          << *bootType;
1561cd9a4666SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootType,
1562cd9a4666SKonstantin Aladyshev                                          "BootSourceOverrideMode");
1563cd9a4666SKonstantin Aladyshev         return;
1564cd9a4666SKonstantin Aladyshev     }
1565cd9a4666SKonstantin Aladyshev 
1566cd9a4666SKonstantin Aladyshev     // Act on validated parameters
1567cd9a4666SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1568cd9a4666SKonstantin Aladyshev 
1569cd9a4666SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1570c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1571cd9a4666SKonstantin Aladyshev             if (ec)
1572cd9a4666SKonstantin Aladyshev             {
1573cd9a4666SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1574cd9a4666SKonstantin Aladyshev                 if (ec.value() == boost::asio::error::host_unreachable)
1575cd9a4666SKonstantin Aladyshev                 {
1576cd9a4666SKonstantin Aladyshev                     messages::resourceNotFound(aResp->res, "Set", "BootType");
1577cd9a4666SKonstantin Aladyshev                     return;
1578cd9a4666SKonstantin Aladyshev                 }
1579cd9a4666SKonstantin Aladyshev                 messages::internalError(aResp->res);
1580cd9a4666SKonstantin Aladyshev                 return;
1581cd9a4666SKonstantin Aladyshev             }
1582cd9a4666SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot type update done.";
1583cd9a4666SKonstantin Aladyshev         },
1584c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1585c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1586cd9a4666SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1587cd9a4666SKonstantin Aladyshev         "xyz.openbmc_project.Control.Boot.Type", "BootType",
1588cd9a4666SKonstantin Aladyshev         std::variant<std::string>(bootTypeStr));
1589cd9a4666SKonstantin Aladyshev }
1590cd9a4666SKonstantin Aladyshev 
1591cd9a4666SKonstantin Aladyshev /**
1592cd9a4666SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1593cd9a4666SKonstantin Aladyshev  *
1594cd9a4666SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1595c21865c4SKonstantin Aladyshev  * @param[in] bootType        The boot type to set.
1596c21865c4SKonstantin Aladyshev  * @return Integer error code.
1597c21865c4SKonstantin Aladyshev  */
1598c21865c4SKonstantin Aladyshev inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1599c21865c4SKonstantin Aladyshev                           const std::optional<std::string>& bootEnable)
1600c21865c4SKonstantin Aladyshev {
1601c21865c4SKonstantin Aladyshev     if (!bootEnable)
1602c21865c4SKonstantin Aladyshev     {
1603c21865c4SKonstantin Aladyshev         return;
1604c21865c4SKonstantin Aladyshev     }
1605c21865c4SKonstantin Aladyshev     // Source target specified
1606c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1607c21865c4SKonstantin Aladyshev 
1608c21865c4SKonstantin Aladyshev     bool bootOverrideEnable = false;
1609c21865c4SKonstantin Aladyshev     bool bootOverridePersistent = false;
1610c21865c4SKonstantin Aladyshev     // Figure out which DBUS interface and property to use
1611c21865c4SKonstantin Aladyshev     if (*bootEnable == "Disabled")
1612c21865c4SKonstantin Aladyshev     {
1613c21865c4SKonstantin Aladyshev         bootOverrideEnable = false;
1614c21865c4SKonstantin Aladyshev     }
1615c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Once")
1616c21865c4SKonstantin Aladyshev     {
1617c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1618c21865c4SKonstantin Aladyshev         bootOverridePersistent = false;
1619c21865c4SKonstantin Aladyshev     }
1620c21865c4SKonstantin Aladyshev     else if (*bootEnable == "Continuous")
1621c21865c4SKonstantin Aladyshev     {
1622c21865c4SKonstantin Aladyshev         bootOverrideEnable = true;
1623c21865c4SKonstantin Aladyshev         bootOverridePersistent = true;
1624c21865c4SKonstantin Aladyshev     }
1625c21865c4SKonstantin Aladyshev     else
1626c21865c4SKonstantin Aladyshev     {
1627c21865c4SKonstantin Aladyshev         BMCWEB_LOG_DEBUG << "Invalid property value for "
1628c21865c4SKonstantin Aladyshev                             "BootSourceOverrideEnabled: "
1629c21865c4SKonstantin Aladyshev                          << *bootEnable;
1630c21865c4SKonstantin Aladyshev         messages::propertyValueNotInList(aResp->res, *bootEnable,
1631c21865c4SKonstantin Aladyshev                                          "BootSourceOverrideEnabled");
1632c21865c4SKonstantin Aladyshev         return;
1633c21865c4SKonstantin Aladyshev     }
1634c21865c4SKonstantin Aladyshev 
1635c21865c4SKonstantin Aladyshev     // Act on validated parameters
1636c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1637c21865c4SKonstantin Aladyshev 
1638c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1639c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1640c21865c4SKonstantin Aladyshev             if (ec)
1641c21865c4SKonstantin Aladyshev             {
1642c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1643c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1644c21865c4SKonstantin Aladyshev                 return;
1645c21865c4SKonstantin Aladyshev             }
1646c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot override enable update done.";
1647c21865c4SKonstantin Aladyshev         },
1648c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1649c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1650c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1651c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1652c21865c4SKonstantin Aladyshev         std::variant<bool>(bootOverrideEnable));
1653c21865c4SKonstantin Aladyshev 
1654c21865c4SKonstantin Aladyshev     if (!bootOverrideEnable)
1655c21865c4SKonstantin Aladyshev     {
1656c21865c4SKonstantin Aladyshev         return;
1657c21865c4SKonstantin Aladyshev     }
1658c21865c4SKonstantin Aladyshev 
1659c21865c4SKonstantin Aladyshev     // In case boot override is enabled we need to set correct value for the
1660c21865c4SKonstantin Aladyshev     // 'one_time' enable DBus interface
1661c21865c4SKonstantin Aladyshev     BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1662c21865c4SKonstantin Aladyshev                      << bootOverridePersistent;
1663c21865c4SKonstantin Aladyshev 
1664c21865c4SKonstantin Aladyshev     crow::connections::systemBus->async_method_call(
1665c21865c4SKonstantin Aladyshev         [aResp](const boost::system::error_code ec) {
1666c21865c4SKonstantin Aladyshev             if (ec)
1667c21865c4SKonstantin Aladyshev             {
1668c21865c4SKonstantin Aladyshev                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1669c21865c4SKonstantin Aladyshev                 messages::internalError(aResp->res);
1670c21865c4SKonstantin Aladyshev                 return;
1671c21865c4SKonstantin Aladyshev             }
1672c21865c4SKonstantin Aladyshev             BMCWEB_LOG_DEBUG << "Boot one_time update done.";
1673c21865c4SKonstantin Aladyshev         },
1674c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1675c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot/one_time",
1676c21865c4SKonstantin Aladyshev         "org.freedesktop.DBus.Properties", "Set",
1677c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Object.Enable", "Enabled",
1678c21865c4SKonstantin Aladyshev         std::variant<bool>(!bootOverridePersistent));
1679c21865c4SKonstantin Aladyshev }
1680c21865c4SKonstantin Aladyshev 
1681c21865c4SKonstantin Aladyshev /**
1682c21865c4SKonstantin Aladyshev  * @brief Sets boot properties into DBUS object(s).
1683c21865c4SKonstantin Aladyshev  *
1684c21865c4SKonstantin Aladyshev  * @param[in] aResp           Shared pointer for generating response message.
1685491d8ee7SSantosh Puranik  * @param[in] bootSource      The boot source to set.
1686491d8ee7SSantosh Puranik  *
1687265c1602SJohnathan Mantey  * @return Integer error code.
1688491d8ee7SSantosh Puranik  */
1689cd9a4666SKonstantin Aladyshev inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1690cd9a4666SKonstantin Aladyshev                                 const std::optional<std::string>& bootSource)
1691491d8ee7SSantosh Puranik {
1692c21865c4SKonstantin Aladyshev     std::string bootSourceStr;
1693c21865c4SKonstantin Aladyshev     std::string bootModeStr;
1694944ffaf9SJohnathan Mantey 
1695c21865c4SKonstantin Aladyshev     if (!bootSource)
1696491d8ee7SSantosh Puranik     {
1697c21865c4SKonstantin Aladyshev         return;
1698c21865c4SKonstantin Aladyshev     }
1699c21865c4SKonstantin Aladyshev 
1700491d8ee7SSantosh Puranik     // Source target specified
1701491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1702491d8ee7SSantosh Puranik     // Figure out which DBUS interface and property to use
1703c21865c4SKonstantin Aladyshev     if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr))
1704491d8ee7SSantosh Puranik     {
1705944ffaf9SJohnathan Mantey         BMCWEB_LOG_DEBUG
1706944ffaf9SJohnathan Mantey             << "Invalid property value for BootSourceOverrideTarget: "
1707491d8ee7SSantosh Puranik             << *bootSource;
1708491d8ee7SSantosh Puranik         messages::propertyValueNotInList(aResp->res, *bootSource,
1709491d8ee7SSantosh Puranik                                          "BootSourceTargetOverride");
1710491d8ee7SSantosh Puranik         return;
1711491d8ee7SSantosh Puranik     }
1712491d8ee7SSantosh Puranik 
1713944ffaf9SJohnathan Mantey     // Act on validated parameters
1714944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1715944ffaf9SJohnathan Mantey     BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1716944ffaf9SJohnathan Mantey 
1717491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1718491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1719491d8ee7SSantosh Puranik             if (ec)
1720491d8ee7SSantosh Puranik             {
1721491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1722491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1723491d8ee7SSantosh Puranik                 return;
1724491d8ee7SSantosh Puranik             }
1725491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot source update done.";
1726491d8ee7SSantosh Puranik         },
1727c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1728c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1729491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1730491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1731491d8ee7SSantosh Puranik         std::variant<std::string>(bootSourceStr));
1732944ffaf9SJohnathan Mantey 
1733491d8ee7SSantosh Puranik     crow::connections::systemBus->async_method_call(
1734491d8ee7SSantosh Puranik         [aResp](const boost::system::error_code ec) {
1735491d8ee7SSantosh Puranik             if (ec)
1736491d8ee7SSantosh Puranik             {
1737491d8ee7SSantosh Puranik                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1738491d8ee7SSantosh Puranik                 messages::internalError(aResp->res);
1739491d8ee7SSantosh Puranik                 return;
1740491d8ee7SSantosh Puranik             }
1741491d8ee7SSantosh Puranik             BMCWEB_LOG_DEBUG << "Boot mode update done.";
1742491d8ee7SSantosh Puranik         },
1743c21865c4SKonstantin Aladyshev         "xyz.openbmc_project.Settings",
1744c21865c4SKonstantin Aladyshev         "/xyz/openbmc_project/control/host0/boot",
1745491d8ee7SSantosh Puranik         "org.freedesktop.DBus.Properties", "Set",
1746491d8ee7SSantosh Puranik         "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1747491d8ee7SSantosh Puranik         std::variant<std::string>(bootModeStr));
1748cd9a4666SKonstantin Aladyshev }
1749944ffaf9SJohnathan Mantey 
1750cd9a4666SKonstantin Aladyshev /**
1751c21865c4SKonstantin Aladyshev  * @brief Sets Boot source override properties.
1752491d8ee7SSantosh Puranik  *
1753491d8ee7SSantosh Puranik  * @param[in] aResp      Shared pointer for generating response message.
1754491d8ee7SSantosh Puranik  * @param[in] bootSource The boot source from incoming RF request.
1755cd9a4666SKonstantin Aladyshev  * @param[in] bootType   The boot type from incoming RF request.
1756491d8ee7SSantosh Puranik  * @param[in] bootEnable The boot override enable from incoming RF request.
1757491d8ee7SSantosh Puranik  *
1758265c1602SJohnathan Mantey  * @return Integer error code.
1759491d8ee7SSantosh Puranik  */
1760c21865c4SKonstantin Aladyshev 
1761c21865c4SKonstantin Aladyshev inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1762c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootSource,
1763c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootType,
1764c21865c4SKonstantin Aladyshev                               const std::optional<std::string>& bootEnable)
1765491d8ee7SSantosh Puranik {
1766491d8ee7SSantosh Puranik     BMCWEB_LOG_DEBUG << "Set boot information.";
1767491d8ee7SSantosh Puranik 
1768c21865c4SKonstantin Aladyshev     setBootModeOrSource(aResp, bootSource);
1769c21865c4SKonstantin Aladyshev     setBootType(aResp, bootType);
1770c21865c4SKonstantin Aladyshev     setBootEnable(aResp, bootEnable);
1771491d8ee7SSantosh Puranik }
1772491d8ee7SSantosh Puranik 
1773c6a620f2SGeorge Liu /**
177498e386ecSGunnar Mills  * @brief Sets AssetTag
177598e386ecSGunnar Mills  *
177698e386ecSGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
177798e386ecSGunnar Mills  * @param[in] assetTag  "AssetTag" from request.
177898e386ecSGunnar Mills  *
177998e386ecSGunnar Mills  * @return None.
178098e386ecSGunnar Mills  */
17818d1b46d7Szhanghch05 inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
178298e386ecSGunnar Mills                         const std::string& assetTag)
178398e386ecSGunnar Mills {
178498e386ecSGunnar Mills     crow::connections::systemBus->async_method_call(
178598e386ecSGunnar Mills         [aResp, assetTag](
178698e386ecSGunnar Mills             const boost::system::error_code ec,
178798e386ecSGunnar Mills             const std::vector<std::pair<
178898e386ecSGunnar Mills                 std::string,
178998e386ecSGunnar Mills                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
179098e386ecSGunnar Mills                 subtree) {
179198e386ecSGunnar Mills             if (ec)
179298e386ecSGunnar Mills             {
179398e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
179498e386ecSGunnar Mills                 messages::internalError(aResp->res);
179598e386ecSGunnar Mills                 return;
179698e386ecSGunnar Mills             }
179798e386ecSGunnar Mills             if (subtree.size() == 0)
179898e386ecSGunnar Mills             {
179998e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
180098e386ecSGunnar Mills                 messages::internalError(aResp->res);
180198e386ecSGunnar Mills                 return;
180298e386ecSGunnar Mills             }
180398e386ecSGunnar Mills             // Assume only 1 system D-Bus object
180498e386ecSGunnar Mills             // Throw an error if there is more than 1
180598e386ecSGunnar Mills             if (subtree.size() > 1)
180698e386ecSGunnar Mills             {
180798e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
180898e386ecSGunnar Mills                 messages::internalError(aResp->res);
180998e386ecSGunnar Mills                 return;
181098e386ecSGunnar Mills             }
181198e386ecSGunnar Mills             if (subtree[0].first.empty() || subtree[0].second.size() != 1)
181298e386ecSGunnar Mills             {
181398e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
181498e386ecSGunnar Mills                 messages::internalError(aResp->res);
181598e386ecSGunnar Mills                 return;
181698e386ecSGunnar Mills             }
181798e386ecSGunnar Mills 
181898e386ecSGunnar Mills             const std::string& path = subtree[0].first;
181998e386ecSGunnar Mills             const std::string& service = subtree[0].second.begin()->first;
182098e386ecSGunnar Mills 
182198e386ecSGunnar Mills             if (service.empty())
182298e386ecSGunnar Mills             {
182398e386ecSGunnar Mills                 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
182498e386ecSGunnar Mills                 messages::internalError(aResp->res);
182598e386ecSGunnar Mills                 return;
182698e386ecSGunnar Mills             }
182798e386ecSGunnar Mills 
182898e386ecSGunnar Mills             crow::connections::systemBus->async_method_call(
182998e386ecSGunnar Mills                 [aResp](const boost::system::error_code ec2) {
183098e386ecSGunnar Mills                     if (ec2)
183198e386ecSGunnar Mills                     {
183298e386ecSGunnar Mills                         BMCWEB_LOG_DEBUG
183398e386ecSGunnar Mills                             << "D-Bus response error on AssetTag Set " << ec2;
183498e386ecSGunnar Mills                         messages::internalError(aResp->res);
183598e386ecSGunnar Mills                         return;
183698e386ecSGunnar Mills                     }
183798e386ecSGunnar Mills                 },
183898e386ecSGunnar Mills                 service, path, "org.freedesktop.DBus.Properties", "Set",
183998e386ecSGunnar Mills                 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
184098e386ecSGunnar Mills                 std::variant<std::string>(assetTag));
184198e386ecSGunnar Mills         },
184298e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper",
184398e386ecSGunnar Mills         "/xyz/openbmc_project/object_mapper",
184498e386ecSGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
184598e386ecSGunnar Mills         "/xyz/openbmc_project/inventory", int32_t(0),
184698e386ecSGunnar Mills         std::array<const char*, 1>{
184798e386ecSGunnar Mills             "xyz.openbmc_project.Inventory.Item.System"});
184898e386ecSGunnar Mills }
184998e386ecSGunnar Mills 
185098e386ecSGunnar Mills /**
185169f35306SGunnar Mills  * @brief Sets automaticRetry (Auto Reboot)
185269f35306SGunnar Mills  *
185369f35306SGunnar Mills  * @param[in] aResp   Shared pointer for generating response message.
185469f35306SGunnar Mills  * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
185569f35306SGunnar Mills  *
185669f35306SGunnar Mills  * @return None.
185769f35306SGunnar Mills  */
18588d1b46d7Szhanghch05 inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1859f23b7296SEd Tanous                               const std::string& automaticRetryConfig)
186069f35306SGunnar Mills {
186169f35306SGunnar Mills     BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
186269f35306SGunnar Mills 
186369f35306SGunnar Mills     // OpenBMC only supports "Disabled" and "RetryAttempts".
186469f35306SGunnar Mills     bool autoRebootEnabled;
186569f35306SGunnar Mills 
186669f35306SGunnar Mills     if (automaticRetryConfig == "Disabled")
186769f35306SGunnar Mills     {
186869f35306SGunnar Mills         autoRebootEnabled = false;
186969f35306SGunnar Mills     }
187069f35306SGunnar Mills     else if (automaticRetryConfig == "RetryAttempts")
187169f35306SGunnar Mills     {
187269f35306SGunnar Mills         autoRebootEnabled = true;
187369f35306SGunnar Mills     }
187469f35306SGunnar Mills     else
187569f35306SGunnar Mills     {
187669f35306SGunnar Mills         BMCWEB_LOG_DEBUG << "Invalid property value for "
187769f35306SGunnar Mills                             "AutomaticRetryConfig: "
187869f35306SGunnar Mills                          << automaticRetryConfig;
187969f35306SGunnar Mills         messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
188069f35306SGunnar Mills                                          "AutomaticRetryConfig");
188169f35306SGunnar Mills         return;
188269f35306SGunnar Mills     }
188369f35306SGunnar Mills 
188469f35306SGunnar Mills     crow::connections::systemBus->async_method_call(
188569f35306SGunnar Mills         [aResp](const boost::system::error_code ec) {
188669f35306SGunnar Mills             if (ec)
188769f35306SGunnar Mills             {
188869f35306SGunnar Mills                 messages::internalError(aResp->res);
188969f35306SGunnar Mills                 return;
189069f35306SGunnar Mills             }
189169f35306SGunnar Mills         },
189269f35306SGunnar Mills         "xyz.openbmc_project.Settings",
189369f35306SGunnar Mills         "/xyz/openbmc_project/control/host0/auto_reboot",
189469f35306SGunnar Mills         "org.freedesktop.DBus.Properties", "Set",
189569f35306SGunnar Mills         "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
189669f35306SGunnar Mills         std::variant<bool>(autoRebootEnabled));
189769f35306SGunnar Mills }
189869f35306SGunnar Mills 
189969f35306SGunnar Mills /**
1900c6a620f2SGeorge Liu  * @brief Sets power restore policy properties.
1901c6a620f2SGeorge Liu  *
1902c6a620f2SGeorge Liu  * @param[in] aResp   Shared pointer for generating response message.
1903c6a620f2SGeorge Liu  * @param[in] policy  power restore policy properties from request.
1904c6a620f2SGeorge Liu  *
1905c6a620f2SGeorge Liu  * @return None.
1906c6a620f2SGeorge Liu  */
19078d1b46d7Szhanghch05 inline void
19088d1b46d7Szhanghch05     setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
19094e69c904SGunnar Mills                           const std::string& policy)
1910c6a620f2SGeorge Liu {
1911c6a620f2SGeorge Liu     BMCWEB_LOG_DEBUG << "Set power restore policy.";
1912c6a620f2SGeorge Liu 
1913c6a620f2SGeorge Liu     const boost::container::flat_map<std::string, std::string> policyMaps = {
1914c6a620f2SGeorge Liu         {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1915c6a620f2SGeorge Liu                      "AlwaysOn"},
1916c6a620f2SGeorge Liu         {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1917c6a620f2SGeorge Liu                       "AlwaysOff"},
1918c6a620f2SGeorge Liu         {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
191937ec9072SGunnar Mills                       "Restore"}};
1920c6a620f2SGeorge Liu 
1921c6a620f2SGeorge Liu     std::string powerRestorPolicy;
1922c6a620f2SGeorge Liu 
19234e69c904SGunnar Mills     auto policyMapsIt = policyMaps.find(policy);
1924c6a620f2SGeorge Liu     if (policyMapsIt == policyMaps.end())
1925c6a620f2SGeorge Liu     {
19264e69c904SGunnar Mills         messages::propertyValueNotInList(aResp->res, policy,
19274e69c904SGunnar Mills                                          "PowerRestorePolicy");
1928c6a620f2SGeorge Liu         return;
1929c6a620f2SGeorge Liu     }
1930c6a620f2SGeorge Liu 
1931c6a620f2SGeorge Liu     powerRestorPolicy = policyMapsIt->second;
1932c6a620f2SGeorge Liu 
1933c6a620f2SGeorge Liu     crow::connections::systemBus->async_method_call(
1934c6a620f2SGeorge Liu         [aResp](const boost::system::error_code ec) {
1935c6a620f2SGeorge Liu             if (ec)
1936c6a620f2SGeorge Liu             {
1937c6a620f2SGeorge Liu                 messages::internalError(aResp->res);
1938c6a620f2SGeorge Liu                 return;
1939c6a620f2SGeorge Liu             }
1940c6a620f2SGeorge Liu         },
1941c6a620f2SGeorge Liu         "xyz.openbmc_project.Settings",
1942c6a620f2SGeorge Liu         "/xyz/openbmc_project/control/host0/power_restore_policy",
1943c6a620f2SGeorge Liu         "org.freedesktop.DBus.Properties", "Set",
1944c6a620f2SGeorge Liu         "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1945c6a620f2SGeorge Liu         std::variant<std::string>(powerRestorPolicy));
1946c6a620f2SGeorge Liu }
1947c6a620f2SGeorge Liu 
1948a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1949a6349918SAppaRao Puli /**
1950a6349918SAppaRao Puli  * @brief Retrieves provisioning status
1951a6349918SAppaRao Puli  *
1952a6349918SAppaRao Puli  * @param[in] aResp     Shared pointer for completing asynchronous calls.
1953a6349918SAppaRao Puli  *
1954a6349918SAppaRao Puli  * @return None.
1955a6349918SAppaRao Puli  */
19568d1b46d7Szhanghch05 inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
1957a6349918SAppaRao Puli {
1958a6349918SAppaRao Puli     BMCWEB_LOG_DEBUG << "Get OEM information.";
1959a6349918SAppaRao Puli     crow::connections::systemBus->async_method_call(
1960a6349918SAppaRao Puli         [aResp](const boost::system::error_code ec,
19611214b7e7SGunnar Mills                 const std::vector<std::pair<std::string, VariantType>>&
19621214b7e7SGunnar Mills                     propertiesList) {
1963b99fb1a9SAppaRao Puli             nlohmann::json& oemPFR =
1964b99fb1a9SAppaRao Puli                 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
196550626f4fSJames Feist             aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
196650626f4fSJames Feist                 "#OemComputerSystem.OpenBmc";
196750626f4fSJames Feist             oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
196850626f4fSJames Feist 
1969a6349918SAppaRao Puli             if (ec)
1970a6349918SAppaRao Puli             {
1971a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1972b99fb1a9SAppaRao Puli                 // not an error, don't have to have the interface
1973b99fb1a9SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1974a6349918SAppaRao Puli                 return;
1975a6349918SAppaRao Puli             }
1976a6349918SAppaRao Puli 
1977a6349918SAppaRao Puli             const bool* provState = nullptr;
1978a6349918SAppaRao Puli             const bool* lockState = nullptr;
1979a6349918SAppaRao Puli             for (const std::pair<std::string, VariantType>& property :
1980a6349918SAppaRao Puli                  propertiesList)
1981a6349918SAppaRao Puli             {
1982a6349918SAppaRao Puli                 if (property.first == "UfmProvisioned")
1983a6349918SAppaRao Puli                 {
1984a6349918SAppaRao Puli                     provState = std::get_if<bool>(&property.second);
1985a6349918SAppaRao Puli                 }
1986a6349918SAppaRao Puli                 else if (property.first == "UfmLocked")
1987a6349918SAppaRao Puli                 {
1988a6349918SAppaRao Puli                     lockState = std::get_if<bool>(&property.second);
1989a6349918SAppaRao Puli                 }
1990a6349918SAppaRao Puli             }
1991a6349918SAppaRao Puli 
1992a6349918SAppaRao Puli             if ((provState == nullptr) || (lockState == nullptr))
1993a6349918SAppaRao Puli             {
1994a6349918SAppaRao Puli                 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1995a6349918SAppaRao Puli                 messages::internalError(aResp->res);
1996a6349918SAppaRao Puli                 return;
1997a6349918SAppaRao Puli             }
1998a6349918SAppaRao Puli 
1999a6349918SAppaRao Puli             if (*provState == true)
2000a6349918SAppaRao Puli             {
2001a6349918SAppaRao Puli                 if (*lockState == true)
2002a6349918SAppaRao Puli                 {
2003a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
2004a6349918SAppaRao Puli                 }
2005a6349918SAppaRao Puli                 else
2006a6349918SAppaRao Puli                 {
2007a6349918SAppaRao Puli                     oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
2008a6349918SAppaRao Puli                 }
2009a6349918SAppaRao Puli             }
2010a6349918SAppaRao Puli             else
2011a6349918SAppaRao Puli             {
2012a6349918SAppaRao Puli                 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2013a6349918SAppaRao Puli             }
2014a6349918SAppaRao Puli         },
2015a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
2016a6349918SAppaRao Puli         "org.freedesktop.DBus.Properties", "GetAll",
2017a6349918SAppaRao Puli         "xyz.openbmc_project.PFR.Attributes");
2018a6349918SAppaRao Puli }
2019a6349918SAppaRao Puli #endif
2020a6349918SAppaRao Puli 
2021491d8ee7SSantosh Puranik /**
20223a2d0424SChris Cain  * @brief Translate the PowerMode to a response message.
20233a2d0424SChris Cain  *
20243a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20253a2d0424SChris Cain  * @param[in] modeValue  PowerMode value to be translated
20263a2d0424SChris Cain  *
20273a2d0424SChris Cain  * @return None.
20283a2d0424SChris Cain  */
20293a2d0424SChris Cain inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
20303a2d0424SChris Cain                                const std::string& modeValue)
20313a2d0424SChris Cain {
20323a2d0424SChris Cain     std::string modeString;
20333a2d0424SChris Cain 
20343a2d0424SChris Cain     if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20353a2d0424SChris Cain                      "PowerMode.Static")
20363a2d0424SChris Cain     {
20373a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "Static";
20383a2d0424SChris Cain     }
20393a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20403a2d0424SChris Cain                           "PowerMode.MaximumPerformance")
20413a2d0424SChris Cain     {
20423a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
20433a2d0424SChris Cain     }
20443a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20453a2d0424SChris Cain                           "PowerMode.PowerSaving")
20463a2d0424SChris Cain     {
20473a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "PowerSaving";
20483a2d0424SChris Cain     }
20493a2d0424SChris Cain     else if (modeValue == "xyz.openbmc_project.Control.Power.Mode."
20503a2d0424SChris Cain                           "PowerMode.OEM")
20513a2d0424SChris Cain     {
20523a2d0424SChris Cain         aResp->res.jsonValue["PowerMode"] = "OEM";
20533a2d0424SChris Cain     }
20543a2d0424SChris Cain     else
20553a2d0424SChris Cain     {
20563a2d0424SChris Cain         // Any other values would be invalid
20573a2d0424SChris Cain         BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
20583a2d0424SChris Cain         messages::internalError(aResp->res);
20593a2d0424SChris Cain     }
20603a2d0424SChris Cain }
20613a2d0424SChris Cain 
20623a2d0424SChris Cain /**
20633a2d0424SChris Cain  * @brief Retrieves system power mode
20643a2d0424SChris Cain  *
20653a2d0424SChris Cain  * @param[in] aResp  Shared pointer for generating response message.
20663a2d0424SChris Cain  *
20673a2d0424SChris Cain  * @return None.
20683a2d0424SChris Cain  */
20693a2d0424SChris Cain inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
20703a2d0424SChris Cain {
20713a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Get power mode.";
20723a2d0424SChris Cain 
20733a2d0424SChris Cain     // Get Power Mode object path:
20743a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
20753a2d0424SChris Cain         [aResp](
20763a2d0424SChris Cain             const boost::system::error_code ec,
20773a2d0424SChris Cain             const std::vector<std::pair<
20783a2d0424SChris Cain                 std::string,
20793a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
20803a2d0424SChris Cain                 subtree) {
20813a2d0424SChris Cain             if (ec)
20823a2d0424SChris Cain             {
20833a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
20843a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
20853a2d0424SChris Cain                 // This is an optional D-Bus object so just return if
20863a2d0424SChris Cain                 // error occurs
20873a2d0424SChris Cain                 return;
20883a2d0424SChris Cain             }
20893a2d0424SChris Cain             if (subtree.empty())
20903a2d0424SChris Cain             {
20913a2d0424SChris Cain                 // As noted above, this is an optional interface so just return
20923a2d0424SChris Cain                 // if there is no instance found
20933a2d0424SChris Cain                 return;
20943a2d0424SChris Cain             }
20953a2d0424SChris Cain             if (subtree.size() > 1)
20963a2d0424SChris Cain             {
20973a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
20983a2d0424SChris Cain                 // error
20993a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
21003a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
21013a2d0424SChris Cain                     << subtree.size();
21023a2d0424SChris Cain                 messages::internalError(aResp->res);
21033a2d0424SChris Cain                 return;
21043a2d0424SChris Cain             }
21053a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
21063a2d0424SChris Cain             {
21073a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
21083a2d0424SChris Cain                 messages::internalError(aResp->res);
21093a2d0424SChris Cain                 return;
21103a2d0424SChris Cain             }
21113a2d0424SChris Cain             const std::string& path = subtree[0].first;
21123a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
21133a2d0424SChris Cain             if (service.empty())
21143a2d0424SChris Cain             {
21153a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
21163a2d0424SChris Cain                 messages::internalError(aResp->res);
21173a2d0424SChris Cain                 return;
21183a2d0424SChris Cain             }
21193a2d0424SChris Cain             // Valid Power Mode object found, now read the current value
21203a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
21213a2d0424SChris Cain                 [aResp](const boost::system::error_code ec,
21223a2d0424SChris Cain                         const std::variant<std::string>& pmode) {
21233a2d0424SChris Cain                     if (ec)
21243a2d0424SChris Cain                     {
21253a2d0424SChris Cain                         BMCWEB_LOG_DEBUG
21263a2d0424SChris Cain                             << "DBUS response error on PowerMode Get: " << ec;
21273a2d0424SChris Cain                         messages::internalError(aResp->res);
21283a2d0424SChris Cain                         return;
21293a2d0424SChris Cain                     }
21303a2d0424SChris Cain 
21313a2d0424SChris Cain                     const std::string* s = std::get_if<std::string>(&pmode);
21323a2d0424SChris Cain                     if (s == nullptr)
21333a2d0424SChris Cain                     {
21343a2d0424SChris Cain                         BMCWEB_LOG_DEBUG << "Unable to get PowerMode value";
21353a2d0424SChris Cain                         messages::internalError(aResp->res);
21363a2d0424SChris Cain                         return;
21373a2d0424SChris Cain                     }
21383a2d0424SChris Cain 
21393a2d0424SChris Cain                     aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] =
21403a2d0424SChris Cain                         {"Static", "MaximumPerformance", "PowerSaving"};
21413a2d0424SChris Cain 
21423a2d0424SChris Cain                     BMCWEB_LOG_DEBUG << "Current power mode: " << *s;
21433a2d0424SChris Cain                     translatePowerMode(aResp, *s);
21443a2d0424SChris Cain                 },
21453a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Get",
21463a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode");
21473a2d0424SChris Cain         },
21483a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
21493a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
21503a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
21513a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
21523a2d0424SChris Cain }
21533a2d0424SChris Cain 
21543a2d0424SChris Cain /**
21553a2d0424SChris Cain  * @brief Validate the specified mode is valid and return the PowerMode
21563a2d0424SChris Cain  * name associated with that string
21573a2d0424SChris Cain  *
21583a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21593a2d0424SChris Cain  * @param[in] modeString  String representing the desired PowerMode
21603a2d0424SChris Cain  *
21613a2d0424SChris Cain  * @return PowerMode value or empty string if mode is not valid
21623a2d0424SChris Cain  */
21633a2d0424SChris Cain inline std::string
21643a2d0424SChris Cain     validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21653a2d0424SChris Cain                       const std::string& modeString)
21663a2d0424SChris Cain {
21673a2d0424SChris Cain     std::string mode;
21683a2d0424SChris Cain 
21693a2d0424SChris Cain     if (modeString == "Static")
21703a2d0424SChris Cain     {
21713a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
21723a2d0424SChris Cain     }
21733a2d0424SChris Cain     else if (modeString == "MaximumPerformance")
21743a2d0424SChris Cain     {
21753a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode."
21763a2d0424SChris Cain                "MaximumPerformance";
21773a2d0424SChris Cain     }
21783a2d0424SChris Cain     else if (modeString == "PowerSaving")
21793a2d0424SChris Cain     {
21803a2d0424SChris Cain         mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
21813a2d0424SChris Cain     }
21823a2d0424SChris Cain     else
21833a2d0424SChris Cain     {
21843a2d0424SChris Cain         messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
21853a2d0424SChris Cain     }
21863a2d0424SChris Cain     return mode;
21873a2d0424SChris Cain }
21883a2d0424SChris Cain 
21893a2d0424SChris Cain /**
21903a2d0424SChris Cain  * @brief Sets system power mode.
21913a2d0424SChris Cain  *
21923a2d0424SChris Cain  * @param[in] aResp   Shared pointer for generating response message.
21933a2d0424SChris Cain  * @param[in] pmode   System power mode from request.
21943a2d0424SChris Cain  *
21953a2d0424SChris Cain  * @return None.
21963a2d0424SChris Cain  */
21973a2d0424SChris Cain inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
21983a2d0424SChris Cain                          const std::string& pmode)
21993a2d0424SChris Cain {
22003a2d0424SChris Cain     BMCWEB_LOG_DEBUG << "Set power mode.";
22013a2d0424SChris Cain 
22023a2d0424SChris Cain     std::string powerMode = validatePowerMode(aResp, pmode);
22033a2d0424SChris Cain     if (powerMode.empty())
22043a2d0424SChris Cain     {
22053a2d0424SChris Cain         return;
22063a2d0424SChris Cain     }
22073a2d0424SChris Cain 
22083a2d0424SChris Cain     // Get Power Mode object path:
22093a2d0424SChris Cain     crow::connections::systemBus->async_method_call(
22103a2d0424SChris Cain         [aResp, powerMode](
22113a2d0424SChris Cain             const boost::system::error_code ec,
22123a2d0424SChris Cain             const std::vector<std::pair<
22133a2d0424SChris Cain                 std::string,
22143a2d0424SChris Cain                 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
22153a2d0424SChris Cain                 subtree) {
22163a2d0424SChris Cain             if (ec)
22173a2d0424SChris Cain             {
22183a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22193a2d0424SChris Cain                     << "DBUS response error on Power.Mode GetSubTree " << ec;
22203a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22213a2d0424SChris Cain                 messages::internalError(aResp->res);
22223a2d0424SChris Cain                 return;
22233a2d0424SChris Cain             }
22243a2d0424SChris Cain             if (subtree.empty())
22253a2d0424SChris Cain             {
22263a2d0424SChris Cain                 // This is an optional D-Bus object, but user attempted to patch
22273a2d0424SChris Cain                 messages::resourceNotFound(aResp->res, "ComputerSystem",
22283a2d0424SChris Cain                                            "PowerMode");
22293a2d0424SChris Cain                 return;
22303a2d0424SChris Cain             }
22313a2d0424SChris Cain             if (subtree.size() > 1)
22323a2d0424SChris Cain             {
22333a2d0424SChris Cain                 // More then one PowerMode object is not supported and is an
22343a2d0424SChris Cain                 // error
22353a2d0424SChris Cain                 BMCWEB_LOG_DEBUG
22363a2d0424SChris Cain                     << "Found more than 1 system D-Bus Power.Mode objects: "
22373a2d0424SChris Cain                     << subtree.size();
22383a2d0424SChris Cain                 messages::internalError(aResp->res);
22393a2d0424SChris Cain                 return;
22403a2d0424SChris Cain             }
22413a2d0424SChris Cain             if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
22423a2d0424SChris Cain             {
22433a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
22443a2d0424SChris Cain                 messages::internalError(aResp->res);
22453a2d0424SChris Cain                 return;
22463a2d0424SChris Cain             }
22473a2d0424SChris Cain             const std::string& path = subtree[0].first;
22483a2d0424SChris Cain             const std::string& service = subtree[0].second.begin()->first;
22493a2d0424SChris Cain             if (service.empty())
22503a2d0424SChris Cain             {
22513a2d0424SChris Cain                 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
22523a2d0424SChris Cain                 messages::internalError(aResp->res);
22533a2d0424SChris Cain                 return;
22543a2d0424SChris Cain             }
22553a2d0424SChris Cain 
22563a2d0424SChris Cain             BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
22573a2d0424SChris Cain                              << path;
22583a2d0424SChris Cain 
22593a2d0424SChris Cain             // Set the Power Mode property
22603a2d0424SChris Cain             crow::connections::systemBus->async_method_call(
22613a2d0424SChris Cain                 [aResp](const boost::system::error_code ec) {
22623a2d0424SChris Cain                     if (ec)
22633a2d0424SChris Cain                     {
22643a2d0424SChris Cain                         messages::internalError(aResp->res);
22653a2d0424SChris Cain                         return;
22663a2d0424SChris Cain                     }
22673a2d0424SChris Cain                 },
22683a2d0424SChris Cain                 service, path, "org.freedesktop.DBus.Properties", "Set",
22693a2d0424SChris Cain                 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
22703a2d0424SChris Cain                 std::variant<std::string>(powerMode));
22713a2d0424SChris Cain         },
22723a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper",
22733a2d0424SChris Cain         "/xyz/openbmc_project/object_mapper",
22743a2d0424SChris Cain         "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
22753a2d0424SChris Cain         std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
22763a2d0424SChris Cain }
22773a2d0424SChris Cain 
22783a2d0424SChris Cain /**
227951709ffdSYong Li  * @brief Translates watchdog timeout action DBUS property value to redfish.
228051709ffdSYong Li  *
228151709ffdSYong Li  * @param[in] dbusAction    The watchdog timeout action in D-BUS.
228251709ffdSYong Li  *
228351709ffdSYong Li  * @return Returns as a string, the timeout action in Redfish terms. If
228451709ffdSYong Li  * translation cannot be done, returns an empty string.
228551709ffdSYong Li  */
228623a21a1cSEd Tanous inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
228751709ffdSYong Li {
228851709ffdSYong Li     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
228951709ffdSYong Li     {
229051709ffdSYong Li         return "None";
229151709ffdSYong Li     }
22923174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
229351709ffdSYong Li     {
229451709ffdSYong Li         return "ResetSystem";
229551709ffdSYong Li     }
22963174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
229751709ffdSYong Li     {
229851709ffdSYong Li         return "PowerDown";
229951709ffdSYong Li     }
23003174e4dfSEd Tanous     if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
230151709ffdSYong Li     {
230251709ffdSYong Li         return "PowerCycle";
230351709ffdSYong Li     }
230451709ffdSYong Li 
230551709ffdSYong Li     return "";
230651709ffdSYong Li }
230751709ffdSYong Li 
230851709ffdSYong Li /**
2309c45f0082SYong Li  *@brief Translates timeout action from Redfish to DBUS property value.
2310c45f0082SYong Li  *
2311c45f0082SYong Li  *@param[in] rfAction The timeout action in Redfish.
2312c45f0082SYong Li  *
2313c45f0082SYong Li  *@return Returns as a string, the time_out action as expected by DBUS.
2314c45f0082SYong Li  *If translation cannot be done, returns an empty string.
2315c45f0082SYong Li  */
2316c45f0082SYong Li 
231723a21a1cSEd Tanous inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
2318c45f0082SYong Li {
2319c45f0082SYong Li     if (rfAction == "None")
2320c45f0082SYong Li     {
2321c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.None";
2322c45f0082SYong Li     }
23233174e4dfSEd Tanous     if (rfAction == "PowerCycle")
2324c45f0082SYong Li     {
2325c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2326c45f0082SYong Li     }
23273174e4dfSEd Tanous     if (rfAction == "PowerDown")
2328c45f0082SYong Li     {
2329c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2330c45f0082SYong Li     }
23313174e4dfSEd Tanous     if (rfAction == "ResetSystem")
2332c45f0082SYong Li     {
2333c45f0082SYong Li         return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2334c45f0082SYong Li     }
2335c45f0082SYong Li 
2336c45f0082SYong Li     return "";
2337c45f0082SYong Li }
2338c45f0082SYong Li 
2339c45f0082SYong Li /**
234051709ffdSYong Li  * @brief Retrieves host watchdog timer properties over DBUS
234151709ffdSYong Li  *
234251709ffdSYong Li  * @param[in] aResp     Shared pointer for completing asynchronous calls.
234351709ffdSYong Li  *
234451709ffdSYong Li  * @return None.
234551709ffdSYong Li  */
23468d1b46d7Szhanghch05 inline void
23478d1b46d7Szhanghch05     getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
234851709ffdSYong Li {
234951709ffdSYong Li     BMCWEB_LOG_DEBUG << "Get host watchodg";
235051709ffdSYong Li     crow::connections::systemBus->async_method_call(
235151709ffdSYong Li         [aResp](const boost::system::error_code ec,
235251709ffdSYong Li                 PropertiesType& properties) {
235351709ffdSYong Li             if (ec)
235451709ffdSYong Li             {
235551709ffdSYong Li                 // watchdog service is stopped
235651709ffdSYong Li                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
235751709ffdSYong Li                 return;
235851709ffdSYong Li             }
235951709ffdSYong Li 
236051709ffdSYong Li             BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
236151709ffdSYong Li 
236251709ffdSYong Li             nlohmann::json& hostWatchdogTimer =
236351709ffdSYong Li                 aResp->res.jsonValue["HostWatchdogTimer"];
236451709ffdSYong Li 
236551709ffdSYong Li             // watchdog service is running/enabled
236651709ffdSYong Li             hostWatchdogTimer["Status"]["State"] = "Enabled";
236751709ffdSYong Li 
236851709ffdSYong Li             for (const auto& property : properties)
236951709ffdSYong Li             {
237051709ffdSYong Li                 BMCWEB_LOG_DEBUG << "prop=" << property.first;
237151709ffdSYong Li                 if (property.first == "Enabled")
237251709ffdSYong Li                 {
237351709ffdSYong Li                     const bool* state = std::get_if<bool>(&property.second);
237451709ffdSYong Li 
237551709ffdSYong Li                     if (!state)
237651709ffdSYong Li                     {
237751709ffdSYong Li                         messages::internalError(aResp->res);
2378601af5edSChicago Duan                         return;
237951709ffdSYong Li                     }
238051709ffdSYong Li 
238151709ffdSYong Li                     hostWatchdogTimer["FunctionEnabled"] = *state;
238251709ffdSYong Li                 }
238351709ffdSYong Li                 else if (property.first == "ExpireAction")
238451709ffdSYong Li                 {
238551709ffdSYong Li                     const std::string* s =
238651709ffdSYong Li                         std::get_if<std::string>(&property.second);
238751709ffdSYong Li                     if (!s)
238851709ffdSYong Li                     {
238951709ffdSYong Li                         messages::internalError(aResp->res);
2390601af5edSChicago Duan                         return;
239151709ffdSYong Li                     }
239251709ffdSYong Li 
239351709ffdSYong Li                     std::string action = dbusToRfWatchdogAction(*s);
239451709ffdSYong Li                     if (action.empty())
239551709ffdSYong Li                     {
239651709ffdSYong Li                         messages::internalError(aResp->res);
2397601af5edSChicago Duan                         return;
239851709ffdSYong Li                     }
239951709ffdSYong Li                     hostWatchdogTimer["TimeoutAction"] = action;
240051709ffdSYong Li                 }
240151709ffdSYong Li             }
240251709ffdSYong Li         },
240351709ffdSYong Li         "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
240451709ffdSYong Li         "org.freedesktop.DBus.Properties", "GetAll",
240551709ffdSYong Li         "xyz.openbmc_project.State.Watchdog");
240651709ffdSYong Li }
240751709ffdSYong Li 
240851709ffdSYong Li /**
2409c45f0082SYong Li  * @brief Sets Host WatchDog Timer properties.
2410c45f0082SYong Li  *
2411c45f0082SYong Li  * @param[in] aResp      Shared pointer for generating response message.
2412c45f0082SYong Li  * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
2413c45f0082SYong Li  *                       RF request.
2414c45f0082SYong Li  * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2415c45f0082SYong Li  *
2416c45f0082SYong Li  * @return None.
2417c45f0082SYong Li  */
24188d1b46d7Szhanghch05 inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2419c45f0082SYong Li                              const std::optional<bool> wdtEnable,
2420c45f0082SYong Li                              const std::optional<std::string>& wdtTimeOutAction)
2421c45f0082SYong Li {
2422c45f0082SYong Li     BMCWEB_LOG_DEBUG << "Set host watchdog";
2423c45f0082SYong Li 
2424c45f0082SYong Li     if (wdtTimeOutAction)
2425c45f0082SYong Li     {
2426c45f0082SYong Li         std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2427c45f0082SYong Li         // check if TimeOut Action is Valid
2428c45f0082SYong Li         if (wdtTimeOutActStr.empty())
2429c45f0082SYong Li         {
2430c45f0082SYong Li             BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2431c45f0082SYong Li                              << *wdtTimeOutAction;
2432c45f0082SYong Li             messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2433c45f0082SYong Li                                              "TimeoutAction");
2434c45f0082SYong Li             return;
2435c45f0082SYong Li         }
2436c45f0082SYong Li 
2437c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2438c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2439c45f0082SYong Li                 if (ec)
2440c45f0082SYong Li                 {
2441c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2442c45f0082SYong Li                     messages::internalError(aResp->res);
2443c45f0082SYong Li                     return;
2444c45f0082SYong Li                 }
2445c45f0082SYong Li             },
2446c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2447c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2448c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2449c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "ExpireAction",
2450c45f0082SYong Li             std::variant<std::string>(wdtTimeOutActStr));
2451c45f0082SYong Li     }
2452c45f0082SYong Li 
2453c45f0082SYong Li     if (wdtEnable)
2454c45f0082SYong Li     {
2455c45f0082SYong Li         crow::connections::systemBus->async_method_call(
2456c45f0082SYong Li             [aResp](const boost::system::error_code ec) {
2457c45f0082SYong Li                 if (ec)
2458c45f0082SYong Li                 {
2459c45f0082SYong Li                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2460c45f0082SYong Li                     messages::internalError(aResp->res);
2461c45f0082SYong Li                     return;
2462c45f0082SYong Li                 }
2463c45f0082SYong Li             },
2464c45f0082SYong Li             "xyz.openbmc_project.Watchdog",
2465c45f0082SYong Li             "/xyz/openbmc_project/watchdog/host0",
2466c45f0082SYong Li             "org.freedesktop.DBus.Properties", "Set",
2467c45f0082SYong Li             "xyz.openbmc_project.State.Watchdog", "Enabled",
2468c45f0082SYong Li             std::variant<bool>(*wdtEnable));
2469c45f0082SYong Li     }
2470c45f0082SYong Li }
2471c45f0082SYong Li 
2472c45f0082SYong Li /**
2473c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
2474c5b2abe0SLewanczyk, Dawid  * Schema
2475c5b2abe0SLewanczyk, Dawid  */
24767e860f15SJohn Edward Broadbent inline void requestRoutesSystemsCollection(App& app)
24771abe55efSEd Tanous {
24787e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
2479ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystemCollection)
24807e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
24814f48d5f6SEd Tanous             [](const crow::Request& /*req*/,
24827e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
24838d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
24840f74e643SEd Tanous                     "#ComputerSystemCollection.ComputerSystemCollection";
24858d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
24868d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2487462023adSSunitha Harish 
2488462023adSSunitha Harish                 crow::connections::systemBus->async_method_call(
24894f48d5f6SEd Tanous                     [asyncResp](const boost::system::error_code ec,
2490cb13a392SEd Tanous                                 const std::variant<std::string>& /*hostName*/) {
24912c70f800SEd Tanous                         nlohmann::json& ifaceArray =
2492462023adSSunitha Harish                             asyncResp->res.jsonValue["Members"];
24932c70f800SEd Tanous                         ifaceArray = nlohmann::json::array();
24947e860f15SJohn Edward Broadbent                         auto& count =
24957e860f15SJohn Edward Broadbent                             asyncResp->res.jsonValue["Members@odata.count"];
24962c70f800SEd Tanous                         ifaceArray.push_back(
2497cb13a392SEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/system"}});
249894bda602STim Lee                         count = ifaceArray.size();
2499cb13a392SEd Tanous                         if (!ec)
2500462023adSSunitha Harish                         {
2501462023adSSunitha Harish                             BMCWEB_LOG_DEBUG << "Hypervisor is available";
25022c70f800SEd Tanous                             ifaceArray.push_back(
25037e860f15SJohn Edward Broadbent                                 {{"@odata.id",
25047e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/hypervisor"}});
25052c70f800SEd Tanous                             count = ifaceArray.size();
2506cb13a392SEd Tanous                         }
2507462023adSSunitha Harish                     },
25088e651fbfSSunitha Harish                     "xyz.openbmc_project.Settings",
25098e651fbfSSunitha Harish                     "/xyz/openbmc_project/network/hypervisor",
2510462023adSSunitha Harish                     "org.freedesktop.DBus.Properties", "Get",
25117e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.Network.SystemConfiguration",
25127e860f15SJohn Edward Broadbent                     "HostName");
25137e860f15SJohn Edward Broadbent             });
2514c5b2abe0SLewanczyk, Dawid }
25157e860f15SJohn Edward Broadbent 
25167e860f15SJohn Edward Broadbent /**
25177e860f15SJohn Edward Broadbent  * Function transceives data with dbus directly.
25187e860f15SJohn Edward Broadbent  */
25194f48d5f6SEd Tanous inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
25207e860f15SJohn Edward Broadbent {
25217e860f15SJohn Edward Broadbent     constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
25227e860f15SJohn Edward Broadbent     constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
25237e860f15SJohn Edward Broadbent     constexpr char const* interfaceName =
25247e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Control.Host.NMI";
25257e860f15SJohn Edward Broadbent     constexpr char const* method = "NMI";
25267e860f15SJohn Edward Broadbent 
25277e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
25287e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code ec) {
25297e860f15SJohn Edward Broadbent             if (ec)
25307e860f15SJohn Edward Broadbent             {
25317e860f15SJohn Edward Broadbent                 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
25327e860f15SJohn Edward Broadbent                 messages::internalError(asyncResp->res);
25337e860f15SJohn Edward Broadbent                 return;
25347e860f15SJohn Edward Broadbent             }
25357e860f15SJohn Edward Broadbent             messages::success(asyncResp->res);
25367e860f15SJohn Edward Broadbent         },
25377e860f15SJohn Edward Broadbent         serviceName, objectPath, interfaceName, method);
25387e860f15SJohn Edward Broadbent }
2539c5b2abe0SLewanczyk, Dawid 
2540c5b2abe0SLewanczyk, Dawid /**
2541cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
2542cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
2543cc340dd9SEd Tanous  */
25447e860f15SJohn Edward Broadbent inline void requestRoutesSystemActionsReset(App& app)
2545cc340dd9SEd Tanous {
2546cc340dd9SEd Tanous     /**
2547cc340dd9SEd Tanous      * Function handles POST method request.
2548cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
2549cc340dd9SEd Tanous      */
25507e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
25517e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
2552ed398213SEd Tanous         .privileges(redfish::privileges::postComputerSystem)
25537e860f15SJohn Edward Broadbent         .methods(
25547e860f15SJohn Edward Broadbent             boost::beast::http::verb::
25557e860f15SJohn Edward Broadbent                 post)([](const crow::Request& req,
25567e860f15SJohn Edward Broadbent                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
25579712f8acSEd Tanous             std::string resetType;
25587e860f15SJohn Edward Broadbent             if (!json_util::readJson(req, asyncResp->res, "ResetType",
25597e860f15SJohn Edward Broadbent                                      resetType))
2560cc340dd9SEd Tanous             {
2561cc340dd9SEd Tanous                 return;
2562cc340dd9SEd Tanous             }
2563cc340dd9SEd Tanous 
2564d22c8396SJason M. Bills             // Get the command and host vs. chassis
2565cc340dd9SEd Tanous             std::string command;
2566d22c8396SJason M. Bills             bool hostCommand;
2567d4d25793SEd Tanous             if ((resetType == "On") || (resetType == "ForceOn"))
2568cc340dd9SEd Tanous             {
2569cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.On";
2570d22c8396SJason M. Bills                 hostCommand = true;
2571d22c8396SJason M. Bills             }
2572d22c8396SJason M. Bills             else if (resetType == "ForceOff")
2573d22c8396SJason M. Bills             {
2574d22c8396SJason M. Bills                 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2575d22c8396SJason M. Bills                 hostCommand = false;
2576d22c8396SJason M. Bills             }
2577d22c8396SJason M. Bills             else if (resetType == "ForceRestart")
2578d22c8396SJason M. Bills             {
257986a0851aSJason M. Bills                 command =
258086a0851aSJason M. Bills                     "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
258186a0851aSJason M. Bills                 hostCommand = true;
2582cc340dd9SEd Tanous             }
25839712f8acSEd Tanous             else if (resetType == "GracefulShutdown")
2584cc340dd9SEd Tanous             {
2585cc340dd9SEd Tanous                 command = "xyz.openbmc_project.State.Host.Transition.Off";
2586d22c8396SJason M. Bills                 hostCommand = true;
2587cc340dd9SEd Tanous             }
25889712f8acSEd Tanous             else if (resetType == "GracefulRestart")
2589cc340dd9SEd Tanous             {
25907e860f15SJohn Edward Broadbent                 command = "xyz.openbmc_project.State.Host.Transition."
25917e860f15SJohn Edward Broadbent                           "GracefulWarmReboot";
2592d22c8396SJason M. Bills                 hostCommand = true;
2593d22c8396SJason M. Bills             }
2594d22c8396SJason M. Bills             else if (resetType == "PowerCycle")
2595d22c8396SJason M. Bills             {
259686a0851aSJason M. Bills                 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
259786a0851aSJason M. Bills                 hostCommand = true;
2598cc340dd9SEd Tanous             }
2599bfd5b826SLakshminarayana R. Kammath             else if (resetType == "Nmi")
2600bfd5b826SLakshminarayana R. Kammath             {
2601bfd5b826SLakshminarayana R. Kammath                 doNMI(asyncResp);
2602bfd5b826SLakshminarayana R. Kammath                 return;
2603bfd5b826SLakshminarayana R. Kammath             }
2604cc340dd9SEd Tanous             else
2605cc340dd9SEd Tanous             {
26068d1b46d7Szhanghch05                 messages::actionParameterUnknown(asyncResp->res, "Reset",
26078d1b46d7Szhanghch05                                                  resetType);
2608cc340dd9SEd Tanous                 return;
2609cc340dd9SEd Tanous             }
2610cc340dd9SEd Tanous 
2611d22c8396SJason M. Bills             if (hostCommand)
2612d22c8396SJason M. Bills             {
2613cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
2614d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2615cc340dd9SEd Tanous                         if (ec)
2616cc340dd9SEd Tanous                         {
2617cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
26187e860f15SJohn Edward Broadbent                             if (ec.value() ==
26197e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2620d22c8396SJason M. Bills                             {
2621d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2622d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2623d22c8396SJason M. Bills                             }
2624d22c8396SJason M. Bills                             else
2625d22c8396SJason M. Bills                             {
2626f12894f8SJason M. Bills                                 messages::internalError(asyncResp->res);
2627d22c8396SJason M. Bills                             }
2628cc340dd9SEd Tanous                             return;
2629cc340dd9SEd Tanous                         }
2630f12894f8SJason M. Bills                         messages::success(asyncResp->res);
2631cc340dd9SEd Tanous                     },
2632cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
2633cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
2634cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
26359712f8acSEd Tanous                     "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2636abf2add6SEd Tanous                     std::variant<std::string>{command});
2637cc340dd9SEd Tanous             }
2638d22c8396SJason M. Bills             else
2639d22c8396SJason M. Bills             {
2640d22c8396SJason M. Bills                 crow::connections::systemBus->async_method_call(
2641d22c8396SJason M. Bills                     [asyncResp, resetType](const boost::system::error_code ec) {
2642d22c8396SJason M. Bills                         if (ec)
2643d22c8396SJason M. Bills                         {
2644d22c8396SJason M. Bills                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
26457e860f15SJohn Edward Broadbent                             if (ec.value() ==
26467e860f15SJohn Edward Broadbent                                 boost::asio::error::invalid_argument)
2647d22c8396SJason M. Bills                             {
2648d22c8396SJason M. Bills                                 messages::actionParameterNotSupported(
2649d22c8396SJason M. Bills                                     asyncResp->res, resetType, "Reset");
2650d22c8396SJason M. Bills                             }
2651d22c8396SJason M. Bills                             else
2652d22c8396SJason M. Bills                             {
2653d22c8396SJason M. Bills                                 messages::internalError(asyncResp->res);
2654d22c8396SJason M. Bills                             }
2655d22c8396SJason M. Bills                             return;
2656d22c8396SJason M. Bills                         }
2657d22c8396SJason M. Bills                         messages::success(asyncResp->res);
2658d22c8396SJason M. Bills                     },
2659d22c8396SJason M. Bills                     "xyz.openbmc_project.State.Chassis",
2660d22c8396SJason M. Bills                     "/xyz/openbmc_project/state/chassis0",
2661d22c8396SJason M. Bills                     "org.freedesktop.DBus.Properties", "Set",
26627e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.State.Chassis",
26637e860f15SJohn Edward Broadbent                     "RequestedPowerTransition",
2664d22c8396SJason M. Bills                     std::variant<std::string>{command});
2665d22c8396SJason M. Bills             }
26667e860f15SJohn Edward Broadbent         });
2667d22c8396SJason M. Bills }
2668cc340dd9SEd Tanous 
2669cc340dd9SEd Tanous /**
26706617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
2671c5b2abe0SLewanczyk, Dawid  */
26727e860f15SJohn Edward Broadbent inline void requestRoutesSystems(App& app)
26731abe55efSEd Tanous {
2674c5b2abe0SLewanczyk, Dawid 
2675c5b2abe0SLewanczyk, Dawid     /**
2676c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
2677c5b2abe0SLewanczyk, Dawid      */
26787e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2679ed398213SEd Tanous         .privileges(redfish::privileges::getComputerSystem)
26807e860f15SJohn Edward Broadbent         .methods(
26817e860f15SJohn Edward Broadbent             boost::beast::http::verb::
26827e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
26837e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
26848d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] =
26853a2d0424SChris Cain                 "#ComputerSystem.v1_15_0.ComputerSystem";
26868d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "system";
26878d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "system";
26888d1b46d7Szhanghch05             asyncResp->res.jsonValue["SystemType"] = "Physical";
26898d1b46d7Szhanghch05             asyncResp->res.jsonValue["Description"] = "Computer System";
26908d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
26918d1b46d7Szhanghch05             asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
26928d1b46d7Szhanghch05                 "Disabled";
26938d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
26948d1b46d7Szhanghch05                 uint64_t(0);
26958d1b46d7Szhanghch05             asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
26968d1b46d7Szhanghch05                 "Disabled";
26977e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue["@odata.id"] =
26987e860f15SJohn Edward Broadbent                 "/redfish/v1/Systems/system";
269904a258f4SEd Tanous 
27008d1b46d7Szhanghch05             asyncResp->res.jsonValue["Processors"] = {
2701029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
27028d1b46d7Szhanghch05             asyncResp->res.jsonValue["Memory"] = {
2703029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
27048d1b46d7Szhanghch05             asyncResp->res.jsonValue["Storage"] = {
2705a25aeccfSNikhil Potade                 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
2706029573d4SEd Tanous 
27078d1b46d7Szhanghch05             asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
2708cc340dd9SEd Tanous                 {"target",
2709029573d4SEd Tanous                  "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
27101cb1a9e6SAppaRao Puli                 {"@Redfish.ActionInfo",
27111cb1a9e6SAppaRao Puli                  "/redfish/v1/Systems/system/ResetActionInfo"}};
2712c5b2abe0SLewanczyk, Dawid 
27138d1b46d7Szhanghch05             asyncResp->res.jsonValue["LogServices"] = {
2714029573d4SEd Tanous                 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
2715c4bf6374SJason M. Bills 
27168d1b46d7Szhanghch05             asyncResp->res.jsonValue["Bios"] = {
2717d82a3acdSCarol Wang                 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
2718d82a3acdSCarol Wang 
27198d1b46d7Szhanghch05             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
2720c5d03ff4SJennifer Lee                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
2721c5d03ff4SJennifer Lee 
27228d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"] = {
2723c5d03ff4SJennifer Lee                 {"Health", "OK"},
2724c5d03ff4SJennifer Lee                 {"State", "Enabled"},
2725c5d03ff4SJennifer Lee             };
27260e8ac5e7SGunnar Mills 
27270e8ac5e7SGunnar Mills             // Fill in SerialConsole info
27280e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
27290e8ac5e7SGunnar Mills                 15;
27300e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["IPMI"] = {
27310e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27320e8ac5e7SGunnar Mills             };
27330e8ac5e7SGunnar Mills             // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
27340e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["SerialConsole"]["SSH"] = {
27350e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27360e8ac5e7SGunnar Mills                 {"Port", 2200},
27370e8ac5e7SGunnar Mills                 // https://github.com/openbmc/docs/blob/master/console.md
27380e8ac5e7SGunnar Mills                 {"HotKeySequenceDisplay", "Press ~. to exit console"},
27390e8ac5e7SGunnar Mills             };
27400e8ac5e7SGunnar Mills 
27410e8ac5e7SGunnar Mills #ifdef BMCWEB_ENABLE_KVM
27420e8ac5e7SGunnar Mills             // Fill in GraphicalConsole info
27430e8ac5e7SGunnar Mills             asyncResp->res.jsonValue["GraphicalConsole"] = {
27440e8ac5e7SGunnar Mills                 {"ServiceEnabled", true},
27450e8ac5e7SGunnar Mills                 {"MaxConcurrentSessions", 4},
27460e8ac5e7SGunnar Mills                 {"ConnectTypesSupported", {"KVMIP"}},
27470e8ac5e7SGunnar Mills             };
27480e8ac5e7SGunnar Mills #endif // BMCWEB_ENABLE_KVM
2749e284a7c1SJames Feist             constexpr const std::array<const char*, 4> inventoryForSystems = {
2750b49ac873SJames Feist                 "xyz.openbmc_project.Inventory.Item.Dimm",
27512ad9c2f6SJames Feist                 "xyz.openbmc_project.Inventory.Item.Cpu",
2752e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.Drive",
2753e284a7c1SJames Feist                 "xyz.openbmc_project.Inventory.Item.StorageController"};
2754b49ac873SJames Feist 
2755b49ac873SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
2756b49ac873SJames Feist             crow::connections::systemBus->async_method_call(
2757b49ac873SJames Feist                 [health](const boost::system::error_code ec,
2758b49ac873SJames Feist                          std::vector<std::string>& resp) {
2759b49ac873SJames Feist                     if (ec)
2760b49ac873SJames Feist                     {
2761b49ac873SJames Feist                         // no inventory
2762b49ac873SJames Feist                         return;
2763b49ac873SJames Feist                     }
2764b49ac873SJames Feist 
2765b49ac873SJames Feist                     health->inventory = std::move(resp);
2766b49ac873SJames Feist                 },
2767b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper",
2768b49ac873SJames Feist                 "/xyz/openbmc_project/object_mapper",
2769b49ac873SJames Feist                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
2770b49ac873SJames Feist                 int32_t(0), inventoryForSystems);
2771b49ac873SJames Feist 
2772b49ac873SJames Feist             health->populate();
2773b49ac873SJames Feist 
27748d1b46d7Szhanghch05             getMainChassisId(
27758d1b46d7Szhanghch05                 asyncResp, [](const std::string& chassisId,
27768d1b46d7Szhanghch05                               const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2777c5d03ff4SJennifer Lee                     aRsp->res.jsonValue["Links"]["Chassis"] = {
2778c5d03ff4SJennifer Lee                         {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
2779c5d03ff4SJennifer Lee                 });
2780a3002228SAppaRao Puli 
27819f8bfa7cSGunnar Mills             getLocationIndicatorActive(asyncResp);
27829f8bfa7cSGunnar Mills             // TODO (Gunnar): Remove IndicatorLED after enough time has passed
2783a3002228SAppaRao Puli             getIndicatorLedState(asyncResp);
27845bc2dc8eSJames Feist             getComputerSystem(asyncResp, health);
27856c34de48SEd Tanous             getHostState(asyncResp);
2786491d8ee7SSantosh Puranik             getBootProperties(asyncResp);
2787978b8803SAndrew Geissler             getBootProgress(asyncResp);
2788adbe192aSJason M. Bills             getPCIeDeviceList(asyncResp, "PCIeDevices");
278951709ffdSYong Li             getHostWatchdogTimer(asyncResp);
2790c6a620f2SGeorge Liu             getPowerRestorePolicy(asyncResp);
27916bd5a8d2SGunnar Mills             getAutomaticRetry(asyncResp);
2792c0557e1aSGunnar Mills             getLastResetTime(asyncResp);
2793a6349918SAppaRao Puli #ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2794a6349918SAppaRao Puli             getProvisioningStatus(asyncResp);
2795a6349918SAppaRao Puli #endif
27961981771bSAli Ahmed             getTrustedModuleRequiredToBoot(asyncResp);
27973a2d0424SChris Cain             getPowerMode(asyncResp);
27987e860f15SJohn Edward Broadbent         });
27997e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2800ed398213SEd Tanous         .privileges(redfish::privileges::patchComputerSystem)
28017e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
28027e860f15SJohn Edward Broadbent             [](const crow::Request& req,
28037e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
28049f8bfa7cSGunnar Mills                 std::optional<bool> locationIndicatorActive;
2805cde19e5fSSantosh Puranik                 std::optional<std::string> indicatorLed;
2806491d8ee7SSantosh Puranik                 std::optional<nlohmann::json> bootProps;
2807c45f0082SYong Li                 std::optional<nlohmann::json> wdtTimerProps;
280898e386ecSGunnar Mills                 std::optional<std::string> assetTag;
2809c6a620f2SGeorge Liu                 std::optional<std::string> powerRestorePolicy;
28103a2d0424SChris Cain                 std::optional<std::string> powerMode;
28119f8bfa7cSGunnar Mills                 if (!json_util::readJson(
28128d1b46d7Szhanghch05                         req, asyncResp->res, "IndicatorLED", indicatorLed,
28137e860f15SJohn Edward Broadbent                         "LocationIndicatorActive", locationIndicatorActive,
28147e860f15SJohn Edward Broadbent                         "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
28157e860f15SJohn Edward Broadbent                         "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
2816ac7e1e0bSAli Ahmed                         assetTag, "PowerMode", powerMode))
28176617338dSEd Tanous                 {
28186617338dSEd Tanous                     return;
28196617338dSEd Tanous                 }
2820491d8ee7SSantosh Puranik 
28218d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
2822c45f0082SYong Li 
282398e386ecSGunnar Mills                 if (assetTag)
282498e386ecSGunnar Mills                 {
282598e386ecSGunnar Mills                     setAssetTag(asyncResp, *assetTag);
282698e386ecSGunnar Mills                 }
282798e386ecSGunnar Mills 
2828c45f0082SYong Li                 if (wdtTimerProps)
2829c45f0082SYong Li                 {
2830c45f0082SYong Li                     std::optional<bool> wdtEnable;
2831c45f0082SYong Li                     std::optional<std::string> wdtTimeOutAction;
2832c45f0082SYong Li 
2833c45f0082SYong Li                     if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
2834c45f0082SYong Li                                              "FunctionEnabled", wdtEnable,
2835c45f0082SYong Li                                              "TimeoutAction", wdtTimeOutAction))
2836c45f0082SYong Li                     {
2837c45f0082SYong Li                         return;
2838c45f0082SYong Li                     }
2839f23b7296SEd Tanous                     setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
2840c45f0082SYong Li                 }
2841c45f0082SYong Li 
2842491d8ee7SSantosh Puranik                 if (bootProps)
2843491d8ee7SSantosh Puranik                 {
2844491d8ee7SSantosh Puranik                     std::optional<std::string> bootSource;
2845cd9a4666SKonstantin Aladyshev                     std::optional<std::string> bootType;
2846491d8ee7SSantosh Puranik                     std::optional<std::string> bootEnable;
284769f35306SGunnar Mills                     std::optional<std::string> automaticRetryConfig;
2848ac7e1e0bSAli Ahmed                     std::optional<bool> trustedModuleRequiredToBoot;
2849491d8ee7SSantosh Puranik 
285069f35306SGunnar Mills                     if (!json_util::readJson(
28517e860f15SJohn Edward Broadbent                             *bootProps, asyncResp->res,
28527e860f15SJohn Edward Broadbent                             "BootSourceOverrideTarget", bootSource,
2853cd9a4666SKonstantin Aladyshev                             "BootSourceOverrideMode", bootType,
28547e860f15SJohn Edward Broadbent                             "BootSourceOverrideEnabled", bootEnable,
2855ac7e1e0bSAli Ahmed                             "AutomaticRetryConfig", automaticRetryConfig,
2856ac7e1e0bSAli Ahmed                             "TrustedModuleRequiredToBoot",
2857ac7e1e0bSAli Ahmed                             trustedModuleRequiredToBoot))
2858491d8ee7SSantosh Puranik                     {
2859491d8ee7SSantosh Puranik                         return;
2860491d8ee7SSantosh Puranik                     }
2861c21865c4SKonstantin Aladyshev 
2862cd9a4666SKonstantin Aladyshev                     if (bootSource || bootType || bootEnable)
286369f35306SGunnar Mills                     {
2864c21865c4SKonstantin Aladyshev                         setBootProperties(asyncResp, bootSource, bootType,
2865c21865c4SKonstantin Aladyshev                                           bootEnable);
2866491d8ee7SSantosh Puranik                     }
286769f35306SGunnar Mills                     if (automaticRetryConfig)
286869f35306SGunnar Mills                     {
2869f23b7296SEd Tanous                         setAutomaticRetry(asyncResp, *automaticRetryConfig);
287069f35306SGunnar Mills                     }
2871ac7e1e0bSAli Ahmed 
2872ac7e1e0bSAli Ahmed                     if (trustedModuleRequiredToBoot)
2873ac7e1e0bSAli Ahmed                     {
2874ac7e1e0bSAli Ahmed                         setTrustedModuleRequiredToBoot(
2875ac7e1e0bSAli Ahmed                             asyncResp, *trustedModuleRequiredToBoot);
2876ac7e1e0bSAli Ahmed                     }
287769f35306SGunnar Mills                 }
2878265c1602SJohnathan Mantey 
28799f8bfa7cSGunnar Mills                 if (locationIndicatorActive)
28809f8bfa7cSGunnar Mills                 {
28817e860f15SJohn Edward Broadbent                     setLocationIndicatorActive(asyncResp,
28827e860f15SJohn Edward Broadbent                                                *locationIndicatorActive);
28839f8bfa7cSGunnar Mills                 }
28849f8bfa7cSGunnar Mills 
28857e860f15SJohn Edward Broadbent                 // TODO (Gunnar): Remove IndicatorLED after enough time has
28867e860f15SJohn Edward Broadbent                 // passed
28879712f8acSEd Tanous                 if (indicatorLed)
28886617338dSEd Tanous                 {
2889f23b7296SEd Tanous                     setIndicatorLedState(asyncResp, *indicatorLed);
28907e860f15SJohn Edward Broadbent                     asyncResp->res.addHeader(
28917e860f15SJohn Edward Broadbent                         boost::beast::http::field::warning,
2892d6aa0093SGunnar Mills                         "299 - \"IndicatorLED is deprecated. Use "
2893d6aa0093SGunnar Mills                         "LocationIndicatorActive instead.\"");
28946617338dSEd Tanous                 }
2895c6a620f2SGeorge Liu 
2896c6a620f2SGeorge Liu                 if (powerRestorePolicy)
2897c6a620f2SGeorge Liu                 {
28984e69c904SGunnar Mills                     setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
2899c6a620f2SGeorge Liu                 }
29003a2d0424SChris Cain 
29013a2d0424SChris Cain                 if (powerMode)
29023a2d0424SChris Cain                 {
29033a2d0424SChris Cain                     setPowerMode(asyncResp, *powerMode);
29043a2d0424SChris Cain                 }
29057e860f15SJohn Edward Broadbent             });
2906c5b2abe0SLewanczyk, Dawid }
29071cb1a9e6SAppaRao Puli 
29081cb1a9e6SAppaRao Puli /**
29091cb1a9e6SAppaRao Puli  * SystemResetActionInfo derived class for delivering Computer Systems
29101cb1a9e6SAppaRao Puli  * ResetType AllowableValues using ResetInfo schema.
29111cb1a9e6SAppaRao Puli  */
29127e860f15SJohn Edward Broadbent inline void requestRoutesSystemResetActionInfo(App& app)
29131cb1a9e6SAppaRao Puli {
29141cb1a9e6SAppaRao Puli 
29151cb1a9e6SAppaRao Puli     /**
29161cb1a9e6SAppaRao Puli      * Functions triggers appropriate requests on DBus
29171cb1a9e6SAppaRao Puli      */
29187e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
2919ed398213SEd Tanous         .privileges(redfish::privileges::getActionInfo)
29207e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
29217e860f15SJohn Edward Broadbent             [](const crow::Request&,
29227e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
29238d1b46d7Szhanghch05                 asyncResp->res.jsonValue = {
29241cb1a9e6SAppaRao Puli                     {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
29251cb1a9e6SAppaRao Puli                     {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
29261cb1a9e6SAppaRao Puli                     {"Name", "Reset Action Info"},
29271cb1a9e6SAppaRao Puli                     {"Id", "ResetActionInfo"},
29281cb1a9e6SAppaRao Puli                     {"Parameters",
29291cb1a9e6SAppaRao Puli                      {{{"Name", "ResetType"},
29301cb1a9e6SAppaRao Puli                        {"Required", true},
29311cb1a9e6SAppaRao Puli                        {"DataType", "String"},
29321cb1a9e6SAppaRao Puli                        {"AllowableValues",
29337e860f15SJohn Edward Broadbent                         {"On", "ForceOff", "ForceOn", "ForceRestart",
29347e860f15SJohn Edward Broadbent                          "GracefulRestart", "GracefulShutdown", "PowerCycle",
29357e860f15SJohn Edward Broadbent                          "Nmi"}}}}}};
29367e860f15SJohn Edward Broadbent             });
29371cb1a9e6SAppaRao Puli }
2938c5b2abe0SLewanczyk, Dawid } // namespace redfish
2939