blob: 2d62763ee3fc7aef4eb913d4e8489639b7f25bed [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070023#include "generated/enums/computer_system.hpp"
James Feistb49ac872019-05-21 15:12:01 -070024#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060025#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080026#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070027#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080028#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080029#include "registries/privilege_registry.hpp"
30#include "utils/dbus_utils.hpp"
31#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050032#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080033#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070034#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080035
Andrew Geisslerfc903b32023-05-31 14:15:42 -040036#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070037#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080038#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070039#include <boost/url/format.hpp>
Chris Cainb6655102024-02-01 14:35:33 -060040#include <generated/enums/computer_system.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>
46#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080047#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020048
Ed Tanous1abe55e2018-09-05 08:30:59 -070049namespace redfish
50{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020051
Abhishek Patel5c3e9272021-06-24 10:11:33 -050052const static std::array<std::pair<std::string_view, std::string_view>, 2>
53 protocolToDBusForSystems{
54 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
55
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056/**
57 * @brief Updates the Functional State of DIMMs
58 *
Ed Tanousac106bf2023-06-07 09:24:59 -070059 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050060 * @param[in] dimmState Dimm's Functional state, true/false
61 *
62 * @return None.
63 */
zhanghch058d1b46d2021-04-01 11:18:24 +080064inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070065 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070066 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050067{
Ed Tanous62598e32023-07-17 17:06:25 -070068 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050069
Gunnar Mills4e0453b2020-07-08 14:00:30 -050070 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071 // Update STATE only if previous State was DISABLED and current Dimm is
72 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070073 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070074 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050075 if (prevMemSummary == "Disabled")
76 {
Ed Tanouse05aec52022-01-25 10:28:56 -080077 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050078 {
Ed Tanousac106bf2023-06-07 09:24:59 -070079 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050080 "Enabled";
81 }
82 }
83}
84
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086 * @brief Update "ProcessorSummary" "Status" "State" based on
87 * CPU Functional State
88 *
Ed Tanousac106bf2023-06-07 09:24:59 -070089 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050090 * @param[in] cpuFunctionalState is CPU functional true/false
91 *
92 * @return None.
93 */
Ed Tanousac106bf2023-06-07 09:24:59 -070094inline void modifyCpuFunctionalState(
95 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050096{
Ed Tanous62598e32023-07-17 17:06:25 -070097 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098
Ed Tanous02cad962022-06-30 16:50:15 -070099 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700100 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500102 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103 // Update STATE only if previous State was Non_Functional and current CPU is
104 // Functional.
105 if (prevProcState == "Disabled")
106 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800107 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500108 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700109 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500110 "Enabled";
111 }
112 }
113}
114
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500115/*
116 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
117 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700118 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500119 * @param[in] cpuPresenceState CPU present or not
120 *
121 * @return None.
122 */
123inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700124 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500125 bool isCpuPresent)
126{
Ed Tanous62598e32023-07-17 17:06:25 -0700127 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500128
129 if (isCpuPresent)
130 {
131 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700132 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500133 auto* procCountPtr =
134 procCount.get_ptr<nlohmann::json::number_integer_t*>();
135 if (procCountPtr != nullptr)
136 {
137 // shouldn't be possible to be nullptr
138 *procCountPtr += 1;
139 }
140 }
141}
142
Ali Ahmed382d6472021-09-03 16:53:53 -0500143inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700144 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500145 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
146 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500147{
Ed Tanous62598e32023-07-17 17:06:25 -0700148 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500149
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200150 // TODO: Get Model
151
152 const uint16_t* coreCount = nullptr;
153
154 const bool success = sdbusplus::unpackPropertiesNoThrow(
155 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
156
157 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500158 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700159 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200160 return;
161 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200163 if (coreCount != nullptr)
164 {
165 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700166 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500168
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200169 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500170 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 coreCountJson = *coreCount;
172 }
173 else
174 {
175 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500176 }
177 }
178}
179
180/*
181 * @brief Get ProcessorSummary fields
182 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700183 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500184 * @param[in] service dbus service for Cpu Information
185 * @param[in] path dbus path for Cpu
186 *
187 * @return None.
188 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700189inline void
190 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
191 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500192{
Ed Tanousac106bf2023-06-07 09:24:59 -0700193 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
194 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500195 if (ec3)
196 {
Ed Tanous62598e32023-07-17 17:06:25 -0700197 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500198 return;
199 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700200 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500201 };
202
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500203 // Get the Presence of CPU
204 sdbusplus::asio::getProperty<bool>(
205 *crow::connections::systemBus, service, path,
206 "xyz.openbmc_project.Inventory.Item", "Present",
207 std::move(getCpuPresenceState));
208
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500209 if constexpr (bmcwebEnableProcMemStatus)
210 {
211 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700212 [asyncResp](const boost::system::error_code& ec3,
213 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500214 if (ec3)
215 {
Ed Tanous62598e32023-07-17 17:06:25 -0700216 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500217 return;
218 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700219 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500220 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500221
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500222 // Get the Functional State
223 sdbusplus::asio::getProperty<bool>(
224 *crow::connections::systemBus, service, path,
225 "xyz.openbmc_project.State.Decorator.OperationalStatus",
226 "Functional", std::move(getCpuFunctionalState));
227 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500228
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200229 sdbusplus::asio::getAllProperties(
230 *crow::connections::systemBus, service, path,
231 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700232 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800233 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800234 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700235 if (ec2)
236 {
Ed Tanous62598e32023-07-17 17:06:25 -0700237 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700238 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700239 return;
240 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700241 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500242 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500243}
244
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500245/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500246 * @brief processMemoryProperties fields
247 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700248 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500249 * @param[in] service dbus service for memory Information
250 * @param[in] path dbus path for Memory
251 * @param[in] DBUS properties for memory
252 *
253 * @return None.
254 */
255inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700256 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500257 [[maybe_unused]] const std::string& service,
258 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500259 const dbus::utility::DBusPropertiesMap& properties)
260{
Ed Tanous62598e32023-07-17 17:06:25 -0700261 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500262
263 if (properties.empty())
264 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500265 if constexpr (bmcwebEnableProcMemStatus)
266 {
267 sdbusplus::asio::getProperty<bool>(
268 *crow::connections::systemBus, service, path,
269 "xyz.openbmc_project.State."
270 "Decorator.OperationalStatus",
271 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700272 [asyncResp](const boost::system::error_code& ec3,
273 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500274 if (ec3)
275 {
Ed Tanous62598e32023-07-17 17:06:25 -0700276 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500277 return;
278 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700279 updateDimmProperties(asyncResp, dimmState);
Patrick Williams5a39f772023-10-20 11:20:21 -0500280 });
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500281 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500282 return;
283 }
284
285 const size_t* memorySizeInKB = nullptr;
286
287 const bool success = sdbusplus::unpackPropertiesNoThrow(
288 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
289 memorySizeInKB);
290
291 if (!success)
292 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700293 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500294 return;
295 }
296
297 if (memorySizeInKB != nullptr)
298 {
299 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700300 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500301 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500302 if (preValue == nullptr)
303 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700304 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500305 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500306 }
307 else
308 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700309 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500310 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
311 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500312 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500313 if constexpr (bmcwebEnableProcMemStatus)
314 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700315 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500316 "Enabled";
317 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500318 }
319}
320
321/*
322 * @brief Get getMemorySummary fields
323 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700324 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500325 * @param[in] service dbus service for memory Information
326 * @param[in] path dbus path for memory
327 *
328 * @return None.
329 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700330inline void
331 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
332 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500333{
334 sdbusplus::asio::getAllProperties(
335 *crow::connections::systemBus, service, path,
336 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700337 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500338 path](const boost::system::error_code& ec2,
339 const dbus::utility::DBusPropertiesMap& properties) {
340 if (ec2)
341 {
Ed Tanous62598e32023-07-17 17:06:25 -0700342 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700343 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500344 return;
345 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700346 processMemoryProperties(asyncResp, service, path, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500347 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500348}
349
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500350inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
351 const boost::system::error_code& ec,
352 const dbus::utility::DBusPropertiesMap& properties)
353{
354 if (ec)
355 {
356 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
357 messages::internalError(asyncResp->res);
358 return;
359 }
360 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
361
362 const std::string* uUID = nullptr;
363
364 const bool success = sdbusplus::unpackPropertiesNoThrow(
365 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
366
367 if (!success)
368 {
369 messages::internalError(asyncResp->res);
370 return;
371 }
372
373 if (uUID != nullptr)
374 {
375 std::string valueStr = *uUID;
376 if (valueStr.size() == 32)
377 {
378 valueStr.insert(8, 1, '-');
379 valueStr.insert(13, 1, '-');
380 valueStr.insert(18, 1, '-');
381 valueStr.insert(23, 1, '-');
382 }
383 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
384 asyncResp->res.jsonValue["UUID"] = valueStr;
385 }
386}
387
388inline void
389 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
390 const boost::system::error_code& ec,
391 const dbus::utility::DBusPropertiesMap& propertiesList)
392{
393 if (ec)
394 {
395 // doesn't have to include this
396 // interface
397 return;
398 }
399 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
400
401 const std::string* partNumber = nullptr;
402 const std::string* serialNumber = nullptr;
403 const std::string* manufacturer = nullptr;
404 const std::string* model = nullptr;
405 const std::string* subModel = nullptr;
406
407 const bool success = sdbusplus::unpackPropertiesNoThrow(
408 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
409 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
410 "Model", model, "SubModel", subModel);
411
412 if (!success)
413 {
414 messages::internalError(asyncResp->res);
415 return;
416 }
417
418 if (partNumber != nullptr)
419 {
420 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
421 }
422
423 if (serialNumber != nullptr)
424 {
425 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
426 }
427
428 if (manufacturer != nullptr)
429 {
430 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
431 }
432
433 if (model != nullptr)
434 {
435 asyncResp->res.jsonValue["Model"] = *model;
436 }
437
438 if (subModel != nullptr)
439 {
440 asyncResp->res.jsonValue["SubModel"] = *subModel;
441 }
442
443 // Grab the bios version
444 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
445 "BiosVersion", false);
446}
447
448inline void
449 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
450 const boost::system::error_code& ec,
451 const std::string& value)
452{
453 if (ec)
454 {
455 // doesn't have to include this
456 // interface
457 return;
458 }
459
460 asyncResp->res.jsonValue["AssetTag"] = value;
461}
462
463inline void afterSystemGetSubTree(
464 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
465 const std::shared_ptr<HealthPopulate>& systemHealth,
466 const boost::system::error_code& ec,
467 const dbus::utility::MapperGetSubTreeResponse& subtree)
468{
469 if (ec)
470 {
471 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
472 messages::internalError(asyncResp->res);
473 return;
474 }
475 // Iterate over all retrieved ObjectPaths.
476 for (const std::pair<
477 std::string,
478 std::vector<std::pair<std::string, std::vector<std::string>>>>&
479 object : subtree)
480 {
481 const std::string& path = object.first;
482 BMCWEB_LOG_DEBUG("Got path: {}", path);
483 const std::vector<std::pair<std::string, std::vector<std::string>>>&
484 connectionNames = object.second;
485 if (connectionNames.empty())
486 {
487 continue;
488 }
489
490 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
491 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
492
493 if constexpr (bmcwebEnableProcMemStatus)
494 {
495 memoryHealth = std::make_shared<HealthPopulate>(
496 asyncResp, "/MemorySummary/Status"_json_pointer);
497 systemHealth->children.emplace_back(memoryHealth);
498
499 if constexpr (bmcwebEnableHealthPopulate)
500 {
501 cpuHealth = std::make_shared<HealthPopulate>(
502 asyncResp, "/ProcessorSummary/Status"_json_pointer);
503
504 systemHealth->children.emplace_back(cpuHealth);
505 }
506 }
507
508 // This is not system, so check if it's cpu, dimm, UUID or
509 // BiosVer
510 for (const auto& connection : connectionNames)
511 {
512 for (const auto& interfaceName : connection.second)
513 {
514 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
515 {
516 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
517
518 getMemorySummary(asyncResp, connection.first, path);
519
520 if constexpr (bmcwebEnableProcMemStatus)
521 {
522 memoryHealth->inventory.emplace_back(path);
523 }
524 }
525 else if (interfaceName ==
526 "xyz.openbmc_project.Inventory.Item.Cpu")
527 {
528 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
529
530 getProcessorSummary(asyncResp, connection.first, path);
531
532 if constexpr (bmcwebEnableProcMemStatus)
533 {
534 cpuHealth->inventory.emplace_back(path);
535 }
536 }
537 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
538 {
539 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
540
541 sdbusplus::asio::getAllProperties(
542 *crow::connections::systemBus, connection.first, path,
543 "xyz.openbmc_project.Common.UUID",
544 [asyncResp](const boost::system::error_code& ec3,
545 const dbus::utility::DBusPropertiesMap&
546 properties) {
547 afterGetUUID(asyncResp, ec3, properties);
548 });
549 }
550 else if (interfaceName ==
551 "xyz.openbmc_project.Inventory.Item.System")
552 {
553 sdbusplus::asio::getAllProperties(
554 *crow::connections::systemBus, connection.first, path,
555 "xyz.openbmc_project.Inventory.Decorator.Asset",
556 [asyncResp](const boost::system::error_code& ec3,
557 const dbus::utility::DBusPropertiesMap&
558 properties) {
559 afterGetInventory(asyncResp, ec3, properties);
560 });
561
562 sdbusplus::asio::getProperty<std::string>(
563 *crow::connections::systemBus, connection.first, path,
564 "xyz.openbmc_project.Inventory.Decorator."
565 "AssetTag",
566 "AssetTag",
567 std::bind_front(afterGetAssetTag, asyncResp));
568 }
569 }
570 }
571 }
572}
573
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500574/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700575 * @brief Retrieves computer system properties over dbus
576 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700577 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500578 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700579 *
580 * @return None.
581 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700582inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700583 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700584 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700585{
Ed Tanous62598e32023-07-17 17:06:25 -0700586 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800587 constexpr std::array<std::string_view, 5> interfaces = {
588 "xyz.openbmc_project.Inventory.Decorator.Asset",
589 "xyz.openbmc_project.Inventory.Item.Cpu",
590 "xyz.openbmc_project.Inventory.Item.Dimm",
591 "xyz.openbmc_project.Inventory.Item.System",
592 "xyz.openbmc_project.Common.UUID",
593 };
594 dbus::utility::getSubTree(
595 "/xyz/openbmc_project/inventory", 0, interfaces,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500596 std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
Ed Tanous6c34de42018-08-29 13:37:36 -0700597}
598
599/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700600 * @brief Retrieves host state properties over dbus
601 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700602 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700603 *
604 * @return None.
605 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700606inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700607{
Ed Tanous62598e32023-07-17 17:06:25 -0700608 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700609 sdbusplus::asio::getProperty<std::string>(
610 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
611 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
612 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700613 [asyncResp](const boost::system::error_code& ec,
614 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700615 if (ec)
616 {
617 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700618 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700619 // Service not available, no error, just don't return
620 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700621 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700622 return;
623 }
Ed Tanous62598e32023-07-17 17:06:25 -0700624 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700625 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700626 return;
627 }
Ed Tanous66173382018-08-15 18:20:59 -0700628
Ed Tanous62598e32023-07-17 17:06:25 -0700629 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700630 // Verify Host State
631 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
632 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700633 asyncResp->res.jsonValue["PowerState"] = "On";
634 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700635 }
636 else if (hostState ==
637 "xyz.openbmc_project.State.Host.HostState.Quiesced")
638 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700639 asyncResp->res.jsonValue["PowerState"] = "On";
640 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700641 }
642 else if (hostState ==
643 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
644 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700645 asyncResp->res.jsonValue["PowerState"] = "On";
646 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700647 }
648 else if (
649 hostState ==
650 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
651 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700652 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
653 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700654 }
655 else if (hostState ==
656 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
657 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700658 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
659 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700660 }
661 else
662 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700663 asyncResp->res.jsonValue["PowerState"] = "Off";
664 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700665 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500666 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700667}
668
669/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500670 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671 *
672 * @param[in] dbusSource The boot source in DBUS speak.
673 *
674 * @return Returns as a string, the boot source in Redfish terms. If translation
675 * cannot be done, returns an empty string.
676 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000677inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530678{
679 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
680 {
681 return "None";
682 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700683 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530684 {
685 return "Hdd";
686 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700687 if (dbusSource ==
688 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530689 {
690 return "Cd";
691 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700692 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530693 {
694 return "Pxe";
695 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700696 if (dbusSource ==
697 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700698 {
699 return "Usb";
700 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700701 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530702}
703
704/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300705 * @brief Translates boot type DBUS property value to redfish.
706 *
707 * @param[in] dbusType The boot type in DBUS speak.
708 *
709 * @return Returns as a string, the boot type in Redfish terms. If translation
710 * cannot be done, returns an empty string.
711 */
712inline std::string dbusToRfBootType(const std::string& dbusType)
713{
714 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
715 {
716 return "Legacy";
717 }
718 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
719 {
720 return "UEFI";
721 }
722 return "";
723}
724
725/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500726 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727 *
728 * @param[in] dbusMode The boot mode in DBUS speak.
729 *
730 * @return Returns as a string, the boot mode in Redfish terms. If translation
731 * cannot be done, returns an empty string.
732 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000733inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530734{
735 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
736 {
737 return "None";
738 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700739 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530740 {
741 return "Diags";
742 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700743 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530744 {
745 return "BiosSetup";
746 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700747 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530748}
749
750/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600751 * @brief Translates boot progress DBUS property value to redfish.
752 *
753 * @param[in] dbusBootProgress The boot progress in DBUS speak.
754 *
755 * @return Returns as a string, the boot progress in Redfish terms. If
756 * translation cannot be done, returns "None".
757 */
758inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
759{
760 // Now convert the D-Bus BootProgress to the appropriate Redfish
761 // enum
762 std::string rfBpLastState = "None";
763 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
764 "ProgressStages.Unspecified")
765 {
766 rfBpLastState = "None";
767 }
768 else if (dbusBootProgress ==
769 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
770 "PrimaryProcInit")
771 {
772 rfBpLastState = "PrimaryProcessorInitializationStarted";
773 }
774 else if (dbusBootProgress ==
775 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
776 "BusInit")
777 {
778 rfBpLastState = "BusInitializationStarted";
779 }
780 else if (dbusBootProgress ==
781 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
782 "MemoryInit")
783 {
784 rfBpLastState = "MemoryInitializationStarted";
785 }
786 else if (dbusBootProgress ==
787 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
788 "SecondaryProcInit")
789 {
790 rfBpLastState = "SecondaryProcessorInitializationStarted";
791 }
792 else if (dbusBootProgress ==
793 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
794 "PCIInit")
795 {
796 rfBpLastState = "PCIResourceConfigStarted";
797 }
798 else if (dbusBootProgress ==
799 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
800 "SystemSetup")
801 {
802 rfBpLastState = "SetupEntered";
803 }
804 else if (dbusBootProgress ==
805 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
806 "SystemInitComplete")
807 {
808 rfBpLastState = "SystemHardwareInitializationComplete";
809 }
810 else if (dbusBootProgress ==
811 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
812 "OSStart")
813 {
814 rfBpLastState = "OSBootStarted";
815 }
816 else if (dbusBootProgress ==
817 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
818 "OSRunning")
819 {
820 rfBpLastState = "OSRunning";
821 }
822 else
823 {
Ed Tanous62598e32023-07-17 17:06:25 -0700824 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600825 // Just return the default
826 }
827 return rfBpLastState;
828}
829
830/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500831 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530832 *
833 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700834 * @param[out] bootSource The DBus source
835 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700837 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700839inline int
840 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
841 const std::string& rfSource, std::string& bootSource,
842 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530843{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300844 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
845 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700846
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530847 if (rfSource == "None")
848 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700849 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530850 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700851 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530852 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700853 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
854 }
855 else if (rfSource == "Hdd")
856 {
857 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
858 }
859 else if (rfSource == "Diags")
860 {
861 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
862 }
863 else if (rfSource == "Cd")
864 {
865 bootSource =
866 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
867 }
868 else if (rfSource == "BiosSetup")
869 {
870 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530871 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700872 else if (rfSource == "Usb")
873 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700874 bootSource =
875 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700876 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530877 else
878 {
Ed Tanous62598e32023-07-17 17:06:25 -0700879 BMCWEB_LOG_DEBUG(
880 "Invalid property value for BootSourceOverrideTarget: {}",
881 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700882 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700883 "BootSourceTargetOverride");
884 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530885 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700886 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530887}
Ali Ahmed19817712021-06-29 17:01:52 -0500888
Andrew Geissler978b8802020-11-19 13:36:40 -0600889/**
890 * @brief Retrieves boot progress of the system
891 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700892 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600893 *
894 * @return None.
895 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700896inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600897{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700898 sdbusplus::asio::getProperty<std::string>(
899 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
900 "/xyz/openbmc_project/state/host0",
901 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700902 [asyncResp](const boost::system::error_code& ec,
903 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700904 if (ec)
905 {
906 // BootProgress is an optional object so just do nothing if
907 // not found
908 return;
909 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600910
Ed Tanous62598e32023-07-17 17:06:25 -0700911 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600912
Ed Tanousac106bf2023-06-07 09:24:59 -0700913 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700914 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500915 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600916}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530917
918/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000919 * @brief Retrieves boot progress Last Update of the system
920 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700921 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000922 *
923 * @return None.
924 */
925inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700926 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000927{
928 sdbusplus::asio::getProperty<uint64_t>(
929 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
930 "/xyz/openbmc_project/state/host0",
931 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700932 [asyncResp](const boost::system::error_code& ec,
933 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000934 if (ec)
935 {
Ed Tanous62598e32023-07-17 17:06:25 -0700936 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000937 return;
938 }
939
940 // BootProgressLastUpdate is the last time the BootProgress property
941 // was updated. The time is the Epoch time, number of microseconds
942 // since 1 Jan 1970 00::00::00 UTC."
943 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
944 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
945
946 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700947 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000948 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500949 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000950}
951
952/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300953 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300954 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700955 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300956 *
957 * @return None.
958 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300959
Ed Tanousac106bf2023-06-07 09:24:59 -0700960inline void
961 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300962{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700963 sdbusplus::asio::getProperty<std::string>(
964 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
965 "/xyz/openbmc_project/control/host0/boot",
966 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700967 [asyncResp](const boost::system::error_code& ec,
968 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700969 if (ec)
970 {
971 // not an error, don't have to have the interface
972 return;
973 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300974
Ed Tanous62598e32023-07-17 17:06:25 -0700975 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300976
Ed Tanousac106bf2023-06-07 09:24:59 -0700977 asyncResp->res
978 .jsonValue["Boot"]
979 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700980 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300981
Ed Tanous002d39b2022-05-31 08:59:27 -0700982 auto rfType = dbusToRfBootType(bootType);
983 if (rfType.empty())
984 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700985 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700986 return;
987 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300988
Ed Tanousac106bf2023-06-07 09:24:59 -0700989 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500990 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300991}
992
993/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300994 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530995 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700996 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530997 *
998 * @return None.
999 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001000
Ed Tanousac106bf2023-06-07 09:24:59 -07001001inline void
1002 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301003{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001004 sdbusplus::asio::getProperty<std::string>(
1005 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1006 "/xyz/openbmc_project/control/host0/boot",
1007 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001008 [asyncResp](const boost::system::error_code& ec,
1009 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001010 if (ec)
1011 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001012 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001013 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001014 return;
1015 }
1016
Ed Tanous62598e32023-07-17 17:06:25 -07001017 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -07001018
Ed Tanousac106bf2023-06-07 09:24:59 -07001019 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001020 .jsonValue["Boot"]
1021 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1022 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1023
1024 if (bootModeStr !=
1025 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1026 {
1027 auto rfMode = dbusToRfBootMode(bootModeStr);
1028 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301029 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001030 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001031 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301032 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001033 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001034 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301035}
1036
1037/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001038 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301039 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001040 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041 *
1042 * @return None.
1043 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001044
1045inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001046 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301047{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001048 sdbusplus::asio::getProperty<std::string>(
1049 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1050 "/xyz/openbmc_project/control/host0/boot",
1051 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001052 [asyncResp](const boost::system::error_code& ec,
1053 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001054 if (ec)
1055 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001056 if (ec.value() == boost::asio::error::host_unreachable)
1057 {
1058 return;
1059 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001060 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001061 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001062 return;
1063 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301064
Ed Tanous62598e32023-07-17 17:06:25 -07001065 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301066
Ed Tanous002d39b2022-05-31 08:59:27 -07001067 auto rfSource = dbusToRfBootSource(bootSourceStr);
1068 if (!rfSource.empty())
1069 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001070 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1071 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001072 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001073
Ed Tanous002d39b2022-05-31 08:59:27 -07001074 // Get BootMode as BootSourceOverrideTarget is constructed
1075 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001076 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001077 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078}
1079
1080/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001081 * @brief This functions abstracts all the logic behind getting a
1082 * "BootSourceOverrideEnabled" property from an overall boot override enable
1083 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301084 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001085 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301086 *
1087 * @return None.
1088 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301089
Ed Tanousac106bf2023-06-07 09:24:59 -07001090inline void processBootOverrideEnable(
1091 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1092 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001093{
1094 if (!bootOverrideEnableSetting)
1095 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001096 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1097 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001098 return;
1099 }
1100
1101 // If boot source override is enabled, we need to check 'one_time'
1102 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001103 sdbusplus::asio::getProperty<bool>(
1104 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1105 "/xyz/openbmc_project/control/host0/boot/one_time",
1106 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001107 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001108 if (ec)
1109 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001110 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001111 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001112 return;
1113 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301114
Ed Tanous002d39b2022-05-31 08:59:27 -07001115 if (oneTimeSetting)
1116 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001117 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1118 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001119 }
1120 else
1121 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001122 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001123 "Continuous";
1124 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001125 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301126}
1127
1128/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001129 * @brief Retrieves boot override enable over DBUS
1130 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001131 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001132 *
1133 * @return None.
1134 */
1135
1136inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001137 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001138{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001139 sdbusplus::asio::getProperty<bool>(
1140 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1141 "/xyz/openbmc_project/control/host0/boot",
1142 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001143 [asyncResp](const boost::system::error_code& ec,
1144 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001145 if (ec)
1146 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001147 if (ec.value() == boost::asio::error::host_unreachable)
1148 {
1149 return;
1150 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001151 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001152 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001153 return;
1154 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001155
Ed Tanousac106bf2023-06-07 09:24:59 -07001156 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001157 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001158}
1159
1160/**
1161 * @brief Retrieves boot source override properties
1162 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001163 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001164 *
1165 * @return None.
1166 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001167inline void
1168 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001169{
Ed Tanous62598e32023-07-17 17:06:25 -07001170 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001171
Ed Tanousac106bf2023-06-07 09:24:59 -07001172 getBootOverrideSource(asyncResp);
1173 getBootOverrideType(asyncResp);
1174 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001175}
1176
1177/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001178 * @brief Retrieves the Last Reset Time
1179 *
1180 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1181 * and power off. Even though this is the "system" Redfish object look at the
1182 * chassis D-Bus interface for the LastStateChangeTime since this has the
1183 * last power operation time.
1184 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001185 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001186 *
1187 * @return None.
1188 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001189inline void
1190 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001191{
Ed Tanous62598e32023-07-17 17:06:25 -07001192 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001193
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001194 sdbusplus::asio::getProperty<uint64_t>(
1195 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1196 "/xyz/openbmc_project/state/chassis0",
1197 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001198 [asyncResp](const boost::system::error_code& ec,
1199 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001200 if (ec)
1201 {
Ed Tanous62598e32023-07-17 17:06:25 -07001202 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001203 return;
1204 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001205
Ed Tanous002d39b2022-05-31 08:59:27 -07001206 // LastStateChangeTime is epoch time, in milliseconds
1207 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1208 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001209
Ed Tanous002d39b2022-05-31 08:59:27 -07001210 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001211 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001212 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001213 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001214}
1215
1216/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001217 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1218 *
1219 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1220 * corresponding property "AttemptsLeft" that keeps track of the amount of
1221 * automatic retry attempts left are hosted in phosphor-state-manager through
1222 * dbus.
1223 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001224 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001225 *
1226 * @return None.
1227 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001228inline void getAutomaticRebootAttempts(
1229 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001230{
Ed Tanous62598e32023-07-17 17:06:25 -07001231 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001232
1233 sdbusplus::asio::getAllProperties(
1234 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1235 "/xyz/openbmc_project/state/host0",
1236 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001237 [asyncResp{asyncResp}](
1238 const boost::system::error_code& ec,
1239 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001240 if (ec)
1241 {
1242 if (ec.value() != EBADR)
1243 {
Ed Tanous62598e32023-07-17 17:06:25 -07001244 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001245 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001246 }
1247 return;
1248 }
1249
1250 const uint32_t* attemptsLeft = nullptr;
1251 const uint32_t* retryAttempts = nullptr;
1252
1253 const bool success = sdbusplus::unpackPropertiesNoThrow(
1254 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1255 attemptsLeft, "RetryAttempts", retryAttempts);
1256
1257 if (!success)
1258 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001259 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001260 return;
1261 }
1262
1263 if (attemptsLeft != nullptr)
1264 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001265 asyncResp->res
1266 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001267 *attemptsLeft;
1268 }
1269
1270 if (retryAttempts != nullptr)
1271 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001272 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001273 *retryAttempts;
1274 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001275 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001276}
1277
1278/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001279 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1280 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001281 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001282 *
1283 * @return None.
1284 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001285inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001286 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001287{
Ed Tanous62598e32023-07-17 17:06:25 -07001288 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001289
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001290 sdbusplus::asio::getProperty<bool>(
1291 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1292 "/xyz/openbmc_project/control/host0/auto_reboot",
1293 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001294 [asyncResp](const boost::system::error_code& ec,
1295 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001296 if (ec)
1297 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001298 if (ec.value() != EBADR)
1299 {
Ed Tanous62598e32023-07-17 17:06:25 -07001300 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001301 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001302 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001303 return;
1304 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001305
Ed Tanous62598e32023-07-17 17:06:25 -07001306 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001307 if (autoRebootEnabled)
1308 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001309 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001310 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001311 }
1312 else
1313 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001314 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1315 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001316 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001317 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001318
Ed Tanous002d39b2022-05-31 08:59:27 -07001319 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1320 // and RetryAttempts. OpenBMC only supports Disabled and
1321 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001322 asyncResp->res
1323 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1324 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001325 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001326}
1327
1328/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001329 * @brief Sets RetryAttempts
1330 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001331 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001332 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1333 *
1334 *@return None.
1335 */
1336
Ed Tanousac106bf2023-06-07 09:24:59 -07001337inline void setAutomaticRetryAttempts(
1338 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1339 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001340{
Ed Tanous62598e32023-07-17 17:06:25 -07001341 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001342 sdbusplus::asio::setProperty(
1343 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1344 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001345 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001346 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001347 if (ec)
1348 {
1349 BMCWEB_LOG_ERROR(
1350 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1351 messages::internalError(asyncResp->res);
1352 return;
1353 }
1354 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001355}
1356
Ed Tanous8d69c662023-06-21 10:29:06 -07001357inline computer_system::PowerRestorePolicyTypes
1358 redfishPowerRestorePolicyFromDbus(std::string_view value)
1359{
1360 if (value ==
1361 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1362 {
1363 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1364 }
1365 if (value ==
1366 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1367 {
1368 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1369 }
1370 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001371 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001372 {
1373 return computer_system::PowerRestorePolicyTypes::LastState;
1374 }
1375 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1376 {
1377 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1378 }
1379 return computer_system::PowerRestorePolicyTypes::Invalid;
1380}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001381/**
George Liuc6a620f2020-04-10 17:18:11 +08001382 * @brief Retrieves power restore policy over DBUS.
1383 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001384 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001385 *
1386 * @return None.
1387 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001388inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001389 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001390{
Ed Tanous62598e32023-07-17 17:06:25 -07001391 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001392
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001393 sdbusplus::asio::getProperty<std::string>(
1394 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1395 "/xyz/openbmc_project/control/host0/power_restore_policy",
1396 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001397 [asyncResp](const boost::system::error_code& ec,
1398 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001399 if (ec)
1400 {
Ed Tanous62598e32023-07-17 17:06:25 -07001401 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001402 return;
1403 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001404 computer_system::PowerRestorePolicyTypes restore =
1405 redfishPowerRestorePolicyFromDbus(policy);
1406 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001407 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001408 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001409 return;
1410 }
George Liuc6a620f2020-04-10 17:18:11 +08001411
Ed Tanous8d69c662023-06-21 10:29:06 -07001412 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001413 });
George Liuc6a620f2020-04-10 17:18:11 +08001414}
1415
1416/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001417 * @brief Stop Boot On Fault over DBUS.
1418 *
1419 * @param[in] asyncResp Shared pointer for generating response message.
1420 *
1421 * @return None.
1422 */
1423inline void
1424 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1425{
Ed Tanous62598e32023-07-17 17:06:25 -07001426 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001427
1428 sdbusplus::asio::getProperty<bool>(
1429 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1430 "/xyz/openbmc_project/logging/settings",
1431 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1432 [asyncResp](const boost::system::error_code& ec, bool value) {
1433 if (ec)
1434 {
1435 if (ec.value() != EBADR)
1436 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001437 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001438 messages::internalError(asyncResp->res);
1439 }
1440 return;
1441 }
1442
1443 if (value)
1444 {
1445 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1446 }
1447 else
1448 {
1449 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1450 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001451 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001452}
1453
1454/**
Ali Ahmed19817712021-06-29 17:01:52 -05001455 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1456 * TPM is required for booting the host.
1457 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001458 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001459 *
1460 * @return None.
1461 */
1462inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001463 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001464{
Ed Tanous62598e32023-07-17 17:06:25 -07001465 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001466 constexpr std::array<std::string_view, 1> interfaces = {
1467 "xyz.openbmc_project.Control.TPM.Policy"};
1468 dbus::utility::getSubTree(
1469 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001470 [asyncResp](const boost::system::error_code& ec,
1471 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001472 if (ec)
1473 {
Ed Tanous62598e32023-07-17 17:06:25 -07001474 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1475 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001476 // This is an optional D-Bus object so just return if
1477 // error occurs
1478 return;
1479 }
1480 if (subtree.empty())
1481 {
1482 // As noted above, this is an optional interface so just return
1483 // if there is no instance found
1484 return;
1485 }
1486
1487 /* When there is more than one TPMEnable object... */
1488 if (subtree.size() > 1)
1489 {
Ed Tanous62598e32023-07-17 17:06:25 -07001490 BMCWEB_LOG_DEBUG(
1491 "DBUS response has more than 1 TPM Enable object:{}",
1492 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001493 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001494 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001495 return;
1496 }
1497
1498 // Make sure the Dbus response map has a service and objectPath
1499 // field
1500 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1501 {
Ed Tanous62598e32023-07-17 17:06:25 -07001502 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001503 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001504 return;
1505 }
1506
1507 const std::string& path = subtree[0].first;
1508 const std::string& serv = subtree[0].second.begin()->first;
1509
1510 // Valid TPM Enable object found, now reading the current value
1511 sdbusplus::asio::getProperty<bool>(
1512 *crow::connections::systemBus, serv, path,
1513 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001514 [asyncResp](const boost::system::error_code& ec2,
1515 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001516 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001517 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001518 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001519 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001520 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001521 return;
1522 }
1523
Ed Tanous002d39b2022-05-31 08:59:27 -07001524 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001525 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001526 asyncResp->res
1527 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001528 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001529 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001530 else
1531 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001532 asyncResp->res
1533 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001534 "Disabled";
1535 }
George Liue99073f2022-12-09 11:06:16 +08001536 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001537 });
Ali Ahmed19817712021-06-29 17:01:52 -05001538}
1539
1540/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001541 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1542 * TPM is required for booting the host.
1543 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001544 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001545 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1546 *
1547 * @return None.
1548 */
1549inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001550 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001551{
Ed Tanous62598e32023-07-17 17:06:25 -07001552 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001553 constexpr std::array<std::string_view, 1> interfaces = {
1554 "xyz.openbmc_project.Control.TPM.Policy"};
1555 dbus::utility::getSubTree(
1556 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001557 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001558 tpmRequired](const boost::system::error_code& ec,
1559 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001560 if (ec)
1561 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001562 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001563 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001564 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001565 return;
1566 }
1567 if (subtree.empty())
1568 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001569 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001570 "TrustedModuleRequiredToBoot");
1571 return;
1572 }
1573
1574 /* When there is more than one TPMEnable object... */
1575 if (subtree.size() > 1)
1576 {
Ed Tanous62598e32023-07-17 17:06:25 -07001577 BMCWEB_LOG_DEBUG(
1578 "DBUS response has more than 1 TPM Enable object:{}",
1579 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001580 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001581 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001582 return;
1583 }
1584
1585 // Make sure the Dbus response map has a service and objectPath
1586 // field
1587 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1588 {
Ed Tanous62598e32023-07-17 17:06:25 -07001589 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001590 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001591 return;
1592 }
1593
1594 const std::string& path = subtree[0].first;
1595 const std::string& serv = subtree[0].second.begin()->first;
1596
1597 if (serv.empty())
1598 {
Ed Tanous62598e32023-07-17 17:06:25 -07001599 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001600 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001601 return;
1602 }
1603
1604 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001605 sdbusplus::asio::setProperty(
1606 *crow::connections::systemBus, serv, path,
1607 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001608 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001609 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001610 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001611 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001612 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1613 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001614 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001615 return;
1616 }
Ed Tanous62598e32023-07-17 17:06:25 -07001617 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001618 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001619 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001620}
1621
1622/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301623 * @brief Sets boot properties into DBUS object(s).
1624 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001625 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001626 * @param[in] bootType The boot type to set.
1627 * @return Integer error code.
1628 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001629inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001630 const std::optional<std::string>& bootType)
1631{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001632 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001633
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001634 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001635 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001636 return;
1637 }
1638
1639 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001640 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001641 // Figure out which DBUS interface and property to use
1642 if (*bootType == "Legacy")
1643 {
1644 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1645 }
1646 else if (*bootType == "UEFI")
1647 {
1648 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1649 }
1650 else
1651 {
Ed Tanous62598e32023-07-17 17:06:25 -07001652 BMCWEB_LOG_DEBUG("Invalid property value for "
1653 "BootSourceOverrideMode: {}",
1654 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001655 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001656 "BootSourceOverrideMode");
1657 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001658 }
1659
1660 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001661 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001662
George Liu9ae226f2023-06-21 17:56:46 +08001663 sdbusplus::asio::setProperty(
1664 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1665 "/xyz/openbmc_project/control/host0/boot",
1666 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001667 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001668 if (ec)
1669 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001670 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001671 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001672 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001673 return;
1674 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001675 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001676 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001677 return;
1678 }
Ed Tanous62598e32023-07-17 17:06:25 -07001679 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001680 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001681}
1682
1683/**
1684 * @brief Sets boot properties into DBUS object(s).
1685 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001686 * @param[in] asyncResp Shared pointer for generating response
1687 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001688 * @param[in] bootType The boot type to set.
1689 * @return Integer error code.
1690 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001691inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001692 const std::optional<std::string>& bootEnable)
1693{
1694 if (!bootEnable)
1695 {
1696 return;
1697 }
1698 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001699 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001700
1701 bool bootOverrideEnable = false;
1702 bool bootOverridePersistent = false;
1703 // Figure out which DBUS interface and property to use
1704 if (*bootEnable == "Disabled")
1705 {
1706 bootOverrideEnable = false;
1707 }
1708 else if (*bootEnable == "Once")
1709 {
1710 bootOverrideEnable = true;
1711 bootOverridePersistent = false;
1712 }
1713 else if (*bootEnable == "Continuous")
1714 {
1715 bootOverrideEnable = true;
1716 bootOverridePersistent = true;
1717 }
1718 else
1719 {
Ed Tanous62598e32023-07-17 17:06:25 -07001720 BMCWEB_LOG_DEBUG(
1721 "Invalid property value for BootSourceOverrideEnabled: {}",
1722 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001723 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001724 "BootSourceOverrideEnabled");
1725 return;
1726 }
1727
1728 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001729 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001730
George Liu9ae226f2023-06-21 17:56:46 +08001731 sdbusplus::asio::setProperty(
1732 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1733 "/xyz/openbmc_project/control/host0/boot",
1734 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001735 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001736 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001737 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001738 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001739 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001740 return;
1741 }
Ed Tanous62598e32023-07-17 17:06:25 -07001742 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001743 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001744
1745 if (!bootOverrideEnable)
1746 {
1747 return;
1748 }
1749
1750 // In case boot override is enabled we need to set correct value for the
1751 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001752 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1753 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001754
George Liu9ae226f2023-06-21 17:56:46 +08001755 sdbusplus::asio::setProperty(
1756 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1757 "/xyz/openbmc_project/control/host0/boot/one_time",
1758 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001759 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001760 if (ec)
1761 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001762 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001763 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001764 return;
1765 }
Ed Tanous62598e32023-07-17 17:06:25 -07001766 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001767 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001768}
1769
1770/**
1771 * @brief Sets boot properties into DBUS object(s).
1772 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001773 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301774 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301775 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001776 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301777 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001778inline void
1779 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1780 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301781{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001782 std::string bootSourceStr;
1783 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001784
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001785 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301786 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001787 return;
1788 }
1789
1790 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001791 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001792 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001793 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1794 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001795 {
Ed Tanous62598e32023-07-17 17:06:25 -07001796 BMCWEB_LOG_DEBUG(
1797 "Invalid property value for BootSourceOverrideTarget: {}",
1798 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001799 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001800 "BootSourceTargetOverride");
1801 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001802 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301803
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001804 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001805 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1806 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001807
George Liu9ae226f2023-06-21 17:56:46 +08001808 sdbusplus::asio::setProperty(
1809 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1810 "/xyz/openbmc_project/control/host0/boot",
1811 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001812 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001813 if (ec)
1814 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001815 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001816 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001817 return;
1818 }
Ed Tanous62598e32023-07-17 17:06:25 -07001819 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001820 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001821
George Liu9ae226f2023-06-21 17:56:46 +08001822 sdbusplus::asio::setProperty(
1823 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1824 "/xyz/openbmc_project/control/host0/boot",
1825 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001826 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001827 if (ec)
1828 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001829 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001830 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001831 return;
1832 }
Ed Tanous62598e32023-07-17 17:06:25 -07001833 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001834 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001835}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001836
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001837/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001838 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301839 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001840 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301841 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001842 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301843 * @param[in] bootEnable The boot override enable from incoming RF request.
1844 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001845 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301846 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001847
Ed Tanousac106bf2023-06-07 09:24:59 -07001848inline void
1849 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1850 const std::optional<std::string>& bootSource,
1851 const std::optional<std::string>& bootType,
1852 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301853{
Ed Tanous62598e32023-07-17 17:06:25 -07001854 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301855
Ed Tanousac106bf2023-06-07 09:24:59 -07001856 setBootModeOrSource(asyncResp, bootSource);
1857 setBootType(asyncResp, bootType);
1858 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301859}
1860
George Liuc6a620f2020-04-10 17:18:11 +08001861/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001862 * @brief Sets AssetTag
1863 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001864 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001865 * @param[in] assetTag "AssetTag" from request.
1866 *
1867 * @return None.
1868 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001869inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001870 const std::string& assetTag)
1871{
George Liue99073f2022-12-09 11:06:16 +08001872 constexpr std::array<std::string_view, 1> interfaces = {
1873 "xyz.openbmc_project.Inventory.Item.System"};
1874 dbus::utility::getSubTree(
1875 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001876 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001877 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001878 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001879 if (ec)
1880 {
Ed Tanous62598e32023-07-17 17:06:25 -07001881 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001882 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001883 return;
1884 }
1885 if (subtree.empty())
1886 {
Ed Tanous62598e32023-07-17 17:06:25 -07001887 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001888 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001889 return;
1890 }
1891 // Assume only 1 system D-Bus object
1892 // Throw an error if there is more than 1
1893 if (subtree.size() > 1)
1894 {
Ed Tanous62598e32023-07-17 17:06:25 -07001895 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001896 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001897 return;
1898 }
1899 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1900 {
Ed Tanous62598e32023-07-17 17:06:25 -07001901 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001902 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001903 return;
1904 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001905
Ed Tanous002d39b2022-05-31 08:59:27 -07001906 const std::string& path = subtree[0].first;
1907 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001908
Ed Tanous002d39b2022-05-31 08:59:27 -07001909 if (service.empty())
1910 {
Ed Tanous62598e32023-07-17 17:06:25 -07001911 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001912 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001913 return;
1914 }
1915
George Liu9ae226f2023-06-21 17:56:46 +08001916 sdbusplus::asio::setProperty(
1917 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001918 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001919 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001920 if (ec2)
1921 {
1922 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1923 ec2);
1924 messages::internalError(asyncResp->res);
1925 return;
1926 }
George Liue99073f2022-12-09 11:06:16 +08001927 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001928 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001929}
1930
1931/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001932 * @brief Validate the specified stopBootOnFault is valid and return the
1933 * stopBootOnFault name associated with that string
1934 *
1935 * @param[in] stopBootOnFaultString String representing the desired
1936 * stopBootOnFault
1937 *
1938 * @return stopBootOnFault value or empty if incoming value is not valid
1939 */
1940inline std::optional<bool>
1941 validstopBootOnFault(const std::string& stopBootOnFaultString)
1942{
1943 if (stopBootOnFaultString == "AnyFault")
1944 {
1945 return true;
1946 }
1947
1948 if (stopBootOnFaultString == "Never")
1949 {
1950 return false;
1951 }
1952
1953 return std::nullopt;
1954}
1955
1956/**
1957 * @brief Sets stopBootOnFault
1958 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001959 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001960 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1961 *
1962 * @return None.
1963 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001964inline void
1965 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1966 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001967{
Ed Tanous62598e32023-07-17 17:06:25 -07001968 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001969
1970 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1971 if (!stopBootEnabled)
1972 {
Ed Tanous62598e32023-07-17 17:06:25 -07001973 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1974 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001975 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001976 "StopBootOnFault");
1977 return;
1978 }
1979
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001980 sdbusplus::asio::setProperty(
1981 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1982 "/xyz/openbmc_project/logging/settings",
1983 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1984 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001985 if (ec)
1986 {
1987 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001988 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001989 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1990 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001991 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001992 return;
1993 }
1994 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001995}
1996
1997/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001998 * @brief Sets automaticRetry (Auto Reboot)
1999 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002000 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05002001 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
2002 *
2003 * @return None.
2004 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002005inline void
2006 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2007 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002008{
Ed Tanous62598e32023-07-17 17:06:25 -07002009 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05002010
2011 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002012 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002013
2014 if (automaticRetryConfig == "Disabled")
2015 {
2016 autoRebootEnabled = false;
2017 }
2018 else if (automaticRetryConfig == "RetryAttempts")
2019 {
2020 autoRebootEnabled = true;
2021 }
2022 else
2023 {
Ed Tanous62598e32023-07-17 17:06:25 -07002024 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2025 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002026 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002027 "AutomaticRetryConfig");
2028 return;
2029 }
2030
George Liu9ae226f2023-06-21 17:56:46 +08002031 sdbusplus::asio::setProperty(
2032 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002033 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002034 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002035 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002036 if (ec)
2037 {
2038 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2039 messages::internalError(asyncResp->res);
2040 return;
2041 }
2042 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002043}
2044
Ed Tanous8d69c662023-06-21 10:29:06 -07002045inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2046{
2047 if (policy == "AlwaysOn")
2048 {
2049 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2050 }
2051 if (policy == "AlwaysOff")
2052 {
2053 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2054 }
2055 if (policy == "LastState")
2056 {
2057 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2058 }
2059 return "";
2060}
2061
Gunnar Mills69f35302020-05-17 16:06:31 -05002062/**
George Liuc6a620f2020-04-10 17:18:11 +08002063 * @brief Sets power restore policy properties.
2064 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002065 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002066 * @param[in] policy power restore policy properties from request.
2067 *
2068 * @return None.
2069 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002070inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002071 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002072 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002073{
Ed Tanous62598e32023-07-17 17:06:25 -07002074 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002075
Ed Tanous8d69c662023-06-21 10:29:06 -07002076 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002077
Ed Tanous8d69c662023-06-21 10:29:06 -07002078 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002079 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002080 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002081 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002082 return;
2083 }
2084
George Liu9ae226f2023-06-21 17:56:46 +08002085 sdbusplus::asio::setProperty(
2086 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002087 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002088 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002089 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002090 if (ec)
2091 {
2092 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2093 messages::internalError(asyncResp->res);
2094 return;
2095 }
2096 });
George Liuc6a620f2020-04-10 17:18:11 +08002097}
2098
AppaRao Pulia6349912019-10-18 17:16:08 +05302099#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2100/**
2101 * @brief Retrieves provisioning status
2102 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002103 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302104 *
2105 * @return None.
2106 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002107inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302108{
Ed Tanous62598e32023-07-17 17:06:25 -07002109 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002110 sdbusplus::asio::getAllProperties(
2111 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2112 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002113 [asyncResp](const boost::system::error_code& ec,
2114 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002115 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002116 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2117 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002118 "#OemComputerSystem.OpenBmc";
2119 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002120
Ed Tanous002d39b2022-05-31 08:59:27 -07002121 if (ec)
2122 {
Ed Tanous62598e32023-07-17 17:06:25 -07002123 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002124 // not an error, don't have to have the interface
2125 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2126 return;
2127 }
2128
2129 const bool* provState = nullptr;
2130 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002131
2132 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002133 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2134 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002135
2136 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002137 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002138 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002139 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002140 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302141
Ed Tanous002d39b2022-05-31 08:59:27 -07002142 if ((provState == nullptr) || (lockState == nullptr))
2143 {
Ed Tanous62598e32023-07-17 17:06:25 -07002144 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002145 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 return;
2147 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302148
Ed Tanous002d39b2022-05-31 08:59:27 -07002149 if (*provState == true)
2150 {
2151 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302152 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002153 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302154 }
2155 else
2156 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002157 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302158 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002159 }
2160 else
2161 {
2162 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2163 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002164 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302165}
2166#endif
2167
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302168/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002169 * @brief Translate the PowerMode to a response message.
2170 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002171 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002172 * @param[in] modeValue PowerMode value to be translated
2173 *
2174 * @return None.
2175 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002176inline void
2177 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2178 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002179{
Chris Cainb6655102024-02-01 14:35:33 -06002180 using PowerMode = computer_system::PowerMode;
2181
George Liu0fda0f12021-11-16 10:06:17 +08002182 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002183 {
Chris Cainb6655102024-02-01 14:35:33 -06002184 asyncResp->res.jsonValue["PowerMode"] = PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002185 }
George Liu0fda0f12021-11-16 10:06:17 +08002186 else if (
2187 modeValue ==
2188 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002189 {
Chris Cainb6655102024-02-01 14:35:33 -06002190 asyncResp->res.jsonValue["PowerMode"] = PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002191 }
George Liu0fda0f12021-11-16 10:06:17 +08002192 else if (modeValue ==
2193 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002194 {
Chris Cainb6655102024-02-01 14:35:33 -06002195 asyncResp->res.jsonValue["PowerMode"] = PowerMode::PowerSaving;
2196 }
2197 else if (
2198 modeValue ==
2199 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2200 {
2201 asyncResp->res.jsonValue["PowerMode"] = PowerMode::BalancedPerformance;
2202 }
2203 else if (
2204 modeValue ==
2205 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2206 {
2207 asyncResp->res.jsonValue["PowerMode"] =
2208 PowerMode::EfficiencyFavorPerformance;
2209 }
2210 else if (
2211 modeValue ==
2212 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2213 {
2214 asyncResp->res.jsonValue["PowerMode"] = PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002215 }
George Liu0fda0f12021-11-16 10:06:17 +08002216 else if (modeValue ==
2217 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002218 {
Chris Cainb6655102024-02-01 14:35:33 -06002219 asyncResp->res.jsonValue["PowerMode"] = PowerMode::OEM;
Chris Cain3a2d04242021-05-28 16:57:10 -05002220 }
2221 else
2222 {
2223 // Any other values would be invalid
Ed Tanous62598e32023-07-17 17:06:25 -07002224 BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
Ed Tanousac106bf2023-06-07 09:24:59 -07002225 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002226 }
2227}
2228
2229/**
2230 * @brief Retrieves system power mode
2231 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002232 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002233 *
2234 * @return None.
2235 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002236inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002237{
Ed Tanous62598e32023-07-17 17:06:25 -07002238 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002239
2240 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002241 constexpr std::array<std::string_view, 1> interfaces = {
2242 "xyz.openbmc_project.Control.Power.Mode"};
2243 dbus::utility::getSubTree(
2244 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002245 [asyncResp](const boost::system::error_code& ec,
2246 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002247 if (ec)
2248 {
Ed Tanous62598e32023-07-17 17:06:25 -07002249 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2250 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002251 // This is an optional D-Bus object so just return if
2252 // error occurs
2253 return;
2254 }
2255 if (subtree.empty())
2256 {
2257 // As noted above, this is an optional interface so just return
2258 // if there is no instance found
2259 return;
2260 }
2261 if (subtree.size() > 1)
2262 {
2263 // More then one PowerMode object is not supported and is an
2264 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002265 BMCWEB_LOG_DEBUG(
2266 "Found more than 1 system D-Bus Power.Mode objects: {}",
2267 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002268 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002269 return;
2270 }
2271 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2272 {
Ed Tanous62598e32023-07-17 17:06:25 -07002273 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002274 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002275 return;
2276 }
2277 const std::string& path = subtree[0].first;
2278 const std::string& service = subtree[0].second.begin()->first;
2279 if (service.empty())
2280 {
Ed Tanous62598e32023-07-17 17:06:25 -07002281 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002283 return;
2284 }
2285 // Valid Power Mode object found, now read the current value
2286 sdbusplus::asio::getProperty<std::string>(
2287 *crow::connections::systemBus, service, path,
2288 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002289 [asyncResp](const boost::system::error_code& ec2,
2290 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002291 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002292 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002293 BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002294 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002295 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002296 return;
2297 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002298
Ed Tanousac106bf2023-06-07 09:24:59 -07002299 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002300 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002301
Ed Tanous62598e32023-07-17 17:06:25 -07002302 BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
Ed Tanousac106bf2023-06-07 09:24:59 -07002303 translatePowerMode(asyncResp, pmode);
George Liue99073f2022-12-09 11:06:16 +08002304 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002305 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002306}
2307
2308/**
2309 * @brief Validate the specified mode is valid and return the PowerMode
2310 * name associated with that string
2311 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002312 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002313 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002314 *
2315 * @return PowerMode value or empty string if mode is not valid
2316 */
2317inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002318 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002319 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002320{
Chris Cainb6655102024-02-01 14:35:33 -06002321 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002322 std::string mode;
2323
Chris Cainb6655102024-02-01 14:35:33 -06002324 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002325 {
2326 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2327 }
Chris Cainb6655102024-02-01 14:35:33 -06002328 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002329 {
George Liu0fda0f12021-11-16 10:06:17 +08002330 mode =
2331 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002332 }
Chris Cainb6655102024-02-01 14:35:33 -06002333 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002334 {
2335 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2336 }
Chris Cainb6655102024-02-01 14:35:33 -06002337 else if (modeValue == PowerMode::BalancedPerformance)
2338 {
2339 mode =
2340 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2341 }
2342 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2343 {
2344 mode =
2345 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2346 }
2347 else if (modeValue == PowerMode::EfficiencyFavorPower)
2348 {
2349 mode =
2350 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2351 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002352 else
2353 {
Chris Cainb6655102024-02-01 14:35:33 -06002354 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002355 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002356 }
2357 return mode;
2358}
2359
2360/**
2361 * @brief Sets system power mode.
2362 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002363 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002364 * @param[in] pmode System power mode from request.
2365 *
2366 * @return None.
2367 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002368inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002369 const std::string& pmode)
2370{
Ed Tanous62598e32023-07-17 17:06:25 -07002371 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002372
Ed Tanousac106bf2023-06-07 09:24:59 -07002373 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002374 if (powerMode.empty())
2375 {
2376 return;
2377 }
2378
2379 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002380 constexpr std::array<std::string_view, 1> interfaces = {
2381 "xyz.openbmc_project.Control.Power.Mode"};
2382 dbus::utility::getSubTree(
2383 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002384 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002385 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002386 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002387 if (ec)
2388 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002389 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002390 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002391 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002392 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002393 return;
2394 }
2395 if (subtree.empty())
2396 {
2397 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002398 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002399 "PowerMode");
2400 return;
2401 }
2402 if (subtree.size() > 1)
2403 {
2404 // More then one PowerMode object is not supported and is an
2405 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002406 BMCWEB_LOG_DEBUG(
2407 "Found more than 1 system D-Bus Power.Mode objects: {}",
2408 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002409 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002410 return;
2411 }
2412 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2413 {
Ed Tanous62598e32023-07-17 17:06:25 -07002414 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002415 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002416 return;
2417 }
2418 const std::string& path = subtree[0].first;
2419 const std::string& service = subtree[0].second.begin()->first;
2420 if (service.empty())
2421 {
Ed Tanous62598e32023-07-17 17:06:25 -07002422 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002423 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002424 return;
2425 }
2426
Ed Tanous62598e32023-07-17 17:06:25 -07002427 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002428
2429 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002430 sdbusplus::asio::setProperty(
2431 *crow::connections::systemBus, service, path,
2432 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002433 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002434 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002435 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002436 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002437 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002438 return;
2439 }
George Liue99073f2022-12-09 11:06:16 +08002440 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002441 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002442}
2443
2444/**
Yong Li51709ff2019-09-30 14:13:04 +08002445 * @brief Translates watchdog timeout action DBUS property value to redfish.
2446 *
2447 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2448 *
2449 * @return Returns as a string, the timeout action in Redfish terms. If
2450 * translation cannot be done, returns an empty string.
2451 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002452inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002453{
2454 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2455 {
2456 return "None";
2457 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002458 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002459 {
2460 return "ResetSystem";
2461 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002462 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002463 {
2464 return "PowerDown";
2465 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002466 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002467 {
2468 return "PowerCycle";
2469 }
2470
2471 return "";
2472}
2473
2474/**
Yong Lic45f0082019-10-10 14:19:01 +08002475 *@brief Translates timeout action from Redfish to DBUS property value.
2476 *
2477 *@param[in] rfAction The timeout action in Redfish.
2478 *
2479 *@return Returns as a string, the time_out action as expected by DBUS.
2480 *If translation cannot be done, returns an empty string.
2481 */
2482
Ed Tanous23a21a12020-07-25 04:45:05 +00002483inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002484{
2485 if (rfAction == "None")
2486 {
2487 return "xyz.openbmc_project.State.Watchdog.Action.None";
2488 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002489 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002490 {
2491 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2492 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002493 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002494 {
2495 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2496 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002497 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002498 {
2499 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2500 }
2501
2502 return "";
2503}
2504
2505/**
Yong Li51709ff2019-09-30 14:13:04 +08002506 * @brief Retrieves host watchdog timer properties over DBUS
2507 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002508 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002509 *
2510 * @return None.
2511 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002512inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002513 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002514{
Ed Tanous62598e32023-07-17 17:06:25 -07002515 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002516 sdbusplus::asio::getAllProperties(
2517 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2518 "/xyz/openbmc_project/watchdog/host0",
2519 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002520 [asyncResp](const boost::system::error_code& ec,
2521 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002522 if (ec)
2523 {
2524 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002525 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002526 return;
2527 }
2528
Ed Tanous62598e32023-07-17 17:06:25 -07002529 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002530
2531 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002532 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002533
2534 // watchdog service is running/enabled
2535 hostWatchdogTimer["Status"]["State"] = "Enabled";
2536
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002537 const bool* enabled = nullptr;
2538 const std::string* expireAction = nullptr;
2539
2540 const bool success = sdbusplus::unpackPropertiesNoThrow(
2541 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2542 "ExpireAction", expireAction);
2543
2544 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002545 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002546 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002547 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002548 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002549
2550 if (enabled != nullptr)
2551 {
2552 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2553 }
2554
2555 if (expireAction != nullptr)
2556 {
2557 std::string action = dbusToRfWatchdogAction(*expireAction);
2558 if (action.empty())
2559 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002560 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002561 return;
2562 }
2563 hostWatchdogTimer["TimeoutAction"] = action;
2564 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002565 });
Yong Li51709ff2019-09-30 14:13:04 +08002566}
2567
2568/**
Yong Lic45f0082019-10-10 14:19:01 +08002569 * @brief Sets Host WatchDog Timer properties.
2570 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002571 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002572 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2573 * RF request.
2574 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2575 *
2576 * @return None.
2577 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002578inline void
2579 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2580 const std::optional<bool> wdtEnable,
2581 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002582{
Ed Tanous62598e32023-07-17 17:06:25 -07002583 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002584
2585 if (wdtTimeOutAction)
2586 {
2587 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2588 // check if TimeOut Action is Valid
2589 if (wdtTimeOutActStr.empty())
2590 {
Ed Tanous62598e32023-07-17 17:06:25 -07002591 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2592 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002593 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002594 "TimeoutAction");
2595 return;
2596 }
2597
George Liu9ae226f2023-06-21 17:56:46 +08002598 sdbusplus::asio::setProperty(
2599 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002600 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002601 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002602 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002603 if (ec)
2604 {
2605 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2606 messages::internalError(asyncResp->res);
2607 return;
2608 }
2609 });
Yong Lic45f0082019-10-10 14:19:01 +08002610 }
2611
2612 if (wdtEnable)
2613 {
George Liu9ae226f2023-06-21 17:56:46 +08002614 sdbusplus::asio::setProperty(
2615 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2616 "/xyz/openbmc_project/watchdog/host0",
2617 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002618 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002619 if (ec)
2620 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002621 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002622 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002623 return;
2624 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002625 });
Yong Lic45f0082019-10-10 14:19:01 +08002626 }
2627}
2628
Chris Cain37bbf982021-09-20 10:53:09 -05002629/**
2630 * @brief Parse the Idle Power Saver properties into json
2631 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002632 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002633 * @param[in] properties IPS property data from DBus.
2634 *
2635 * @return true if successful
2636 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002637inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002638 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002639 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002640{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002641 const bool* enabled = nullptr;
2642 const uint8_t* enterUtilizationPercent = nullptr;
2643 const uint64_t* enterDwellTime = nullptr;
2644 const uint8_t* exitUtilizationPercent = nullptr;
2645 const uint64_t* exitDwellTime = nullptr;
2646
2647 const bool success = sdbusplus::unpackPropertiesNoThrow(
2648 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002649 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2650 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2651 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002652
2653 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002654 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002655 return false;
2656 }
2657
2658 if (enabled != nullptr)
2659 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002660 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002661 }
2662
2663 if (enterUtilizationPercent != nullptr)
2664 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002665 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002666 *enterUtilizationPercent;
2667 }
2668
2669 if (enterDwellTime != nullptr)
2670 {
2671 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002672 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002673 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2674 .count();
2675 }
2676
2677 if (exitUtilizationPercent != nullptr)
2678 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002679 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002680 *exitUtilizationPercent;
2681 }
2682
2683 if (exitDwellTime != nullptr)
2684 {
2685 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002686 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002687 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2688 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002689 }
2690
2691 return true;
2692}
2693
2694/**
2695 * @brief Retrieves host watchdog timer properties over DBUS
2696 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002697 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002698 *
2699 * @return None.
2700 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002701inline void
2702 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002703{
Ed Tanous62598e32023-07-17 17:06:25 -07002704 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002705
2706 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002707 constexpr std::array<std::string_view, 1> interfaces = {
2708 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2709 dbus::utility::getSubTree(
2710 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 [asyncResp](const boost::system::error_code& ec,
2712 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002713 if (ec)
2714 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002715 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002716 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2717 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002718 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002719 return;
2720 }
2721 if (subtree.empty())
2722 {
2723 // This is an optional interface so just return
2724 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002725 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002726 return;
2727 }
2728 if (subtree.size() > 1)
2729 {
2730 // More then one PowerIdlePowerSaver object is not supported and
2731 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002732 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2733 "Power.IdlePowerSaver objects: {}",
2734 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002735 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002736 return;
2737 }
2738 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2739 {
Ed Tanous62598e32023-07-17 17:06:25 -07002740 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002741 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002742 return;
2743 }
2744 const std::string& path = subtree[0].first;
2745 const std::string& service = subtree[0].second.begin()->first;
2746 if (service.empty())
2747 {
Ed Tanous62598e32023-07-17 17:06:25 -07002748 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002749 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002750 return;
2751 }
2752
2753 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002754 sdbusplus::asio::getAllProperties(
2755 *crow::connections::systemBus, service, path,
2756 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002757 [asyncResp](const boost::system::error_code& ec2,
2758 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002759 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002760 {
Ed Tanous62598e32023-07-17 17:06:25 -07002761 BMCWEB_LOG_ERROR(
2762 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002763 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002764 return;
2765 }
2766
Ed Tanousac106bf2023-06-07 09:24:59 -07002767 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002768 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002769 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002770 return;
2771 }
George Liue99073f2022-12-09 11:06:16 +08002772 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002773 });
Chris Cain37bbf982021-09-20 10:53:09 -05002774
Ed Tanous62598e32023-07-17 17:06:25 -07002775 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002776}
2777
2778/**
2779 * @brief Sets Idle Power Saver properties.
2780 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002781 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002782 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2783 * RF request.
2784 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2785 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2786 * before entering idle state.
2787 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2788 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2789 * before exiting idle state
2790 *
2791 * @return None.
2792 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002793inline void
2794 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2795 const std::optional<bool> ipsEnable,
2796 const std::optional<uint8_t> ipsEnterUtil,
2797 const std::optional<uint64_t> ipsEnterTime,
2798 const std::optional<uint8_t> ipsExitUtil,
2799 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002800{
Ed Tanous62598e32023-07-17 17:06:25 -07002801 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002802
2803 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002804 constexpr std::array<std::string_view, 1> interfaces = {
2805 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2806 dbus::utility::getSubTree(
2807 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002808 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002809 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002810 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002811 if (ec)
2812 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002813 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002814 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2815 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002816 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002817 return;
2818 }
2819 if (subtree.empty())
2820 {
2821 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002822 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002823 "IdlePowerSaver");
2824 return;
2825 }
2826 if (subtree.size() > 1)
2827 {
2828 // More then one PowerIdlePowerSaver object is not supported and
2829 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002830 BMCWEB_LOG_DEBUG(
2831 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2832 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002833 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002834 return;
2835 }
2836 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2837 {
Ed Tanous62598e32023-07-17 17:06:25 -07002838 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002839 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002840 return;
2841 }
2842 const std::string& path = subtree[0].first;
2843 const std::string& service = subtree[0].second.begin()->first;
2844 if (service.empty())
2845 {
Ed Tanous62598e32023-07-17 17:06:25 -07002846 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002847 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002848 return;
2849 }
Chris Cain37bbf982021-09-20 10:53:09 -05002850
Ed Tanous002d39b2022-05-31 08:59:27 -07002851 // Valid Power IdlePowerSaver object found, now set any values that
2852 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002853
Ed Tanous002d39b2022-05-31 08:59:27 -07002854 if (ipsEnable)
2855 {
George Liu9ae226f2023-06-21 17:56:46 +08002856 sdbusplus::asio::setProperty(
2857 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002858 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002859 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002860 if (ec2)
2861 {
2862 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2863 messages::internalError(asyncResp->res);
2864 return;
2865 }
2866 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002867 }
2868 if (ipsEnterUtil)
2869 {
George Liu9ae226f2023-06-21 17:56:46 +08002870 sdbusplus::asio::setProperty(
2871 *crow::connections::systemBus, service, path,
2872 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2873 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002874 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002875 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002876 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002877 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002878 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002879 return;
2880 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002881 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002882 }
2883 if (ipsEnterTime)
2884 {
2885 // Convert from seconds into milliseconds for DBus
2886 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002887 sdbusplus::asio::setProperty(
2888 *crow::connections::systemBus, service, path,
2889 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2890 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002891 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002892 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002893 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002894 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002895 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002896 return;
2897 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002898 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002899 }
2900 if (ipsExitUtil)
2901 {
George Liu9ae226f2023-06-21 17:56:46 +08002902 sdbusplus::asio::setProperty(
2903 *crow::connections::systemBus, service, path,
2904 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2905 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002906 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002907 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002908 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002909 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002910 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002911 return;
2912 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002913 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002914 }
2915 if (ipsExitTime)
2916 {
2917 // Convert from seconds into milliseconds for DBus
2918 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002919 sdbusplus::asio::setProperty(
2920 *crow::connections::systemBus, service, path,
2921 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2922 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002923 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002924 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002925 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002926 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002927 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002928 return;
2929 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002930 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002931 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002932 });
Chris Cain37bbf982021-09-20 10:53:09 -05002933
Ed Tanous62598e32023-07-17 17:06:25 -07002934 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002935}
2936
Ed Tanousc1e219d2023-06-07 10:34:33 -07002937inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002938 crow::App& app, const crow::Request& req,
2939 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2940{
2941 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2942 {
2943 return;
2944 }
2945 asyncResp->res.addHeader(
2946 boost::beast::http::field::link,
2947 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2948}
2949
Ed Tanousc1e219d2023-06-07 10:34:33 -07002950inline void handleComputerSystemCollectionGet(
2951 crow::App& app, const crow::Request& req,
2952 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2953{
2954 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2955 {
2956 return;
2957 }
2958
2959 asyncResp->res.addHeader(
2960 boost::beast::http::field::link,
2961 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2962 asyncResp->res.jsonValue["@odata.type"] =
2963 "#ComputerSystemCollection.ComputerSystemCollection";
2964 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2965 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2966
2967 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2968 ifaceArray = nlohmann::json::array();
2969 if constexpr (bmcwebEnableMultiHost)
2970 {
2971 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2972 // Option currently returns no systems. TBD
2973 return;
2974 }
2975 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2976 nlohmann::json::object_t system;
2977 system["@odata.id"] = "/redfish/v1/Systems/system";
2978 ifaceArray.emplace_back(std::move(system));
2979 sdbusplus::asio::getProperty<std::string>(
2980 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2981 "/xyz/openbmc_project/network/hypervisor",
2982 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2983 [asyncResp](const boost::system::error_code& ec2,
2984 const std::string& /*hostName*/) {
2985 if (ec2)
2986 {
2987 return;
2988 }
2989 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2990 if (val == asyncResp->res.jsonValue.end())
2991 {
Ed Tanous62598e32023-07-17 17:06:25 -07002992 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002993 return;
2994 }
2995 uint64_t* count = val->get_ptr<uint64_t*>();
2996 if (count == nullptr)
2997 {
Ed Tanous62598e32023-07-17 17:06:25 -07002998 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002999 return;
3000 }
3001 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07003002 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003003 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
3004 nlohmann::json::object_t hypervisor;
3005 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
3006 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05003007 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003008}
3009
Yong Lic45f0082019-10-10 14:19:01 +08003010/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003011 * Function transceives data with dbus directly.
3012 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07003013inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003014{
Patrick Williams89492a12023-05-10 07:51:34 -05003015 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
3016 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
3017 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003018 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05003019 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003020
3021 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08003022 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003023 if (ec)
3024 {
Ed Tanous62598e32023-07-17 17:06:25 -07003025 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07003026 messages::internalError(asyncResp->res);
3027 return;
3028 }
3029 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003030 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003031 serviceName, objectPath, interfaceName, method);
3032}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003033
3034/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003035 * Handle error responses from d-bus for system power requests
3036 */
3037inline void handleSystemActionResetError(const boost::system::error_code& ec,
3038 const sdbusplus::message_t& eMsg,
3039 std::string_view resetType,
3040 crow::Response& res)
3041{
3042 if (ec.value() == boost::asio::error::invalid_argument)
3043 {
3044 messages::actionParameterNotSupported(res, resetType, "Reset");
3045 return;
3046 }
3047
3048 if (eMsg.get_error() == nullptr)
3049 {
Ed Tanous62598e32023-07-17 17:06:25 -07003050 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003051 messages::internalError(res);
3052 return;
3053 }
3054 std::string_view errorMessage = eMsg.get_error()->name;
3055
3056 // If operation failed due to BMC not being in Ready state, tell
3057 // user to retry in a bit
3058 if ((errorMessage ==
3059 std::string_view(
3060 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3061 (errorMessage ==
3062 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3063 {
Ed Tanous62598e32023-07-17 17:06:25 -07003064 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003065 messages::serviceTemporarilyUnavailable(res, "10");
3066 return;
3067 }
3068
Ed Tanous62598e32023-07-17 17:06:25 -07003069 BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
3070 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003071 messages::internalError(res);
3072}
3073
Ed Tanousc1e219d2023-06-07 10:34:33 -07003074inline void handleComputerSystemResetActionPost(
3075 crow::App& app, const crow::Request& req,
3076 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3077 const std::string& systemName)
3078{
3079 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3080 {
3081 return;
3082 }
3083 if (systemName != "system")
3084 {
3085 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3086 systemName);
3087 return;
3088 }
3089 if constexpr (bmcwebEnableMultiHost)
3090 {
3091 // Option currently returns no systems. TBD
3092 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3093 systemName);
3094 return;
3095 }
3096 std::string resetType;
3097 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3098 {
3099 return;
3100 }
3101
3102 // Get the command and host vs. chassis
3103 std::string command;
3104 bool hostCommand = true;
3105 if ((resetType == "On") || (resetType == "ForceOn"))
3106 {
3107 command = "xyz.openbmc_project.State.Host.Transition.On";
3108 hostCommand = true;
3109 }
3110 else if (resetType == "ForceOff")
3111 {
3112 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3113 hostCommand = false;
3114 }
3115 else if (resetType == "ForceRestart")
3116 {
3117 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3118 hostCommand = true;
3119 }
3120 else if (resetType == "GracefulShutdown")
3121 {
3122 command = "xyz.openbmc_project.State.Host.Transition.Off";
3123 hostCommand = true;
3124 }
3125 else if (resetType == "GracefulRestart")
3126 {
3127 command =
3128 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3129 hostCommand = true;
3130 }
3131 else if (resetType == "PowerCycle")
3132 {
3133 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3134 hostCommand = true;
3135 }
3136 else if (resetType == "Nmi")
3137 {
3138 doNMI(asyncResp);
3139 return;
3140 }
3141 else
3142 {
3143 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3144 return;
3145 }
3146
3147 if (hostCommand)
3148 {
George Liu9ae226f2023-06-21 17:56:46 +08003149 sdbusplus::asio::setProperty(
3150 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3151 "/xyz/openbmc_project/state/host0",
3152 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3153 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003154 [asyncResp, resetType](const boost::system::error_code& ec,
3155 sdbusplus::message_t& sdbusErrMsg) {
3156 if (ec)
3157 {
3158 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3159 asyncResp->res);
3160
3161 return;
3162 }
3163 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003164 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003165 }
3166 else
3167 {
George Liu9ae226f2023-06-21 17:56:46 +08003168 sdbusplus::asio::setProperty(
3169 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3170 "/xyz/openbmc_project/state/chassis0",
3171 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3172 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003173 [asyncResp, resetType](const boost::system::error_code& ec,
3174 sdbusplus::message_t& sdbusErrMsg) {
3175 if (ec)
3176 {
3177 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3178 asyncResp->res);
3179 return;
3180 }
3181 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003182 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003183 }
3184}
3185
Ed Tanousc1e219d2023-06-07 10:34:33 -07003186inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003187 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003188 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3189 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003190{
3191 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3192 {
3193 return;
3194 }
3195
3196 asyncResp->res.addHeader(
3197 boost::beast::http::field::link,
3198 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3199}
3200
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003201inline void afterPortRequest(
3202 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3203 const boost::system::error_code& ec,
3204 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3205{
3206 if (ec)
3207 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003208 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003209 messages::internalError(asyncResp->res);
3210 return;
3211 }
3212 for (const auto& data : socketData)
3213 {
3214 const std::string& socketPath = get<0>(data);
3215 const std::string& protocolName = get<1>(data);
3216 bool isProtocolEnabled = get<2>(data);
3217 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3218 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3219 // need to retrieve port number for
3220 // obmc-console-ssh service
3221 if (protocolName == "SSH")
3222 {
3223 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003224 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003225 int portNumber) {
3226 if (ec1)
3227 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003228 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003229 messages::internalError(asyncResp->res);
3230 return;
3231 }
3232 nlohmann::json& dataJson1 =
3233 asyncResp->res.jsonValue["SerialConsole"];
3234 dataJson1[protocolName]["Port"] = portNumber;
3235 });
3236 }
3237 }
3238}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003239
3240inline void
3241 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3242 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3243 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003244{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003245 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3246 {
3247 return;
3248 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003249
Ed Tanousc1e219d2023-06-07 10:34:33 -07003250 if constexpr (bmcwebEnableMultiHost)
3251 {
3252 // Option currently returns no systems. TBD
3253 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3254 systemName);
3255 return;
3256 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003257
Ed Tanousc1e219d2023-06-07 10:34:33 -07003258 if (systemName == "hypervisor")
3259 {
3260 handleHypervisorSystemGet(asyncResp);
3261 return;
3262 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003263
Ed Tanousc1e219d2023-06-07 10:34:33 -07003264 if (systemName != "system")
3265 {
3266 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3267 systemName);
3268 return;
3269 }
3270 asyncResp->res.addHeader(
3271 boost::beast::http::field::link,
3272 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3273 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003274 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanousc1e219d2023-06-07 10:34:33 -07003275 asyncResp->res.jsonValue["Name"] = "system";
3276 asyncResp->res.jsonValue["Id"] = "system";
3277 asyncResp->res.jsonValue["SystemType"] = "Physical";
3278 asyncResp->res.jsonValue["Description"] = "Computer System";
3279 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3280 if constexpr (bmcwebEnableProcMemStatus)
3281 {
3282 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3283 "Disabled";
3284 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3285 "Disabled";
3286 }
3287 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003288 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003289 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003290
Ed Tanousc1e219d2023-06-07 10:34:33 -07003291 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3292 "/redfish/v1/Systems/system/Processors";
3293 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3294 "/redfish/v1/Systems/system/Memory";
3295 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3296 "/redfish/v1/Systems/system/Storage";
3297 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3298 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003299
Ed Tanousc1e219d2023-06-07 10:34:33 -07003300 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3301 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3302 asyncResp->res
3303 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3304 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003305
Ed Tanousc1e219d2023-06-07 10:34:33 -07003306 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3307 "/redfish/v1/Systems/system/LogServices";
3308 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3309 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003310
Ed Tanousc1e219d2023-06-07 10:34:33 -07003311 nlohmann::json::array_t managedBy;
3312 nlohmann::json& manager = managedBy.emplace_back();
3313 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3314 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3315 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3316 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003317
Ed Tanousc1e219d2023-06-07 10:34:33 -07003318 // Fill in SerialConsole info
3319 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3320 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003321
Ed Tanousc1e219d2023-06-07 10:34:33 -07003322 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3323 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3324 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3325 "Press ~. to exit console";
3326 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3327 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003328
3329#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003330 // Fill in GraphicalConsole info
3331 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3332 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3333 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3334 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003335
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003336#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003337
Ed Tanousc1e219d2023-06-07 10:34:33 -07003338 auto health = std::make_shared<HealthPopulate>(asyncResp);
3339 if constexpr (bmcwebEnableHealthPopulate)
3340 {
3341 constexpr std::array<std::string_view, 4> inventoryForSystems{
3342 "xyz.openbmc_project.Inventory.Item.Dimm",
3343 "xyz.openbmc_project.Inventory.Item.Cpu",
3344 "xyz.openbmc_project.Inventory.Item.Drive",
3345 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003346
Ed Tanousc1e219d2023-06-07 10:34:33 -07003347 dbus::utility::getSubTreePaths(
3348 "/", 0, inventoryForSystems,
3349 [health](const boost::system::error_code& ec,
3350 const std::vector<std::string>& resp) {
3351 if (ec)
3352 {
3353 // no inventory
3354 return;
3355 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003356
Ed Tanousc1e219d2023-06-07 10:34:33 -07003357 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003358 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003359 health->populate();
3360 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003361
Ed Tanousc1e219d2023-06-07 10:34:33 -07003362 getMainChassisId(asyncResp,
3363 [](const std::string& chassisId,
3364 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3365 nlohmann::json::array_t chassisArray;
3366 nlohmann::json& chassis = chassisArray.emplace_back();
3367 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3368 chassisId);
3369 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3370 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003371
George Liu59a17e42022-10-08 09:27:47 +08003372 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003373 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3374 getIndicatorLedState(asyncResp);
3375 getComputerSystem(asyncResp, health);
3376 getHostState(asyncResp);
3377 getBootProperties(asyncResp);
3378 getBootProgress(asyncResp);
3379 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003380 pcie_util::getPCIeDeviceList(asyncResp,
3381 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003382 getHostWatchdogTimer(asyncResp);
3383 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003384 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003385 getAutomaticRetryPolicy(asyncResp);
3386 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003387#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003388 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003389#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003390 getTrustedModuleRequiredToBoot(asyncResp);
3391 getPowerMode(asyncResp);
3392 getIdlePowerSaver(asyncResp);
3393}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003394
Ed Tanousc1e219d2023-06-07 10:34:33 -07003395inline void handleComputerSystemPatch(
3396 crow::App& app, const crow::Request& req,
3397 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3398 const std::string& systemName)
3399{
3400 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3401 {
3402 return;
3403 }
3404 if constexpr (bmcwebEnableMultiHost)
3405 {
3406 // Option currently returns no systems. TBD
3407 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3408 systemName);
3409 return;
3410 }
3411 if (systemName != "system")
3412 {
3413 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3414 systemName);
3415 return;
3416 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003417
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 asyncResp->res.addHeader(
3419 boost::beast::http::field::link,
3420 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003421
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 std::optional<bool> locationIndicatorActive;
3423 std::optional<std::string> indicatorLed;
3424 std::optional<std::string> assetTag;
3425 std::optional<std::string> powerRestorePolicy;
3426 std::optional<std::string> powerMode;
3427 std::optional<bool> wdtEnable;
3428 std::optional<std::string> wdtTimeOutAction;
3429 std::optional<std::string> bootSource;
3430 std::optional<std::string> bootType;
3431 std::optional<std::string> bootEnable;
3432 std::optional<std::string> bootAutomaticRetry;
3433 std::optional<uint32_t> bootAutomaticRetryAttempts;
3434 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003435 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003436 std::optional<bool> ipsEnable;
3437 std::optional<uint8_t> ipsEnterUtil;
3438 std::optional<uint64_t> ipsEnterTime;
3439 std::optional<uint8_t> ipsExitUtil;
3440 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003441
Ed Tanousc1e219d2023-06-07 10:34:33 -07003442 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003443 if (!json_util::readJsonPatch(
3444 req, asyncResp->res,
3445 "IndicatorLED", indicatorLed,
3446 "LocationIndicatorActive", locationIndicatorActive,
3447 "AssetTag", assetTag,
3448 "PowerRestorePolicy", powerRestorePolicy,
3449 "PowerMode", powerMode,
3450 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3451 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3452 "Boot/BootSourceOverrideTarget", bootSource,
3453 "Boot/BootSourceOverrideMode", bootType,
3454 "Boot/BootSourceOverrideEnabled", bootEnable,
3455 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003456 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003457 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003458 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003459 "IdlePowerSaver/Enabled", ipsEnable,
3460 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3461 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3462 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3463 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3464 {
3465 return;
3466 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003467 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003468
Ed Tanousc1e219d2023-06-07 10:34:33 -07003469 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003470
Ed Tanousc1e219d2023-06-07 10:34:33 -07003471 if (assetTag)
3472 {
3473 setAssetTag(asyncResp, *assetTag);
3474 }
James Feistb49ac872019-05-21 15:12:01 -07003475
Ed Tanousc1e219d2023-06-07 10:34:33 -07003476 if (wdtEnable || wdtTimeOutAction)
3477 {
3478 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3479 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003480
Ed Tanousc1e219d2023-06-07 10:34:33 -07003481 if (bootSource || bootType || bootEnable)
3482 {
3483 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3484 }
3485 if (bootAutomaticRetry)
3486 {
3487 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3488 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003489
Ed Tanousc1e219d2023-06-07 10:34:33 -07003490 if (bootAutomaticRetryAttempts)
3491 {
3492 setAutomaticRetryAttempts(asyncResp,
3493 bootAutomaticRetryAttempts.value());
3494 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003495
Ed Tanousc1e219d2023-06-07 10:34:33 -07003496 if (bootTrustedModuleRequired)
3497 {
3498 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3499 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003500
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003501 if (stopBootOnFault)
3502 {
3503 setStopBootOnFault(asyncResp, *stopBootOnFault);
3504 }
3505
Ed Tanousc1e219d2023-06-07 10:34:33 -07003506 if (locationIndicatorActive)
3507 {
George Liu59a17e42022-10-08 09:27:47 +08003508 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003509 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003510
Ed Tanousc1e219d2023-06-07 10:34:33 -07003511 // TODO (Gunnar): Remove IndicatorLED after enough time has
3512 // passed
3513 if (indicatorLed)
3514 {
3515 setIndicatorLedState(asyncResp, *indicatorLed);
3516 asyncResp->res.addHeader(boost::beast::http::field::warning,
3517 "299 - \"IndicatorLED is deprecated. Use "
3518 "LocationIndicatorActive instead.\"");
3519 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003520
Ed Tanousc1e219d2023-06-07 10:34:33 -07003521 if (powerRestorePolicy)
3522 {
3523 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3524 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003525
Ed Tanousc1e219d2023-06-07 10:34:33 -07003526 if (powerMode)
3527 {
3528 setPowerMode(asyncResp, *powerMode);
3529 }
Chris Cain37bbf982021-09-20 10:53:09 -05003530
Ed Tanousc1e219d2023-06-07 10:34:33 -07003531 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3532 {
3533 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3534 ipsExitUtil, ipsExitTime);
3535 }
3536}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303537
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003538inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003539 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003540 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003541 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003542{
3543 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3544 {
3545 return;
3546 }
3547 asyncResp->res.addHeader(
3548 boost::beast::http::field::link,
3549 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3550}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003551inline void handleSystemCollectionResetActionGet(
3552 crow::App& app, const crow::Request& req,
3553 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3554 const std::string& systemName)
3555{
3556 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3557 {
3558 return;
3559 }
3560 if constexpr (bmcwebEnableMultiHost)
3561 {
3562 // Option currently returns no systems. TBD
3563 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3564 systemName);
3565 return;
3566 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003567
Ed Tanousc1e219d2023-06-07 10:34:33 -07003568 if (systemName == "hypervisor")
3569 {
3570 handleHypervisorResetActionGet(asyncResp);
3571 return;
3572 }
3573
3574 if (systemName != "system")
3575 {
3576 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3577 systemName);
3578 return;
3579 }
3580
3581 asyncResp->res.addHeader(
3582 boost::beast::http::field::link,
3583 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3584
3585 asyncResp->res.jsonValue["@odata.id"] =
3586 "/redfish/v1/Systems/system/ResetActionInfo";
3587 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3588 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3589 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3590
3591 nlohmann::json::array_t parameters;
3592 nlohmann::json::object_t parameter;
3593
3594 parameter["Name"] = "ResetType";
3595 parameter["Required"] = true;
3596 parameter["DataType"] = "String";
3597 nlohmann::json::array_t allowableValues;
3598 allowableValues.emplace_back("On");
3599 allowableValues.emplace_back("ForceOff");
3600 allowableValues.emplace_back("ForceOn");
3601 allowableValues.emplace_back("ForceRestart");
3602 allowableValues.emplace_back("GracefulRestart");
3603 allowableValues.emplace_back("GracefulShutdown");
3604 allowableValues.emplace_back("PowerCycle");
3605 allowableValues.emplace_back("Nmi");
3606 parameter["AllowableValues"] = std::move(allowableValues);
3607 parameters.emplace_back(std::move(parameter));
3608
3609 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3610}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303611/**
3612 * SystemResetActionInfo derived class for delivering Computer Systems
3613 * ResetType AllowableValues using ResetInfo schema.
3614 */
Ed Tanous100afe52023-06-07 13:30:46 -07003615inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303616{
Ed Tanous100afe52023-06-07 13:30:46 -07003617 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3618 .privileges(redfish::privileges::headComputerSystemCollection)
3619 .methods(boost::beast::http::verb::head)(
3620 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3621
3622 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3623 .privileges(redfish::privileges::getComputerSystemCollection)
3624 .methods(boost::beast::http::verb::get)(
3625 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3626
3627 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3628 .privileges(redfish::privileges::headComputerSystem)
3629 .methods(boost::beast::http::verb::head)(
3630 std::bind_front(handleComputerSystemHead, std::ref(app)));
3631
3632 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3633 .privileges(redfish::privileges::getComputerSystem)
3634 .methods(boost::beast::http::verb::get)(
3635 std::bind_front(handleComputerSystemGet, std::ref(app)));
3636
3637 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3638 .privileges(redfish::privileges::patchComputerSystem)
3639 .methods(boost::beast::http::verb::patch)(
3640 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3641
3642 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3643 .privileges(redfish::privileges::postComputerSystem)
3644 .methods(boost::beast::http::verb::post)(std::bind_front(
3645 handleComputerSystemResetActionPost, std::ref(app)));
3646
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003647 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003648 .privileges(redfish::privileges::headActionInfo)
3649 .methods(boost::beast::http::verb::head)(std::bind_front(
3650 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003651 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003652 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003653 .methods(boost::beast::http::verb::get)(std::bind_front(
3654 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003655}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003656} // namespace redfish