blob: 399989848b009d29474daf36789a566b35255dc3 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070023#include "generated/enums/computer_system.hpp"
James Feistb49ac872019-05-21 15:12:01 -070024#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060025#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080026#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070027#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080028#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080029#include "registries/privilege_registry.hpp"
30#include "utils/dbus_utils.hpp"
31#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050032#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080033#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070034#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080035
Andrew Geisslerfc903b32023-05-31 14:15:42 -040036#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070037#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080038#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070039#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070040#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040041#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020042#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050043
George Liu7a1dbc42022-12-07 16:03:22 +080044#include <array>
45#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080046#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020047
Ed Tanous1abe55e2018-09-05 08:30:59 -070048namespace redfish
49{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020050
Abhishek Patel5c3e9272021-06-24 10:11:33 -050051const static std::array<std::pair<std::string_view, std::string_view>, 2>
52 protocolToDBusForSystems{
53 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
54
Alpana Kumari9d3ae102019-04-12 06:49:32 -050055/**
56 * @brief Updates the Functional State of DIMMs
57 *
Ed Tanousac106bf2023-06-07 09:24:59 -070058 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059 * @param[in] dimmState Dimm's Functional state, true/false
60 *
61 * @return None.
62 */
zhanghch058d1b46d2021-04-01 11:18:24 +080063inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070064 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070065 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050066{
Ed Tanous62598e32023-07-17 17:06:25 -070067 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050068
Gunnar Mills4e0453b2020-07-08 14:00:30 -050069 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050070 // Update STATE only if previous State was DISABLED and current Dimm is
71 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070072 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070073 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050074 if (prevMemSummary == "Disabled")
75 {
Ed Tanouse05aec52022-01-25 10:28:56 -080076 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050077 {
Ed Tanousac106bf2023-06-07 09:24:59 -070078 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050079 "Enabled";
80 }
81 }
82}
83
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085 * @brief Update "ProcessorSummary" "Status" "State" based on
86 * CPU Functional State
87 *
Ed Tanousac106bf2023-06-07 09:24:59 -070088 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089 * @param[in] cpuFunctionalState is CPU functional true/false
90 *
91 * @return None.
92 */
Ed Tanousac106bf2023-06-07 09:24:59 -070093inline void modifyCpuFunctionalState(
94 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050095{
Ed Tanous62598e32023-07-17 17:06:25 -070096 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050097
Ed Tanous02cad962022-06-30 16:50:15 -070098 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -070099 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500101 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500102 // Update STATE only if previous State was Non_Functional and current CPU is
103 // Functional.
104 if (prevProcState == "Disabled")
105 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800106 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500107 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700108 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500109 "Enabled";
110 }
111 }
112}
113
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500114/*
115 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
116 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700117 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500118 * @param[in] cpuPresenceState CPU present or not
119 *
120 * @return None.
121 */
122inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500124 bool isCpuPresent)
125{
Ed Tanous62598e32023-07-17 17:06:25 -0700126 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500127
128 if (isCpuPresent)
129 {
130 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700131 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132 auto* procCountPtr =
133 procCount.get_ptr<nlohmann::json::number_integer_t*>();
134 if (procCountPtr != nullptr)
135 {
136 // shouldn't be possible to be nullptr
137 *procCountPtr += 1;
138 }
139 }
140}
141
Ali Ahmed382d6472021-09-03 16:53:53 -0500142inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700143 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500144 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
145 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500146{
Ed Tanous62598e32023-07-17 17:06:25 -0700147 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500148
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200149 // TODO: Get Model
150
151 const uint16_t* coreCount = nullptr;
152
153 const bool success = sdbusplus::unpackPropertiesNoThrow(
154 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
155
156 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500157 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700158 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200159 return;
160 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500161
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200162 if (coreCount != nullptr)
163 {
164 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700165 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200166 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500167
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200168 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500169 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200170 coreCountJson = *coreCount;
171 }
172 else
173 {
174 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500175 }
176 }
177}
178
179/*
180 * @brief Get ProcessorSummary fields
181 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700182 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500183 * @param[in] service dbus service for Cpu Information
184 * @param[in] path dbus path for Cpu
185 *
186 * @return None.
187 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700188inline void
189 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
190 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500191{
Ed Tanousac106bf2023-06-07 09:24:59 -0700192 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
193 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500194 if (ec3)
195 {
Ed Tanous62598e32023-07-17 17:06:25 -0700196 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500197 return;
198 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700199 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500200 };
201
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500202 // Get the Presence of CPU
203 sdbusplus::asio::getProperty<bool>(
204 *crow::connections::systemBus, service, path,
205 "xyz.openbmc_project.Inventory.Item", "Present",
206 std::move(getCpuPresenceState));
207
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500208 if constexpr (bmcwebEnableProcMemStatus)
209 {
210 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700211 [asyncResp](const boost::system::error_code& ec3,
212 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500213 if (ec3)
214 {
Ed Tanous62598e32023-07-17 17:06:25 -0700215 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500216 return;
217 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700218 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500219 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500220
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500221 // Get the Functional State
222 sdbusplus::asio::getProperty<bool>(
223 *crow::connections::systemBus, service, path,
224 "xyz.openbmc_project.State.Decorator.OperationalStatus",
225 "Functional", std::move(getCpuFunctionalState));
226 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500227
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200228 sdbusplus::asio::getAllProperties(
229 *crow::connections::systemBus, service, path,
230 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700231 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800232 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800233 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700234 if (ec2)
235 {
Ed Tanous62598e32023-07-17 17:06:25 -0700236 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700237 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700238 return;
239 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700240 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500241 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500242}
243
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500244/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500245 * @brief processMemoryProperties fields
246 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700247 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500248 * @param[in] service dbus service for memory Information
249 * @param[in] path dbus path for Memory
250 * @param[in] DBUS properties for memory
251 *
252 * @return None.
253 */
254inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700255 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500256 [[maybe_unused]] const std::string& service,
257 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500258 const dbus::utility::DBusPropertiesMap& properties)
259{
Ed Tanous62598e32023-07-17 17:06:25 -0700260 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500261
262 if (properties.empty())
263 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500264 if constexpr (bmcwebEnableProcMemStatus)
265 {
266 sdbusplus::asio::getProperty<bool>(
267 *crow::connections::systemBus, service, path,
268 "xyz.openbmc_project.State."
269 "Decorator.OperationalStatus",
270 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700271 [asyncResp](const boost::system::error_code& ec3,
272 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500273 if (ec3)
274 {
Ed Tanous62598e32023-07-17 17:06:25 -0700275 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500276 return;
277 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700278 updateDimmProperties(asyncResp, dimmState);
Patrick Williams5a39f772023-10-20 11:20:21 -0500279 });
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500280 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500281 return;
282 }
283
284 const size_t* memorySizeInKB = nullptr;
285
286 const bool success = sdbusplus::unpackPropertiesNoThrow(
287 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
288 memorySizeInKB);
289
290 if (!success)
291 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700292 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500293 return;
294 }
295
296 if (memorySizeInKB != nullptr)
297 {
298 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700299 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500300 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500301 if (preValue == nullptr)
302 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700303 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500304 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500305 }
306 else
307 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500309 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
310 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500311 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500312 if constexpr (bmcwebEnableProcMemStatus)
313 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700314 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500315 "Enabled";
316 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500317 }
318}
319
320/*
321 * @brief Get getMemorySummary fields
322 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700323 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500324 * @param[in] service dbus service for memory Information
325 * @param[in] path dbus path for memory
326 *
327 * @return None.
328 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700329inline void
330 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500332{
333 sdbusplus::asio::getAllProperties(
334 *crow::connections::systemBus, service, path,
335 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700336 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500337 path](const boost::system::error_code& ec2,
338 const dbus::utility::DBusPropertiesMap& properties) {
339 if (ec2)
340 {
Ed Tanous62598e32023-07-17 17:06:25 -0700341 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700342 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500343 return;
344 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700345 processMemoryProperties(asyncResp, service, path, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500346 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500347}
348
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500349inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
350 const boost::system::error_code& ec,
351 const dbus::utility::DBusPropertiesMap& properties)
352{
353 if (ec)
354 {
355 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
356 messages::internalError(asyncResp->res);
357 return;
358 }
359 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
360
361 const std::string* uUID = nullptr;
362
363 const bool success = sdbusplus::unpackPropertiesNoThrow(
364 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
365
366 if (!success)
367 {
368 messages::internalError(asyncResp->res);
369 return;
370 }
371
372 if (uUID != nullptr)
373 {
374 std::string valueStr = *uUID;
375 if (valueStr.size() == 32)
376 {
377 valueStr.insert(8, 1, '-');
378 valueStr.insert(13, 1, '-');
379 valueStr.insert(18, 1, '-');
380 valueStr.insert(23, 1, '-');
381 }
382 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
383 asyncResp->res.jsonValue["UUID"] = valueStr;
384 }
385}
386
387inline void
388 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
389 const boost::system::error_code& ec,
390 const dbus::utility::DBusPropertiesMap& propertiesList)
391{
392 if (ec)
393 {
394 // doesn't have to include this
395 // interface
396 return;
397 }
398 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
399
400 const std::string* partNumber = nullptr;
401 const std::string* serialNumber = nullptr;
402 const std::string* manufacturer = nullptr;
403 const std::string* model = nullptr;
404 const std::string* subModel = nullptr;
405
406 const bool success = sdbusplus::unpackPropertiesNoThrow(
407 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
408 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
409 "Model", model, "SubModel", subModel);
410
411 if (!success)
412 {
413 messages::internalError(asyncResp->res);
414 return;
415 }
416
417 if (partNumber != nullptr)
418 {
419 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
420 }
421
422 if (serialNumber != nullptr)
423 {
424 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
425 }
426
427 if (manufacturer != nullptr)
428 {
429 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
430 }
431
432 if (model != nullptr)
433 {
434 asyncResp->res.jsonValue["Model"] = *model;
435 }
436
437 if (subModel != nullptr)
438 {
439 asyncResp->res.jsonValue["SubModel"] = *subModel;
440 }
441
442 // Grab the bios version
443 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
444 "BiosVersion", false);
445}
446
447inline void
448 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
449 const boost::system::error_code& ec,
450 const std::string& value)
451{
452 if (ec)
453 {
454 // doesn't have to include this
455 // interface
456 return;
457 }
458
459 asyncResp->res.jsonValue["AssetTag"] = value;
460}
461
462inline void afterSystemGetSubTree(
463 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
464 const std::shared_ptr<HealthPopulate>& systemHealth,
465 const boost::system::error_code& ec,
466 const dbus::utility::MapperGetSubTreeResponse& subtree)
467{
468 if (ec)
469 {
470 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
471 messages::internalError(asyncResp->res);
472 return;
473 }
474 // Iterate over all retrieved ObjectPaths.
475 for (const std::pair<
476 std::string,
477 std::vector<std::pair<std::string, std::vector<std::string>>>>&
478 object : subtree)
479 {
480 const std::string& path = object.first;
481 BMCWEB_LOG_DEBUG("Got path: {}", path);
482 const std::vector<std::pair<std::string, std::vector<std::string>>>&
483 connectionNames = object.second;
484 if (connectionNames.empty())
485 {
486 continue;
487 }
488
489 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
490 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
491
492 if constexpr (bmcwebEnableProcMemStatus)
493 {
494 memoryHealth = std::make_shared<HealthPopulate>(
495 asyncResp, "/MemorySummary/Status"_json_pointer);
496 systemHealth->children.emplace_back(memoryHealth);
497
498 if constexpr (bmcwebEnableHealthPopulate)
499 {
500 cpuHealth = std::make_shared<HealthPopulate>(
501 asyncResp, "/ProcessorSummary/Status"_json_pointer);
502
503 systemHealth->children.emplace_back(cpuHealth);
504 }
505 }
506
507 // This is not system, so check if it's cpu, dimm, UUID or
508 // BiosVer
509 for (const auto& connection : connectionNames)
510 {
511 for (const auto& interfaceName : connection.second)
512 {
513 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
514 {
515 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
516
517 getMemorySummary(asyncResp, connection.first, path);
518
519 if constexpr (bmcwebEnableProcMemStatus)
520 {
521 memoryHealth->inventory.emplace_back(path);
522 }
523 }
524 else if (interfaceName ==
525 "xyz.openbmc_project.Inventory.Item.Cpu")
526 {
527 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
528
529 getProcessorSummary(asyncResp, connection.first, path);
530
531 if constexpr (bmcwebEnableProcMemStatus)
532 {
533 cpuHealth->inventory.emplace_back(path);
534 }
535 }
536 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
537 {
538 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
539
540 sdbusplus::asio::getAllProperties(
541 *crow::connections::systemBus, connection.first, path,
542 "xyz.openbmc_project.Common.UUID",
543 [asyncResp](const boost::system::error_code& ec3,
544 const dbus::utility::DBusPropertiesMap&
545 properties) {
546 afterGetUUID(asyncResp, ec3, properties);
547 });
548 }
549 else if (interfaceName ==
550 "xyz.openbmc_project.Inventory.Item.System")
551 {
552 sdbusplus::asio::getAllProperties(
553 *crow::connections::systemBus, connection.first, path,
554 "xyz.openbmc_project.Inventory.Decorator.Asset",
555 [asyncResp](const boost::system::error_code& ec3,
556 const dbus::utility::DBusPropertiesMap&
557 properties) {
558 afterGetInventory(asyncResp, ec3, properties);
559 });
560
561 sdbusplus::asio::getProperty<std::string>(
562 *crow::connections::systemBus, connection.first, path,
563 "xyz.openbmc_project.Inventory.Decorator."
564 "AssetTag",
565 "AssetTag",
566 std::bind_front(afterGetAssetTag, asyncResp));
567 }
568 }
569 }
570 }
571}
572
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500573/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700574 * @brief Retrieves computer system properties over dbus
575 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700576 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500577 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700578 *
579 * @return None.
580 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700581inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700582 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700583 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700584{
Ed Tanous62598e32023-07-17 17:06:25 -0700585 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800586 constexpr std::array<std::string_view, 5> interfaces = {
587 "xyz.openbmc_project.Inventory.Decorator.Asset",
588 "xyz.openbmc_project.Inventory.Item.Cpu",
589 "xyz.openbmc_project.Inventory.Item.Dimm",
590 "xyz.openbmc_project.Inventory.Item.System",
591 "xyz.openbmc_project.Common.UUID",
592 };
593 dbus::utility::getSubTree(
594 "/xyz/openbmc_project/inventory", 0, interfaces,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500595 std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
Ed Tanous6c34de42018-08-29 13:37:36 -0700596}
597
598/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700599 * @brief Retrieves host state properties over dbus
600 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700601 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700602 *
603 * @return None.
604 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700605inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700606{
Ed Tanous62598e32023-07-17 17:06:25 -0700607 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700608 sdbusplus::asio::getProperty<std::string>(
609 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
610 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
611 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700612 [asyncResp](const boost::system::error_code& ec,
613 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700614 if (ec)
615 {
616 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700617 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700618 // Service not available, no error, just don't return
619 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700620 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700621 return;
622 }
Ed Tanous62598e32023-07-17 17:06:25 -0700623 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700624 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700625 return;
626 }
Ed Tanous66173382018-08-15 18:20:59 -0700627
Ed Tanous62598e32023-07-17 17:06:25 -0700628 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700629 // Verify Host State
630 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
631 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700632 asyncResp->res.jsonValue["PowerState"] = "On";
633 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700634 }
635 else if (hostState ==
636 "xyz.openbmc_project.State.Host.HostState.Quiesced")
637 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700638 asyncResp->res.jsonValue["PowerState"] = "On";
639 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700640 }
641 else if (hostState ==
642 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
643 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700644 asyncResp->res.jsonValue["PowerState"] = "On";
645 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700646 }
647 else if (
648 hostState ==
649 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
650 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700651 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
652 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700653 }
654 else if (hostState ==
655 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
656 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700657 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
658 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700659 }
660 else
661 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700662 asyncResp->res.jsonValue["PowerState"] = "Off";
663 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700664 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500665 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700666}
667
668/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500669 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530670 *
671 * @param[in] dbusSource The boot source in DBUS speak.
672 *
673 * @return Returns as a string, the boot source in Redfish terms. If translation
674 * cannot be done, returns an empty string.
675 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000676inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530677{
678 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
679 {
680 return "None";
681 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700682 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530683 {
684 return "Hdd";
685 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700686 if (dbusSource ==
687 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530688 {
689 return "Cd";
690 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700691 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530692 {
693 return "Pxe";
694 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700695 if (dbusSource ==
696 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700697 {
698 return "Usb";
699 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700700 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530701}
702
703/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300704 * @brief Translates boot type DBUS property value to redfish.
705 *
706 * @param[in] dbusType The boot type in DBUS speak.
707 *
708 * @return Returns as a string, the boot type in Redfish terms. If translation
709 * cannot be done, returns an empty string.
710 */
711inline std::string dbusToRfBootType(const std::string& dbusType)
712{
713 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
714 {
715 return "Legacy";
716 }
717 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
718 {
719 return "UEFI";
720 }
721 return "";
722}
723
724/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500725 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530726 *
727 * @param[in] dbusMode The boot mode in DBUS speak.
728 *
729 * @return Returns as a string, the boot mode in Redfish terms. If translation
730 * cannot be done, returns an empty string.
731 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000732inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530733{
734 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
735 {
736 return "None";
737 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700738 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530739 {
740 return "Diags";
741 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700742 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530743 {
744 return "BiosSetup";
745 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700746 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530747}
748
749/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600750 * @brief Translates boot progress DBUS property value to redfish.
751 *
752 * @param[in] dbusBootProgress The boot progress in DBUS speak.
753 *
754 * @return Returns as a string, the boot progress in Redfish terms. If
755 * translation cannot be done, returns "None".
756 */
757inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
758{
759 // Now convert the D-Bus BootProgress to the appropriate Redfish
760 // enum
761 std::string rfBpLastState = "None";
762 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
763 "ProgressStages.Unspecified")
764 {
765 rfBpLastState = "None";
766 }
767 else if (dbusBootProgress ==
768 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
769 "PrimaryProcInit")
770 {
771 rfBpLastState = "PrimaryProcessorInitializationStarted";
772 }
773 else if (dbusBootProgress ==
774 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
775 "BusInit")
776 {
777 rfBpLastState = "BusInitializationStarted";
778 }
779 else if (dbusBootProgress ==
780 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
781 "MemoryInit")
782 {
783 rfBpLastState = "MemoryInitializationStarted";
784 }
785 else if (dbusBootProgress ==
786 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
787 "SecondaryProcInit")
788 {
789 rfBpLastState = "SecondaryProcessorInitializationStarted";
790 }
791 else if (dbusBootProgress ==
792 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
793 "PCIInit")
794 {
795 rfBpLastState = "PCIResourceConfigStarted";
796 }
797 else if (dbusBootProgress ==
798 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
799 "SystemSetup")
800 {
801 rfBpLastState = "SetupEntered";
802 }
803 else if (dbusBootProgress ==
804 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
805 "SystemInitComplete")
806 {
807 rfBpLastState = "SystemHardwareInitializationComplete";
808 }
809 else if (dbusBootProgress ==
810 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
811 "OSStart")
812 {
813 rfBpLastState = "OSBootStarted";
814 }
815 else if (dbusBootProgress ==
816 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
817 "OSRunning")
818 {
819 rfBpLastState = "OSRunning";
820 }
821 else
822 {
Ed Tanous62598e32023-07-17 17:06:25 -0700823 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600824 // Just return the default
825 }
826 return rfBpLastState;
827}
828
829/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500830 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530831 *
832 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700833 * @param[out] bootSource The DBus source
834 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530835 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700836 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530837 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700838inline int
839 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
840 const std::string& rfSource, std::string& bootSource,
841 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530842{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300843 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
844 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700845
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530846 if (rfSource == "None")
847 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700848 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530849 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700850 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530851 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700852 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
853 }
854 else if (rfSource == "Hdd")
855 {
856 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
857 }
858 else if (rfSource == "Diags")
859 {
860 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
861 }
862 else if (rfSource == "Cd")
863 {
864 bootSource =
865 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
866 }
867 else if (rfSource == "BiosSetup")
868 {
869 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530870 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700871 else if (rfSource == "Usb")
872 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700873 bootSource =
874 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700875 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530876 else
877 {
Ed Tanous62598e32023-07-17 17:06:25 -0700878 BMCWEB_LOG_DEBUG(
879 "Invalid property value for BootSourceOverrideTarget: {}",
880 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700881 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700882 "BootSourceTargetOverride");
883 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530884 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700885 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530886}
Ali Ahmed19817712021-06-29 17:01:52 -0500887
Andrew Geissler978b8802020-11-19 13:36:40 -0600888/**
889 * @brief Retrieves boot progress of the system
890 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700891 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600892 *
893 * @return None.
894 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700895inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600896{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700897 sdbusplus::asio::getProperty<std::string>(
898 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
899 "/xyz/openbmc_project/state/host0",
900 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700901 [asyncResp](const boost::system::error_code& ec,
902 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700903 if (ec)
904 {
905 // BootProgress is an optional object so just do nothing if
906 // not found
907 return;
908 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600909
Ed Tanous62598e32023-07-17 17:06:25 -0700910 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600911
Ed Tanousac106bf2023-06-07 09:24:59 -0700912 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700913 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500914 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600915}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530916
917/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000918 * @brief Retrieves boot progress Last Update of the system
919 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700920 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000921 *
922 * @return None.
923 */
924inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700925 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000926{
927 sdbusplus::asio::getProperty<uint64_t>(
928 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
929 "/xyz/openbmc_project/state/host0",
930 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700931 [asyncResp](const boost::system::error_code& ec,
932 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000933 if (ec)
934 {
Ed Tanous62598e32023-07-17 17:06:25 -0700935 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000936 return;
937 }
938
939 // BootProgressLastUpdate is the last time the BootProgress property
940 // was updated. The time is the Epoch time, number of microseconds
941 // since 1 Jan 1970 00::00::00 UTC."
942 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
943 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
944
945 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700946 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000947 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500948 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000949}
950
951/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300952 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300953 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700954 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300955 *
956 * @return None.
957 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300958
Ed Tanousac106bf2023-06-07 09:24:59 -0700959inline void
960 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300961{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700962 sdbusplus::asio::getProperty<std::string>(
963 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
964 "/xyz/openbmc_project/control/host0/boot",
965 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700966 [asyncResp](const boost::system::error_code& ec,
967 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700968 if (ec)
969 {
970 // not an error, don't have to have the interface
971 return;
972 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300973
Ed Tanous62598e32023-07-17 17:06:25 -0700974 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300975
Ed Tanousac106bf2023-06-07 09:24:59 -0700976 asyncResp->res
977 .jsonValue["Boot"]
978 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700979 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300980
Ed Tanous002d39b2022-05-31 08:59:27 -0700981 auto rfType = dbusToRfBootType(bootType);
982 if (rfType.empty())
983 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700984 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700985 return;
986 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300987
Ed Tanousac106bf2023-06-07 09:24:59 -0700988 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500989 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300990}
991
992/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300993 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530994 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700995 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530996 *
997 * @return None.
998 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300999
Ed Tanousac106bf2023-06-07 09:24:59 -07001000inline void
1001 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301002{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001003 sdbusplus::asio::getProperty<std::string>(
1004 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1005 "/xyz/openbmc_project/control/host0/boot",
1006 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001007 [asyncResp](const boost::system::error_code& ec,
1008 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001009 if (ec)
1010 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001011 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001012 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001013 return;
1014 }
1015
Ed Tanous62598e32023-07-17 17:06:25 -07001016 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -07001017
Ed Tanousac106bf2023-06-07 09:24:59 -07001018 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001019 .jsonValue["Boot"]
1020 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1021 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1022
1023 if (bootModeStr !=
1024 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1025 {
1026 auto rfMode = dbusToRfBootMode(bootModeStr);
1027 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301028 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001029 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001030 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301031 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001032 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001033 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034}
1035
1036/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001037 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301038 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001039 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301040 *
1041 * @return None.
1042 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001043
1044inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001045 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301046{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001047 sdbusplus::asio::getProperty<std::string>(
1048 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1049 "/xyz/openbmc_project/control/host0/boot",
1050 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001051 [asyncResp](const boost::system::error_code& ec,
1052 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001053 if (ec)
1054 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001055 if (ec.value() == boost::asio::error::host_unreachable)
1056 {
1057 return;
1058 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001059 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001060 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001061 return;
1062 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301063
Ed Tanous62598e32023-07-17 17:06:25 -07001064 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301065
Ed Tanous002d39b2022-05-31 08:59:27 -07001066 auto rfSource = dbusToRfBootSource(bootSourceStr);
1067 if (!rfSource.empty())
1068 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001069 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1070 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001071 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001072
Ed Tanous002d39b2022-05-31 08:59:27 -07001073 // Get BootMode as BootSourceOverrideTarget is constructed
1074 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001075 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001076 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301077}
1078
1079/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001080 * @brief This functions abstracts all the logic behind getting a
1081 * "BootSourceOverrideEnabled" property from an overall boot override enable
1082 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301083 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001084 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301085 *
1086 * @return None.
1087 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301088
Ed Tanousac106bf2023-06-07 09:24:59 -07001089inline void processBootOverrideEnable(
1090 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1091 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001092{
1093 if (!bootOverrideEnableSetting)
1094 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001095 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1096 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001097 return;
1098 }
1099
1100 // If boot source override is enabled, we need to check 'one_time'
1101 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001102 sdbusplus::asio::getProperty<bool>(
1103 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1104 "/xyz/openbmc_project/control/host0/boot/one_time",
1105 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001106 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001107 if (ec)
1108 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001109 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001110 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001111 return;
1112 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301113
Ed Tanous002d39b2022-05-31 08:59:27 -07001114 if (oneTimeSetting)
1115 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001116 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1117 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001118 }
1119 else
1120 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001121 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001122 "Continuous";
1123 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001124 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301125}
1126
1127/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001128 * @brief Retrieves boot override enable over DBUS
1129 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001130 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001131 *
1132 * @return None.
1133 */
1134
1135inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001136 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001137{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001138 sdbusplus::asio::getProperty<bool>(
1139 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1140 "/xyz/openbmc_project/control/host0/boot",
1141 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001142 [asyncResp](const boost::system::error_code& ec,
1143 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001144 if (ec)
1145 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001146 if (ec.value() == boost::asio::error::host_unreachable)
1147 {
1148 return;
1149 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001150 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001151 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001152 return;
1153 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001154
Ed Tanousac106bf2023-06-07 09:24:59 -07001155 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001156 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001157}
1158
1159/**
1160 * @brief Retrieves boot source override properties
1161 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001162 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001163 *
1164 * @return None.
1165 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001166inline void
1167 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001168{
Ed Tanous62598e32023-07-17 17:06:25 -07001169 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001170
Ed Tanousac106bf2023-06-07 09:24:59 -07001171 getBootOverrideSource(asyncResp);
1172 getBootOverrideType(asyncResp);
1173 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001174}
1175
1176/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001177 * @brief Retrieves the Last Reset Time
1178 *
1179 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1180 * and power off. Even though this is the "system" Redfish object look at the
1181 * chassis D-Bus interface for the LastStateChangeTime since this has the
1182 * last power operation time.
1183 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001184 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001185 *
1186 * @return None.
1187 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001188inline void
1189 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001190{
Ed Tanous62598e32023-07-17 17:06:25 -07001191 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001192
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001193 sdbusplus::asio::getProperty<uint64_t>(
1194 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1195 "/xyz/openbmc_project/state/chassis0",
1196 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001197 [asyncResp](const boost::system::error_code& ec,
1198 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001199 if (ec)
1200 {
Ed Tanous62598e32023-07-17 17:06:25 -07001201 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001202 return;
1203 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001204
Ed Tanous002d39b2022-05-31 08:59:27 -07001205 // LastStateChangeTime is epoch time, in milliseconds
1206 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1207 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001208
Ed Tanous002d39b2022-05-31 08:59:27 -07001209 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001210 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001211 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001212 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001213}
1214
1215/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001216 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1217 *
1218 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1219 * corresponding property "AttemptsLeft" that keeps track of the amount of
1220 * automatic retry attempts left are hosted in phosphor-state-manager through
1221 * dbus.
1222 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001223 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001224 *
1225 * @return None.
1226 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001227inline void getAutomaticRebootAttempts(
1228 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001229{
Ed Tanous62598e32023-07-17 17:06:25 -07001230 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001231
1232 sdbusplus::asio::getAllProperties(
1233 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1234 "/xyz/openbmc_project/state/host0",
1235 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001236 [asyncResp{asyncResp}](
1237 const boost::system::error_code& ec,
1238 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001239 if (ec)
1240 {
1241 if (ec.value() != EBADR)
1242 {
Ed Tanous62598e32023-07-17 17:06:25 -07001243 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001244 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001245 }
1246 return;
1247 }
1248
1249 const uint32_t* attemptsLeft = nullptr;
1250 const uint32_t* retryAttempts = nullptr;
1251
1252 const bool success = sdbusplus::unpackPropertiesNoThrow(
1253 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1254 attemptsLeft, "RetryAttempts", retryAttempts);
1255
1256 if (!success)
1257 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001258 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001259 return;
1260 }
1261
1262 if (attemptsLeft != nullptr)
1263 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001264 asyncResp->res
1265 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001266 *attemptsLeft;
1267 }
1268
1269 if (retryAttempts != nullptr)
1270 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001271 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001272 *retryAttempts;
1273 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001274 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001275}
1276
1277/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001278 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1279 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001280 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001281 *
1282 * @return None.
1283 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001284inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001285 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001286{
Ed Tanous62598e32023-07-17 17:06:25 -07001287 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001288
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001289 sdbusplus::asio::getProperty<bool>(
1290 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1291 "/xyz/openbmc_project/control/host0/auto_reboot",
1292 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001293 [asyncResp](const boost::system::error_code& ec,
1294 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001295 if (ec)
1296 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001297 if (ec.value() != EBADR)
1298 {
Ed Tanous62598e32023-07-17 17:06:25 -07001299 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001300 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001301 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001302 return;
1303 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001304
Ed Tanous62598e32023-07-17 17:06:25 -07001305 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001306 if (autoRebootEnabled)
1307 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001308 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001309 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001310 }
1311 else
1312 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001313 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1314 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001315 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001316 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001317
Ed Tanous002d39b2022-05-31 08:59:27 -07001318 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1319 // and RetryAttempts. OpenBMC only supports Disabled and
1320 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001321 asyncResp->res
1322 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1323 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001324 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001325}
1326
1327/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001328 * @brief Sets RetryAttempts
1329 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001330 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001331 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1332 *
1333 *@return None.
1334 */
1335
Ed Tanousac106bf2023-06-07 09:24:59 -07001336inline void setAutomaticRetryAttempts(
1337 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1338 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001339{
Ed Tanous62598e32023-07-17 17:06:25 -07001340 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001341 sdbusplus::asio::setProperty(
1342 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1343 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001344 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001345 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001346 if (ec)
1347 {
1348 BMCWEB_LOG_ERROR(
1349 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1350 messages::internalError(asyncResp->res);
1351 return;
1352 }
1353 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001354}
1355
Ed Tanous8d69c662023-06-21 10:29:06 -07001356inline computer_system::PowerRestorePolicyTypes
1357 redfishPowerRestorePolicyFromDbus(std::string_view value)
1358{
1359 if (value ==
1360 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1361 {
1362 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1363 }
1364 if (value ==
1365 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1366 {
1367 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1368 }
1369 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001370 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001371 {
1372 return computer_system::PowerRestorePolicyTypes::LastState;
1373 }
1374 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1375 {
1376 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1377 }
1378 return computer_system::PowerRestorePolicyTypes::Invalid;
1379}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001380/**
George Liuc6a620f2020-04-10 17:18:11 +08001381 * @brief Retrieves power restore policy over DBUS.
1382 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001383 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001384 *
1385 * @return None.
1386 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001387inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001388 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001389{
Ed Tanous62598e32023-07-17 17:06:25 -07001390 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001391
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001392 sdbusplus::asio::getProperty<std::string>(
1393 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1394 "/xyz/openbmc_project/control/host0/power_restore_policy",
1395 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001396 [asyncResp](const boost::system::error_code& ec,
1397 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001398 if (ec)
1399 {
Ed Tanous62598e32023-07-17 17:06:25 -07001400 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001401 return;
1402 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001403 computer_system::PowerRestorePolicyTypes restore =
1404 redfishPowerRestorePolicyFromDbus(policy);
1405 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001406 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001407 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001408 return;
1409 }
George Liuc6a620f2020-04-10 17:18:11 +08001410
Ed Tanous8d69c662023-06-21 10:29:06 -07001411 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001412 });
George Liuc6a620f2020-04-10 17:18:11 +08001413}
1414
1415/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001416 * @brief Stop Boot On Fault over DBUS.
1417 *
1418 * @param[in] asyncResp Shared pointer for generating response message.
1419 *
1420 * @return None.
1421 */
1422inline void
1423 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1424{
Ed Tanous62598e32023-07-17 17:06:25 -07001425 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001426
1427 sdbusplus::asio::getProperty<bool>(
1428 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1429 "/xyz/openbmc_project/logging/settings",
1430 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1431 [asyncResp](const boost::system::error_code& ec, bool value) {
1432 if (ec)
1433 {
1434 if (ec.value() != EBADR)
1435 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001436 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001437 messages::internalError(asyncResp->res);
1438 }
1439 return;
1440 }
1441
1442 if (value)
1443 {
1444 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1445 }
1446 else
1447 {
1448 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1449 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001450 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001451}
1452
1453/**
Ali Ahmed19817712021-06-29 17:01:52 -05001454 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1455 * TPM is required for booting the host.
1456 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001457 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001458 *
1459 * @return None.
1460 */
1461inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001462 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001463{
Ed Tanous62598e32023-07-17 17:06:25 -07001464 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001465 constexpr std::array<std::string_view, 1> interfaces = {
1466 "xyz.openbmc_project.Control.TPM.Policy"};
1467 dbus::utility::getSubTree(
1468 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001469 [asyncResp](const boost::system::error_code& ec,
1470 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001471 if (ec)
1472 {
Ed Tanous62598e32023-07-17 17:06:25 -07001473 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1474 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001475 // This is an optional D-Bus object so just return if
1476 // error occurs
1477 return;
1478 }
1479 if (subtree.empty())
1480 {
1481 // As noted above, this is an optional interface so just return
1482 // if there is no instance found
1483 return;
1484 }
1485
1486 /* When there is more than one TPMEnable object... */
1487 if (subtree.size() > 1)
1488 {
Ed Tanous62598e32023-07-17 17:06:25 -07001489 BMCWEB_LOG_DEBUG(
1490 "DBUS response has more than 1 TPM Enable object:{}",
1491 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001492 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001493 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001494 return;
1495 }
1496
1497 // Make sure the Dbus response map has a service and objectPath
1498 // field
1499 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1500 {
Ed Tanous62598e32023-07-17 17:06:25 -07001501 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001502 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001503 return;
1504 }
1505
1506 const std::string& path = subtree[0].first;
1507 const std::string& serv = subtree[0].second.begin()->first;
1508
1509 // Valid TPM Enable object found, now reading the current value
1510 sdbusplus::asio::getProperty<bool>(
1511 *crow::connections::systemBus, serv, path,
1512 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001513 [asyncResp](const boost::system::error_code& ec2,
1514 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001515 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001516 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001517 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001518 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001519 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001520 return;
1521 }
1522
Ed Tanous002d39b2022-05-31 08:59:27 -07001523 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001524 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001525 asyncResp->res
1526 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001527 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001528 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001529 else
1530 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001531 asyncResp->res
1532 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001533 "Disabled";
1534 }
George Liue99073f2022-12-09 11:06:16 +08001535 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001536 });
Ali Ahmed19817712021-06-29 17:01:52 -05001537}
1538
1539/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001540 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1541 * TPM is required for booting the host.
1542 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001543 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001544 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1545 *
1546 * @return None.
1547 */
1548inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001549 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001550{
Ed Tanous62598e32023-07-17 17:06:25 -07001551 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001552 constexpr std::array<std::string_view, 1> interfaces = {
1553 "xyz.openbmc_project.Control.TPM.Policy"};
1554 dbus::utility::getSubTree(
1555 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001556 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001557 tpmRequired](const boost::system::error_code& ec,
1558 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001559 if (ec)
1560 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001561 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001562 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001563 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001564 return;
1565 }
1566 if (subtree.empty())
1567 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001568 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001569 "TrustedModuleRequiredToBoot");
1570 return;
1571 }
1572
1573 /* When there is more than one TPMEnable object... */
1574 if (subtree.size() > 1)
1575 {
Ed Tanous62598e32023-07-17 17:06:25 -07001576 BMCWEB_LOG_DEBUG(
1577 "DBUS response has more than 1 TPM Enable object:{}",
1578 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001579 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001580 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001581 return;
1582 }
1583
1584 // Make sure the Dbus response map has a service and objectPath
1585 // field
1586 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1587 {
Ed Tanous62598e32023-07-17 17:06:25 -07001588 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001589 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001590 return;
1591 }
1592
1593 const std::string& path = subtree[0].first;
1594 const std::string& serv = subtree[0].second.begin()->first;
1595
1596 if (serv.empty())
1597 {
Ed Tanous62598e32023-07-17 17:06:25 -07001598 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001599 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001600 return;
1601 }
1602
1603 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001604 sdbusplus::asio::setProperty(
1605 *crow::connections::systemBus, serv, path,
1606 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001607 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001608 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001609 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001610 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001611 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1612 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001613 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001614 return;
1615 }
Ed Tanous62598e32023-07-17 17:06:25 -07001616 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001617 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001618 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001619}
1620
1621/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301622 * @brief Sets boot properties into DBUS object(s).
1623 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001624 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001625 * @param[in] bootType The boot type to set.
1626 * @return Integer error code.
1627 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001628inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001629 const std::optional<std::string>& bootType)
1630{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001631 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001632
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001633 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001634 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001635 return;
1636 }
1637
1638 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001639 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001640 // Figure out which DBUS interface and property to use
1641 if (*bootType == "Legacy")
1642 {
1643 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1644 }
1645 else if (*bootType == "UEFI")
1646 {
1647 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1648 }
1649 else
1650 {
Ed Tanous62598e32023-07-17 17:06:25 -07001651 BMCWEB_LOG_DEBUG("Invalid property value for "
1652 "BootSourceOverrideMode: {}",
1653 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001654 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001655 "BootSourceOverrideMode");
1656 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001657 }
1658
1659 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001660 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001661
George Liu9ae226f2023-06-21 17:56:46 +08001662 sdbusplus::asio::setProperty(
1663 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1664 "/xyz/openbmc_project/control/host0/boot",
1665 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001666 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001667 if (ec)
1668 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001669 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001670 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001671 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001672 return;
1673 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001674 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001675 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001676 return;
1677 }
Ed Tanous62598e32023-07-17 17:06:25 -07001678 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001679 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001680}
1681
1682/**
1683 * @brief Sets boot properties into DBUS object(s).
1684 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001685 * @param[in] asyncResp Shared pointer for generating response
1686 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001687 * @param[in] bootType The boot type to set.
1688 * @return Integer error code.
1689 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001690inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001691 const std::optional<std::string>& bootEnable)
1692{
1693 if (!bootEnable)
1694 {
1695 return;
1696 }
1697 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001698 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001699
1700 bool bootOverrideEnable = false;
1701 bool bootOverridePersistent = false;
1702 // Figure out which DBUS interface and property to use
1703 if (*bootEnable == "Disabled")
1704 {
1705 bootOverrideEnable = false;
1706 }
1707 else if (*bootEnable == "Once")
1708 {
1709 bootOverrideEnable = true;
1710 bootOverridePersistent = false;
1711 }
1712 else if (*bootEnable == "Continuous")
1713 {
1714 bootOverrideEnable = true;
1715 bootOverridePersistent = true;
1716 }
1717 else
1718 {
Ed Tanous62598e32023-07-17 17:06:25 -07001719 BMCWEB_LOG_DEBUG(
1720 "Invalid property value for BootSourceOverrideEnabled: {}",
1721 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001722 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001723 "BootSourceOverrideEnabled");
1724 return;
1725 }
1726
1727 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001728 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001729
George Liu9ae226f2023-06-21 17:56:46 +08001730 sdbusplus::asio::setProperty(
1731 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1732 "/xyz/openbmc_project/control/host0/boot",
1733 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001734 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001735 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001736 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001737 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001738 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001739 return;
1740 }
Ed Tanous62598e32023-07-17 17:06:25 -07001741 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001742 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001743
1744 if (!bootOverrideEnable)
1745 {
1746 return;
1747 }
1748
1749 // In case boot override is enabled we need to set correct value for the
1750 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001751 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1752 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001753
George Liu9ae226f2023-06-21 17:56:46 +08001754 sdbusplus::asio::setProperty(
1755 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1756 "/xyz/openbmc_project/control/host0/boot/one_time",
1757 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001758 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001759 if (ec)
1760 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001761 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001762 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001763 return;
1764 }
Ed Tanous62598e32023-07-17 17:06:25 -07001765 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001766 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001767}
1768
1769/**
1770 * @brief Sets boot properties into DBUS object(s).
1771 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001772 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301773 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301774 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001775 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301776 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001777inline void
1778 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1779 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301780{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001781 std::string bootSourceStr;
1782 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001783
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001784 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301785 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001786 return;
1787 }
1788
1789 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001790 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001791 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001792 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1793 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001794 {
Ed Tanous62598e32023-07-17 17:06:25 -07001795 BMCWEB_LOG_DEBUG(
1796 "Invalid property value for BootSourceOverrideTarget: {}",
1797 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001798 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001799 "BootSourceTargetOverride");
1800 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001801 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301802
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001803 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001804 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1805 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001806
George Liu9ae226f2023-06-21 17:56:46 +08001807 sdbusplus::asio::setProperty(
1808 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1809 "/xyz/openbmc_project/control/host0/boot",
1810 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001811 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001812 if (ec)
1813 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001814 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001815 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001816 return;
1817 }
Ed Tanous62598e32023-07-17 17:06:25 -07001818 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001819 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001820
George Liu9ae226f2023-06-21 17:56:46 +08001821 sdbusplus::asio::setProperty(
1822 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1823 "/xyz/openbmc_project/control/host0/boot",
1824 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001825 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001826 if (ec)
1827 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001828 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001829 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001830 return;
1831 }
Ed Tanous62598e32023-07-17 17:06:25 -07001832 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001833 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001834}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001835
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001836/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001837 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301838 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001839 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301840 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001841 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301842 * @param[in] bootEnable The boot override enable from incoming RF request.
1843 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001844 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301845 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001846
Ed Tanousac106bf2023-06-07 09:24:59 -07001847inline void
1848 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1849 const std::optional<std::string>& bootSource,
1850 const std::optional<std::string>& bootType,
1851 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301852{
Ed Tanous62598e32023-07-17 17:06:25 -07001853 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301854
Ed Tanousac106bf2023-06-07 09:24:59 -07001855 setBootModeOrSource(asyncResp, bootSource);
1856 setBootType(asyncResp, bootType);
1857 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301858}
1859
George Liuc6a620f2020-04-10 17:18:11 +08001860/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001861 * @brief Sets AssetTag
1862 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001863 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001864 * @param[in] assetTag "AssetTag" from request.
1865 *
1866 * @return None.
1867 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001868inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001869 const std::string& assetTag)
1870{
George Liue99073f2022-12-09 11:06:16 +08001871 constexpr std::array<std::string_view, 1> interfaces = {
1872 "xyz.openbmc_project.Inventory.Item.System"};
1873 dbus::utility::getSubTree(
1874 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001875 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001876 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001877 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001878 if (ec)
1879 {
Ed Tanous62598e32023-07-17 17:06:25 -07001880 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001881 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001882 return;
1883 }
1884 if (subtree.empty())
1885 {
Ed Tanous62598e32023-07-17 17:06:25 -07001886 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001887 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001888 return;
1889 }
1890 // Assume only 1 system D-Bus object
1891 // Throw an error if there is more than 1
1892 if (subtree.size() > 1)
1893 {
Ed Tanous62598e32023-07-17 17:06:25 -07001894 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001895 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001896 return;
1897 }
1898 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1899 {
Ed Tanous62598e32023-07-17 17:06:25 -07001900 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001901 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001902 return;
1903 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001904
Ed Tanous002d39b2022-05-31 08:59:27 -07001905 const std::string& path = subtree[0].first;
1906 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001907
Ed Tanous002d39b2022-05-31 08:59:27 -07001908 if (service.empty())
1909 {
Ed Tanous62598e32023-07-17 17:06:25 -07001910 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001911 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001912 return;
1913 }
1914
George Liu9ae226f2023-06-21 17:56:46 +08001915 sdbusplus::asio::setProperty(
1916 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001917 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001918 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001919 if (ec2)
1920 {
1921 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1922 ec2);
1923 messages::internalError(asyncResp->res);
1924 return;
1925 }
George Liue99073f2022-12-09 11:06:16 +08001926 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001927 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001928}
1929
1930/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001931 * @brief Validate the specified stopBootOnFault is valid and return the
1932 * stopBootOnFault name associated with that string
1933 *
1934 * @param[in] stopBootOnFaultString String representing the desired
1935 * stopBootOnFault
1936 *
1937 * @return stopBootOnFault value or empty if incoming value is not valid
1938 */
1939inline std::optional<bool>
1940 validstopBootOnFault(const std::string& stopBootOnFaultString)
1941{
1942 if (stopBootOnFaultString == "AnyFault")
1943 {
1944 return true;
1945 }
1946
1947 if (stopBootOnFaultString == "Never")
1948 {
1949 return false;
1950 }
1951
1952 return std::nullopt;
1953}
1954
1955/**
1956 * @brief Sets stopBootOnFault
1957 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001958 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001959 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1960 *
1961 * @return None.
1962 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001963inline void
1964 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1965 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001966{
Ed Tanous62598e32023-07-17 17:06:25 -07001967 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001968
1969 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1970 if (!stopBootEnabled)
1971 {
Ed Tanous62598e32023-07-17 17:06:25 -07001972 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1973 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001974 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001975 "StopBootOnFault");
1976 return;
1977 }
1978
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001979 sdbusplus::asio::setProperty(
1980 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1981 "/xyz/openbmc_project/logging/settings",
1982 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1983 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001984 if (ec)
1985 {
1986 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001987 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001988 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1989 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001990 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001991 return;
1992 }
1993 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001994}
1995
1996/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001997 * @brief Sets automaticRetry (Auto Reboot)
1998 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001999 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05002000 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
2001 *
2002 * @return None.
2003 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002004inline void
2005 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2006 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002007{
Ed Tanous62598e32023-07-17 17:06:25 -07002008 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05002009
2010 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002011 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002012
2013 if (automaticRetryConfig == "Disabled")
2014 {
2015 autoRebootEnabled = false;
2016 }
2017 else if (automaticRetryConfig == "RetryAttempts")
2018 {
2019 autoRebootEnabled = true;
2020 }
2021 else
2022 {
Ed Tanous62598e32023-07-17 17:06:25 -07002023 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2024 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002025 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002026 "AutomaticRetryConfig");
2027 return;
2028 }
2029
George Liu9ae226f2023-06-21 17:56:46 +08002030 sdbusplus::asio::setProperty(
2031 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002032 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002033 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002034 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002035 if (ec)
2036 {
2037 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2038 messages::internalError(asyncResp->res);
2039 return;
2040 }
2041 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002042}
2043
Ed Tanous8d69c662023-06-21 10:29:06 -07002044inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2045{
2046 if (policy == "AlwaysOn")
2047 {
2048 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2049 }
2050 if (policy == "AlwaysOff")
2051 {
2052 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2053 }
2054 if (policy == "LastState")
2055 {
2056 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2057 }
2058 return "";
2059}
2060
Gunnar Mills69f35302020-05-17 16:06:31 -05002061/**
George Liuc6a620f2020-04-10 17:18:11 +08002062 * @brief Sets power restore policy properties.
2063 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002064 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002065 * @param[in] policy power restore policy properties from request.
2066 *
2067 * @return None.
2068 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002069inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002070 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002071 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002072{
Ed Tanous62598e32023-07-17 17:06:25 -07002073 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002074
Ed Tanous8d69c662023-06-21 10:29:06 -07002075 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002076
Ed Tanous8d69c662023-06-21 10:29:06 -07002077 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002078 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002079 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002080 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002081 return;
2082 }
2083
George Liu9ae226f2023-06-21 17:56:46 +08002084 sdbusplus::asio::setProperty(
2085 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002086 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002087 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002088 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002089 if (ec)
2090 {
2091 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2092 messages::internalError(asyncResp->res);
2093 return;
2094 }
2095 });
George Liuc6a620f2020-04-10 17:18:11 +08002096}
2097
AppaRao Pulia6349912019-10-18 17:16:08 +05302098#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2099/**
2100 * @brief Retrieves provisioning status
2101 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002102 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302103 *
2104 * @return None.
2105 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002106inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302107{
Ed Tanous62598e32023-07-17 17:06:25 -07002108 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002109 sdbusplus::asio::getAllProperties(
2110 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2111 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002112 [asyncResp](const boost::system::error_code& ec,
2113 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002114 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002115 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2116 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002117 "#OemComputerSystem.OpenBmc";
2118 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002119
Ed Tanous002d39b2022-05-31 08:59:27 -07002120 if (ec)
2121 {
Ed Tanous62598e32023-07-17 17:06:25 -07002122 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002123 // not an error, don't have to have the interface
2124 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2125 return;
2126 }
2127
2128 const bool* provState = nullptr;
2129 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002130
2131 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002132 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2133 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002134
2135 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002136 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002137 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002138 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002139 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302140
Ed Tanous002d39b2022-05-31 08:59:27 -07002141 if ((provState == nullptr) || (lockState == nullptr))
2142 {
Ed Tanous62598e32023-07-17 17:06:25 -07002143 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002144 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002145 return;
2146 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302147
Ed Tanous002d39b2022-05-31 08:59:27 -07002148 if (*provState == true)
2149 {
2150 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302151 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002152 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302153 }
2154 else
2155 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002156 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302157 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002158 }
2159 else
2160 {
2161 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2162 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002163 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302164}
2165#endif
2166
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302167/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002168 * @brief Translate the PowerMode to a response message.
2169 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002170 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002171 * @param[in] modeValue PowerMode value to be translated
2172 *
2173 * @return None.
2174 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002175inline void
2176 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2177 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002178{
George Liu0fda0f12021-11-16 10:06:17 +08002179 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002180 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002181 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002182 }
George Liu0fda0f12021-11-16 10:06:17 +08002183 else if (
2184 modeValue ==
2185 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002186 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002187 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002188 }
George Liu0fda0f12021-11-16 10:06:17 +08002189 else if (modeValue ==
2190 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002191 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002192 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002193 }
George Liu0fda0f12021-11-16 10:06:17 +08002194 else if (modeValue ==
2195 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002196 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002197 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002198 }
2199 else
2200 {
2201 // Any other values would be invalid
Ed Tanous62598e32023-07-17 17:06:25 -07002202 BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
Ed Tanousac106bf2023-06-07 09:24:59 -07002203 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002204 }
2205}
2206
2207/**
2208 * @brief Retrieves system power mode
2209 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002210 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002211 *
2212 * @return None.
2213 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002214inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002215{
Ed Tanous62598e32023-07-17 17:06:25 -07002216 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002217
2218 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002219 constexpr std::array<std::string_view, 1> interfaces = {
2220 "xyz.openbmc_project.Control.Power.Mode"};
2221 dbus::utility::getSubTree(
2222 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002223 [asyncResp](const boost::system::error_code& ec,
2224 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002225 if (ec)
2226 {
Ed Tanous62598e32023-07-17 17:06:25 -07002227 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2228 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002229 // This is an optional D-Bus object so just return if
2230 // error occurs
2231 return;
2232 }
2233 if (subtree.empty())
2234 {
2235 // As noted above, this is an optional interface so just return
2236 // if there is no instance found
2237 return;
2238 }
2239 if (subtree.size() > 1)
2240 {
2241 // More then one PowerMode object is not supported and is an
2242 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002243 BMCWEB_LOG_DEBUG(
2244 "Found more than 1 system D-Bus Power.Mode objects: {}",
2245 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002246 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002247 return;
2248 }
2249 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2250 {
Ed Tanous62598e32023-07-17 17:06:25 -07002251 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002252 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002253 return;
2254 }
2255 const std::string& path = subtree[0].first;
2256 const std::string& service = subtree[0].second.begin()->first;
2257 if (service.empty())
2258 {
Ed Tanous62598e32023-07-17 17:06:25 -07002259 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002260 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002261 return;
2262 }
2263 // Valid Power Mode object found, now read the current value
2264 sdbusplus::asio::getProperty<std::string>(
2265 *crow::connections::systemBus, service, path,
2266 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002267 [asyncResp](const boost::system::error_code& ec2,
2268 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002269 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002270 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002271 BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002272 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002273 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002274 return;
2275 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002276
Ed Tanousac106bf2023-06-07 09:24:59 -07002277 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002278 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002279
Ed Tanous62598e32023-07-17 17:06:25 -07002280 BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
Ed Tanousac106bf2023-06-07 09:24:59 -07002281 translatePowerMode(asyncResp, pmode);
George Liue99073f2022-12-09 11:06:16 +08002282 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002283 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002284}
2285
2286/**
2287 * @brief Validate the specified mode is valid and return the PowerMode
2288 * name associated with that string
2289 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002290 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002291 * @param[in] modeString String representing the desired PowerMode
2292 *
2293 * @return PowerMode value or empty string if mode is not valid
2294 */
2295inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002296 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002297 const std::string& modeString)
2298{
2299 std::string mode;
2300
2301 if (modeString == "Static")
2302 {
2303 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2304 }
2305 else if (modeString == "MaximumPerformance")
2306 {
George Liu0fda0f12021-11-16 10:06:17 +08002307 mode =
2308 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002309 }
2310 else if (modeString == "PowerSaving")
2311 {
2312 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2313 }
2314 else
2315 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002316 messages::propertyValueNotInList(asyncResp->res, modeString,
2317 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002318 }
2319 return mode;
2320}
2321
2322/**
2323 * @brief Sets system power mode.
2324 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002325 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002326 * @param[in] pmode System power mode from request.
2327 *
2328 * @return None.
2329 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002330inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002331 const std::string& pmode)
2332{
Ed Tanous62598e32023-07-17 17:06:25 -07002333 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002334
Ed Tanousac106bf2023-06-07 09:24:59 -07002335 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002336 if (powerMode.empty())
2337 {
2338 return;
2339 }
2340
2341 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002342 constexpr std::array<std::string_view, 1> interfaces = {
2343 "xyz.openbmc_project.Control.Power.Mode"};
2344 dbus::utility::getSubTree(
2345 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002346 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002347 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002348 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002349 if (ec)
2350 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002351 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002352 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002353 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002354 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002355 return;
2356 }
2357 if (subtree.empty())
2358 {
2359 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002360 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002361 "PowerMode");
2362 return;
2363 }
2364 if (subtree.size() > 1)
2365 {
2366 // More then one PowerMode object is not supported and is an
2367 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002368 BMCWEB_LOG_DEBUG(
2369 "Found more than 1 system D-Bus Power.Mode objects: {}",
2370 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002371 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002372 return;
2373 }
2374 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2375 {
Ed Tanous62598e32023-07-17 17:06:25 -07002376 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002377 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002378 return;
2379 }
2380 const std::string& path = subtree[0].first;
2381 const std::string& service = subtree[0].second.begin()->first;
2382 if (service.empty())
2383 {
Ed Tanous62598e32023-07-17 17:06:25 -07002384 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002385 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002386 return;
2387 }
2388
Ed Tanous62598e32023-07-17 17:06:25 -07002389 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002390
2391 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002392 sdbusplus::asio::setProperty(
2393 *crow::connections::systemBus, service, path,
2394 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002395 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002396 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002397 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002398 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002399 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002400 return;
2401 }
George Liue99073f2022-12-09 11:06:16 +08002402 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002403 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002404}
2405
2406/**
Yong Li51709ff2019-09-30 14:13:04 +08002407 * @brief Translates watchdog timeout action DBUS property value to redfish.
2408 *
2409 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2410 *
2411 * @return Returns as a string, the timeout action in Redfish terms. If
2412 * translation cannot be done, returns an empty string.
2413 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002414inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002415{
2416 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2417 {
2418 return "None";
2419 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002420 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002421 {
2422 return "ResetSystem";
2423 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002424 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002425 {
2426 return "PowerDown";
2427 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002428 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002429 {
2430 return "PowerCycle";
2431 }
2432
2433 return "";
2434}
2435
2436/**
Yong Lic45f0082019-10-10 14:19:01 +08002437 *@brief Translates timeout action from Redfish to DBUS property value.
2438 *
2439 *@param[in] rfAction The timeout action in Redfish.
2440 *
2441 *@return Returns as a string, the time_out action as expected by DBUS.
2442 *If translation cannot be done, returns an empty string.
2443 */
2444
Ed Tanous23a21a12020-07-25 04:45:05 +00002445inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002446{
2447 if (rfAction == "None")
2448 {
2449 return "xyz.openbmc_project.State.Watchdog.Action.None";
2450 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002451 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002452 {
2453 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2454 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002455 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002456 {
2457 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2458 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002459 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002460 {
2461 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2462 }
2463
2464 return "";
2465}
2466
2467/**
Yong Li51709ff2019-09-30 14:13:04 +08002468 * @brief Retrieves host watchdog timer properties over DBUS
2469 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002470 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002471 *
2472 * @return None.
2473 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002474inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002475 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002476{
Ed Tanous62598e32023-07-17 17:06:25 -07002477 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002478 sdbusplus::asio::getAllProperties(
2479 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2480 "/xyz/openbmc_project/watchdog/host0",
2481 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002482 [asyncResp](const boost::system::error_code& ec,
2483 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002484 if (ec)
2485 {
2486 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002487 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002488 return;
2489 }
2490
Ed Tanous62598e32023-07-17 17:06:25 -07002491 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002492
2493 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002494 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002495
2496 // watchdog service is running/enabled
2497 hostWatchdogTimer["Status"]["State"] = "Enabled";
2498
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002499 const bool* enabled = nullptr;
2500 const std::string* expireAction = nullptr;
2501
2502 const bool success = sdbusplus::unpackPropertiesNoThrow(
2503 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2504 "ExpireAction", expireAction);
2505
2506 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002507 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002508 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002509 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002510 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002511
2512 if (enabled != nullptr)
2513 {
2514 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2515 }
2516
2517 if (expireAction != nullptr)
2518 {
2519 std::string action = dbusToRfWatchdogAction(*expireAction);
2520 if (action.empty())
2521 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002522 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002523 return;
2524 }
2525 hostWatchdogTimer["TimeoutAction"] = action;
2526 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002527 });
Yong Li51709ff2019-09-30 14:13:04 +08002528}
2529
2530/**
Yong Lic45f0082019-10-10 14:19:01 +08002531 * @brief Sets Host WatchDog Timer properties.
2532 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002533 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002534 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2535 * RF request.
2536 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2537 *
2538 * @return None.
2539 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002540inline void
2541 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2542 const std::optional<bool> wdtEnable,
2543 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002544{
Ed Tanous62598e32023-07-17 17:06:25 -07002545 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002546
2547 if (wdtTimeOutAction)
2548 {
2549 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2550 // check if TimeOut Action is Valid
2551 if (wdtTimeOutActStr.empty())
2552 {
Ed Tanous62598e32023-07-17 17:06:25 -07002553 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2554 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002555 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002556 "TimeoutAction");
2557 return;
2558 }
2559
George Liu9ae226f2023-06-21 17:56:46 +08002560 sdbusplus::asio::setProperty(
2561 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002562 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002563 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002564 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002565 if (ec)
2566 {
2567 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2568 messages::internalError(asyncResp->res);
2569 return;
2570 }
2571 });
Yong Lic45f0082019-10-10 14:19:01 +08002572 }
2573
2574 if (wdtEnable)
2575 {
George Liu9ae226f2023-06-21 17:56:46 +08002576 sdbusplus::asio::setProperty(
2577 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2578 "/xyz/openbmc_project/watchdog/host0",
2579 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002580 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002581 if (ec)
2582 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002583 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002584 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002585 return;
2586 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002587 });
Yong Lic45f0082019-10-10 14:19:01 +08002588 }
2589}
2590
Chris Cain37bbf982021-09-20 10:53:09 -05002591/**
2592 * @brief Parse the Idle Power Saver properties into json
2593 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002594 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002595 * @param[in] properties IPS property data from DBus.
2596 *
2597 * @return true if successful
2598 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002599inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002600 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002601 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002602{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002603 const bool* enabled = nullptr;
2604 const uint8_t* enterUtilizationPercent = nullptr;
2605 const uint64_t* enterDwellTime = nullptr;
2606 const uint8_t* exitUtilizationPercent = nullptr;
2607 const uint64_t* exitDwellTime = nullptr;
2608
2609 const bool success = sdbusplus::unpackPropertiesNoThrow(
2610 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002611 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2612 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2613 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002614
2615 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002616 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002617 return false;
2618 }
2619
2620 if (enabled != nullptr)
2621 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002622 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002623 }
2624
2625 if (enterUtilizationPercent != nullptr)
2626 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002627 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002628 *enterUtilizationPercent;
2629 }
2630
2631 if (enterDwellTime != nullptr)
2632 {
2633 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002634 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002635 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2636 .count();
2637 }
2638
2639 if (exitUtilizationPercent != nullptr)
2640 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002641 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002642 *exitUtilizationPercent;
2643 }
2644
2645 if (exitDwellTime != nullptr)
2646 {
2647 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002648 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002649 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2650 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002651 }
2652
2653 return true;
2654}
2655
2656/**
2657 * @brief Retrieves host watchdog timer properties over DBUS
2658 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002659 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002660 *
2661 * @return None.
2662 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002663inline void
2664 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002665{
Ed Tanous62598e32023-07-17 17:06:25 -07002666 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002667
2668 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002669 constexpr std::array<std::string_view, 1> interfaces = {
2670 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2671 dbus::utility::getSubTree(
2672 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002673 [asyncResp](const boost::system::error_code& ec,
2674 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002675 if (ec)
2676 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002677 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002678 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2679 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002680 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002681 return;
2682 }
2683 if (subtree.empty())
2684 {
2685 // This is an optional interface so just return
2686 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002687 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002688 return;
2689 }
2690 if (subtree.size() > 1)
2691 {
2692 // More then one PowerIdlePowerSaver object is not supported and
2693 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002694 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2695 "Power.IdlePowerSaver objects: {}",
2696 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002697 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002698 return;
2699 }
2700 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2701 {
Ed Tanous62598e32023-07-17 17:06:25 -07002702 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002703 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002704 return;
2705 }
2706 const std::string& path = subtree[0].first;
2707 const std::string& service = subtree[0].second.begin()->first;
2708 if (service.empty())
2709 {
Ed Tanous62598e32023-07-17 17:06:25 -07002710 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002712 return;
2713 }
2714
2715 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002716 sdbusplus::asio::getAllProperties(
2717 *crow::connections::systemBus, service, path,
2718 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002719 [asyncResp](const boost::system::error_code& ec2,
2720 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002721 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002722 {
Ed Tanous62598e32023-07-17 17:06:25 -07002723 BMCWEB_LOG_ERROR(
2724 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002725 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002726 return;
2727 }
2728
Ed Tanousac106bf2023-06-07 09:24:59 -07002729 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002730 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002731 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002732 return;
2733 }
George Liue99073f2022-12-09 11:06:16 +08002734 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002735 });
Chris Cain37bbf982021-09-20 10:53:09 -05002736
Ed Tanous62598e32023-07-17 17:06:25 -07002737 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002738}
2739
2740/**
2741 * @brief Sets Idle Power Saver properties.
2742 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002743 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002744 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2745 * RF request.
2746 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2747 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2748 * before entering idle state.
2749 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2750 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2751 * before exiting idle state
2752 *
2753 * @return None.
2754 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002755inline void
2756 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2757 const std::optional<bool> ipsEnable,
2758 const std::optional<uint8_t> ipsEnterUtil,
2759 const std::optional<uint64_t> ipsEnterTime,
2760 const std::optional<uint8_t> ipsExitUtil,
2761 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002762{
Ed Tanous62598e32023-07-17 17:06:25 -07002763 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002764
2765 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002766 constexpr std::array<std::string_view, 1> interfaces = {
2767 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2768 dbus::utility::getSubTree(
2769 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002770 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002771 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002772 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002773 if (ec)
2774 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002775 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002776 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2777 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002778 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002779 return;
2780 }
2781 if (subtree.empty())
2782 {
2783 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002784 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002785 "IdlePowerSaver");
2786 return;
2787 }
2788 if (subtree.size() > 1)
2789 {
2790 // More then one PowerIdlePowerSaver object is not supported and
2791 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002792 BMCWEB_LOG_DEBUG(
2793 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2794 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002795 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002796 return;
2797 }
2798 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2799 {
Ed Tanous62598e32023-07-17 17:06:25 -07002800 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002801 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002802 return;
2803 }
2804 const std::string& path = subtree[0].first;
2805 const std::string& service = subtree[0].second.begin()->first;
2806 if (service.empty())
2807 {
Ed Tanous62598e32023-07-17 17:06:25 -07002808 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002809 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002810 return;
2811 }
Chris Cain37bbf982021-09-20 10:53:09 -05002812
Ed Tanous002d39b2022-05-31 08:59:27 -07002813 // Valid Power IdlePowerSaver object found, now set any values that
2814 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002815
Ed Tanous002d39b2022-05-31 08:59:27 -07002816 if (ipsEnable)
2817 {
George Liu9ae226f2023-06-21 17:56:46 +08002818 sdbusplus::asio::setProperty(
2819 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002820 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002821 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002822 if (ec2)
2823 {
2824 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2825 messages::internalError(asyncResp->res);
2826 return;
2827 }
2828 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002829 }
2830 if (ipsEnterUtil)
2831 {
George Liu9ae226f2023-06-21 17:56:46 +08002832 sdbusplus::asio::setProperty(
2833 *crow::connections::systemBus, service, path,
2834 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2835 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002836 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002837 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002838 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002839 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002840 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002841 return;
2842 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002843 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002844 }
2845 if (ipsEnterTime)
2846 {
2847 // Convert from seconds into milliseconds for DBus
2848 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002849 sdbusplus::asio::setProperty(
2850 *crow::connections::systemBus, service, path,
2851 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2852 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002853 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002854 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002855 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002856 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002857 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002858 return;
2859 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002860 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002861 }
2862 if (ipsExitUtil)
2863 {
George Liu9ae226f2023-06-21 17:56:46 +08002864 sdbusplus::asio::setProperty(
2865 *crow::connections::systemBus, service, path,
2866 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2867 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002868 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002869 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002870 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002871 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002872 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002873 return;
2874 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002875 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002876 }
2877 if (ipsExitTime)
2878 {
2879 // Convert from seconds into milliseconds for DBus
2880 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002881 sdbusplus::asio::setProperty(
2882 *crow::connections::systemBus, service, path,
2883 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2884 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002885 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002886 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002887 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002888 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002889 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002890 return;
2891 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002892 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002893 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002894 });
Chris Cain37bbf982021-09-20 10:53:09 -05002895
Ed Tanous62598e32023-07-17 17:06:25 -07002896 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002897}
2898
Ed Tanousc1e219d2023-06-07 10:34:33 -07002899inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002900 crow::App& app, const crow::Request& req,
2901 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2902{
2903 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2904 {
2905 return;
2906 }
2907 asyncResp->res.addHeader(
2908 boost::beast::http::field::link,
2909 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2910}
2911
Ed Tanousc1e219d2023-06-07 10:34:33 -07002912inline void handleComputerSystemCollectionGet(
2913 crow::App& app, const crow::Request& req,
2914 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2915{
2916 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2917 {
2918 return;
2919 }
2920
2921 asyncResp->res.addHeader(
2922 boost::beast::http::field::link,
2923 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2924 asyncResp->res.jsonValue["@odata.type"] =
2925 "#ComputerSystemCollection.ComputerSystemCollection";
2926 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2927 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2928
2929 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2930 ifaceArray = nlohmann::json::array();
2931 if constexpr (bmcwebEnableMultiHost)
2932 {
2933 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2934 // Option currently returns no systems. TBD
2935 return;
2936 }
2937 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2938 nlohmann::json::object_t system;
2939 system["@odata.id"] = "/redfish/v1/Systems/system";
2940 ifaceArray.emplace_back(std::move(system));
2941 sdbusplus::asio::getProperty<std::string>(
2942 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2943 "/xyz/openbmc_project/network/hypervisor",
2944 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2945 [asyncResp](const boost::system::error_code& ec2,
2946 const std::string& /*hostName*/) {
2947 if (ec2)
2948 {
2949 return;
2950 }
2951 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2952 if (val == asyncResp->res.jsonValue.end())
2953 {
Ed Tanous62598e32023-07-17 17:06:25 -07002954 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002955 return;
2956 }
2957 uint64_t* count = val->get_ptr<uint64_t*>();
2958 if (count == nullptr)
2959 {
Ed Tanous62598e32023-07-17 17:06:25 -07002960 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002961 return;
2962 }
2963 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07002964 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002965 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2966 nlohmann::json::object_t hypervisor;
2967 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2968 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05002969 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07002970}
2971
Yong Lic45f0082019-10-10 14:19:01 +08002972/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002973 * Function transceives data with dbus directly.
2974 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002975inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002976{
Patrick Williams89492a12023-05-10 07:51:34 -05002977 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2978 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2979 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002980 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002981 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002982
2983 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002984 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002985 if (ec)
2986 {
Ed Tanous62598e32023-07-17 17:06:25 -07002987 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002988 messages::internalError(asyncResp->res);
2989 return;
2990 }
2991 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05002992 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002993 serviceName, objectPath, interfaceName, method);
2994}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002995
2996/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002997 * Handle error responses from d-bus for system power requests
2998 */
2999inline void handleSystemActionResetError(const boost::system::error_code& ec,
3000 const sdbusplus::message_t& eMsg,
3001 std::string_view resetType,
3002 crow::Response& res)
3003{
3004 if (ec.value() == boost::asio::error::invalid_argument)
3005 {
3006 messages::actionParameterNotSupported(res, resetType, "Reset");
3007 return;
3008 }
3009
3010 if (eMsg.get_error() == nullptr)
3011 {
Ed Tanous62598e32023-07-17 17:06:25 -07003012 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003013 messages::internalError(res);
3014 return;
3015 }
3016 std::string_view errorMessage = eMsg.get_error()->name;
3017
3018 // If operation failed due to BMC not being in Ready state, tell
3019 // user to retry in a bit
3020 if ((errorMessage ==
3021 std::string_view(
3022 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3023 (errorMessage ==
3024 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3025 {
Ed Tanous62598e32023-07-17 17:06:25 -07003026 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003027 messages::serviceTemporarilyUnavailable(res, "10");
3028 return;
3029 }
3030
Ed Tanous62598e32023-07-17 17:06:25 -07003031 BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
3032 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003033 messages::internalError(res);
3034}
3035
Ed Tanousc1e219d2023-06-07 10:34:33 -07003036inline void handleComputerSystemResetActionPost(
3037 crow::App& app, const crow::Request& req,
3038 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3039 const std::string& systemName)
3040{
3041 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3042 {
3043 return;
3044 }
3045 if (systemName != "system")
3046 {
3047 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3048 systemName);
3049 return;
3050 }
3051 if constexpr (bmcwebEnableMultiHost)
3052 {
3053 // Option currently returns no systems. TBD
3054 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3055 systemName);
3056 return;
3057 }
3058 std::string resetType;
3059 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3060 {
3061 return;
3062 }
3063
3064 // Get the command and host vs. chassis
3065 std::string command;
3066 bool hostCommand = true;
3067 if ((resetType == "On") || (resetType == "ForceOn"))
3068 {
3069 command = "xyz.openbmc_project.State.Host.Transition.On";
3070 hostCommand = true;
3071 }
3072 else if (resetType == "ForceOff")
3073 {
3074 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3075 hostCommand = false;
3076 }
3077 else if (resetType == "ForceRestart")
3078 {
3079 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3080 hostCommand = true;
3081 }
3082 else if (resetType == "GracefulShutdown")
3083 {
3084 command = "xyz.openbmc_project.State.Host.Transition.Off";
3085 hostCommand = true;
3086 }
3087 else if (resetType == "GracefulRestart")
3088 {
3089 command =
3090 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3091 hostCommand = true;
3092 }
3093 else if (resetType == "PowerCycle")
3094 {
3095 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3096 hostCommand = true;
3097 }
3098 else if (resetType == "Nmi")
3099 {
3100 doNMI(asyncResp);
3101 return;
3102 }
3103 else
3104 {
3105 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3106 return;
3107 }
3108
3109 if (hostCommand)
3110 {
George Liu9ae226f2023-06-21 17:56:46 +08003111 sdbusplus::asio::setProperty(
3112 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3113 "/xyz/openbmc_project/state/host0",
3114 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3115 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003116 [asyncResp, resetType](const boost::system::error_code& ec,
3117 sdbusplus::message_t& sdbusErrMsg) {
3118 if (ec)
3119 {
3120 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3121 asyncResp->res);
3122
3123 return;
3124 }
3125 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003126 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003127 }
3128 else
3129 {
George Liu9ae226f2023-06-21 17:56:46 +08003130 sdbusplus::asio::setProperty(
3131 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3132 "/xyz/openbmc_project/state/chassis0",
3133 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3134 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003135 [asyncResp, resetType](const boost::system::error_code& ec,
3136 sdbusplus::message_t& sdbusErrMsg) {
3137 if (ec)
3138 {
3139 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3140 asyncResp->res);
3141 return;
3142 }
3143 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003144 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003145 }
3146}
3147
Ed Tanousc1e219d2023-06-07 10:34:33 -07003148inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003149 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003150 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3151 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003152{
3153 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3154 {
3155 return;
3156 }
3157
3158 asyncResp->res.addHeader(
3159 boost::beast::http::field::link,
3160 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3161}
3162
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003163inline void afterPortRequest(
3164 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3165 const boost::system::error_code& ec,
3166 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3167{
3168 if (ec)
3169 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003170 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003171 messages::internalError(asyncResp->res);
3172 return;
3173 }
3174 for (const auto& data : socketData)
3175 {
3176 const std::string& socketPath = get<0>(data);
3177 const std::string& protocolName = get<1>(data);
3178 bool isProtocolEnabled = get<2>(data);
3179 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3180 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3181 // need to retrieve port number for
3182 // obmc-console-ssh service
3183 if (protocolName == "SSH")
3184 {
3185 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003186 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003187 int portNumber) {
3188 if (ec1)
3189 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003190 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003191 messages::internalError(asyncResp->res);
3192 return;
3193 }
3194 nlohmann::json& dataJson1 =
3195 asyncResp->res.jsonValue["SerialConsole"];
3196 dataJson1[protocolName]["Port"] = portNumber;
3197 });
3198 }
3199 }
3200}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003201
3202inline void
3203 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3204 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3205 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003206{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003207 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3208 {
3209 return;
3210 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003211
Ed Tanousc1e219d2023-06-07 10:34:33 -07003212 if constexpr (bmcwebEnableMultiHost)
3213 {
3214 // Option currently returns no systems. TBD
3215 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3216 systemName);
3217 return;
3218 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003219
Ed Tanousc1e219d2023-06-07 10:34:33 -07003220 if (systemName == "hypervisor")
3221 {
3222 handleHypervisorSystemGet(asyncResp);
3223 return;
3224 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003225
Ed Tanousc1e219d2023-06-07 10:34:33 -07003226 if (systemName != "system")
3227 {
3228 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3229 systemName);
3230 return;
3231 }
3232 asyncResp->res.addHeader(
3233 boost::beast::http::field::link,
3234 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3235 asyncResp->res.jsonValue["@odata.type"] =
3236 "#ComputerSystem.v1_16_0.ComputerSystem";
3237 asyncResp->res.jsonValue["Name"] = "system";
3238 asyncResp->res.jsonValue["Id"] = "system";
3239 asyncResp->res.jsonValue["SystemType"] = "Physical";
3240 asyncResp->res.jsonValue["Description"] = "Computer System";
3241 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3242 if constexpr (bmcwebEnableProcMemStatus)
3243 {
3244 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3245 "Disabled";
3246 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3247 "Disabled";
3248 }
3249 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003250 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003251 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003252
Ed Tanousc1e219d2023-06-07 10:34:33 -07003253 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3254 "/redfish/v1/Systems/system/Processors";
3255 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3256 "/redfish/v1/Systems/system/Memory";
3257 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3258 "/redfish/v1/Systems/system/Storage";
3259 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3260 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003261
Ed Tanousc1e219d2023-06-07 10:34:33 -07003262 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3263 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3264 asyncResp->res
3265 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3266 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003267
Ed Tanousc1e219d2023-06-07 10:34:33 -07003268 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3269 "/redfish/v1/Systems/system/LogServices";
3270 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3271 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003272
Ed Tanousc1e219d2023-06-07 10:34:33 -07003273 nlohmann::json::array_t managedBy;
3274 nlohmann::json& manager = managedBy.emplace_back();
3275 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3276 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3277 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3278 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003279
Ed Tanousc1e219d2023-06-07 10:34:33 -07003280 // Fill in SerialConsole info
3281 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3282 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003283
Ed Tanousc1e219d2023-06-07 10:34:33 -07003284 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3285 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3286 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3287 "Press ~. to exit console";
3288 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3289 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003290
3291#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003292 // Fill in GraphicalConsole info
3293 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3294 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3295 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3296 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003297
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003298#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003299
Ed Tanousc1e219d2023-06-07 10:34:33 -07003300 auto health = std::make_shared<HealthPopulate>(asyncResp);
3301 if constexpr (bmcwebEnableHealthPopulate)
3302 {
3303 constexpr std::array<std::string_view, 4> inventoryForSystems{
3304 "xyz.openbmc_project.Inventory.Item.Dimm",
3305 "xyz.openbmc_project.Inventory.Item.Cpu",
3306 "xyz.openbmc_project.Inventory.Item.Drive",
3307 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003308
Ed Tanousc1e219d2023-06-07 10:34:33 -07003309 dbus::utility::getSubTreePaths(
3310 "/", 0, inventoryForSystems,
3311 [health](const boost::system::error_code& ec,
3312 const std::vector<std::string>& resp) {
3313 if (ec)
3314 {
3315 // no inventory
3316 return;
3317 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003318
Ed Tanousc1e219d2023-06-07 10:34:33 -07003319 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003320 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003321 health->populate();
3322 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003323
Ed Tanousc1e219d2023-06-07 10:34:33 -07003324 getMainChassisId(asyncResp,
3325 [](const std::string& chassisId,
3326 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3327 nlohmann::json::array_t chassisArray;
3328 nlohmann::json& chassis = chassisArray.emplace_back();
3329 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3330 chassisId);
3331 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3332 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003333
Ed Tanousc1e219d2023-06-07 10:34:33 -07003334 getLocationIndicatorActive(asyncResp);
3335 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3336 getIndicatorLedState(asyncResp);
3337 getComputerSystem(asyncResp, health);
3338 getHostState(asyncResp);
3339 getBootProperties(asyncResp);
3340 getBootProgress(asyncResp);
3341 getBootProgressLastStateTime(asyncResp);
3342 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3343 getHostWatchdogTimer(asyncResp);
3344 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003345 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003346 getAutomaticRetryPolicy(asyncResp);
3347 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003348#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003349 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003350#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003351 getTrustedModuleRequiredToBoot(asyncResp);
3352 getPowerMode(asyncResp);
3353 getIdlePowerSaver(asyncResp);
3354}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003355
Ed Tanousc1e219d2023-06-07 10:34:33 -07003356inline void handleComputerSystemPatch(
3357 crow::App& app, const crow::Request& req,
3358 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3359 const std::string& systemName)
3360{
3361 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3362 {
3363 return;
3364 }
3365 if constexpr (bmcwebEnableMultiHost)
3366 {
3367 // Option currently returns no systems. TBD
3368 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3369 systemName);
3370 return;
3371 }
3372 if (systemName != "system")
3373 {
3374 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3375 systemName);
3376 return;
3377 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003378
Ed Tanousc1e219d2023-06-07 10:34:33 -07003379 asyncResp->res.addHeader(
3380 boost::beast::http::field::link,
3381 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003382
Ed Tanousc1e219d2023-06-07 10:34:33 -07003383 std::optional<bool> locationIndicatorActive;
3384 std::optional<std::string> indicatorLed;
3385 std::optional<std::string> assetTag;
3386 std::optional<std::string> powerRestorePolicy;
3387 std::optional<std::string> powerMode;
3388 std::optional<bool> wdtEnable;
3389 std::optional<std::string> wdtTimeOutAction;
3390 std::optional<std::string> bootSource;
3391 std::optional<std::string> bootType;
3392 std::optional<std::string> bootEnable;
3393 std::optional<std::string> bootAutomaticRetry;
3394 std::optional<uint32_t> bootAutomaticRetryAttempts;
3395 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003396 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003397 std::optional<bool> ipsEnable;
3398 std::optional<uint8_t> ipsEnterUtil;
3399 std::optional<uint64_t> ipsEnterTime;
3400 std::optional<uint8_t> ipsExitUtil;
3401 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003402
Ed Tanousc1e219d2023-06-07 10:34:33 -07003403 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003404 if (!json_util::readJsonPatch(
3405 req, asyncResp->res,
3406 "IndicatorLED", indicatorLed,
3407 "LocationIndicatorActive", locationIndicatorActive,
3408 "AssetTag", assetTag,
3409 "PowerRestorePolicy", powerRestorePolicy,
3410 "PowerMode", powerMode,
3411 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3412 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3413 "Boot/BootSourceOverrideTarget", bootSource,
3414 "Boot/BootSourceOverrideMode", bootType,
3415 "Boot/BootSourceOverrideEnabled", bootEnable,
3416 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003417 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003418 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003419 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003420 "IdlePowerSaver/Enabled", ipsEnable,
3421 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3422 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3423 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3424 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3425 {
3426 return;
3427 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003428 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003429
Ed Tanousc1e219d2023-06-07 10:34:33 -07003430 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003431
Ed Tanousc1e219d2023-06-07 10:34:33 -07003432 if (assetTag)
3433 {
3434 setAssetTag(asyncResp, *assetTag);
3435 }
James Feistb49ac872019-05-21 15:12:01 -07003436
Ed Tanousc1e219d2023-06-07 10:34:33 -07003437 if (wdtEnable || wdtTimeOutAction)
3438 {
3439 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3440 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003441
Ed Tanousc1e219d2023-06-07 10:34:33 -07003442 if (bootSource || bootType || bootEnable)
3443 {
3444 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3445 }
3446 if (bootAutomaticRetry)
3447 {
3448 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3449 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003450
Ed Tanousc1e219d2023-06-07 10:34:33 -07003451 if (bootAutomaticRetryAttempts)
3452 {
3453 setAutomaticRetryAttempts(asyncResp,
3454 bootAutomaticRetryAttempts.value());
3455 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003456
Ed Tanousc1e219d2023-06-07 10:34:33 -07003457 if (bootTrustedModuleRequired)
3458 {
3459 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3460 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003461
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003462 if (stopBootOnFault)
3463 {
3464 setStopBootOnFault(asyncResp, *stopBootOnFault);
3465 }
3466
Ed Tanousc1e219d2023-06-07 10:34:33 -07003467 if (locationIndicatorActive)
3468 {
3469 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3470 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003471
Ed Tanousc1e219d2023-06-07 10:34:33 -07003472 // TODO (Gunnar): Remove IndicatorLED after enough time has
3473 // passed
3474 if (indicatorLed)
3475 {
3476 setIndicatorLedState(asyncResp, *indicatorLed);
3477 asyncResp->res.addHeader(boost::beast::http::field::warning,
3478 "299 - \"IndicatorLED is deprecated. Use "
3479 "LocationIndicatorActive instead.\"");
3480 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003481
Ed Tanousc1e219d2023-06-07 10:34:33 -07003482 if (powerRestorePolicy)
3483 {
3484 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3485 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003486
Ed Tanousc1e219d2023-06-07 10:34:33 -07003487 if (powerMode)
3488 {
3489 setPowerMode(asyncResp, *powerMode);
3490 }
Chris Cain37bbf982021-09-20 10:53:09 -05003491
Ed Tanousc1e219d2023-06-07 10:34:33 -07003492 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3493 {
3494 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3495 ipsExitUtil, ipsExitTime);
3496 }
3497}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303498
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003499inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003500 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003501 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003502 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003503{
3504 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3505 {
3506 return;
3507 }
3508 asyncResp->res.addHeader(
3509 boost::beast::http::field::link,
3510 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3511}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003512inline void handleSystemCollectionResetActionGet(
3513 crow::App& app, const crow::Request& req,
3514 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3515 const std::string& systemName)
3516{
3517 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3518 {
3519 return;
3520 }
3521 if constexpr (bmcwebEnableMultiHost)
3522 {
3523 // Option currently returns no systems. TBD
3524 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3525 systemName);
3526 return;
3527 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003528
Ed Tanousc1e219d2023-06-07 10:34:33 -07003529 if (systemName == "hypervisor")
3530 {
3531 handleHypervisorResetActionGet(asyncResp);
3532 return;
3533 }
3534
3535 if (systemName != "system")
3536 {
3537 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3538 systemName);
3539 return;
3540 }
3541
3542 asyncResp->res.addHeader(
3543 boost::beast::http::field::link,
3544 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3545
3546 asyncResp->res.jsonValue["@odata.id"] =
3547 "/redfish/v1/Systems/system/ResetActionInfo";
3548 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3549 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3550 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3551
3552 nlohmann::json::array_t parameters;
3553 nlohmann::json::object_t parameter;
3554
3555 parameter["Name"] = "ResetType";
3556 parameter["Required"] = true;
3557 parameter["DataType"] = "String";
3558 nlohmann::json::array_t allowableValues;
3559 allowableValues.emplace_back("On");
3560 allowableValues.emplace_back("ForceOff");
3561 allowableValues.emplace_back("ForceOn");
3562 allowableValues.emplace_back("ForceRestart");
3563 allowableValues.emplace_back("GracefulRestart");
3564 allowableValues.emplace_back("GracefulShutdown");
3565 allowableValues.emplace_back("PowerCycle");
3566 allowableValues.emplace_back("Nmi");
3567 parameter["AllowableValues"] = std::move(allowableValues);
3568 parameters.emplace_back(std::move(parameter));
3569
3570 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3571}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303572/**
3573 * SystemResetActionInfo derived class for delivering Computer Systems
3574 * ResetType AllowableValues using ResetInfo schema.
3575 */
Ed Tanous100afe52023-06-07 13:30:46 -07003576inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303577{
Ed Tanous100afe52023-06-07 13:30:46 -07003578 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3579 .privileges(redfish::privileges::headComputerSystemCollection)
3580 .methods(boost::beast::http::verb::head)(
3581 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3582
3583 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3584 .privileges(redfish::privileges::getComputerSystemCollection)
3585 .methods(boost::beast::http::verb::get)(
3586 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3587
3588 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3589 .privileges(redfish::privileges::headComputerSystem)
3590 .methods(boost::beast::http::verb::head)(
3591 std::bind_front(handleComputerSystemHead, std::ref(app)));
3592
3593 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3594 .privileges(redfish::privileges::getComputerSystem)
3595 .methods(boost::beast::http::verb::get)(
3596 std::bind_front(handleComputerSystemGet, std::ref(app)));
3597
3598 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3599 .privileges(redfish::privileges::patchComputerSystem)
3600 .methods(boost::beast::http::verb::patch)(
3601 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3602
3603 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3604 .privileges(redfish::privileges::postComputerSystem)
3605 .methods(boost::beast::http::verb::post)(std::bind_front(
3606 handleComputerSystemResetActionPost, std::ref(app)));
3607
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003608 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003609 .privileges(redfish::privileges::headActionInfo)
3610 .methods(boost::beast::http::verb::head)(std::bind_front(
3611 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003612 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003613 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003614 .methods(boost::beast::http::verb::get)(std::bind_front(
3615 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003616}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003617} // namespace redfish