blob: 082af6439b9a5169a2d44eb1eba54195ae6cecf1 [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"
Andrew Geissler33e1f122024-02-26 21:10:16 -060024#include "generated/enums/resource.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>
Andrew Geissler33e1f122024-02-26 21:10:16 -060039#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070040#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070041#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040042#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020043#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050044
George Liu7a1dbc42022-12-07 16:03:22 +080045#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060046#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060047#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080048#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080049#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060050#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020051
Ed Tanous1abe55e2018-09-05 08:30:59 -070052namespace redfish
53{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020054
Abhishek Patel5c3e9272021-06-24 10:11:33 -050055const static std::array<std::pair<std::string_view, std::string_view>, 2>
56 protocolToDBusForSystems{
57 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
58
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059/**
60 * @brief Updates the Functional State of DIMMs
61 *
Ed Tanousac106bf2023-06-07 09:24:59 -070062 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050063 * @param[in] dimmState Dimm's Functional state, true/false
64 *
65 * @return None.
66 */
zhanghch058d1b46d2021-04-01 11:18:24 +080067inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070068 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070069 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050070{
Ed Tanous62598e32023-07-17 17:06:25 -070071 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050072
Gunnar Mills4e0453b2020-07-08 14:00:30 -050073 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050074 // Update STATE only if previous State was DISABLED and current Dimm is
75 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070076 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070077 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050078 if (prevMemSummary == "Disabled")
79 {
Ed Tanouse05aec52022-01-25 10:28:56 -080080 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050081 {
Ed Tanousac106bf2023-06-07 09:24:59 -070082 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050083 "Enabled";
84 }
85 }
86}
87
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050088/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089 * @brief Update "ProcessorSummary" "Status" "State" based on
90 * CPU Functional State
91 *
Ed Tanousac106bf2023-06-07 09:24:59 -070092 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050093 * @param[in] cpuFunctionalState is CPU functional true/false
94 *
95 * @return None.
96 */
Ed Tanousac106bf2023-06-07 09:24:59 -070097inline void modifyCpuFunctionalState(
98 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099{
Ed Tanous62598e32023-07-17 17:06:25 -0700100 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101
Ed Tanous02cad962022-06-30 16:50:15 -0700102 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700103 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500104
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500105 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500106 // Update STATE only if previous State was Non_Functional and current CPU is
107 // Functional.
108 if (prevProcState == "Disabled")
109 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800110 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500111 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700112 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113 "Enabled";
114 }
115 }
116}
117
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500118/*
119 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
120 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700121 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500122 * @param[in] cpuPresenceState CPU present or not
123 *
124 * @return None.
125 */
126inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700127 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500128 bool isCpuPresent)
129{
Ed Tanous62598e32023-07-17 17:06:25 -0700130 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500131
132 if (isCpuPresent)
133 {
134 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700135 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500136 auto* procCountPtr =
137 procCount.get_ptr<nlohmann::json::number_integer_t*>();
138 if (procCountPtr != nullptr)
139 {
140 // shouldn't be possible to be nullptr
141 *procCountPtr += 1;
142 }
143 }
144}
145
Ali Ahmed382d6472021-09-03 16:53:53 -0500146inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700147 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500148 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
149 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500150{
Ed Tanous62598e32023-07-17 17:06:25 -0700151 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500152
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200153 // TODO: Get Model
154
155 const uint16_t* coreCount = nullptr;
156
157 const bool success = sdbusplus::unpackPropertiesNoThrow(
158 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
159
160 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500161 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700162 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200163 return;
164 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500165
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200166 if (coreCount != nullptr)
167 {
168 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700169 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200170 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500171
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200172 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500173 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200174 coreCountJson = *coreCount;
175 }
176 else
177 {
178 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500179 }
180 }
181}
182
183/*
184 * @brief Get ProcessorSummary fields
185 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700186 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500187 * @param[in] service dbus service for Cpu Information
188 * @param[in] path dbus path for Cpu
189 *
190 * @return None.
191 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700192inline void
193 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
194 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500195{
Ed Tanousac106bf2023-06-07 09:24:59 -0700196 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
197 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500198 if (ec3)
199 {
Ed Tanous62598e32023-07-17 17:06:25 -0700200 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500201 return;
202 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700203 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500204 };
205
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500206 // Get the Presence of CPU
207 sdbusplus::asio::getProperty<bool>(
208 *crow::connections::systemBus, service, path,
209 "xyz.openbmc_project.Inventory.Item", "Present",
210 std::move(getCpuPresenceState));
211
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200212 sdbusplus::asio::getAllProperties(
213 *crow::connections::systemBus, service, path,
214 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700215 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800216 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800217 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700218 if (ec2)
219 {
Ed Tanous62598e32023-07-17 17:06:25 -0700220 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700221 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700222 return;
223 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700224 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500225 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500226}
227
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500228/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500229 * @brief processMemoryProperties fields
230 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700231 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500232 * @param[in] DBUS properties for memory
233 *
234 * @return None.
235 */
236inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700237 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500238 const dbus::utility::DBusPropertiesMap& properties)
239{
Ed Tanous62598e32023-07-17 17:06:25 -0700240 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500241
242 if (properties.empty())
243 {
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500244 return;
245 }
246
247 const size_t* memorySizeInKB = nullptr;
248
249 const bool success = sdbusplus::unpackPropertiesNoThrow(
250 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
251 memorySizeInKB);
252
253 if (!success)
254 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700255 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500256 return;
257 }
258
259 if (memorySizeInKB != nullptr)
260 {
261 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700262 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500263 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500264 if (preValue == nullptr)
265 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700266 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500267 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500268 }
269 else
270 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700271 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500272 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
273 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500274 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500275 }
276}
277
278/*
279 * @brief Get getMemorySummary fields
280 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700281 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500282 * @param[in] service dbus service for memory Information
283 * @param[in] path dbus path for memory
284 *
285 * @return None.
286 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700287inline void
288 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
289 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500290{
291 sdbusplus::asio::getAllProperties(
292 *crow::connections::systemBus, service, path,
293 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700294 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500295 path](const boost::system::error_code& ec2,
296 const dbus::utility::DBusPropertiesMap& properties) {
297 if (ec2)
298 {
Ed Tanous62598e32023-07-17 17:06:25 -0700299 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700300 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500301 return;
302 }
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500303 processMemoryProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500304 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500305}
306
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500307inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
308 const boost::system::error_code& ec,
309 const dbus::utility::DBusPropertiesMap& properties)
310{
311 if (ec)
312 {
313 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
314 messages::internalError(asyncResp->res);
315 return;
316 }
317 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
318
319 const std::string* uUID = nullptr;
320
321 const bool success = sdbusplus::unpackPropertiesNoThrow(
322 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
323
324 if (!success)
325 {
326 messages::internalError(asyncResp->res);
327 return;
328 }
329
330 if (uUID != nullptr)
331 {
332 std::string valueStr = *uUID;
333 if (valueStr.size() == 32)
334 {
335 valueStr.insert(8, 1, '-');
336 valueStr.insert(13, 1, '-');
337 valueStr.insert(18, 1, '-');
338 valueStr.insert(23, 1, '-');
339 }
340 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
341 asyncResp->res.jsonValue["UUID"] = valueStr;
342 }
343}
344
345inline void
346 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
347 const boost::system::error_code& ec,
348 const dbus::utility::DBusPropertiesMap& propertiesList)
349{
350 if (ec)
351 {
352 // doesn't have to include this
353 // interface
354 return;
355 }
356 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
357
358 const std::string* partNumber = nullptr;
359 const std::string* serialNumber = nullptr;
360 const std::string* manufacturer = nullptr;
361 const std::string* model = nullptr;
362 const std::string* subModel = nullptr;
363
364 const bool success = sdbusplus::unpackPropertiesNoThrow(
365 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
366 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
367 "Model", model, "SubModel", subModel);
368
369 if (!success)
370 {
371 messages::internalError(asyncResp->res);
372 return;
373 }
374
375 if (partNumber != nullptr)
376 {
377 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
378 }
379
380 if (serialNumber != nullptr)
381 {
382 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
383 }
384
385 if (manufacturer != nullptr)
386 {
387 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
388 }
389
390 if (model != nullptr)
391 {
392 asyncResp->res.jsonValue["Model"] = *model;
393 }
394
395 if (subModel != nullptr)
396 {
397 asyncResp->res.jsonValue["SubModel"] = *subModel;
398 }
399
400 // Grab the bios version
401 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
402 "BiosVersion", false);
403}
404
405inline void
406 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
407 const boost::system::error_code& ec,
408 const std::string& value)
409{
410 if (ec)
411 {
412 // doesn't have to include this
413 // interface
414 return;
415 }
416
417 asyncResp->res.jsonValue["AssetTag"] = value;
418}
419
420inline void afterSystemGetSubTree(
421 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500422 const boost::system::error_code& ec,
423 const dbus::utility::MapperGetSubTreeResponse& subtree)
424{
425 if (ec)
426 {
427 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
428 messages::internalError(asyncResp->res);
429 return;
430 }
431 // Iterate over all retrieved ObjectPaths.
432 for (const std::pair<
433 std::string,
434 std::vector<std::pair<std::string, std::vector<std::string>>>>&
435 object : subtree)
436 {
437 const std::string& path = object.first;
438 BMCWEB_LOG_DEBUG("Got path: {}", path);
439 const std::vector<std::pair<std::string, std::vector<std::string>>>&
440 connectionNames = object.second;
441 if (connectionNames.empty())
442 {
443 continue;
444 }
445
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500446 // This is not system, so check if it's cpu, dimm, UUID or
447 // BiosVer
448 for (const auto& connection : connectionNames)
449 {
450 for (const auto& interfaceName : connection.second)
451 {
452 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
453 {
454 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
455
456 getMemorySummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500457 }
458 else if (interfaceName ==
459 "xyz.openbmc_project.Inventory.Item.Cpu")
460 {
461 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
462
463 getProcessorSummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500464 }
465 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
466 {
467 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
468
469 sdbusplus::asio::getAllProperties(
470 *crow::connections::systemBus, connection.first, path,
471 "xyz.openbmc_project.Common.UUID",
472 [asyncResp](const boost::system::error_code& ec3,
473 const dbus::utility::DBusPropertiesMap&
474 properties) {
475 afterGetUUID(asyncResp, ec3, properties);
476 });
477 }
478 else if (interfaceName ==
479 "xyz.openbmc_project.Inventory.Item.System")
480 {
481 sdbusplus::asio::getAllProperties(
482 *crow::connections::systemBus, connection.first, path,
483 "xyz.openbmc_project.Inventory.Decorator.Asset",
484 [asyncResp](const boost::system::error_code& ec3,
485 const dbus::utility::DBusPropertiesMap&
486 properties) {
487 afterGetInventory(asyncResp, ec3, properties);
488 });
489
490 sdbusplus::asio::getProperty<std::string>(
491 *crow::connections::systemBus, connection.first, path,
492 "xyz.openbmc_project.Inventory.Decorator."
493 "AssetTag",
494 "AssetTag",
495 std::bind_front(afterGetAssetTag, asyncResp));
496 }
497 }
498 }
499 }
500}
501
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500502/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700503 * @brief Retrieves computer system properties over dbus
504 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700505 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ed Tanous6c34de42018-08-29 13:37:36 -0700506 *
507 * @return None.
508 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700509inline void
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500510 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700511{
Ed Tanous62598e32023-07-17 17:06:25 -0700512 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800513 constexpr std::array<std::string_view, 5> interfaces = {
514 "xyz.openbmc_project.Inventory.Decorator.Asset",
515 "xyz.openbmc_project.Inventory.Item.Cpu",
516 "xyz.openbmc_project.Inventory.Item.Dimm",
517 "xyz.openbmc_project.Inventory.Item.System",
518 "xyz.openbmc_project.Common.UUID",
519 };
520 dbus::utility::getSubTree(
521 "/xyz/openbmc_project/inventory", 0, interfaces,
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500522 std::bind_front(afterSystemGetSubTree, asyncResp));
Ed Tanous6c34de42018-08-29 13:37:36 -0700523}
524
525/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700526 * @brief Retrieves host state properties over dbus
527 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700528 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700529 *
530 * @return None.
531 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700532inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700533{
Ed Tanous62598e32023-07-17 17:06:25 -0700534 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700535 sdbusplus::asio::getProperty<std::string>(
536 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
537 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
538 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700539 [asyncResp](const boost::system::error_code& ec,
540 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700541 if (ec)
542 {
543 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700544 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700545 // Service not available, no error, just don't return
546 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700547 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700548 return;
549 }
Ed Tanous62598e32023-07-17 17:06:25 -0700550 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700551 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700552 return;
553 }
Ed Tanous66173382018-08-15 18:20:59 -0700554
Ed Tanous62598e32023-07-17 17:06:25 -0700555 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700556 // Verify Host State
557 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
558 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700559 asyncResp->res.jsonValue["PowerState"] = "On";
560 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700561 }
562 else if (hostState ==
563 "xyz.openbmc_project.State.Host.HostState.Quiesced")
564 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700565 asyncResp->res.jsonValue["PowerState"] = "On";
566 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700567 }
568 else if (hostState ==
569 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
570 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700571 asyncResp->res.jsonValue["PowerState"] = "On";
572 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700573 }
574 else if (
575 hostState ==
576 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
577 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700578 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
579 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700580 }
581 else if (hostState ==
582 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
583 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700584 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
585 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700586 }
587 else
588 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700589 asyncResp->res.jsonValue["PowerState"] = "Off";
590 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700591 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500592 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700593}
594
595/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500596 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530597 *
598 * @param[in] dbusSource The boot source in DBUS speak.
599 *
600 * @return Returns as a string, the boot source in Redfish terms. If translation
601 * cannot be done, returns an empty string.
602 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000603inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530604{
605 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
606 {
607 return "None";
608 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700609 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530610 {
611 return "Hdd";
612 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700613 if (dbusSource ==
614 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530615 {
616 return "Cd";
617 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700618 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530619 {
620 return "Pxe";
621 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700622 if (dbusSource ==
623 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700624 {
625 return "Usb";
626 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700627 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530628}
629
630/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300631 * @brief Translates boot type DBUS property value to redfish.
632 *
633 * @param[in] dbusType The boot type in DBUS speak.
634 *
635 * @return Returns as a string, the boot type in Redfish terms. If translation
636 * cannot be done, returns an empty string.
637 */
638inline std::string dbusToRfBootType(const std::string& dbusType)
639{
640 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
641 {
642 return "Legacy";
643 }
644 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
645 {
646 return "UEFI";
647 }
648 return "";
649}
650
651/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500652 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530653 *
654 * @param[in] dbusMode The boot mode in DBUS speak.
655 *
656 * @return Returns as a string, the boot mode in Redfish terms. If translation
657 * cannot be done, returns an empty string.
658 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000659inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530660{
661 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
662 {
663 return "None";
664 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700665 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530666 {
667 return "Diags";
668 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700669 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530670 {
671 return "BiosSetup";
672 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700673 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530674}
675
676/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600677 * @brief Translates boot progress DBUS property value to redfish.
678 *
679 * @param[in] dbusBootProgress The boot progress in DBUS speak.
680 *
681 * @return Returns as a string, the boot progress in Redfish terms. If
682 * translation cannot be done, returns "None".
683 */
684inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
685{
686 // Now convert the D-Bus BootProgress to the appropriate Redfish
687 // enum
688 std::string rfBpLastState = "None";
689 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
690 "ProgressStages.Unspecified")
691 {
692 rfBpLastState = "None";
693 }
694 else if (dbusBootProgress ==
695 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
696 "PrimaryProcInit")
697 {
698 rfBpLastState = "PrimaryProcessorInitializationStarted";
699 }
700 else if (dbusBootProgress ==
701 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
702 "BusInit")
703 {
704 rfBpLastState = "BusInitializationStarted";
705 }
706 else if (dbusBootProgress ==
707 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
708 "MemoryInit")
709 {
710 rfBpLastState = "MemoryInitializationStarted";
711 }
712 else if (dbusBootProgress ==
713 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
714 "SecondaryProcInit")
715 {
716 rfBpLastState = "SecondaryProcessorInitializationStarted";
717 }
718 else if (dbusBootProgress ==
719 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
720 "PCIInit")
721 {
722 rfBpLastState = "PCIResourceConfigStarted";
723 }
724 else if (dbusBootProgress ==
725 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
726 "SystemSetup")
727 {
728 rfBpLastState = "SetupEntered";
729 }
730 else if (dbusBootProgress ==
731 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
732 "SystemInitComplete")
733 {
734 rfBpLastState = "SystemHardwareInitializationComplete";
735 }
736 else if (dbusBootProgress ==
737 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
738 "OSStart")
739 {
740 rfBpLastState = "OSBootStarted";
741 }
742 else if (dbusBootProgress ==
743 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
744 "OSRunning")
745 {
746 rfBpLastState = "OSRunning";
747 }
748 else
749 {
Ed Tanous62598e32023-07-17 17:06:25 -0700750 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600751 // Just return the default
752 }
753 return rfBpLastState;
754}
755
756/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500757 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530758 *
759 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700760 * @param[out] bootSource The DBus source
761 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530762 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700763 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530764 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700765inline int
766 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
767 const std::string& rfSource, std::string& bootSource,
768 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530769{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300770 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
771 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700772
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530773 if (rfSource == "None")
774 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700775 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530776 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700777 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530778 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700779 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
780 }
781 else if (rfSource == "Hdd")
782 {
783 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
784 }
785 else if (rfSource == "Diags")
786 {
787 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
788 }
789 else if (rfSource == "Cd")
790 {
791 bootSource =
792 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
793 }
794 else if (rfSource == "BiosSetup")
795 {
796 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530797 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700798 else if (rfSource == "Usb")
799 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700800 bootSource =
801 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700802 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530803 else
804 {
Ed Tanous62598e32023-07-17 17:06:25 -0700805 BMCWEB_LOG_DEBUG(
806 "Invalid property value for BootSourceOverrideTarget: {}",
807 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700808 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700809 "BootSourceTargetOverride");
810 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530811 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700812 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530813}
Ali Ahmed19817712021-06-29 17:01:52 -0500814
Andrew Geissler978b8802020-11-19 13:36:40 -0600815/**
816 * @brief Retrieves boot progress of the system
817 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700818 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600819 *
820 * @return None.
821 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700822inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600823{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700824 sdbusplus::asio::getProperty<std::string>(
825 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
826 "/xyz/openbmc_project/state/host0",
827 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700828 [asyncResp](const boost::system::error_code& ec,
829 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700830 if (ec)
831 {
832 // BootProgress is an optional object so just do nothing if
833 // not found
834 return;
835 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600836
Ed Tanous62598e32023-07-17 17:06:25 -0700837 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600838
Ed Tanousac106bf2023-06-07 09:24:59 -0700839 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700840 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500841 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600842}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530843
844/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000845 * @brief Retrieves boot progress Last Update of the system
846 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700847 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000848 *
849 * @return None.
850 */
851inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700852 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000853{
854 sdbusplus::asio::getProperty<uint64_t>(
855 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
856 "/xyz/openbmc_project/state/host0",
857 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700858 [asyncResp](const boost::system::error_code& ec,
859 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000860 if (ec)
861 {
Ed Tanous62598e32023-07-17 17:06:25 -0700862 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000863 return;
864 }
865
866 // BootProgressLastUpdate is the last time the BootProgress property
867 // was updated. The time is the Epoch time, number of microseconds
868 // since 1 Jan 1970 00::00::00 UTC."
869 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
870 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
871
872 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700873 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000874 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500875 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000876}
877
878/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300879 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300880 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700881 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300882 *
883 * @return None.
884 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300885
Ed Tanousac106bf2023-06-07 09:24:59 -0700886inline void
887 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300888{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700889 sdbusplus::asio::getProperty<std::string>(
890 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
891 "/xyz/openbmc_project/control/host0/boot",
892 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700893 [asyncResp](const boost::system::error_code& ec,
894 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700895 if (ec)
896 {
897 // not an error, don't have to have the interface
898 return;
899 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300900
Ed Tanous62598e32023-07-17 17:06:25 -0700901 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300902
Ed Tanousac106bf2023-06-07 09:24:59 -0700903 asyncResp->res
904 .jsonValue["Boot"]
905 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700906 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300907
Ed Tanous002d39b2022-05-31 08:59:27 -0700908 auto rfType = dbusToRfBootType(bootType);
909 if (rfType.empty())
910 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700911 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700912 return;
913 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300914
Ed Tanousac106bf2023-06-07 09:24:59 -0700915 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500916 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300917}
918
919/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300920 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530921 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700922 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530923 *
924 * @return None.
925 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300926
Ed Tanousac106bf2023-06-07 09:24:59 -0700927inline void
928 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530929{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700930 sdbusplus::asio::getProperty<std::string>(
931 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
932 "/xyz/openbmc_project/control/host0/boot",
933 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700934 [asyncResp](const boost::system::error_code& ec,
935 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700936 if (ec)
937 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500938 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700939 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700940 return;
941 }
942
Ed Tanous62598e32023-07-17 17:06:25 -0700943 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -0700944
Ed Tanousac106bf2023-06-07 09:24:59 -0700945 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -0700946 .jsonValue["Boot"]
947 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
948 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
949
950 if (bootModeStr !=
951 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
952 {
953 auto rfMode = dbusToRfBootMode(bootModeStr);
954 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530955 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700956 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700957 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530958 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700959 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500960 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530961}
962
963/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300964 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530965 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700966 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530967 *
968 * @return None.
969 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300970
971inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700972 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530973{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700974 sdbusplus::asio::getProperty<std::string>(
975 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
976 "/xyz/openbmc_project/control/host0/boot",
977 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -0700978 [asyncResp](const boost::system::error_code& ec,
979 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700980 if (ec)
981 {
Nan Zhou5ef735c2022-06-22 05:24:21 +0000982 if (ec.value() == boost::asio::error::host_unreachable)
983 {
984 return;
985 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500986 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700987 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700988 return;
989 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530990
Ed Tanous62598e32023-07-17 17:06:25 -0700991 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992
Ed Tanous002d39b2022-05-31 08:59:27 -0700993 auto rfSource = dbusToRfBootSource(bootSourceStr);
994 if (!rfSource.empty())
995 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700996 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
997 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -0700998 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300999
Ed Tanous002d39b2022-05-31 08:59:27 -07001000 // Get BootMode as BootSourceOverrideTarget is constructed
1001 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001002 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001003 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301004}
1005
1006/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001007 * @brief This functions abstracts all the logic behind getting a
1008 * "BootSourceOverrideEnabled" property from an overall boot override enable
1009 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301010 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001011 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301012 *
1013 * @return None.
1014 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301015
Ed Tanousac106bf2023-06-07 09:24:59 -07001016inline void processBootOverrideEnable(
1017 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1018 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001019{
1020 if (!bootOverrideEnableSetting)
1021 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001022 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1023 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001024 return;
1025 }
1026
1027 // If boot source override is enabled, we need to check 'one_time'
1028 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001029 sdbusplus::asio::getProperty<bool>(
1030 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1031 "/xyz/openbmc_project/control/host0/boot/one_time",
1032 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001033 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001034 if (ec)
1035 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001036 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001037 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001038 return;
1039 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301040
Ed Tanous002d39b2022-05-31 08:59:27 -07001041 if (oneTimeSetting)
1042 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001043 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1044 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001045 }
1046 else
1047 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001048 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001049 "Continuous";
1050 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001051 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301052}
1053
1054/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001055 * @brief Retrieves boot override enable over DBUS
1056 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001057 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001058 *
1059 * @return None.
1060 */
1061
1062inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001063 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001064{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001065 sdbusplus::asio::getProperty<bool>(
1066 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1067 "/xyz/openbmc_project/control/host0/boot",
1068 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001069 [asyncResp](const boost::system::error_code& ec,
1070 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001071 if (ec)
1072 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001073 if (ec.value() == boost::asio::error::host_unreachable)
1074 {
1075 return;
1076 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001077 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001078 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001079 return;
1080 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001081
Ed Tanousac106bf2023-06-07 09:24:59 -07001082 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001083 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001084}
1085
1086/**
1087 * @brief Retrieves boot source override properties
1088 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001089 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001090 *
1091 * @return None.
1092 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001093inline void
1094 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001095{
Ed Tanous62598e32023-07-17 17:06:25 -07001096 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001097
Ed Tanousac106bf2023-06-07 09:24:59 -07001098 getBootOverrideSource(asyncResp);
1099 getBootOverrideType(asyncResp);
1100 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001101}
1102
1103/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001104 * @brief Retrieves the Last Reset Time
1105 *
1106 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1107 * and power off. Even though this is the "system" Redfish object look at the
1108 * chassis D-Bus interface for the LastStateChangeTime since this has the
1109 * last power operation time.
1110 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001111 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001112 *
1113 * @return None.
1114 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001115inline void
1116 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001117{
Ed Tanous62598e32023-07-17 17:06:25 -07001118 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001119
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001120 sdbusplus::asio::getProperty<uint64_t>(
1121 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1122 "/xyz/openbmc_project/state/chassis0",
1123 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001124 [asyncResp](const boost::system::error_code& ec,
1125 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001126 if (ec)
1127 {
Ed Tanous62598e32023-07-17 17:06:25 -07001128 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001129 return;
1130 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001131
Ed Tanous002d39b2022-05-31 08:59:27 -07001132 // LastStateChangeTime is epoch time, in milliseconds
1133 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1134 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001135
Ed Tanous002d39b2022-05-31 08:59:27 -07001136 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001137 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001138 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001139 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001140}
1141
1142/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001143 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1144 *
1145 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1146 * corresponding property "AttemptsLeft" that keeps track of the amount of
1147 * automatic retry attempts left are hosted in phosphor-state-manager through
1148 * dbus.
1149 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001150 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001151 *
1152 * @return None.
1153 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001154inline void getAutomaticRebootAttempts(
1155 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001156{
Ed Tanous62598e32023-07-17 17:06:25 -07001157 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001158
1159 sdbusplus::asio::getAllProperties(
1160 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1161 "/xyz/openbmc_project/state/host0",
1162 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001163 [asyncResp{asyncResp}](
1164 const boost::system::error_code& ec,
1165 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001166 if (ec)
1167 {
1168 if (ec.value() != EBADR)
1169 {
Ed Tanous62598e32023-07-17 17:06:25 -07001170 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001171 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001172 }
1173 return;
1174 }
1175
1176 const uint32_t* attemptsLeft = nullptr;
1177 const uint32_t* retryAttempts = nullptr;
1178
1179 const bool success = sdbusplus::unpackPropertiesNoThrow(
1180 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1181 attemptsLeft, "RetryAttempts", retryAttempts);
1182
1183 if (!success)
1184 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001185 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001186 return;
1187 }
1188
1189 if (attemptsLeft != nullptr)
1190 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001191 asyncResp->res
1192 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001193 *attemptsLeft;
1194 }
1195
1196 if (retryAttempts != nullptr)
1197 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001198 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001199 *retryAttempts;
1200 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001201 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001202}
1203
1204/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001205 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1206 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001207 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001208 *
1209 * @return None.
1210 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001211inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001212 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001213{
Ed Tanous62598e32023-07-17 17:06:25 -07001214 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001215
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001216 sdbusplus::asio::getProperty<bool>(
1217 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1218 "/xyz/openbmc_project/control/host0/auto_reboot",
1219 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001220 [asyncResp](const boost::system::error_code& ec,
1221 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001222 if (ec)
1223 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001224 if (ec.value() != EBADR)
1225 {
Ed Tanous62598e32023-07-17 17:06:25 -07001226 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001227 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001228 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001229 return;
1230 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001231
Ed Tanous62598e32023-07-17 17:06:25 -07001232 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001233 if (autoRebootEnabled)
1234 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001235 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001236 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001237 }
1238 else
1239 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001240 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1241 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001242 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001243 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001244
Ed Tanous002d39b2022-05-31 08:59:27 -07001245 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1246 // and RetryAttempts. OpenBMC only supports Disabled and
1247 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001248 asyncResp->res
1249 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1250 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001251 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001252}
1253
1254/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001255 * @brief Sets RetryAttempts
1256 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001257 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001258 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1259 *
1260 *@return None.
1261 */
1262
Ed Tanousac106bf2023-06-07 09:24:59 -07001263inline void setAutomaticRetryAttempts(
1264 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1265 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001266{
Ed Tanous62598e32023-07-17 17:06:25 -07001267 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001268 sdbusplus::asio::setProperty(
1269 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1270 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001271 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001272 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001273 if (ec)
1274 {
1275 BMCWEB_LOG_ERROR(
1276 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1277 messages::internalError(asyncResp->res);
1278 return;
1279 }
1280 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001281}
1282
Ed Tanous8d69c662023-06-21 10:29:06 -07001283inline computer_system::PowerRestorePolicyTypes
1284 redfishPowerRestorePolicyFromDbus(std::string_view value)
1285{
1286 if (value ==
1287 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1288 {
1289 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1290 }
1291 if (value ==
1292 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1293 {
1294 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1295 }
1296 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001297 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001298 {
1299 return computer_system::PowerRestorePolicyTypes::LastState;
1300 }
1301 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1302 {
1303 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1304 }
1305 return computer_system::PowerRestorePolicyTypes::Invalid;
1306}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001307/**
George Liuc6a620f2020-04-10 17:18:11 +08001308 * @brief Retrieves power restore policy over DBUS.
1309 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001310 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001311 *
1312 * @return None.
1313 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001314inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001315 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001316{
Ed Tanous62598e32023-07-17 17:06:25 -07001317 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001318
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001319 sdbusplus::asio::getProperty<std::string>(
1320 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1321 "/xyz/openbmc_project/control/host0/power_restore_policy",
1322 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001323 [asyncResp](const boost::system::error_code& ec,
1324 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001325 if (ec)
1326 {
Ed Tanous62598e32023-07-17 17:06:25 -07001327 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001328 return;
1329 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001330 computer_system::PowerRestorePolicyTypes restore =
1331 redfishPowerRestorePolicyFromDbus(policy);
1332 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001333 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001334 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001335 return;
1336 }
George Liuc6a620f2020-04-10 17:18:11 +08001337
Ed Tanous8d69c662023-06-21 10:29:06 -07001338 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001339 });
George Liuc6a620f2020-04-10 17:18:11 +08001340}
1341
1342/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001343 * @brief Stop Boot On Fault over DBUS.
1344 *
1345 * @param[in] asyncResp Shared pointer for generating response message.
1346 *
1347 * @return None.
1348 */
1349inline void
1350 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1351{
Ed Tanous62598e32023-07-17 17:06:25 -07001352 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001353
1354 sdbusplus::asio::getProperty<bool>(
1355 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1356 "/xyz/openbmc_project/logging/settings",
1357 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1358 [asyncResp](const boost::system::error_code& ec, bool value) {
1359 if (ec)
1360 {
1361 if (ec.value() != EBADR)
1362 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001363 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001364 messages::internalError(asyncResp->res);
1365 }
1366 return;
1367 }
1368
1369 if (value)
1370 {
1371 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1372 }
1373 else
1374 {
1375 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1376 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001377 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001378}
1379
1380/**
Ali Ahmed19817712021-06-29 17:01:52 -05001381 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1382 * TPM is required for booting the host.
1383 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001384 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001385 *
1386 * @return None.
1387 */
1388inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001389 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001390{
Ed Tanous62598e32023-07-17 17:06:25 -07001391 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001392 constexpr std::array<std::string_view, 1> interfaces = {
1393 "xyz.openbmc_project.Control.TPM.Policy"};
1394 dbus::utility::getSubTree(
1395 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001396 [asyncResp](const boost::system::error_code& ec,
1397 const dbus::utility::MapperGetSubTreeResponse& subtree) {
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 on TPM.Policy GetSubTree{}",
1401 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001402 // This is an optional D-Bus object so just return if
1403 // error occurs
1404 return;
1405 }
1406 if (subtree.empty())
1407 {
1408 // As noted above, this is an optional interface so just return
1409 // if there is no instance found
1410 return;
1411 }
1412
1413 /* When there is more than one TPMEnable object... */
1414 if (subtree.size() > 1)
1415 {
Ed Tanous62598e32023-07-17 17:06:25 -07001416 BMCWEB_LOG_DEBUG(
1417 "DBUS response has more than 1 TPM Enable object:{}",
1418 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001419 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001420 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001421 return;
1422 }
1423
1424 // Make sure the Dbus response map has a service and objectPath
1425 // field
1426 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1427 {
Ed Tanous62598e32023-07-17 17:06:25 -07001428 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001429 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001430 return;
1431 }
1432
1433 const std::string& path = subtree[0].first;
1434 const std::string& serv = subtree[0].second.begin()->first;
1435
1436 // Valid TPM Enable object found, now reading the current value
1437 sdbusplus::asio::getProperty<bool>(
1438 *crow::connections::systemBus, serv, path,
1439 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001440 [asyncResp](const boost::system::error_code& ec2,
1441 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001442 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001443 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001444 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001445 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001446 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001447 return;
1448 }
1449
Ed Tanous002d39b2022-05-31 08:59:27 -07001450 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001451 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001452 asyncResp->res
1453 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001454 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001455 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001456 else
1457 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001458 asyncResp->res
1459 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001460 "Disabled";
1461 }
George Liue99073f2022-12-09 11:06:16 +08001462 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001463 });
Ali Ahmed19817712021-06-29 17:01:52 -05001464}
1465
1466/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001467 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1468 * TPM is required for booting the host.
1469 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001470 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001471 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1472 *
1473 * @return None.
1474 */
1475inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001476 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001477{
Ed Tanous62598e32023-07-17 17:06:25 -07001478 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001479 constexpr std::array<std::string_view, 1> interfaces = {
1480 "xyz.openbmc_project.Control.TPM.Policy"};
1481 dbus::utility::getSubTree(
1482 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001483 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001484 tpmRequired](const boost::system::error_code& ec,
1485 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001486 if (ec)
1487 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001488 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001489 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001490 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001491 return;
1492 }
1493 if (subtree.empty())
1494 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001495 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001496 "TrustedModuleRequiredToBoot");
1497 return;
1498 }
1499
1500 /* When there is more than one TPMEnable object... */
1501 if (subtree.size() > 1)
1502 {
Ed Tanous62598e32023-07-17 17:06:25 -07001503 BMCWEB_LOG_DEBUG(
1504 "DBUS response has more than 1 TPM Enable object:{}",
1505 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001506 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001507 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001508 return;
1509 }
1510
1511 // Make sure the Dbus response map has a service and objectPath
1512 // field
1513 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1514 {
Ed Tanous62598e32023-07-17 17:06:25 -07001515 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001516 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001517 return;
1518 }
1519
1520 const std::string& path = subtree[0].first;
1521 const std::string& serv = subtree[0].second.begin()->first;
1522
1523 if (serv.empty())
1524 {
Ed Tanous62598e32023-07-17 17:06:25 -07001525 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001526 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001527 return;
1528 }
1529
1530 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001531 sdbusplus::asio::setProperty(
1532 *crow::connections::systemBus, serv, path,
1533 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001534 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001535 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001536 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001537 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001538 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1539 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001540 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001541 return;
1542 }
Ed Tanous62598e32023-07-17 17:06:25 -07001543 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001544 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001545 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001546}
1547
1548/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301549 * @brief Sets boot properties into DBUS object(s).
1550 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001551 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001552 * @param[in] bootType The boot type to set.
1553 * @return Integer error code.
1554 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001555inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001556 const std::optional<std::string>& bootType)
1557{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001558 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001559
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001560 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001561 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001562 return;
1563 }
1564
1565 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001566 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001567 // Figure out which DBUS interface and property to use
1568 if (*bootType == "Legacy")
1569 {
1570 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1571 }
1572 else if (*bootType == "UEFI")
1573 {
1574 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1575 }
1576 else
1577 {
Ed Tanous62598e32023-07-17 17:06:25 -07001578 BMCWEB_LOG_DEBUG("Invalid property value for "
1579 "BootSourceOverrideMode: {}",
1580 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001581 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001582 "BootSourceOverrideMode");
1583 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001584 }
1585
1586 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001587 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001588
George Liu9ae226f2023-06-21 17:56:46 +08001589 sdbusplus::asio::setProperty(
1590 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1591 "/xyz/openbmc_project/control/host0/boot",
1592 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001593 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001594 if (ec)
1595 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001596 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001597 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001598 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001599 return;
1600 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001601 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001602 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001603 return;
1604 }
Ed Tanous62598e32023-07-17 17:06:25 -07001605 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001606 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001607}
1608
1609/**
1610 * @brief Sets boot properties into DBUS object(s).
1611 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001612 * @param[in] asyncResp Shared pointer for generating response
1613 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001614 * @param[in] bootType The boot type to set.
1615 * @return Integer error code.
1616 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001617inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001618 const std::optional<std::string>& bootEnable)
1619{
1620 if (!bootEnable)
1621 {
1622 return;
1623 }
1624 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001625 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001626
1627 bool bootOverrideEnable = false;
1628 bool bootOverridePersistent = false;
1629 // Figure out which DBUS interface and property to use
1630 if (*bootEnable == "Disabled")
1631 {
1632 bootOverrideEnable = false;
1633 }
1634 else if (*bootEnable == "Once")
1635 {
1636 bootOverrideEnable = true;
1637 bootOverridePersistent = false;
1638 }
1639 else if (*bootEnable == "Continuous")
1640 {
1641 bootOverrideEnable = true;
1642 bootOverridePersistent = true;
1643 }
1644 else
1645 {
Ed Tanous62598e32023-07-17 17:06:25 -07001646 BMCWEB_LOG_DEBUG(
1647 "Invalid property value for BootSourceOverrideEnabled: {}",
1648 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001649 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001650 "BootSourceOverrideEnabled");
1651 return;
1652 }
1653
1654 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001655 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001656
George Liu9ae226f2023-06-21 17:56:46 +08001657 sdbusplus::asio::setProperty(
1658 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1659 "/xyz/openbmc_project/control/host0/boot",
1660 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001661 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001662 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001663 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001664 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001665 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001666 return;
1667 }
Ed Tanous62598e32023-07-17 17:06:25 -07001668 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001669 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001670
1671 if (!bootOverrideEnable)
1672 {
1673 return;
1674 }
1675
1676 // In case boot override is enabled we need to set correct value for the
1677 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001678 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1679 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001680
George Liu9ae226f2023-06-21 17:56:46 +08001681 sdbusplus::asio::setProperty(
1682 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1683 "/xyz/openbmc_project/control/host0/boot/one_time",
1684 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001685 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001686 if (ec)
1687 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001688 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001689 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001690 return;
1691 }
Ed Tanous62598e32023-07-17 17:06:25 -07001692 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001693 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001694}
1695
1696/**
1697 * @brief Sets boot properties into DBUS object(s).
1698 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001699 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301700 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301701 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001702 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301703 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001704inline void
1705 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1706 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301707{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001708 std::string bootSourceStr;
1709 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001710
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001711 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301712 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001713 return;
1714 }
1715
1716 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001717 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001718 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001719 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1720 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001721 {
Ed Tanous62598e32023-07-17 17:06:25 -07001722 BMCWEB_LOG_DEBUG(
1723 "Invalid property value for BootSourceOverrideTarget: {}",
1724 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001725 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001726 "BootSourceTargetOverride");
1727 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001728 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301729
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001730 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001731 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1732 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001733
George Liu9ae226f2023-06-21 17:56:46 +08001734 sdbusplus::asio::setProperty(
1735 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1736 "/xyz/openbmc_project/control/host0/boot",
1737 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001738 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001739 if (ec)
1740 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001741 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001742 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001743 return;
1744 }
Ed Tanous62598e32023-07-17 17:06:25 -07001745 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001746 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001747
George Liu9ae226f2023-06-21 17:56:46 +08001748 sdbusplus::asio::setProperty(
1749 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1750 "/xyz/openbmc_project/control/host0/boot",
1751 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001752 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001753 if (ec)
1754 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001755 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001756 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001757 return;
1758 }
Ed Tanous62598e32023-07-17 17:06:25 -07001759 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001760 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001761}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001762
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001763/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001764 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301765 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001766 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301767 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001768 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301769 * @param[in] bootEnable The boot override enable from incoming RF request.
1770 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001771 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301772 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001773
Ed Tanousac106bf2023-06-07 09:24:59 -07001774inline void
1775 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1776 const std::optional<std::string>& bootSource,
1777 const std::optional<std::string>& bootType,
1778 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301779{
Ed Tanous62598e32023-07-17 17:06:25 -07001780 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301781
Ed Tanousac106bf2023-06-07 09:24:59 -07001782 setBootModeOrSource(asyncResp, bootSource);
1783 setBootType(asyncResp, bootType);
1784 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301785}
1786
George Liuc6a620f2020-04-10 17:18:11 +08001787/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001788 * @brief Sets AssetTag
1789 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001790 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001791 * @param[in] assetTag "AssetTag" from request.
1792 *
1793 * @return None.
1794 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001795inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001796 const std::string& assetTag)
1797{
George Liue99073f2022-12-09 11:06:16 +08001798 constexpr std::array<std::string_view, 1> interfaces = {
1799 "xyz.openbmc_project.Inventory.Item.System"};
1800 dbus::utility::getSubTree(
1801 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001802 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001803 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001804 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001805 if (ec)
1806 {
Ed Tanous62598e32023-07-17 17:06:25 -07001807 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001808 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001809 return;
1810 }
1811 if (subtree.empty())
1812 {
Ed Tanous62598e32023-07-17 17:06:25 -07001813 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001814 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001815 return;
1816 }
1817 // Assume only 1 system D-Bus object
1818 // Throw an error if there is more than 1
1819 if (subtree.size() > 1)
1820 {
Ed Tanous62598e32023-07-17 17:06:25 -07001821 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001822 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001823 return;
1824 }
1825 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1826 {
Ed Tanous62598e32023-07-17 17:06:25 -07001827 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001828 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001829 return;
1830 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001831
Ed Tanous002d39b2022-05-31 08:59:27 -07001832 const std::string& path = subtree[0].first;
1833 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001834
Ed Tanous002d39b2022-05-31 08:59:27 -07001835 if (service.empty())
1836 {
Ed Tanous62598e32023-07-17 17:06:25 -07001837 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001838 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001839 return;
1840 }
1841
George Liu9ae226f2023-06-21 17:56:46 +08001842 sdbusplus::asio::setProperty(
1843 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001844 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001845 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001846 if (ec2)
1847 {
1848 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1849 ec2);
1850 messages::internalError(asyncResp->res);
1851 return;
1852 }
George Liue99073f2022-12-09 11:06:16 +08001853 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001854 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001855}
1856
1857/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001858 * @brief Validate the specified stopBootOnFault is valid and return the
1859 * stopBootOnFault name associated with that string
1860 *
1861 * @param[in] stopBootOnFaultString String representing the desired
1862 * stopBootOnFault
1863 *
1864 * @return stopBootOnFault value or empty if incoming value is not valid
1865 */
1866inline std::optional<bool>
1867 validstopBootOnFault(const std::string& stopBootOnFaultString)
1868{
1869 if (stopBootOnFaultString == "AnyFault")
1870 {
1871 return true;
1872 }
1873
1874 if (stopBootOnFaultString == "Never")
1875 {
1876 return false;
1877 }
1878
1879 return std::nullopt;
1880}
1881
1882/**
1883 * @brief Sets stopBootOnFault
1884 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001885 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001886 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1887 *
1888 * @return None.
1889 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001890inline void
1891 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1892 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001893{
Ed Tanous62598e32023-07-17 17:06:25 -07001894 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001895
1896 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1897 if (!stopBootEnabled)
1898 {
Ed Tanous62598e32023-07-17 17:06:25 -07001899 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1900 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001901 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001902 "StopBootOnFault");
1903 return;
1904 }
1905
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001906 sdbusplus::asio::setProperty(
1907 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1908 "/xyz/openbmc_project/logging/settings",
1909 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1910 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001911 if (ec)
1912 {
1913 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001914 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001915 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1916 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001917 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001918 return;
1919 }
1920 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001921}
1922
1923/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001924 * @brief Sets automaticRetry (Auto Reboot)
1925 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001926 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001927 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1928 *
1929 * @return None.
1930 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001931inline void
1932 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1933 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001934{
Ed Tanous62598e32023-07-17 17:06:25 -07001935 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001936
1937 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001938 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001939
1940 if (automaticRetryConfig == "Disabled")
1941 {
1942 autoRebootEnabled = false;
1943 }
1944 else if (automaticRetryConfig == "RetryAttempts")
1945 {
1946 autoRebootEnabled = true;
1947 }
1948 else
1949 {
Ed Tanous62598e32023-07-17 17:06:25 -07001950 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
1951 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07001952 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001953 "AutomaticRetryConfig");
1954 return;
1955 }
1956
George Liu9ae226f2023-06-21 17:56:46 +08001957 sdbusplus::asio::setProperty(
1958 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05001959 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05001960 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08001961 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001962 if (ec)
1963 {
1964 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1965 messages::internalError(asyncResp->res);
1966 return;
1967 }
1968 });
Gunnar Mills69f35302020-05-17 16:06:31 -05001969}
1970
Ed Tanous8d69c662023-06-21 10:29:06 -07001971inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1972{
1973 if (policy == "AlwaysOn")
1974 {
1975 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1976 }
1977 if (policy == "AlwaysOff")
1978 {
1979 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1980 }
1981 if (policy == "LastState")
1982 {
1983 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1984 }
1985 return "";
1986}
1987
Gunnar Mills69f35302020-05-17 16:06:31 -05001988/**
George Liuc6a620f2020-04-10 17:18:11 +08001989 * @brief Sets power restore policy properties.
1990 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001991 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001992 * @param[in] policy power restore policy properties from request.
1993 *
1994 * @return None.
1995 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001996inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001997 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001998 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001999{
Ed Tanous62598e32023-07-17 17:06:25 -07002000 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002001
Ed Tanous8d69c662023-06-21 10:29:06 -07002002 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002003
Ed Tanous8d69c662023-06-21 10:29:06 -07002004 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002005 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002006 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002007 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002008 return;
2009 }
2010
George Liu9ae226f2023-06-21 17:56:46 +08002011 sdbusplus::asio::setProperty(
2012 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002013 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002014 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002015 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002016 if (ec)
2017 {
2018 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2019 messages::internalError(asyncResp->res);
2020 return;
2021 }
2022 });
George Liuc6a620f2020-04-10 17:18:11 +08002023}
2024
AppaRao Pulia6349912019-10-18 17:16:08 +05302025#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2026/**
2027 * @brief Retrieves provisioning status
2028 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002029 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302030 *
2031 * @return None.
2032 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002033inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302034{
Ed Tanous62598e32023-07-17 17:06:25 -07002035 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002036 sdbusplus::asio::getAllProperties(
2037 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2038 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002039 [asyncResp](const boost::system::error_code& ec,
2040 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002041 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002042 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2043 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002044 "#OemComputerSystem.OpenBmc";
2045 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002046
Ed Tanous002d39b2022-05-31 08:59:27 -07002047 if (ec)
2048 {
Ed Tanous62598e32023-07-17 17:06:25 -07002049 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002050 // not an error, don't have to have the interface
2051 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2052 return;
2053 }
2054
2055 const bool* provState = nullptr;
2056 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002057
2058 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002059 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2060 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002061
2062 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002063 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002064 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002065 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002066 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302067
Ed Tanous002d39b2022-05-31 08:59:27 -07002068 if ((provState == nullptr) || (lockState == nullptr))
2069 {
Ed Tanous62598e32023-07-17 17:06:25 -07002070 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002071 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002072 return;
2073 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302074
Ed Tanous002d39b2022-05-31 08:59:27 -07002075 if (*provState == true)
2076 {
2077 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302078 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002079 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302080 }
2081 else
2082 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002083 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302084 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002085 }
2086 else
2087 {
2088 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2089 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002090 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302091}
2092#endif
2093
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302094/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002095 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002096 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002097 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002098 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002099 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002100 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002101inline computer_system::PowerMode
2102 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002103{
Chris Cainb6655102024-02-01 14:35:33 -06002104 using PowerMode = computer_system::PowerMode;
2105
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002106 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002107 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002108 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002109 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002110 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002111 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002112 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002113 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002114 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002115 if (modeString ==
2116 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002117 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002118 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002119 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002120 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002121 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2122 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002123 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002124 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002125 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002126 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2127 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002128 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002129 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002130 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002131 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2132 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002133 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002134 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002135 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002136 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002137 return PowerMode::OEM;
2138 }
2139 // Any other values would be invalid
2140 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2141 return PowerMode::Invalid;
2142}
2143
2144inline void
2145 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2146 const boost::system::error_code& ec,
2147 const dbus::utility::DBusPropertiesMap& properties)
2148{
2149 if (ec)
2150 {
2151 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2152 messages::internalError(asyncResp->res);
2153 return;
2154 }
2155
2156 std::string powerMode;
2157 const std::vector<std::string>* allowedModes = nullptr;
2158 const bool success = sdbusplus::unpackPropertiesNoThrow(
2159 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2160 "AllowedPowerModes", allowedModes);
2161
2162 if (!success)
2163 {
2164 messages::internalError(asyncResp->res);
2165 return;
2166 }
2167
2168 nlohmann::json::array_t modeList;
2169 if (allowedModes == nullptr)
2170 {
2171 modeList.emplace_back("Static");
2172 modeList.emplace_back("MaximumPerformance");
2173 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002174 }
2175 else
2176 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002177 for (const auto& aMode : *allowedModes)
2178 {
2179 computer_system::PowerMode modeValue =
2180 translatePowerModeString(aMode);
2181 if (modeValue == computer_system::PowerMode::Invalid)
2182 {
2183 messages::internalError(asyncResp->res);
2184 continue;
2185 }
2186 modeList.emplace_back(modeValue);
2187 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002188 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002189 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002190
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002191 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2192 const computer_system::PowerMode modeValue =
2193 translatePowerModeString(powerMode);
2194 if (modeValue == computer_system::PowerMode::Invalid)
2195 {
2196 messages::internalError(asyncResp->res);
2197 return;
2198 }
2199 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2200}
Chris Cain3a2d04242021-05-28 16:57:10 -05002201/**
2202 * @brief Retrieves system power mode
2203 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002204 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002205 *
2206 * @return None.
2207 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002208inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002209{
Ed Tanous62598e32023-07-17 17:06:25 -07002210 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002211
2212 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002213 constexpr std::array<std::string_view, 1> interfaces = {
2214 "xyz.openbmc_project.Control.Power.Mode"};
2215 dbus::utility::getSubTree(
2216 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002217 [asyncResp](const boost::system::error_code& ec,
2218 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002219 if (ec)
2220 {
Ed Tanous62598e32023-07-17 17:06:25 -07002221 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2222 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002223 // This is an optional D-Bus object so just return if
2224 // error occurs
2225 return;
2226 }
2227 if (subtree.empty())
2228 {
2229 // As noted above, this is an optional interface so just return
2230 // if there is no instance found
2231 return;
2232 }
2233 if (subtree.size() > 1)
2234 {
2235 // More then one PowerMode object is not supported and is an
2236 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002237 BMCWEB_LOG_DEBUG(
2238 "Found more than 1 system D-Bus Power.Mode objects: {}",
2239 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002240 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002241 return;
2242 }
2243 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2244 {
Ed Tanous62598e32023-07-17 17:06:25 -07002245 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002246 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002247 return;
2248 }
2249 const std::string& path = subtree[0].first;
2250 const std::string& service = subtree[0].second.begin()->first;
2251 if (service.empty())
2252 {
Ed Tanous62598e32023-07-17 17:06:25 -07002253 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002254 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002255 return;
2256 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002257
2258 // Valid Power Mode object found, now read the mode properties
2259 sdbusplus::asio::getAllProperties(
Ed Tanous002d39b2022-05-31 08:59:27 -07002260 *crow::connections::systemBus, service, path,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002261 "xyz.openbmc_project.Control.Power.Mode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002262 [asyncResp](const boost::system::error_code& ec2,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002263 const dbus::utility::DBusPropertiesMap& properties) {
2264 afterGetPowerMode(asyncResp, ec2, properties);
George Liue99073f2022-12-09 11:06:16 +08002265 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002266 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002267}
2268
2269/**
2270 * @brief Validate the specified mode is valid and return the PowerMode
2271 * name associated with that string
2272 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002273 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002274 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002275 *
2276 * @return PowerMode value or empty string if mode is not valid
2277 */
2278inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002279 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002280 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002281{
Chris Cainb6655102024-02-01 14:35:33 -06002282 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002283 std::string mode;
2284
Chris Cainb6655102024-02-01 14:35:33 -06002285 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002286 {
2287 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2288 }
Chris Cainb6655102024-02-01 14:35:33 -06002289 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002290 {
George Liu0fda0f12021-11-16 10:06:17 +08002291 mode =
2292 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002293 }
Chris Cainb6655102024-02-01 14:35:33 -06002294 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002295 {
2296 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2297 }
Chris Cainb6655102024-02-01 14:35:33 -06002298 else if (modeValue == PowerMode::BalancedPerformance)
2299 {
2300 mode =
2301 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2302 }
2303 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2304 {
2305 mode =
2306 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2307 }
2308 else if (modeValue == PowerMode::EfficiencyFavorPower)
2309 {
2310 mode =
2311 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2312 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002313 else
2314 {
Chris Cainb6655102024-02-01 14:35:33 -06002315 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002316 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002317 }
2318 return mode;
2319}
2320
2321/**
2322 * @brief Sets system power mode.
2323 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002324 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002325 * @param[in] pmode System power mode from request.
2326 *
2327 * @return None.
2328 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002329inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002330 const std::string& pmode)
2331{
Ed Tanous62598e32023-07-17 17:06:25 -07002332 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002333
Ed Tanousac106bf2023-06-07 09:24:59 -07002334 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002335 if (powerMode.empty())
2336 {
2337 return;
2338 }
2339
2340 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002341 constexpr std::array<std::string_view, 1> interfaces = {
2342 "xyz.openbmc_project.Control.Power.Mode"};
2343 dbus::utility::getSubTree(
2344 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002345 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002346 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002347 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002348 if (ec)
2349 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002350 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002351 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002352 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002353 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002354 return;
2355 }
2356 if (subtree.empty())
2357 {
2358 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002359 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002360 "PowerMode");
2361 return;
2362 }
2363 if (subtree.size() > 1)
2364 {
2365 // More then one PowerMode object is not supported and is an
2366 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002367 BMCWEB_LOG_DEBUG(
2368 "Found more than 1 system D-Bus Power.Mode objects: {}",
2369 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002370 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002371 return;
2372 }
2373 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2374 {
Ed Tanous62598e32023-07-17 17:06:25 -07002375 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002376 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002377 return;
2378 }
2379 const std::string& path = subtree[0].first;
2380 const std::string& service = subtree[0].second.begin()->first;
2381 if (service.empty())
2382 {
Ed Tanous62598e32023-07-17 17:06:25 -07002383 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002384 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002385 return;
2386 }
2387
Ed Tanous62598e32023-07-17 17:06:25 -07002388 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002389
2390 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002391 sdbusplus::asio::setProperty(
2392 *crow::connections::systemBus, service, path,
2393 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002394 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002395 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002396 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002397 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002398 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002399 return;
2400 }
George Liue99073f2022-12-09 11:06:16 +08002401 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002402 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002403}
2404
2405/**
Yong Li51709ff2019-09-30 14:13:04 +08002406 * @brief Translates watchdog timeout action DBUS property value to redfish.
2407 *
2408 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2409 *
2410 * @return Returns as a string, the timeout action in Redfish terms. If
2411 * translation cannot be done, returns an empty string.
2412 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002413inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002414{
2415 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2416 {
2417 return "None";
2418 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002419 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002420 {
2421 return "ResetSystem";
2422 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002423 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002424 {
2425 return "PowerDown";
2426 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002427 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002428 {
2429 return "PowerCycle";
2430 }
2431
2432 return "";
2433}
2434
2435/**
Yong Lic45f0082019-10-10 14:19:01 +08002436 *@brief Translates timeout action from Redfish to DBUS property value.
2437 *
2438 *@param[in] rfAction The timeout action in Redfish.
2439 *
2440 *@return Returns as a string, the time_out action as expected by DBUS.
2441 *If translation cannot be done, returns an empty string.
2442 */
2443
Ed Tanous23a21a12020-07-25 04:45:05 +00002444inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002445{
2446 if (rfAction == "None")
2447 {
2448 return "xyz.openbmc_project.State.Watchdog.Action.None";
2449 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002450 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002451 {
2452 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2453 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002454 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002455 {
2456 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2457 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002458 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002459 {
2460 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2461 }
2462
2463 return "";
2464}
2465
2466/**
Yong Li51709ff2019-09-30 14:13:04 +08002467 * @brief Retrieves host watchdog timer properties over DBUS
2468 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002469 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002470 *
2471 * @return None.
2472 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002473inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002474 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002475{
Ed Tanous62598e32023-07-17 17:06:25 -07002476 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002477 sdbusplus::asio::getAllProperties(
2478 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2479 "/xyz/openbmc_project/watchdog/host0",
2480 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002481 [asyncResp](const boost::system::error_code& ec,
2482 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002483 if (ec)
2484 {
2485 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002486 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002487 return;
2488 }
2489
Ed Tanous62598e32023-07-17 17:06:25 -07002490 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002491
2492 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002493 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002494
2495 // watchdog service is running/enabled
2496 hostWatchdogTimer["Status"]["State"] = "Enabled";
2497
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002498 const bool* enabled = nullptr;
2499 const std::string* expireAction = nullptr;
2500
2501 const bool success = sdbusplus::unpackPropertiesNoThrow(
2502 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2503 "ExpireAction", expireAction);
2504
2505 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002506 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002507 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002508 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002509 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002510
2511 if (enabled != nullptr)
2512 {
2513 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2514 }
2515
2516 if (expireAction != nullptr)
2517 {
2518 std::string action = dbusToRfWatchdogAction(*expireAction);
2519 if (action.empty())
2520 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002521 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002522 return;
2523 }
2524 hostWatchdogTimer["TimeoutAction"] = action;
2525 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002526 });
Yong Li51709ff2019-09-30 14:13:04 +08002527}
2528
2529/**
Yong Lic45f0082019-10-10 14:19:01 +08002530 * @brief Sets Host WatchDog Timer properties.
2531 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002532 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002533 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2534 * RF request.
2535 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2536 *
2537 * @return None.
2538 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002539inline void
2540 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2541 const std::optional<bool> wdtEnable,
2542 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002543{
Ed Tanous62598e32023-07-17 17:06:25 -07002544 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002545
2546 if (wdtTimeOutAction)
2547 {
2548 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2549 // check if TimeOut Action is Valid
2550 if (wdtTimeOutActStr.empty())
2551 {
Ed Tanous62598e32023-07-17 17:06:25 -07002552 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2553 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002554 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002555 "TimeoutAction");
2556 return;
2557 }
2558
George Liu9ae226f2023-06-21 17:56:46 +08002559 sdbusplus::asio::setProperty(
2560 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002561 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002562 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002563 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002564 if (ec)
2565 {
2566 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2567 messages::internalError(asyncResp->res);
2568 return;
2569 }
2570 });
Yong Lic45f0082019-10-10 14:19:01 +08002571 }
2572
2573 if (wdtEnable)
2574 {
George Liu9ae226f2023-06-21 17:56:46 +08002575 sdbusplus::asio::setProperty(
2576 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2577 "/xyz/openbmc_project/watchdog/host0",
2578 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002579 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002580 if (ec)
2581 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002582 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002583 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002584 return;
2585 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002586 });
Yong Lic45f0082019-10-10 14:19:01 +08002587 }
2588}
2589
Chris Cain37bbf982021-09-20 10:53:09 -05002590/**
2591 * @brief Parse the Idle Power Saver properties into json
2592 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002593 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002594 * @param[in] properties IPS property data from DBus.
2595 *
2596 * @return true if successful
2597 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002598inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002599 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002600 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002601{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002602 const bool* enabled = nullptr;
2603 const uint8_t* enterUtilizationPercent = nullptr;
2604 const uint64_t* enterDwellTime = nullptr;
2605 const uint8_t* exitUtilizationPercent = nullptr;
2606 const uint64_t* exitDwellTime = nullptr;
2607
2608 const bool success = sdbusplus::unpackPropertiesNoThrow(
2609 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002610 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2611 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2612 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002613
2614 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002615 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002616 return false;
2617 }
2618
2619 if (enabled != nullptr)
2620 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002621 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002622 }
2623
2624 if (enterUtilizationPercent != nullptr)
2625 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002626 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002627 *enterUtilizationPercent;
2628 }
2629
2630 if (enterDwellTime != nullptr)
2631 {
2632 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002633 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002634 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2635 .count();
2636 }
2637
2638 if (exitUtilizationPercent != nullptr)
2639 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002640 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002641 *exitUtilizationPercent;
2642 }
2643
2644 if (exitDwellTime != nullptr)
2645 {
2646 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002647 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002648 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2649 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002650 }
2651
2652 return true;
2653}
2654
2655/**
2656 * @brief Retrieves host watchdog timer properties over DBUS
2657 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002658 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002659 *
2660 * @return None.
2661 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002662inline void
2663 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002664{
Ed Tanous62598e32023-07-17 17:06:25 -07002665 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002666
2667 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002668 constexpr std::array<std::string_view, 1> interfaces = {
2669 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2670 dbus::utility::getSubTree(
2671 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002672 [asyncResp](const boost::system::error_code& ec,
2673 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002674 if (ec)
2675 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002676 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002677 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2678 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002679 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002680 return;
2681 }
2682 if (subtree.empty())
2683 {
2684 // This is an optional interface so just return
2685 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002686 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002687 return;
2688 }
2689 if (subtree.size() > 1)
2690 {
2691 // More then one PowerIdlePowerSaver object is not supported and
2692 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002693 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2694 "Power.IdlePowerSaver objects: {}",
2695 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002696 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002697 return;
2698 }
2699 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2700 {
Ed Tanous62598e32023-07-17 17:06:25 -07002701 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002702 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002703 return;
2704 }
2705 const std::string& path = subtree[0].first;
2706 const std::string& service = subtree[0].second.begin()->first;
2707 if (service.empty())
2708 {
Ed Tanous62598e32023-07-17 17:06:25 -07002709 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002710 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002711 return;
2712 }
2713
2714 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002715 sdbusplus::asio::getAllProperties(
2716 *crow::connections::systemBus, service, path,
2717 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002718 [asyncResp](const boost::system::error_code& ec2,
2719 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002720 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002721 {
Ed Tanous62598e32023-07-17 17:06:25 -07002722 BMCWEB_LOG_ERROR(
2723 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002724 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002725 return;
2726 }
2727
Ed Tanousac106bf2023-06-07 09:24:59 -07002728 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002729 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002730 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002731 return;
2732 }
George Liue99073f2022-12-09 11:06:16 +08002733 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002734 });
Chris Cain37bbf982021-09-20 10:53:09 -05002735
Ed Tanous62598e32023-07-17 17:06:25 -07002736 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002737}
2738
2739/**
2740 * @brief Sets Idle Power Saver properties.
2741 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002742 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002743 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2744 * RF request.
2745 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2746 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2747 * before entering idle state.
2748 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2749 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2750 * before exiting idle state
2751 *
2752 * @return None.
2753 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002754inline void
2755 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2756 const std::optional<bool> ipsEnable,
2757 const std::optional<uint8_t> ipsEnterUtil,
2758 const std::optional<uint64_t> ipsEnterTime,
2759 const std::optional<uint8_t> ipsExitUtil,
2760 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002761{
Ed Tanous62598e32023-07-17 17:06:25 -07002762 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002763
2764 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002765 constexpr std::array<std::string_view, 1> interfaces = {
2766 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2767 dbus::utility::getSubTree(
2768 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002769 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002770 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002771 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002772 if (ec)
2773 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002774 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002775 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2776 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002777 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002778 return;
2779 }
2780 if (subtree.empty())
2781 {
2782 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002783 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002784 "IdlePowerSaver");
2785 return;
2786 }
2787 if (subtree.size() > 1)
2788 {
2789 // More then one PowerIdlePowerSaver object is not supported and
2790 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002791 BMCWEB_LOG_DEBUG(
2792 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2793 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002794 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002795 return;
2796 }
2797 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2798 {
Ed Tanous62598e32023-07-17 17:06:25 -07002799 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002800 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002801 return;
2802 }
2803 const std::string& path = subtree[0].first;
2804 const std::string& service = subtree[0].second.begin()->first;
2805 if (service.empty())
2806 {
Ed Tanous62598e32023-07-17 17:06:25 -07002807 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002808 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002809 return;
2810 }
Chris Cain37bbf982021-09-20 10:53:09 -05002811
Ed Tanous002d39b2022-05-31 08:59:27 -07002812 // Valid Power IdlePowerSaver object found, now set any values that
2813 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002814
Ed Tanous002d39b2022-05-31 08:59:27 -07002815 if (ipsEnable)
2816 {
George Liu9ae226f2023-06-21 17:56:46 +08002817 sdbusplus::asio::setProperty(
2818 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002819 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002820 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002821 if (ec2)
2822 {
2823 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2824 messages::internalError(asyncResp->res);
2825 return;
2826 }
2827 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002828 }
2829 if (ipsEnterUtil)
2830 {
George Liu9ae226f2023-06-21 17:56:46 +08002831 sdbusplus::asio::setProperty(
2832 *crow::connections::systemBus, service, path,
2833 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2834 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002835 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002836 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002837 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002838 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002839 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002840 return;
2841 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002842 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002843 }
2844 if (ipsEnterTime)
2845 {
2846 // Convert from seconds into milliseconds for DBus
2847 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002848 sdbusplus::asio::setProperty(
2849 *crow::connections::systemBus, service, path,
2850 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2851 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002852 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002853 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002854 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002855 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002856 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002857 return;
2858 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002859 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002860 }
2861 if (ipsExitUtil)
2862 {
George Liu9ae226f2023-06-21 17:56:46 +08002863 sdbusplus::asio::setProperty(
2864 *crow::connections::systemBus, service, path,
2865 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2866 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002867 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002868 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002869 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002870 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002871 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002872 return;
2873 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002874 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002875 }
2876 if (ipsExitTime)
2877 {
2878 // Convert from seconds into milliseconds for DBus
2879 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002880 sdbusplus::asio::setProperty(
2881 *crow::connections::systemBus, service, path,
2882 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2883 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002884 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002885 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002886 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002887 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002888 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002889 return;
2890 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002891 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002892 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002893 });
Chris Cain37bbf982021-09-20 10:53:09 -05002894
Ed Tanous62598e32023-07-17 17:06:25 -07002895 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002896}
2897
Ed Tanousc1e219d2023-06-07 10:34:33 -07002898inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002899 crow::App& app, const crow::Request& req,
2900 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2901{
2902 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2903 {
2904 return;
2905 }
2906 asyncResp->res.addHeader(
2907 boost::beast::http::field::link,
2908 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2909}
2910
Ed Tanousc1e219d2023-06-07 10:34:33 -07002911inline void handleComputerSystemCollectionGet(
2912 crow::App& app, const crow::Request& req,
2913 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2914{
2915 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2916 {
2917 return;
2918 }
2919
2920 asyncResp->res.addHeader(
2921 boost::beast::http::field::link,
2922 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2923 asyncResp->res.jsonValue["@odata.type"] =
2924 "#ComputerSystemCollection.ComputerSystemCollection";
2925 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2926 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2927
2928 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2929 ifaceArray = nlohmann::json::array();
2930 if constexpr (bmcwebEnableMultiHost)
2931 {
2932 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2933 // Option currently returns no systems. TBD
2934 return;
2935 }
2936 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2937 nlohmann::json::object_t system;
2938 system["@odata.id"] = "/redfish/v1/Systems/system";
2939 ifaceArray.emplace_back(std::move(system));
2940 sdbusplus::asio::getProperty<std::string>(
2941 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2942 "/xyz/openbmc_project/network/hypervisor",
2943 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2944 [asyncResp](const boost::system::error_code& ec2,
2945 const std::string& /*hostName*/) {
2946 if (ec2)
2947 {
2948 return;
2949 }
2950 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2951 if (val == asyncResp->res.jsonValue.end())
2952 {
Ed Tanous62598e32023-07-17 17:06:25 -07002953 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002954 return;
2955 }
2956 uint64_t* count = val->get_ptr<uint64_t*>();
2957 if (count == nullptr)
2958 {
Ed Tanous62598e32023-07-17 17:06:25 -07002959 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002960 return;
2961 }
2962 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07002963 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002964 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2965 nlohmann::json::object_t hypervisor;
2966 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2967 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05002968 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07002969}
2970
Yong Lic45f0082019-10-10 14:19:01 +08002971/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002972 * Function transceives data with dbus directly.
2973 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002974inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002975{
Patrick Williams89492a12023-05-10 07:51:34 -05002976 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2977 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2978 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002979 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002980 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002981
2982 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002983 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002984 if (ec)
2985 {
Ed Tanous62598e32023-07-17 17:06:25 -07002986 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002987 messages::internalError(asyncResp->res);
2988 return;
2989 }
2990 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05002991 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002992 serviceName, objectPath, interfaceName, method);
2993}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002994
Ed Tanousc1e219d2023-06-07 10:34:33 -07002995inline void handleComputerSystemResetActionPost(
2996 crow::App& app, const crow::Request& req,
2997 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2998 const std::string& systemName)
2999{
3000 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3001 {
3002 return;
3003 }
3004 if (systemName != "system")
3005 {
3006 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3007 systemName);
3008 return;
3009 }
3010 if constexpr (bmcwebEnableMultiHost)
3011 {
3012 // Option currently returns no systems. TBD
3013 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3014 systemName);
3015 return;
3016 }
3017 std::string resetType;
3018 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3019 {
3020 return;
3021 }
3022
3023 // Get the command and host vs. chassis
3024 std::string command;
3025 bool hostCommand = true;
3026 if ((resetType == "On") || (resetType == "ForceOn"))
3027 {
3028 command = "xyz.openbmc_project.State.Host.Transition.On";
3029 hostCommand = true;
3030 }
3031 else if (resetType == "ForceOff")
3032 {
3033 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3034 hostCommand = false;
3035 }
3036 else if (resetType == "ForceRestart")
3037 {
3038 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3039 hostCommand = true;
3040 }
3041 else if (resetType == "GracefulShutdown")
3042 {
3043 command = "xyz.openbmc_project.State.Host.Transition.Off";
3044 hostCommand = true;
3045 }
3046 else if (resetType == "GracefulRestart")
3047 {
3048 command =
3049 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3050 hostCommand = true;
3051 }
3052 else if (resetType == "PowerCycle")
3053 {
3054 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3055 hostCommand = true;
3056 }
3057 else if (resetType == "Nmi")
3058 {
3059 doNMI(asyncResp);
3060 return;
3061 }
3062 else
3063 {
3064 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3065 return;
3066 }
Ed Tanousd02aad32024-02-13 14:43:34 -08003067 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003068
3069 if (hostCommand)
3070 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003071 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host",
3072 statePath / "host0", "xyz.openbmc_project.State.Host",
3073 "RequestedHostTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003074 }
3075 else
3076 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003077 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis",
3078 statePath / "chassis0",
3079 "xyz.openbmc_project.State.Chassis",
3080 "RequestedPowerTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003081 }
3082}
3083
Ed Tanousc1e219d2023-06-07 10:34:33 -07003084inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003085 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003086 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3087 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003088{
3089 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3090 {
3091 return;
3092 }
3093
3094 asyncResp->res.addHeader(
3095 boost::beast::http::field::link,
3096 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3097}
3098
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003099inline void afterPortRequest(
3100 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3101 const boost::system::error_code& ec,
3102 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3103{
3104 if (ec)
3105 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003106 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003107 messages::internalError(asyncResp->res);
3108 return;
3109 }
3110 for (const auto& data : socketData)
3111 {
3112 const std::string& socketPath = get<0>(data);
3113 const std::string& protocolName = get<1>(data);
3114 bool isProtocolEnabled = get<2>(data);
3115 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3116 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3117 // need to retrieve port number for
3118 // obmc-console-ssh service
3119 if (protocolName == "SSH")
3120 {
3121 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003122 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003123 int portNumber) {
3124 if (ec1)
3125 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003126 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003127 messages::internalError(asyncResp->res);
3128 return;
3129 }
3130 nlohmann::json& dataJson1 =
3131 asyncResp->res.jsonValue["SerialConsole"];
3132 dataJson1[protocolName]["Port"] = portNumber;
3133 });
3134 }
3135 }
3136}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003137
3138inline void
3139 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3140 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3141 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003142{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003143 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3144 {
3145 return;
3146 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003147
Ed Tanousc1e219d2023-06-07 10:34:33 -07003148 if constexpr (bmcwebEnableMultiHost)
3149 {
3150 // Option currently returns no systems. TBD
3151 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3152 systemName);
3153 return;
3154 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003155
Ed Tanousc1e219d2023-06-07 10:34:33 -07003156 if (systemName == "hypervisor")
3157 {
3158 handleHypervisorSystemGet(asyncResp);
3159 return;
3160 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003161
Ed Tanousc1e219d2023-06-07 10:34:33 -07003162 if (systemName != "system")
3163 {
3164 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3165 systemName);
3166 return;
3167 }
3168 asyncResp->res.addHeader(
3169 boost::beast::http::field::link,
3170 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3171 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003172 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanousc1e219d2023-06-07 10:34:33 -07003173 asyncResp->res.jsonValue["Name"] = "system";
3174 asyncResp->res.jsonValue["Id"] = "system";
3175 asyncResp->res.jsonValue["SystemType"] = "Physical";
3176 asyncResp->res.jsonValue["Description"] = "Computer System";
3177 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003178 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003179 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003180 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003181
Ed Tanousc1e219d2023-06-07 10:34:33 -07003182 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3183 "/redfish/v1/Systems/system/Processors";
3184 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3185 "/redfish/v1/Systems/system/Memory";
3186 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3187 "/redfish/v1/Systems/system/Storage";
3188 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3189 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003190
Ed Tanousc1e219d2023-06-07 10:34:33 -07003191 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3192 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3193 asyncResp->res
3194 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3195 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003196
Ed Tanousc1e219d2023-06-07 10:34:33 -07003197 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3198 "/redfish/v1/Systems/system/LogServices";
3199 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3200 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003201
Ed Tanousc1e219d2023-06-07 10:34:33 -07003202 nlohmann::json::array_t managedBy;
3203 nlohmann::json& manager = managedBy.emplace_back();
3204 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3205 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3206 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3207 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003208
Ed Tanousc1e219d2023-06-07 10:34:33 -07003209 // Fill in SerialConsole info
3210 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3211 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003212
Ed Tanousc1e219d2023-06-07 10:34:33 -07003213 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3214 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3215 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3216 "Press ~. to exit console";
3217 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3218 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003219
3220#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003221 // Fill in GraphicalConsole info
3222 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3223 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3224 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3225 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003226
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003227#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003228
Ed Tanousc1e219d2023-06-07 10:34:33 -07003229 getMainChassisId(asyncResp,
3230 [](const std::string& chassisId,
3231 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3232 nlohmann::json::array_t chassisArray;
3233 nlohmann::json& chassis = chassisArray.emplace_back();
3234 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3235 chassisId);
3236 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3237 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003238
George Liu59a17e42022-10-08 09:27:47 +08003239 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003240 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3241 getIndicatorLedState(asyncResp);
Gunnar Mills51bd2d82024-04-01 15:25:51 -05003242 getComputerSystem(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003243 getHostState(asyncResp);
3244 getBootProperties(asyncResp);
3245 getBootProgress(asyncResp);
3246 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003247 pcie_util::getPCIeDeviceList(asyncResp,
3248 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003249 getHostWatchdogTimer(asyncResp);
3250 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003251 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003252 getAutomaticRetryPolicy(asyncResp);
3253 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003254#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003255 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003256#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003257 getTrustedModuleRequiredToBoot(asyncResp);
3258 getPowerMode(asyncResp);
3259 getIdlePowerSaver(asyncResp);
3260}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003261
Ed Tanousc1e219d2023-06-07 10:34:33 -07003262inline void handleComputerSystemPatch(
3263 crow::App& app, const crow::Request& req,
3264 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3265 const std::string& systemName)
3266{
3267 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3268 {
3269 return;
3270 }
3271 if constexpr (bmcwebEnableMultiHost)
3272 {
3273 // Option currently returns no systems. TBD
3274 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3275 systemName);
3276 return;
3277 }
3278 if (systemName != "system")
3279 {
3280 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3281 systemName);
3282 return;
3283 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003284
Ed Tanousc1e219d2023-06-07 10:34:33 -07003285 asyncResp->res.addHeader(
3286 boost::beast::http::field::link,
3287 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003288
Ed Tanousc1e219d2023-06-07 10:34:33 -07003289 std::optional<bool> locationIndicatorActive;
3290 std::optional<std::string> indicatorLed;
3291 std::optional<std::string> assetTag;
3292 std::optional<std::string> powerRestorePolicy;
3293 std::optional<std::string> powerMode;
3294 std::optional<bool> wdtEnable;
3295 std::optional<std::string> wdtTimeOutAction;
3296 std::optional<std::string> bootSource;
3297 std::optional<std::string> bootType;
3298 std::optional<std::string> bootEnable;
3299 std::optional<std::string> bootAutomaticRetry;
3300 std::optional<uint32_t> bootAutomaticRetryAttempts;
3301 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003302 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003303 std::optional<bool> ipsEnable;
3304 std::optional<uint8_t> ipsEnterUtil;
3305 std::optional<uint64_t> ipsEnterTime;
3306 std::optional<uint8_t> ipsExitUtil;
3307 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003308
Ed Tanousc1e219d2023-06-07 10:34:33 -07003309 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003310 if (!json_util::readJsonPatch(
3311 req, asyncResp->res,
3312 "IndicatorLED", indicatorLed,
3313 "LocationIndicatorActive", locationIndicatorActive,
3314 "AssetTag", assetTag,
3315 "PowerRestorePolicy", powerRestorePolicy,
3316 "PowerMode", powerMode,
3317 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3318 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3319 "Boot/BootSourceOverrideTarget", bootSource,
3320 "Boot/BootSourceOverrideMode", bootType,
3321 "Boot/BootSourceOverrideEnabled", bootEnable,
3322 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003323 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003324 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003325 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003326 "IdlePowerSaver/Enabled", ipsEnable,
3327 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3328 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3329 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3330 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3331 {
3332 return;
3333 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003334 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003335
Ed Tanousc1e219d2023-06-07 10:34:33 -07003336 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003337
Ed Tanousc1e219d2023-06-07 10:34:33 -07003338 if (assetTag)
3339 {
3340 setAssetTag(asyncResp, *assetTag);
3341 }
James Feistb49ac872019-05-21 15:12:01 -07003342
Ed Tanousc1e219d2023-06-07 10:34:33 -07003343 if (wdtEnable || wdtTimeOutAction)
3344 {
3345 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3346 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003347
Ed Tanousc1e219d2023-06-07 10:34:33 -07003348 if (bootSource || bootType || bootEnable)
3349 {
3350 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3351 }
3352 if (bootAutomaticRetry)
3353 {
3354 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3355 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003356
Ed Tanousc1e219d2023-06-07 10:34:33 -07003357 if (bootAutomaticRetryAttempts)
3358 {
3359 setAutomaticRetryAttempts(asyncResp,
3360 bootAutomaticRetryAttempts.value());
3361 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003362
Ed Tanousc1e219d2023-06-07 10:34:33 -07003363 if (bootTrustedModuleRequired)
3364 {
3365 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3366 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003367
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003368 if (stopBootOnFault)
3369 {
3370 setStopBootOnFault(asyncResp, *stopBootOnFault);
3371 }
3372
Ed Tanousc1e219d2023-06-07 10:34:33 -07003373 if (locationIndicatorActive)
3374 {
George Liu59a17e42022-10-08 09:27:47 +08003375 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003376 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003377
Ed Tanousc1e219d2023-06-07 10:34:33 -07003378 // TODO (Gunnar): Remove IndicatorLED after enough time has
3379 // passed
3380 if (indicatorLed)
3381 {
3382 setIndicatorLedState(asyncResp, *indicatorLed);
3383 asyncResp->res.addHeader(boost::beast::http::field::warning,
3384 "299 - \"IndicatorLED is deprecated. Use "
3385 "LocationIndicatorActive instead.\"");
3386 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003387
Ed Tanousc1e219d2023-06-07 10:34:33 -07003388 if (powerRestorePolicy)
3389 {
3390 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3391 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003392
Ed Tanousc1e219d2023-06-07 10:34:33 -07003393 if (powerMode)
3394 {
3395 setPowerMode(asyncResp, *powerMode);
3396 }
Chris Cain37bbf982021-09-20 10:53:09 -05003397
Ed Tanousc1e219d2023-06-07 10:34:33 -07003398 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3399 {
3400 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3401 ipsExitUtil, ipsExitTime);
3402 }
3403}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303404
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003405inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003406 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003407 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003408 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003409{
3410 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3411 {
3412 return;
3413 }
3414 asyncResp->res.addHeader(
3415 boost::beast::http::field::link,
3416 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3417}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003418
3419/**
3420 * @brief Translates allowed host transitions to redfish string
3421 *
3422 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3423 * @param[out] allowableValues The translated host transition(s)
3424 *
3425 * @return Emplaces correpsonding Redfish translated value(s) in
3426 * allowableValues. If translation not possible, does nothing to
3427 * allowableValues.
3428 */
3429inline void
3430 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3431 nlohmann::json::array_t& allowableValues)
3432{
3433 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3434 {
3435 allowableValues.emplace_back(resource::ResetType::On);
3436 allowableValues.emplace_back(resource::ResetType::ForceOn);
3437 }
3438 else if (dbusAllowedHostTran ==
3439 "xyz.openbmc_project.State.Host.Transition.Off")
3440 {
3441 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3442 }
3443 else if (dbusAllowedHostTran ==
3444 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3445 {
3446 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3447 }
3448 else if (dbusAllowedHostTran ==
3449 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3450 {
3451 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3452 }
3453 else
3454 {
3455 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3456 }
3457}
3458
3459inline void afterGetAllowedHostTransitions(
3460 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3461 const boost::system::error_code& ec,
3462 const std::vector<std::string>& allowedHostTransitions)
3463{
3464 nlohmann::json::array_t allowableValues;
3465
3466 // Supported on all systems currently
3467 allowableValues.emplace_back(resource::ResetType::ForceOff);
3468 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3469 allowableValues.emplace_back(resource::ResetType::Nmi);
3470
3471 if (ec)
3472 {
Ed Tanouse715d142024-03-07 15:47:37 -08003473 if ((ec.value() ==
3474 boost::system::linux_error::bad_request_descriptor) ||
3475 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003476 {
3477 // Property not implemented so just return defaults
3478 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3479 allowableValues.emplace_back(resource::ResetType::On);
3480 allowableValues.emplace_back(resource::ResetType::ForceOn);
3481 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3482 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3483 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3484 }
3485 else
3486 {
3487 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3488 messages::internalError(asyncResp->res);
3489 return;
3490 }
3491 }
3492 else
3493 {
3494 for (const std::string& transition : allowedHostTransitions)
3495 {
3496 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3497 dbusToRfAllowedHostTransitions(transition, allowableValues);
3498 }
3499 }
3500
3501 nlohmann::json::object_t parameter;
3502 parameter["Name"] = "ResetType";
3503 parameter["Required"] = true;
3504 parameter["DataType"] = "String";
3505 parameter["AllowableValues"] = std::move(allowableValues);
3506 nlohmann::json::array_t parameters;
3507 parameters.emplace_back(std::move(parameter));
3508 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3509}
3510
Ed Tanousc1e219d2023-06-07 10:34:33 -07003511inline void handleSystemCollectionResetActionGet(
3512 crow::App& app, const crow::Request& req,
3513 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3514 const std::string& systemName)
3515{
3516 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3517 {
3518 return;
3519 }
3520 if constexpr (bmcwebEnableMultiHost)
3521 {
3522 // Option currently returns no systems. TBD
3523 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3524 systemName);
3525 return;
3526 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003527
Ed Tanousc1e219d2023-06-07 10:34:33 -07003528 if (systemName == "hypervisor")
3529 {
3530 handleHypervisorResetActionGet(asyncResp);
3531 return;
3532 }
3533
3534 if (systemName != "system")
3535 {
3536 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3537 systemName);
3538 return;
3539 }
3540
3541 asyncResp->res.addHeader(
3542 boost::beast::http::field::link,
3543 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3544
3545 asyncResp->res.jsonValue["@odata.id"] =
3546 "/redfish/v1/Systems/system/ResetActionInfo";
3547 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3548 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3549 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3550
Andrew Geissler33e1f122024-02-26 21:10:16 -06003551 // Look to see if system defines AllowedHostTransitions
3552 sdbusplus::asio::getProperty<std::vector<std::string>>(
3553 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3554 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
3555 "AllowedHostTransitions",
3556 [asyncResp](const boost::system::error_code& ec,
3557 const std::vector<std::string>& allowedHostTransitions) {
3558 afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
3559 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003560}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303561/**
3562 * SystemResetActionInfo derived class for delivering Computer Systems
3563 * ResetType AllowableValues using ResetInfo schema.
3564 */
Ed Tanous100afe52023-06-07 13:30:46 -07003565inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303566{
Ed Tanous100afe52023-06-07 13:30:46 -07003567 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3568 .privileges(redfish::privileges::headComputerSystemCollection)
3569 .methods(boost::beast::http::verb::head)(
3570 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3571
3572 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3573 .privileges(redfish::privileges::getComputerSystemCollection)
3574 .methods(boost::beast::http::verb::get)(
3575 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3576
3577 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3578 .privileges(redfish::privileges::headComputerSystem)
3579 .methods(boost::beast::http::verb::head)(
3580 std::bind_front(handleComputerSystemHead, std::ref(app)));
3581
3582 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3583 .privileges(redfish::privileges::getComputerSystem)
3584 .methods(boost::beast::http::verb::get)(
3585 std::bind_front(handleComputerSystemGet, std::ref(app)));
3586
3587 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3588 .privileges(redfish::privileges::patchComputerSystem)
3589 .methods(boost::beast::http::verb::patch)(
3590 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3591
3592 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3593 .privileges(redfish::privileges::postComputerSystem)
3594 .methods(boost::beast::http::verb::post)(std::bind_front(
3595 handleComputerSystemResetActionPost, std::ref(app)));
3596
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003597 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003598 .privileges(redfish::privileges::headActionInfo)
3599 .methods(boost::beast::http::verb::head)(std::bind_front(
3600 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003601 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003602 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003603 .methods(boost::beast::http::verb::get)(std::bind_front(
3604 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003605}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003606} // namespace redfish